@weser/form 1.0.0 → 1.0.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/dist/__tests__/createForm.test.d.ts +2 -0
- package/dist/__tests__/createForm.test.d.ts.map +1 -0
- package/dist/__tests__/createForm.test.jsx +136 -0
- package/dist/__tests__/createForm.test.jsx.map +1 -0
- package/dist/__tests__/useField.test.d.ts +2 -0
- package/dist/__tests__/useField.test.d.ts.map +1 -0
- package/dist/__tests__/useField.test.js +203 -0
- package/dist/__tests__/useField.test.js.map +1 -0
- package/dist/__tests__/useForm.test.d.ts +2 -0
- package/dist/__tests__/useForm.test.d.ts.map +1 -0
- package/dist/__tests__/useForm.test.js +170 -0
- package/dist/__tests__/useForm.test.js.map +1 -0
- package/dist/createForm.d.ts +3 -3
- package/package.json +10 -7
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createForm.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/createForm.test.tsx"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { describe, test, expect, vi, afterEach } from 'vitest';
|
|
3
|
+
import { render, screen, renderHook, cleanup } from '@testing-library/react';
|
|
4
|
+
import z from 'zod';
|
|
5
|
+
import createForm from '../createForm';
|
|
6
|
+
afterEach(() => {
|
|
7
|
+
cleanup();
|
|
8
|
+
});
|
|
9
|
+
describe('createForm', () => {
|
|
10
|
+
const schema = z.object({
|
|
11
|
+
name: z.string().min(1),
|
|
12
|
+
email: z.string().email(),
|
|
13
|
+
});
|
|
14
|
+
test('returns useForm, useFormContext, FormProvider, and Field', () => {
|
|
15
|
+
const form = createForm(schema);
|
|
16
|
+
expect(form.useForm).toBeDefined();
|
|
17
|
+
expect(typeof form.useForm).toBe('function');
|
|
18
|
+
expect(form.useFormContext).toBeDefined();
|
|
19
|
+
expect(typeof form.useFormContext).toBe('function');
|
|
20
|
+
expect(form.FormProvider).toBeDefined();
|
|
21
|
+
expect(typeof form.FormProvider).toBe('function');
|
|
22
|
+
expect(form.Field).toBeDefined();
|
|
23
|
+
expect(typeof form.Field).toBe('function');
|
|
24
|
+
});
|
|
25
|
+
test('useForm returns form handlers', () => {
|
|
26
|
+
const { useForm } = createForm(schema);
|
|
27
|
+
const { result } = renderHook(() => useForm());
|
|
28
|
+
expect(result.current.useFormField).toBeDefined();
|
|
29
|
+
expect(result.current.handleSubmit).toBeDefined();
|
|
30
|
+
expect(result.current.reset).toBeDefined();
|
|
31
|
+
expect(result.current.checkDirty).toBeDefined();
|
|
32
|
+
});
|
|
33
|
+
test('FormProvider and useFormContext work together', () => {
|
|
34
|
+
const { useForm, useFormContext, FormProvider } = createForm(schema);
|
|
35
|
+
function FormContent() {
|
|
36
|
+
const form = useFormContext();
|
|
37
|
+
return (<div data-testid="form-available">
|
|
38
|
+
{form ? 'Form Available' : 'No Form'}
|
|
39
|
+
</div>);
|
|
40
|
+
}
|
|
41
|
+
function TestForm() {
|
|
42
|
+
const form = useForm();
|
|
43
|
+
return (<FormProvider value={form}>
|
|
44
|
+
<FormContent />
|
|
45
|
+
</FormProvider>);
|
|
46
|
+
}
|
|
47
|
+
render(<TestForm />);
|
|
48
|
+
expect(screen.getByTestId('form-available').textContent).toBe('Form Available');
|
|
49
|
+
});
|
|
50
|
+
test('Field component renders with field data', () => {
|
|
51
|
+
const { useForm, FormProvider, Field } = createForm(schema);
|
|
52
|
+
function TestForm() {
|
|
53
|
+
const form = useForm();
|
|
54
|
+
return (<FormProvider value={form}>
|
|
55
|
+
<Field name="name">
|
|
56
|
+
{(field) => (<input data-testid="name-input" {...field.inputProps} placeholder="Name"/>)}
|
|
57
|
+
</Field>
|
|
58
|
+
</FormProvider>);
|
|
59
|
+
}
|
|
60
|
+
render(<TestForm />);
|
|
61
|
+
const input = screen.getByTestId('name-input');
|
|
62
|
+
expect(input).toBeDefined();
|
|
63
|
+
expect(input.getAttribute('name')).toBe('name');
|
|
64
|
+
});
|
|
65
|
+
test('Field component provides field state', () => {
|
|
66
|
+
const { useForm, FormProvider, Field } = createForm(schema);
|
|
67
|
+
function TestForm() {
|
|
68
|
+
const form = useForm();
|
|
69
|
+
return (<FormProvider value={form}>
|
|
70
|
+
<Field name="email" value="test@example.com">
|
|
71
|
+
{(field) => (<div>
|
|
72
|
+
<input data-testid="email-input" {...field.inputProps}/>
|
|
73
|
+
<span data-testid="email-valid">{String(field.valid)}</span>
|
|
74
|
+
</div>)}
|
|
75
|
+
</Field>
|
|
76
|
+
</FormProvider>);
|
|
77
|
+
}
|
|
78
|
+
render(<TestForm />);
|
|
79
|
+
expect(screen.getByTestId('email-valid').textContent).toBe('true');
|
|
80
|
+
});
|
|
81
|
+
test('Field component shows error for invalid value', () => {
|
|
82
|
+
const { useForm, FormProvider, Field } = createForm(schema);
|
|
83
|
+
function TestForm() {
|
|
84
|
+
const form = useForm();
|
|
85
|
+
return (<FormProvider value={form}>
|
|
86
|
+
<Field name="email" value="invalid-email" touched>
|
|
87
|
+
{(field) => (<div>
|
|
88
|
+
<input data-testid="email-input" {...field.inputProps}/>
|
|
89
|
+
<span data-testid="email-error">{field.errorMessage || ''}</span>
|
|
90
|
+
</div>)}
|
|
91
|
+
</Field>
|
|
92
|
+
</FormProvider>);
|
|
93
|
+
}
|
|
94
|
+
render(<TestForm />);
|
|
95
|
+
expect(screen.getByTestId('email-error').textContent).toBeTruthy();
|
|
96
|
+
});
|
|
97
|
+
test('useFormContext throws when used outside FormProvider', () => {
|
|
98
|
+
const { useFormContext } = createForm(schema);
|
|
99
|
+
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => { });
|
|
100
|
+
expect(() => {
|
|
101
|
+
renderHook(() => useFormContext());
|
|
102
|
+
}).toThrow();
|
|
103
|
+
consoleSpy.mockRestore();
|
|
104
|
+
});
|
|
105
|
+
test('Field passes additional options to useField', () => {
|
|
106
|
+
const { useForm, FormProvider, Field } = createForm(schema);
|
|
107
|
+
function TestForm() {
|
|
108
|
+
const form = useForm();
|
|
109
|
+
return (<FormProvider value={form}>
|
|
110
|
+
<Field name="name" disabled>
|
|
111
|
+
{(field) => (<input data-testid="name-input" {...field.inputProps} data-disabled={String(field.disabled)}/>)}
|
|
112
|
+
</Field>
|
|
113
|
+
</FormProvider>);
|
|
114
|
+
}
|
|
115
|
+
render(<TestForm />);
|
|
116
|
+
expect(screen.getByTestId('name-input').getAttribute('data-disabled')).toBe('true');
|
|
117
|
+
});
|
|
118
|
+
test('multiple Fields work correctly', () => {
|
|
119
|
+
const { useForm, FormProvider, Field } = createForm(schema);
|
|
120
|
+
function TestForm() {
|
|
121
|
+
const form = useForm();
|
|
122
|
+
return (<FormProvider value={form}>
|
|
123
|
+
<Field name="name" value="John">
|
|
124
|
+
{(field) => (<input data-testid="name-input" {...field.inputProps}/>)}
|
|
125
|
+
</Field>
|
|
126
|
+
<Field name="email" value="john@example.com">
|
|
127
|
+
{(field) => (<input data-testid="email-input" {...field.inputProps}/>)}
|
|
128
|
+
</Field>
|
|
129
|
+
</FormProvider>);
|
|
130
|
+
}
|
|
131
|
+
render(<TestForm />);
|
|
132
|
+
expect(screen.getByTestId('name-input').value).toBe('John');
|
|
133
|
+
expect(screen.getByTestId('email-input').value).toBe('john@example.com');
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
//# sourceMappingURL=createForm.test.jsx.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createForm.test.jsx","sourceRoot":"","sources":["../../src/__tests__/createForm.test.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAA;AAC5E,OAAO,CAAC,MAAM,KAAK,CAAA;AAEnB,OAAO,UAAU,MAAM,eAAe,CAAA;AAEtC,SAAS,CAAC,GAAG,EAAE;IACb,OAAO,EAAE,CAAA;AACX,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;QACtB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACvB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE;KAC1B,CAAC,CAAA;IAEF,IAAI,CAAC,0DAA0D,EAAE,GAAG,EAAE;QACpE,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,CAAA;QAE/B,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAA;QAClC,MAAM,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QAC5C,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,WAAW,EAAE,CAAA;QACzC,MAAM,CAAC,OAAO,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QACnD,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CAAA;QACvC,MAAM,CAAC,OAAO,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QACjD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAA;QAChC,MAAM,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IAC5C,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACzC,MAAM,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,CAAA;QAEtC,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAA;QAE9C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CAAA;QACjD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CAAA;QACjD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAA;QAC1C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAA;IACjD,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACzD,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,CAAA;QAEpE,SAAS,WAAW;YAClB,MAAM,IAAI,GAAG,cAAc,EAAE,CAAA;YAC7B,OAAO,CACL,CAAC,GAAG,CAAC,WAAW,CAAC,gBAAgB,CAC/B;UAAA,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS,CACtC;QAAA,EAAE,GAAG,CAAC,CACP,CAAA;QACH,CAAC;QAED,SAAS,QAAQ;YACf,MAAM,IAAI,GAAG,OAAO,EAAE,CAAA;YACtB,OAAO,CACL,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CACxB;UAAA,CAAC,WAAW,CAAC,AAAD,EACd;QAAA,EAAE,YAAY,CAAC,CAChB,CAAA;QACH,CAAC;QAED,MAAM,CAAC,CAAC,QAAQ,CAAC,AAAD,EAAG,CAAC,CAAA;QAEpB,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,CAC3D,gBAAgB,CACjB,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACnD,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,CAAA;QAE3D,SAAS,QAAQ;YACf,MAAM,IAAI,GAAG,OAAO,EAAE,CAAA;YACtB,OAAO,CACL,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CACxB;UAAA,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAChB;YAAA,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CACV,CAAC,KAAK,CACJ,WAAW,CAAC,YAAY,CACxB,IAAI,KAAK,CAAC,UAAU,CAAC,CACrB,WAAW,CAAC,MAAM,EAClB,CACH,CACH;UAAA,EAAE,KAAK,CACT;QAAA,EAAE,YAAY,CAAC,CAChB,CAAA;QACH,CAAC;QAED,MAAM,CAAC,CAAC,QAAQ,CAAC,AAAD,EAAG,CAAC,CAAA;QAEpB,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,CAAA;QAC9C,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAA;QAC3B,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACjD,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAChD,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,CAAA;QAE3D,SAAS,QAAQ;YACf,MAAM,IAAI,GAAG,OAAO,EAAE,CAAA;YACtB,OAAO,CACL,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CACxB;UAAA,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAC1C;YAAA,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CACV,CAAC,GAAG,CACF;gBAAA,CAAC,KAAK,CAAC,WAAW,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,EACtD;gBAAA,CAAC,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAC7D;cAAA,EAAE,GAAG,CAAC,CACP,CACH;UAAA,EAAE,KAAK,CACT;QAAA,EAAE,YAAY,CAAC,CAChB,CAAA;QACH,CAAC;QAED,MAAM,CAAC,CAAC,QAAQ,CAAC,AAAD,EAAG,CAAC,CAAA;QAEpB,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACpE,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACzD,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,CAAA;QAE3D,SAAS,QAAQ;YACf,MAAM,IAAI,GAAG,OAAO,EAAE,CAAA;YACtB,OAAO,CACL,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CACxB;UAAA,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,OAAO,CAC/C;YAAA,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CACV,CAAC,GAAG,CACF;gBAAA,CAAC,KAAK,CAAC,WAAW,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,EACtD;gBAAA,CAAC,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,KAAK,CAAC,YAAY,IAAI,EAAE,CAAC,EAAE,IAAI,CAClE;cAAA,EAAE,GAAG,CAAC,CACP,CACH;UAAA,EAAE,KAAK,CACT;QAAA,EAAE,YAAY,CAAC,CAChB,CAAA;QACH,CAAC;QAED,MAAM,CAAC,CAAC,QAAQ,CAAC,AAAD,EAAG,CAAC,CAAA;QAEpB,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,WAAW,CAAC,CAAC,UAAU,EAAE,CAAA;IACpE,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAChE,MAAM,EAAE,cAAc,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,CAAA;QAE7C,MAAM,UAAU,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;QAE1E,MAAM,CAAC,GAAG,EAAE;YACV,UAAU,CAAC,GAAG,EAAE,CAAC,cAAc,EAAE,CAAC,CAAA;QACpC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAA;QAEZ,UAAU,CAAC,WAAW,EAAE,CAAA;IAC1B,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACvD,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,CAAA;QAE3D,SAAS,QAAQ;YACf,MAAM,IAAI,GAAG,OAAO,EAAE,CAAA;YACtB,OAAO,CACL,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CACxB;UAAA,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CACzB;YAAA,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CACV,CAAC,KAAK,CACJ,WAAW,CAAC,YAAY,CACxB,IAAI,KAAK,CAAC,UAAU,CAAC,CACrB,aAAa,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EACtC,CACH,CACH;UAAA,EAAE,KAAK,CACT;QAAA,EAAE,YAAY,CAAC,CAChB,CAAA;QACH,CAAC;QAED,MAAM,CAAC,CAAC,QAAQ,CAAC,AAAD,EAAG,CAAC,CAAA;QAEpB,MAAM,CACJ,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,eAAe,CAAC,CAC/D,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IAChB,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,gCAAgC,EAAE,GAAG,EAAE;QAC1C,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,CAAA;QAE3D,SAAS,QAAQ;YACf,MAAM,IAAI,GAAG,OAAO,EAAE,CAAA;YACtB,OAAO,CACL,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CACxB;UAAA,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAC7B;YAAA,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CACV,CAAC,KAAK,CAAC,WAAW,CAAC,YAAY,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,EAAG,CACzD,CACH;UAAA,EAAE,KAAK,CACP;UAAA,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAC1C;YAAA,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CACV,CAAC,KAAK,CAAC,WAAW,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,EAAG,CAC1D,CACH;UAAA,EAAE,KAAK,CACT;QAAA,EAAE,YAAY,CAAC,CAChB,CAAA;QACH,CAAC;QAED,MAAM,CAAC,CAAC,QAAQ,CAAC,AAAD,EAAG,CAAC,CAAA;QAEpB,MAAM,CACH,MAAM,CAAC,WAAW,CAAC,YAAY,CAAsB,CAAC,KAAK,CAC7D,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACd,MAAM,CACH,MAAM,CAAC,WAAW,CAAC,aAAa,CAAsB,CAAC,KAAK,CAC9D,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAA;IAC5B,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useField.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/useField.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { describe, test, expect } from 'vitest';
|
|
2
|
+
import { renderHook, act } from '@testing-library/react';
|
|
3
|
+
import z from 'zod';
|
|
4
|
+
import useField from '../useField';
|
|
5
|
+
describe('useField', () => {
|
|
6
|
+
const stringSchema = z.string().min(1);
|
|
7
|
+
const emailSchema = z.string().email();
|
|
8
|
+
test('initializes with default values', () => {
|
|
9
|
+
const { result } = renderHook(() => useField(stringSchema));
|
|
10
|
+
expect(result.current.value).toBe('');
|
|
11
|
+
expect(result.current.touched).toBe(false);
|
|
12
|
+
expect(result.current.dirty).toBe(false);
|
|
13
|
+
expect(result.current.disabled).toBe(false);
|
|
14
|
+
});
|
|
15
|
+
test('initializes with provided value', () => {
|
|
16
|
+
const { result } = renderHook(() => useField(stringSchema, { value: 'initial' }));
|
|
17
|
+
expect(result.current.value).toBe('initial');
|
|
18
|
+
});
|
|
19
|
+
test('update changes the value', () => {
|
|
20
|
+
const { result } = renderHook(() => useField(stringSchema));
|
|
21
|
+
act(() => {
|
|
22
|
+
result.current.update({ value: 'new value' });
|
|
23
|
+
});
|
|
24
|
+
expect(result.current.value).toBe('new value');
|
|
25
|
+
});
|
|
26
|
+
test('tracks dirty state', () => {
|
|
27
|
+
const { result } = renderHook(() => useField(stringSchema, { value: 'initial' }));
|
|
28
|
+
expect(result.current.dirty).toBe(false);
|
|
29
|
+
act(() => {
|
|
30
|
+
result.current.update({ value: 'changed' });
|
|
31
|
+
});
|
|
32
|
+
expect(result.current.dirty).toBe(true);
|
|
33
|
+
});
|
|
34
|
+
test('validates against schema', () => {
|
|
35
|
+
const { result } = renderHook(() => useField(emailSchema, { value: 'invalid', touched: true }));
|
|
36
|
+
expect(result.current.valid).toBe(false);
|
|
37
|
+
expect(result.current.errorMessage).toBeDefined();
|
|
38
|
+
});
|
|
39
|
+
test('shows valid for valid input', () => {
|
|
40
|
+
const { result } = renderHook(() => useField(emailSchema, { value: 'test@example.com', touched: true }));
|
|
41
|
+
expect(result.current.valid).toBe(true);
|
|
42
|
+
expect(result.current.errorMessage).toBeUndefined();
|
|
43
|
+
});
|
|
44
|
+
test('reset returns to initial state', () => {
|
|
45
|
+
const { result } = renderHook(() => useField(stringSchema, { value: 'initial' }));
|
|
46
|
+
act(() => {
|
|
47
|
+
result.current.update({ value: 'changed' });
|
|
48
|
+
});
|
|
49
|
+
expect(result.current.value).toBe('changed');
|
|
50
|
+
act(() => {
|
|
51
|
+
result.current.reset();
|
|
52
|
+
});
|
|
53
|
+
expect(result.current.value).toBe('initial');
|
|
54
|
+
expect(result.current.dirty).toBe(false);
|
|
55
|
+
});
|
|
56
|
+
test('provides inputProps for form binding', () => {
|
|
57
|
+
const { result } = renderHook(() => useField(stringSchema, { name: 'test-field' }));
|
|
58
|
+
expect(result.current.inputProps).toHaveProperty('value');
|
|
59
|
+
expect(result.current.inputProps).toHaveProperty('onChange');
|
|
60
|
+
expect(result.current.inputProps).toHaveProperty('name', 'test-field');
|
|
61
|
+
expect(result.current.inputProps).toHaveProperty('disabled', false);
|
|
62
|
+
});
|
|
63
|
+
test('provides props with validation info', () => {
|
|
64
|
+
const { result } = renderHook(() => useField(stringSchema, { name: 'test' }));
|
|
65
|
+
expect(result.current.props).toHaveProperty('valid');
|
|
66
|
+
expect(result.current.props).toHaveProperty('errorMessage');
|
|
67
|
+
});
|
|
68
|
+
test('validate returns safeParse result', () => {
|
|
69
|
+
const { result } = renderHook(() => useField(emailSchema, { value: 'invalid' }));
|
|
70
|
+
const validation = result.current.validate();
|
|
71
|
+
expect(validation.success).toBe(false);
|
|
72
|
+
expect(validation.error).toBeDefined();
|
|
73
|
+
});
|
|
74
|
+
test('validate returns success for valid input', () => {
|
|
75
|
+
const { result } = renderHook(() => useField(emailSchema, { value: 'test@example.com' }));
|
|
76
|
+
const validation = result.current.validate();
|
|
77
|
+
expect(validation.success).toBe(true);
|
|
78
|
+
});
|
|
79
|
+
test('showValidationOn change marks touched on value change', () => {
|
|
80
|
+
const { result } = renderHook(() => useField(stringSchema, { showValidationOn: 'change' }));
|
|
81
|
+
expect(result.current.touched).toBe(false);
|
|
82
|
+
act(() => {
|
|
83
|
+
result.current.update({ value: 'changed' });
|
|
84
|
+
});
|
|
85
|
+
expect(result.current.touched).toBe(true);
|
|
86
|
+
});
|
|
87
|
+
test('showValidationOn submit does not mark touched on value change', () => {
|
|
88
|
+
const { result } = renderHook(() => useField(stringSchema, { showValidationOn: 'submit' }));
|
|
89
|
+
expect(result.current.touched).toBe(false);
|
|
90
|
+
act(() => {
|
|
91
|
+
result.current.update({ value: 'changed' });
|
|
92
|
+
});
|
|
93
|
+
expect(result.current.touched).toBe(false);
|
|
94
|
+
});
|
|
95
|
+
test('showValidationOn blur provides onFocus and onBlur in inputProps', () => {
|
|
96
|
+
const { result } = renderHook(() => useField(stringSchema, { showValidationOn: 'blur' }));
|
|
97
|
+
expect(result.current.inputProps).toHaveProperty('onFocus');
|
|
98
|
+
expect(result.current.inputProps).toHaveProperty('onBlur');
|
|
99
|
+
});
|
|
100
|
+
test('formatErrorMessage customizes error message', () => {
|
|
101
|
+
const customFormat = (error, value, name) => `Custom error for ${name}: ${error.code}`;
|
|
102
|
+
const { result } = renderHook(() => useField(emailSchema, {
|
|
103
|
+
name: 'email',
|
|
104
|
+
value: 'invalid',
|
|
105
|
+
touched: true,
|
|
106
|
+
formatErrorMessage: customFormat,
|
|
107
|
+
}));
|
|
108
|
+
expect(result.current.errorMessage).toContain('Custom error for email');
|
|
109
|
+
});
|
|
110
|
+
test('formatValue transforms value for display', () => {
|
|
111
|
+
const formatValue = (value) => value.toUpperCase();
|
|
112
|
+
const { result } = renderHook(() => useField(stringSchema, {
|
|
113
|
+
value: 'hello',
|
|
114
|
+
formatValue,
|
|
115
|
+
}));
|
|
116
|
+
expect(result.current.inputProps.value).toBe('HELLO');
|
|
117
|
+
});
|
|
118
|
+
test('parseEvent extracts value from custom event', () => {
|
|
119
|
+
const parseEvent = (e) => (e.checked ? 'yes' : 'no');
|
|
120
|
+
const { result } = renderHook(() => useField(stringSchema, {
|
|
121
|
+
value: 'no',
|
|
122
|
+
parseEvent,
|
|
123
|
+
}));
|
|
124
|
+
act(() => {
|
|
125
|
+
result.current.inputProps.onChange({ checked: true });
|
|
126
|
+
});
|
|
127
|
+
expect(result.current.value).toBe('yes');
|
|
128
|
+
});
|
|
129
|
+
test('disabled state is reflected in inputProps', () => {
|
|
130
|
+
const { result } = renderHook(() => useField(stringSchema, { disabled: true }));
|
|
131
|
+
expect(result.current.inputProps.disabled).toBe(true);
|
|
132
|
+
expect(result.current.disabled).toBe(true);
|
|
133
|
+
});
|
|
134
|
+
// Tests based on docs examples for generic types
|
|
135
|
+
describe('Generic Types (from docs)', () => {
|
|
136
|
+
test('handles boolean values for checkbox (docs example)', () => {
|
|
137
|
+
const booleanSchema = z.boolean();
|
|
138
|
+
const { result } = renderHook(() => useField(booleanSchema, {
|
|
139
|
+
parseEvent: (e) => e.target.checked,
|
|
140
|
+
value: false,
|
|
141
|
+
}));
|
|
142
|
+
expect(result.current.value).toBe(false);
|
|
143
|
+
act(() => {
|
|
144
|
+
result.current.inputProps.onChange({ target: { checked: true } });
|
|
145
|
+
});
|
|
146
|
+
expect(result.current.value).toBe(true);
|
|
147
|
+
});
|
|
148
|
+
test('validates boolean field correctly', () => {
|
|
149
|
+
// Require true (like terms acceptance)
|
|
150
|
+
const acceptTermsSchema = z.literal(true);
|
|
151
|
+
const { result } = renderHook(() => useField(acceptTermsSchema, {
|
|
152
|
+
parseEvent: (e) => e.target.checked,
|
|
153
|
+
value: false,
|
|
154
|
+
touched: true,
|
|
155
|
+
}));
|
|
156
|
+
expect(result.current.valid).toBe(false);
|
|
157
|
+
act(() => {
|
|
158
|
+
result.current.inputProps.onChange({ target: { checked: true } });
|
|
159
|
+
});
|
|
160
|
+
expect(result.current.valid).toBe(true);
|
|
161
|
+
});
|
|
162
|
+
test('handles array values (docs example)', () => {
|
|
163
|
+
const tagsSchema = z.array(z.string());
|
|
164
|
+
const { result } = renderHook(() => useField(tagsSchema, {
|
|
165
|
+
parseEvent: (value) => value,
|
|
166
|
+
value: [],
|
|
167
|
+
}));
|
|
168
|
+
expect(result.current.value).toEqual([]);
|
|
169
|
+
act(() => {
|
|
170
|
+
result.current.inputProps.onChange(['tag1', 'tag2']);
|
|
171
|
+
});
|
|
172
|
+
expect(result.current.value).toEqual(['tag1', 'tag2']);
|
|
173
|
+
});
|
|
174
|
+
test('validates array with minimum items', () => {
|
|
175
|
+
const tagsSchema = z.array(z.string()).min(1, 'At least one tag required');
|
|
176
|
+
const { result } = renderHook(() => useField(tagsSchema, {
|
|
177
|
+
parseEvent: (value) => value,
|
|
178
|
+
value: [],
|
|
179
|
+
touched: true,
|
|
180
|
+
}));
|
|
181
|
+
expect(result.current.valid).toBe(false);
|
|
182
|
+
expect(result.current.errorMessage).toBeDefined();
|
|
183
|
+
act(() => {
|
|
184
|
+
result.current.inputProps.onChange(['tag1']);
|
|
185
|
+
});
|
|
186
|
+
expect(result.current.valid).toBe(true);
|
|
187
|
+
expect(result.current.errorMessage).toBeUndefined();
|
|
188
|
+
});
|
|
189
|
+
test('number type with custom parsing', () => {
|
|
190
|
+
const numberSchema = z.number().min(0).max(100);
|
|
191
|
+
const { result } = renderHook(() => useField(numberSchema, {
|
|
192
|
+
parseEvent: (e) => parseInt(e.target.value) || 0,
|
|
193
|
+
value: 50,
|
|
194
|
+
}));
|
|
195
|
+
expect(result.current.value).toBe(50);
|
|
196
|
+
act(() => {
|
|
197
|
+
result.current.inputProps.onChange({ target: { value: '75' } });
|
|
198
|
+
});
|
|
199
|
+
expect(result.current.value).toBe(75);
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
//# sourceMappingURL=useField.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useField.test.js","sourceRoot":"","sources":["../../src/__tests__/useField.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useForm.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/useForm.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { describe, test, expect, vi } from 'vitest';
|
|
2
|
+
import { renderHook, act } from '@testing-library/react';
|
|
3
|
+
import z from 'zod';
|
|
4
|
+
import useForm from '../useForm';
|
|
5
|
+
describe('useForm', () => {
|
|
6
|
+
const schema = z.object({
|
|
7
|
+
name: z.string().min(1),
|
|
8
|
+
email: z.string().email(),
|
|
9
|
+
});
|
|
10
|
+
test('provides useFormField hook', () => {
|
|
11
|
+
const { result } = renderHook(() => useForm(schema));
|
|
12
|
+
expect(result.current.useFormField).toBeDefined();
|
|
13
|
+
expect(typeof result.current.useFormField).toBe('function');
|
|
14
|
+
});
|
|
15
|
+
test('provides handleSubmit function', () => {
|
|
16
|
+
const { result } = renderHook(() => useForm(schema));
|
|
17
|
+
expect(result.current.handleSubmit).toBeDefined();
|
|
18
|
+
expect(typeof result.current.handleSubmit).toBe('function');
|
|
19
|
+
});
|
|
20
|
+
test('provides reset function', () => {
|
|
21
|
+
const { result } = renderHook(() => useForm(schema));
|
|
22
|
+
expect(result.current.reset).toBeDefined();
|
|
23
|
+
expect(typeof result.current.reset).toBe('function');
|
|
24
|
+
});
|
|
25
|
+
test('provides checkDirty function', () => {
|
|
26
|
+
const { result } = renderHook(() => useForm(schema));
|
|
27
|
+
expect(result.current.checkDirty).toBeDefined();
|
|
28
|
+
expect(typeof result.current.checkDirty).toBe('function');
|
|
29
|
+
});
|
|
30
|
+
test('isValidating is initially false', () => {
|
|
31
|
+
const { result } = renderHook(() => useForm(schema));
|
|
32
|
+
expect(result.current.isValidating).toBe(false);
|
|
33
|
+
});
|
|
34
|
+
test('useFormField creates a field with schema validation', () => {
|
|
35
|
+
const { result } = renderHook(() => {
|
|
36
|
+
const form = useForm(schema);
|
|
37
|
+
const nameField = form.useFormField('name');
|
|
38
|
+
const emailField = form.useFormField('email');
|
|
39
|
+
return { form, nameField, emailField };
|
|
40
|
+
});
|
|
41
|
+
expect(result.current.nameField.value).toBe('');
|
|
42
|
+
expect(result.current.emailField.value).toBe('');
|
|
43
|
+
});
|
|
44
|
+
test('useFormField updates work correctly', () => {
|
|
45
|
+
const { result } = renderHook(() => {
|
|
46
|
+
const form = useForm(schema);
|
|
47
|
+
const nameField = form.useFormField('name');
|
|
48
|
+
return { form, nameField };
|
|
49
|
+
});
|
|
50
|
+
act(() => {
|
|
51
|
+
result.current.nameField.update({ value: 'John' });
|
|
52
|
+
});
|
|
53
|
+
expect(result.current.nameField.value).toBe('John');
|
|
54
|
+
});
|
|
55
|
+
test('checkDirty returns false when no fields are modified', () => {
|
|
56
|
+
const { result } = renderHook(() => {
|
|
57
|
+
const form = useForm(schema);
|
|
58
|
+
form.useFormField('name');
|
|
59
|
+
form.useFormField('email');
|
|
60
|
+
return form;
|
|
61
|
+
});
|
|
62
|
+
expect(result.current.checkDirty()).toBe(false);
|
|
63
|
+
});
|
|
64
|
+
test('checkDirty returns true when a field is modified', () => {
|
|
65
|
+
const { result } = renderHook(() => {
|
|
66
|
+
const form = useForm(schema);
|
|
67
|
+
const nameField = form.useFormField('name');
|
|
68
|
+
return { form, nameField };
|
|
69
|
+
});
|
|
70
|
+
act(() => {
|
|
71
|
+
result.current.nameField.update({ value: 'Modified' });
|
|
72
|
+
});
|
|
73
|
+
expect(result.current.form.checkDirty()).toBe(true);
|
|
74
|
+
});
|
|
75
|
+
test('reset resets all fields to initial state', () => {
|
|
76
|
+
const { result } = renderHook(() => {
|
|
77
|
+
const form = useForm(schema);
|
|
78
|
+
const nameField = form.useFormField('name');
|
|
79
|
+
const emailField = form.useFormField('email');
|
|
80
|
+
return { form, nameField, emailField };
|
|
81
|
+
});
|
|
82
|
+
act(() => {
|
|
83
|
+
result.current.nameField.update({ value: 'John' });
|
|
84
|
+
result.current.emailField.update({ value: 'john@example.com' });
|
|
85
|
+
});
|
|
86
|
+
expect(result.current.nameField.value).toBe('John');
|
|
87
|
+
expect(result.current.emailField.value).toBe('john@example.com');
|
|
88
|
+
act(() => {
|
|
89
|
+
result.current.form.reset();
|
|
90
|
+
});
|
|
91
|
+
expect(result.current.nameField.value).toBe('');
|
|
92
|
+
expect(result.current.emailField.value).toBe('');
|
|
93
|
+
});
|
|
94
|
+
test('handleSubmit calls onSubmit with valid data', async () => {
|
|
95
|
+
const onSubmit = vi.fn();
|
|
96
|
+
const onError = vi.fn();
|
|
97
|
+
const { result } = renderHook(() => {
|
|
98
|
+
const form = useForm(schema);
|
|
99
|
+
const nameField = form.useFormField('name');
|
|
100
|
+
const emailField = form.useFormField('email');
|
|
101
|
+
return { form, nameField, emailField };
|
|
102
|
+
});
|
|
103
|
+
act(() => {
|
|
104
|
+
result.current.nameField.update({ value: 'John' });
|
|
105
|
+
result.current.emailField.update({ value: 'john@example.com' });
|
|
106
|
+
});
|
|
107
|
+
const mockEvent = {
|
|
108
|
+
stopPropagation: vi.fn(),
|
|
109
|
+
preventDefault: vi.fn(),
|
|
110
|
+
};
|
|
111
|
+
await act(async () => {
|
|
112
|
+
await result.current.form.handleSubmit(onSubmit, onError)(mockEvent);
|
|
113
|
+
});
|
|
114
|
+
expect(onSubmit).toHaveBeenCalledWith({
|
|
115
|
+
name: 'John',
|
|
116
|
+
email: 'john@example.com',
|
|
117
|
+
});
|
|
118
|
+
expect(onError).not.toHaveBeenCalled();
|
|
119
|
+
});
|
|
120
|
+
test('handleSubmit calls onError with invalid data', async () => {
|
|
121
|
+
const onSubmit = vi.fn();
|
|
122
|
+
const onError = vi.fn();
|
|
123
|
+
const { result } = renderHook(() => {
|
|
124
|
+
const form = useForm(schema);
|
|
125
|
+
const nameField = form.useFormField('name');
|
|
126
|
+
const emailField = form.useFormField('email');
|
|
127
|
+
return { form, nameField, emailField };
|
|
128
|
+
});
|
|
129
|
+
// Leave fields empty (invalid)
|
|
130
|
+
const mockEvent = {
|
|
131
|
+
stopPropagation: vi.fn(),
|
|
132
|
+
preventDefault: vi.fn(),
|
|
133
|
+
};
|
|
134
|
+
await act(async () => {
|
|
135
|
+
await result.current.form.handleSubmit(onSubmit, onError)(mockEvent);
|
|
136
|
+
});
|
|
137
|
+
expect(onSubmit).not.toHaveBeenCalled();
|
|
138
|
+
expect(onError).toHaveBeenCalled();
|
|
139
|
+
});
|
|
140
|
+
test('handleSubmit touches all fields on submit', async () => {
|
|
141
|
+
const { result } = renderHook(() => {
|
|
142
|
+
const form = useForm(schema);
|
|
143
|
+
const nameField = form.useFormField('name');
|
|
144
|
+
const emailField = form.useFormField('email');
|
|
145
|
+
return { form, nameField, emailField };
|
|
146
|
+
});
|
|
147
|
+
expect(result.current.nameField.touched).toBe(false);
|
|
148
|
+
expect(result.current.emailField.touched).toBe(false);
|
|
149
|
+
const mockEvent = {
|
|
150
|
+
stopPropagation: vi.fn(),
|
|
151
|
+
preventDefault: vi.fn(),
|
|
152
|
+
};
|
|
153
|
+
await act(async () => {
|
|
154
|
+
await result.current.form.handleSubmit(vi.fn(), vi.fn())(mockEvent);
|
|
155
|
+
});
|
|
156
|
+
expect(result.current.nameField.touched).toBe(true);
|
|
157
|
+
expect(result.current.emailField.touched).toBe(true);
|
|
158
|
+
});
|
|
159
|
+
test('formatErrorMessage config customizes error messages', () => {
|
|
160
|
+
const customFormat = () => 'Custom error';
|
|
161
|
+
const { result } = renderHook(() => {
|
|
162
|
+
const form = useForm(schema, { formatErrorMessage: customFormat });
|
|
163
|
+
const nameField = form.useFormField('name', { touched: true });
|
|
164
|
+
return { form, nameField };
|
|
165
|
+
});
|
|
166
|
+
// Name is empty, so should be invalid
|
|
167
|
+
expect(result.current.nameField.errorMessage).toBe('Custom error');
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
//# sourceMappingURL=useForm.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useForm.test.js","sourceRoot":"","sources":["../../src/__tests__/useForm.test.ts"],"names":[],"mappings":"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"}
|
package/dist/createForm.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { ChangeEvent, ReactNode } from 'react';
|
|
|
3
3
|
export default function createForm<T extends ZodRawShape>(schema: ZodObject<T>): {
|
|
4
4
|
useForm: () => {
|
|
5
5
|
isValidating: boolean;
|
|
6
|
-
useFormField: <T_1 = string, C = ChangeEvent<HTMLInputElement>>(_name: keyof T, options?: Omit<import("./types").Options<T_1, C>, "
|
|
6
|
+
useFormField: <T_1 = string, C = ChangeEvent<HTMLInputElement>>(_name: keyof T, options?: Omit<import("./types").Options<T_1, C>, "_storedField" | "name" | "formatErrorMessage" | "_onInit" | "_onUpdate">) => {
|
|
7
7
|
valid: boolean;
|
|
8
8
|
update: (data: Partial<import("./types").T_Field<T_1>>) => void;
|
|
9
9
|
reset: () => void;
|
|
@@ -65,7 +65,7 @@ export default function createForm<T extends ZodRawShape>(schema: ZodObject<T>):
|
|
|
65
65
|
};
|
|
66
66
|
useFormContext: () => {
|
|
67
67
|
isValidating: boolean;
|
|
68
|
-
useFormField: <T_1 = string, C = ChangeEvent<HTMLInputElement>>(_name: keyof T, options?: Omit<import("./types").Options<T_1, C>, "
|
|
68
|
+
useFormField: <T_1 = string, C = ChangeEvent<HTMLInputElement>>(_name: keyof T, options?: Omit<import("./types").Options<T_1, C>, "_storedField" | "name" | "formatErrorMessage" | "_onInit" | "_onUpdate">) => {
|
|
69
69
|
valid: boolean;
|
|
70
70
|
update: (data: Partial<import("./types").T_Field<T_1>>) => void;
|
|
71
71
|
reset: () => void;
|
|
@@ -128,7 +128,7 @@ export default function createForm<T extends ZodRawShape>(schema: ZodObject<T>):
|
|
|
128
128
|
FormProvider: import("react").ComponentType<{
|
|
129
129
|
value: {
|
|
130
130
|
isValidating: boolean;
|
|
131
|
-
useFormField: <T_1 = string, C = ChangeEvent<HTMLInputElement>>(_name: keyof T, options?: Omit<import("./types").Options<T_1, C>, "
|
|
131
|
+
useFormField: <T_1 = string, C = ChangeEvent<HTMLInputElement>>(_name: keyof T, options?: Omit<import("./types").Options<T_1, C>, "_storedField" | "name" | "formatErrorMessage" | "_onInit" | "_onUpdate">) => {
|
|
132
132
|
valid: boolean;
|
|
133
133
|
update: (data: Partial<import("./types").T_Field<T_1>>) => void;
|
|
134
134
|
reset: () => void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weser/form",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "React hooks for forms with zod schemas",
|
|
5
5
|
"author": "Robin Weser <robin@weser.io>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"clean": "rimraf dist",
|
|
34
34
|
"build": "tsc -b",
|
|
35
35
|
"dev": "pnpm build -w",
|
|
36
|
-
"test": "
|
|
36
|
+
"test": "vitest run"
|
|
37
37
|
},
|
|
38
38
|
"keywords": [
|
|
39
39
|
"react",
|
|
@@ -44,19 +44,22 @@
|
|
|
44
44
|
"zod"
|
|
45
45
|
],
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@weser/context": "1.0.
|
|
47
|
+
"@weser/context": "1.0.2"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
50
|
"react": ">16.3.0",
|
|
51
51
|
"zod": ">=4"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
|
-
"@
|
|
55
|
-
"
|
|
56
|
-
"
|
|
54
|
+
"@testing-library/react": "^16.0.0",
|
|
55
|
+
"@types/react": "^19.0.0",
|
|
56
|
+
"jsdom": "^25.0.1",
|
|
57
|
+
"react": "19.3.0-canary-d2908752-20260119",
|
|
58
|
+
"react-dom": "19.3.0-canary-d2908752-20260119",
|
|
57
59
|
"rimraf": "^3.0.2",
|
|
58
60
|
"typescript": "^5.4.5",
|
|
61
|
+
"vitest": "^3.0.0",
|
|
59
62
|
"zod": "^4.1.11"
|
|
60
63
|
},
|
|
61
|
-
"gitHead": "
|
|
64
|
+
"gitHead": "07cd8acd29e916cf20fe509029328862df87b08d"
|
|
62
65
|
}
|