@rachelallyson/hero-hook-form 2.5.1 → 2.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.ts CHANGED
@@ -1,21 +1,21 @@
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, Control, UseFormReturn, FieldErrors, UseFormProps, SubmitHandler, UseFormSetError, DefaultValues, ArrayPath, 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';
11
11
  import { Checkbox } from '@heroui/checkbox';
12
+ import { DateInput } from '@heroui/date-input';
12
13
  import { Input, Textarea } from '@heroui/input';
13
14
  import { RadioGroup } from '@heroui/radio';
14
15
  import { Select } from '@heroui/select';
16
+ import { Slider } from '@heroui/slider';
15
17
  import { Switch } from '@heroui/switch';
16
18
  import { Button as Button$1 } from '@heroui/button';
17
- import { DateInput } from '@heroui/date-input';
18
- import { Slider } from '@heroui/slider';
19
19
 
20
20
  interface FieldBaseProps<TFieldValues extends FieldValues, TValue> {
21
21
  name: Path<TFieldValues>;
@@ -76,24 +76,29 @@ interface RadioFieldConfig<TFieldValues extends FieldValues> extends BaseFormFie
76
76
  interface SliderFieldConfig<TFieldValues extends FieldValues> extends BaseFormFieldConfig<TFieldValues> {
77
77
  type: "slider";
78
78
  defaultValue?: number;
79
- sliderProps?: Record<string, string | number | boolean>;
79
+ sliderProps?: Omit<ComponentProps<typeof Slider>, "value" | "onChange" | "label" | "isDisabled">;
80
80
  }
81
81
  interface DateFieldConfig<TFieldValues extends FieldValues> extends BaseFormFieldConfig<TFieldValues> {
82
82
  type: "date";
83
83
  defaultValue?: _internationalized_date.CalendarDate | null;
84
- dateProps?: Record<string, string | number | boolean>;
84
+ dateProps?: Omit<ComponentProps<typeof DateInput>, "value" | "onChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled">;
85
85
  }
86
86
  interface FileFieldConfig<TFieldValues extends FieldValues> extends BaseFormFieldConfig<TFieldValues> {
87
87
  type: "file";
88
88
  defaultValue?: FileList | null;
89
- fileProps?: Record<string, string | number | boolean>;
89
+ fileProps?: Omit<ComponentProps<typeof Input>, "value" | "onValueChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled" | "type">;
90
90
  multiple?: boolean;
91
91
  accept?: string;
92
92
  }
93
93
  interface FontPickerFieldConfig<TFieldValues extends FieldValues> extends BaseFormFieldConfig<TFieldValues> {
94
94
  type: "fontPicker";
95
95
  defaultValue?: string;
96
- fontPickerProps?: Record<string, string | number | boolean>;
96
+ fontPickerProps?: {
97
+ showFontPreview?: boolean;
98
+ loadAllVariants?: boolean;
99
+ onFontsLoaded?: (loaded: boolean) => void;
100
+ fontsLoadedTimeout?: number;
101
+ };
97
102
  }
98
103
  interface CustomFieldConfig<TFieldValues extends FieldValues> extends BaseFormFieldConfig<TFieldValues> {
99
104
  type: "custom";
@@ -110,13 +115,74 @@ interface ConditionalFieldConfig<TFieldValues extends FieldValues> extends BaseF
110
115
  condition: (formData: Partial<TFieldValues>) => boolean;
111
116
  field: ZodFormFieldConfig<TFieldValues>;
112
117
  }
118
+ /**
119
+ * Field array config for dynamic repeating field groups.
120
+ *
121
+ * @description
122
+ * Configuration for field arrays that support reordering, custom rendering,
123
+ * default values, and conditional fields within array items.
124
+ *
125
+ * @template TFieldValues - The form data type
126
+ */
113
127
  interface FieldArrayConfig<TFieldValues extends FieldValues> extends BaseFormFieldConfig<TFieldValues> {
114
128
  type: "fieldArray";
129
+ /** Field configurations for each array item */
115
130
  fields: ZodFormFieldConfig<TFieldValues>[];
131
+ /** Minimum number of items (default: 0) */
116
132
  min?: number;
133
+ /** Maximum number of items (default: 10) */
117
134
  max?: number;
135
+ /** Add button text (default: "Add Item") */
118
136
  addButtonText?: string;
137
+ /** Remove button text (default: "Remove") */
119
138
  removeButtonText?: string;
139
+ /** Enable reordering of array items with up/down buttons (default: false) */
140
+ enableReordering?: boolean;
141
+ /** Custom text for reorder buttons */
142
+ reorderButtonText?: {
143
+ /** Text for move up button (default: "↑") */
144
+ up?: string;
145
+ /** Text for move down button (default: "↓") */
146
+ down?: string;
147
+ };
148
+ /** Function to create default item when adding new array item */
149
+ defaultItem?: () => any;
150
+ /** Custom render function for array items */
151
+ renderItem?: (props: {
152
+ /** Item index (0-based) */
153
+ index: number;
154
+ /** Field array item with id */
155
+ field: {
156
+ id: string;
157
+ [key: string]: any;
158
+ };
159
+ /** All fields in the array */
160
+ fields: {
161
+ id: string;
162
+ [key: string]: any;
163
+ }[];
164
+ /** Rendered field elements */
165
+ children: React.ReactNode;
166
+ /** Remove this item */
167
+ onRemove: () => void;
168
+ /** Move item up */
169
+ onMoveUp: () => void;
170
+ /** Move item down */
171
+ onMoveDown: () => void;
172
+ /** Whether item can be removed */
173
+ canRemove: boolean;
174
+ /** Whether item can move up */
175
+ canMoveUp: boolean;
176
+ /** Whether item can move down */
177
+ canMoveDown: boolean;
178
+ }) => React.ReactNode;
179
+ /** Custom render function for add button */
180
+ renderAddButton?: (props: {
181
+ /** Add new item */
182
+ onAdd: () => void;
183
+ /** Whether new item can be added */
184
+ canAdd: boolean;
185
+ }) => React.ReactNode;
120
186
  }
121
187
  interface DynamicSectionConfig<TFieldValues extends FieldValues> extends BaseFormFieldConfig<TFieldValues> {
122
188
  type: "dynamicSection";
@@ -2027,6 +2093,83 @@ interface ZodFormProps<T extends FieldValues> {
2027
2093
  */
2028
2094
  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;
2029
2095
 
2096
+ /**
2097
+ * Props for the SimpleForm component.
2098
+ *
2099
+ * @template TFieldValues - The form data type
2100
+ */
2101
+ interface SimpleFormProps<TFieldValues extends FieldValues> {
2102
+ /** Zod schema for validation */
2103
+ schema: ZodSchema<TFieldValues>;
2104
+ /** Single field configuration */
2105
+ field: ZodFormFieldConfig<TFieldValues>;
2106
+ /** Submit handler */
2107
+ onSubmit: (data: TFieldValues) => Promise<void> | void;
2108
+ /** Optional custom submit button */
2109
+ submitButton?: React$1.ReactNode;
2110
+ /** Optional form title */
2111
+ title?: string;
2112
+ /** Optional form subtitle */
2113
+ subtitle?: string;
2114
+ /** Optional className */
2115
+ className?: string;
2116
+ /** Optional default values */
2117
+ defaultValues?: DefaultValues<TFieldValues>;
2118
+ /** Optional error callback */
2119
+ onError?: (error: FormValidationError) => void;
2120
+ /** Optional success callback */
2121
+ onSuccess?: (data: TFieldValues) => void;
2122
+ /** Hide default submit button (use custom submitButton instead) */
2123
+ hideSubmitButton?: boolean;
2124
+ }
2125
+ /**
2126
+ * Simple form component for single-field forms.
2127
+ *
2128
+ * @description
2129
+ * A simplified API for forms with a single field. Provides the same validation
2130
+ * and error handling as ZodForm but with a simpler configuration.
2131
+ * Useful for simple inputs like search bars, message inputs, or single-field forms.
2132
+ *
2133
+ * @template TFieldValues - The form data type
2134
+ *
2135
+ * @param {SimpleFormProps<TFieldValues>} props - Component props
2136
+ * @returns {JSX.Element} The rendered form
2137
+ *
2138
+ * @example
2139
+ * ```tsx
2140
+ * import { SimpleForm, FormFieldHelpers } from "@rachelallyson/hero-hook-form";
2141
+ * import { z } from "zod";
2142
+ *
2143
+ * const messageSchema = z.object({
2144
+ * message: z.string().min(1, "Message cannot be empty"),
2145
+ * });
2146
+ *
2147
+ * function MessageInput() {
2148
+ * return (
2149
+ * <SimpleForm
2150
+ * schema={messageSchema}
2151
+ * field={FormFieldHelpers.input("message", "", {
2152
+ * placeholder: "Add a note...",
2153
+ * endContent: (
2154
+ * <Button type="submit" isIconOnly>
2155
+ * <SendIcon />
2156
+ * </Button>
2157
+ * ),
2158
+ * })}
2159
+ * onSubmit={async (data) => {
2160
+ * await sendMessage(data.message);
2161
+ * }}
2162
+ * hideSubmitButton
2163
+ * />
2164
+ * );
2165
+ * }
2166
+ * ```
2167
+ *
2168
+ * @see {@link ZodForm} for multi-field forms
2169
+ * @category Components
2170
+ */
2171
+ declare function SimpleForm<TFieldValues extends FieldValues>({ className, defaultValues, field, hideSubmitButton, onError, onSubmit, onSuccess, schema, submitButton, subtitle, title, }: SimpleFormProps<TFieldValues>): React$1.JSX.Element;
2172
+
2030
2173
  /**
2031
2174
  * Hook for using Zod validation with React Hook Form
2032
2175
  */
@@ -2187,15 +2330,42 @@ declare function createBasicFormBuilder<T extends FieldValues>(): BasicFormBuild
2187
2330
  declare const FormFieldHelpers: {
2188
2331
  /**
2189
2332
  * Create an autocomplete field
2333
+ *
2334
+ * @example
2335
+ * ```tsx
2336
+ * // Simple autocomplete
2337
+ * FormFieldHelpers.autocomplete("country", "Country", options)
2338
+ *
2339
+ * // With placeholder
2340
+ * FormFieldHelpers.autocomplete("country", "Country", options, "Search countries")
2341
+ *
2342
+ * // With full customization
2343
+ * FormFieldHelpers.autocomplete("country", "Country", options, "Search countries", {
2344
+ * classNames: { base: "custom-autocomplete" },
2345
+ * allowsCustomValue: true
2346
+ * })
2347
+ * ```
2190
2348
  */
2191
2349
  autocomplete: <T extends FieldValues>(name: Path<T>, label: string, items: {
2192
2350
  label: string;
2193
2351
  value: string | number;
2194
- }[], placeholder?: string) => ZodFormFieldConfig<T>;
2352
+ }[], placeholder?: string, autocompleteProps?: Omit<React$1.ComponentProps<typeof Autocomplete>, "selectedKey" | "onSelectionChange" | "inputValue" | "onInputChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled" | "children" | "items">) => ZodFormFieldConfig<T>;
2195
2353
  /**
2196
2354
  * Create a checkbox field
2355
+ *
2356
+ * @example
2357
+ * ```tsx
2358
+ * // Simple checkbox
2359
+ * FormFieldHelpers.checkbox("newsletter", "Subscribe to newsletter")
2360
+ *
2361
+ * // With full customization
2362
+ * FormFieldHelpers.checkbox("newsletter", "Subscribe to newsletter", {
2363
+ * classNames: { base: "custom-checkbox" },
2364
+ * size: "lg"
2365
+ * })
2366
+ * ```
2197
2367
  */
2198
- checkbox: <T extends FieldValues>(name: Path<T>, label: string) => ZodFormFieldConfig<T>;
2368
+ checkbox: <T extends FieldValues>(name: Path<T>, label: string, checkboxProps?: Omit<React$1.ComponentProps<typeof Checkbox>, "isSelected" | "onValueChange" | "isInvalid" | "errorMessage" | "isDisabled">) => ZodFormFieldConfig<T>;
2199
2369
  /**
2200
2370
  * Create a conditional field that shows/hides based on form data
2201
2371
  *
@@ -2245,27 +2415,192 @@ declare const FormFieldHelpers: {
2245
2415
  }) => ZodFormFieldConfig<T>;
2246
2416
  /**
2247
2417
  * Create a date field
2418
+ *
2419
+ * @example
2420
+ * ```tsx
2421
+ * // Simple date field
2422
+ * FormFieldHelpers.date("birthDate", "Birth Date")
2423
+ *
2424
+ * // With full customization
2425
+ * FormFieldHelpers.date("birthDate", "Birth Date", {
2426
+ * label: "Select your birth date",
2427
+ * granularity: "day",
2428
+ * minValue: new CalendarDate(1900, 1, 1)
2429
+ * })
2430
+ * ```
2431
+ */
2432
+ date: <T extends FieldValues>(name: Path<T>, label: string, dateProps?: Omit<React$1.ComponentProps<typeof DateInput>, "value" | "onChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled">) => ZodFormFieldConfig<T>;
2433
+ /**
2434
+ * Create a file upload field
2435
+ *
2436
+ * @example
2437
+ * ```tsx
2438
+ * // Simple file field
2439
+ * FormFieldHelpers.file("avatar", "Profile Picture")
2440
+ *
2441
+ * // With accept and multiple
2442
+ * FormFieldHelpers.file("avatar", "Profile Picture", {
2443
+ * accept: "image/*",
2444
+ * multiple: true
2445
+ * })
2446
+ *
2447
+ * // With full customization
2448
+ * FormFieldHelpers.file("avatar", "Profile Picture", {
2449
+ * accept: "image/*",
2450
+ * multiple: false,
2451
+ * fileProps: { className: "custom-file-input" }
2452
+ * })
2453
+ * ```
2248
2454
  */
2249
- date: <T extends FieldValues>(name: Path<T>, label: string, dateProps?: Record<string, string | number | boolean>) => ZodFormFieldConfig<T>;
2455
+ file: <T extends FieldValues>(name: Path<T>, label: string, options?: {
2456
+ accept?: string;
2457
+ fileProps?: Omit<React$1.ComponentProps<typeof Input>, "value" | "onValueChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled" | "type">;
2458
+ multiple?: boolean;
2459
+ }) => ZodFormFieldConfig<T>;
2460
+ /**
2461
+ * Create a font picker field
2462
+ *
2463
+ * @example
2464
+ * ```tsx
2465
+ * // Simple font picker
2466
+ * FormFieldHelpers.fontPicker("font", "Choose Font")
2467
+ *
2468
+ * // With full customization
2469
+ * FormFieldHelpers.fontPicker("font", "Choose Font", {
2470
+ * showFontPreview: true,
2471
+ * loadAllVariants: false,
2472
+ * fontsLoadedTimeout: 5000
2473
+ * })
2474
+ * ```
2475
+ */
2476
+ fontPicker: <T extends FieldValues>(name: Path<T>, label: string, fontPickerProps?: {
2477
+ showFontPreview?: boolean;
2478
+ loadAllVariants?: boolean;
2479
+ onFontsLoaded?: (loaded: boolean) => void;
2480
+ fontsLoadedTimeout?: number;
2481
+ }) => ZodFormFieldConfig<T>;
2250
2482
  /**
2251
2483
  * Create an input field
2484
+ *
2485
+ * @example
2486
+ * ```tsx
2487
+ * // Simple input
2488
+ * FormFieldHelpers.input("name", "Name")
2489
+ *
2490
+ * // With type
2491
+ * FormFieldHelpers.input("email", "Email", "email")
2492
+ *
2493
+ * // With full customization
2494
+ * FormFieldHelpers.input("email", "Email", "email", {
2495
+ * placeholder: "Enter your email",
2496
+ * classNames: { input: "custom-input" },
2497
+ * startContent: <MailIcon />,
2498
+ * description: "We'll never share your email"
2499
+ * })
2500
+ * ```
2252
2501
  */
2253
- input: <T extends FieldValues>(name: Path<T>, label: string, type?: "text" | "email" | "tel" | "password") => ZodFormFieldConfig<T>;
2502
+ input: <T extends FieldValues>(name: Path<T>, label: string, type?: "text" | "email" | "tel" | "password", inputProps?: Omit<React$1.ComponentProps<typeof Input>, "value" | "onValueChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled">) => ZodFormFieldConfig<T>;
2503
+ /**
2504
+ * Create a radio group field
2505
+ *
2506
+ * @example
2507
+ * ```tsx
2508
+ * // Simple radio group
2509
+ * FormFieldHelpers.radio("gender", "Gender", [
2510
+ * { label: "Male", value: "male" },
2511
+ * { label: "Female", value: "female" }
2512
+ * ])
2513
+ *
2514
+ * // With full customization
2515
+ * FormFieldHelpers.radio("gender", "Gender", options, {
2516
+ * orientation: "horizontal",
2517
+ * classNames: { base: "custom-radio" }
2518
+ * })
2519
+ * ```
2520
+ */
2521
+ radio: <T extends FieldValues>(name: Path<T>, label: string, options: {
2522
+ label: string;
2523
+ value: string | number;
2524
+ }[], radioProps?: Omit<React$1.ComponentProps<typeof RadioGroup>, "value" | "onValueChange" | "label">) => ZodFormFieldConfig<T>;
2254
2525
  /**
2255
2526
  * Create a select field
2527
+ *
2528
+ * @example
2529
+ * ```tsx
2530
+ * // Simple select
2531
+ * FormFieldHelpers.select("country", "Country", options)
2532
+ *
2533
+ * // With full customization
2534
+ * FormFieldHelpers.select("country", "Country", options, {
2535
+ * placeholder: "Select a country",
2536
+ * classNames: { trigger: "custom-select" },
2537
+ * selectionMode: "multiple"
2538
+ * })
2539
+ * ```
2256
2540
  */
2257
2541
  select: <T extends FieldValues>(name: Path<T>, label: string, options: {
2258
2542
  label: string;
2259
2543
  value: string | number;
2260
- }[]) => ZodFormFieldConfig<T>;
2544
+ }[], selectProps?: Omit<React$1.ComponentProps<typeof Select>, "selectedKeys" | "onSelectionChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled">) => ZodFormFieldConfig<T>;
2545
+ /**
2546
+ * Create a slider field
2547
+ *
2548
+ * @example
2549
+ * ```tsx
2550
+ * // Simple slider
2551
+ * FormFieldHelpers.slider("rating", "Rating")
2552
+ *
2553
+ * // With full customization
2554
+ * FormFieldHelpers.slider("rating", "Rating", {
2555
+ * minValue: 1,
2556
+ * maxValue: 5,
2557
+ * step: 1,
2558
+ * showSteps: true,
2559
+ * classNames: { base: "custom-slider" }
2560
+ * })
2561
+ * ```
2562
+ */
2563
+ slider: <T extends FieldValues>(name: Path<T>, label: string, sliderProps?: Omit<React$1.ComponentProps<typeof Slider>, "value" | "onChange" | "label" | "isDisabled">) => ZodFormFieldConfig<T>;
2261
2564
  /**
2262
2565
  * Create a switch field
2566
+ *
2567
+ * @example
2568
+ * ```tsx
2569
+ * // Simple switch
2570
+ * FormFieldHelpers.switch("notifications", "Enable notifications")
2571
+ *
2572
+ * // With description
2573
+ * FormFieldHelpers.switch("notifications", "Enable notifications", "Receive email notifications")
2574
+ *
2575
+ * // With full customization
2576
+ * FormFieldHelpers.switch("notifications", "Enable notifications", "Receive email notifications", {
2577
+ * classNames: { base: "custom-switch" },
2578
+ * size: "lg",
2579
+ * color: "primary"
2580
+ * })
2581
+ * ```
2263
2582
  */
