All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
submit()Method: Added a propersubmit()method toFormInstance. Previously it wasundefinedwhen noonSubmitoption was provided, causing a runtime error on invocation. Now it is always a callable function — validates the form and, if anonSubmithandler is configured, proceeds to call it. Also added JSDoc and API reference documentation.
- Form Submission Raw Data: The
onSubmit/handleSubmitvalidation callback now passes native browserraw: FormDataas the 3rd parameter, facilitating file uploads and custom FormData processing. - Form Busy State: Added a new public
busyproperty toFormInstancethat indicates whether the form is currently submitting or validating (isSubmitting || isValidating). - Batch Array Removal: Extended the form array helper
remove()to accept either a single indexnumberor an array of indicesnumber[]to delete multiple elements in a single batch update with correct index shifting. - Reset Options: Added configuration options support to the
reset(opts?: { ignoreDefaults?: boolean })helper, allowing developers to reset form values while ignoring default values if specified.
- Async Validation Signature (Breaking):
- Renamed the async validation callback configuration property from
validatetofn. - Changed the callback parameters to
fn: (value, formValues) => Promise<string | undefined | null>(passing the full form values instead of only the previous field value), enabling async validations that depend on other form fields.
- Renamed the async validation callback configuration property from
- Type Safety:
- Corrected
ArrayItemtypescript helper to resolve index types properly for readonly arrays.
- Corrected
- DevTools Production Optimization: Configured DevTools floating inspector to automatically render as
nullin production environments, except when the explicit environment variableNEXT_PUBLIC_IS_EXAMPLES === "true"is set.
- DevTools Boundary Control: Added the
devToolsBoundaryoption to<Form>component to easily restrict the DevTools floating panel inside the viewport or its parent container. - Form Schema Exposure: Exposed the current
schemagetter on both theFormInstanceobject and the returned object of theuseFormByIdhook. - Type Enhancements: Added
isTouchedto the public TypeScript type definition of the form instance.
- DevTools Path Typo: Corrected internal folder name typo from
devtoostodevtoolsand refactored all internal imports/exports accordingly. - Label Nesting Prevention: Improved the
<Label>component to automatically detect nested label elements and dynamically render as aspanor use a customizable tag with theasprop, avoiding invalid nested<label>structures. - Form Registry Safekeeping: Safely unsubscribe and clear references from the global
FormRegistryduring component unmounting, matching only active instance IDs to prevent accidental cleanup of subsequent form renders. - Drafts LocalStorage Safety: Wrapped localStorage operations with try-catch blocks to prevent runtime crashes in iframe contexts or restricted browser settings.
- Interactive DevTools Inspector: Added a zero-setup, floating interactive DevTools inspector that automatically mounts inside development environments. Includes:
- Live nested value tree viewer and copy helper.
- Live patch diffing payload representation (
getChanges()). - Active validation errors, flat dirty path lists, touched trackers, metadata map, and dropdown loading states.
- Interactive Action Panel to manually trigger validations, resets, step routing, or state overrides.
- Footer toolbar with direct links to the Live Demos & Playground (formly.explita.ng), npm package page, and GitHub repository.
- Cascading Dropdowns (
cascade): Declarative selector relationships that automatically fetch and options-bind choices upon dependency updates with full TypeScript autocompletion. - Accidental Navigation Prevention (
preventUnload): Option to automatically block page reloads, tab closures, and accidental browser route changes when the form has unsaved/dirty state. - Input Normalization & Auto-Formatters (
normalize): Real-time value sanitization and formatting directly on user keystrokes (e.g. UPPERCASING, phone digit formatting, spacing, etc.). - Precise Delta Tracking (
getChanges): Helper to extract and submit only modified fields compared to the initial payload, keeping API requests lightweight. - Wizard & Multi-Step Forms (
steps): Multi-step configuration with native step-by-step layout tracking, step-level schema/custom validation, and navigation utilities (nextStep,prevStep,currentStep, etc.). - Auto-Keyed Dynamic Arrays: Automatically generated parallel persistent unique keys (
keysarray) to avoid rendering bugs and enable smooth animation list transitions. - Live Playground: Configured and deployed the examples website to formly.explita.ng and linked it in the documentation.
- Optional Zod Support: Marked
zodas an optional peer dependency, allowing developer setups to run without schema validations if desired.
- React 19 StrictMode warnings: Resolved "Cannot update component while rendering" errors in FormRegistry by deferring state updates with
setTimeout - Computed field double-renders: Fixed redundant initial render cycles during dependency subscription setup
- Zod to optional peer dependency - Reduces bundle size for non-Zod users
- FormRegistry state updates - Deferred to macro-task queue for React 19 compat
- Accessibility & Testing: Added
data-errorattribute toFieldErrorcomponent to improve semantic structure and facilitate testing.
- Improved computed fields initialization to ensure dependency tracking is established correctly during the first render.
- Refined draft restoration logic when
persistKeyis provided.
- Internal Improvements: Refined form state initialization and update logic for better stability.
- Type Safety: Improved type-safety for nested paths and form value access.
- Maintenance: Updated internal dependencies and cleaned up unused code.
- Field Arrays: Full support for dynamic lists with a comprehensive API (
push,insert,remove,swap,move,moveUp,moveDown, etc.). - Form persistence (Drafts): Built-in support for saving and restoring form progress locally using
persistKey. - Computed Fields: Support for fields that derive their value from other fields, including wildcard support for arrays (
array.*.field). - Form Registry: Ability to access and control any form instance globally by its unique ID.
- Improved Performance: Switched to a flat-state internal representation with precise pub/sub notifications to minimize re-renders.
- Deep Path Utilities: Enhanced handling of nested objects and arrays in form state.
- Refactored internal state Management for better scalability and performance.
- Simplified
useForminitialization logic.
- Initial maintenance and stabilization improvements.
- Initial release of
@explita/formly. - Core Hooks:
useForm: Core hook for form state management, validation, and submission.useField: Hook for managing individual field state and interactions.useFormContext: Hook for accessing form state within theFormprovider.useFormById: Utility hook to access a form instance globally by its ID.
- Components:
Form: Provider component for the form context.Field: Declarative component for field management.FieldError: Component for displaying field validation messages.FormSpy: Component to monitor form state changes without triggering global re-renders.Label: Accessible label component integrated with form field state.
- Validation:
- First-class support for
zodschema validation.
- First-class support for
- Features:
- Support for complex, nested data structures.
- Optimized performance through precise subscription-based updates.
- Fully type-safe API for form values, errors, and handlers.