@otitoju/formcraft-core
Version:
š Lightweight, TypeScript-first form management library for React and React Native with built-in validation, zero dependencies, and excellent developer experience
287 lines (227 loc) ⢠7.58 kB
Markdown
# @otitoju/formcraft-core
<div align="center">
š **Lightweight, TypeScript-first form management library for React and React Native**
[](https://www.npmjs.com/package/@otitoju/formcraft-core)
[](https://www.npmjs.com/package/@otitoju/formcraft-core)
[](https://bundlephobia.com/package/@otitoju/formcraft-core)
[](https://www.typescriptlang.org/)
[](https://opensource.org/licenses/MIT)
</div>
## ⨠Why FormCraft?
- šŖ¶ **Ultra Lightweight** - Only ~5KB gzipped, zero dependencies
- š§ **TypeScript First** - Full type safety with excellent IntelliSense
- š **Cross Platform** - Works seamlessly with React and React Native
- ā” **Performance Focused** - Optimized re-renders and efficient updates
- šÆ **Developer Experience** - Simple API inspired by React Hook Form
- ā
**Built-in Validation** - Zod-inspired schema validation included
- š± **Mobile Ready** - Native components for React Native
- āæ **Accessible** - WCAG compliant with proper ARIA attributes
## š Quick Start
\`\`\`bash
npm install @otitoju/formcraft-core
# or
yarn add @otitoju/formcraft-core
# or
pnpm add @otitoju/formcraft-core
\`\`\`
### React/Next.js Example
\`\`\`tsx
import { useForm, WebFormProvider, WebInput, Schema } from '@otitoju/formcraft-core';
import '@otitoju/formcraft-core/dist/web.css'; // Optional default styles
interface FormData {
email: string;
password: string;
}
function LoginForm() {
const form = useForm<FormData>({
defaultValues: { email: '', password: '' },
validation: {
email: Schema.email().required('Email is required'),
password: Schema.string().min(8, 'At least 8 characters').required()
}
});
const onSubmit = (data: FormData) => {
console.log('Form submitted:', data);
};
return (
<WebFormProvider form={form}>
<form onSubmit={form.handleSubmit(onSubmit)}>
<WebInput name="email" label="Email" type="email" />
<WebInput name="password" label="Password" type="password" />
<button type="submit" disabled={!form.formState.isValid}>
Sign In
</button>
</form>
</WebFormProvider>
);
}
\`\`\`
### React Native Example
\`\`\`tsx
import { useForm, NativeFormProvider, NativeInput, Schema } from '@otitoju/formcraft-core';
import { View, Button } from 'react-native';
function ContactForm() {
const form = useForm({
defaultValues: { name: '', email: '' },
validation: {
name: Schema.string().required('Name is required'),
email: Schema.email().required('Email is required')
}
});
return (
<NativeFormProvider form={form}>
<View>
<NativeInput name="name" label="Name" />
<NativeInput name="email" label="Email" keyboardType="email-address" />
<Button
title="Submit"
onPress={form.handleSubmit(console.log)}
disabled={!form.formState.isValid}
/>
</View>
</NativeFormProvider>
);
}
\`\`\`
## š Documentation
### Core Hook
\`\`\`tsx
const form = useForm({
defaultValues: { name: '', email: '' },
validation: {
name: Schema.string().required().min(2),
email: Schema.email().required()
},
mode: 'onChange' // 'onChange' | 'onBlur' | 'onSubmit'
});
\`\`\`
### Schema Validation
\`\`\`tsx
const schema = {
email: Schema.email().required('Email is required'),
age: Schema.number().min(18, 'Must be 18+').max(100),
website: Schema.url().required(),
password: Schema.string()
.min(8, 'At least 8 characters')
.pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)/, 'Must contain uppercase, lowercase, and number')
.required(),
terms: Schema.string().custom(value => value === true || 'You must accept the terms')
};
\`\`\`
### Form State
\`\`\`tsx
const {
values, // Current form values
errors, // Validation errors
touched, // Fields that have been interacted with
dirty, // Fields that have been modified
isValid, // Overall form validity
isSubmitting,// Submission state
isDirty // Whether any field has been modified
} = form.formState;
\`\`\`
## šÆ Comparison
| Feature | FormCraft | React Hook Form | Formik |
|---------|-----------|-----------------|--------|
| Bundle Size | ~5KB | ~25KB | ~45KB |
| TypeScript | ā
Built-in | ā
Good | ā ļø Basic |
| React Native | ā
Native | ā Manual | ā Manual |
| Validation | ā
Built-in | ā External | ā External |
| Learning Curve | š¢ Easy | š” Medium | š“ Hard |
| Performance | ā” Excellent | ā” Excellent | š” Good |
## š ļø Advanced Usage
### Conditional Fields
\`\`\`tsx
const showDetails = form.watch('type') !== '';
return (
<WebFormProvider form={form}>
<WebSelect name="type" options={typeOptions} />
{showDetails && <WebTextarea name="details" />}
</WebFormProvider>
);
\`\`\`
### Custom Validation
\`\`\`tsx
const validation = {
username: Schema.string()
.required('Username is required')
.custom(async (value) => {
const isAvailable = await checkAvailability(value);
return isAvailable || 'Username is taken';
})
};
\`\`\`
### Dynamic Forms
\`\`\`tsx
const [fields, setFields] = useState(['field1']);
return (
<WebFormProvider form={form}>
{fields.map(fieldName => (
<WebInput key={fieldName} name={fieldName} />
))}
<button onClick={() => setFields(prev => [...prev, `field${prev.length + 1}`])}>
Add Field
</button>
</WebFormProvider>
);
\`\`\`
## šØ Styling
### Web (CSS Classes)
\`\`\`tsx
<WebInput
name="email"
className="my-input"
containerClassName="my-field"
labelClassName="my-label"
errorClassName="my-error"
/>
\`\`\`
### React Native (Style Objects)
\`\`\`tsx
<NativeInput
name="email"
inputStyle={{ borderColor: 'blue' }}
containerStyle={{ marginBottom: 20 }}
labelStyle={{ fontSize: 18 }}
/>
\`\`\`
## š¤ Migration Guides
### From React Hook Form
\`\`\`tsx
// React Hook Form
const { register, handleSubmit, formState: { errors } } = useForm();
// FormCraft
const form = useForm();
const field = form.register('email'); // Same API!
\`\`\`
### From Formik
\`\`\`tsx
// Formik
<Formik initialValues={{ email: '' }} onSubmit={handleSubmit}>
<Field name="email" />
</Formik>
// FormCraft
<WebFormProvider form={form}>
<WebInput name="email" />
</WebFormProvider>
\`\`\`
## š¦ What's Included
- ā
Core form management hook
- ā
Built-in validation with Schema builder
- ā
Web components (Input, Select, Textarea, Checkbox)
- ā
React Native components
- ā
TypeScript definitions
- ā
Default CSS styles
- ā
Comprehensive examples
## š Links
- [š Full Documentation](https://github.com/otitoju/formcraft-core#readme)
- [š® Interactive Examples](https://github.com/otitoju/formcraft-core/tree/main/examples)
- [š Report Issues](https://github.com/otitoju/formcraft-core/issues)
- [š¬ Discussions](https://github.com/otitoju/formcraft-core/discussions)
## š License
MIT Ā© [Otitoju](https://github.com/otitoju)
---
<div align="center">
**Made with ā¤ļø for the React community**
[ā Star on GitHub](https://github.com/otitoju/formcraft-core) | [š¦ View on NPM](https://www.npmjs.com/package/@otitoju/formcraft-core)
</div>