A modern, type-safe form builder application built with React, TypeScript, and best practices.
- Dynamic Form Generation: Create forms dynamically from JSON configuration
- Type Safety: Full TypeScript support with discriminated unions
- Form Validation: Zod-based validation with custom validators
- State Management: Redux Toolkit for global state management
- Form Handling: React Hook Form for efficient form state management
- Local Storage: Persist form configurations locally
- Accessibility: ARIA attributes and keyboard navigation support
- Modern UI: TailwindCSS styling with responsive design
- React 18 - UI library
- TypeScript - Type safety
- Vite - Build tool
- Redux Toolkit - State management
- React Hook Form - Form handling
- Zod - Schema validation
- TailwindCSS - Styling
- React Query - Server state management
- React Toastify - Notifications
src/
├── components/
│ ├── common/ # Shared components
│ ├── config/ # Configuration tab components
│ ├── result/ # Form result tab components
│ └── ui/ # Base UI components
├── hooks/ # Custom React hooks
├── pages/ # Page components
├── store/ # Redux store configuration
│ └── slices/ # Redux slices
├── styles/ # CSS files
└── utils/ # Utility functions and types
├── constants.ts # Application constants
├── types.ts # TypeScript type definitions
└── validation.ts # Zod validation schemas
- Node.js 16+
- npm or yarn
- Clone the repository:
git clone <repository-url>
cd react-form-builder- Install dependencies:
npm install
# or
yarn install- Start the development server:
npm run dev
# or
yarn dev- Open http://localhost:5173 in your browser
The form builder accepts a JSON configuration with the following structure:
{
"title": "Sample Form",
"description": "Optional form description",
"buttons": ["Cancel", "Save"],
"items": [
{
"label": "Name",
"type": "string",
"required": true,
"placeholder": "Enter your name",
"minLength": 2,
"maxLength": 50
},
{
"label": "Age",
"type": "number",
"min": 0,
"max": 120,
"step": 1
},
{
"label": "Bio",
"type": "multi-line",
"rows": 4,
"maxLength": 500
},
{
"label": "Active",
"type": "boolean",
"defaultValue": true
},
{
"label": "Birth Date",
"type": "date",
"min": "1900-01-01",
"max": "2023-12-31"
},
{
"label": "Category",
"type": "enum",
"options": ["Option 1", "Option 2", "Option 3"],
"defaultValue": "Option 1"
}
]
}- string: Single-line text input
- number: Numeric input with optional min/max/step
- multi-line: Textarea for longer text
- boolean: Checkbox input
- date: Date picker
- enum: Radio button group
Common properties for all field types:
label(required): Field labeltype(required): Field typerequired: Whether the field is requiredplaceholder: Placeholder textdisabled: Disable the field
Type-specific properties are documented in the TypeScript interfaces.
npm run dev- Start development servernpm run build- Build for productionnpm run lint- Run ESLintnpm run preview- Preview production build
The project uses:
- ESLint for code linting
- TypeScript for type checking
- Strict mode enabled
- No unused locals/parameters allowed
The application uses Redux Toolkit with two main slices:
-
formConfigSlice: Manages form configuration
- Stores the current form configuration
- Validates configuration with Zod
- Tracks validation state
-
formDataSlice: Manages form data
- Stores form field values
- Tracks form dirty state
- Handles form submission
useFormConfig: Form configuration managementuseFormData: Form data managementuseLocalStorage: Local storage persistence
-
Type Safety
- Discriminated unions for form items
- Type guards for runtime checks
- Strict TypeScript configuration
-
Performance
- React.memo for pure components
- useCallback/useMemo for optimization
- Efficient re-renders with Redux
-
Accessibility
- ARIA labels and descriptions
- Keyboard navigation support
- Error announcements
-
Code Organization
- Feature-based folder structure
- Separation of concerns
- Reusable components
-
Error Handling
- Comprehensive error boundaries
- Validation error display
- User-friendly error messages