form-hook-kit 1.2.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -372
- package/dist/devtools/FormContext.d.ts +8 -0
- package/dist/devtools/FormContext.d.ts.map +1 -0
- package/dist/devtools/FormDevTools.d.ts.map +1 -1
- package/dist/devtools/FormProvider.d.ts +33 -0
- package/dist/devtools/FormProvider.d.ts.map +1 -0
- package/dist/devtools/devtools/FormDevTools.d.ts +86 -0
- package/dist/devtools/devtools/FormDevTools.d.ts.map +1 -0
- package/dist/devtools/devtools/index.d.ts +3 -0
- package/dist/devtools/devtools/index.d.ts.map +1 -0
- package/dist/devtools/hooks/index.d.ts +4 -0
- package/dist/devtools/hooks/index.d.ts.map +1 -0
- package/dist/devtools/hooks/useForm.d.ts +30 -0
- package/dist/devtools/hooks/useForm.d.ts.map +1 -0
- package/dist/devtools/hooks/useFormField.d.ts +40 -0
- package/dist/devtools/hooks/useFormField.d.ts.map +1 -0
- package/dist/devtools/hooks/useFormPerformance.d.ts +57 -0
- package/dist/devtools/hooks/useFormPerformance.d.ts.map +1 -0
- package/dist/devtools/index.d.ts +11 -2
- package/dist/devtools/index.d.ts.map +1 -1
- package/dist/devtools/index.esm.js +203 -0
- package/dist/devtools/index.esm.js.map +1 -0
- package/dist/devtools/index.js +205 -0
- package/dist/devtools/index.js.map +1 -0
- package/dist/devtools/package.json +6 -0
- package/dist/devtools/types/index.d.ts +94 -0
- package/dist/devtools/types/index.d.ts.map +1 -0
- package/dist/devtools/utils/debounce.d.ts +6 -0
- package/dist/devtools/utils/debounce.d.ts.map +1 -0
- package/dist/devtools/utils/errors.d.ts +11 -0
- package/dist/devtools/utils/errors.d.ts.map +1 -0
- package/dist/devtools/utils/formActions.d.ts +57 -0
- package/dist/devtools/utils/formActions.d.ts.map +1 -0
- package/dist/devtools/utils/formReducer.d.ts +7 -0
- package/dist/devtools/utils/formReducer.d.ts.map +1 -0
- package/dist/devtools/utils/index.d.ts +7 -0
- package/dist/devtools/utils/index.d.ts.map +1 -0
- package/dist/devtools/utils/performance.d.ts +7 -0
- package/dist/devtools/utils/performance.d.ts.map +1 -0
- package/dist/devtools/utils/validation.d.ts +25 -0
- package/dist/devtools/utils/validation.d.ts.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +128 -2
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +128 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -118,26 +118,18 @@ pnpm add form-hook-kit yup
|
|
|
118
118
|
|
|
119
119
|
## Quick Start
|
|
120
120
|
|
|
121
|
-
### Basic Example (React Web)
|
|
122
|
-
|
|
123
121
|
```tsx
|
|
124
122
|
import React from 'react';
|
|
125
123
|
import * as yup from 'yup';
|
|
126
124
|
import {FormProvider, useForm, useFormField} from 'form-hook-kit';
|
|
127
125
|
|
|
128
|
-
// Define your validation schema
|
|
129
126
|
const schema = yup.object({
|
|
130
127
|
email: yup.string().email('Invalid email').required('Email is required'),
|
|
131
|
-
password: yup
|
|
132
|
-
.string()
|
|
133
|
-
.min(8, 'Password must be at least 8 characters')
|
|
134
|
-
.required('Password is required'),
|
|
128
|
+
password: yup.string().min(8).required('Password is required'),
|
|
135
129
|
});
|
|
136
130
|
|
|
137
|
-
// Create form fields
|
|
138
131
|
function EmailField() {
|
|
139
132
|
const {value, error, onChange, onBlur} = useFormField('email');
|
|
140
|
-
|
|
141
133
|
return (
|
|
142
134
|
<div>
|
|
143
135
|
<input
|
|
@@ -152,33 +144,13 @@ function EmailField() {
|
|
|
152
144
|
);
|
|
153
145
|
}
|
|
154
146
|
|
|
155
|
-
function PasswordField() {
|
|
156
|
-
const {value, error, onChange, onBlur} = useFormField('password');
|
|
157
|
-
|
|
158
|
-
return (
|
|
159
|
-
<div>
|
|
160
|
-
<input
|
|
161
|
-
type="password"
|
|
162
|
-
value={value || ''}
|
|
163
|
-
onChange={onChange}
|
|
164
|
-
onBlur={onBlur}
|
|
165
|
-
placeholder="Password"
|
|
166
|
-
/>
|
|
167
|
-
{error && <span className="error">{error}</span>}
|
|
168
|
-
</div>
|
|
169
|
-
);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
// Create your form
|
|
173
147
|
function LoginForm() {
|
|
174
148
|
const {validateForm, values} = useForm();
|
|
175
149
|
|
|
176
150
|
const handleSubmit = (e: React.FormEvent) => {
|
|
177
151
|
e.preventDefault();
|
|
178
152
|
const errors = validateForm();
|
|
179
|
-
|
|
180
153
|
if (Object.values(errors).every(error => !error)) {
|
|
181
|
-
// Form is valid, submit it
|
|
182
154
|
console.log('Form submitted:', values);
|
|
183
155
|
}
|
|
184
156
|
};
|
|
@@ -186,118 +158,27 @@ function LoginForm() {
|
|
|
186
158
|
return (
|
|
187
159
|
<form onSubmit={handleSubmit}>
|
|
188
160
|
<EmailField />
|
|
189
|
-
<PasswordField />
|
|
190
161
|
<button type="submit">Login</button>
|
|
191
162
|
</form>
|
|
192
163
|
);
|
|
193
164
|
}
|
|
194
165
|
|
|
195
|
-
// Wrap with FormProvider
|
|
196
166
|
export default function App() {
|
|
197
167
|
return (
|
|
198
|
-
<FormProvider
|
|
199
|
-
schema={schema}
|
|
200
|
-
initialValues={{email: '', password: ''}}
|
|
201
|
-
>
|
|
168
|
+
<FormProvider schema={schema} initialValues={{email: '', password: ''}}>
|
|
202
169
|
<LoginForm />
|
|
203
170
|
</FormProvider>
|
|
204
171
|
);
|
|
205
172
|
}
|
|
206
173
|
```
|
|
207
174
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
> **Note:** form-hook-kit has **zero native dependencies** - it's pure JavaScript/TypeScript. This means it's fully compatible with:
|
|
211
|
-
> - ✅ React Native legacy architecture
|
|
212
|
-
> - ✅ React Native new architecture (Fabric & TurboModules)
|
|
213
|
-
> - ✅ Android 16KB page size requirement
|
|
214
|
-
> - ✅ Expo (including Expo Go)
|
|
215
|
-
>
|
|
216
|
-
> **📱 For detailed React Native usage and platform-specific features, see [REACT_NATIVE.md](REACT_NATIVE.md)**
|
|
217
|
-
|
|
218
|
-
```tsx
|
|
219
|
-
import React from 'react';
|
|
220
|
-
import {View, TextInput, Text, Button} from 'react-native';
|
|
221
|
-
import * as yup from 'yup';
|
|
222
|
-
import {FormProvider, useFormField, useForm} from 'form-hook-kit';
|
|
223
|
-
|
|
224
|
-
const schema = yup.object({
|
|
225
|
-
username: yup.string().required('Username is required'),
|
|
226
|
-
email: yup.string().email('Invalid email').required('Email is required'),
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
function UsernameField() {
|
|
230
|
-
const {value, error, onChangeValue, onBlur, setRef} = useFormField('username');
|
|
231
|
-
|
|
232
|
-
return (
|
|
233
|
-
<View>
|
|
234
|
-
<TextInput
|
|
235
|
-
ref={setRef}
|
|
236
|
-
value={value || ''}
|
|
237
|
-
onChangeText={onChangeValue}
|
|
238
|
-
onBlur={onBlur}
|
|
239
|
-
placeholder="Username"
|
|
240
|
-
/>
|
|
241
|
-
{error && <Text style={{color: 'red'}}>{error}</Text>}
|
|
242
|
-
</View>
|
|
243
|
-
);
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
function EmailField() {
|
|
247
|
-
const {value, error, onChangeValue, onBlur, setRef} = useFormField('email');
|
|
248
|
-
|
|
249
|
-
return (
|
|
250
|
-
<View>
|
|
251
|
-
<TextInput
|
|
252
|
-
ref={setRef}
|
|
253
|
-
value={value || ''}
|
|
254
|
-
onChangeText={onChangeValue}
|
|
255
|
-
onBlur={onBlur}
|
|
256
|
-
placeholder="Email"
|
|
257
|
-
keyboardType="email-address"
|
|
258
|
-
/>
|
|
259
|
-
{error && <Text style={{color: 'red'}}>{error}</Text>}
|
|
260
|
-
</View>
|
|
261
|
-
);
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
function SignupForm() {
|
|
265
|
-
const {validateForm, values} = useForm();
|
|
266
|
-
|
|
267
|
-
const handleSubmit = () => {
|
|
268
|
-
const errors = validateForm();
|
|
269
|
-
|
|
270
|
-
if (Object.values(errors).every(error => !error)) {
|
|
271
|
-
console.log('Form submitted:', values);
|
|
272
|
-
}
|
|
273
|
-
};
|
|
274
|
-
|
|
275
|
-
return (
|
|
276
|
-
<View>
|
|
277
|
-
<UsernameField />
|
|
278
|
-
<EmailField />
|
|
279
|
-
<Button title="Sign Up" onPress={handleSubmit} />
|
|
280
|
-
</View>
|
|
281
|
-
);
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
export default function App() {
|
|
285
|
-
return (
|
|
286
|
-
<FormProvider
|
|
287
|
-
schema={schema}
|
|
288
|
-
initialValues={{username: '', email: ''}}
|
|
289
|
-
>
|
|
290
|
-
<SignupForm />
|
|
291
|
-
</FormProvider>
|
|
292
|
-
);
|
|
293
|
-
}
|
|
294
|
-
```
|
|
175
|
+
**📚 For complete examples including React Native, see [USAGE.md](./USAGE.md)**
|
|
295
176
|
|
|
296
177
|
---
|
|
297
178
|
|
|
298
179
|
## API Reference
|
|
299
180
|
|
|
300
|
-
For advanced usage
|
|
181
|
+
For complete API documentation, advanced usage, React Native examples, and performance optimization, see [USAGE.md](./USAGE.md).
|
|
301
182
|
|
|
302
183
|
### `FormProvider`
|
|
303
184
|
|
|
@@ -473,270 +354,45 @@ global.formDevTools.logAll() // Log everything
|
|
|
473
354
|
- `position` (optional): `'top-left'` | `'top-right'` | `'bottom-left'` | `'bottom-right'` (default: `'bottom-right'`)
|
|
474
355
|
- `defaultOpen` (optional): Whether to show by default (default: `false`)
|
|
475
356
|
|
|
476
|
-
---
|
|
477
|
-
|
|
478
|
-
## Advanced Usage
|
|
479
|
-
|
|
480
|
-
### Performance Optimization
|
|
481
|
-
|
|
482
|
-
**Debounced Validation:**
|
|
483
|
-
|
|
484
|
-
For forms with real-time validation, you can debounce validation to improve performance:
|
|
485
|
-
|
|
486
|
-
```tsx
|
|
487
|
-
<FormProvider
|
|
488
|
-
schema={schema}
|
|
489
|
-
validationDebounce={300} // Wait 300ms after user stops typing
|
|
490
|
-
>
|
|
491
|
-
<MyForm />
|
|
492
|
-
</FormProvider>
|
|
493
|
-
```
|
|
494
|
-
|
|
495
|
-
**Performance Monitoring:**
|
|
496
|
-
|
|
497
|
-
Track and optimize your form's performance:
|
|
498
|
-
|
|
499
|
-
```tsx
|
|
500
|
-
import {useFormPerformance} from 'form-hook-kit';
|
|
501
|
-
|
|
502
|
-
function MyForm() {
|
|
503
|
-
const metrics = useFormPerformance();
|
|
504
|
-
|
|
505
|
-
// Log performance in development
|
|
506
|
-
useEffect(() => {
|
|
507
|
-
if (process.env.NODE_ENV === 'development') {
|
|
508
|
-
console.log('Form Performance:', metrics);
|
|
509
|
-
}
|
|
510
|
-
}, [metrics]);
|
|
511
|
-
|
|
512
|
-
return <div>...</div>;
|
|
513
|
-
}
|
|
514
|
-
```
|
|
515
|
-
|
|
516
|
-
### Custom Validation
|
|
517
|
-
|
|
518
|
-
```tsx
|
|
519
|
-
import * as yup from 'yup';
|
|
520
|
-
|
|
521
|
-
const schema = yup.object({
|
|
522
|
-
password: yup.string().required('Password is required'),
|
|
523
|
-
confirmPassword: yup
|
|
524
|
-
.string()
|
|
525
|
-
.oneOf([yup.ref('password')], 'Passwords must match')
|
|
526
|
-
.required('Confirm password is required'),
|
|
527
|
-
});
|
|
528
|
-
```
|
|
529
|
-
|
|
530
|
-
### Manual Field Validation
|
|
531
|
-
|
|
532
|
-
```tsx
|
|
533
|
-
function MyField() {
|
|
534
|
-
const {values, errors, changeValue, validateField} = useForm();
|
|
535
|
-
|
|
536
|
-
const handleChange = (value: string) => {
|
|
537
|
-
changeValue({name: 'email', value});
|
|
538
|
-
// Validate immediately on change
|
|
539
|
-
validateField('email', value);
|
|
540
|
-
};
|
|
541
|
-
|
|
542
|
-
return (
|
|
543
|
-
<input
|
|
544
|
-
value={values.email || ''}
|
|
545
|
-
onChange={(e) => handleChange(e.target.value)}
|
|
546
|
-
/>
|
|
547
|
-
);
|
|
548
|
-
}
|
|
549
|
-
```
|
|
550
|
-
|
|
551
|
-
### Setting Errors Manually
|
|
552
|
-
|
|
553
|
-
```tsx
|
|
554
|
-
function MyForm() {
|
|
555
|
-
const {setError, clearError} = useForm();
|
|
556
|
-
|
|
557
|
-
const handleCustomValidation = () => {
|
|
558
|
-
if (someCondition) {
|
|
559
|
-
setError({name: 'email', error: 'Custom error message'});
|
|
560
|
-
} else {
|
|
561
|
-
clearError('email');
|
|
562
|
-
}
|
|
563
|
-
};
|
|
564
|
-
|
|
565
|
-
return (
|
|
566
|
-
// ...
|
|
567
|
-
);
|
|
568
|
-
}
|
|
569
|
-
```
|
|
570
|
-
|
|
571
|
-
### Focus Management (React Native)
|
|
572
|
-
|
|
573
|
-
```tsx
|
|
574
|
-
function MyForm() {
|
|
575
|
-
const {fieldRefs} = useForm();
|
|
576
|
-
|
|
577
|
-
const focusNextField = () => {
|
|
578
|
-
// Focus the email field
|
|
579
|
-
fieldRefs.current.email?.focus();
|
|
580
|
-
};
|
|
581
|
-
|
|
582
|
-
return (
|
|
583
|
-
<View>
|
|
584
|
-
<TextInput
|
|
585
|
-
ref={(ref) => (fieldRefs.current.username = ref)}
|
|
586
|
-
onSubmitEditing={() => fieldRefs.current.email?.focus()}
|
|
587
|
-
returnKeyType="next"
|
|
588
|
-
/>
|
|
589
|
-
<TextInput
|
|
590
|
-
ref={(ref) => (fieldRefs.current.email = ref)}
|
|
591
|
-
returnKeyType="done"
|
|
592
|
-
/>
|
|
593
|
-
</View>
|
|
594
|
-
);
|
|
595
|
-
}
|
|
596
|
-
```
|
|
597
|
-
|
|
598
|
-
### Updating Multiple Values
|
|
599
|
-
|
|
600
|
-
```tsx
|
|
601
|
-
function MyForm() {
|
|
602
|
-
const {changeValues} = useForm();
|
|
603
|
-
|
|
604
|
-
const resetForm = () => {
|
|
605
|
-
changeValues({
|
|
606
|
-
email: '',
|
|
607
|
-
password: '',
|
|
608
|
-
username: '',
|
|
609
|
-
});
|
|
610
|
-
};
|
|
611
|
-
|
|
612
|
-
return (
|
|
613
|
-
<button onClick={resetForm}>Reset</button>
|
|
614
|
-
);
|
|
615
|
-
}
|
|
616
|
-
```
|
|
617
|
-
|
|
618
|
-
### Custom Formatters
|
|
619
|
-
|
|
620
|
-
```tsx
|
|
621
|
-
function PhoneField() {
|
|
622
|
-
const {value, error, onChangeValue, onBlur} = useFormField('phone');
|
|
623
|
-
|
|
624
|
-
const formatPhone = (text: string) => {
|
|
625
|
-
// Remove non-digits
|
|
626
|
-
const digits = text.replace(/\D/g, '');
|
|
627
|
-
// Format as (XXX) XXX-XXXX
|
|
628
|
-
if (digits.length <= 3) return digits;
|
|
629
|
-
if (digits.length <= 6) return `(${digits.slice(0, 3)}) ${digits.slice(3)}`;
|
|
630
|
-
return `(${digits.slice(0, 3)}) ${digits.slice(3, 6)}-${digits.slice(6, 10)}`;
|
|
631
|
-
};
|
|
632
|
-
|
|
633
|
-
return (
|
|
634
|
-
<input
|
|
635
|
-
value={value || ''}
|
|
636
|
-
onChange={(e) => onChangeValue(formatPhone(e.target.value))}
|
|
637
|
-
onBlur={onBlur}
|
|
638
|
-
/>
|
|
639
|
-
);
|
|
640
|
-
}
|
|
641
|
-
```
|
|
642
357
|
|
|
643
358
|
---
|
|
644
359
|
|
|
645
|
-
##
|
|
646
|
-
|
|
647
|
-
Full TypeScript support with type inference:
|
|
648
|
-
|
|
649
|
-
```tsx
|
|
650
|
-
import {FormProvider, useForm, useFormField} from 'form-hook-kit';
|
|
651
|
-
import * as yup from 'yup';
|
|
652
|
-
|
|
653
|
-
interface FormValues {
|
|
654
|
-
email: string;
|
|
655
|
-
password: string;
|
|
656
|
-
}
|
|
657
|
-
|
|
658
|
-
const schema = yup.object({
|
|
659
|
-
email: yup.string().email().required(),
|
|
660
|
-
password: yup.string().min(8).required(),
|
|
661
|
-
});
|
|
360
|
+
## Documentation
|
|
662
361
|
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
// values and errors are properly typed based on schema
|
|
666
|
-
}
|
|
667
|
-
```
|
|
362
|
+
- **[USAGE.md](./USAGE.md)** - Complete usage guide with examples
|
|
363
|
+
- **[CHANGELOG.md](./CHANGELOG.md)** - Version history
|
|
668
364
|
|
|
669
365
|
---
|
|
670
366
|
|
|
671
|
-
##
|
|
672
|
-
|
|
673
|
-
Example test using React Testing Library:
|
|
674
|
-
|
|
675
|
-
```tsx
|
|
676
|
-
import {render, screen, fireEvent} from '@testing-library/react';
|
|
677
|
-
import * as yup from 'yup';
|
|
678
|
-
import {FormProvider, useForm} from 'form-hook-kit';
|
|
679
|
-
|
|
680
|
-
const schema = yup.object({
|
|
681
|
-
email: yup.string().email().required(),
|
|
682
|
-
});
|
|
683
|
-
|
|
684
|
-
test('validates email field', async () => {
|
|
685
|
-
function TestForm() {
|
|
686
|
-
const {values, errors, changeValue, validateField} = useForm();
|
|
687
|
-
|
|
688
|
-
return (
|
|
689
|
-
<div>
|
|
690
|
-
<input
|
|
691
|
-
data-testid="email"
|
|
692
|
-
value={values.email || ''}
|
|
693
|
-
onChange={(e) => changeValue({name: 'email', value: e.target.value})}
|
|
694
|
-
onBlur={() => validateField('email')}
|
|
695
|
-
/>
|
|
696
|
-
{errors.email && <span data-testid="error">{errors.email}</span>}
|
|
697
|
-
</div>
|
|
698
|
-
);
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
render(
|
|
702
|
-
<FormProvider schema={schema} initialValues={{email: ''}}>
|
|
703
|
-
<TestForm />
|
|
704
|
-
</FormProvider>
|
|
705
|
-
);
|
|
706
|
-
|
|
707
|
-
const input = screen.getByTestId('email');
|
|
708
|
-
fireEvent.change(input, {target: {value: 'invalid'}});
|
|
709
|
-
fireEvent.blur(input);
|
|
367
|
+
## Contributing
|
|
710
368
|
|
|
711
|
-
|
|
712
|
-
});
|
|
713
|
-
```
|
|
369
|
+
Contributions are welcome! To contribute:
|
|
714
370
|
|
|
715
|
-
|
|
371
|
+
1. Fork the repository
|
|
372
|
+
2. Create a feature branch (`git checkout -b feature/your-feature`)
|
|
373
|
+
3. Make your changes and add tests
|
|
374
|
+
4. Ensure tests pass (`npm test`)
|
|
375
|
+
5. Commit your changes (`git commit -m 'Add some feature'`)
|
|
376
|
+
6. Push to the branch (`git push origin feature/your-feature`)
|
|
377
|
+
7. Open a Pull Request
|
|
716
378
|
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
4. **Schema optimization**: Keep Yup schemas simple and efficient
|
|
379
|
+
Please ensure:
|
|
380
|
+
- All tests pass
|
|
381
|
+
- Code follows the existing style
|
|
382
|
+
- New features include tests
|
|
383
|
+
- TypeScript types are properly defined
|
|
723
384
|
|
|
724
385
|
---
|
|
725
386
|
|
|
726
|
-
##
|
|
727
|
-
|
|
728
|
-
| Issue | Solution |
|
|
729
|
-
|-------|----------|
|
|
730
|
-
| Validation not working | Ensure your Yup schema is properly defined and passed to FormProvider |
|
|
731
|
-
| Field not updating | Check that you're using the correct field name and onChange handler |
|
|
732
|
-
| TypeScript errors | Make sure your form values interface matches your Yup schema |
|
|
733
|
-
| React Native TextInput issues | Use `onChangeText` with `onChangeValue` instead of `onChange` |
|
|
387
|
+
## Security
|
|
734
388
|
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
389
|
+
When using form-hook-kit:
|
|
390
|
+
- Always validate user input with proper Yup schemas
|
|
391
|
+
- Keep your dependencies up to date
|
|
392
|
+
- Sanitize any user input before displaying it
|
|
393
|
+
- Follow React security best practices
|
|
738
394
|
|
|
739
|
-
|
|
395
|
+
To report security vulnerabilities, please open an issue on [GitHub](https://github.com/bc-bane/form-hook-kit/issues).
|
|
740
396
|
|
|
741
397
|
---
|
|
742
398
|
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { FormContextValue } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Form context
|
|
4
|
+
* Provides form state and methods to child components
|
|
5
|
+
*/
|
|
6
|
+
export declare const FormContext: import("react").Context<FormContextValue | null>;
|
|
7
|
+
export default FormContext;
|
|
8
|
+
//# sourceMappingURL=FormContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormContext.d.ts","sourceRoot":"","sources":["../../src/FormContext.tsx"],"names":[],"mappings":"AACA,OAAO,EAAC,gBAAgB,EAAC,MAAM,SAAS,CAAC;AAEzC;;;GAGG;AACH,eAAO,MAAM,WAAW,kDAA+C,CAAC;AAExE,eAAe,WAAW,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormDevTools.d.ts","sourceRoot":"","sources":["../../src/devtools/FormDevTools.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoC,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"FormDevTools.d.ts","sourceRoot":"","sources":["../../src/devtools/FormDevTools.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoC,MAAM,OAAO,CAAC;AAMzD;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAAC;AAErD,MAAM,WAAW,iBAAiB;IAChC;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,QAAQ,CAAC,EAAE,UAAU,GAAG,WAAW,GAAG,aAAa,GAAG,cAAc,CAAC;IACrE;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAQD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAEH,wBAAgB,YAAY,CAAC,EAC3B,IAAuC,EACvC,OAAe,EACf,SAA4B,EAC5B,QAAyB,EACzB,WAAkB,GACnB,GAAE,iBAAsB,4BAqMxB"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { FormProviderProps } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Form Provider Component
|
|
5
|
+
*
|
|
6
|
+
* Wraps your form and provides form state management using React Context.
|
|
7
|
+
* Integrates with Yup for validation.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* import * as yup from 'yup';
|
|
12
|
+
* import {FormProvider} from 'form-hook-kit';
|
|
13
|
+
*
|
|
14
|
+
* const schema = yup.object({
|
|
15
|
+
* email: yup.string().email().required(),
|
|
16
|
+
* password: yup.string().min(8).required(),
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* function MyForm() {
|
|
20
|
+
* return (
|
|
21
|
+
* <FormProvider
|
|
22
|
+
* schema={schema}
|
|
23
|
+
* initialValues={{ email: '', password: '' }}
|
|
24
|
+
* >
|
|
25
|
+
* <MyFormFields />
|
|
26
|
+
* </FormProvider>
|
|
27
|
+
* );
|
|
28
|
+
* }
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare function FormProvider({ children, initialErrors, initialValues, schema, validationDebounce, }: FormProviderProps): React.JSX.Element;
|
|
32
|
+
export default FormProvider;
|
|
33
|
+
//# sourceMappingURL=FormProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormProvider.d.ts","sourceRoot":"","sources":["../../src/FormProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoC,MAAM,OAAO,CAAC;AAEzD,OAAO,EAAC,iBAAiB,EAAiB,MAAM,SAAS,CAAC;AAY1D;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,YAAY,CAAC,EAC3B,QAAQ,EACR,aAAkB,EAClB,aAAkB,EAClB,MAAM,EACN,kBAAsB,GACvB,EAAE,iBAAiB,qBAkGnB;AAED,eAAe,YAAY,CAAC"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* DevTools mode configuration
|
|
4
|
+
*/
|
|
5
|
+
export type DevToolsMode = 'ui' | 'console' | 'none';
|
|
6
|
+
export interface FormDevToolsProps {
|
|
7
|
+
/**
|
|
8
|
+
* Display mode for DevTools
|
|
9
|
+
* - 'ui': Shows visual UI panel (web only)
|
|
10
|
+
* - 'console': Logs to console (works everywhere, including React Native)
|
|
11
|
+
* - 'none': Disabled
|
|
12
|
+
* @default 'ui' in web, 'console' in React Native
|
|
13
|
+
*/
|
|
14
|
+
mode?: DevToolsMode;
|
|
15
|
+
/**
|
|
16
|
+
* Enable automatic logging on value/error changes
|
|
17
|
+
* Only applies when mode is 'console'
|
|
18
|
+
* @default false
|
|
19
|
+
*/
|
|
20
|
+
autoLog?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Custom log prefix
|
|
23
|
+
* @default '[FormDevTools]'
|
|
24
|
+
*/
|
|
25
|
+
logPrefix?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Position of the UI panel (only for 'ui' mode)
|
|
28
|
+
* @default 'bottom-right'
|
|
29
|
+
*/
|
|
30
|
+
position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
|
31
|
+
/**
|
|
32
|
+
* Whether UI panel is open by default (only for 'ui' mode)
|
|
33
|
+
* @default true
|
|
34
|
+
*/
|
|
35
|
+
defaultOpen?: boolean;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* FormDevTools Component
|
|
39
|
+
*
|
|
40
|
+
* A cross-platform development tool for inspecting form state in real-time.
|
|
41
|
+
*
|
|
42
|
+
* **Platform Support:**
|
|
43
|
+
* - **Web**: Shows a visual UI panel by default (`mode="ui"`)
|
|
44
|
+
* - **React Native**: Logs to console by default (`mode="console"`)
|
|
45
|
+
* - Use with React Native Debugger, Flipper, or Metro logs
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```tsx
|
|
49
|
+
* // Web - shows UI panel
|
|
50
|
+
* import {FormProvider} from 'form-hook-kit';
|
|
51
|
+
* import {FormDevTools} from 'form-hook-kit/devtools';
|
|
52
|
+
*
|
|
53
|
+
* function App() {
|
|
54
|
+
* return (
|
|
55
|
+
* <FormProvider schema={schema}>
|
|
56
|
+
* <MyForm />
|
|
57
|
+
* {process.env.NODE_ENV === 'development' && <FormDevTools />}
|
|
58
|
+
* </FormProvider>
|
|
59
|
+
* );
|
|
60
|
+
* }
|
|
61
|
+
* ```
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```tsx
|
|
65
|
+
* // React Native - logs to console
|
|
66
|
+
* import {FormProvider} from 'form-hook-kit';
|
|
67
|
+
* import {FormDevTools} from 'form-hook-kit/devtools';
|
|
68
|
+
*
|
|
69
|
+
* function App() {
|
|
70
|
+
* return (
|
|
71
|
+
* <FormProvider schema={schema}>
|
|
72
|
+
* <MyForm />
|
|
73
|
+
* {__DEV__ && <FormDevTools mode="console" autoLog />}
|
|
74
|
+
* </FormProvider>
|
|
75
|
+
* );
|
|
76
|
+
* }
|
|
77
|
+
* ```
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```tsx
|
|
81
|
+
* // Force console mode (works everywhere)
|
|
82
|
+
* <FormDevTools mode="console" autoLog logPrefix="[MyForm]" />
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export declare function FormDevTools({ mode, autoLog, logPrefix, position, defaultOpen, }?: FormDevToolsProps): React.JSX.Element | null;
|
|
86
|
+
//# sourceMappingURL=FormDevTools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormDevTools.d.ts","sourceRoot":"","sources":["../../../src/devtools/FormDevTools.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoC,MAAM,OAAO,CAAC;AAMzD;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAAC;AAErD,MAAM,WAAW,iBAAiB;IAChC;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,QAAQ,CAAC,EAAE,UAAU,GAAG,WAAW,GAAG,aAAa,GAAG,cAAc,CAAC;IACrE;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAQD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAEH,wBAAgB,YAAY,CAAC,EAC3B,IAAuC,EACvC,OAAe,EACf,SAA4B,EAC5B,QAAyB,EACzB,WAAkB,GACnB,GAAE,iBAAsB,4BAqMxB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/devtools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAC5C,YAAY,EAAC,iBAAiB,EAAC,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAClC,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAC,kBAAkB,EAAE,wBAAwB,EAAC,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { FormContextValue } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Hook to access form context
|
|
4
|
+
*
|
|
5
|
+
* Must be used within a FormProvider component.
|
|
6
|
+
* Provides access to form state, values, errors, and methods.
|
|
7
|
+
*
|
|
8
|
+
* @returns Form context value with state and methods
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```tsx
|
|
12
|
+
* function MyFormField() {
|
|
13
|
+
* const {values, errors, changeValue, validateField} = useForm();
|
|
14
|
+
*
|
|
15
|
+
* return (
|
|
16
|
+
* <div>
|
|
17
|
+
* <input
|
|
18
|
+
* value={values.email || ''}
|
|
19
|
+
* onChange={(e) => changeValue({name: 'email', value: e.target.value})}
|
|
20
|
+
* onBlur={() => validateField('email')}
|
|
21
|
+
* />
|
|
22
|
+
* {errors.email && <span>{errors.email}</span>}
|
|
23
|
+
* </div>
|
|
24
|
+
* );
|
|
25
|
+
* }
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare function useForm(): FormContextValue;
|
|
29
|
+
export default useForm;
|
|
30
|
+
//# sourceMappingURL=useForm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useForm.d.ts","sourceRoot":"","sources":["../../../src/hooks/useForm.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,gBAAgB,EAAC,MAAM,UAAU,CAAC;AAG1C;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,OAAO,IAAI,gBAAgB,CAa1C;AAED,eAAe,OAAO,CAAC"}
|