mui-smart-form-builder
Version:
A reusable React component for dynamically rendering MUI forms from JSON configuration with Formik integration
400 lines (331 loc) ⢠11.3 kB
Markdown
# MUI Smart Form Builder
A powerful and flexible React component for dynamically rendering Material-UI forms from JSON configuration with Formik integration.
[](https://codesandbox.io/s/github/deepu9990/mui-smart-form-builder/tree/main/demo)
[](https://deepu9990.github.io/mui-smart-form-builder/)
[](https://www.npmjs.com/package/mui-smart-form-builder)
[](https://opensource.org/licenses/MIT)
## Features
- šÆ **Formik Integration**: Seamless integration with Formik for form state management
- šØ **Material-UI Components**: Built with MUI components for consistent design
- š± **Responsive Layout**: Grid-based responsive layout system
- š§ **Flexible Configuration**: JSON-driven form configuration
- š **Custom Rendering**: Support for custom field renderers
- š **Dynamic Search**: Autocomplete fields with async search capabilities
- š **Rich Field Types**: Support for 15+ field types
- šŖ **TypeScript**: Full TypeScript support with comprehensive types
- š³ **Tree Shakeable**: Optimized for tree shaking
## Installation
```bash
npm install mui-smart-form-builder
```
### Peer Dependencies
```bash
npm install @mui/material @emotion/react @emotion/styled formik
```
### Optional Dependencies (for date/time fields)
```bash
npm install @mui/x-date-pickers dayjs
```
> **Note**: When using date/time fields, you must wrap your app with `LocalizationProvider`:
```tsx
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
<LocalizationProvider dateAdapter={AdapterDayjs}>
<YourApp />
</LocalizationProvider>
```
```bash
npm install mui-smart-form-builder
# Peer dependencies (if not already installed)
npm install react react-dom @mui/material @emotion/react @emotion/styled formik
```
For date/time pickers, also install:
```bash
npm install @mui/x-date-pickers dayjs
```
## Quick Start
```tsx
import React from 'react';
import { useFormik } from 'formik';
import { SmartFormBuilder } from 'mui-smart-form-builder';
const MyForm = () => {
const formik = useFormik({
initialValues: {
firstName: '',
lastName: '',
email: '',
age: 0,
gender: '',
newsletter: false
},
onSubmit: (values) => {
console.log('Form submitted:', values);
}
});
const fields = [
{
name: 'firstName',
label: 'First Name',
type: 'text',
required: true,
grid: { xs: 12, md: 6 }
},
{
name: 'lastName',
label: 'Last Name',
type: 'text',
required: true,
grid: { xs: 12, md: 6 }
},
{
name: 'email',
label: 'Email',
type: 'text',
placeholder: 'Enter your email',
grid: { xs: 12 }
},
{
name: 'age',
label: 'Age',
type: 'number',
min: 0,
max: 120,
grid: { xs: 12, md: 6 }
},
{
name: 'gender',
label: 'Gender',
type: 'radio',
options: [
{ label: 'Male', value: 'M' },
{ label: 'Female', value: 'F' },
{ label: 'Other', value: 'O' }
],
grid: { xs: 12, md: 6 }
},
{
name: 'newsletter',
label: 'Subscribe to newsletter',
type: 'checkbox',
grid: { xs: 12 }
}
];
const buttons = [
{
label: 'Reset',
variant: 'outlined',
onClick: (formik) => formik.resetForm()
},
{
label: 'Submit',
variant: 'contained',
type: 'submit'
}
];
return (
<SmartFormBuilder
formik={formik}
title="User Registration Form"
fields={fields}
buttons={buttons}
gridSpacing={2}
/>
);
};
export default MyForm;
```
## Supported Field Types
### Text Fields
- `text` - Standard text input
- `textarea` - Multi-line text input
- `number` - Numeric input with min/max/step support
- `password` - Password input
### Selection Fields
- `checkbox` - Single checkbox
- `multiCheckbox` - Multiple checkboxes
- `radio` - Radio button group
- `select` - Dropdown select (single/multiple)
- `autocomplete` - Autocomplete with async search
### Date/Time Fields
- `date` - Date picker
- `time` - Time picker
- `dateTime` - Date and time picker
### Interactive Fields
- `switch` - Toggle switch
- `slider` - Range slider
- `file` - File upload
### Layout
- `empty` - Empty space for layout purposes
## API Reference
### SmartFormBuilderProps
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `formik` | `FormikProps<any>` | ā
| Formik instance |
| `fields` | `FieldConfig[]` | ā
| Array of field configurations |
| `buttons` | `ButtonConfig[]` | ā | Form buttons configuration |
| `title` | `string` | ā | Form title |
| `className` | `string` | ā | CSS class name |
| `sx` | `SxProps` | ā | MUI sx prop for styling |
| `gridSpacing` | `number` | ā | Grid spacing (default: 2) |
### FieldConfig
| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `name` | `string` | ā | Field name (formik key) |
| `label` | `string` | ā | Field label |
| `type` | `FieldType` | ā
| Field type |
| `placeholder` | `string` | ā | Placeholder text |
| `options` | `FieldOption[]` or `string[]` | ā | Options for select/radio/checkbox |
| `grid` | `GridBreakpoint` | ā | Grid responsive breakpoints |
| `required` | `boolean` | ā | Required field validation |
| `variant` | `'outlined'` \| `'filled'` \| `'standard'` | ā | MUI variant |
| `muiProps` | `Record<string, any>` | ā | Additional MUI props |
| `onChange` | `(value: any, formik: FormikProps) => void` | ā | Custom change handler |
| `onSearch` | `(searchTerm: string) => Promise<FieldOption[]>` | ā | Async search for autocomplete |
| `render` | `(props) => ReactNode` | ā | Custom render function |
#### Field-specific Properties
| Property | Applicable Types | Description |
|----------|------------------|-------------|
| `min`, `max`, `step` | `number`, `slider` | Numeric constraints |
| `marks` | `slider` | Show marks on slider |
| `freeSolo` | `autocomplete` | Allow free text input |
| `multiple` | `select`, `autocomplete` | Multiple selection |
| `accept` | `file` | File type filter |
### ButtonConfig
| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `label` | `string` | ā
| Button text |
| `variant` | `'text'` \| `'outlined'` \| `'contained'` | ā | Button variant |
| `color` | MUI color | ā | Button color |
| `type` | `'submit'` \| `'button'` \| `'reset'` | ā | Button type |
| `onClick` | `(formik: FormikProps) => void` | ā | Click handler |
| `muiProps` | `Record<string, any>` | ā | Additional MUI props |
## Advanced Usage
### Custom Field Rendering
```tsx
const customField = {
name: 'customField',
type: 'text',
render: ({ fieldProps, formik }) => (
<CustomComponent
{...fieldProps}
onCustomAction={() => {
// Custom logic
formik.setFieldValue('customField', 'new value');
}}
/>
)
};
```
### Async Autocomplete
```tsx
const asyncAutocomplete = {
name: 'skills',
label: 'Skills',
type: 'autocomplete',
freeSolo: true,
multiple: true,
onSearch: async (searchTerm) => {
const response = await fetch(`/api/skills?q=${searchTerm}`);
const data = await response.json();
return data.map(skill => ({ label: skill.name, value: skill.id }));
}
};
```
### Dynamic Field Updates
```tsx
const conditionalField = {
name: 'country',
label: 'Country',
type: 'select',
options: countries,
onChange: (value, formik) => {
// Reset state field when country changes
formik.setFieldValue('state', '');
// Fetch states for selected country
fetchStates(value).then(states => {
// Update form configuration dynamically
});
}
};
```
## Validation
The component works seamlessly with Formik's validation. You can use Yup schema or custom validation:
```tsx
import * as Yup from 'yup';
const validationSchema = Yup.object({
firstName: Yup.string().required('First name is required'),
email: Yup.string().email('Invalid email').required('Email is required'),
age: Yup.number().min(18, 'Must be at least 18').required()
});
const formik = useFormik({
initialValues,
validationSchema,
onSubmit: handleSubmit
});
```
## Styling
### Global Styling
```tsx
<SmartFormBuilder
formik={formik}
fields={fields}
sx={{
'& .MuiTextField-root': {
marginBottom: 2
},
'& .MuiFormControl-root': {
width: '100%'
}
}}
/>
```
### Per-field Styling
```tsx
const styledField = {
name: 'specialField',
type: 'text',
muiProps: {
sx: {
backgroundColor: 'primary.light',
'& .MuiInputBase-root': {
borderRadius: 2
}
}
}
};
```
## Examples
See the `/demo` folder for a complete example application showcasing all features.
## Changelog
### [1.0.2] - 2025-08-10
- **BREAKING**: Moved `@mui/x-date-pickers` and `dayjs` from dependencies to peer dependencies
- **BREAKING**: Removed internal `LocalizationProvider` wrapper - consumers must now provide it
- Updated documentation with LocalizationProvider setup requirements
- Fixed build configuration to properly exclude peer dependencies
- Added custom icon for demo application
- Improved GitHub Pages deployment configuration
### [1.0.1] - 2025-08-09
- Cleaned up build outputs from version control
- Added `.gitignore` for `dist/` directory
- Improved rollup configuration for peer dependencies handling
### [1.0.0] - 2025-08-09
- Initial release
- Complete form builder with 15+ field types
- Formik integration
- Material-UI components
- TypeScript support
- Responsive grid system
- Custom field renderers
- Async autocomplete search
## Contributing
1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
## Demo
š **Live Demo**: [https://deepu9990.github.io/mui-smart-form-builder/](https://deepu9990.github.io/mui-smart-form-builder/)
š¦ **CodeSandbox**: [https://codesandbox.io/s/github/deepu9990/mui-smart-form-builder/tree/main/demo](https://codesandbox.io/s/github/deepu9990/mui-smart-form-builder/tree/main/demo)
Try the interactive demo to see all field types and features in action!
## License
MIT License - see the [LICENSE](LICENSE) file for details.