Package Exports
- z-react-dynamic-form
- z-react-dynamic-form/dist/index.esm.js
- z-react-dynamic-form/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (z-react-dynamic-form) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
React Dynamic Form Builder
A powerful, flexible, and fully customizable form builder for React applications with built-in validation using Zod. Create everything from simple forms to complex multi-step wizards with ease.
Features
- 🔄 Dynamic Form Generation: Create forms with various input types on the fly
- ✅ Built-in Validation: Seamless integration with Zod for robust form validation
- 🧩 Multiple Input Types: Support for text, select, multi-select, date pickers, file uploads, and more
- 📱 Responsive Design: Works beautifully on all screen sizes
- 🧙♂️ Multi-step Forms: Create step-by-step form wizards with individual validation per step
- 📁 File Upload: Support for single or multiple file uploads with preview
- 📝 Rich Text Editor: Simple built-in rich text editor for content creation
- 🔍 Searchable Selects: Type to search in dropdown options
- 🔒 OTP Verification: Built-in OTP input handling for verification flows
- 🎨 Customizable: Fully customizable styling and behavior
Installation
npm install react-dynamic-form-builder
# or
yarn add react-dynamic-form-builder
Peer Dependencies
You'll need to install the following peer dependencies if you don't already have them:
npm install react react-dom zod
# or
yarn add react react-dom zod
Type Definitions
TypeScript types are included and no additional installation is needed.
Integration with CSS Frameworks
The library works well with any CSS framework, but it's designed to be easy to use with Tailwind CSS. If you're using Tailwind, add the following to your tailwind.config.js to ensure all the styling works correctly:
// tailwind.config.js
module.exports = {
content: [
// ...other content paths
"./node_modules/react-dynamic-form-builder/**/*.{js,ts,jsx,tsx}",
],
// ...rest of your config
};
Project Structure
react-dynamic-form-builder/
├── DynamicForm.tsx # Main component
├── components/ # Form components
│ ├── FileUploadHandler/ # File upload component
│ ├── RichTextEditor/ # Rich text editor
│ ├── DateHandler/ # Date picker
│ ├── FormElementHandler # Input renderer
│ └── ... other components
├── services/ # API and services
│ ├── axiosConfig.ts # API configuration
│ └── sessionService.ts # Session management
├── types/ # Type definitions
└── utils/ # Utility functions
Basic Usage
Here's a simple example of a form with validation:
import React from "react";
import { DynamicForm } from "react-dynamic-form-builder";
import { z } from "zod";
const MyForm = () => {
// Define validation schema
const formSchema = z.object({
name: z.string().min(2, "Name must be at least 2 characters"),
email: z.string().email("Please enter a valid email"),
age: z.number().min(18, "Must be at least 18 years old"),
});
// Define form fields
const controllers = [
{
name: "name",
label: "Full Name",
type: "text",
placeholder: "Enter your full name",
},
{
name: "email",
label: "Email Address",
type: "email",
placeholder: "Enter your email address",
},
{
name: "age",
label: "Age",
type: "number",
placeholder: "Enter your age",
},
];
// Handle form submission
const handleSubmit = async ({ values, setError, reset }) => {
console.log("Form values:", values);
try {
// Process form data here (e.g., API call)
// If you need to set custom errors:
// setError('fieldName', { message: 'Custom error message' });
// Reset form if needed
// reset();
} catch (error) {
console.error("Error submitting form:", error);
}
};
return (
<DynamicForm
controllers={controllers}
formSchema={formSchema}
handleSubmit={handleSubmit}
submitBtn={{ label: "Submit Form" }}
/>
);
};
export default MyForm;
Multi-step Forms
Create wizards with individual validation per step:
import React from "react";
import { DynamicForm } from "react-dynamic-form-builder";
import { z } from "zod";
const MyStepForm = () => {
// Define step schemas
const personalInfoSchema = z.object({
firstName: z.string().min(2, "First name is required"),
lastName: z.string().min(2, "Last name is required"),
email: z.string().email("Please enter a valid email"),
});
const addressSchema = z.object({
street: z.string().min(5, "Street address is required"),
city: z.string().min(2, "City is required"),
zipCode: z.string().min(5, "Valid zip code is required"),
});
// Define steps
const steps = [
{
stepName: "Personal Information",
stepSchema: personalInfoSchema,
controllers: [
{
name: "firstName",
label: "First Name",
type: "text",
placeholder: "Enter your first name",
},
{
name: "lastName",
label: "Last Name",
type: "text",
placeholder: "Enter your last name",
},
{
name: "email",
label: "Email",
type: "email",
placeholder: "Enter your email address",
},
],
},
{
stepName: "Address Information",
stepSchema: addressSchema,
controllers: [
{
name: "street",
label: "Street Address",
type: "text",
placeholder: "Enter your street address",
},
{
name: "city",
label: "City",
type: "text",
placeholder: "Enter your city",
},
{
name: "zipCode",
label: "Zip Code",
type: "text",
placeholder: "Enter your zip code",
},
],
},
];
// Handle form submission
const handleSubmit = async ({ values }) => {
console.log("Form values:", values);
// Process form data here
};
return (
<DynamicForm
steps={steps}
formtype="steper"
handleSubmit={handleSubmit}
submitBtn={{ label: "Complete Registration" }}
stepPreview={(values) => (
<div>
<h3>Review Your Information</h3>
<pre>{JSON.stringify(values, null, 2)}</pre>
</div>
)}
/>
);
};
export default MyStepForm;
File Upload
Handle file uploads with ease:
import React from "react";
import { DynamicForm } from "react-dynamic-form-builder";
import { z } from "zod";
const FileUploadForm = () => {
const formSchema = z.object({
name: z.string().min(2, "Name is required"),
documents: z.any().optional(), // File validation is handled by the component
});
const controllers = [
{
name: "name",
label: "Name",
type: "text",
placeholder: "Enter your name",
},
{
name: "documents",
label: "Upload Documents",
type: "upload",
multiple: true, // Allow multiple files
maxFiles: 3, // Maximum number of files
acceptedFileTypes: {
"application/pdf": [".pdf"],
"image/jpeg": [".jpg", ".jpeg"],
"image/png": [".png"],
},
},
];
const handleSubmit = async ({ values }) => {
console.log("Files:", values.documents);
// Process files here
};
return (
<DynamicForm
controllers={controllers}
formSchema={formSchema}
handleSubmit={handleSubmit}
submitBtn={{ label: "Upload Files" }}
/>
);
};
export default FileUploadForm;
Available Input Types
text
- Text inputemail
- Email inputpassword
- Password input with visibility togglenumber
- Number inputtextarea
- Multiline text inputselect
- Dropdown selectionmulti-select
- Multiple selection dropdownsearchable-select
- Searchable dropdowncheckbox
- Single checkboxgroup-checkbox
- Group of checkboxesdate
- Date picker with single or range modeupload
- File upload with previewrich-text-editor
- Simple rich text editorphone-number
- Phone number inputreact-node
- Custom React component
API Configuration
The library automatically reads configuration from a form.config.json
file in your project root. Create this file with your API settings:
{
"api": {
"baseURL": "https://api.example.com",
"headers": {
"Content-Type": "application/json",
"X-Custom-Header": "Custom Value"
},
"timeout": 30000
}
}
Authentication
For authentication, create a services/sessionService.js
or services/sessionService.ts
file in your project:
// services/sessionService.js
export const getSession = async () => {
// Your custom logic to get the auth token
const token = localStorage.getItem("auth_token");
return { accessToken: token };
};
The library will automatically detect and use your session service.
Manual Configuration
You can also configure the API programmatically:
import { initConfig } from 'react-dynamic-form-builder/dist/services/axiosConfig';
// Initialize with custom config and session function
initConfig(
{
api: {
baseURL: 'https://api.example.com'
}
},
async () => ({ accessToken: 'my-token' })
);
```1. Using form.config.json
Create a `form.config.json` file in your project root:
```json
{
"api": {
"baseURL": "https://api.example.com",
"headers": {
"Content-Type": "application/json",
"Accept": "application/json",
"X-Custom-Header": "Custom Value"
},
"timeout": 30000
}
}
2. Using the initConfig method
import { initConfig } from "react-dynamic-form-builder/services/axiosConfig";
// Initialize with custom config
initConfig({
api: {
baseURL: "https://api.example.com",
headers: {
"Content-Type": "application/json",
"X-Custom-Header": "Custom Value",
},
timeout: 30000,
},
});
Authentication Integration
The library supports session-based authentication. You can implement your own session handler by creating a services/sessionService.ts
file in your project:
// services/sessionService.ts
export const getSession = async (): Promise<{ accessToken?: string }> => {
// Your custom logic to get the access token
// Example with next-auth:
const session = await getNextAuthSession();
return { accessToken: session?.accessToken };
};
With this setup, all API requests made by the form will automatically include the access token in the Authorization header.