formstand 0.5.0 → 0.7.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.
package/dist/index.d.cts CHANGED
@@ -162,28 +162,8 @@ type FormContextApi<TSchema extends z.ZodType> = Readonly<{
162
162
  declare const createFormContext: <TSchema extends z.ZodType>() => FormContextApi<TSchema>;
163
163
 
164
164
  type ReadonlyStore$2<T> = Pick<StoreApi<T>, "getState" | "getInitialState" | "subscribe">;
165
- type FormStateApi = Readonly<{
166
- store: ReadonlyStore$2<FormState<unknown>>;
167
- }>;
168
- declare function useFormSelector<TSchema extends z.ZodType, U>(form: Form<TSchema>, selector: (state: FormState<z.input<TSchema>>) => U): U;
169
- declare function useFormSelector<U>(form: FormStateApi & {
170
- readonly schema?: undefined;
171
- }, selector: (state: FormState<unknown>) => U): U;
172
- declare function useFormSelectorShallow<TSchema extends z.ZodType, U>(form: Form<TSchema>, selector: (state: FormState<z.input<TSchema>>) => U): U;
173
- declare function useFormSelectorShallow<U>(form: FormStateApi & {
174
- readonly schema?: undefined;
175
- }, selector: (state: FormState<unknown>) => U): U;
176
-
177
- declare const useFormError: (form: FormStateApi) => readonly string[] | undefined;
178
-
179
- declare const useIsDirty: (form: FormStateApi) => boolean;
180
- declare const useIsValid: (form: FormStateApi) => boolean;
181
- declare const useIsSubmitting: (form: FormStateApi) => boolean;
182
- declare const useSubmitCount: (form: FormStateApi) => number;
183
-
184
- type ReadonlyStore$1<T> = Pick<StoreApi<T>, "getState" | "getInitialState" | "subscribe">;
185
165
  type FieldFormApi = Readonly<{
186
- store: ReadonlyStore$1<FormState<unknown>>;
166
+ store: ReadonlyStore$2<FormState<unknown>>;
187
167
  setValue(path: string, value: unknown): void;
188
168
  setTouched(path: string, touched?: boolean): void;
189
169
  setError(path: string, errors: string | readonly string[]): void;
@@ -218,6 +198,94 @@ declare function useField<TValue = unknown>(form: FieldFormApi & {
218
198
  }, path: string | ((state: FormState<unknown>) => string), options?: UseFieldOptions): UseFieldReturn<TValue>;
219
199
  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
200
 
201
+ type ReadonlyStore$1<T> = Pick<StoreApi<T>, "getState" | "getInitialState" | "subscribe">;
202
+ type FieldArrayFormApi = Readonly<{
203
+ store: ReadonlyStore$1<FormState<unknown>>;
204
+ arrayPush(path: string, item: unknown): void;
205
+ arrayRemove(path: string, index: number): void;
206
+ arrayInsert(path: string, index: number, item: unknown): void;
207
+ arrayMove(path: string, from: number, to: number): void;
208
+ arraySwap(path: string, a: number, b: number): void;
209
+ }>;
210
+ type FieldArrayEntry<TItem> = Readonly<{
211
+ id: string;
212
+ value: TItem;
213
+ }>;
214
+ type UseFieldArrayReturn<TItem> = Readonly<{
215
+ fields: readonly FieldArrayEntry<TItem>[];
216
+ items: readonly TItem[];
217
+ length: number;
218
+ error: readonly string[] | undefined;
219
+ push: (item: TItem) => void;
220
+ remove: (index: number) => void;
221
+ insert: (index: number, item: TItem) => void;
222
+ move: (from: number, to: number) => void;
223
+ swap: (a: number, b: number) => void;
224
+ }>;
225
+ type ArrayItemOf<T> = [NonNullable<T>] extends [readonly (infer U)[]] ? U : never;
226
+ declare function useFieldArray<TSchema extends z.ZodType>(form: Form<TSchema>, pathSelector: (state: FormState<z.input<TSchema>>) => string): UseFieldArrayReturn<unknown>;
227
+ declare function useFieldArray<TItem = unknown>(form: FieldArrayFormApi & {
228
+ readonly schema?: undefined;
229
+ }, path: string | ((state: FormState<unknown>) => string)): UseFieldArrayReturn<TItem>;
230
+ declare function useFieldArray<TSchema extends z.ZodType, P extends FieldPath<z.input<TSchema>>>(form: Form<TSchema>, path: P): UseFieldArrayReturn<ArrayItemOf<FieldValue<z.input<TSchema>, P>>>;
231
+
232
+ type BoundUseField<TSchema extends z.ZodType> = {
233
+ (pathSelector: (state: FormState<z.input<TSchema>>) => string, options?: UseFieldOptions): UseFieldReturn<unknown>;
234
+ <P extends FieldPath<z.input<TSchema>>>(path: P, options?: UseFieldOptions): UseFieldReturn<FieldValue<z.input<TSchema>, P>>;
235
+ };
236
+ type BoundUseFieldArray<TSchema extends z.ZodType> = {
237
+ (pathSelector: (state: FormState<z.input<TSchema>>) => string): UseFieldArrayReturn<unknown>;
238
+ <P extends FieldPath<z.input<TSchema>>>(path: P): UseFieldArrayReturn<ArrayItemOf<FieldValue<z.input<TSchema>, P>>>;
239
+ };
240
+ type BoundUseSelector<TSchema extends z.ZodType> = <U>(selector: (state: FormState<z.input<TSchema>>) => U) => U;
241
+ type BoundUseFlag<TSchema extends z.ZodType> = (path?: FieldPath<z.input<TSchema>>) => boolean;
242
+ type FormHooks<TSchema extends z.ZodType, N extends string> = Readonly<{
243
+ [K in `use${Capitalize<N>}Field`]: BoundUseField<TSchema>;
244
+ } & {
245
+ [K in `use${Capitalize<N>}FieldArray`]: BoundUseFieldArray<TSchema>;
246
+ } & {
247
+ [K in `use${Capitalize<N>}Selector`]: BoundUseSelector<TSchema>;
248
+ } & {
249
+ [K in `use${Capitalize<N>}SelectorShallow`]: BoundUseSelector<TSchema>;
250
+ } & {
251
+ [K in `use${Capitalize<N>}Error`]: () => readonly string[] | undefined;
252
+ } & {
253
+ [K in `use${Capitalize<N>}IsDirty`]: BoundUseFlag<TSchema>;
254
+ } & {
255
+ [K in `use${Capitalize<N>}IsValid`]: BoundUseFlag<TSchema>;
256
+ } & {
257
+ [K in `use${Capitalize<N>}IsSubmitting`]: () => boolean;
258
+ } & {
259
+ [K in `use${Capitalize<N>}SubmitCount`]: () => number;
260
+ }>;
261
+ declare const createFormHooks: <TSchema extends z.ZodType, N extends string = "">(form: Form<TSchema>, name?: N) => FormHooks<TSchema, N>;
262
+
263
+ type ReadonlyStore<T> = Pick<StoreApi<T>, "getState" | "getInitialState" | "subscribe">;
264
+ type FormStateApi = Readonly<{
265
+ store: ReadonlyStore<FormState<unknown>>;
266
+ }>;
267
+ declare function useFormSelector<TSchema extends z.ZodType, U>(form: Form<TSchema>, selector: (state: FormState<z.input<TSchema>>) => U): U;
268
+ declare function useFormSelector<U>(form: FormStateApi & {
269
+ readonly schema?: undefined;
270
+ }, selector: (state: FormState<unknown>) => U): U;
271
+ declare function useFormSelectorShallow<TSchema extends z.ZodType, U>(form: Form<TSchema>, selector: (state: FormState<z.input<TSchema>>) => U): U;
272
+ declare function useFormSelectorShallow<U>(form: FormStateApi & {
273
+ readonly schema?: undefined;
274
+ }, selector: (state: FormState<unknown>) => U): U;
275
+
276
+ declare const useFormError: (form: FormStateApi) => readonly string[] | undefined;
277
+
278
+ declare function useIsDirty(form: FormStateApi & {
279
+ readonly schema?: undefined;
280
+ }, path?: string): boolean;
281
+ declare function useIsDirty<TSchema extends z.ZodType, P extends FieldPath<z.input<TSchema>>>(form: Form<TSchema>, path?: P): boolean;
282
+ declare function useIsValid(form: FormStateApi & {
283
+ readonly schema?: undefined;
284
+ }, path?: string): boolean;
285
+ declare function useIsValid<TSchema extends z.ZodType, P extends FieldPath<z.input<TSchema>>>(form: Form<TSchema>, path?: P): boolean;
286
+ declare const useIsSubmitting: (form: FormStateApi) => boolean;
287
+ declare const useSubmitCount: (form: FormStateApi) => number;
288
+
221
289
  type PathsOf<F extends FieldFormApi> = F extends Form<infer TSchema extends z.ZodType> ? FieldPath<z.input<TSchema>> : string;
222
290
  type FieldRef<T> = ((instance: T | null) => void) | Readonly<{
223
291
  current: T | null;
@@ -264,37 +332,6 @@ declare const SelectField: <T extends string, F extends FieldFormApi>({ form, pa
264
332
  declare const focusFirstError: (errors: ErrorMap, root?: ParentNode) => boolean;
265
333
  declare const focusField: (path: string, root?: ParentNode) => boolean;
266
334
 
267
- type ReadonlyStore<T> = Pick<StoreApi<T>, "getState" | "getInitialState" | "subscribe">;
268
- type FieldArrayFormApi = Readonly<{
269
- store: ReadonlyStore<FormState<unknown>>;
270
- arrayPush(path: string, item: unknown): void;
271
- arrayRemove(path: string, index: number): void;
272
- arrayInsert(path: string, index: number, item: unknown): void;
273
- arrayMove(path: string, from: number, to: number): void;
274
- arraySwap(path: string, a: number, b: number): void;
275
- }>;
276
- type FieldArrayEntry<TItem> = Readonly<{
277
- id: string;
278
- value: TItem;
279
- }>;
280
- type UseFieldArrayReturn<TItem> = Readonly<{
281
- fields: readonly FieldArrayEntry<TItem>[];
282
- items: readonly TItem[];
283
- length: number;
284
- error: readonly string[] | undefined;
285
- push: (item: TItem) => void;
286
- remove: (index: number) => void;
287
- insert: (index: number, item: TItem) => void;
288
- move: (from: number, to: number) => void;
289
- swap: (a: number, b: number) => void;
290
- }>;
291
- type ArrayItemOf<T> = [NonNullable<T>] extends [readonly (infer U)[]] ? U : never;
292
- declare function useFieldArray<TSchema extends z.ZodType>(form: Form<TSchema>, pathSelector: (state: FormState<z.input<TSchema>>) => string): UseFieldArrayReturn<unknown>;
293
- declare function useFieldArray<TItem = unknown>(form: FieldArrayFormApi & {
294
- readonly schema?: undefined;
295
- }, path: string | ((state: FormState<unknown>) => string)): UseFieldArrayReturn<TItem>;
296
- declare function useFieldArray<TSchema extends z.ZodType, P extends FieldPath<z.input<TSchema>>>(form: Form<TSchema>, path: P): UseFieldArrayReturn<ArrayItemOf<FieldValue<z.input<TSchema>, P>>>;
297
-
298
335
  type TextInputProps = Readonly<{
299
336
  name: string;
300
337
  value: string;
@@ -340,4 +377,4 @@ declare const numberInputProps: <T extends number | null | undefined>(field: Use
340
377
  declare const checkboxProps: <T extends boolean | null | undefined>(field: UseFieldReturn<T>) => CheckboxProps;
341
378
  declare const selectProps: <T extends string | null | undefined>(field: UseFieldReturn<T>) => SelectProps;
342
379
 
343
- 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 ParsedNumberText, type PathSegment, type PathsOf, 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, emptyValueForSchema, flattenIssues, focusField, focusFirstError, getAtPath, isAsyncRequiredError, numberInputProps, numberToInputText, parseNumberText, parsePath, selectProps, setAtPath, shouldValidateOn, textInputProps, useField, useFieldArray, useForm, useFormError, useFormSelector, useFormSelectorShallow, useIsDirty, useIsSubmitting, useIsValid, useSubmitCount, validateAsync, validateSync };
380
+ export { type BoolMap, type BoundUseField, type BoundUseFieldArray, type BoundUseFlag, type BoundUseSelector, 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 FormHooks, type FormProviderProps, type FormState, type FormStateApi, type InvalidSubmitHandler, NumberField, type NumberFieldProps, type NumberInputProps, type ParsedNumberText, type PathSegment, type PathsOf, 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, createFormHooks, emptyValueForSchema, flattenIssues, focusField, focusFirstError, getAtPath, isAsyncRequiredError, numberInputProps, numberToInputText, parseNumberText, parsePath, selectProps, setAtPath, shouldValidateOn, textInputProps, useField, useFieldArray, useForm, useFormError, useFormSelector, useFormSelectorShallow, useIsDirty, useIsSubmitting, useIsValid, useSubmitCount, validateAsync, validateSync };
package/dist/index.d.ts CHANGED
@@ -162,28 +162,8 @@ type FormContextApi<TSchema extends z.ZodType> = Readonly<{
162
162
  declare const createFormContext: <TSchema extends z.ZodType>() => FormContextApi<TSchema>;
163
163
 
164
164
  type ReadonlyStore$2<T> = Pick<StoreApi<T>, "getState" | "getInitialState" | "subscribe">;
165
- type FormStateApi = Readonly<{
166
- store: ReadonlyStore$2<FormState<unknown>>;
167
- }>;
168
- declare function useFormSelector<TSchema extends z.ZodType, U>(form: Form<TSchema>, selector: (state: FormState<z.input<TSchema>>) => U): U;
169
- declare function useFormSelector<U>(form: FormStateApi & {
170
- readonly schema?: undefined;
171
- }, selector: (state: FormState<unknown>) => U): U;
172
- declare function useFormSelectorShallow<TSchema extends z.ZodType, U>(form: Form<TSchema>, selector: (state: FormState<z.input<TSchema>>) => U): U;
173
- declare function useFormSelectorShallow<U>(form: FormStateApi & {
174
- readonly schema?: undefined;
175
- }, selector: (state: FormState<unknown>) => U): U;
176
-
177
- declare const useFormError: (form: FormStateApi) => readonly string[] | undefined;
178
-
179
- declare const useIsDirty: (form: FormStateApi) => boolean;
180
- declare const useIsValid: (form: FormStateApi) => boolean;
181
- declare const useIsSubmitting: (form: FormStateApi) => boolean;
182
- declare const useSubmitCount: (form: FormStateApi) => number;
183
-
184
- type ReadonlyStore$1<T> = Pick<StoreApi<T>, "getState" | "getInitialState" | "subscribe">;
185
165
  type FieldFormApi = Readonly<{
186
- store: ReadonlyStore$1<FormState<unknown>>;
166
+ store: ReadonlyStore$2<FormState<unknown>>;
187
167
  setValue(path: string, value: unknown): void;
188
168
  setTouched(path: string, touched?: boolean): void;
189
169
  setError(path: string, errors: string | readonly string[]): void;
@@ -218,6 +198,94 @@ declare function useField<TValue = unknown>(form: FieldFormApi & {
218
198
  }, path: string | ((state: FormState<unknown>) => string), options?: UseFieldOptions): UseFieldReturn<TValue>;
219
199
  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
200
 
201
+ type ReadonlyStore$1<T> = Pick<StoreApi<T>, "getState" | "getInitialState" | "subscribe">;
202
+ type FieldArrayFormApi = Readonly<{
203
+ store: ReadonlyStore$1<FormState<unknown>>;
204
+ arrayPush(path: string, item: unknown): void;
205
+ arrayRemove(path: string, index: number): void;
206
+ arrayInsert(path: string, index: number, item: unknown): void;
207
+ arrayMove(path: string, from: number, to: number): void;
208
+ arraySwap(path: string, a: number, b: number): void;
209
+ }>;
210
+ type FieldArrayEntry<TItem> = Readonly<{
211
+ id: string;
212
+ value: TItem;
213
+ }>;
214
+ type UseFieldArrayReturn<TItem> = Readonly<{
215
+ fields: readonly FieldArrayEntry<TItem>[];
216
+ items: readonly TItem[];
217
+ length: number;
218
+ error: readonly string[] | undefined;
219
+ push: (item: TItem) => void;
220
+ remove: (index: number) => void;
221
+ insert: (index: number, item: TItem) => void;
222
+ move: (from: number, to: number) => void;
223
+ swap: (a: number, b: number) => void;
224
+ }>;
225
+ type ArrayItemOf<T> = [NonNullable<T>] extends [readonly (infer U)[]] ? U : never;
226
+ declare function useFieldArray<TSchema extends z.ZodType>(form: Form<TSchema>, pathSelector: (state: FormState<z.input<TSchema>>) => string): UseFieldArrayReturn<unknown>;
227
+ declare function useFieldArray<TItem = unknown>(form: FieldArrayFormApi & {
228
+ readonly schema?: undefined;
229
+ }, path: string | ((state: FormState<unknown>) => string)): UseFieldArrayReturn<TItem>;
230
+ declare function useFieldArray<TSchema extends z.ZodType, P extends FieldPath<z.input<TSchema>>>(form: Form<TSchema>, path: P): UseFieldArrayReturn<ArrayItemOf<FieldValue<z.input<TSchema>, P>>>;
231
+
232
+ type BoundUseField<TSchema extends z.ZodType> = {
233
+ (pathSelector: (state: FormState<z.input<TSchema>>) => string, options?: UseFieldOptions): UseFieldReturn<unknown>;
234
+ <P extends FieldPath<z.input<TSchema>>>(path: P, options?: UseFieldOptions): UseFieldReturn<FieldValue<z.input<TSchema>, P>>;
235
+ };
236
+ type BoundUseFieldArray<TSchema extends z.ZodType> = {
237
+ (pathSelector: (state: FormState<z.input<TSchema>>) => string): UseFieldArrayReturn<unknown>;
238
+ <P extends FieldPath<z.input<TSchema>>>(path: P): UseFieldArrayReturn<ArrayItemOf<FieldValue<z.input<TSchema>, P>>>;
239
+ };
240
+ type BoundUseSelector<TSchema extends z.ZodType> = <U>(selector: (state: FormState<z.input<TSchema>>) => U) => U;
241
+ type BoundUseFlag<TSchema extends z.ZodType> = (path?: FieldPath<z.input<TSchema>>) => boolean;
242
+ type FormHooks<TSchema extends z.ZodType, N extends string> = Readonly<{
243
+ [K in `use${Capitalize<N>}Field`]: BoundUseField<TSchema>;
244
+ } & {
245
+ [K in `use${Capitalize<N>}FieldArray`]: BoundUseFieldArray<TSchema>;
246
+ } & {
247
+ [K in `use${Capitalize<N>}Selector`]: BoundUseSelector<TSchema>;
248
+ } & {
249
+ [K in `use${Capitalize<N>}SelectorShallow`]: BoundUseSelector<TSchema>;
250
+ } & {
251
+ [K in `use${Capitalize<N>}Error`]: () => readonly string[] | undefined;
252
+ } & {
253
+ [K in `use${Capitalize<N>}IsDirty`]: BoundUseFlag<TSchema>;
254
+ } & {
255
+ [K in `use${Capitalize<N>}IsValid`]: BoundUseFlag<TSchema>;
256
+ } & {
257
+ [K in `use${Capitalize<N>}IsSubmitting`]: () => boolean;
258
+ } & {
259
+ [K in `use${Capitalize<N>}SubmitCount`]: () => number;
260
+ }>;
261
+ declare const createFormHooks: <TSchema extends z.ZodType, N extends string = "">(form: Form<TSchema>, name?: N) => FormHooks<TSchema, N>;
262
+
263
+ type ReadonlyStore<T> = Pick<StoreApi<T>, "getState" | "getInitialState" | "subscribe">;
264
+ type FormStateApi = Readonly<{
265
+ store: ReadonlyStore<FormState<unknown>>;
266
+ }>;
267
+ declare function useFormSelector<TSchema extends z.ZodType, U>(form: Form<TSchema>, selector: (state: FormState<z.input<TSchema>>) => U): U;
268
+ declare function useFormSelector<U>(form: FormStateApi & {
269
+ readonly schema?: undefined;
270
+ }, selector: (state: FormState<unknown>) => U): U;
271
+ declare function useFormSelectorShallow<TSchema extends z.ZodType, U>(form: Form<TSchema>, selector: (state: FormState<z.input<TSchema>>) => U): U;
272
+ declare function useFormSelectorShallow<U>(form: FormStateApi & {
273
+ readonly schema?: undefined;
274
+ }, selector: (state: FormState<unknown>) => U): U;
275
+
276
+ declare const useFormError: (form: FormStateApi) => readonly string[] | undefined;
277
+
278
+ declare function useIsDirty(form: FormStateApi & {
279
+ readonly schema?: undefined;
280
+ }, path?: string): boolean;
281
+ declare function useIsDirty<TSchema extends z.ZodType, P extends FieldPath<z.input<TSchema>>>(form: Form<TSchema>, path?: P): boolean;
282
+ declare function useIsValid(form: FormStateApi & {
283
+ readonly schema?: undefined;
284
+ }, path?: string): boolean;
285
+ declare function useIsValid<TSchema extends z.ZodType, P extends FieldPath<z.input<TSchema>>>(form: Form<TSchema>, path?: P): boolean;
286
+ declare const useIsSubmitting: (form: FormStateApi) => boolean;
287
+ declare const useSubmitCount: (form: FormStateApi) => number;
288
+
221
289
  type PathsOf<F extends FieldFormApi> = F extends Form<infer TSchema extends z.ZodType> ? FieldPath<z.input<TSchema>> : string;
222
290
  type FieldRef<T> = ((instance: T | null) => void) | Readonly<{
223
291
  current: T | null;
@@ -264,37 +332,6 @@ declare const SelectField: <T extends string, F extends FieldFormApi>({ form, pa
264
332
  declare const focusFirstError: (errors: ErrorMap, root?: ParentNode) => boolean;
265
333
  declare const focusField: (path: string, root?: ParentNode) => boolean;
266
334
 
267
- type ReadonlyStore<T> = Pick<StoreApi<T>, "getState" | "getInitialState" | "subscribe">;
268
- type FieldArrayFormApi = Readonly<{
269
- store: ReadonlyStore<FormState<unknown>>;
270
- arrayPush(path: string, item: unknown): void;
271
- arrayRemove(path: string, index: number): void;
272
- arrayInsert(path: string, index: number, item: unknown): void;
273
- arrayMove(path: string, from: number, to: number): void;
274
- arraySwap(path: string, a: number, b: number): void;
275
- }>;
276
- type FieldArrayEntry<TItem> = Readonly<{
277
- id: string;
278
- value: TItem;
279
- }>;
280
- type UseFieldArrayReturn<TItem> = Readonly<{
281
- fields: readonly FieldArrayEntry<TItem>[];
282
- items: readonly TItem[];
283
- length: number;
284
- error: readonly string[] | undefined;
285
- push: (item: TItem) => void;
286
- remove: (index: number) => void;
287
- insert: (index: number, item: TItem) => void;
288
- move: (from: number, to: number) => void;
289
- swap: (a: number, b: number) => void;
290
- }>;
291
- type ArrayItemOf<T> = [NonNullable<T>] extends [readonly (infer U)[]] ? U : never;
292
- declare function useFieldArray<TSchema extends z.ZodType>(form: Form<TSchema>, pathSelector: (state: FormState<z.input<TSchema>>) => string): UseFieldArrayReturn<unknown>;
293
- declare function useFieldArray<TItem = unknown>(form: FieldArrayFormApi & {
294
- readonly schema?: undefined;
295
- }, path: string | ((state: FormState<unknown>) => string)): UseFieldArrayReturn<TItem>;
296
- declare function useFieldArray<TSchema extends z.ZodType, P extends FieldPath<z.input<TSchema>>>(form: Form<TSchema>, path: P): UseFieldArrayReturn<ArrayItemOf<FieldValue<z.input<TSchema>, P>>>;
297
-
298
335
  type TextInputProps = Readonly<{
299
336
  name: string;
300
337
  value: string;
@@ -340,4 +377,4 @@ declare const numberInputProps: <T extends number | null | undefined>(field: Use
340
377
  declare const checkboxProps: <T extends boolean | null | undefined>(field: UseFieldReturn<T>) => CheckboxProps;
341
378
  declare const selectProps: <T extends string | null | undefined>(field: UseFieldReturn<T>) => SelectProps;
342
379
 
343
- 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 ParsedNumberText, type PathSegment, type PathsOf, 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, emptyValueForSchema, flattenIssues, focusField, focusFirstError, getAtPath, isAsyncRequiredError, numberInputProps, numberToInputText, parseNumberText, parsePath, selectProps, setAtPath, shouldValidateOn, textInputProps, useField, useFieldArray, useForm, useFormError, useFormSelector, useFormSelectorShallow, useIsDirty, useIsSubmitting, useIsValid, useSubmitCount, validateAsync, validateSync };
380
+ export { type BoolMap, type BoundUseField, type BoundUseFieldArray, type BoundUseFlag, type BoundUseSelector, 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 FormHooks, type FormProviderProps, type FormState, type FormStateApi, type InvalidSubmitHandler, NumberField, type NumberFieldProps, type NumberInputProps, type ParsedNumberText, type PathSegment, type PathsOf, 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, createFormHooks, emptyValueForSchema, flattenIssues, focusField, focusFirstError, getAtPath, isAsyncRequiredError, numberInputProps, numberToInputText, parseNumberText, parsePath, selectProps, setAtPath, shouldValidateOn, textInputProps, useField, useFieldArray, useForm, useFormError, useFormSelector, useFormSelectorShallow, useIsDirty, useIsSubmitting, useIsValid, useSubmitCount, validateAsync, validateSync };
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { createStore } from 'zustand/vanilla';
2
2
  import { z } from 'zod';
3
- import { useRef, useEffect, createContext, useMemo, useCallback, useId, useState, useContext } from 'react';
3
+ import { useRef, useEffect, createContext, useMemo, useCallback, useState, useId, useContext } from 'react';
4
4
  import { jsxs, jsx } from 'react/jsx-runtime';
5
5
  import { useStore } from 'zustand/react';
6
6
  import { useShallow } from 'zustand/react/shallow';
@@ -983,29 +983,6 @@ var createFormContext = () => {
983
983
  };
984
984
  return { Provider, useFormContext };
985
985
  };
986
- function useFormSelector(form, selector) {
987
- return useStore(form.store, selector);
988
- }
989
- function useFormSelectorShallow(form, selector) {
990
- return useStore(form.store, useShallow(selector));
991
- }
992
- var useFormError = (form) => useStore(
993
- form.store,
994
- useShallow((state) => state.errors[""])
995
- );
996
- var useIsDirty = (form) => useStore(
997
- form.store,
998
- (state) => isFieldDirty(state.values, state.initialValues)
999
- );
1000
- var useIsValid = (form) => useStore(form.store, (state) => {
1001
- for (const k in state.errors) {
1002
- const errs = state.errors[k];
1003
- if (errs !== void 0 && errs.length > 0) return false;
1004
- }
1005
- return true;
1006
- });
1007
- var useIsSubmitting = (form) => useStore(form.store, (state) => state.isSubmitting);
1008
- var useSubmitCount = (form) => useStore(form.store, (state) => state.submitCount);
1009
986
  function useField(form, pathArg, options) {
1010
987
  const slice = useStore(
1011
988
  form.store,
@@ -1135,6 +1112,169 @@ function useField(form, pathArg, options) {
1135
1112
  [slice, emptyValue, setValue, setTouched, setError, clearError, validate, validateAsync2, onBlur]
1136
1113
  );
1137
1114
  }
1115
+ var EMPTY_ID_STATE = { items: [], ids: [], counter: 0 };
1116
+ var EMPTY_ITEMS = [];
1117
+ var reconcileIds = (prev, nextItems) => {
1118
+ if (prev.items === nextItems) return prev;
1119
+ if (prev.items.length === nextItems.length && prev.items.every((item, i) => Object.is(item, nextItems[i]))) {
1120
+ return prev;
1121
+ }
1122
+ const buckets = prev.items.reduce((acc, item, i) => {
1123
+ const bucket = acc.get(item);
1124
+ if (bucket === void 0) {
1125
+ acc.set(item, [i]);
1126
+ } else {
1127
+ bucket.push(i);
1128
+ }
1129
+ return acc;
1130
+ }, /* @__PURE__ */ new Map());
1131
+ const matchedIds = nextItems.map((item) => {
1132
+ const prevIndex = buckets.get(item)?.shift();
1133
+ return prevIndex === void 0 ? null : prev.ids[prevIndex] ?? null;
1134
+ });
1135
+ const leftover = [...buckets.values()].flat().sort((a, b) => a - b).map((i) => prev.ids[i]).filter((id) => id !== void 0);
1136
+ const ordinals = matchedIds.reduce((acc, id) => {
1137
+ const count = acc.length === 0 ? 0 : acc[acc.length - 1] ?? 0;
1138
+ acc.push(id === null ? count + 1 : count);
1139
+ return acc;
1140
+ }, []);
1141
+ const unmatched = ordinals.length === 0 ? 0 : ordinals[ordinals.length - 1] ?? 0;
1142
+ const ids = matchedIds.map((id, i) => {
1143
+ if (id !== null) return id;
1144
+ const ordinal = ordinals[i] ?? 0;
1145
+ return leftover[ordinal - 1] ?? `__zfa_${prev.counter + (ordinal - leftover.length)}`;
1146
+ });
1147
+ return {
1148
+ items: nextItems,
1149
+ ids,
1150
+ counter: prev.counter + Math.max(0, unmatched - leftover.length)
1151
+ };
1152
+ };
1153
+ function useFieldArray(form, pathArg) {
1154
+ const path = useStore(
1155
+ form.store,
1156
+ (state) => typeof pathArg === "function" ? pathArg(state) : pathArg
1157
+ );
1158
+ const slice = useStore(
1159
+ form.store,
1160
+ useShallow((state) => {
1161
+ const value = getAtPath(state.values, path);
1162
+ return {
1163
+ items: Array.isArray(value) ? value : EMPTY_ITEMS,
1164
+ error: state.errors[path]
1165
+ };
1166
+ })
1167
+ );
1168
+ const items = slice.items;
1169
+ const error = slice.error;
1170
+ const [idEntry, setIdEntry] = useState({ form, path, state: EMPTY_ID_STATE });
1171
+ const base = idEntry.form === form && idEntry.path === path ? idEntry.state : { ...EMPTY_ID_STATE, counter: idEntry.state.counter };
1172
+ const nextIdState = reconcileIds(base, items);
1173
+ if (idEntry.form !== form || idEntry.path !== path || idEntry.state !== nextIdState) {
1174
+ setIdEntry({ form, path, state: nextIdState });
1175
+ }
1176
+ const ids = nextIdState.ids;
1177
+ const push = useCallback(
1178
+ (item) => form.arrayPush(path, item),
1179
+ [form, path]
1180
+ );
1181
+ const remove = useCallback(
1182
+ (index) => form.arrayRemove(path, index),
1183
+ [form, path]
1184
+ );
1185
+ const insert = useCallback(
1186
+ (index, item) => form.arrayInsert(path, index, item),
1187
+ [form, path]
1188
+ );
1189
+ const move = useCallback(
1190
+ (from, to) => form.arrayMove(path, from, to),
1191
+ [form, path]
1192
+ );
1193
+ const swap = useCallback(
1194
+ (a, b) => form.arraySwap(path, a, b),
1195
+ [form, path]
1196
+ );
1197
+ const fields = useMemo(
1198
+ () => items.map((value, index) => ({
1199
+ id: ids[index] ?? `__zfa_fallback_${index}`,
1200
+ value
1201
+ })),
1202
+ [items, ids]
1203
+ );
1204
+ return useMemo(
1205
+ () => ({
1206
+ fields,
1207
+ items,
1208
+ length: items.length,
1209
+ error,
1210
+ push,
1211
+ remove,
1212
+ insert,
1213
+ move,
1214
+ swap
1215
+ }),
1216
+ [fields, items, error, push, remove, insert, move, swap]
1217
+ );
1218
+ }
1219
+ var useFormError = (form) => useStore(
1220
+ form.store,
1221
+ useShallow((state) => state.errors[""])
1222
+ );
1223
+ function useIsDirty(form, path) {
1224
+ return useStore(
1225
+ form.store,
1226
+ (state) => path === void 0 || path === "" ? isFieldDirty(state.values, state.initialValues) : isFieldDirty(
1227
+ getAtPath(state.values, path),
1228
+ getAtPath(state.initialValues, path)
1229
+ )
1230
+ );
1231
+ }
1232
+ function useIsValid(form, path) {
1233
+ return useStore(form.store, (state) => {
1234
+ for (const k in state.errors) {
1235
+ const errs = state.errors[k];
1236
+ if (errs !== void 0 && errs.length > 0 && (path === void 0 || path === "" || isPathOrChild(k, path))) {
1237
+ return false;
1238
+ }
1239
+ }
1240
+ return true;
1241
+ });
1242
+ }
1243
+ var useIsSubmitting = (form) => useStore(form.store, (state) => state.isSubmitting);
1244
+ var useSubmitCount = (form) => useStore(form.store, (state) => state.submitCount);
1245
+ function useFormSelector(form, selector) {
1246
+ return useStore(form.store, selector);
1247
+ }
1248
+ function useFormSelectorShallow(form, selector) {
1249
+ return useStore(form.store, useShallow(selector));
1250
+ }
1251
+
1252
+ // src/react/createFormHooks.ts
1253
+ var capitalize = (name) => name.length === 0 ? name : name.charAt(0).toUpperCase() + name.slice(1);
1254
+ var createFormHooks = (form, name) => {
1255
+ const structural = form;
1256
+ const useBoundField = (path, options) => useField(structural, path, options);
1257
+ const useBoundFieldArray = (path) => useFieldArray(structural, path);
1258
+ const useBoundSelector = (selector) => useFormSelector(structural, selector);
1259
+ const useBoundSelectorShallow = (selector) => useFormSelectorShallow(structural, selector);
1260
+ const useBoundError = () => useFormError(structural);
1261
+ const useBoundIsDirty = (path) => useIsDirty(structural, path);
1262
+ const useBoundIsValid = (path) => useIsValid(structural, path);
1263
+ const useBoundIsSubmitting = () => useIsSubmitting(structural);
1264
+ const useBoundSubmitCount = () => useSubmitCount(structural);
1265
+ const prefix = capitalize(name ?? "");
1266
+ return {
1267
+ [`use${prefix}Field`]: useBoundField,
1268
+ [`use${prefix}FieldArray`]: useBoundFieldArray,
1269
+ [`use${prefix}Selector`]: useBoundSelector,
1270
+ [`use${prefix}SelectorShallow`]: useBoundSelectorShallow,
1271
+ [`use${prefix}Error`]: useBoundError,
1272
+ [`use${prefix}IsDirty`]: useBoundIsDirty,
1273
+ [`use${prefix}IsValid`]: useBoundIsValid,
1274
+ [`use${prefix}IsSubmitting`]: useBoundIsSubmitting,
1275
+ [`use${prefix}SubmitCount`]: useBoundSubmitCount
1276
+ };
1277
+ };
1138
1278
 
1139
1279
  // src/react/inputProps.ts
1140
1280
  var ariaInvalid = (field) => field.error !== void 0 && field.error.length > 0 ? true : void 0;
@@ -1389,111 +1529,7 @@ var focusField = (path, root) => {
1389
1529
  const controls = focusableControls(root ?? document);
1390
1530
  return path === "" ? (root !== void 0 || document.querySelectorAll("form").length <= 1) && focusFirstOf(controls) : focusFirstOf(controls.filter((el) => nameMatchesAny(el, [path])));
1391
1531
  };
1392
- var EMPTY_ID_STATE = { items: [], ids: [], counter: 0 };
1393
- var EMPTY_ITEMS = [];
1394
- var reconcileIds = (prev, nextItems) => {
1395
- if (prev.items === nextItems) return prev;
1396
- if (prev.items.length === nextItems.length && prev.items.every((item, i) => Object.is(item, nextItems[i]))) {
1397
- return prev;
1398
- }
1399
- const buckets = prev.items.reduce((acc, item, i) => {
1400
- const bucket = acc.get(item);
1401
- if (bucket === void 0) {
1402
- acc.set(item, [i]);
1403
- } else {
1404
- bucket.push(i);
1405
- }
1406
- return acc;
1407
- }, /* @__PURE__ */ new Map());
1408
- const matchedIds = nextItems.map((item) => {
1409
- const prevIndex = buckets.get(item)?.shift();
1410
- return prevIndex === void 0 ? null : prev.ids[prevIndex] ?? null;
1411
- });
1412
- const leftover = [...buckets.values()].flat().sort((a, b) => a - b).map((i) => prev.ids[i]).filter((id) => id !== void 0);
1413
- const ordinals = matchedIds.reduce((acc, id) => {
1414
- const count = acc.length === 0 ? 0 : acc[acc.length - 1] ?? 0;
1415
- acc.push(id === null ? count + 1 : count);
1416
- return acc;
1417
- }, []);
1418
- const unmatched = ordinals.length === 0 ? 0 : ordinals[ordinals.length - 1] ?? 0;
1419
- const ids = matchedIds.map((id, i) => {
1420
- if (id !== null) return id;
1421
- const ordinal = ordinals[i] ?? 0;
1422
- return leftover[ordinal - 1] ?? `__zfa_${prev.counter + (ordinal - leftover.length)}`;
1423
- });
1424
- return {
1425
- items: nextItems,
1426
- ids,
1427
- counter: prev.counter + Math.max(0, unmatched - leftover.length)
1428
- };
1429
- };
1430
- function useFieldArray(form, pathArg) {
1431
- const path = useStore(
1432
- form.store,
1433
- (state) => typeof pathArg === "function" ? pathArg(state) : pathArg
1434
- );
1435
- const slice = useStore(
1436
- form.store,
1437
- useShallow((state) => {
1438
- const value = getAtPath(state.values, path);
1439
- return {
1440
- items: Array.isArray(value) ? value : EMPTY_ITEMS,
1441
- error: state.errors[path]
1442
- };
1443
- })
1444
- );
1445
- const items = slice.items;
1446
- const error = slice.error;
1447
- const [idEntry, setIdEntry] = useState({ form, path, state: EMPTY_ID_STATE });
1448
- const base = idEntry.form === form && idEntry.path === path ? idEntry.state : { ...EMPTY_ID_STATE, counter: idEntry.state.counter };
1449
- const nextIdState = reconcileIds(base, items);
1450
- if (idEntry.form !== form || idEntry.path !== path || idEntry.state !== nextIdState) {
1451
- setIdEntry({ form, path, state: nextIdState });
1452
- }
1453
- const ids = nextIdState.ids;
1454
- const push = useCallback(
1455
- (item) => form.arrayPush(path, item),
1456
- [form, path]
1457
- );
1458
- const remove = useCallback(
1459
- (index) => form.arrayRemove(path, index),
1460
- [form, path]
1461
- );
1462
- const insert = useCallback(
1463
- (index, item) => form.arrayInsert(path, index, item),
1464
- [form, path]
1465
- );
1466
- const move = useCallback(
1467
- (from, to) => form.arrayMove(path, from, to),
1468
- [form, path]
1469
- );
1470
- const swap = useCallback(
1471
- (a, b) => form.arraySwap(path, a, b),
1472
- [form, path]
1473
- );
1474
- const fields = useMemo(
1475
- () => items.map((value, index) => ({
1476
- id: ids[index] ?? `__zfa_fallback_${index}`,
1477
- value
1478
- })),
1479
- [items, ids]
1480
- );
1481
- return useMemo(
1482
- () => ({
1483
- fields,
1484
- items,
1485
- length: items.length,
1486
- error,
1487
- push,
1488
- remove,
1489
- insert,
1490
- move,
1491
- swap
1492
- }),
1493
- [fields, items, error, push, remove, insert, move, swap]
1494
- );
1495
- }
1496
1532
 
1497
- export { CheckboxField, NumberField, SelectField, TextField, checkboxProps, createForm, createFormContext, emptyValueForSchema, flattenIssues, focusField, focusFirstError, getAtPath, isAsyncRequiredError, numberInputProps, numberToInputText, parseNumberText, parsePath, selectProps, setAtPath, shouldValidateOn, textInputProps, useField, useFieldArray, useForm, useFormError, useFormSelector, useFormSelectorShallow, useIsDirty, useIsSubmitting, useIsValid, useSubmitCount, validateAsync, validateSync };
1533
+ export { CheckboxField, NumberField, SelectField, TextField, checkboxProps, createForm, createFormContext, createFormHooks, emptyValueForSchema, flattenIssues, focusField, focusFirstError, getAtPath, isAsyncRequiredError, numberInputProps, numberToInputText, parseNumberText, parsePath, selectProps, setAtPath, shouldValidateOn, textInputProps, useField, useFieldArray, useForm, useFormError, useFormSelector, useFormSelectorShallow, useIsDirty, useIsSubmitting, useIsValid, useSubmitCount, validateAsync, validateSync };
1498
1534
  //# sourceMappingURL=index.js.map
1499
1535
  //# sourceMappingURL=index.js.map