formstand 0.2.0

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,330 @@
1
+ import { z } from 'zod';
2
+ import { StoreApi } from 'zustand/vanilla';
3
+ import * as react from 'react';
4
+ import { ReactNode, ChangeEvent } from 'react';
5
+
6
+ type LeafType = string | number | boolean | bigint | symbol | null | undefined | Date | RegExp;
7
+ type IsRecord<T> = T extends LeafType ? false : T extends readonly unknown[] ? false : T extends object ? true : false;
8
+ type IsArray<T> = T extends readonly unknown[] ? true : false;
9
+ type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8];
10
+ type FieldPath<T, D extends number = 7> = [D] extends [0] ? never : IsArray<T> extends true ? T extends readonly (infer U)[] ? `${number}` | (IsRecord<NonNullable<U>> extends true ? `${number}.${FieldPath<NonNullable<U>, Prev[D]>}` : IsArray<NonNullable<U>> extends true ? `${number}.${FieldPath<NonNullable<U>, Prev[D]>}` : never) : never : IsRecord<T> extends true ? {
11
+ [K in keyof T & string]: K | (IsRecord<NonNullable<T[K]>> extends true ? `${K}.${FieldPath<NonNullable<T[K]>, Prev[D]>}` : IsArray<NonNullable<T[K]>> extends true ? `${K}.${FieldPath<NonNullable<T[K]>, Prev[D]>}` : never);
12
+ }[keyof T & string] : never;
13
+ type StepValue<T, K extends string> = T extends readonly (infer U)[] ? K extends `${number}` ? U : never : T extends object ? K extends keyof T ? T[K] : never : never;
14
+ type FieldValue<T, P extends string> = [T] extends [NonNullable<T>] ? P extends `${infer Head}.${infer Tail}` ? FieldValue<StepValue<T, Head>, Tail> : StepValue<T, P> : FieldValue<NonNullable<T>, P> | undefined;
15
+
16
+ type ValidationMode = "onChange" | "onBlur" | "onSubmit" | "onTouched" | "all";
17
+ type ValidationTrigger = "change" | "blur";
18
+ declare const shouldValidateOn: (trigger: ValidationTrigger, mode: ValidationMode, reValidateMode: ValidationMode, submitAttempted: boolean, touched?: boolean) => boolean;
19
+
20
+ type ErrorMap = Readonly<Record<string, readonly string[]>>;
21
+ type BoolMap = Readonly<Record<string, boolean>>;
22
+ type FormState<TValues> = Readonly<{
23
+ values: TValues;
24
+ initialValues: TValues;
25
+ errors: ErrorMap;
26
+ schemaErrors: ErrorMap;
27
+ serverErrors: ErrorMap;
28
+ touched: BoolMap;
29
+ isSubmitting: boolean;
30
+ submitCount: number;
31
+ isValidating: BoolMap;
32
+ isValidatingForm: boolean;
33
+ mode: ValidationMode;
34
+ reValidateMode: ValidationMode;
35
+ }>;
36
+
37
+ type SettledValidationResult<TOutput> = Readonly<{
38
+ kind: "valid";
39
+ data: TOutput;
40
+ }> | Readonly<{
41
+ kind: "invalid";
42
+ errors: ErrorMap;
43
+ }>;
44
+ type ValidationResult<TOutput> = SettledValidationResult<TOutput> | Readonly<{
45
+ kind: "pending";
46
+ promise: Promise<SettledValidationResult<TOutput>>;
47
+ }>;
48
+ type SettledFieldValidationResult = Readonly<{
49
+ kind: "valid";
50
+ }> | Readonly<{
51
+ kind: "invalid";
52
+ errors: readonly string[];
53
+ }>;
54
+ type FieldValidationResult = SettledFieldValidationResult | Readonly<{
55
+ kind: "pending";
56
+ promise: Promise<SettledFieldValidationResult>;
57
+ }>;
58
+ declare const flattenIssues: (issues: readonly z.core.$ZodIssue[]) => ErrorMap;
59
+ declare const validateSync: <TSchema extends z.ZodType>(schema: TSchema, values: z.input<TSchema>) => SettledValidationResult<z.output<TSchema>>;
60
+ declare const validateAsync: <TSchema extends z.ZodType>(schema: TSchema, values: z.input<TSchema>) => Promise<SettledValidationResult<z.output<TSchema>>>;
61
+ declare const isAsyncRequiredError: (e: unknown) => boolean;
62
+
63
+ type ReadonlyStoreApi<T> = Pick<StoreApi<T>, "getState" | "getInitialState" | "subscribe">;
64
+ type CreateFormOptions<TSchema extends z.ZodType> = Readonly<{
65
+ initialValues: z.input<TSchema>;
66
+ mode?: ValidationMode;
67
+ reValidateMode?: ValidationMode;
68
+ validateOnMount?: boolean;
69
+ }>;
70
+ type SubmitHandler<TSchema extends z.ZodType> = (data: z.output<TSchema>) => void | Promise<void>;
71
+ type InvalidSubmitHandler = (errors: ErrorMap) => void;
72
+ type SubmitOptions = Readonly<{
73
+ force?: boolean;
74
+ }>;
75
+ type SubmitResult<TOutput> = Readonly<{
76
+ kind: "valid";
77
+ data: TOutput;
78
+ }> | Readonly<{
79
+ kind: "invalid";
80
+ errors: ErrorMap;
81
+ }> | Readonly<{
82
+ kind: "skipped";
83
+ }>;
84
+ type ArrayItemOf<T> = T extends readonly (infer U)[] ? U : never;
85
+ type ErrorPath<TValues> = FieldPath<TValues> | "";
86
+ type ResetOptions = Readonly<{
87
+ keepErrors?: boolean;
88
+ keepTouched?: boolean;
89
+ keepSubmitCount?: boolean;
90
+ }>;
91
+ type FieldSnapshot<TValue> = Readonly<{
92
+ value: TValue;
93
+ error: readonly string[] | undefined;
94
+ touched: boolean;
95
+ dirty: boolean;
96
+ isValidating: boolean;
97
+ }>;
98
+ type Form<TSchema extends z.ZodType> = Readonly<{
99
+ schema: TSchema;
100
+ store: ReadonlyStoreApi<FormState<z.input<TSchema>>>;
101
+ getState: () => FormState<z.input<TSchema>>;
102
+ subscribe: (listener: (state: FormState<z.input<TSchema>>, prev: FormState<z.input<TSchema>>) => void) => () => void;
103
+ getField: <P extends FieldPath<z.input<TSchema>>>(path: P) => FieldValue<z.input<TSchema>, P>;
104
+ watchField: <P extends FieldPath<z.input<TSchema>>>(path: P, listener: (snapshot: FieldSnapshot<FieldValue<z.input<TSchema>, P>>) => void) => () => void;
105
+ watchValue: <P extends FieldPath<z.input<TSchema>>>(path: P, listener: (value: FieldValue<z.input<TSchema>, P>, previous: FieldValue<z.input<TSchema>, P>) => void) => () => void;
106
+ watchValues: (listener: (values: z.input<TSchema>, previous: z.input<TSchema>) => void) => () => void;
107
+ setValue: <P extends FieldPath<z.input<TSchema>>>(path: P, value: FieldValue<z.input<TSchema>, P>) => void;
108
+ setValues: (next: z.input<TSchema>) => void;
109
+ setTouched: (path: FieldPath<z.input<TSchema>>, touched?: boolean) => void;
110
+ setSubmitting: (value: boolean) => void;
111
+ setMode: (mode: ValidationMode) => void;
112
+ setReValidateMode: (mode: ValidationMode) => void;
113
+ setError: (path: ErrorPath<z.input<TSchema>>, errors: string | readonly string[]) => void;
114
+ setErrors: (errors: ErrorMap) => void;
115
+ clearErrors: (path?: ErrorPath<z.input<TSchema>>) => void;
116
+ updateState: (updater: (state: FormState<z.input<TSchema>>) => Partial<Omit<FormState<z.input<TSchema>>, "errors">>) => void;
117
+ reset: (nextInitial?: Partial<z.input<TSchema>>, options?: ResetOptions) => void;
118
+ resetField: (path: FieldPath<z.input<TSchema>>) => void;
119
+ adoptValues: (values: z.input<TSchema>) => void;
120
+ getFieldState: <P extends FieldPath<z.input<TSchema>>>(path: P) => FieldSnapshot<FieldValue<z.input<TSchema>, P>>;
121
+ validate: () => ValidationResult<z.output<TSchema>>;
122
+ validateField: (path: ErrorPath<z.input<TSchema>>) => FieldValidationResult;
123
+ validateFields: (paths: readonly FieldPath<z.input<TSchema>>[]) => boolean | Promise<boolean>;
124
+ validateAsync: () => Promise<ValidationResult<z.output<TSchema>>>;
125
+ validateFieldAsync: (path: ErrorPath<z.input<TSchema>>) => Promise<FieldValidationResult>;
126
+ validateFieldsAsync: (paths: readonly FieldPath<z.input<TSchema>>[]) => Promise<boolean>;
127
+ submit: (onValid: SubmitHandler<TSchema>, onInvalid?: InvalidSubmitHandler, options?: SubmitOptions) => Promise<SubmitResult<z.output<TSchema>>>;
128
+ arrayPush: <P extends FieldPath<z.input<TSchema>>>(path: P, item: ArrayItemOf<NonNullable<FieldValue<z.input<TSchema>, P>>>) => void;
129
+ arrayRemove: (path: FieldPath<z.input<TSchema>>, index: number) => void;
130
+ arrayInsert: <P extends FieldPath<z.input<TSchema>>>(path: P, index: number, item: ArrayItemOf<NonNullable<FieldValue<z.input<TSchema>, P>>>) => void;
131
+ arrayMove: (path: FieldPath<z.input<TSchema>>, from: number, to: number) => void;
132
+ arraySwap: (path: FieldPath<z.input<TSchema>>, a: number, b: number) => void;
133
+ handleSubmit: (onValid: SubmitHandler<TSchema>, onInvalid?: InvalidSubmitHandler, options?: SubmitOptions) => (event?: {
134
+ preventDefault: () => void;
135
+ }) => Promise<SubmitResult<z.output<TSchema>>>;
136
+ diff: () => Readonly<Record<string, unknown>>;
137
+ dirtyFields: () => readonly string[];
138
+ snapshot: () => FormState<z.input<TSchema>>;
139
+ restore: (snapshot: FormState<z.input<TSchema>>) => void;
140
+ }>;
141
+ declare const createForm: <TSchema extends z.ZodType>(schema: TSchema, options: CreateFormOptions<TSchema>) => Form<TSchema>;
142
+
143
+ type PathSegment = string | number;
144
+ declare const parsePath: (path: string) => readonly PathSegment[];
145
+ declare const getAtPath: (obj: unknown, path: string) => unknown;
146
+ declare const setAtPath: <T>(obj: T, path: string, value: unknown) => T;
147
+
148
+ declare const useForm: <TSchema extends z.ZodType>(schema: TSchema, options: CreateFormOptions<TSchema>) => Form<TSchema>;
149
+
150
+ type FormProviderProps<TSchema extends z.ZodType> = Readonly<{
151
+ form: Form<TSchema>;
152
+ children: ReactNode;
153
+ }>;
154
+ type FormContextApi<TSchema extends z.ZodType> = Readonly<{
155
+ Provider: (props: FormProviderProps<TSchema>) => ReactNode;
156
+ useFormContext: () => Form<TSchema>;
157
+ }>;
158
+ declare const createFormContext: <TSchema extends z.ZodType>() => FormContextApi<TSchema>;
159
+
160
+ type ReadonlyStore$2<T> = Pick<StoreApi<T>, "getState" | "getInitialState" | "subscribe">;
161
+ type FormStateApi = Readonly<{
162
+ store: ReadonlyStore$2<FormState<unknown>>;
163
+ }>;
164
+ declare function useFormSelector<TSchema extends z.ZodType, U>(form: Form<TSchema>, selector: (state: FormState<z.input<TSchema>>) => U): U;
165
+ declare function useFormSelector<U>(form: FormStateApi & {
166
+ readonly schema?: undefined;
167
+ }, selector: (state: FormState<unknown>) => U): U;
168
+ declare function useFormSelectorShallow<TSchema extends z.ZodType, U>(form: Form<TSchema>, selector: (state: FormState<z.input<TSchema>>) => U): U;
169
+ declare function useFormSelectorShallow<U>(form: FormStateApi & {
170
+ readonly schema?: undefined;
171
+ }, selector: (state: FormState<unknown>) => U): U;
172
+ /**
173
+ * @deprecated Renamed to `useFormSelector` — React DOM ships its own
174
+ * (deprecated) `useFormState`, and auto-imports regularly grab the wrong one.
175
+ * This alias will be removed before 1.0.
176
+ */
177
+ declare const useFormState: typeof useFormSelector;
178
+ /** @deprecated Renamed to `useFormSelectorShallow`; see `useFormState`. */
179
+ declare const useFormStateShallow: typeof useFormSelectorShallow;
180
+
181
+ declare const useFormError: (form: FormStateApi) => readonly string[] | undefined;
182
+
183
+ declare const useIsDirty: (form: FormStateApi) => boolean;
184
+ declare const useIsValid: (form: FormStateApi) => boolean;
185
+ declare const useIsSubmitting: (form: FormStateApi) => boolean;
186
+ declare const useSubmitCount: (form: FormStateApi) => number;
187
+
188
+ type ReadonlyStore$1<T> = Pick<StoreApi<T>, "getState" | "getInitialState" | "subscribe">;
189
+ type FieldFormApi = Readonly<{
190
+ store: ReadonlyStore$1<FormState<unknown>>;
191
+ setValue(path: string, value: unknown): void;
192
+ setTouched(path: string, touched?: boolean): void;
193
+ setError(path: string, errors: readonly string[]): void;
194
+ clearErrors(path?: string): void;
195
+ validateField(path: string): FieldValidationResult;
196
+ validateFieldAsync(path: string): Promise<FieldValidationResult>;
197
+ }>;
198
+ type FieldPathArg<TValues> = string | ((state: FormState<TValues>) => string);
199
+ type UseFieldOptions = Readonly<{
200
+ debounceMs?: number;
201
+ }>;
202
+ type UseFieldReturn<TValue> = Readonly<{
203
+ path: string;
204
+ value: TValue;
205
+ initialValue: TValue;
206
+ emptyValue: null | undefined;
207
+ error: readonly string[] | undefined;
208
+ touched: boolean;
209
+ dirty: boolean;
210
+ isValidating: boolean;
211
+ setValue: (value: TValue) => void;
212
+ setTouched: (touched?: boolean) => void;
213
+ setError: (errors: readonly string[]) => void;
214
+ clearError: () => void;
215
+ validate: () => FieldValidationResult;
216
+ validateAsync: () => Promise<FieldValidationResult>;
217
+ onBlur: () => void;
218
+ }>;
219
+ declare function useField<TSchema extends z.ZodType, P extends FieldPath<z.input<TSchema>>>(form: Form<TSchema>, path: P, options?: UseFieldOptions): UseFieldReturn<FieldValue<z.input<TSchema>, P>>;
220
+ declare function useField<TSchema extends z.ZodType>(form: Form<TSchema>, pathSelector: (state: FormState<z.input<TSchema>>) => string, options?: UseFieldOptions): UseFieldReturn<unknown>;
221
+ declare function useField<TValue = unknown>(form: FieldFormApi & {
222
+ readonly schema?: undefined;
223
+ }, path: string | ((state: FormState<unknown>) => string), options?: UseFieldOptions): UseFieldReturn<TValue>;
224
+
225
+ type FieldRef<T> = ((instance: T | null) => void) | Readonly<{
226
+ current: T | null;
227
+ }> | null;
228
+ type TextFieldProps = Readonly<{
229
+ form: FieldFormApi;
230
+ path: string;
231
+ label?: ReactNode;
232
+ placeholder?: string;
233
+ type?: "text" | "password" | "email" | "url" | "tel";
234
+ autoComplete?: string;
235
+ ref?: FieldRef<HTMLInputElement>;
236
+ }>;
237
+ declare const TextField: ({ form, path, label, placeholder, type, autoComplete, ref, }: TextFieldProps) => react.JSX.Element;
238
+ type NumberFieldProps = Readonly<{
239
+ form: FieldFormApi;
240
+ path: string;
241
+ label?: ReactNode;
242
+ placeholder?: string;
243
+ ref?: FieldRef<HTMLInputElement>;
244
+ }>;
245
+ declare const NumberField: ({ form, path, label, placeholder, ref, }: NumberFieldProps) => react.JSX.Element;
246
+ type CheckboxFieldProps = Readonly<{
247
+ form: FieldFormApi;
248
+ path: string;
249
+ label?: ReactNode;
250
+ ref?: FieldRef<HTMLInputElement>;
251
+ }>;
252
+ declare const CheckboxField: ({ form, path, label, ref }: CheckboxFieldProps) => react.JSX.Element;
253
+ type SelectFieldOption<T extends string> = Readonly<{
254
+ value: T;
255
+ label: ReactNode;
256
+ }>;
257
+ type SelectFieldProps<T extends string> = Readonly<{
258
+ form: FieldFormApi;
259
+ path: string;
260
+ label?: ReactNode;
261
+ options: readonly SelectFieldOption<T>[];
262
+ placeholder?: string;
263
+ ref?: FieldRef<HTMLSelectElement>;
264
+ }>;
265
+ declare const SelectField: <T extends string>({ form, path, label, options, placeholder, ref, }: SelectFieldProps<T>) => react.JSX.Element;
266
+
267
+ declare const focusFirstError: (errors: ErrorMap, root?: ParentNode) => boolean;
268
+
269
+ type ReadonlyStore<T> = Pick<StoreApi<T>, "getState" | "getInitialState" | "subscribe">;
270
+ type FieldArrayFormApi = Readonly<{
271
+ store: ReadonlyStore<FormState<unknown>>;
272
+ arrayPush(path: string, item: unknown): void;
273
+ arrayRemove(path: string, index: number): void;
274
+ arrayInsert(path: string, index: number, item: unknown): void;
275
+ arrayMove(path: string, from: number, to: number): void;
276
+ arraySwap(path: string, a: number, b: number): void;
277
+ }>;
278
+ type FieldArrayEntry<TItem> = Readonly<{
279
+ id: string;
280
+ value: TItem;
281
+ }>;
282
+ type UseFieldArrayReturn<TItem> = Readonly<{
283
+ fields: readonly FieldArrayEntry<TItem>[];
284
+ items: readonly TItem[];
285
+ length: number;
286
+ error: readonly string[] | undefined;
287
+ push: (item: TItem) => void;
288
+ remove: (index: number) => void;
289
+ insert: (index: number, item: TItem) => void;
290
+ move: (from: number, to: number) => void;
291
+ swap: (a: number, b: number) => void;
292
+ }>;
293
+ declare const useFieldArray: <TItem = unknown>(form: FieldArrayFormApi, pathArg: string | ((state: FormState<unknown>) => string)) => UseFieldArrayReturn<TItem>;
294
+
295
+ type TextInputProps = Readonly<{
296
+ name: string;
297
+ value: string;
298
+ "aria-invalid": true | undefined;
299
+ onChange: (e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
300
+ onBlur: () => void;
301
+ }>;
302
+ type NumberInputProps = Readonly<{
303
+ type: "number";
304
+ name: string;
305
+ value: string;
306
+ "aria-invalid": true | undefined;
307
+ onChange: (e: ChangeEvent<HTMLInputElement>) => void;
308
+ onBlur: () => void;
309
+ }>;
310
+ type CheckboxProps = Readonly<{
311
+ type: "checkbox";
312
+ name: string;
313
+ checked: boolean;
314
+ "aria-invalid": true | undefined;
315
+ onChange: (e: ChangeEvent<HTMLInputElement>) => void;
316
+ onBlur: () => void;
317
+ }>;
318
+ type SelectProps = Readonly<{
319
+ name: string;
320
+ value: string;
321
+ "aria-invalid": true | undefined;
322
+ onChange: (e: ChangeEvent<HTMLSelectElement>) => void;
323
+ onBlur: () => void;
324
+ }>;
325
+ declare const textInputProps: <T extends string | null | undefined>(field: UseFieldReturn<T>) => TextInputProps;
326
+ declare const numberInputProps: <T extends number | null | undefined>(field: UseFieldReturn<T>) => NumberInputProps;
327
+ declare const checkboxProps: <T extends boolean | null | undefined>(field: UseFieldReturn<T>) => CheckboxProps;
328
+ declare const selectProps: <T extends string | null | undefined>(field: UseFieldReturn<T>) => SelectProps;
329
+
330
+ export { type BoolMap, CheckboxField, type CheckboxFieldProps, type CheckboxProps, type CreateFormOptions, type ErrorMap, type FieldArrayEntry, type FieldArrayFormApi, type FieldFormApi, type FieldPath, type FieldPathArg, type FieldRef, type FieldSnapshot, type FieldValidationResult, type FieldValue, type Form, type FormContextApi, type FormProviderProps, type FormState, type FormStateApi, type InvalidSubmitHandler, NumberField, type NumberFieldProps, type NumberInputProps, type PathSegment, type ReadonlyStoreApi, type ResetOptions, SelectField, type SelectFieldOption, type SelectFieldProps, type SelectProps, type SettledFieldValidationResult, type SettledValidationResult, type SubmitHandler, type SubmitOptions, type SubmitResult, TextField, type TextFieldProps, type TextInputProps, type UseFieldArrayReturn, type UseFieldOptions, type UseFieldReturn, type ValidationMode, type ValidationResult, type ValidationTrigger, checkboxProps, createForm, createFormContext, flattenIssues, focusFirstError, getAtPath, isAsyncRequiredError, numberInputProps, parsePath, selectProps, setAtPath, shouldValidateOn, textInputProps, useField, useFieldArray, useForm, useFormError, useFormSelector, useFormSelectorShallow, useFormState, useFormStateShallow, useIsDirty, useIsSubmitting, useIsValid, useSubmitCount, validateAsync, validateSync };
@@ -0,0 +1,330 @@
1
+ import { z } from 'zod';
2
+ import { StoreApi } from 'zustand/vanilla';
3
+ import * as react from 'react';
4
+ import { ReactNode, ChangeEvent } from 'react';
5
+
6
+ type LeafType = string | number | boolean | bigint | symbol | null | undefined | Date | RegExp;
7
+ type IsRecord<T> = T extends LeafType ? false : T extends readonly unknown[] ? false : T extends object ? true : false;
8
+ type IsArray<T> = T extends readonly unknown[] ? true : false;
9
+ type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8];
10
+ type FieldPath<T, D extends number = 7> = [D] extends [0] ? never : IsArray<T> extends true ? T extends readonly (infer U)[] ? `${number}` | (IsRecord<NonNullable<U>> extends true ? `${number}.${FieldPath<NonNullable<U>, Prev[D]>}` : IsArray<NonNullable<U>> extends true ? `${number}.${FieldPath<NonNullable<U>, Prev[D]>}` : never) : never : IsRecord<T> extends true ? {
11
+ [K in keyof T & string]: K | (IsRecord<NonNullable<T[K]>> extends true ? `${K}.${FieldPath<NonNullable<T[K]>, Prev[D]>}` : IsArray<NonNullable<T[K]>> extends true ? `${K}.${FieldPath<NonNullable<T[K]>, Prev[D]>}` : never);
12
+ }[keyof T & string] : never;
13
+ type StepValue<T, K extends string> = T extends readonly (infer U)[] ? K extends `${number}` ? U : never : T extends object ? K extends keyof T ? T[K] : never : never;
14
+ type FieldValue<T, P extends string> = [T] extends [NonNullable<T>] ? P extends `${infer Head}.${infer Tail}` ? FieldValue<StepValue<T, Head>, Tail> : StepValue<T, P> : FieldValue<NonNullable<T>, P> | undefined;
15
+
16
+ type ValidationMode = "onChange" | "onBlur" | "onSubmit" | "onTouched" | "all";
17
+ type ValidationTrigger = "change" | "blur";
18
+ declare const shouldValidateOn: (trigger: ValidationTrigger, mode: ValidationMode, reValidateMode: ValidationMode, submitAttempted: boolean, touched?: boolean) => boolean;
19
+
20
+ type ErrorMap = Readonly<Record<string, readonly string[]>>;
21
+ type BoolMap = Readonly<Record<string, boolean>>;
22
+ type FormState<TValues> = Readonly<{
23
+ values: TValues;
24
+ initialValues: TValues;
25
+ errors: ErrorMap;
26
+ schemaErrors: ErrorMap;
27
+ serverErrors: ErrorMap;
28
+ touched: BoolMap;
29
+ isSubmitting: boolean;
30
+ submitCount: number;
31
+ isValidating: BoolMap;
32
+ isValidatingForm: boolean;
33
+ mode: ValidationMode;
34
+ reValidateMode: ValidationMode;
35
+ }>;
36
+
37
+ type SettledValidationResult<TOutput> = Readonly<{
38
+ kind: "valid";
39
+ data: TOutput;
40
+ }> | Readonly<{
41
+ kind: "invalid";
42
+ errors: ErrorMap;
43
+ }>;
44
+ type ValidationResult<TOutput> = SettledValidationResult<TOutput> | Readonly<{
45
+ kind: "pending";
46
+ promise: Promise<SettledValidationResult<TOutput>>;
47
+ }>;
48
+ type SettledFieldValidationResult = Readonly<{
49
+ kind: "valid";
50
+ }> | Readonly<{
51
+ kind: "invalid";
52
+ errors: readonly string[];
53
+ }>;
54
+ type FieldValidationResult = SettledFieldValidationResult | Readonly<{
55
+ kind: "pending";
56
+ promise: Promise<SettledFieldValidationResult>;
57
+ }>;
58
+ declare const flattenIssues: (issues: readonly z.core.$ZodIssue[]) => ErrorMap;
59
+ declare const validateSync: <TSchema extends z.ZodType>(schema: TSchema, values: z.input<TSchema>) => SettledValidationResult<z.output<TSchema>>;
60
+ declare const validateAsync: <TSchema extends z.ZodType>(schema: TSchema, values: z.input<TSchema>) => Promise<SettledValidationResult<z.output<TSchema>>>;
61
+ declare const isAsyncRequiredError: (e: unknown) => boolean;
62
+
63
+ type ReadonlyStoreApi<T> = Pick<StoreApi<T>, "getState" | "getInitialState" | "subscribe">;
64
+ type CreateFormOptions<TSchema extends z.ZodType> = Readonly<{
65
+ initialValues: z.input<TSchema>;
66
+ mode?: ValidationMode;
67
+ reValidateMode?: ValidationMode;
68
+ validateOnMount?: boolean;
69
+ }>;
70
+ type SubmitHandler<TSchema extends z.ZodType> = (data: z.output<TSchema>) => void | Promise<void>;
71
+ type InvalidSubmitHandler = (errors: ErrorMap) => void;
72
+ type SubmitOptions = Readonly<{
73
+ force?: boolean;
74
+ }>;
75
+ type SubmitResult<TOutput> = Readonly<{
76
+ kind: "valid";
77
+ data: TOutput;
78
+ }> | Readonly<{
79
+ kind: "invalid";
80
+ errors: ErrorMap;
81
+ }> | Readonly<{
82
+ kind: "skipped";
83
+ }>;
84
+ type ArrayItemOf<T> = T extends readonly (infer U)[] ? U : never;
85
+ type ErrorPath<TValues> = FieldPath<TValues> | "";
86
+ type ResetOptions = Readonly<{
87
+ keepErrors?: boolean;
88
+ keepTouched?: boolean;
89
+ keepSubmitCount?: boolean;
90
+ }>;
91
+ type FieldSnapshot<TValue> = Readonly<{
92
+ value: TValue;
93
+ error: readonly string[] | undefined;
94
+ touched: boolean;
95
+ dirty: boolean;
96
+ isValidating: boolean;
97
+ }>;
98
+ type Form<TSchema extends z.ZodType> = Readonly<{
99
+ schema: TSchema;
100
+ store: ReadonlyStoreApi<FormState<z.input<TSchema>>>;
101
+ getState: () => FormState<z.input<TSchema>>;
102
+ subscribe: (listener: (state: FormState<z.input<TSchema>>, prev: FormState<z.input<TSchema>>) => void) => () => void;
103
+ getField: <P extends FieldPath<z.input<TSchema>>>(path: P) => FieldValue<z.input<TSchema>, P>;
104
+ watchField: <P extends FieldPath<z.input<TSchema>>>(path: P, listener: (snapshot: FieldSnapshot<FieldValue<z.input<TSchema>, P>>) => void) => () => void;
105
+ watchValue: <P extends FieldPath<z.input<TSchema>>>(path: P, listener: (value: FieldValue<z.input<TSchema>, P>, previous: FieldValue<z.input<TSchema>, P>) => void) => () => void;
106
+ watchValues: (listener: (values: z.input<TSchema>, previous: z.input<TSchema>) => void) => () => void;
107
+ setValue: <P extends FieldPath<z.input<TSchema>>>(path: P, value: FieldValue<z.input<TSchema>, P>) => void;
108
+ setValues: (next: z.input<TSchema>) => void;
109
+ setTouched: (path: FieldPath<z.input<TSchema>>, touched?: boolean) => void;
110
+ setSubmitting: (value: boolean) => void;
111
+ setMode: (mode: ValidationMode) => void;
112
+ setReValidateMode: (mode: ValidationMode) => void;
113
+ setError: (path: ErrorPath<z.input<TSchema>>, errors: string | readonly string[]) => void;
114
+ setErrors: (errors: ErrorMap) => void;
115
+ clearErrors: (path?: ErrorPath<z.input<TSchema>>) => void;
116
+ updateState: (updater: (state: FormState<z.input<TSchema>>) => Partial<Omit<FormState<z.input<TSchema>>, "errors">>) => void;
117
+ reset: (nextInitial?: Partial<z.input<TSchema>>, options?: ResetOptions) => void;
118
+ resetField: (path: FieldPath<z.input<TSchema>>) => void;
119
+ adoptValues: (values: z.input<TSchema>) => void;
120
+ getFieldState: <P extends FieldPath<z.input<TSchema>>>(path: P) => FieldSnapshot<FieldValue<z.input<TSchema>, P>>;
121
+ validate: () => ValidationResult<z.output<TSchema>>;
122
+ validateField: (path: ErrorPath<z.input<TSchema>>) => FieldValidationResult;
123
+ validateFields: (paths: readonly FieldPath<z.input<TSchema>>[]) => boolean | Promise<boolean>;
124
+ validateAsync: () => Promise<ValidationResult<z.output<TSchema>>>;
125
+ validateFieldAsync: (path: ErrorPath<z.input<TSchema>>) => Promise<FieldValidationResult>;
126
+ validateFieldsAsync: (paths: readonly FieldPath<z.input<TSchema>>[]) => Promise<boolean>;
127
+ submit: (onValid: SubmitHandler<TSchema>, onInvalid?: InvalidSubmitHandler, options?: SubmitOptions) => Promise<SubmitResult<z.output<TSchema>>>;
128
+ arrayPush: <P extends FieldPath<z.input<TSchema>>>(path: P, item: ArrayItemOf<NonNullable<FieldValue<z.input<TSchema>, P>>>) => void;
129
+ arrayRemove: (path: FieldPath<z.input<TSchema>>, index: number) => void;
130
+ arrayInsert: <P extends FieldPath<z.input<TSchema>>>(path: P, index: number, item: ArrayItemOf<NonNullable<FieldValue<z.input<TSchema>, P>>>) => void;
131
+ arrayMove: (path: FieldPath<z.input<TSchema>>, from: number, to: number) => void;
132
+ arraySwap: (path: FieldPath<z.input<TSchema>>, a: number, b: number) => void;
133
+ handleSubmit: (onValid: SubmitHandler<TSchema>, onInvalid?: InvalidSubmitHandler, options?: SubmitOptions) => (event?: {
134
+ preventDefault: () => void;
135
+ }) => Promise<SubmitResult<z.output<TSchema>>>;
136
+ diff: () => Readonly<Record<string, unknown>>;
137
+ dirtyFields: () => readonly string[];
138
+ snapshot: () => FormState<z.input<TSchema>>;
139
+ restore: (snapshot: FormState<z.input<TSchema>>) => void;
140
+ }>;
141
+ declare const createForm: <TSchema extends z.ZodType>(schema: TSchema, options: CreateFormOptions<TSchema>) => Form<TSchema>;
142
+
143
+ type PathSegment = string | number;
144
+ declare const parsePath: (path: string) => readonly PathSegment[];
145
+ declare const getAtPath: (obj: unknown, path: string) => unknown;
146
+ declare const setAtPath: <T>(obj: T, path: string, value: unknown) => T;
147
+
148
+ declare const useForm: <TSchema extends z.ZodType>(schema: TSchema, options: CreateFormOptions<TSchema>) => Form<TSchema>;
149
+
150
+ type FormProviderProps<TSchema extends z.ZodType> = Readonly<{
151
+ form: Form<TSchema>;
152
+ children: ReactNode;
153
+ }>;
154
+ type FormContextApi<TSchema extends z.ZodType> = Readonly<{
155
+ Provider: (props: FormProviderProps<TSchema>) => ReactNode;
156
+ useFormContext: () => Form<TSchema>;
157
+ }>;
158
+ declare const createFormContext: <TSchema extends z.ZodType>() => FormContextApi<TSchema>;
159
+
160
+ type ReadonlyStore$2<T> = Pick<StoreApi<T>, "getState" | "getInitialState" | "subscribe">;
161
+ type FormStateApi = Readonly<{
162
+ store: ReadonlyStore$2<FormState<unknown>>;
163
+ }>;
164
+ declare function useFormSelector<TSchema extends z.ZodType, U>(form: Form<TSchema>, selector: (state: FormState<z.input<TSchema>>) => U): U;
165
+ declare function useFormSelector<U>(form: FormStateApi & {
166
+ readonly schema?: undefined;
167
+ }, selector: (state: FormState<unknown>) => U): U;
168
+ declare function useFormSelectorShallow<TSchema extends z.ZodType, U>(form: Form<TSchema>, selector: (state: FormState<z.input<TSchema>>) => U): U;
169
+ declare function useFormSelectorShallow<U>(form: FormStateApi & {
170
+ readonly schema?: undefined;
171
+ }, selector: (state: FormState<unknown>) => U): U;
172
+ /**
173
+ * @deprecated Renamed to `useFormSelector` — React DOM ships its own
174
+ * (deprecated) `useFormState`, and auto-imports regularly grab the wrong one.
175
+ * This alias will be removed before 1.0.
176
+ */
177
+ declare const useFormState: typeof useFormSelector;
178
+ /** @deprecated Renamed to `useFormSelectorShallow`; see `useFormState`. */
179
+ declare const useFormStateShallow: typeof useFormSelectorShallow;
180
+
181
+ declare const useFormError: (form: FormStateApi) => readonly string[] | undefined;
182
+
183
+ declare const useIsDirty: (form: FormStateApi) => boolean;
184
+ declare const useIsValid: (form: FormStateApi) => boolean;
185
+ declare const useIsSubmitting: (form: FormStateApi) => boolean;
186
+ declare const useSubmitCount: (form: FormStateApi) => number;
187
+
188
+ type ReadonlyStore$1<T> = Pick<StoreApi<T>, "getState" | "getInitialState" | "subscribe">;
189
+ type FieldFormApi = Readonly<{
190
+ store: ReadonlyStore$1<FormState<unknown>>;
191
+ setValue(path: string, value: unknown): void;
192
+ setTouched(path: string, touched?: boolean): void;
193
+ setError(path: string, errors: readonly string[]): void;
194
+ clearErrors(path?: string): void;
195
+ validateField(path: string): FieldValidationResult;
196
+ validateFieldAsync(path: string): Promise<FieldValidationResult>;
197
+ }>;
198
+ type FieldPathArg<TValues> = string | ((state: FormState<TValues>) => string);
199
+ type UseFieldOptions = Readonly<{
200
+ debounceMs?: number;
201
+ }>;
202
+ type UseFieldReturn<TValue> = Readonly<{
203
+ path: string;
204
+ value: TValue;
205
+ initialValue: TValue;
206
+ emptyValue: null | undefined;
207
+ error: readonly string[] | undefined;
208
+ touched: boolean;
209
+ dirty: boolean;
210
+ isValidating: boolean;
211
+ setValue: (value: TValue) => void;
212
+ setTouched: (touched?: boolean) => void;
213
+ setError: (errors: readonly string[]) => void;
214
+ clearError: () => void;
215
+ validate: () => FieldValidationResult;
216
+ validateAsync: () => Promise<FieldValidationResult>;
217
+ onBlur: () => void;
218
+ }>;
219
+ declare function useField<TSchema extends z.ZodType, P extends FieldPath<z.input<TSchema>>>(form: Form<TSchema>, path: P, options?: UseFieldOptions): UseFieldReturn<FieldValue<z.input<TSchema>, P>>;
220
+ declare function useField<TSchema extends z.ZodType>(form: Form<TSchema>, pathSelector: (state: FormState<z.input<TSchema>>) => string, options?: UseFieldOptions): UseFieldReturn<unknown>;
221
+ declare function useField<TValue = unknown>(form: FieldFormApi & {
222
+ readonly schema?: undefined;
223
+ }, path: string | ((state: FormState<unknown>) => string), options?: UseFieldOptions): UseFieldReturn<TValue>;
224
+
225
+ type FieldRef<T> = ((instance: T | null) => void) | Readonly<{
226
+ current: T | null;
227
+ }> | null;
228
+ type TextFieldProps = Readonly<{
229
+ form: FieldFormApi;
230
+ path: string;
231
+ label?: ReactNode;
232
+ placeholder?: string;
233
+ type?: "text" | "password" | "email" | "url" | "tel";
234
+ autoComplete?: string;
235
+ ref?: FieldRef<HTMLInputElement>;
236
+ }>;
237
+ declare const TextField: ({ form, path, label, placeholder, type, autoComplete, ref, }: TextFieldProps) => react.JSX.Element;
238
+ type NumberFieldProps = Readonly<{
239
+ form: FieldFormApi;
240
+ path: string;
241
+ label?: ReactNode;
242
+ placeholder?: string;
243
+ ref?: FieldRef<HTMLInputElement>;
244
+ }>;
245
+ declare const NumberField: ({ form, path, label, placeholder, ref, }: NumberFieldProps) => react.JSX.Element;
246
+ type CheckboxFieldProps = Readonly<{
247
+ form: FieldFormApi;
248
+ path: string;
249
+ label?: ReactNode;
250
+ ref?: FieldRef<HTMLInputElement>;
251
+ }>;
252
+ declare const CheckboxField: ({ form, path, label, ref }: CheckboxFieldProps) => react.JSX.Element;
253
+ type SelectFieldOption<T extends string> = Readonly<{
254
+ value: T;
255
+ label: ReactNode;
256
+ }>;
257
+ type SelectFieldProps<T extends string> = Readonly<{
258
+ form: FieldFormApi;
259
+ path: string;
260
+ label?: ReactNode;
261
+ options: readonly SelectFieldOption<T>[];
262
+ placeholder?: string;
263
+ ref?: FieldRef<HTMLSelectElement>;
264
+ }>;
265
+ declare const SelectField: <T extends string>({ form, path, label, options, placeholder, ref, }: SelectFieldProps<T>) => react.JSX.Element;
266
+
267
+ declare const focusFirstError: (errors: ErrorMap, root?: ParentNode) => boolean;
268
+
269
+ type ReadonlyStore<T> = Pick<StoreApi<T>, "getState" | "getInitialState" | "subscribe">;
270
+ type FieldArrayFormApi = Readonly<{
271
+ store: ReadonlyStore<FormState<unknown>>;
272
+ arrayPush(path: string, item: unknown): void;
273
+ arrayRemove(path: string, index: number): void;
274
+ arrayInsert(path: string, index: number, item: unknown): void;
275
+ arrayMove(path: string, from: number, to: number): void;
276
+ arraySwap(path: string, a: number, b: number): void;
277
+ }>;
278
+ type FieldArrayEntry<TItem> = Readonly<{
279
+ id: string;
280
+ value: TItem;
281
+ }>;
282
+ type UseFieldArrayReturn<TItem> = Readonly<{
283
+ fields: readonly FieldArrayEntry<TItem>[];
284
+ items: readonly TItem[];
285
+ length: number;
286
+ error: readonly string[] | undefined;
287
+ push: (item: TItem) => void;
288
+ remove: (index: number) => void;
289
+ insert: (index: number, item: TItem) => void;
290
+ move: (from: number, to: number) => void;
291
+ swap: (a: number, b: number) => void;
292
+ }>;
293
+ declare const useFieldArray: <TItem = unknown>(form: FieldArrayFormApi, pathArg: string | ((state: FormState<unknown>) => string)) => UseFieldArrayReturn<TItem>;
294
+
295
+ type TextInputProps = Readonly<{
296
+ name: string;
297
+ value: string;
298
+ "aria-invalid": true | undefined;
299
+ onChange: (e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
300
+ onBlur: () => void;
301
+ }>;
302
+ type NumberInputProps = Readonly<{
303
+ type: "number";
304
+ name: string;
305
+ value: string;
306
+ "aria-invalid": true | undefined;
307
+ onChange: (e: ChangeEvent<HTMLInputElement>) => void;
308
+ onBlur: () => void;
309
+ }>;
310
+ type CheckboxProps = Readonly<{
311
+ type: "checkbox";
312
+ name: string;
313
+ checked: boolean;
314
+ "aria-invalid": true | undefined;
315
+ onChange: (e: ChangeEvent<HTMLInputElement>) => void;
316
+ onBlur: () => void;
317
+ }>;
318
+ type SelectProps = Readonly<{
319
+ name: string;
320
+ value: string;
321
+ "aria-invalid": true | undefined;
322
+ onChange: (e: ChangeEvent<HTMLSelectElement>) => void;
323
+ onBlur: () => void;
324
+ }>;
325
+ declare const textInputProps: <T extends string | null | undefined>(field: UseFieldReturn<T>) => TextInputProps;
326
+ declare const numberInputProps: <T extends number | null | undefined>(field: UseFieldReturn<T>) => NumberInputProps;
327
+ declare const checkboxProps: <T extends boolean | null | undefined>(field: UseFieldReturn<T>) => CheckboxProps;
328
+ declare const selectProps: <T extends string | null | undefined>(field: UseFieldReturn<T>) => SelectProps;
329
+
330
+ export { type BoolMap, CheckboxField, type CheckboxFieldProps, type CheckboxProps, type CreateFormOptions, type ErrorMap, type FieldArrayEntry, type FieldArrayFormApi, type FieldFormApi, type FieldPath, type FieldPathArg, type FieldRef, type FieldSnapshot, type FieldValidationResult, type FieldValue, type Form, type FormContextApi, type FormProviderProps, type FormState, type FormStateApi, type InvalidSubmitHandler, NumberField, type NumberFieldProps, type NumberInputProps, type PathSegment, type ReadonlyStoreApi, type ResetOptions, SelectField, type SelectFieldOption, type SelectFieldProps, type SelectProps, type SettledFieldValidationResult, type SettledValidationResult, type SubmitHandler, type SubmitOptions, type SubmitResult, TextField, type TextFieldProps, type TextInputProps, type UseFieldArrayReturn, type UseFieldOptions, type UseFieldReturn, type ValidationMode, type ValidationResult, type ValidationTrigger, checkboxProps, createForm, createFormContext, flattenIssues, focusFirstError, getAtPath, isAsyncRequiredError, numberInputProps, parsePath, selectProps, setAtPath, shouldValidateOn, textInputProps, useField, useFieldArray, useForm, useFormError, useFormSelector, useFormSelectorShallow, useFormState, useFormStateShallow, useIsDirty, useIsSubmitting, useIsValid, useSubmitCount, validateAsync, validateSync };