react-form-craft
v1.4.12
Published
A lightweight, flexible form building library for React applications with TypeScript support.
Maintainers
Readme
React Form Craft
A lightweight, flexible form building library for React applications with TypeScript support.
Features
- 🔧 Easy form setup with declarative configuration
- 🧩 Built-in form elements (Input, Select, Checkbox)
- 🛠 Custom control components support
- ✅ Validation support
- 🔄 Form state management
- 🎨 Customizable styling
Installation
npm install react-form-craftBasic Usage
import { useState } from 'react';
import {
FormCraft,
type ValidationErrors,
type FormCraftOnChange,
type FormCraftHandleSubmitParams
} from 'react-form-craft';
function MyForm() {
const formState = {
name: '',
email: '',
role: 'user',
agreeToTerms: false
};
const fields = [
{
name: 'name',
placeholder: 'Enter your name'
},
{
name: 'email',
placeholder: 'Enter your email',
control: (props) => <CustomInput {...props} errorMsg={props.error} />
},
{
name: 'role',
type: 'select',
options: [
{ value: 'user', label: 'User' },
{ value: 'admin', label: 'Admin' }
]
},
{
name: 'agreeToTerms',
type: 'checkbox'
},
{
name: 'radio',
type: 'radio',
options: ['radio1', 'radio2', 'radio3'],
placeholder: 'Radio',
},
{
name: 'group example',
type: 'group',
group: [
{
name: 'name',
placeholder: 'Enter name',
},
{
name: 'agree_with_policy',
type: 'checkbox',
placeholder: 'Do you agree with user policy?',
},
],
},
];
const validationRules = {
name: {
required: {
value: true,
message: 'Name is required',
},
maxLength: {
value: 10,
message: 'Name is too long',
},
minLength: {
value: 1,
message: 'Name is too short',
},
},
email: {
required: true,
customRule: (value?: string) => {
if (value && !value.includes('@')) {
return { value, message: 'Email is invalid' };
}
},
},
age: {
range: {
value: [18, 100],
},
}
};
const handleSubmit = async ({ state, payload, errors }: FormCraftHandleSubmitParams) => {
console.log('state', state);
console.log('payload', payload);
console.log('errors', errors);
// if you want to reset form data then return void
// else return payload(changed state) or state(initial state)
return payload;
};
const handleChange = ({ field, value }: FormCraftOnChange) => {
console.log('field', field);
console.log('value', value);
// Process field data
};
return (
<FormCraft
fields={fields}
state={formState}
submit={handleSubmit}
onChange={handleChange}
validationRules={validationRules}
className="my-form"
btnSubmit={<button type='submit' className="submit-btn">Submit Form</button>}
/>
);
}
See examples in src/app
API Reference
Props FormCraft
| Prop | Type | Required | Description |
| --- |-----------------------------------------------------------------------------| --- | --- |
| fields | FormCraftField[] | Yes | Array of field configurations |
| state | any | Yes | Form state object |
| submit | ({ state, payload, errors }: FormCraftHandleSubmitParams) => Promise<any> | Yes | Submit handler function |
| btnSubmit | ReactNode | No | Custom submit button |
| className | string | No | CSS class for form element |
| onChange | ({ field, value }: FormCraftOnChange) => void | No | Form change handler |
| validationRules | ValidationRules | No | Validation rules for fields |
Interface FormCraftField
interface FormCraftField {
name: string;
type?:
'text' |
'email' |
'password' |
'select' |
'checkbox' |
'textarea' |
'file' |
'number' |
'date' |
'radio' |
'group' |
string;
placeholder?: string;
options?: Array<{ value: string; label: string }>;
control?: ReactElement | ComponentType<any>;
onChange?: (e: ChangeEvent<HTMLInputElement | HTMLSelectElement>) => void;
[key: string]: any;
}Custom Form Controls
You can provide custom form controls using the property: control
import { MyCustomInput } from './components';
const fields = [
{
name: 'customField',
control: <MyCustomInput className="custom-input" />
}
];
const fields2 = [
{
name: 'customField',
control: MyCustomInput
}
];
Validation
FormCraft supports validation rules:
const validationRules = {
username: {
required: {
value: true,
message: 'Name is required',
},
maxLength: {
value: 10,
message: 'Name is too long',
},
minLength: {
value: 1,
message: 'Name is too short',
}
},
email: {
...
email: {
value: true,
message: 'Email is invalid',
},
customRule: (value?: string) => {
if (value && !value.includes('@')) {
return { value, message: 'Email is invalid' };
}
}
},
age: {
range: {
value: [18, 100],
},
},
birthday: {
range: {
value: [new Date(1991, 0, 1), new Date(2025, 0, 1)],
},
},
...
};License
MIT
