DynamicForm
A fully configuration-driven form that renders fields from a fields array. It supports create, edit, globalEdit, submit, readOnly, and view modes, optional API fetch and save integration, field-level visibility conditions (showIf), and column spans. An imperative ref API exposes clearForm, resetForm, getFormValues, and setFormValues.
Props
| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| fields | Field[] | Yes | — | Array of field configuration objects (see below). |
| mode | 'create' \| 'edit' \| 'globalEdit' \| 'readOnly' \| 'submit' \| 'view' | No | 'create' | Determines which fields are shown and the submit button label. |
| data | Record<string, any> | No | — | Initial form values when not fetching from an API. |
| title | string | No | — | Optional heading displayed above the form body. |
| apiBaseUrl | string | No | config urls.apiBase | Base URL for the HTTP client. |
| useAuthToken | boolean | No | true | Uses the authenticated HTTP client when true. |
| fetchPath | string | No | — | API path used to pre-populate the form (non-create modes). |
| fetchMethod | 'GET' \| 'POST' \| 'PUT' | No | 'GET' | HTTP method for the fetch request. |
| fetchDataKey | string | No | 'data' | Key to extract from the fetch response. |
| savePath | string | No | — | API path used to submit the form. |
| saveMethod | 'POST' \| 'PUT' \| 'PATCH' | No | 'POST' | HTTP method for the save request. |
| saveDataKey | string | No | — | Key to extract from the save response. |
| extraData | Record<string, any> | No | — | Additional fields merged into the payload on submit. |
| clearOnSubmit | boolean | No | true | Resets the form after a successful submit. |
| onChange | (formData: Record<string, any>) => void | No | — | Fires on every field change with the current form state. |
| onSave | (formData: Record<string, any>) => void | No | — | Called instead of the API when no savePath is provided. |
| onSaveSuccess | (response: any) => void | No | — | Called after a successful API save in submit mode. |
| onSaveError | (error: any) => void | No | — | Called after a failed API save in submit mode. |
| onCreateSuccess | (response: any) => void | No | — | Called after a successful save in create mode. |
| onCreateError | (error: any) => void | No | — | Called after a failed save in create mode. |
| onEditSuccess | (response: any) => void | No | — | Called after a successful save in globalEdit mode. |
| onEditError | (error: any) => void | No | — | Called after a failed save in globalEdit mode. |
| onFieldEditSuccess | (field, value, newData, oldData) => void | No | — | Called when an inline field edit succeeds. |
| onFieldEditError | (field, error) => void | No | — | Called when an inline field edit fails. |
| hasSendButton | boolean | No | true | Shows or hides the submit button. |
| sendButtonTitle | string | No | mode-dependent | Custom label for the submit button. |
| sendButtonType | 'clear' \| 'outline' \| 'solid' | No | 'solid' | Visual style of the submit button. |
| sendButtonSize | 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' | No | 'md' | Size of the submit button. |
| sendButtonColor | string | No | 'primary' | Color of the submit button. |
| sendButtonIcon | string | No | — | Icon name on the submit button. |
| sendButtonStyle | React.CSSProperties | No | — | Inline styles for the submit button. |
| sendButtonWrapperStyle | React.CSSProperties | No | — | Inline styles for the submit button wrapper. |
| containerStyle | React.CSSProperties | No | — | Inline styles for the form container. |
| bodyStyle | React.CSSProperties | No | — | Inline styles for the fields area. |
| headerStyle | React.CSSProperties | No | — | Inline styles for the title header. |
| titleStyle | React.CSSProperties | No | — | Inline styles for the title text. |
| fieldContainerStyle | React.CSSProperties | No | — | Inline styles applied to every field wrapper. |
| fieldLabelStyle | React.CSSProperties | No | — | Inline styles for field labels. |
| className | string | No | — | CSS class name for the <form> element. |
| id | string | No | — | HTML id attribute for the <form> element. |
Field shape
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| name | string | Yes | Field key in the form values object. Supports dot notation for nested values. |
| type | string | Yes | Field type (e.g. 'text', 'radio', 'checkbox', 'date', 'integer', 'decimal', 'money', 'picker', 'autocomplete', 'list', 'images', 'grid', 'iconPicker', etc.). |
| label | string | No | Human-readable label shown above the field. |
| value | any | No | Initial value (used when no data or fetchPath is provided). |
| config | object | No | Field-specific configuration (see below). |
Common field config options
| Option | Type | Description |
|--------|------|-------------|
| defaultValue | any | Default value used on initialization and after clear. |
| colSpan | number | Column span out of 12 (responsive grid). |
| showIf | string | Expression evaluated against form values; field is hidden when falsy. |
| showInModes | string[] | List of modes in which the field is visible. Defaults to all modes. |
| hidden | boolean | Hides the field wrapper without unmounting it. |
| clearOnSubmit | boolean | Per-field override for clearOnSubmit. |
| validations | object | Validation rules (e.g. maxItems). |
Ref API (DynamicFormRef)
| Method | Description |
|--------|-------------|
| clearForm() | Clears all clearable fields to their defaults. |
| resetForm() | Resets the form to its original initial values. |
| getFormValues() | Returns the current form values object. |
| setFormValues(values) | Programmatically sets the form values. |
Usage
Basic create form
import DynamicForm from '@/components/DynamicForm/DynamicForm';
const fields = [
{ name: 'name', type: 'text', label: 'Product Name' },
{ name: 'price', type: 'money', label: 'Price' },
{ name: 'category', type: 'radio', label: 'Category', config: {
options: [
{ label: 'Electronics', value: 'electronics' },
{ label: 'Clothing', value: 'clothing' },
],
}},
];
export default function Example() {
return (
<DynamicForm
fields={fields}
mode="create"
savePath="/v1/products"
saveMethod="POST"
onCreateSuccess={(res) => console.log('Created:', res)}
onCreateError={(err) => console.error(err)}
/>
);
}
Edit form with ref
import { useRef } from 'react';
import DynamicForm, { DynamicFormRef } from '@/components/DynamicForm/DynamicForm';
const fields = [
{ name: 'name', type: 'text', label: 'Name' },
{ name: 'email', type: 'text', label: 'Email' },
];
export default function Example() {
const formRef = useRef<DynamicFormRef>(null);
return (
<>
<DynamicForm
ref={formRef}
fields={fields}
mode="globalEdit"
fetchPath="/v1/users/1"
savePath="/v1/users/1"
saveMethod="PUT"
onEditSuccess={() => console.log('Saved')}
/>
<button onClick={() => console.log(formRef.current?.getFormValues())}>
Log values
</button>
</>
);
}