2264
- switch: <T extends FieldValues>(name: Path<T>, label: string, description?: string) => ZodFormFieldConfig<T>;
2583
+ switch: <T extends FieldValues>(name: Path<T>, label: string, description?: string, switchProps?: Omit<React$1.ComponentProps<typeof Switch>, "isSelected" | "onValueChange" | "isInvalid" | "errorMessage" | "isDisabled">) => ZodFormFieldConfig<T>;
2265
2584
  /**
2266
2585
  * Create a textarea field
2586
+ *
2587
+ * @example
2588
+ * ```tsx
2589
+ * // Simple textarea
2590
+ * FormFieldHelpers.textarea("message", "Message")
2591
+ *
2592
+ * // With placeholder
2593
+ * FormFieldHelpers.textarea("message", "Message", "Enter your message")
2594
+ *
2595
+ * // With full customization
2596
+ * FormFieldHelpers.textarea("message", "Message", "Enter your message", {
2597
+ * classNames: { input: "custom-textarea" },
2598
+ * minRows: 3,
2599
+ * maxRows: 10
2600
+ * })
2601
+ * ```
2267
2602
  */
2268
- textarea: <T extends FieldValues>(name: Path<T>, label: string, placeholder?: string) => ZodFormFieldConfig<T>;
2603
+ textarea: <T extends FieldValues>(name: Path<T>, label: string, placeholder?: string, textareaProps?: Omit<React$1.ComponentProps<typeof Textarea>, "value" | "onValueChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled">) => ZodFormFieldConfig<T>;
2269
2604
  };
