/v1.0

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>
    </>
  );
}