API — driven-form
Pure JavaScript — no React. Import these from driven-form.
Functions
Section titled “Functions”calculateFieldDependencies
Section titled “calculateFieldDependencies”calculateFieldDependencies(field: Partial<FieldData> | null | undefined): FieldDependenciesCompute which fields a given field depends on for each expression type. All arrays are deduplicated.
Uses normalised property names (post-schemaParser): show, required, disabled, calculateValue, minLength, maxLength
| Parameter | Type | Description |
|---|---|---|
field | Partial<FieldData> | null | undefined |
clearASTCache
Section titled “clearASTCache”clearASTCache(): voidClear the AST cache — useful in tests to ensure fresh parsing
clearMemoizedData
Section titled “clearMemoizedData”clearMemoizedData(): voidClear memoized parse results — useful in tests
computeFieldLifecycle
Section titled “computeFieldLifecycle”computeFieldLifecycle(field: Partial<FieldData>, data: FormData, fieldDetailMap: FieldDetailMap): FieldLifecycleState| Parameter | Type | Description |
|---|---|---|
field | Partial<FieldData> | |
data | FormData | |
fieldDetailMap | FieldDetailMap |
computeIsDisabled
Section titled “computeIsDisabled”computeIsDisabled(disabled: string | boolean | undefined, data: FormData, fieldDetailMap: FieldDetailMap): booleanEvaluate a disabled condition.
| Parameter | Type | Description |
|---|---|---|
disabled | string | boolean | undefined | boolean (static) or expression string (conditional) |
data | FormData | Current form data |
fieldDetailMap | FieldDetailMap |
computeIsRequired
Section titled “computeIsRequired”computeIsRequired(required: string | boolean | undefined, data: FormData, fieldDetailMap: FieldDetailMap): booleanEvaluate a required condition.
| Parameter | Type | Description |
|---|---|---|
required | string | boolean | undefined | boolean (static) or expression string (conditional) |
data | FormData | Current form data |
fieldDetailMap | FieldDetailMap |
computeIsShow
Section titled “computeIsShow”computeIsShow(show: string | undefined, data: FormData, fieldDetailMap: FieldDetailMap): booleanEvaluate a show expression.
| Parameter | Type | Description |
|---|---|---|
show | string | undefined | Expression string, boolean, or undefined |
data | FormData | Current form data |
fieldDetailMap | FieldDetailMap | Field configs (for date-type coercion in expressions) |
computeStepStateValue
Section titled “computeStepStateValue”computeStepStateValue(fieldValue: unknown, isRequired: boolean, isMasked: boolean, originalValue: unknown): unknownCompute whether a field is “satisfied” for step progress tracking.
A field is satisfied when:
- It has a value, OR
- It’s not required
Special case: masked fields compare against their original value (showing ”***” should still count as filled).
| Parameter | Type | Description |
|---|---|---|
fieldValue | unknown | Current field value |
isRequired | boolean | Whether the field is currently required |
isMasked | boolean | Whether the value is displayed as masked (e.g. ***) |
originalValue | unknown | The original unmasked value (used when isMasked is true) |
createValidatorRegistry
Section titled “createValidatorRegistry”createValidatorRegistry(): ValidatorRegistryCreate a new validator registry pre-loaded with built-in validators.
Custom validators shadow built-ins when registered with the same name.
extractDependencyData
Section titled “extractDependencyData”extractDependencyData(dependencies: string[], data: FormData): FormDataSlice form data to only the fields a given field depends on. Pass this slice as dependencyData to field components so re-renders are limited to actual dependency changes.
| Parameter | Type | Description |
|---|---|---|
dependencies | string[] | Array of field names (usually FieldDependencies.all) |
data | FormData | Current full form data |
getCalculatedValue
Section titled “getCalculatedValue”getCalculatedValue(calculateValue: string | undefined, data: FormData, fieldDetailMap: FieldDetailMap): unknownEvaluate a calculateValue expression. Returns undefined if no expression is configured.
| Parameter | Type | Description |
|---|---|---|
calculateValue | string | undefined | Expression string, e.g. “%price% * %quantity%” |
data | FormData | Current form data |
fieldDetailMap | FieldDetailMap |
getClearedValue
Section titled “getClearedValue”getClearedValue(fieldValue: unknown): unknownThe empty value a hidden field is reset to. Arrays keep their shape ([]) so multi-select components that map over the value don’t receive a string; everything else clears to ”.
| Parameter | Type | Description |
|---|---|---|
fieldValue | unknown |
getExpressionFunction
Section titled “getExpressionFunction”getExpressionFunction(name: string): ExpressionFunction | undefinedResolve a callable for the evaluator: consumer registrations shadow built-ins.
| Parameter | Type | Description |
|---|---|---|
name | string |
isContainerNode
Section titled “isContainerNode”isContainerNode(node: FieldData): booleanTrue if this node is a container (has children) rather than a leaf input
| Parameter | Type | Description |
|---|---|---|
node | FieldData |
isDebugMode
Section titled “isDebugMode”isDebugMode(): booleanisEmptyValue
Section titled “isEmptyValue”isEmptyValue(value: unknown): booleanThe engine-wide definition of “no value”: ” | null | undefined | []. Used by the required check and by hide-clearing. Note that 0 and false ARE values — a filled number/boolean field is not empty.
| Parameter | Type | Description |
|---|---|---|
value | unknown |
parseExpression
Section titled “parseExpression”parseExpression(expression: string | null | undefined, data: FormData, fieldDetailMap: FieldDetailMap, options: ParseExpressionOptions): unknownEvaluate a %fieldName%-style expression string using current form data.
Steps:
- Extract %fieldName% tokens
- Resolve each token to its value from
data(date fields get timestamp conversion) - Strip % delimiters, leaving a plain JS expression
- Evaluate via safeEvaluate with a variable map
Results are memoized per (expression, resolved-values) pair.
| Parameter | Type | Description |
|---|---|---|
expression | string | null | undefined | e.g. “%country% == ‘IN’ && %hasGST% == ‘Yes’” |
data | FormData | Current form data keyed by field name |
fieldDetailMap | FieldDetailMap | Field configs (used to detect date fields for timestamp coercion) |
options | ParseExpressionOptions | { returnIfVariableValueNull } — see ParseExpressionOptions |
parseSchema
Section titled “parseSchema”parseSchema(rawSchema: DrivenFormSchema | Record<string, unknown>): ParsedSchemaParse and normalise the schema returned by your backend API.
| Parameter | Type | Description |
|---|---|---|
rawSchema | DrivenFormSchema | Record<string, unknown> | { fields: […] } — an arbitrary container/leaf node tree. |
parseVariables
Section titled “parseVariables”parseVariables(exp: string, wrapperCh: string): string[]Extract all %fieldName% references from an expression string.
| Parameter | Type | Description |
|---|---|---|
exp | string | Expression string, e.g. “%country% == ‘IN’” |
wrapperCh | string | Delimiter character (default: ’%’) |
registerExpressionFunction
Section titled “registerExpressionFunction”registerExpressionFunction(name: string, fn: ExpressionFunction): voidRegister a function callable from schema expressions, e.g.
registerExpressionFunction('lookup', (table, key) => ...) enables
calculateValue: "lookup(%rates%, %country%)".
Re-registering a name replaces it (and invalidates memoized expression results). Registering a built-in name (sum/count/min/max/avg) shadows it. Throws on names that aren’t valid identifiers or are reserved by the evaluator (Number, String, Boolean, Math, Date, …).
| Parameter | Type | Description |
|---|---|---|
name | string | |
fn | ExpressionFunction |
safeEvaluate
Section titled “safeEvaluate”safeEvaluate(expression: string, variables: Record<string, unknown>): unknownSafely evaluate an expression string with the given variable bindings.
| Parameter | Type | Description |
|---|---|---|
expression | string | e.g. “CityId == 1 && StateId > 0” |
variables | Record<string, unknown> | e.g. { CityId: 1, StateId: 5 } |
setDebugMode
Section titled “setDebugMode”setDebugMode(enabled: boolean): void| Parameter | Type | Description |
|---|---|---|
enabled | boolean |
shouldClearDataOnHide
Section titled “shouldClearDataOnHide”shouldClearDataOnHide(isShow: unknown, fieldValue: unknown): booleanReturns true if the field’s value should be cleared on hide. A field with a value that becomes hidden should be cleared so that hidden data doesn’t pollute the submitted form state. 0 and false count as values and are cleared too.
| Parameter | Type | Description |
|---|---|---|
isShow | unknown | |
fieldValue | unknown |
unregisterExpressionFunction
Section titled “unregisterExpressionFunction”unregisterExpressionFunction(name: string): voidRemove a consumer-registered expression function. A shadowed built-in becomes reachable again. No-op for names that were never registered.
| Parameter | Type | Description |
|---|---|---|
name | string |
Classes
Section titled “Classes”DrivenFormError
Section titled “DrivenFormError”class
DrivenFormExpressionError
Section titled “DrivenFormExpressionError”class
DrivenFormSchemaError
Section titled “DrivenFormSchemaError”class
Interfaces
Section titled “Interfaces”BlockFieldContextValue
Section titled “BlockFieldContextValue”| Property | Type | Description |
|---|---|---|
dataRef? | ReadonlyRef<FormData> | Read-only live view of this scope’s data, for event-time reads. At the root this is the form’s dataRef; inside a row scope it is a getter view onto that row’s values object. Reading it does not subscribe — same contract as errorsRef. |
errorsRef | MutableRefObject<Record<string, string>> | Ref containing current errors — writable so useValidation can sync it. Fields read this without subscribing to error state. |
fieldDetailMap | FieldDetailMap | Flat map of all field configs (post-parse), keyed by field name. Stable after form load. Used by expressions that need field type info (e.g. Date fields need special handling in expression evaluation). |
focusElem? | FocusElem | Scroll (and optionally focus) a field by name |
markFieldLoaded | (fieldName: string) => void | Mark a field as loaded — its lazy component resolved, or the field was removed. Called by the inner sentinel on Suspense resolve, and by the outer sentinel’s cleanup when the field unmounts entirely. |
markFieldPending | (fieldName: string) => void | Mark a field as pending — its lazy component has not yet resolved. |
registerBlockFieldShowState | (fieldName: string, isShow: boolean) => void | Register this field’s visibility. Called by useBlockField after computing isShow from the show expression. |
registerBlockFieldStepState | (fieldName: string, value: unknown) => void | Register this field’s step state value. Step state is truthy when the field is satisfied (filled or not required). |
registerBlockFieldVALID | (fieldName: string, rules: unknown) => void | Register this field’s validation rules. Called by useBlockField on mount and when isShow/isRequired changes. Internally de-dupes by JSON-stringifying rules — safe to call on every render. |
registerFocusTarget? | (name: string, element: Element | null) => void | Register a DOM element for focus/scroll-to-error under an explicit name. Row scopes use this to register inputs under their scoped key (“directors.r3.name”) so focusElem can reach inside repeater rows. Pass null to deregister. |
scopePath? | string | The scoped-key prefix for field names registered through this context (e.g. “directors.r3” inside row r3 of a root-level repeater). Undefined/” at the root. Used by nested scopes to build their own paths. |
setErrors | Dispatch<SetStateAction<Record<string, string>>> | Directly set errors (used by fields that do their own async validation) |
stepAstateRef | RefObject<StepAState> | Ref containing current step state. Fields read this without subscribing. |
unregisterBlockFieldShowState | (fieldName: string) => void | Unregister show state. Called on unmount. |
unregisterBlockFieldStepState | (fieldName: string) => void | Unregister step state. Called when field becomes hidden or unmounts. |
unregisterBlockFieldVALID | (fieldName: string) => void | Unregister this field’s validation rules. Called by useBlockField when field becomes hidden or unmounts. |
updateData | (fieldName: string, value: unknown) => void | Update a single field’s value in form data |
validate | (fieldName: string | string[], value: unknown, options?: object) => Promise<void> | Validate a field (or list of fields) against current VALID rules |
validatorRegistry? | ValidatorRegistry | Validator registry used by useBlockField to resolve field.validation rules. Passed through from useDynamicField — consumers can register custom validators. |
VALIDRef? | RefObject<ValidRules> | Ref containing current VALID rules. Passed to validate() calls so they always use the latest rules without creating a dependency. |
valueResolversRef? | MutableRefObject<Record<string, (data: FormData) => unknown>> | Registry of value resolvers for SCOPED field names (e.g. “directors.r3.name”). A row scope registers one resolver per row field alongside its VALID rules; submit validation uses these to read values that don’t exist as flat data keys. Flat fields never appear here. |
BlockFieldFns
Section titled “BlockFieldFns”| Property | Type | Description |
|---|---|---|
registerBlockFieldShowState | (fieldName: string, isShow: boolean) => void | |
registerBlockFieldStepState | (fieldName: string, value: unknown) => void | |
registerBlockFieldVALID | (fieldName: string, rules: unknown) => void | |
stepAstateRef | RefObject<StepAState> | |
unregisterBlockFieldShowState | (fieldName: string) => void | |
unregisterBlockFieldStepState | (fieldName: string) => void | |
unregisterBlockFieldVALID | (fieldName: string) => void |
CalcGraph
Section titled “CalcGraph”Parse-time dependency graph over calculateValue fields. Built by parseSchema (see core/calcGraph.ts); consumed by updateData to settle calculated values synchronously in a single write.
| Property | Type | Description |
|---|---|---|
cyclic | string[] | Calculated fields excluded from propagation because they sit on a cycle |
dependents | Record<string, string[]> | Field name → calculated fields whose calculateValue references it |
order | string[] | All calculated fields in topological evaluation order (cyclic fields excluded) |
orderIndex | Record<string, number> | Evaluation position per calculated field (for ordering affected subsets) |
ContainerComponentProps
Section titled “ContainerComponentProps”Props every registered CONTAINER component receives.
A container groups and lays out its children — it holds no value of its own. The engine renders the children (recursively) and hands them over; the container only decides how to wrap them: card, row, tabs, accordion, etc.
Container show expressions are evaluated by the engine BEFORE the
component renders — a hidden container never mounts at all.
| Property | Type | Description |
|---|---|---|
children | ReactNode | The container’s already-rendered children — place them in your layout |
field | FieldData | The container node config (label, order, columnGrid, custom metadata…) |
index | number | Sibling index of this container within its parent (0-based) |
DrivenFormBag
Section titled “DrivenFormBag”The subset of form state and actions exposed to
| Property | Type | Description |
|---|---|---|
allFieldsLoaded | boolean | True once all lazy field components have resolved their Suspense boundaries |
data | FormData | |
errors | Record<string, string> | |
fieldRegistry | FieldRegistry | The registry passed to |
focusElem | FocusElem | Programmatically focus/scroll to a field by name |
getValues | () => FormData | |
handleContinue | () => Promise<HandleContinueResult> | |
isValidating | Record<string, boolean> | Per-field async validation in-flight status — true while a Promise is pending |
refFunc | RefFunc | |
schema | DrivenFormSchema | |
setError | (fieldName: string, message: string | null) => void | |
setErrors | Dispatch<SetStateAction<Record<string, string>>> | |
setTree | Dispatch<SetStateAction<FieldData[]>> | |
setValue | (fieldName: string, value: unknown, options?: object) => Promise<void> | |
tree | FieldData[] | |
updateData | (fieldName: string, value: unknown) => void | |
validate | (fieldName: string | string[], value: unknown, options?: object) => Promise<void> |
DrivenFormSchema
Section titled “DrivenFormSchema”The root schema returned by your backend API.
driven-form expects one active form per schema object. Multi-step forms can be implemented by fetching a new schema per step.
| Property | Type | Description |
|---|---|---|
fields | FieldSchema[] | Root node tree. Containers (nodes with fields) nest arbitrarily; leaves are inputs. |
id? | string | number | Form identifier — returned to onFormLoad callback |
FieldComponentProps
Section titled “FieldComponentProps”Props every registered field component receives from RenderDynamicFields.
The field component is responsible for:
- Calling useBlockField() internally to get isShow, isRequired, isDisabled
- Rendering nothing (or returning null) when isShow is false
- Calling onChange() with the new value when the user interacts
- Wiring refFunc to the actual DOM input element (for focus management)
- Wiring label, helpText, required, disabled to appropriate ARIA attributes
| Property | Type | Description |
|---|---|---|
columnGrid? | number | Grid column span for layout (from field.columnGrid) |
currentGridPosition? | number | Current cumulative grid position (for reducePaddingLeft/Right logic) |
dependencyData | FormData | Pre-filtered slice of form data containing only the fields this field depends on (from its show/required/disabled/calculateValue expressions). Pass this to useBlockField as dependencyData. |
field | FieldData | Normalised field config from the backend schema |
fieldError? | string | null | Current validation error for this field, if any |
fieldValue | unknown | Current value from form data |
isFieldValidating? | boolean | True while an async validator for this field is still pending. Use this to show a spinner, disable submit, etc. |
onBlur? | () => void | Call when the input loses focus. driven-form uses this to run ‘blur’-mode validators (e.g. async uniqueness checks). Wire to your input’s onBlur event. |
onChange | (value: unknown) => void | Call with the new field value when the user makes a change. driven-form handles updateData + validate internally. |
refFunc? | (element: Element | null) => void | Attach to your DOM input element to enable focus-on-error behaviour. Pass the element (or null to deregister). |
FieldData
Section titled “FieldData”A field after schemaParser normalisation.
requiredreflects the validation array (a ‘required’ rule implies true)- Date values have time component stripped
- Numeric values coerced to string for consistent validation
Note: Defined independently (not via Omit
| Property | Type | Description |
|---|---|---|
calculateValue? | string | |
columnFields? | FieldData[] | Recursive: column fields for table/repeater fields |
columnGrid? | number | |
disabled? | string | boolean | Disabled condition — boolean or expression string |
fields? | FieldData[] | Child nodes. Present = this node is a CONTAINER (groups children, holds no value). Absent = this node is a LEAF (a real input). |
helpText? | string | |
isHidden? | boolean | |
label? | string | |
name | string | Unique identifier — used as the key in form data |
options? | FieldOption[] | |
order | number | |
placeholder? | string | |
required? | string | boolean | Required condition — boolean or expression string |
show? | string | Show expression — always a string after parsing |
type | string | Field type — must match a registered type in your FieldRegistry |
validation? | ValidationRule[] | |
value? | unknown |
FieldDependencies
Section titled “FieldDependencies”| Property | Type | Description |
|---|---|---|
all | string[] | Union of all dependency categories below |
calculated | string[] | Fields referenced in calculateValue |
disabled | string[] | Fields referenced in the disabled expression |
minMax | string[] | Fields referenced in minLength / maxLength expressions (dynamic length constraints) |
required | string[] | Fields referenced in the required expression |
show | string[] | Fields referenced in the show expression |
FieldLifecycleState
Section titled “FieldLifecycleState”| Property | Type | Description |
|---|---|---|
calculatedValue | unknown | |
isDisabled | boolean | |
isRequired | boolean | |
isShow | boolean |
FieldOption
Section titled “FieldOption”A single option for dropdown / radio / multi-select fields
| Property | Type | Description |
|---|---|---|
id | string | number | Stored as the field value when selected |
label | string | Displayed to the user |
FieldRegistry
Section titled “FieldRegistry”Interface for the field type registry
| Property | Type | Description |
|---|---|---|
containerTypes | () => string[] | Returns all registered container type strings |
get | (type: string) => FieldComponent | undefined | Returns the registered leaf component, or undefined if not found |
getContainer | (type: string) => ContainerComponent | undefined | Returns the registered container component, or undefined if not found |
has | (type: string) => boolean | Returns true if a leaf component is registered for this type |
hasContainer | (type: string) => boolean | Returns true if a container component is registered for this type |
register | (type: string, component: FieldComponent) => void | Register a component for a LEAF field type. |
registerContainer | (type: string, component: ContainerComponent) => void | Register a component for a CONTAINER type (a node with fields). |
types | () => string[] | Returns all registered leaf type strings |
FieldSchema
Section titled “FieldSchema”A single field definition as received from the backend.
After parsing, this becomes FieldData (see internal.ts). Expression strings use %fieldName% syntax: “%country% == IN”
| Property | Type | Description |
|---|---|---|
calculateValue? | string | Calculated value expression. Field value is auto-derived when dependencies change. Expression: “%price% * %quantity%” |
columnFields? | FieldSchema[] | Column field definitions for composite fields (e.g. table rows). Each entry is a full FieldSchema — recursive composition. |
columnGrid? | number | Grid column span hint, e.g. 1–12 for a 12-column layout |
disabled? | string | boolean | Disabled condition. Boolean or expression string. Expression: “%isVerified% == true” |
fields? | FieldSchema[] | Child field definitions. A node with fields is a CONTAINER — it groups and lays out its children but holds no value of its own. A node without fields is a LEAF — a real input that stores a value in form data. |
helpText? | string | Helper text displayed below the field |
isHidden? | boolean | When true, field value is kept in form data but the field is never rendered. Useful for fields needed by expressions but not shown to the user. |
label? | string | Display label |
name | string | Unique identifier — used as the key in form data |
options? | FieldOption[] | Static options list |
order | number | Render order within its section (ascending) |
placeholder? | string | Placeholder text for input fields |
required? | string | boolean | Required condition. Boolean or expression string. Expression: “%companyType% == Private” |
show? | string | Show condition. If omitted, field is always shown. Expression: “%country% == IN && %hasGST% == Yes” |
type | string | Field type — must match a registered type in your FieldRegistry |
validation? | ValidationRule[] | Ordered list of validation rules applied to this field |
value? | unknown | Initial value |
OnSaveParams
Section titled “OnSaveParams”Params passed to onSave when the user submits the form
| Property | Type | Description |
|---|---|---|
data | FormData | All current field values |
fieldDetailMap | FieldDetailMap | All field configs (for building the save payload) |
schema | DrivenFormSchema | Original raw schema from the backend |
ParsedSchema
Section titled “ParsedSchema”| Property | Type | Description |
|---|---|---|
calcGraph | CalcGraph | Dependency graph for synchronous calculated-value propagation |
fieldDetailMap | FieldDetailMap | Every LEAF node’s config, keyed by name (flat) |
fieldValues | FormData | Initial values for every LEAF node, keyed by name (flat) |
tree | FieldData[] | Root node tree — containers (nodes with fields) and leaves, sorted by order at every level. |
ParseExpressionOptions
Section titled “ParseExpressionOptions”| Property | Type | Description |
|---|---|---|
returnIfVariableValueNull? | boolean | If true and any variable resolves to null, return null immediately instead of evaluating (useful for conditional-required short-circuits). |
RepeaterRowData
Section titled “RepeaterRowData”One row of a repeater, as exposed to the consumer’s component
| Property | Type | Description |
|---|---|---|
errors | Record<string, string> | This row’s validation errors, keyed by row-local field name |
id | string | Stable row identity — use as the React key; survives remove/reorder |
index | number | Current display position (0-based). Changes on reorder; id does not. |
values | FormData | This row’s values object — the same object stored in the form data array |
ResolvedValidator
Section titled “ResolvedValidator”The resolved result of looking up a validator for a field
| Property | Type | Description |
|---|---|---|
fn | ValidatorFn | |
message? | string | |
validateOn? | ValidationMode | Inherited from the schema rule — controls when this validator runs |
UseBlockFieldProps
Section titled “UseBlockFieldProps”| Property | Type | Description |
|---|---|---|
dependencyData? | FormData | Pre-filtered slice of form data — only the fields this field depends on (computed in RenderDynamicFields via fieldDependencyDataMap). |
field | FieldData | Normalised field config |
fieldError? | string | null | Current error for this field |
fieldValue | unknown | Current value of this field |
options? | object |
UseBlockFieldReturn
Section titled “UseBlockFieldReturn”| Property | Type | Description |
|---|---|---|
fieldError | string | null | undefined | Current validation error — same as fieldError prop, exposed for convenience |
isDisabled | boolean | Whether this field is disabled right now (based on disabled expression) |
isRequired | boolean | Whether this field is required right now (based on required expression) |
isShow | boolean | Whether this field should be rendered (based on show expression) |
updateData | (fieldName: string, value: unknown) => void | Direct access to updateData for fields that need custom update logic |
validate | (fieldName: string | string[], value: unknown) => void | Direct access to validate for fields that do their own validation timing |
UseDynamicFieldProps
Section titled “UseDynamicFieldProps”Input props for useDynamicField
| Property | Type | Description |
|---|---|---|
onFormLoad? | (formId: string | number | undefined) => void | Called after loadFormData processes the schema. Receives the form id from the schema — useful for multi-step forms. |
onSave | (params: OnSaveParams) => void | Called when the user submits the form after all validation passes. This is where you make your API call to save the data. |
validatorRegistry? | ValidatorRegistry | Optional custom validator registry. If not provided, a default registry with built-in validators is used. Use this to register domain-specific validators (e.g. PAN, GST number). |
UseDynamicFieldReturn
Section titled “UseDynamicFieldReturn”Everything useDynamicField returns
| Property | Type | Description |
|---|---|---|
allFieldsLoaded | boolean | True once all field components wrapped in FieldComponentSuspense have resolved. handleContinue is blocked while this is false — lazy fields that haven’t loaded yet haven’t registered their validation rules, so required checks would be skipped. Wire this to your submit button’s disabled state alongside isValidating. |
blockFieldFns | BlockFieldFns | Functions for useBlockField to register/unregister its state. Pass to RenderDynamicFields as the blockFieldFns prop. |
contextValue | BlockFieldContextValue | Pre-built context value — pass this to BlockFieldProvider so that useBlockField inside field components can access form state. |
data | FormData | All current field values keyed by field name |
errors | Record<string, string> | Current validation errors keyed by field name |
fieldDetailMap | FieldDetailMap | Flat field config map keyed by field name |
focusElem | FocusElem | Programmatically focus/scroll to a field by name |
getValues | () => FormData | Read the current form data synchronously, without subscribing to it. Prefer this over the data state inside callbacks/effects that don’t want to re-run on every keystroke (data is fine in render). |
handleContinue | () => Promise<HandleContinueResult> | The submit handler. Wire this to your form’s submit button. |
isValidating | Record<string, boolean> | Per-field async validation in-flight status. True for a field name while its async validator Promise is pending. Use this to render a spinner or disable submit. |
loadFormData | (schema: DrivenFormSchema) => void | Load the schema returned by your API. Call this after fetching the schema from your backend. |
onSubmitValidation | (options?: object) => Promise<boolean | object> | Run full-form validation — returns whether the form is valid |
refFunc | RefFunc | Attach to a DOM element to enable focus-on-error. Pass to RenderDynamicFields as the refFunc prop. |
schema | DrivenFormSchema | Raw schema as received from the backend |
setError | (fieldName: string, message: string | null) => void | Set or clear a single field’s error directly — e.g. from a server-side validation response on submit. Pass null to clear. |
setErrors | Dispatch<SetStateAction<Record<string, string>>> | Directly set errors (e.g. from server-side validation response) |
setTree | Dispatch<SetStateAction<FieldData[]>> | Directly update the node tree (e.g. for multi-step back navigation) |
setValue | (fieldName: string, value: unknown, options?: object) => Promise<void> | Set a field’s value and (by default) validate it — the same two steps a field’s own onChange performs. Pass { validate: false } to only update the value. Resolves once validation settles (or immediately if skipped) — safe to leave unawaited for fire-and-forget use. |
showField | ShowFieldState | Show/hide state keyed by field name (populated by useBlockField as fields mount) |
tree | FieldData[] | Parsed, ordered node tree. Containers (nodes with fields) nest arbitrarily; leaves are inputs. |
updateData | (fieldName: string, value: unknown) => void | Manually update a single field value. Normally called via the onChange prop passed to field components. |
validate | (fieldName: string | string[], value: unknown, options?: object) => Promise<void> | Validate a single field (or array of fields) |
VALIDRef | MutableRefObject<ValidRules> | Stable ref to VALID rules — passed through to validate calls |
UseRepeaterFieldProps
Section titled “UseRepeaterFieldProps”| Property | Type | Description |
|---|---|---|
dependencyData? | FormData | Dependency slice from the parent renderer. Includes any form-level fields the row template references (hoisted automatically), which the rows resolve via fallback. |
field | FieldData | The repeater field config (must have columnFields as the row template) |
fieldError? | string | null | Error for the repeater itself (repeater-level validators) |
fieldValue | unknown | Current field value — the rows array (or undefined before seeding) |
UseRepeaterFieldReturn
Section titled “UseRepeaterFieldReturn”| Property | Type | Description |
|---|---|---|
addRow | (initialValues?: FormData) => void | Append a row (optionally pre-filled). No-ops at maxRows. |
canAddRow | boolean | False when maxRows is reached — wire to the add button’s disabled |
canRemoveRow | boolean | False when minRows is reached — wire to remove buttons’ disabled |
externalDeps | FormData | Form-level values the rows fall back to — RepeaterRow merges these under row values |
fieldError | string | null | Repeater-level error (e.g. a whole-array validator’s message) |
getRowScope | (rowId: string) => BlockFieldContextValue | Scoped context for a row — stable per row id for the row’s lifetime |
isDisabled | boolean | |
isRequired | boolean | |
isShow | boolean | |
moveRow | (rowId: string, toIndex: number) => void | Move a row to a new index. Errors and identity travel with the row. |
removeRow | (rowId: string) => void | Remove a row by id (also clears its errors). No-ops at minRows. |
rows | RepeaterRowData[] | Ordered rows — render each through RepeaterRow with key={row.id} |
rowTemplate | FieldData[] | Row template (sorted columnFields) — RepeaterRow renders this |
ValidationRule
Section titled “ValidationRule”A single validation rule attached to a field.
Built-in names: “required” | “minLength” | “maxLength” | “min” | “max” | “email” | “url” | “pattern” Custom names: any string you register via the validator registry
| Property | Type | Description |
|---|---|---|
message? | string | Error message shown when this rule fails |
name | string | Rule identifier — matches a built-in or a registered custom validator |
validateOn? | ValidationMode | When this rule is evaluated. Defaults to ‘change’. Set to ‘blur’ for async validators to avoid firing on every keystroke. Set to ‘submit’ for expensive checks that only need to run on form submission. |
value? | unknown | Argument for parameterised validators (e.g. minLength: 3) |
ValidatorRegistry
Section titled “ValidatorRegistry”Interface for the validator registry
| Property | Type | Description |
|---|---|---|
has | (name: string) => boolean | Returns true if a validator is registered for this name |
register | (name: string, validator: ValidatorEntry) => void | Register a custom validator by name. If the validator needs a parameter (e.g. minLength), pass a factory. |
resolve | (rule: object) => ResolvedValidator | null | Resolve a validation rule to a { fn, message, validateOn } triple. Returns null if no validator found for the name. |
Type aliases
Section titled “Type aliases”ContainerComponent
Section titled “ContainerComponent”type ContainerComponent = ComponentType<ContainerComponentProps>A React component that can be registered as a container type
DrivenFormErrorCode
Section titled “DrivenFormErrorCode”type DrivenFormErrorCode = 'EXPRESSION_PARSE_ERROR' | 'EXPRESSION_EVAL_ERROR' | 'SCHEMA_VALIDATION_ERROR' | 'DUPLICATE_FIELD_NAME' | 'CIRCULAR_DEPENDENCY' | 'UNREGISTERED_FIELD_TYPE' | 'UNREGISTERED_VALIDATOR'errors.ts — Typed error classes
All driven-form errors have a code property for programmatic handling.
ExpressionFunction
Section titled “ExpressionFunction”type ExpressionFunction = (...args: unknown[]) => unknownA function callable from schema expressions. Must be pure and synchronous.
FieldComponent
Section titled “FieldComponent”type FieldComponent = ComponentType<FieldComponentProps>A React component that can be registered as a field type
FieldDetailMap
Section titled “FieldDetailMap”type FieldDetailMap = Record<string, FieldData>All parsed field configs, keyed by field name
FocusElem
Section titled “FocusElem”type FocusElem = (fieldName: string, options?: object) => voidScroll to (and optionally focus) a field by name. Used by validation to jump to the first error field on submit.
FormData
Section titled “FormData”type FormData = Record<string, unknown>All current field values, keyed by field name
HandleContinueResult
Section titled “HandleContinueResult”type HandleContinueResult = object | object | objectDiscriminated result of handleContinue — says what happened so consumers can react (show a toast, log, retry) instead of guessing from silence.
- ‘saved’ — validation passed and onSave was called
- ‘blocked’ — submit refused;
reason: 'fields-loading'means lazy field components haven’t resolved yet, so their validation rules aren’t registered (watchallFieldsLoadedto disable the button instead) - ‘validation-failed’ — one or more fields failed;
errorsis keyed by field name
ParseExpressionFn
Section titled “ParseExpressionFn”type ParseExpressionFn = (expression: string | null | undefined, data: FormData, fieldDetailMap?: FieldDetailMap, options?: ParseExpressionOptions) => unknownRefFunc
Section titled “RefFunc”type RefFunc = (element: Element | null) => voidAttach a DOM element to the multi-ref manager. Pass null to deregister (standard ref callback pattern).
RequireKeys
Section titled “RequireKeys”type RequireKeys = T & Required<Pick<T, K>>Make specific keys of T required
ShowFieldState
Section titled “ShowFieldState”type ShowFieldState = Record<string, boolean>Show/hide state per field name (false = hidden, true or undefined = shown)
StepAState
Section titled “StepAState”type StepAState = Record<string, unknown>Step/fill state per field name. Truthy = field is satisfied (filled or not required). Used by onSubmitValidation to determine overall form validity.
UnregisteredFieldBehaviour
Section titled “UnregisteredFieldBehaviour”type UnregisteredFieldBehaviour = 'warn' | 'throw' | 'silent' | 'custom'What to do when RenderDynamicFields encounters an unregistered field type
ValidationMode
Section titled “ValidationMode”type ValidationMode = 'change' | 'blur' | 'submit'When a validation rule is evaluated.
- ‘change’ (default) — on every value change. Use for cheap sync checks (required, format).
- ‘blur’ — when the user leaves the field. Use for async checks (server uniqueness).
- ‘submit’ — only when the form is submitted. Use for expensive or final server checks.
On submit, ALL rules run regardless of their validateOn setting. On blur, ‘change’ and ‘blur’ rules run. On change, only ‘change’ rules run.
ValidatorEntry
Section titled “ValidatorEntry”type ValidatorEntry = ValidatorFn | ValidatorFactoryEither a direct validator or a factory (for parameterised rules)
ValidatorFactory
Section titled “ValidatorFactory”type ValidatorFactory = (ruleValue: unknown) => ValidatorFnA parameterised validator factory.
Called with the rule’s value from the schema, returns a ValidatorFn.
Example: minLength factory is called with 3, returns a validator that checks value.length >= 3.
ValidatorFn
Section titled “ValidatorFn”type ValidatorFn = (value: unknown, formData?: FormData, field?: FieldData) => string | null | undefined | Promise<string | null | undefined>A validator function. Returns an error message string if invalid, null/undefined if valid. Can return a Promise for async validation (e.g. server-side uniqueness checks).
ValidRules
Section titled “ValidRules”type ValidRules = Record<string, unknown>Validation rules per field name. Populated by useBlockField as fields mount, cleared as they unmount.
Values
Section titled “Values”type Values = T[keyof T]Extract value types from a const object
Variables
Section titled “Variables”BUILT_IN_VALIDATORS
Section titled “BUILT_IN_VALIDATORS”const