2270
2605
  /**
2271
2606
  * Common field collections
@@ -2965,6 +3300,7 @@ interface FieldArrayFieldProps<TFieldValues extends FieldValues> {
2965
3300
  * Allows users to add and remove multiple instances of a field group.
2966
3301
  * Useful for forms with repeating data like addresses, items, or contacts.
2967
3302
  * Automatically manages field array state and provides add/remove buttons.
3303
+ * Supports reordering, custom item rendering, default values, and conditional fields within items.
2968
3304
  *
2969
3305
  * @template TFieldValues - The form data type
2970
3306
  *
@@ -2975,42 +3311,101 @@ interface FieldArrayFieldProps<TFieldValues extends FieldValues> {
2975
3311
  * @returns {JSX.Element} The rendered field array with add/remove controls
2976
3312
  *
2977
3313
  * @example
3314
+ * Basic usage:
2978
3315
  * ```tsx
2979
3316
  * import { FieldArrayField, FormFieldHelpers } from "@rachelallyson/hero-hook-form";
2980
3317
  *
2981
3318
  * const fields = [
2982
3319
  * FormFieldHelpers.input("name", "Name"),
2983
- * FieldArrayField({
2984
- * config: {
2985
- * name: "addresses",
2986
- * label: "Address",
2987
- * fields: [
2988
- * FormFieldHelpers.input("street", "Street Address"),
2989
- * FormFieldHelpers.input("city", "City"),
2990
- * FormFieldHelpers.input("zipCode", "ZIP Code"),
2991
- * ],
2992
- * min: 1,
2993
- * max: 5,
2994
- * addButtonText: "Add Address",
2995
- * removeButtonText: "Remove Address",
2996
- * },
2997
- * }),
3320
+ * {
3321
+ * type: "fieldArray",
3322
+ * name: "addresses",
3323
+ * label: "Address",
3324
+ * fields: [
3325
+ * FormFieldHelpers.input("street", "Street Address"),
3326
+ * FormFieldHelpers.input("city", "City"),
3327
+ * FormFieldHelpers.input("zipCode", "ZIP Code"),
3328
+ * ],
3329
+ * min: 1,
3330
+ * max: 5,
3331
+ * addButtonText: "Add Address",
3332
+ * removeButtonText: "Remove Address",
3333
+ * },
2998
3334
  * ];
2999
3335
  * ```
3000
3336
  *
3001
3337
  * @example
3002
- * With validation:
3338
+ * With reordering:
3003
3339
  * ```tsx
3004
- * const schema = z.object({
3005
- * addresses: z.array(z.object({
3006
- * street: z.string().min(1, "Street is required"),
3007
- * city: z.string().min(1, "City is required"),
3008
- * })).min(1, "At least one address is required"),
3009
- * });
3340
+ * {
3341
+ * type: "fieldArray",
3342
+ * name: "slots",
3343
+ * label: "Question Slots",
3344
+ * enableReordering: true,
3345
+ * reorderButtonText: { up: "↑", down: "↓" },
3346
+ * fields: [
3347
+ * FormFieldHelpers.select("slotType", "Slot Type", options),
3348
+ * ],
3349
+ * }
3350
+ * ```
3351
+ *
3352
+ * @example
3353
+ * With custom item rendering:
3354
+ * ```tsx
3355
+ * {
3356
+ * type: "fieldArray",
3357
+ * name: "items",
3358
+ * renderItem: ({ index, children, onMoveUp, onMoveDown, onRemove }) => (
3359
+ * <Card className="p-4">
3360
+ * <div className="flex justify-between">
3361
+ * <span>Item {index + 1}</span>
3362
+ * <Button onPress={onRemove}>Remove</Button>
3363
+ * </div>
3364
+ * {children}
3365
+ * </Card>
3366
+ * ),
3367
+ * fields: [...],
3368
+ * }
3369
+ * ```
3370
+ *
3371
+ * @example
3372
+ * With default item:
3373
+ * ```tsx
3374
+ * {
3375
+ * type: "fieldArray",
3376
+ * name: "slots",
3377
+ * defaultItem: () => ({
3378
+ * order: 0,
3379
+ * slotType: "STATIC",
3380
+ * staticQuestionId: "",
3381
+ * }),
3382
+ * fields: [...],
3383
+ * }
3384
+ * ```
3385
+ *
3386
+ * @example
3387
+ * With conditional fields within items:
3388
+ * ```tsx
3389
+ * {
3390
+ * type: "fieldArray",
3391
+ * name: "slots",
3392
+ * fields: [
3393
+ * FormFieldHelpers.select("slotType", "Slot Type", [
3394
+ * { label: "Static", value: "STATIC" },
3395
+ * { label: "Dynamic", value: "DYNAMIC" },
3396
+ * ]),
3397
+ * {
3398
+ * ...FormFieldHelpers.select("staticQuestionId", "Question", questions),
3399
+ * dependsOn: "slotType",
3400
+ * dependsOnValue: "STATIC",
3401
+ * },
3402
+ * ],
3403
+ * }
3010
3404
  * ```
3011
3405
  *
3012
3406
  * @see {@link ConditionalField} for conditional single fields
3013
3407
  * @see {@link DynamicSectionField} for conditional field groups
3408
+ * @see {@link createFieldArrayCustomConfig} for advanced custom rendering
3014
3409
  * @category Fields
3015
3410
  */
