A flexible and extensible form-rendering React component powered by a JSON configuration. Built with TypeScript and Material UI, it supports nested fields, conditional rendering, and dynamic data loading.
⚙️ Built with React, TypeScript, and MUI (v5)
📦 Ideal for internal tools, admin panels, and dashboards
npm install react-dynoform
# or
yarn add react-dynoform
import React from 'react';
import DynamicForm, { FormField } from 'react-dynoform';
const formFields: FormField[] = [
{
key: 'name',
label: 'Name',
type: 'text',
required: true,
},
{
key: 'subscribe',
label: 'Subscribe to newsletter',
type: 'checkbox',
},
{
key: 'dob',
label: 'Date of Birth',
type: 'date',
},
{
key: 'gender',
label: 'Gender',
type: 'radio',
options: [
{ label: 'Male', value: 'male' },
{ label: 'Female', value: 'female' },
],
},
];
export default function App() {
return (
<DynamicForm
fields={formFields}
onSubmit={(data) => console.log('Submitted:', data)}
/>
);
}
- ✅ Supports
text
,select
,checkbox
,radio
,date
,array
,hidden
- 📚 Nested forms (
type: 'array'
) with collapsible sections - ⚡ Dynamic
select
options from API (loadOptionsApi
) - 🎯 Conditional rendering via
dependsOn
andshowIf
- 🔄 Bi-directional data mapping (
mapTo
,mapFrom
,doNotMap
) - 🔐 Full support for validation and controlled components
- 🧪 Type-safe props with TypeScript
interface FormField {
key: string;
label: string;
type?: "text" | "checkbox" | "radio" | "select" | "hidden" | "date" | "array";
nestedFields?: FormField[];
options?: { label: string; value: string }[] | ((formData: Record<string, any>) => { label: string; value: string }[]);
defaultValue?: any;
disabled?: boolean;
required?: boolean;
dependsOn?: string;
showIf?: string; // "*" for any value, or comma-separated values
mapTo?: string;
doNotMap?: boolean;
mapFrom?: string;
valueType?: "string" | "number" | "boolean" | "date" | "json" | "jsonString" | "array";
}
Prop | Type | Description |
---|---|---|
fields |
FormField[] |
Configuration array |
disabled? |
boolean |
Disables all inputs |
selectedValues? |
Record<string, any> |
Pre-filled values |
submitButtonLabel? |
string |
Custom submit label |
hideSubmit? |
boolean |
Hide the submit button |
onChange? |
(data: Record<string, any>) => void |
Called on any change |
onSubmit? |
(data: Record<string, any>) => void |
Called on submit |
onRemove? |
(data: Record<string, any>) => void |
Called when delete is clicked |
text
: Single-line text inputcheckbox
: Boolean checkboxradio
: Select one from multiple optionsselect
: Dropdown with options or async API loadingdate
: MUI-compatible date pickerhidden
: Hidden input for internal valuesarray
: Nested and repeatable field sets
You can make fields appear based on another field's value using:
dependsOn
: key of the controlling fieldshowIf
: comma-separated list of values to match (*
= any value)
Example:
{
key: "state",
label: "State",
type: "text",
dependsOn: "country",
showIf: "USA,Canada"
}
Clone locally:
git clone https://github.com/your-org/dynafield.git
cd dynafield
npm install
Build for production:
npm run build
MIT © 2025 Prashanth Molakala