- Added missing exports for 19 API & data hooks (useAuth, useDBAL, useKV, etc.) - Removed bad imports of deleted files (hooks.ts, I18nNavigation.ts) - Organized exports into clear categories - All 100 hooks now properly exported from /hooks/index.ts This completes the comprehensive hooks library consolidation. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Form Validation & Input Hooks
Comprehensive collection of production-ready React hooks for managing form state, validation, and input handling.
🎯 Overview
5 powerful, fully-typed hooks for building complex forms with validation, state management, and error handling.
Location: /hooks/
📦 Available Hooks
1. useValidation - Schema-Based Form Validation
- Generic schema-based validation
- Field-level error tracking
- Bulk form validation
- Manual error management
File: useValidation.ts (198 lines)
const { errors, isValid, validate, validateField } = useValidation(schema)
2. useInput - Controlled Text Input State
- Dirty/touched tracking
- Optional validation on blur
- Value transformation
- Auto-reset on error
File: useInput.ts (199 lines)
const { value, error, handlers } = useInput('', { onValidate })
3. useCheckbox - Checkbox State Management
- Single checkbox OR checkbox groups
- Indeterminate state detection
- Check all/uncheck all operations
- Count tracking
File: useCheckbox.ts (418 lines)
// Single
const { checked, handlers } = useCheckbox(false)
// Multiple
const { values, handlers, isAllChecked } = useCheckbox({ read: false, write: false })
4. useSelect - Select Dropdown State
- Single select OR multi-select
- Search/filter options
- Clearable selections
- Option label tracking
File: useSelect.ts (467 lines)
// Single
const { value, handlers } = useSelect('option1', { options })
// Multiple
const { values, handlers, count } = useSelect([], { options, isMulti: true })
5. useFieldArray - Dynamic Form Arrays
- Add/remove/reorder fields
- Min/max constraints
- Field-level validation
- Array-like methods (push, pop, shift, unshift)
File: useFieldArray.ts (484 lines)
const { fields, handlers, canAdd, canRemove } = useFieldArray([], { maxFields: 5 })
🚀 Quick Start
Installation
All hooks are included in the project - no additional installation needed.
Import
import { useValidation } from '@/hooks/useValidation'
import { useInput } from '@/hooks/useInput'
import { useCheckbox } from '@/hooks/useCheckbox'
import { useSelect } from '@/hooks/useSelect'
import { useFieldArray } from '@/hooks/useFieldArray'
Basic Example
'use client'
import { useInput, useSelect, useCheckbox } from '@/hooks'
export const ContactForm = () => {
const name = useInput('', {
onValidate: (v) => v.length >= 2 ? '' : 'Min 2 chars'
})
const country = useSelect('us', {
options: [
{ value: 'us', label: 'USA' },
{ value: 'uk', label: 'UK' }
]
})
const subscribe = useCheckbox(false)
return (
<form>
<input value={name.value} onChange={name.handlers.onChange} />
{name.error && <span>{name.error}</span>}
<select value={country.value} onChange={country.handlers.onChange}>
{country.filteredOptions.map(opt => (
<option key={opt.value} value={opt.value}>{opt.label}</option>
))}
</select>
<label>
<input
type="checkbox"
checked={subscribe.checked}
onChange={subscribe.handlers.onChange}
/>
Subscribe
</label>
<button type="submit">Submit</button>
</form>
)
}
📚 Documentation
| Document | Purpose |
|---|---|
| FORM_VALIDATION_HOOKS.md | Complete API reference for all 5 hooks |
| QUICK_REFERENCE.md | Quick start guide with 30+ code examples |
| EXPORT_GUIDE.md | Import methods, type exports, troubleshooting |
| README.md | This file |
✨ Features
All Hooks Provide
- ✅ State tracking (value, isDirty, isTouched)
- ✅ Error handling with field-level messages
- ✅ Validation (field-level or bulk)
- ✅ Reset to initial state
- ✅ Touch tracking for conditional error display
- ✅ Fully typed with TypeScript
- ✅ useCallback memoization for performance
Hook-Specific Features
| Feature | useValidation | useInput | useCheckbox | useSelect | useFieldArray |
|---|---|---|---|---|---|
| Schema validation | ✅ | ||||
| Multi-field validation | ✅ | ||||
| Text input management | ✅ | ||||
| Value transformation | ✅ | ||||
| Single checkbox | ✅ | ||||
| Checkbox groups | ✅ | ||||
| Indeterminate state | ✅ | ||||
| Single select | ✅ | ||||
| Multi-select | ✅ | ||||
| Search/filter | ✅ | ||||
| Dynamic arrays | ✅ | ||||
| Array operations | ✅ | ||||
| Min/max constraints | ✅ |
🎨 Use Cases
Form Building
const form = {
name: useInput(''),
email: useInput(''),
country: useSelect('us', { options }),
agree: useCheckbox(false)
}
Dynamic Lists
const skills = useFieldArray(
[{ name: '' }],
{ minFields: 1, maxFields: 10 }
)
Permission Management
const permissions = useCheckbox({
read: false,
write: false,
delete: false,
admin: false
})
Multi-Select Filtering
const tags = useSelect([], {
options: allTags,
isMulti: true,
searchable: true
})
Cross-Field Validation
const password = useInput('')
const confirm = useInput('', {
onValidate: (v) => v !== password.value ? 'Passwords must match' : ''
})
🔧 API Summary
Common Handlers
All hooks return handlers object with methods:
onChange()- Handle change eventsreset()- Reset to initial statetouch()- Mark as touchedvalidate()- Manually validatesetError(),clearError()- Manual error control
Common State
All hooks return:
{
isDirty: boolean // Changed from initial
isTouched: boolean // User interacted
error: string // Validation error
isValid: boolean // No errors
handlers: { ... } // Event handlers
}
🎯 TypeScript Support
Full generic type support:
type FormData = {
name: string
age: number
email: string
}
const schema: ValidationSchema<FormData> = {
name: (v) => v.length > 0 ? '' : 'Required',
age: (v) => v > 0 ? '' : 'Invalid',
email: (v) => v.includes('@') ? '' : 'Invalid'
}
🔒 Performance
All hooks are optimized with:
useCallbackmemoization on all handlers- Minimal re-renders
- Efficient state updates
- No unnecessary computations
📱 Browser Support
- Chrome 70+
- Firefox 63+
- Safari 12+
- Edge 79+
- React 16.8+
🧪 Testing
All hooks are testable with React Testing Library:
import { render, screen, fireEvent } from '@testing-library/react'
import { useInput } from '@/hooks/useInput'
test('tracks dirty state', () => {
const Component = () => {
const input = useInput('initial')
return <input {...input.handlers.onChange} />
}
render(<Component />)
fireEvent.change(screen.getByRole('textbox'), { target: { value: 'changed' } })
// Assert isDirty === true
})
📋 Requirements
Peer Dependencies
react16.8+ (hooks support)react-dom16.8+
Dependencies
nanoid(for useFieldArray unique IDs)
Optional
react-redux(for integration)@reduxjs/toolkit(for Redux integration)
🚦 Status
| Hook | Status | Version | Last Updated |
|---|---|---|---|
| useValidation | ✅ Production | 1.0.0 | 2026-01-23 |
| useInput | ✅ Production | 1.0.0 | 2026-01-23 |
| useCheckbox | ✅ Production | 1.0.0 | 2026-01-23 |
| useSelect | ✅ Production | 1.0.0 | 2026-01-23 |
| useFieldArray | ✅ Production | 1.0.0 | 2026-01-23 |
📖 Examples
Complete Contact Form
See QUICK_REFERENCE.md for 30+ working examples including:
- Simple text input
- Checkbox validation
- Multi-select with search
- Dynamic field arrays
- Async validation
- Dependent field validation
- Complex multi-field forms
Example: Newsletter Signup
export const NewsletterSignup = () => {
const email = useInput('', {
onValidate: (v) => /^[^@]+@[^@]+$/.test(v) ? '' : 'Invalid email'
})
const preferences = useCheckbox({
weekly: true,
monthly: false,
deals: true
})
const handleSubmit = (e) => {
e.preventDefault()
if (email.isValid && preferences.isValid) {
console.log('Subscribe:', {
email: email.value,
preferences: preferences.values
})
}
}
return (
<form onSubmit={handleSubmit}>
<input
type="email"
value={email.value}
onChange={email.handlers.onChange}
placeholder="your@email.com"
/>
{email.error && <span className="error">{email.error}</span>}
<fieldset>
<legend>Frequency</legend>
{Object.keys(preferences.values).map(key => (
<label key={key}>
<input
type="checkbox"
checked={preferences.values[key]}
onChange={preferences.handlers.onChange}
name={key}
/>
{key.charAt(0).toUpperCase() + key.slice(1)}
</label>
))}
</fieldset>
<button type="submit">Subscribe</button>
</form>
)
}
🔗 Files Included
/hooks/
├── useValidation.ts (198 lines) - Schema validation
├── useInput.ts (199 lines) - Text input state
├── useCheckbox.ts (418 lines) - Checkbox management
├── useSelect.ts (467 lines) - Select/dropdown state
├── useFieldArray.ts (484 lines) - Dynamic arrays
├── FORM_VALIDATION_HOOKS.md - Complete API docs
├── QUICK_REFERENCE.md - Quick start + examples
├── EXPORT_GUIDE.md - Import & export guide
└── README.md - This file
Total code: ~1,766 lines | Documentation: ~1,200 lines
💡 Best Practices
- Use schema validation - Define validators centrally with
useValidation - Leverage dirty tracking - Only show errors after user changes
- Use touched state - Show validation after blur, not on render
- Reset on success - Clear form after successful submission
- Combine hooks - Use multiple hooks for complex forms
- Type your data - Always use TypeScript for form data
- Memoize in components - Use
useCallbackwrapping form components - Test error states - Test both valid and invalid states
🤝 Contributing
All hooks follow the same patterns:
- State management with
useState - Handler memoization with
useCallback - Consistent API across all hooks
- Full TypeScript support
- Comprehensive JSDoc comments
📞 Support
For issues or questions:
- Check
QUICK_REFERENCE.mdfor examples - Review
FORM_VALIDATION_HOOKS.mdAPI docs - See
EXPORT_GUIDE.mdfor common issues - Review hook source code with JSDoc comments
📄 License
Same as main project
Quick Links
Created: 2026-01-23 | Status: Production Ready ✅