@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.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=createForm.test.d.ts.map
@@ -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":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=useField.test.d.ts.map
@@ -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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=useForm.test.d.ts.map
@@ -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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"}
@@ -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>, "name" | "formatErrorMessage" | "_onInit" | "_onUpdate" | "_storedField">) => {
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>, "name" | "formatErrorMessage" | "_onInit" | "_onUpdate" | "_storedField">) => {
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>, "name" | "formatErrorMessage" | "_onInit" | "_onUpdate" | "_storedField">) => {
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.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": "echo 1"
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.1"
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
- "@types/react": "^18.3.3",
55
- "ava": "^6.1.3",
56
- "react": "canary",
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": "45f425a5a38595dcf1553593c97ea5ffc9fd0c25"
64
+ "gitHead": "07cd8acd29e916cf20fe509029328862df87b08d"
62
65
  }