@rachelallyson/hero-hook-form 2.6.0 → 2.7.2
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/CHANGELOG.md +53 -0
- package/dist/cypress/index.d.ts +62 -71
- package/dist/cypress/index.js +583 -70
- package/dist/index.d.ts +876 -101
- package/dist/index.js +1684 -719
- package/package.json +15 -12
- package/dist/react/index.d.ts +0 -3428
- package/dist/react/index.js +0 -3989
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import React$1, { ComponentProps } from 'react';
|
|
2
2
|
import { Button } from '@heroui/react';
|
|
3
3
|
import * as react_hook_form from 'react-hook-form';
|
|
4
|
-
import { FieldValues, Path, RegisterOptions, Control, UseFormReturn, FieldErrors, UseFormProps, SubmitHandler, UseFormSetError } from 'react-hook-form';
|
|
4
|
+
import { FieldValues, Path, RegisterOptions, ArrayPath, Control, UseFormReturn, FieldErrors, UseFormProps, SubmitHandler, DefaultValues, UseFormSetError, FieldArrayWithId } from 'react-hook-form';
|
|
5
5
|
export { UseFormReturn, useFormContext } from 'react-hook-form';
|
|
6
6
|
import * as zod from 'zod';
|
|
7
|
-
import { z } from 'zod';
|
|
7
|
+
import { z, ZodSchema } from 'zod';
|
|
8
8
|
import * as _internationalized_date from '@internationalized/date';
|
|
9
9
|
import { CalendarDate } from '@internationalized/date';
|
|
10
10
|
import { Autocomplete } from '@heroui/autocomplete';
|
|
@@ -17,6 +17,19 @@ import { Slider } from '@heroui/slider';
|
|
|
17
17
|
import { Switch } from '@heroui/switch';
|
|
18
18
|
import { Button as Button$1 } from '@heroui/button';
|
|
19
19
|
|
|
20
|
+
/**
|
|
21
|
+
* All supported field types that can be used in form builders
|
|
22
|
+
* This type is used throughout the codebase to ensure consistency
|
|
23
|
+
*/
|
|
24
|
+
type FormFieldType = "input" | "textarea" | "select" | "autocomplete" | "checkbox" | "switch" | "radio" | "slider" | "date" | "file" | "fontPicker" | "stringArray";
|
|
25
|
+
/**
|
|
26
|
+
* Helper to convert a Path<T>, ArrayPath<T>, or string to a string for use in React keys and DOM operations.
|
|
27
|
+
* Path<T> and ArrayPath<T> are branded string types, so this is safe - it's just removing the brand.
|
|
28
|
+
*
|
|
29
|
+
* @param path - The path to convert (can be Path<T>, ArrayPath<T>, string, or undefined)
|
|
30
|
+
* @returns The path as a plain string, or empty string if undefined
|
|
31
|
+
*/
|
|
32
|
+
declare function pathToString<T extends FieldValues>(path: Path<T> | ArrayPath<T> | string | undefined): string;
|
|
20
33
|
interface FieldBaseProps<TFieldValues extends FieldValues, TValue> {
|
|
21
34
|
name: Path<TFieldValues>;
|
|
22
35
|
label?: string;
|
|
@@ -30,7 +43,7 @@ interface FieldBaseProps<TFieldValues extends FieldValues, TValue> {
|
|
|
30
43
|
isDisabled?: boolean;
|
|
31
44
|
}
|
|
32
45
|
interface WithControl<TFieldValues extends FieldValues> {
|
|
33
|
-
control: Control<TFieldValues>;
|
|
46
|
+
control: Control<TFieldValues, any>;
|
|
34
47
|
}
|
|
35
48
|
interface BaseFormFieldConfig<TFieldValues extends FieldValues> {
|
|
36
49
|
name: Path<TFieldValues>;
|
|
@@ -73,6 +86,16 @@ interface RadioFieldConfig<TFieldValues extends FieldValues> extends BaseFormFie
|
|
|
73
86
|
value: string | number;
|
|
74
87
|
}[];
|
|
75
88
|
}
|
|
89
|
+
interface CheckboxGroupFieldConfig<TFieldValues extends FieldValues> extends BaseFormFieldConfig<TFieldValues> {
|
|
90
|
+
type: "checkboxGroup";
|
|
91
|
+
defaultValue?: (string | number)[];
|
|
92
|
+
checkboxGroupOptions?: {
|
|
93
|
+
label: string;
|
|
94
|
+
value: string | number;
|
|
95
|
+
}[];
|
|
96
|
+
checkboxProps?: Omit<React.ComponentProps<typeof Checkbox>, "isSelected" | "onValueChange" | "isInvalid" | "errorMessage" | "isDisabled" | "name">;
|
|
97
|
+
orientation?: "vertical" | "horizontal";
|
|
98
|
+
}
|
|
76
99
|
interface SliderFieldConfig<TFieldValues extends FieldValues> extends BaseFormFieldConfig<TFieldValues> {
|
|
77
100
|
type: "slider";
|
|
78
101
|
defaultValue?: number;
|
|
@@ -100,10 +123,35 @@ interface FontPickerFieldConfig<TFieldValues extends FieldValues> extends BaseFo
|
|
|
100
123
|
fontsLoadedTimeout?: number;
|
|
101
124
|
};
|
|
102
125
|
}
|
|
103
|
-
interface
|
|
126
|
+
interface StringArrayFieldConfig<TFieldValues extends FieldValues> extends BaseFormFieldConfig<TFieldValues> {
|
|
127
|
+
type: "stringArray";
|
|
128
|
+
defaultValue?: string[];
|
|
129
|
+
stringArrayProps?: {
|
|
130
|
+
/** Placeholder text for the input */
|
|
131
|
+
placeholder?: string;
|
|
132
|
+
/** Maximum number of items allowed */
|
|
133
|
+
maxItems?: number;
|
|
134
|
+
/** Minimum number of items required */
|
|
135
|
+
minItems?: number;
|
|
136
|
+
/** Allow duplicate values */
|
|
137
|
+
allowDuplicates?: boolean;
|
|
138
|
+
/** Custom validation function for each item */
|
|
139
|
+
validateItem?: (item: string) => string | true;
|
|
140
|
+
/** Transform item before adding (e.g., trim whitespace) */
|
|
141
|
+
transformItem?: (item: string) => string;
|
|
142
|
+
/** Custom chip render function */
|
|
143
|
+
renderChip?: (item: string, onRemove: () => void) => React.ReactNode;
|
|
144
|
+
/** Custom add button text */
|
|
145
|
+
addButtonText?: string;
|
|
146
|
+
/** Whether to show add button or use enter key */
|
|
147
|
+
showAddButton?: boolean;
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
interface CustomFieldConfig<TFieldValues extends FieldValues> extends Omit<BaseFormFieldConfig<TFieldValues>, "name"> {
|
|
104
151
|
type: "custom";
|
|
152
|
+
name: Path<TFieldValues> | ArrayPath<TFieldValues>;
|
|
105
153
|
render: (field: {
|
|
106
|
-
name: Path<TFieldValues>;
|
|
154
|
+
name: Path<TFieldValues> | ArrayPath<TFieldValues>;
|
|
107
155
|
control: Control<TFieldValues>;
|
|
108
156
|
form: UseFormReturn<TFieldValues>;
|
|
109
157
|
errors: FieldErrors<TFieldValues>;
|
|
@@ -115,13 +163,76 @@ interface ConditionalFieldConfig<TFieldValues extends FieldValues> extends BaseF
|
|
|
115
163
|
condition: (formData: Partial<TFieldValues>) => boolean;
|
|
116
164
|
field: ZodFormFieldConfig<TFieldValues>;
|
|
117
165
|
}
|
|
118
|
-
|
|
166
|
+
/**
|
|
167
|
+
* Field array config for dynamic repeating field groups.
|
|
168
|
+
*
|
|
169
|
+
* @description
|
|
170
|
+
* Configuration for field arrays that support reordering, custom rendering,
|
|
171
|
+
* default values, and conditional fields within array items.
|
|
172
|
+
*
|
|
173
|
+
* @template TFieldValues - The form data type
|
|
174
|
+
*/
|
|
175
|
+
interface FieldArrayConfig<TFieldValues extends FieldValues> extends Omit<BaseFormFieldConfig<TFieldValues>, "name"> {
|
|
119
176
|
type: "fieldArray";
|
|
177
|
+
/** Field array name - must be an ArrayPath (points to an array field) */
|
|
178
|
+
name: ArrayPath<TFieldValues>;
|
|
179
|
+
/** Field configurations for each array item */
|
|
120
180
|
fields: ZodFormFieldConfig<TFieldValues>[];
|
|
181
|
+
/** Minimum number of items (default: 0) */
|
|
121
182
|
min?: number;
|
|
183
|
+
/** Maximum number of items (default: 10) */
|
|
122
184
|
max?: number;
|
|
185
|
+
/** Add button text (default: "Add Item") */
|
|
123
186
|
addButtonText?: string;
|
|
187
|
+
/** Remove button text (default: "Remove") */
|
|
124
188
|
removeButtonText?: string;
|
|
189
|
+
/** Enable reordering of array items with up/down buttons (default: false) */
|
|
190
|
+
enableReordering?: boolean;
|
|
191
|
+
/** Custom text for reorder buttons */
|
|
192
|
+
reorderButtonText?: {
|
|
193
|
+
/** Text for move up button (default: "↑") */
|
|
194
|
+
up?: string;
|
|
195
|
+
/** Text for move down button (default: "↓") */
|
|
196
|
+
down?: string;
|
|
197
|
+
};
|
|
198
|
+
/** Function to create default item when adding new array item */
|
|
199
|
+
defaultItem?: () => any;
|
|
200
|
+
/** Custom render function for array items */
|
|
201
|
+
renderItem?: (props: {
|
|
202
|
+
/** Item index (0-based) */
|
|
203
|
+
index: number;
|
|
204
|
+
/** Field array item with id */
|
|
205
|
+
field: {
|
|
206
|
+
id: string;
|
|
207
|
+
[key: string]: any;
|
|
208
|
+
};
|
|
209
|
+
/** All fields in the array */
|
|
210
|
+
fields: {
|
|
211
|
+
id: string;
|
|
212
|
+
[key: string]: any;
|
|
213
|
+
}[];
|
|
214
|
+
/** Rendered field elements */
|
|
215
|
+
children: React.ReactNode;
|
|
216
|
+
/** Remove this item */
|
|
217
|
+
onRemove: () => void;
|
|
218
|
+
/** Move item up */
|
|
219
|
+
onMoveUp: () => void;
|
|
220
|
+
/** Move item down */
|
|
221
|
+
onMoveDown: () => void;
|
|
222
|
+
/** Whether item can be removed */
|
|
223
|
+
canRemove: boolean;
|
|
224
|
+
/** Whether item can move up */
|
|
225
|
+
canMoveUp: boolean;
|
|
226
|
+
/** Whether item can move down */
|
|
227
|
+
canMoveDown: boolean;
|
|
228
|
+
}) => React.ReactNode;
|
|
229
|
+
/** Custom render function for add button */
|
|
230
|
+
renderAddButton?: (props: {
|
|
231
|
+
/** Add new item */
|
|
232
|
+
onAdd: () => void;
|
|
233
|
+
/** Whether new item can be added */
|
|
234
|
+
canAdd: boolean;
|
|
235
|
+
}) => React.ReactNode;
|
|
125
236
|
}
|
|
126
237
|
interface DynamicSectionConfig<TFieldValues extends FieldValues> extends BaseFormFieldConfig<TFieldValues> {
|
|
127
238
|
type: "dynamicSection";
|
|
@@ -132,7 +243,7 @@ interface DynamicSectionConfig<TFieldValues extends FieldValues> extends BaseFor
|
|
|
132
243
|
}
|
|
133
244
|
interface ContentFieldConfig<TFieldValues extends FieldValues = FieldValues> {
|
|
134
245
|
type: "content";
|
|
135
|
-
name?:
|
|
246
|
+
name?: Path<TFieldValues>;
|
|
136
247
|
title?: string;
|
|
137
248
|
description?: string;
|
|
138
249
|
render?: (field: {
|
|
@@ -142,7 +253,7 @@ interface ContentFieldConfig<TFieldValues extends FieldValues = FieldValues> {
|
|
|
142
253
|
}) => React.ReactNode;
|
|
143
254
|
className?: string;
|
|
144
255
|
}
|
|
145
|
-
type FormFieldConfig<TFieldValues extends FieldValues> = StringFieldConfig<TFieldValues> | BooleanFieldConfig<TFieldValues> | RadioFieldConfig<TFieldValues> | SliderFieldConfig<TFieldValues> | DateFieldConfig<TFieldValues> | FileFieldConfig<TFieldValues> | FontPickerFieldConfig<TFieldValues> | CustomFieldConfig<TFieldValues> | ConditionalFieldConfig<TFieldValues> | FieldArrayConfig<TFieldValues> | DynamicSectionConfig<TFieldValues> | ContentFieldConfig<TFieldValues>;
|
|
256
|
+
type FormFieldConfig<TFieldValues extends FieldValues> = StringFieldConfig<TFieldValues> | BooleanFieldConfig<TFieldValues> | RadioFieldConfig<TFieldValues> | CheckboxGroupFieldConfig<TFieldValues> | SliderFieldConfig<TFieldValues> | DateFieldConfig<TFieldValues> | FileFieldConfig<TFieldValues> | FontPickerFieldConfig<TFieldValues> | StringArrayFieldConfig<TFieldValues> | CustomFieldConfig<TFieldValues> | ConditionalFieldConfig<TFieldValues> | FieldArrayConfig<TFieldValues> | DynamicSectionConfig<TFieldValues> | ContentFieldConfig<TFieldValues>;
|
|
146
257
|
interface FormConfig<TFieldValues extends FieldValues> {
|
|
147
258
|
fields: FormFieldConfig<TFieldValues>[];
|
|
148
259
|
layout?: "vertical" | "horizontal" | "grid" | "custom";
|
|
@@ -156,10 +267,12 @@ interface FormConfig<TFieldValues extends FieldValues> {
|
|
|
156
267
|
className?: string;
|
|
157
268
|
defaultValues?: Partial<TFieldValues>;
|
|
158
269
|
}
|
|
159
|
-
type ZodFormFieldConfig<TFieldValues extends FieldValues> = Omit<StringFieldConfig<TFieldValues>, "rules"> | Omit<BooleanFieldConfig<TFieldValues>, "rules"> | Omit<RadioFieldConfig<TFieldValues>, "rules"> | Omit<SliderFieldConfig<TFieldValues>, "rules"> | Omit<DateFieldConfig<TFieldValues>, "rules"> | Omit<FileFieldConfig<TFieldValues>, "rules"> | Omit<FontPickerFieldConfig<TFieldValues>, "rules"> | Omit<CustomFieldConfig<TFieldValues>, "rules"> | Omit<ConditionalFieldConfig<TFieldValues>, "rules"> | Omit<FieldArrayConfig<TFieldValues>, "rules"> | Omit<DynamicSectionConfig<TFieldValues>, "rules"> | ContentFieldConfig<TFieldValues>;
|
|
270
|
+
type ZodFormFieldConfig<TFieldValues extends FieldValues> = Omit<StringFieldConfig<TFieldValues>, "rules"> | Omit<BooleanFieldConfig<TFieldValues>, "rules"> | Omit<RadioFieldConfig<TFieldValues>, "rules"> | Omit<CheckboxGroupFieldConfig<TFieldValues>, "rules"> | Omit<SliderFieldConfig<TFieldValues>, "rules"> | Omit<DateFieldConfig<TFieldValues>, "rules"> | Omit<FileFieldConfig<TFieldValues>, "rules"> | Omit<FontPickerFieldConfig<TFieldValues>, "rules"> | Omit<StringArrayFieldConfig<TFieldValues>, "rules"> | Omit<CustomFieldConfig<TFieldValues>, "rules"> | Omit<ConditionalFieldConfig<TFieldValues>, "rules"> | Omit<FieldArrayConfig<TFieldValues>, "rules"> | Omit<DynamicSectionConfig<TFieldValues>, "rules"> | ContentFieldConfig<TFieldValues>;
|
|
160
271
|
interface ZodFormConfig<TFieldValues extends FieldValues> extends UseFormProps<TFieldValues> {
|
|
161
272
|
schema: zod.ZodSchema<TFieldValues>;
|
|
162
|
-
fields: ZodFormFieldConfig<TFieldValues>
|
|
273
|
+
fields: (ZodFormFieldConfig<TFieldValues> | (Omit<ZodFormFieldConfig<FieldValues>, "name"> & {
|
|
274
|
+
name: Path<TFieldValues>;
|
|
275
|
+
}))[];
|
|
163
276
|
onError?: (errors: FieldErrors<TFieldValues>) => void;
|
|
164
277
|
errorDisplay?: "inline" | "toast" | "modal" | "none";
|
|
165
278
|
}
|
|
@@ -247,7 +360,7 @@ interface FormProps$1<T extends FieldValues> {
|
|
|
247
360
|
submitButtonText?: string;
|
|
248
361
|
subtitle?: string;
|
|
249
362
|
title?: string;
|
|
250
|
-
defaultValues?:
|
|
363
|
+
defaultValues?: DefaultValues<T>;
|
|
251
364
|
}
|
|
252
365
|
/**
|
|
253
366
|
* Base form component for building forms without Zod validation.
|
|
@@ -303,11 +416,16 @@ interface FormProps$1<T extends FieldValues> {
|
|
|
303
416
|
declare function ConfigurableForm<T extends FieldValues>({ className, columns, defaultValues, fields, layout, onError, onSubmit, onSuccess, resetButtonText, showResetButton, spacing, submitButtonProps, submitButtonText, subtitle, title, }: FormProps$1<T>): React$1.JSX.Element;
|
|
304
417
|
|
|
305
418
|
interface FormFieldProps<TFieldValues extends FieldValues> {
|
|
306
|
-
config: FormFieldConfig<TFieldValues
|
|
419
|
+
config: FormFieldConfig<TFieldValues> | ZodFormFieldConfig<TFieldValues> | (Omit<FormFieldConfig<FieldValues>, "name"> & {
|
|
420
|
+
name: Path<TFieldValues>;
|
|
421
|
+
}) | (Omit<ZodFormFieldConfig<FieldValues>, "name"> & {
|
|
422
|
+
name: Path<TFieldValues>;
|
|
423
|
+
});
|
|
307
424
|
form: UseFormReturn<TFieldValues>;
|
|
308
425
|
submissionState: FormSubmissionState;
|
|
309
426
|
}
|
|
310
|
-
declare
|
|
427
|
+
declare function FormFieldComponent<TFieldValues extends FieldValues>({ config, form, submissionState, }: FormFieldProps<TFieldValues>): string | number | bigint | boolean | Iterable<React$1.ReactNode> | Promise<string | number | bigint | boolean | React$1.ReactPortal | React$1.ReactElement<unknown, string | React$1.JSXElementConstructor<any>> | Iterable<React$1.ReactNode> | null | undefined> | React$1.JSX.Element | null | undefined;
|
|
428
|
+
declare const FormField: typeof FormFieldComponent;
|
|
311
429
|
|
|
312
430
|
type ServerAction<TState = unknown, TFormData = FormData> = (state: TState | undefined, formData: TFormData) => Promise<TState>;
|
|
313
431
|
interface ActionState {
|
|
@@ -323,8 +441,12 @@ interface ServerActionFormProps<T extends FieldValues> {
|
|
|
323
441
|
className?: string;
|
|
324
442
|
columns?: 1 | 2 | 3;
|
|
325
443
|
/** Default values for form fields */
|
|
326
|
-
defaultValues?: Partial<T>;
|
|
327
|
-
fields: FormFieldConfig<T>
|
|
444
|
+
defaultValues?: Partial<T> | Record<string, unknown>;
|
|
445
|
+
fields: (FormFieldConfig<T> | FormFieldConfig<any> | ZodFormFieldConfig<any> | (Omit<FormFieldConfig<FieldValues>, "name"> & {
|
|
446
|
+
name: Path<T>;
|
|
447
|
+
}) | (Omit<ZodFormFieldConfig<FieldValues>, "name"> & {
|
|
448
|
+
name: Path<T>;
|
|
449
|
+
}))[];
|
|
328
450
|
/** Initial state for useActionState */
|
|
329
451
|
initialState?: ActionState;
|
|
330
452
|
layout?: "vertical" | "horizontal" | "grid";
|
|
@@ -433,7 +555,7 @@ interface ServerActionFormProps<T extends FieldValues> {
|
|
|
433
555
|
* @see {@link ConfigurableForm} for forms without Server Actions
|
|
434
556
|
* @category Components
|
|
435
557
|
*/
|
|
436
|
-
declare function ServerActionForm<T extends FieldValues>({ action, className, clientValidationSchema, columns, defaultValues, fields, initialState, layout, onError, onSuccess, resetButtonText, showResetButton, spacing, submitButtonProps, submitButtonText, subtitle, title, }: ServerActionFormProps<T>): React$1.JSX.Element;
|
|
558
|
+
declare function ServerActionForm<T extends FieldValues = FieldValues>({ action, className, clientValidationSchema, columns, defaultValues, fields, initialState, layout, onError, onSuccess, resetButtonText, showResetButton, spacing, submitButtonProps, submitButtonText, subtitle, title, }: ServerActionFormProps<T>): React$1.JSX.Element;
|
|
437
559
|
|
|
438
560
|
/**
|
|
439
561
|
* Configuration for an autocomplete option.
|
|
@@ -637,6 +759,119 @@ type CheckboxFieldProps<TFieldValues extends FieldValues> = FieldBaseProps<TFiel
|
|
|
637
759
|
*/
|
|
638
760
|
declare function CheckboxField<TFieldValues extends FieldValues>(props: CheckboxFieldProps<TFieldValues>): React$1.JSX.Element;
|
|
639
761
|
|
|
762
|
+
/**
|
|
763
|
+
* Configuration for a checkbox option in a checkbox group.
|
|
764
|
+
*
|
|
765
|
+
* @template TValue - The value type for the option
|
|
766
|
+
*/
|
|
767
|
+
interface CheckboxOption<TValue extends string | number> {
|
|
768
|
+
/** Display label for the option */
|
|
769
|
+
label: string;
|
|
770
|
+
/** Value of the option */
|
|
771
|
+
value: TValue;
|
|
772
|
+
/** Optional description text */
|
|
773
|
+
description?: string;
|
|
774
|
+
/** Whether the option is disabled */
|
|
775
|
+
disabled?: boolean;
|
|
776
|
+
}
|
|
777
|
+
/**
|
|
778
|
+
* Props for the CheckboxGroupField component.
|
|
779
|
+
*
|
|
780
|
+
* @template TFieldValues - The form data type
|
|
781
|
+
* @template TValue - The value type for the checkbox group (string or number)
|
|
782
|
+
*
|
|
783
|
+
* @example
|
|
784
|
+
* ```tsx
|
|
785
|
+
* import { CheckboxGroupField } from "@rachelallyson/hero-hook-form";
|
|
786
|
+
* import { useForm } from "react-hook-form";
|
|
787
|
+
*
|
|
788
|
+
* const form = useForm({
|
|
789
|
+
* defaultValues: { interests: [] },
|
|
790
|
+
* });
|
|
791
|
+
*
|
|
792
|
+
* const options = [
|
|
793
|
+
* { label: "Reading", value: "reading" },
|
|
794
|
+
* { label: "Sports", value: "sports" },
|
|
795
|
+
* { label: "Music", value: "music" },
|
|
796
|
+
* ];
|
|
797
|
+
*
|
|
798
|
+
* <CheckboxGroupField
|
|
799
|
+
* control={form.control}
|
|
800
|
+
* name="interests"
|
|
801
|
+
* label="Interests"
|
|
802
|
+
* options={options}
|
|
803
|
+
* />
|
|
804
|
+
* ```
|
|
805
|
+
*/
|
|
806
|
+
type CheckboxGroupFieldProps<TFieldValues extends FieldValues, TValue extends string | number = string> = FieldBaseProps<TFieldValues, TValue[]> & WithControl<TFieldValues> & {
|
|
807
|
+
/** Array of checkbox options */
|
|
808
|
+
options: readonly CheckboxOption<TValue>[];
|
|
809
|
+
/** Additional props to pass to individual Checkbox components */
|
|
810
|
+
checkboxProps?: Omit<React$1.ComponentProps<typeof Checkbox>, "isSelected" | "onValueChange" | "isInvalid" | "errorMessage" | "isDisabled" | "name">;
|
|
811
|
+
/** Layout orientation for the checkboxes */
|
|
812
|
+
orientation?: "vertical" | "horizontal";
|
|
813
|
+
};
|
|
814
|
+
/**
|
|
815
|
+
* A checkbox group field component that integrates React Hook Form with HeroUI Checkbox.
|
|
816
|
+
*
|
|
817
|
+
* This component provides a type-safe checkbox group field with validation support,
|
|
818
|
+
* error handling, and accessibility features. Multiple options can be selected,
|
|
819
|
+
* and the value is stored as an array of selected option values.
|
|
820
|
+
*
|
|
821
|
+
* @template TFieldValues - The form data type
|
|
822
|
+
* @template TValue - The value type for the checkbox group (string or number)
|
|
823
|
+
*
|
|
824
|
+
* @param props - The checkbox group field props
|
|
825
|
+
* @returns The rendered checkbox group field component
|
|
826
|
+
*
|
|
827
|
+
* @example
|
|
828
|
+
* ```tsx
|
|
829
|
+
* import { ZodForm, FormFieldHelpers } from "@rachelallyson/hero-hook-form";
|
|
830
|
+
* import { z } from "zod";
|
|
831
|
+
*
|
|
832
|
+
* const schema = z.object({
|
|
833
|
+
* interests: z.array(z.string()).min(1, "Please select at least one interest"),
|
|
834
|
+
* });
|
|
835
|
+
*
|
|
836
|
+
* const options = [
|
|
837
|
+
* { label: "Reading", value: "reading" },
|
|
838
|
+
* { label: "Sports", value: "sports" },
|
|
839
|
+
* { label: "Music", value: "music" },
|
|
840
|
+
* ];
|
|
841
|
+
*
|
|
842
|
+
* function MyForm() {
|
|
843
|
+
* return (
|
|
844
|
+
* <ZodForm
|
|
845
|
+
* config={{
|
|
846
|
+
* schema,
|
|
847
|
+
* fields: [
|
|
848
|
+
* FormFieldHelpers.checkboxGroup("interests", "Interests", options),
|
|
849
|
+
* ],
|
|
850
|
+
* }}
|
|
851
|
+
* onSubmit={(data) => console.log(data)}
|
|
852
|
+
* />
|
|
853
|
+
* );
|
|
854
|
+
* }
|
|
855
|
+
* ```
|
|
856
|
+
*
|
|
857
|
+
* @example
|
|
858
|
+
* ```tsx
|
|
859
|
+
* // With custom styling and horizontal layout
|
|
860
|
+
* <CheckboxGroupField
|
|
861
|
+
* control={form.control}
|
|
862
|
+
* name="interests"
|
|
863
|
+
* label="Interests"
|
|
864
|
+
* options={options}
|
|
865
|
+
* orientation="horizontal"
|
|
866
|
+
* checkboxProps={{
|
|
867
|
+
* color: "primary",
|
|
868
|
+
* size: "lg",
|
|
869
|
+
* }}
|
|
870
|
+
* />
|
|
871
|
+
* ```
|
|
872
|
+
*/
|
|
873
|
+
declare function CheckboxGroupField<TFieldValues extends FieldValues, TValue extends string | number = string>(props: CheckboxGroupFieldProps<TFieldValues, TValue>): React$1.JSX.Element;
|
|
874
|
+
|
|
640
875
|
/**
|
|
641
876
|
* Props for the DateField component.
|
|
642
877
|
*
|
|
@@ -1362,7 +1597,7 @@ interface UseFormHelperOptions<T extends FieldValues> {
|
|
|
1362
1597
|
onError?: (error: FormValidationError) => void;
|
|
1363
1598
|
onSubmit: SubmitHandler<T>;
|
|
1364
1599
|
onSuccess?: (data: T) => void;
|
|
1365
|
-
defaultValues?:
|
|
1600
|
+
defaultValues?: DefaultValues<T>;
|
|
1366
1601
|
methods?: UseFormReturn<T>;
|
|
1367
1602
|
}
|
|
1368
1603
|
/**
|
|
@@ -1497,7 +1732,7 @@ declare function useFormHelper<T extends FieldValues>({ defaultValues, methods,
|
|
|
1497
1732
|
* @category Hooks
|
|
1498
1733
|
*/
|
|
1499
1734
|
declare function useHeroForm<TFieldValues extends FieldValues>(): {
|
|
1500
|
-
defaults: Required<Pick<HeroHookFormDefaultsConfig, "input" | "textarea" | "select" | "
|
|
1735
|
+
defaults: Required<Pick<HeroHookFormDefaultsConfig, "input" | "textarea" | "select" | "checkbox" | "switch" | "slider" | "radioGroup" | "dateInput" | "submitButton">>;
|
|
1501
1736
|
watch: react_hook_form.UseFormWatch<TFieldValues>;
|
|
1502
1737
|
getValues: react_hook_form.UseFormGetValues<TFieldValues>;
|
|
1503
1738
|
getFieldState: react_hook_form.UseFormGetFieldState<TFieldValues>;
|
|
@@ -1940,6 +2175,7 @@ interface ZodFormProps<T extends FieldValues> {
|
|
|
1940
2175
|
className?: string;
|
|
1941
2176
|
columns?: 1 | 2 | 3;
|
|
1942
2177
|
config: ZodFormConfig<T>;
|
|
2178
|
+
errorDisplay?: "inline" | "toast" | "modal" | "none";
|
|
1943
2179
|
layout?: "vertical" | "horizontal" | "grid";
|
|
1944
2180
|
onError?: (error: FormValidationError) => void;
|
|
1945
2181
|
onSubmit: SubmitHandler<T>;
|
|
@@ -2032,6 +2268,83 @@ interface ZodFormProps<T extends FieldValues> {
|
|
|
2032
2268
|
*/
|
|
2033
2269
|
declare function ZodForm<T extends FieldValues>({ className, columns, config, layout, onError, onSubmit, onSuccess, resetButtonText, showResetButton, spacing, submitButtonProps, submitButtonText, subtitle, title, }: ZodFormProps<T>): React$1.JSX.Element;
|
|
2034
2270
|
|
|
2271
|
+
/**
|
|
2272
|
+
* Props for the SimpleForm component.
|
|
2273
|
+
*
|
|
2274
|
+
* @template TFieldValues - The form data type
|
|
2275
|
+
*/
|
|
2276
|
+
interface SimpleFormProps<TFieldValues extends FieldValues> {
|
|
2277
|
+
/** Zod schema for validation */
|
|
2278
|
+
schema: ZodSchema<TFieldValues>;
|
|
2279
|
+
/** Single field configuration */
|
|
2280
|
+
field: ZodFormFieldConfig<TFieldValues>;
|
|
2281
|
+
/** Submit handler */
|
|
2282
|
+
onSubmit: (data: TFieldValues) => Promise<void> | void;
|
|
2283
|
+
/** Optional custom submit button */
|
|
2284
|
+
submitButton?: React$1.ReactNode;
|
|
2285
|
+
/** Optional form title */
|
|
2286
|
+
title?: string;
|
|
2287
|
+
/** Optional form subtitle */
|
|
2288
|
+
subtitle?: string;
|
|
2289
|
+
/** Optional className */
|
|
2290
|
+
className?: string;
|
|
2291
|
+
/** Optional default values */
|
|
2292
|
+
defaultValues?: DefaultValues<TFieldValues>;
|
|
2293
|
+
/** Optional error callback */
|
|
2294
|
+
onError?: (error: FormValidationError) => void;
|
|
2295
|
+
/** Optional success callback */
|
|
2296
|
+
onSuccess?: (data: TFieldValues) => void;
|
|
2297
|
+
/** Hide default submit button (use custom submitButton instead) */
|
|
2298
|
+
hideSubmitButton?: boolean;
|
|
2299
|
+
}
|
|
2300
|
+
/**
|
|
2301
|
+
* Simple form component for single-field forms.
|
|
2302
|
+
*
|
|
2303
|
+
* @description
|
|
2304
|
+
* A simplified API for forms with a single field. Provides the same validation
|
|
2305
|
+
* and error handling as ZodForm but with a simpler configuration.
|
|
2306
|
+
* Useful for simple inputs like search bars, message inputs, or single-field forms.
|
|
2307
|
+
*
|
|
2308
|
+
* @template TFieldValues - The form data type
|
|
2309
|
+
*
|
|
2310
|
+
* @param {SimpleFormProps<TFieldValues>} props - Component props
|
|
2311
|
+
* @returns {JSX.Element} The rendered form
|
|
2312
|
+
*
|
|
2313
|
+
* @example
|
|
2314
|
+
* ```tsx
|
|
2315
|
+
* import { SimpleForm, FormFieldHelpers } from "@rachelallyson/hero-hook-form";
|
|
2316
|
+
* import { z } from "zod";
|
|
2317
|
+
*
|
|
2318
|
+
* const messageSchema = z.object({
|
|
2319
|
+
* message: z.string().min(1, "Message cannot be empty"),
|
|
2320
|
+
* });
|
|
2321
|
+
*
|
|
2322
|
+
* function MessageInput() {
|
|
2323
|
+
* return (
|
|
2324
|
+
* <SimpleForm
|
|
2325
|
+
* schema={messageSchema}
|
|
2326
|
+
* field={FormFieldHelpers.input("message", "", {
|
|
2327
|
+
* placeholder: "Add a note...",
|
|
2328
|
+
* endContent: (
|
|
2329
|
+
* <Button type="submit" isIconOnly>
|
|
2330
|
+
* <SendIcon />
|
|
2331
|
+
* </Button>
|
|
2332
|
+
* ),
|
|
2333
|
+
* })}
|
|
2334
|
+
* onSubmit={async (data) => {
|
|
2335
|
+
* await sendMessage(data.message);
|
|
2336
|
+
* }}
|
|
2337
|
+
* hideSubmitButton
|
|
2338
|
+
* />
|
|
2339
|
+
* );
|
|
2340
|
+
* }
|
|
2341
|
+
* ```
|
|
2342
|
+
*
|
|
2343
|
+
* @see {@link ZodForm} for multi-field forms
|
|
2344
|
+
* @category Components
|
|
2345
|
+
*/
|
|
2346
|
+
declare function SimpleForm<TFieldValues extends FieldValues>({ className, defaultValues, field, hideSubmitButton, onError, onSubmit, onSuccess, schema, submitButton, subtitle, title, }: SimpleFormProps<TFieldValues>): React$1.JSX.Element;
|
|
2347
|
+
|
|
2035
2348
|
/**
|
|
2036
2349
|
* Hook for using Zod validation with React Hook Form
|
|
2037
2350
|
*/
|
|
@@ -2039,7 +2352,7 @@ declare function useZodForm<TFieldValues extends FieldValues>(config: ZodFormCon
|
|
|
2039
2352
|
/**
|
|
2040
2353
|
* Helper function to create Zod form configurations
|
|
2041
2354
|
*/
|
|
2042
|
-
declare function createZodFormConfig<TFieldValues extends FieldValues>(schema: z.ZodSchema<TFieldValues>, fields: ZodFormFieldConfig<TFieldValues>[], defaultValues?:
|
|
2355
|
+
declare function createZodFormConfig<TFieldValues extends FieldValues>(schema: z.ZodSchema<TFieldValues>, fields: ZodFormFieldConfig<TFieldValues>[], defaultValues?: DefaultValues<TFieldValues>): ZodFormConfig<TFieldValues>;
|
|
2043
2356
|
|
|
2044
2357
|
/**
|
|
2045
2358
|
* Basic form field builder for creating form field configurations.
|
|
@@ -2189,6 +2502,11 @@ declare function createBasicFormBuilder<T extends FieldValues>(): BasicFormBuild
|
|
|
2189
2502
|
* @see {@link createBasicFormBuilder} for builder pattern alternative
|
|
2190
2503
|
* @category Builders
|
|
2191
2504
|
*/
|
|
2505
|
+
type InputPropsType = Omit<React$1.ComponentProps<typeof Input>, "value" | "onValueChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled">;
|
|
2506
|
+
declare function inputHelper<T extends FieldValues>(name: Path<T>, label: string): ZodFormFieldConfig<T>;
|
|
2507
|
+
declare function inputHelper<T extends FieldValues>(name: Path<T>, label: string, type: "text" | "email" | "tel" | "password"): ZodFormFieldConfig<T>;
|
|
2508
|
+
declare function inputHelper<T extends FieldValues>(name: Path<T>, label: string, inputProps: InputPropsType): ZodFormFieldConfig<T>;
|
|
2509
|
+
declare function inputHelper<T extends FieldValues>(name: Path<T>, label: string, type: "text" | "email" | "tel" | "password", inputProps: InputPropsType): ZodFormFieldConfig<T>;
|
|
2192
2510
|
declare const FormFieldHelpers: {
|
|
2193
2511
|
/**
|
|
2194
2512
|
* Create an autocomplete field
|
|
@@ -2228,6 +2546,33 @@ declare const FormFieldHelpers: {
|
|
|
2228
2546
|
* ```
|
|
2229
2547
|
*/
|
|
2230
2548
|
checkbox: <T extends FieldValues>(name: Path<T>, label: string, checkboxProps?: Omit<React$1.ComponentProps<typeof Checkbox>, "isSelected" | "onValueChange" | "isInvalid" | "errorMessage" | "isDisabled">) => ZodFormFieldConfig<T>;
|
|
2549
|
+
/**
|
|
2550
|
+
* Create a checkbox group field (multiple checkboxes saving to an array)
|
|
2551
|
+
*
|
|
2552
|
+
* @example
|
|
2553
|
+
* ```tsx
|
|
2554
|
+
* // Simple checkbox group
|
|
2555
|
+
* FormFieldHelpers.checkboxGroup("interests", "Interests", [
|
|
2556
|
+
* { label: "Reading", value: "reading" },
|
|
2557
|
+
* { label: "Sports", value: "sports" },
|
|
2558
|
+
* { label: "Music", value: "music" },
|
|
2559
|
+
* ])
|
|
2560
|
+
*
|
|
2561
|
+
* // With horizontal layout and custom styling
|
|
2562
|
+
* FormFieldHelpers.checkboxGroup("interests", "Interests", options, {
|
|
2563
|
+
* orientation: "horizontal",
|
|
2564
|
+
* checkboxProps: { color: "primary", size: "lg" }
|
|
2565
|
+
* })
|
|
2566
|
+
* ```
|
|
2567
|
+
*/
|
|
2568
|
+
checkboxGroup: <T extends FieldValues>(name: Path<T>, label: string, options: {
|
|
2569
|
+
label: string;
|
|
2570
|
+
value: string | number;
|
|
2571
|
+
}[], config?: {
|
|
2572
|
+
checkboxProps?: Omit<React$1.ComponentProps<typeof Checkbox>, "isSelected" | "onValueChange" | "isInvalid" | "errorMessage" | "isDisabled" | "name">;
|
|
2573
|
+
orientation?: "vertical" | "horizontal";
|
|
2574
|
+
description?: string;
|
|
2575
|
+
}) => ZodFormFieldConfig<T>;
|
|
2231
2576
|
/**
|
|
2232
2577
|
* Create a conditional field that shows/hides based on form data
|
|
2233
2578
|
*
|
|
@@ -2273,7 +2618,34 @@ declare const FormFieldHelpers: {
|
|
|
2273
2618
|
isSubmitting: boolean;
|
|
2274
2619
|
}) => React$1.ReactNode;
|
|
2275
2620
|
className?: string;
|
|
2276
|
-
name?:
|
|
2621
|
+
name?: Path<T>;
|
|
2622
|
+
}) => ZodFormFieldConfig<T>;
|
|
2623
|
+
/**
|
|
2624
|
+
* Create a custom field with full control over rendering
|
|
2625
|
+
*
|
|
2626
|
+
* @example
|
|
2627
|
+
* ```tsx
|
|
2628
|
+
* // Custom field with render function
|
|
2629
|
+
* FormFieldHelpers.custom<FormData>(
|
|
2630
|
+
* "skills",
|
|
2631
|
+
* "Skills",
|
|
2632
|
+
* ({ form, control }) => {
|
|
2633
|
+
* // Custom rendering logic
|
|
2634
|
+
* return <div>...</div>;
|
|
2635
|
+
* }
|
|
2636
|
+
* )
|
|
2637
|
+
* ```
|
|
2638
|
+
*/
|
|
2639
|
+
custom: <T extends FieldValues>(name: Path<T> | ArrayPath<T>, label: string, render: (field: {
|
|
2640
|
+
name: Path<T> | ArrayPath<T>;
|
|
2641
|
+
control: Control<T>;
|
|
2642
|
+
form: UseFormReturn<T>;
|
|
2643
|
+
errors: FieldErrors<T>;
|
|
2644
|
+
isSubmitting: boolean;
|
|
2645
|
+
}) => React$1.ReactNode, options?: {
|
|
2646
|
+
description?: string;
|
|
2647
|
+
className?: string;
|
|
2648
|
+
isDisabled?: boolean;
|
|
2277
2649
|
}) => ZodFormFieldConfig<T>;
|
|
2278
2650
|
/**
|
|
2279
2651
|
* Create a date field
|
|
@@ -2352,7 +2724,10 @@ declare const FormFieldHelpers: {
|
|
|
2352
2724
|
* // With type
|
|
2353
2725
|
* FormFieldHelpers.input("email", "Email", "email")
|
|
2354
2726
|
*
|
|
2355
|
-
* // With
|
|
2727
|
+
* // With props only (no type)
|
|
2728
|
+
* FormFieldHelpers.input("name", "Name", { placeholder: "Enter name" })
|
|
2729
|
+
*
|
|
2730
|
+
* // With type and props
|
|
2356
2731
|
* FormFieldHelpers.input("email", "Email", "email", {
|
|
2357
2732
|
* placeholder: "Enter your email",
|
|
2358
2733
|
* classNames: { input: "custom-input" },
|
|
@@ -2361,7 +2736,25 @@ declare const FormFieldHelpers: {
|
|
|
2361
2736
|
* })
|
|
2362
2737
|
* ```
|
|
2363
2738
|
*/
|
|
2364
|
-
input:
|
|
2739
|
+
input: typeof inputHelper;
|
|
2740
|
+
/**
|
|
2741
|
+
* Create a radio group field
|
|
2742
|
+
*
|
|
2743
|
+
* @example
|
|
2744
|
+
* ```tsx
|
|
2745
|
+
* // Simple radio group
|
|
2746
|
+
* FormFieldHelpers.radio("gender", "Gender", [
|
|
2747
|
+
* { label: "Male", value: "male" },
|
|
2748
|
+
* { label: "Female", value: "female" }
|
|
2749
|
+
* ])
|
|
2750
|
+
*
|
|
2751
|
+
* // With full customization
|
|
2752
|
+
* FormFieldHelpers.radio("gender", "Gender", options, {
|
|
2753
|
+
* orientation: "horizontal",
|
|
2754
|
+
* classNames: { base: "custom-radio" }
|
|
2755
|
+
* })
|
|
2756
|
+
* ```
|
|
2757
|
+
*/
|
|
2365
2758
|
/**
|
|
2366
2759
|
* Create a radio group field
|
|
2367
2760
|
*
|
|
@@ -2466,6 +2859,26 @@ declare const FormFieldHelpers: {
|
|
|
2466
2859
|
};
|
|
2467
2860
|
/**
|
|
2468
2861
|
* Common field collections
|
|
2862
|
+
*
|
|
2863
|
+
* These helpers provide reusable field sets for common form patterns.
|
|
2864
|
+
* The `as Path<T>` assertions are necessary because TypeScript cannot prove
|
|
2865
|
+
* that string literals like "street" or "email" are valid paths in an arbitrary
|
|
2866
|
+
* form type `T`. These helpers are designed to work with any form type that
|
|
2867
|
+
* happens to have these fields - the type safety is enforced when you use them
|
|
2868
|
+
* with a specific form schema.
|
|
2869
|
+
*
|
|
2870
|
+
* @example
|
|
2871
|
+
* ```tsx
|
|
2872
|
+
* const schema = z.object({
|
|
2873
|
+
* street: z.string(),
|
|
2874
|
+
* city: z.string(),
|
|
2875
|
+
* // ... other fields
|
|
2876
|
+
* });
|
|
2877
|
+
*
|
|
2878
|
+
* const fields = [
|
|
2879
|
+
* ...CommonFields.address<z.infer<typeof schema>>(),
|
|
2880
|
+
* ];
|
|
2881
|
+
* ```
|
|
2469
2882
|
*/
|
|
2470
2883
|
declare const CommonFields: {
|
|
2471
2884
|
/**
|
|
@@ -2483,10 +2896,163 @@ declare const CommonFields: {
|
|
|
2483
2896
|
};
|
|
2484
2897
|
|
|
2485
2898
|
/**
|
|
2486
|
-
*
|
|
2487
|
-
*
|
|
2899
|
+
* Discriminated union types for field creation parameters
|
|
2900
|
+
* This eliminates the need for 'unknown' types and type assertions
|
|
2488
2901
|
*/
|
|
2489
|
-
|
|
2902
|
+
type FieldCreationParams<T extends FieldValues> = {
|
|
2903
|
+
type: "input";
|
|
2904
|
+
name: Path<T>;
|
|
2905
|
+
label: string;
|
|
2906
|
+
props?: {
|
|
2907
|
+
type?: "text" | "email" | "tel" | "password" | "number" | "url";
|
|
2908
|
+
placeholder?: string;
|
|
2909
|
+
description?: string;
|
|
2910
|
+
isDisabled?: boolean;
|
|
2911
|
+
className?: string;
|
|
2912
|
+
};
|
|
2913
|
+
} | {
|
|
2914
|
+
type: "textarea";
|
|
2915
|
+
name: Path<T>;
|
|
2916
|
+
label: string;
|
|
2917
|
+
props?: {
|
|
2918
|
+
placeholder?: string;
|
|
2919
|
+
description?: string;
|
|
2920
|
+
isDisabled?: boolean;
|
|
2921
|
+
className?: string;
|
|
2922
|
+
rows?: number;
|
|
2923
|
+
};
|
|
2924
|
+
} | {
|
|
2925
|
+
type: "select";
|
|
2926
|
+
name: Path<T>;
|
|
2927
|
+
label: string;
|
|
2928
|
+
options: {
|
|
2929
|
+
label: string;
|
|
2930
|
+
value: string | number;
|
|
2931
|
+
}[];
|
|
2932
|
+
} | {
|
|
2933
|
+
type: "autocomplete";
|
|
2934
|
+
name: Path<T>;
|
|
2935
|
+
label: string;
|
|
2936
|
+
options: {
|
|
2937
|
+
label: string;
|
|
2938
|
+
value: string | number;
|
|
2939
|
+
}[];
|
|
2940
|
+
props?: Record<string, unknown>;
|
|
2941
|
+
} | {
|
|
2942
|
+
type: "checkbox";
|
|
2943
|
+
name: Path<T>;
|
|
2944
|
+
label: string;
|
|
2945
|
+
props?: {
|
|
2946
|
+
description?: string;
|
|
2947
|
+
isDisabled?: boolean;
|
|
2948
|
+
className?: string;
|
|
2949
|
+
};
|
|
2950
|
+
} | {
|
|
2951
|
+
type: "switch";
|
|
2952
|
+
name: Path<T>;
|
|
2953
|
+
label: string;
|
|
2954
|
+
props?: {
|
|
2955
|
+
description?: string;
|
|
2956
|
+
isDisabled?: boolean;
|
|
2957
|
+
className?: string;
|
|
2958
|
+
};
|
|
2959
|
+
} | {
|
|
2960
|
+
type: "radio";
|
|
2961
|
+
name: Path<T>;
|
|
2962
|
+
label: string;
|
|
2963
|
+
options: {
|
|
2964
|
+
label: string;
|
|
2965
|
+
value: string | number;
|
|
2966
|
+
}[];
|
|
2967
|
+
props?: {
|
|
2968
|
+
description?: string;
|
|
2969
|
+
isDisabled?: boolean;
|
|
2970
|
+
className?: string;
|
|
2971
|
+
orientation?: "horizontal" | "vertical";
|
|
2972
|
+
};
|
|
2973
|
+
} | {
|
|
2974
|
+
type: "slider";
|
|
2975
|
+
name: Path<T>;
|
|
2976
|
+
label: string;
|
|
2977
|
+
props?: {
|
|
2978
|
+
min?: number;
|
|
2979
|
+
max?: number;
|
|
2980
|
+
step?: number;
|
|
2981
|
+
description?: string;
|
|
2982
|
+
isDisabled?: boolean;
|
|
2983
|
+
className?: string;
|
|
2984
|
+
};
|
|
2985
|
+
} | {
|
|
2986
|
+
type: "date";
|
|
2987
|
+
name: Path<T>;
|
|
2988
|
+
label: string;
|
|
2989
|
+
props?: {
|
|
2990
|
+
placeholder?: string;
|
|
2991
|
+
description?: string;
|
|
2992
|
+
isDisabled?: boolean;
|
|
2993
|
+
className?: string;
|
|
2994
|
+
};
|
|
2995
|
+
} | {
|
|
2996
|
+
type: "file";
|
|
2997
|
+
name: Path<T>;
|
|
2998
|
+
label: string;
|
|
2999
|
+
props?: {
|
|
3000
|
+
accept?: string;
|
|
3001
|
+
multiple?: boolean;
|
|
3002
|
+
description?: string;
|
|
3003
|
+
isDisabled?: boolean;
|
|
3004
|
+
className?: string;
|
|
3005
|
+
};
|
|
3006
|
+
} | {
|
|
3007
|
+
type: "fontPicker";
|
|
3008
|
+
name: Path<T>;
|
|
3009
|
+
label: string;
|
|
3010
|
+
props?: {
|
|
3011
|
+
description?: string;
|
|
3012
|
+
isDisabled?: boolean;
|
|
3013
|
+
className?: string;
|
|
3014
|
+
fontPickerProps?: {
|
|
3015
|
+
showFontPreview?: boolean;
|
|
3016
|
+
loadAllVariants?: boolean;
|
|
3017
|
+
onFontsLoaded?: (loaded: boolean) => void;
|
|
3018
|
+
fontsLoadedTimeout?: number;
|
|
3019
|
+
};
|
|
3020
|
+
};
|
|
3021
|
+
} | {
|
|
3022
|
+
type: "stringArray";
|
|
3023
|
+
name: Path<T>;
|
|
3024
|
+
label: string;
|
|
3025
|
+
props?: {
|
|
3026
|
+
placeholder?: string;
|
|
3027
|
+
maxItems?: number;
|
|
3028
|
+
minItems?: number;
|
|
3029
|
+
allowDuplicates?: boolean;
|
|
3030
|
+
validateItem?: (item: string) => string | true;
|
|
3031
|
+
transformItem?: (item: string) => string;
|
|
3032
|
+
addButtonText?: string;
|
|
3033
|
+
showAddButton?: boolean;
|
|
3034
|
+
description?: string;
|
|
3035
|
+
isDisabled?: boolean;
|
|
3036
|
+
className?: string;
|
|
3037
|
+
};
|
|
3038
|
+
} | {
|
|
3039
|
+
type: "content";
|
|
3040
|
+
name?: Path<T>;
|
|
3041
|
+
label?: string;
|
|
3042
|
+
title?: string | null;
|
|
3043
|
+
description?: string | null;
|
|
3044
|
+
render?: (field: {
|
|
3045
|
+
form: UseFormReturn<T>;
|
|
3046
|
+
errors: FieldErrors<T>;
|
|
3047
|
+
isSubmitting: boolean;
|
|
3048
|
+
}) => React$1.ReactNode;
|
|
3049
|
+
className?: string;
|
|
3050
|
+
};
|
|
3051
|
+
/**
|
|
3052
|
+
* Unified field creation function using discriminated union types
|
|
3053
|
+
* This provides full type safety without complex overloads
|
|
3054
|
+
*/
|
|
3055
|
+
declare function createField<T extends FieldValues>(params: FieldCreationParams<T>): ZodFormFieldConfig<T>;
|
|
2490
3056
|
/**
|
|
2491
3057
|
* Builder pattern for advanced field creation
|
|
2492
3058
|
*/
|
|
@@ -2495,21 +3061,7 @@ declare class AdvancedFieldBuilder<T extends FieldValues> {
|
|
|
2495
3061
|
/**
|
|
2496
3062
|
* Add any field type using the unified API
|
|
2497
3063
|
*/
|
|
2498
|
-
field(
|
|
2499
|
-
field(type: "textarea", name: Path<T>, label: string, props?: Parameters<typeof createField<T>>[3]): this;
|
|
2500
|
-
field(type: "select", name: Path<T>, label: string, options: {
|
|
2501
|
-
label: string;
|
|
2502
|
-
value: string | number;
|
|
2503
|
-
}[], props?: Parameters<typeof createField<T>>[4]): this;
|
|
2504
|
-
field(type: "checkbox", name: Path<T>, label: string, props?: Parameters<typeof createField<T>>[3]): this;
|
|
2505
|
-
field(type: "switch", name: Path<T>, label: string, props?: Parameters<typeof createField<T>>[3]): this;
|
|
2506
|
-
field(type: "radio", name: Path<T>, label: string, options: {
|
|
2507
|
-
label: string;
|
|
2508
|
-
value: string | number;
|
|
2509
|
-
}[], props?: Parameters<typeof createField<T>>[4]): this;
|
|
2510
|
-
field(type: "slider", name: Path<T>, label: string, props?: Parameters<typeof createField<T>>[3]): this;
|
|
2511
|
-
field(type: "date", name: Path<T>, label: string, props?: Parameters<typeof createField<T>>[3]): this;
|
|
2512
|
-
field(type: "file", name: Path<T>, label: string, props?: Parameters<typeof createField<T>>[3]): this;
|
|
3064
|
+
field(params: FieldCreationParams<T>): this;
|
|
2513
3065
|
/**
|
|
2514
3066
|
* Add a conditional field that shows/hides based on form data
|
|
2515
3067
|
*/
|
|
@@ -2517,7 +3069,7 @@ declare class AdvancedFieldBuilder<T extends FieldValues> {
|
|
|
2517
3069
|
/**
|
|
2518
3070
|
* Add a field array for dynamic repeating field groups
|
|
2519
3071
|
*/
|
|
2520
|
-
fieldArray(name:
|
|
3072
|
+
fieldArray(name: ArrayPath<T>, label: string, fields: ZodFormFieldConfig<T>[], options?: {
|
|
2521
3073
|
min?: number;
|
|
2522
3074
|
max?: number;
|
|
2523
3075
|
addButtonText?: string;
|
|
@@ -2543,22 +3095,7 @@ declare class FieldArrayItemBuilder<TItem extends FieldValues> {
|
|
|
2543
3095
|
/**
|
|
2544
3096
|
* Add any field type using the unified API for array items
|
|
2545
3097
|
*/
|
|
2546
|
-
field(
|
|
2547
|
-
field(type: "textarea", name: Path<TItem>, label: string, props?: Parameters<typeof createField<TItem>>[3]): this;
|
|
2548
|
-
field(type: "select", name: Path<TItem>, label: string, options: {
|
|
2549
|
-
label: string;
|
|
2550
|
-
value: string | number;
|
|
2551
|
-
}[], props?: Parameters<typeof createField<TItem>>[4]): this;
|
|
2552
|
-
field(type: "checkbox", name: Path<TItem>, label: string, props?: Parameters<typeof createField<TItem>>[3]): this;
|
|
2553
|
-
field(type: "switch", name: Path<TItem>, label: string, props?: Parameters<typeof createField<TItem>>[3]): this;
|
|
2554
|
-
field(type: "radio", name: Path<TItem>, label: string, options: {
|
|
2555
|
-
label: string;
|
|
2556
|
-
value: string | number;
|
|
2557
|
-
}[], props?: Parameters<typeof createField<TItem>>[4]): this;
|
|
2558
|
-
field(type: "slider", name: Path<TItem>, label: string, props?: Parameters<typeof createField<TItem>>[3]): this;
|
|
2559
|
-
field(type: "date", name: Path<TItem>, label: string, props?: Parameters<typeof createField<TItem>>[3]): this;
|
|
2560
|
-
field(type: "file", name: Path<TItem>, label: string, props?: Parameters<typeof createField<TItem>>[3]): this;
|
|
2561
|
-
field(type: "fontPicker", name: Path<TItem>, label: string, props?: Parameters<typeof createField<TItem>>[3]): this;
|
|
3098
|
+
field(params: FieldCreationParams<TItem>): this;
|
|
2562
3099
|
/**
|
|
2563
3100
|
* Build the field array item configuration
|
|
2564
3101
|
*/
|
|
@@ -2575,8 +3112,8 @@ declare class FieldArrayBuilder<T extends FieldValues, TArrayName extends Path<T
|
|
|
2575
3112
|
private arrayName;
|
|
2576
3113
|
private fields;
|
|
2577
3114
|
constructor(arrayName: TArrayName);
|
|
2578
|
-
field(
|
|
2579
|
-
build(): ZodFormFieldConfig<
|
|
3115
|
+
field(params: FieldCreationParams<Record<string, any>>): this;
|
|
3116
|
+
build(): ZodFormFieldConfig<T>[];
|
|
2580
3117
|
}
|
|
2581
3118
|
/**
|
|
2582
3119
|
* Create a field array builder that constructs proper paths for array items
|
|
@@ -2745,17 +3282,32 @@ declare const field: {
|
|
|
2745
3282
|
textarea: <T extends FieldValues>(name: Path<T>, label: string, options?: Parameters<TypeInferredBuilder<T>["textarea"]>[2]) => TypeInferredBuilder<T>;
|
|
2746
3283
|
};
|
|
2747
3284
|
|
|
3285
|
+
/**
|
|
3286
|
+
* Helper type to construct a nested path from a base path and sub-path.
|
|
3287
|
+
* Attempts to construct the path and falls back to Path<T> if TypeScript
|
|
3288
|
+
* can't verify the nested structure at compile time.
|
|
3289
|
+
*
|
|
3290
|
+
* @example
|
|
3291
|
+
* type T = { user: { name: string } };
|
|
3292
|
+
* type Nested = ConstructNestedPath<T, "user", "name">; // "user.name"
|
|
3293
|
+
*/
|
|
3294
|
+
type ConstructNestedPath<T extends FieldValues, TBasePath extends Path<T>, TSubPath extends string> = `${TBasePath}.${TSubPath}` extends Path<T> ? `${TBasePath}.${TSubPath}` : Path<T>;
|
|
2748
3295
|
/**
|
|
2749
3296
|
* Enhanced nested path builder with better syntax for complex nested structures
|
|
2750
3297
|
* Provides multiple approaches for handling nested field paths
|
|
2751
3298
|
*/
|
|
2752
3299
|
declare class NestedPathBuilder<T extends FieldValues> {
|
|
2753
|
-
|
|
3300
|
+
fields: ZodFormFieldConfig<T>[];
|
|
2754
3301
|
/**
|
|
2755
3302
|
* Create a nested object path builder
|
|
2756
3303
|
* Usage: builder.nest("address").field("street", "Street Address")
|
|
3304
|
+
*
|
|
3305
|
+
* @param path - A path in the form data structure. When called from root level,
|
|
3306
|
+
* accepts Path<T>. When called after .end() from a nested context,
|
|
3307
|
+
* accepts any string for nested paths under sections.
|
|
3308
|
+
* @returns A builder for nested paths under the specified path
|
|
2757
3309
|
*/
|
|
2758
|
-
nest
|
|
3310
|
+
nest(path: string & {}): NestedObjectBuilder<T, Path<T>>;
|
|
2759
3311
|
/**
|
|
2760
3312
|
* Create a section-based path builder
|
|
2761
3313
|
* Usage: builder.section("shipping").field("street", "Street Address")
|
|
@@ -2763,14 +3315,14 @@ declare class NestedPathBuilder<T extends FieldValues> {
|
|
|
2763
3315
|
section<TPath extends Path<T>>(path: TPath): SectionBuilder<T, TPath>;
|
|
2764
3316
|
/**
|
|
2765
3317
|
* Add a field with single path
|
|
2766
|
-
* Usage: builder.field("firstName", "First Name")
|
|
3318
|
+
* Usage: builder.field({ type: "input", name: "firstName", label: "First Name" })
|
|
2767
3319
|
*/
|
|
2768
|
-
field(
|
|
3320
|
+
field(params: FieldCreationParams<T> | FieldCreationParams<Record<string, any>>): this;
|
|
2769
3321
|
/**
|
|
2770
3322
|
* Add a field with path segments
|
|
2771
|
-
* Usage: builder.fieldPath(
|
|
3323
|
+
* Usage: builder.fieldPath({ type: "input", name: path.join("."), label: "Full Name" })
|
|
2772
3324
|
*/
|
|
2773
|
-
fieldPath(
|
|
3325
|
+
fieldPath(params: FieldCreationParams<T>): this;
|
|
2774
3326
|
/**
|
|
2775
3327
|
* Add a field with template literal path
|
|
2776
3328
|
* Usage: builder.field`user.profile.name`("Full Name")
|
|
@@ -2792,11 +3344,16 @@ declare class NestedObjectBuilder<T extends FieldValues, TPath extends Path<T>>
|
|
|
2792
3344
|
/**
|
|
2793
3345
|
* Add a field to the current nested path
|
|
2794
3346
|
*/
|
|
2795
|
-
field
|
|
3347
|
+
field(params: FieldCreationParams<Record<string, any>>): NestedObjectBuilder<T, TPath>;
|
|
2796
3348
|
/**
|
|
2797
3349
|
* Nest deeper into the object
|
|
3350
|
+
*
|
|
3351
|
+
* @param subPath - A string representing a nested path under the current path.
|
|
3352
|
+
* The parameter accepts any string; TypeScript validates the constructed
|
|
3353
|
+
* path (basePath.subPath) in the return type.
|
|
3354
|
+
* @returns A builder for the nested path
|
|
2798
3355
|
*/
|
|
2799
|
-
nest<SubPath extends string>(subPath: SubPath): NestedObjectBuilder<T, TPath
|
|
3356
|
+
nest<SubPath extends string>(subPath: SubPath): NestedObjectBuilder<T, ConstructNestedPath<T, TPath, SubPath>>;
|
|
2800
3357
|
/**
|
|
2801
3358
|
* Return to the parent builder
|
|
2802
3359
|
*/
|
|
@@ -2812,20 +3369,25 @@ declare class SectionBuilder<T extends FieldValues, TPath extends Path<T>> {
|
|
|
2812
3369
|
/**
|
|
2813
3370
|
* Add a field to the current section
|
|
2814
3371
|
*/
|
|
2815
|
-
field
|
|
3372
|
+
field(params: FieldCreationParams<Record<string, any>>): SectionBuilder<T, TPath>;
|
|
2816
3373
|
/**
|
|
2817
3374
|
* Add multiple fields to the section
|
|
2818
3375
|
*/
|
|
2819
3376
|
fields(fieldDefinitions: {
|
|
2820
3377
|
name: string;
|
|
2821
3378
|
label: string;
|
|
2822
|
-
type?:
|
|
2823
|
-
props?:
|
|
3379
|
+
type?: FormFieldType;
|
|
3380
|
+
props?: Record<string, unknown>;
|
|
2824
3381
|
}[]): SectionBuilder<T, TPath>;
|
|
2825
3382
|
/**
|
|
2826
3383
|
* Nest deeper into the section
|
|
3384
|
+
*
|
|
3385
|
+
* @param subPath - A string representing a nested path under the current section path.
|
|
3386
|
+
* The parameter accepts any string; TypeScript validates the constructed
|
|
3387
|
+
* path (basePath.subPath) in the return type.
|
|
3388
|
+
* @returns A builder for the nested path
|
|
2827
3389
|
*/
|
|
2828
|
-
nest<SubPath extends string>(subPath: SubPath): NestedObjectBuilder<T, TPath
|
|
3390
|
+
nest<SubPath extends string = string>(subPath: SubPath): NestedObjectBuilder<T, ConstructNestedPath<T, TPath, string>>;
|
|
2829
3391
|
/**
|
|
2830
3392
|
* Return to the parent builder
|
|
2831
3393
|
*/
|
|
@@ -2841,7 +3403,9 @@ declare class FieldTemplateBuilder<T extends FieldValues> {
|
|
|
2841
3403
|
/**
|
|
2842
3404
|
* Complete the field definition
|
|
2843
3405
|
*/
|
|
2844
|
-
complete(
|
|
3406
|
+
complete(params: Omit<FieldCreationParams<Record<string, any>>, "name"> & {
|
|
3407
|
+
name?: string;
|
|
3408
|
+
}): NestedPathBuilder<T>;
|
|
2845
3409
|
}
|
|
2846
3410
|
/**
|
|
2847
3411
|
* Factory function for creating the nested path builder
|
|
@@ -2851,9 +3415,9 @@ declare function createNestedPathBuilder<T extends FieldValues>(): NestedPathBui
|
|
|
2851
3415
|
/**
|
|
2852
3416
|
* Options for the useDebouncedValidation hook.
|
|
2853
3417
|
*/
|
|
2854
|
-
interface UseDebouncedValidationOptions {
|
|
3418
|
+
interface UseDebouncedValidationOptions<T extends FieldValues = FieldValues> {
|
|
2855
3419
|
delay?: number;
|
|
2856
|
-
fields?:
|
|
3420
|
+
fields?: Path<T>[];
|
|
2857
3421
|
enabled?: boolean;
|
|
2858
3422
|
}
|
|
2859
3423
|
/**
|
|
@@ -2906,7 +3470,7 @@ interface UseDebouncedValidationOptions {
|
|
|
2906
3470
|
* @see {@link useDebouncedFieldValidation} for single field debouncing
|
|
2907
3471
|
* @category Hooks
|
|
2908
3472
|
*/
|
|
2909
|
-
declare function useDebouncedValidation<T extends
|
|
3473
|
+
declare function useDebouncedValidation<T extends FieldValues>(form: UseFormReturn<T>, options?: UseDebouncedValidationOptions<T>): {
|
|
2910
3474
|
debouncedTrigger: () => void;
|
|
2911
3475
|
isDebouncing: boolean;
|
|
2912
3476
|
};
|
|
@@ -2957,7 +3521,7 @@ declare function useDebouncedValidation<T extends Record<string, any>>(form: Use
|
|
|
2957
3521
|
* @see {@link useDebouncedValidation} for multiple fields
|
|
2958
3522
|
* @category Hooks
|
|
2959
3523
|
*/
|
|
2960
|
-
declare function useDebouncedFieldValidation<T extends
|
|
3524
|
+
declare function useDebouncedFieldValidation<T extends FieldValues>(form: UseFormReturn<T>, fieldName: Path<T>, options?: {
|
|
2961
3525
|
delay?: number;
|
|
2962
3526
|
enabled?: boolean;
|
|
2963
3527
|
}): {
|
|
@@ -2971,7 +3535,7 @@ declare function useDebouncedFieldValidation<T extends Record<string, any>>(form
|
|
|
2971
3535
|
* @template T - The form data type
|
|
2972
3536
|
*/
|
|
2973
3537
|
interface UseInferredFormOptions<T extends FieldValues> {
|
|
2974
|
-
defaultValues?:
|
|
3538
|
+
defaultValues?: DefaultValues<T>;
|
|
2975
3539
|
mode?: "onChange" | "onBlur" | "onSubmit" | "onTouched" | "all";
|
|
2976
3540
|
reValidateMode?: "onChange" | "onBlur" | "onSubmit";
|
|
2977
3541
|
shouldFocusError?: boolean;
|
|
@@ -3162,6 +3726,7 @@ interface FieldArrayFieldProps<TFieldValues extends FieldValues> {
|
|
|
3162
3726
|
* Allows users to add and remove multiple instances of a field group.
|
|
3163
3727
|
* Useful for forms with repeating data like addresses, items, or contacts.
|
|
3164
3728
|
* Automatically manages field array state and provides add/remove buttons.
|
|
3729
|
+
* Supports reordering, custom item rendering, default values, and conditional fields within items.
|
|
3165
3730
|
*
|
|
3166
3731
|
* @template TFieldValues - The form data type
|
|
3167
3732
|
*
|
|
@@ -3172,42 +3737,101 @@ interface FieldArrayFieldProps<TFieldValues extends FieldValues> {
|
|
|
3172
3737
|
* @returns {JSX.Element} The rendered field array with add/remove controls
|
|
3173
3738
|
*
|
|
3174
3739
|
* @example
|
|
3740
|
+
* Basic usage:
|
|
3175
3741
|
* ```tsx
|
|
3176
3742
|
* import { FieldArrayField, FormFieldHelpers } from "@rachelallyson/hero-hook-form";
|
|
3177
3743
|
*
|
|
3178
3744
|
* const fields = [
|
|
3179
3745
|
* FormFieldHelpers.input("name", "Name"),
|
|
3180
|
-
*
|
|
3181
|
-
*
|
|
3182
|
-
*
|
|
3183
|
-
*
|
|
3184
|
-
*
|
|
3185
|
-
*
|
|
3186
|
-
*
|
|
3187
|
-
*
|
|
3188
|
-
*
|
|
3189
|
-
*
|
|
3190
|
-
*
|
|
3191
|
-
*
|
|
3192
|
-
*
|
|
3193
|
-
*
|
|
3194
|
-
* }),
|
|
3746
|
+
* {
|
|
3747
|
+
* type: "fieldArray",
|
|
3748
|
+
* name: "addresses",
|
|
3749
|
+
* label: "Address",
|
|
3750
|
+
* fields: [
|
|
3751
|
+
* FormFieldHelpers.input("street", "Street Address"),
|
|
3752
|
+
* FormFieldHelpers.input("city", "City"),
|
|
3753
|
+
* FormFieldHelpers.input("zipCode", "ZIP Code"),
|
|
3754
|
+
* ],
|
|
3755
|
+
* min: 1,
|
|
3756
|
+
* max: 5,
|
|
3757
|
+
* addButtonText: "Add Address",
|
|
3758
|
+
* removeButtonText: "Remove Address",
|
|
3759
|
+
* },
|
|
3195
3760
|
* ];
|
|
3196
3761
|
* ```
|
|
3197
3762
|
*
|
|
3198
3763
|
* @example
|
|
3199
|
-
* With
|
|
3764
|
+
* With reordering:
|
|
3200
3765
|
* ```tsx
|
|
3201
|
-
*
|
|
3202
|
-
*
|
|
3203
|
-
*
|
|
3204
|
-
*
|
|
3205
|
-
*
|
|
3206
|
-
* }
|
|
3766
|
+
* {
|
|
3767
|
+
* type: "fieldArray",
|
|
3768
|
+
* name: "slots",
|
|
3769
|
+
* label: "Question Slots",
|
|
3770
|
+
* enableReordering: true,
|
|
3771
|
+
* reorderButtonText: { up: "↑", down: "↓" },
|
|
3772
|
+
* fields: [
|
|
3773
|
+
* FormFieldHelpers.select("slotType", "Slot Type", options),
|
|
3774
|
+
* ],
|
|
3775
|
+
* }
|
|
3776
|
+
* ```
|
|
3777
|
+
*
|
|
3778
|
+
* @example
|
|
3779
|
+
* With custom item rendering:
|
|
3780
|
+
* ```tsx
|
|
3781
|
+
* {
|
|
3782
|
+
* type: "fieldArray",
|
|
3783
|
+
* name: "items",
|
|
3784
|
+
* renderItem: ({ index, children, onMoveUp, onMoveDown, onRemove }) => (
|
|
3785
|
+
* <Card className="p-4">
|
|
3786
|
+
* <div className="flex justify-between">
|
|
3787
|
+
* <span>Item {index + 1}</span>
|
|
3788
|
+
* <Button onPress={onRemove}>Remove</Button>
|
|
3789
|
+
* </div>
|
|
3790
|
+
* {children}
|
|
3791
|
+
* </Card>
|
|
3792
|
+
* ),
|
|
3793
|
+
* fields: [...],
|
|
3794
|
+
* }
|
|
3795
|
+
* ```
|
|
3796
|
+
*
|
|
3797
|
+
* @example
|
|
3798
|
+
* With default item:
|
|
3799
|
+
* ```tsx
|
|
3800
|
+
* {
|
|
3801
|
+
* type: "fieldArray",
|
|
3802
|
+
* name: "slots",
|
|
3803
|
+
* defaultItem: () => ({
|
|
3804
|
+
* order: 0,
|
|
3805
|
+
* slotType: "STATIC",
|
|
3806
|
+
* staticQuestionId: "",
|
|
3807
|
+
* }),
|
|
3808
|
+
* fields: [...],
|
|
3809
|
+
* }
|
|
3810
|
+
* ```
|
|
3811
|
+
*
|
|
3812
|
+
* @example
|
|
3813
|
+
* With conditional fields within items:
|
|
3814
|
+
* ```tsx
|
|
3815
|
+
* {
|
|
3816
|
+
* type: "fieldArray",
|
|
3817
|
+
* name: "slots",
|
|
3818
|
+
* fields: [
|
|
3819
|
+
* FormFieldHelpers.select("slotType", "Slot Type", [
|
|
3820
|
+
* { label: "Static", value: "STATIC" },
|
|
3821
|
+
* { label: "Dynamic", value: "DYNAMIC" },
|
|
3822
|
+
* ]),
|
|
3823
|
+
* {
|
|
3824
|
+
* ...FormFieldHelpers.select("staticQuestionId", "Question", questions),
|
|
3825
|
+
* dependsOn: "slotType",
|
|
3826
|
+
* dependsOnValue: "STATIC",
|
|
3827
|
+
* },
|
|
3828
|
+
* ],
|
|
3829
|
+
* }
|
|
3207
3830
|
* ```
|
|
3208
3831
|
*
|
|
3209
3832
|
* @see {@link ConditionalField} for conditional single fields
|
|
3210
3833
|
* @see {@link DynamicSectionField} for conditional field groups
|
|
3834
|
+
* @see {@link createFieldArrayCustomConfig} for advanced custom rendering
|
|
3211
3835
|
* @category Fields
|
|
3212
3836
|
*/
|
|
3213
3837
|
declare function FieldArrayField<TFieldValues extends FieldValues>({ className, config, }: FieldArrayFieldProps<TFieldValues>): React$1.JSX.Element | null;
|
|
@@ -3323,7 +3947,7 @@ declare function throttle<T extends (...args: any[]) => any>(func: T, limit: num
|
|
|
3323
3947
|
/**
|
|
3324
3948
|
* Memoization helper for expensive computations
|
|
3325
3949
|
*/
|
|
3326
|
-
declare function useMemoizedCallback<T extends (...args:
|
|
3950
|
+
declare function useMemoizedCallback<T extends (...args: unknown[]) => unknown>(callback: T, deps: React.DependencyList): T;
|
|
3327
3951
|
/**
|
|
3328
3952
|
* Shallow comparison for React.memo
|
|
3329
3953
|
*/
|
|
@@ -3351,6 +3975,157 @@ declare function createOptimizedFieldHandler<T>(onChange: (value: T) => void, op
|
|
|
3351
3975
|
*/
|
|
3352
3976
|
declare function useMemoizedFieldProps<T extends Record<string, any>>(props: T, deps: React.DependencyList): T;
|
|
3353
3977
|
|
|
3978
|
+
/**
|
|
3979
|
+
* Options for syncing arrays
|
|
3980
|
+
*
|
|
3981
|
+
* @template TItem - The item type in the arrays
|
|
3982
|
+
*/
|
|
3983
|
+
interface ArraySyncOptions<TItem> {
|
|
3984
|
+
/** Existing items (from database/API) */
|
|
3985
|
+
existing: TItem[];
|
|
3986
|
+
/** Current items (from form) */
|
|
3987
|
+
current: TItem[];
|
|
3988
|
+
/** Function to extract ID from an item */
|
|
3989
|
+
getId: (item: TItem) => string | number | undefined;
|
|
3990
|
+
}
|
|
3991
|
+
/**
|
|
3992
|
+
* Result of array sync operation
|
|
3993
|
+
*
|
|
3994
|
+
* @template TItem - The item type in the arrays
|
|
3995
|
+
*/
|
|
3996
|
+
interface ArraySyncResult<TItem> {
|
|
3997
|
+
/** Items that should be deleted (exist in existing but not in current) */
|
|
3998
|
+
toDelete: TItem[];
|
|
3999
|
+
/** Items that should be updated (exist in both, may have changed) */
|
|
4000
|
+
toUpdate: {
|
|
4001
|
+
existing: TItem;
|
|
4002
|
+
current: TItem;
|
|
4003
|
+
}[];
|
|
4004
|
+
/** Items that should be created (exist in current but not in existing) */
|
|
4005
|
+
toCreate: TItem[];
|
|
4006
|
+
}
|
|
4007
|
+
/**
|
|
4008
|
+
* Sync arrays to determine what items to delete, update, and create.
|
|
4009
|
+
*
|
|
4010
|
+
* @description
|
|
4011
|
+
* Compares existing items (from database) with current items (from form)
|
|
4012
|
+
* to determine which items need to be deleted, updated, or created.
|
|
4013
|
+
* Useful for edit forms where you need to sync array changes.
|
|
4014
|
+
*
|
|
4015
|
+
* @template TItem - The item type in the arrays
|
|
4016
|
+
*
|
|
4017
|
+
* @param {ArraySyncOptions<TItem>} options - Sync options
|
|
4018
|
+
* @returns {ArraySyncResult<TItem>} Result with items to delete, update, and create
|
|
4019
|
+
*
|
|
4020
|
+
* @example
|
|
4021
|
+
* ```tsx
|
|
4022
|
+
* const { toDelete, toUpdate, toCreate } = syncArrays({
|
|
4023
|
+
* existing: slots,
|
|
4024
|
+
* current: data.slots,
|
|
4025
|
+
* getId: (slot) => slot.id,
|
|
4026
|
+
* });
|
|
4027
|
+
*
|
|
4028
|
+
* // Delete removed slots
|
|
4029
|
+
* await Promise.all(toDelete.map(slot => deleteSlot(slot.id)));
|
|
4030
|
+
*
|
|
4031
|
+
* // Update existing slots
|
|
4032
|
+
* await Promise.all(
|
|
4033
|
+
* toUpdate.map(({ existing, current }) =>
|
|
4034
|
+
* updateSlot(existing.id, current)
|
|
4035
|
+
* )
|
|
4036
|
+
* );
|
|
4037
|
+
*
|
|
4038
|
+
* // Create new slots
|
|
4039
|
+
* await Promise.all(toCreate.map(slot => createSlot(slot)));
|
|
4040
|
+
* ```
|
|
4041
|
+
*
|
|
4042
|
+
* @category Utilities
|
|
4043
|
+
*/
|
|
4044
|
+
declare function syncArrays<TItem>(options: ArraySyncOptions<TItem>): ArraySyncResult<TItem>;
|
|
4045
|
+
|
|
4046
|
+
/**
|
|
4047
|
+
* Options for creating a custom field array config
|
|
4048
|
+
*
|
|
4049
|
+
* @template TFieldValues - The form data type
|
|
4050
|
+
*/
|
|
4051
|
+
interface CreateFieldArrayCustomConfigOptions<TFieldValues extends FieldValues> {
|
|
4052
|
+
/** Field array name */
|
|
4053
|
+
name: ArrayPath<TFieldValues>;
|
|
4054
|
+
/** Optional label for the field array */
|
|
4055
|
+
label?: string;
|
|
4056
|
+
/** Render function for each array item */
|
|
4057
|
+
renderItem: (props: {
|
|
4058
|
+
index: number;
|
|
4059
|
+
field: FieldArrayWithId<TFieldValues, ArrayPath<TFieldValues>>;
|
|
4060
|
+
fields: FieldArrayWithId<TFieldValues, ArrayPath<TFieldValues>>[];
|
|
4061
|
+
form: UseFormReturn<TFieldValues>;
|
|
4062
|
+
control: Control<TFieldValues>;
|
|
4063
|
+
errors: FieldErrors<TFieldValues>;
|
|
4064
|
+
canMoveUp: boolean;
|
|
4065
|
+
canMoveDown: boolean;
|
|
4066
|
+
onMoveUp: () => void;
|
|
4067
|
+
onMoveDown: () => void;
|
|
4068
|
+
onRemove: () => void;
|
|
4069
|
+
}) => React$1.ReactNode;
|
|
4070
|
+
/** Optional render function for add button */
|
|
4071
|
+
renderAddButton?: (props: {
|
|
4072
|
+
onAdd: () => void;
|
|
4073
|
+
canAdd: boolean;
|
|
4074
|
+
}) => React$1.ReactNode;
|
|
4075
|
+
/** Function to create default item when adding new array item */
|
|
4076
|
+
defaultItem?: () => any;
|
|
4077
|
+
/** Minimum number of items */
|
|
4078
|
+
min?: number;
|
|
4079
|
+
/** Maximum number of items */
|
|
4080
|
+
max?: number;
|
|
4081
|
+
/** Enable reordering of array items */
|
|
4082
|
+
enableReordering?: boolean;
|
|
4083
|
+
/** Optional className */
|
|
4084
|
+
className?: string;
|
|
4085
|
+
}
|
|
4086
|
+
/**
|
|
4087
|
+
* Create a CustomFieldConfig for field arrays with full control over rendering.
|
|
4088
|
+
*
|
|
4089
|
+
* @description
|
|
4090
|
+
* This helper creates a CustomFieldConfig that uses useFieldArray internally,
|
|
4091
|
+
* giving you full control over the UI while still being integrated with the form.
|
|
4092
|
+
* Useful when you need custom layouts, reordering, or complex item rendering
|
|
4093
|
+
* that FieldArrayConfig doesn't support.
|
|
4094
|
+
*
|
|
4095
|
+
* @template TFieldValues - The form data type
|
|
4096
|
+
*
|
|
4097
|
+
* @param {CreateFieldArrayCustomConfigOptions<TFieldValues>} options - Configuration options
|
|
4098
|
+
* @returns {CustomFieldConfig<TFieldValues>} Custom field config for field arrays
|
|
4099
|
+
*
|
|
4100
|
+
* @example
|
|
4101
|
+
* ```tsx
|
|
4102
|
+
* const slotsConfig = createFieldArrayCustomConfig("slots", {
|
|
4103
|
+
* label: "Question Slots",
|
|
4104
|
+
* enableReordering: true,
|
|
4105
|
+
* renderItem: ({ index, field, form, control, onMoveUp, onMoveDown, onRemove }) => (
|
|
4106
|
+
* <div className="border rounded-lg p-4">
|
|
4107
|
+
* <div className="flex justify-between">
|
|
4108
|
+
* <span>Slot {index + 1}</span>
|
|
4109
|
+
* <div className="flex gap-2">
|
|
4110
|
+
* <Button onPress={onMoveUp}>↑</Button>
|
|
4111
|
+
* <Button onPress={onMoveDown}>↓</Button>
|
|
4112
|
+
* <Button onPress={onRemove}>Remove</Button>
|
|
4113
|
+
* </div>
|
|
4114
|
+
* </div>
|
|
4115
|
+
* <SelectField
|
|
4116
|
+
* name={`slots.${index}.slotType`}
|
|
4117
|
+
* control={control}
|
|
4118
|
+
* // ...
|
|
4119
|
+
* />
|
|
4120
|
+
* </div>
|
|
4121
|
+
* ),
|
|
4122
|
+
* });
|
|
4123
|
+
* ```
|
|
4124
|
+
*
|
|
4125
|
+
* @category Utilities
|
|
4126
|
+
*/
|
|
4127
|
+
declare function createFieldArrayCustomConfig<TFieldValues extends FieldValues>(options: CreateFieldArrayCustomConfigOptions<TFieldValues>): CustomFieldConfig<TFieldValues>;
|
|
4128
|
+
|
|
3354
4129
|
/**
|
|
3355
4130
|
* Common validation patterns for forms
|
|
3356
4131
|
*/
|
|
@@ -3434,4 +4209,4 @@ declare const validationUtils: {
|
|
|
3434
4209
|
}>;
|
|
3435
4210
|
};
|
|
3436
4211
|
|
|
3437
|
-
export { AdvancedFieldBuilder, AutocompleteField, type AutocompleteFieldProps, type AutocompleteOption, type BaseFormFieldConfig, BasicFormBuilder, type BooleanFieldConfig, type ButtonDefaults, type CheckboxDefaults, CheckboxField, type CheckboxFieldProps, type CommonFieldDefaults, CommonFields, ConditionalField, type ConditionalFieldConfig, type ConditionalFieldProps, type ConditionalValidation, ConfigurableForm, ContentField, type ContentFieldConfig, type CustomFieldConfig, DateField, type DateFieldConfig, type DateFieldProps, type DateInputDefaults, type DynamicSectionConfig, DynamicSectionField, type DynamicSectionFieldProps, type EnhancedFormState, FieldArrayBuilder, type FieldArrayConfig, FieldArrayField, type FieldArrayFieldProps, FieldArrayItemBuilder, type FieldBaseProps, type FieldGroup, FileField, type FileFieldConfig, type FileFieldProps, FontPickerField, type FontPickerFieldConfig, type FontPickerFieldProps, type FormConfig, FormField, type FormFieldConfig, FormFieldHelpers, type FormProps, FormProvider, FormStatus, type FormStatusProps, type FormStep, type FormSubmissionState, type FormTestUtils, FormToast, type FormToastProps, type FormValidationError, type HeroHookFormDefaultsConfig, HeroHookFormProvider, type HeroHookFormProviderProps, type InputDefaults, InputField, type InputFieldProps, type RadioFieldConfig, type RadioGroupDefaults, RadioGroupField, type RadioGroupFieldProps, type SelectDefaults, SelectField, type SelectFieldProps, ServerActionForm, type ServerFieldError, type ServerFormError, type SliderDefaults, SliderField, type SliderFieldConfig, type SliderFieldProps, type StringFieldConfig, SubmitButton, type SubmitButtonProps, type SwitchDefaults, SwitchField, type SwitchFieldProps, type TextareaDefaults, TextareaField, type TextareaFieldProps, TypeInferredBuilder, type UseDebouncedValidationOptions, type UseEnhancedFormStateOptions, type UseInferredFormOptions, type ValidationUtils, type WithControl, type WizardFormConfig, ZodForm, type ZodFormConfig, type ZodFormFieldConfig, applyServerErrors, asyncValidation, commonValidations, createAdvancedBuilder, createBasicFormBuilder, createDateSchema, createEmailSchema, createField, createFieldArrayBuilder, createFieldArrayItemBuilder, createFileSchema, createFormTestUtils, createFutureDateSchema, createMaxLengthSchema, createMinLengthSchema, createMockFormData, createMockFormErrors, createNestedPathBuilder, createNumberRangeSchema, createOptimizedFieldHandler, createPasswordSchema, createPastDateSchema, createPhoneSchema, createRequiredCheckboxSchema, createRequiredSchema, createTypeInferredBuilder, createUrlSchema, createZodFormConfig, crossFieldValidation, debounce, deepEqual, defineInferredForm, errorMessages, field, getFieldError, getFormErrors, hasFieldError, hasFormErrors, serverValidation, shallowEqual, simulateFieldInput, simulateFormSubmission, throttle, useDebouncedFieldValidation, useDebouncedValidation, useEnhancedFormState, useFormHelper, useHeroForm, useHeroHookFormDefaults, useInferredForm, useMemoizedCallback, useMemoizedFieldProps, usePerformanceMonitor, useTypeInferredForm, useZodForm, validationPatterns, validationUtils, waitForFormState };
|
|
4212
|
+
export { AdvancedFieldBuilder, type ArraySyncOptions, type ArraySyncResult, AutocompleteField, type AutocompleteFieldProps, type AutocompleteOption, type BaseFormFieldConfig, BasicFormBuilder, type BooleanFieldConfig, type ButtonDefaults, type CheckboxDefaults, CheckboxField, type CheckboxFieldProps, CheckboxGroupField, type CheckboxGroupFieldConfig, type CheckboxGroupFieldProps, type CommonFieldDefaults, CommonFields, ConditionalField, type ConditionalFieldConfig, type ConditionalFieldProps, type ConditionalValidation, ConfigurableForm, ContentField, type ContentFieldConfig, type CreateFieldArrayCustomConfigOptions, type CustomFieldConfig, DateField, type DateFieldConfig, type DateFieldProps, type DateInputDefaults, type DynamicSectionConfig, DynamicSectionField, type DynamicSectionFieldProps, type EnhancedFormState, FieldArrayBuilder, type FieldArrayConfig, FieldArrayField, type FieldArrayFieldProps, FieldArrayItemBuilder, type FieldBaseProps, type FieldCreationParams, type FieldGroup, FileField, type FileFieldConfig, type FileFieldProps, FontPickerField, type FontPickerFieldConfig, type FontPickerFieldProps, type FormConfig, FormField, type FormFieldConfig, FormFieldHelpers, type FormFieldType, type FormProps, FormProvider, FormStatus, type FormStatusProps, type FormStep, type FormSubmissionState, type FormTestUtils, FormToast, type FormToastProps, type FormValidationError, type HeroHookFormDefaultsConfig, HeroHookFormProvider, type HeroHookFormProviderProps, type InputDefaults, InputField, type InputFieldProps, type RadioFieldConfig, type RadioGroupDefaults, RadioGroupField, type RadioGroupFieldProps, type SelectDefaults, SelectField, type SelectFieldProps, ServerActionForm, type ServerFieldError, type ServerFormError, SimpleForm, type SimpleFormProps, type SliderDefaults, SliderField, type SliderFieldConfig, type SliderFieldProps, type StringArrayFieldConfig, type StringFieldConfig, SubmitButton, type SubmitButtonProps, type SwitchDefaults, SwitchField, type SwitchFieldProps, type TextareaDefaults, TextareaField, type TextareaFieldProps, TypeInferredBuilder, type UseDebouncedValidationOptions, type UseEnhancedFormStateOptions, type UseInferredFormOptions, type ValidationUtils, type WithControl, type WizardFormConfig, ZodForm, type ZodFormConfig, type ZodFormFieldConfig, applyServerErrors, asyncValidation, commonValidations, createAdvancedBuilder, createBasicFormBuilder, createDateSchema, createEmailSchema, createField, createFieldArrayBuilder, createFieldArrayCustomConfig, createFieldArrayItemBuilder, createFileSchema, createFormTestUtils, createFutureDateSchema, createMaxLengthSchema, createMinLengthSchema, createMockFormData, createMockFormErrors, createNestedPathBuilder, createNumberRangeSchema, createOptimizedFieldHandler, createPasswordSchema, createPastDateSchema, createPhoneSchema, createRequiredCheckboxSchema, createRequiredSchema, createTypeInferredBuilder, createUrlSchema, createZodFormConfig, crossFieldValidation, debounce, deepEqual, defineInferredForm, errorMessages, field, getFieldError, getFormErrors, hasFieldError, hasFormErrors, pathToString, serverValidation, shallowEqual, simulateFieldInput, simulateFormSubmission, syncArrays, throttle, useDebouncedFieldValidation, useDebouncedValidation, useEnhancedFormState, useFormHelper, useHeroForm, useHeroHookFormDefaults, useInferredForm, useMemoizedCallback, useMemoizedFieldProps, usePerformanceMonitor, useTypeInferredForm, useZodForm, validationPatterns, validationUtils, waitForFormState };
|