3016
3411
  declare function FieldArrayField<TFieldValues extends FieldValues>({ className, config, }: FieldArrayFieldProps<TFieldValues>): React$1.JSX.Element | null;
@@ -3154,6 +3549,157 @@ declare function createOptimizedFieldHandler<T>(onChange: (value: T) => void, op
3154
3549
  */
3155
3550
  declare function useMemoizedFieldProps<T extends Record<string, any>>(props: T, deps: React.DependencyList): T;
3156
3551
 
3552
+ /**
3553
+ * Options for syncing arrays
3554
+ *
3555
+ * @template TItem - The item type in the arrays
3556
+ */
3557
+ interface ArraySyncOptions<TItem> {
3558
+ /** Existing items (from database/API) */
3559
+ existing: TItem[];
3560
+ /** Current items (from form) */
3561
+ current: TItem[];
3562
+ /** Function to extract ID from an item */
3563
+ getId: (item: TItem) => string | number | undefined;
3564
+ }
3565
+ /**
3566
+ * Result of array sync operation
3567
+ *
3568
+ * @template TItem - The item type in the arrays
3569
+ */
3570
+ interface ArraySyncResult<TItem> {
3571
+ /** Items that should be deleted (exist in existing but not in current) */
3572
+ toDelete: TItem[];
3573
+ /** Items that should be updated (exist in both, may have changed) */
3574
+ toUpdate: {
3575
+ existing: TItem;
3576
+ current: TItem;
3577
+ }[];
3578
+ /** Items that should be created (exist in current but not in existing) */
3579
+ toCreate: TItem[];
3580
+ }
3581
+ /**
3582
+ * Sync arrays to determine what items to delete, update, and create.
3583
+ *
3584
+ * @description
3585
+ * Compares existing items (from database) with current items (from form)
3586
+ * to determine which items need to be deleted, updated, or created.
3587
+ * Useful for edit forms where you need to sync array changes.
3588
+ *
3589
+ * @template TItem - The item type in the arrays
3590
+ *
3591
+ * @param {ArraySyncOptions<TItem>} options - Sync options
3592
+ * @returns {ArraySyncResult<TItem>} Result with items to delete, update, and create
3593
+ *
3594
+ * @example
3595
+ * ```tsx
3596
+ * const { toDelete, toUpdate, toCreate } = syncArrays({
3597
+ * existing: slots,
3598
+ * current: data.slots,
3599
+ * getId: (slot) => slot.id,
3600
+ * });
3601
+ *
3602
+ * // Delete removed slots
3603
+ * await Promise.all(toDelete.map(slot => deleteSlot(slot.id)));
3604
+ *
3605
+ * // Update existing slots
3606
+ * await Promise.all(
3607
+ * toUpdate.map(({ existing, current }) =>
3608
+ * updateSlot(existing.id, current)
3609
+ * )
3610
+ * );
3611
+ *
3612
+ * // Create new slots
3613
+ * await Promise.all(toCreate.map(slot => createSlot(slot)));
3614
+ * ```
3615
+ *
3616
+ * @category Utilities
3617
+ */
3618
+ declare function syncArrays<TItem>(options: ArraySyncOptions<TItem>): ArraySyncResult<TItem>;
3619
+
3620
+ /**
3621
+ * Options for creating a custom field array config
3622
+ *
3623
+ * @template TFieldValues - The form data type
3624
+ */
3625
+ interface CreateFieldArrayCustomConfigOptions<TFieldValues extends FieldValues> {
3626
+ /** Field array name */
3627
+ name: ArrayPath<TFieldValues>;
3628
+ /** Optional label for the field array */
3629
+ label?: string;
3630
+ /** Render function for each array item */
3631
+ renderItem: (props: {
3632
+ index: number;
3633
+ field: FieldArrayWithId<TFieldValues, ArrayPath<TFieldValues>>;
3634
+ fields: FieldArrayWithId<TFieldValues, ArrayPath<TFieldValues>>[];
3635
+ form: UseFormReturn<TFieldValues>;
3636
+ control: Control<TFieldValues>;
3637
+ errors: FieldErrors<TFieldValues>;
3638
+ canMoveUp: boolean;
3639
+ canMoveDown: boolean;
3640
+ onMoveUp: () => void;
3641
+ onMoveDown: () => void;
3642
+ onRemove: () => void;
3643
+ }) => React$1.ReactNode;
3644
+ /** Optional render function for add button */
3645
+ renderAddButton?: (props: {
3646
+ onAdd: () => void;
3647
+ canAdd: boolean;
3648
+ }) => React$1.ReactNode;
3649
+ /** Function to create default item when adding new array item */
3650
+ defaultItem?: () => any;
3651
+ /** Minimum number of items */
3652
+ min?: number;
3653
+ /** Maximum number of items */
3654
+ max?: number;
3655
+ /** Enable reordering of array items */
3656
+ enableReordering?: boolean;
3657
+ /** Optional className */
3658
+ className?: string;
3659
+ }
3660
+ /**
3661
+ * Create a CustomFieldConfig for field arrays with full control over rendering.
3662
+ *
3663
+ * @description
3664
+ * This helper creates a CustomFieldConfig that uses useFieldArray internally,
3665
+ * giving you full control over the UI while still being integrated with the form.
3666
+ * Useful when you need custom layouts, reordering, or complex item rendering
3667
+ * that FieldArrayConfig doesn't support.
3668
+ *
3669
+ * @template TFieldValues - The form data type
3670
+ *
3671
+ * @param {CreateFieldArrayCustomConfigOptions<TFieldValues>} options - Configuration options
3672
+ * @returns {CustomFieldConfig<TFieldValues>} Custom field config for field arrays
3673
+ *
3674
+ * @example
3675
+ * ```tsx
3676
+ * const slotsConfig = createFieldArrayCustomConfig("slots", {
3677
+ * label: "Question Slots",
3678
+ * enableReordering: true,
3679
+ * renderItem: ({ index, field, form, control, onMoveUp, onMoveDown, onRemove }) => (
3680
+ * <div className="border rounded-lg p-4">
3681
+ * <div className="flex justify-between">
3682
+ * <span>Slot {index + 1}</span>
3683
+ * <div className="flex gap-2">
3684
+ * <Button onPress={onMoveUp}>↑</Button>
3685
+ * <Button onPress={onMoveDown}>↓</Button>
3686
+ * <Button onPress={onRemove}>Remove</Button>
3687
+ * </div>
3688
+ * </div>
3689
+ * <SelectField
3690
+ * name={`slots.${index}.slotType`}
3691
+ * control={control}
3692
+ * // ...
3693
+ * />
3694
+ * </div>
3695
+ * ),
3696
+ * });
3697
+ * ```
3698
+ *
3699
+ * @category Utilities
3700
+ */
3701
+ declare function createFieldArrayCustomConfig<TFieldValues extends FieldValues>(options: CreateFieldArrayCustomConfigOptions<TFieldValues>): CustomFieldConfig<TFieldValues>;
3702
+
3157
3703
  /**
3158
3704
  * Common validation patterns for forms
3159
3705
  */
@@ -3237,4 +3783,4 @@ declare const validationUtils: {
3237
3783
  }>;
3238
3784
  };
3239
3785
 
3240
- 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 };
3786
+ export { AdvancedFieldBuilder, type ArraySyncOptions, type ArraySyncResult, 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 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 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, SimpleForm, type SimpleFormProps, 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, 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, serverValidation, shallowEqual, simulateFieldInput, simulateFormSubmission, syncArrays, throttle, useDebouncedFieldValidation, useDebouncedValidation, useEnhancedFormState, useFormHelper, useHeroForm, useHeroHookFormDefaults, useInferredForm, useMemoizedCallback, useMemoizedFieldProps, usePerformanceMonitor, useTypeInferredForm, useZodForm, validationPatterns, validationUtils, waitForFormState };