Profile Form
A dynamic profile form component that allows users to edit their profile information with flexible field configuration, validation, and automatic API integration.
Getting Started
Basic Usage
The simplest way to implement a profile form:
import { ProfileForm } from "@ovok/native";
import React from "react";
const fields = [
{
name: "name.given.0",
label: "First Name",
type: "text" as const,
value: "John",
},
{
name: "name.family",
label: "Last Name",
type: "text" as const,
value: "Doe",
},
{
name: "birthDate",
label: "Date of Birth",
type: "date" as const,
value: "1990-01-01",
},
];
const BasicProfileForm = () => {
return <ProfileForm fields={fields} />;
};
export default BasicProfileForm;
With Custom Validation
Add custom validation rules to fields:
import { ProfileForm } from "@ovok/native";
import React from "react";
import * as Yup from "yup";
const fields = [
{
name: "name.given.0",
label: "First Name",
type: "text" as const,
value: "",
validation: Yup.string()
.required("First name is required")
.min(2, "Must be at least 2 characters"),
},
{
name: "birthDate",
label: "Date of Birth",
type: "date" as const,
value: "",
validation: Yup.string().required("Date of birth is required"),
},
{
name: "gender",
label: "Gender",
type: "select" as const,
value: "",
options: [
{ label: "Male", value: "male" },
{ label: "Female", value: "female" },
{ label: "Other", value: "other" },
],
validation: Yup.string().required("Please select a gender"),
},
];
const ValidatedProfileForm = () => {
return (
<ProfileForm
fields={fields}
onSuccess={(patient) => console.log("Updated:", patient)}
/>
);
};
export default ValidatedProfileForm;
Features
- Dynamic Fields: Configure any number and type of form fields
- Multiple Field Types: Support for text, date, and select fields
- FHIR Integration: Automatic Patient resource patching via FHIR API
- Custom Validation: Yup-based validation with custom rules per field
- Patch Operations: Efficient API updates using JSON Patch operations
- Error Handling: Comprehensive error handling and display
- Theme Integration: Consistent styling with your app theme
- Loading States: Built-in loading indicators during submission
- TypeScript: Full type safety throughout
Props
| Prop | Type | Default | Description |
|---|---|---|---|
fields | ProfileFormField[] | - | Array of form field configurations |
style | StyleProp<ViewStyle> | undefined | Custom container styling |
testID | string | undefined | Test identifier |
onSuccess | (patient: Patient) => void | undefined | Called when profile update succeeds |
onSubmit | (values, helpers) => Promise<void> | undefined | Custom form submission handler |
ProfileFormField Type
type ProfileFormField = {
name: string; // Path to field in form values (supports nested paths)
label: string; // Display label for the field
value: string; // Initial/current value
validation?: Yup.Schema<string>; // Custom validation schema
disabled?: boolean; // Disable field input
testID?: string; // Test identifier for field
} & (
| {
type: "text";
}
| {
type: "date";
mode?: "date" | "time" | "datetime";
}
| {
type: "select";
options: { label: string; value: string }[];
}
);
Field Types
Text Fields
Simple text input fields for names, descriptions, etc:
{
name: "name.given.0",
label: "First Name",
type: "text",
value: "John",
validation: Yup.string().required("Required"),
}
Date Fields
Date picker fields with customizable modes:
{
name: "birthDate",
label: "Date of Birth",
type: "date",
mode: "date", // "date" | "time" | "datetime"
value: "1990-01-01",
validation: Yup.string().required("Date required"),
}
Select Fields
Dropdown selection fields with predefined options:
{
name: "gender",
label: "Gender",
type: "select",
value: "male",
options: [
{ label: "Male", value: "male" },
{ label: "Female", value: "female" },
{ label: "Other", value: "other" },
],
validation: Yup.string().required("Please select"),
}
FHIR Integration
The component automatically integrates with FHIR Patient resources:
Field Path Mapping
Field names are automatically mapped to FHIR Patient resource paths:
// Field configuration
{
name: "name.given.0", // Maps to patient.name[0].given[0]
name: "name.family", // Maps to patient.name[0].family
name: "birthDate", // Maps to patient.birthDate
name: "gender", // Maps to patient.gender
}
Patch Operations
The component generates JSON Patch operations for efficient updates:
// Example patch operations generated:
[
{
op: "replace",
path: "/name/0/given/0",
value: "John",
},
{
op: "add",
path: "/birthDate",
value: "1990-01-01",
},
];
Validation
Default Validation
Basic validation is applied based on field type:
// Text fields: string validation
// Date fields: date format validation
// Select fields: option value validation
Custom Validation
Add custom Yup validation schemas to any field:
{
name: "name.given.0",
label: "First Name",
type: "text",
value: "",
validation: Yup.string()
.required("First name is required")
.min(2, "Must be at least 2 characters")
.max(50, "Cannot exceed 50 characters")
.matches(/^[a-zA-Z\s]+$/, "Only letters and spaces allowed"),
}
Validation Examples
// Email validation
{
name: "email",
label: "Email",
type: "text",
value: "",
validation: Yup.string()
.email("Invalid email format")
.required("Email is required"),
}
// Phone validation
{
name: "phone",
label: "Phone Number",
type: "text",
value: "",
validation: Yup.string()
.matches(/^\+?[\d\s-()]+$/, "Invalid phone format")
.min(10, "Phone number too short"),
}
// Age validation
{
name: "birthDate",
label: "Date of Birth",
type: "date",
value: "",
validation: Yup.string()
.required("Date of birth is required")
.test("age", "Must be at least 18 years old", function(value) {
if (!value) return false;
const age = new Date().getFullYear() - new Date(value).getFullYear();
return age >= 18;
}),
}
Localization
The component uses these translation keys:
{
"profile": {
"save": "Save Profile"
}
}
Ensure your field labels and validation messages are also properly localized.
Related Components
- Register - Initial profile creation during registration
- Sign-In - User authentication to access profile
- Logout Button - User session management