@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.
@@ -1,3428 +0,0 @@
1
- import React$1, { ComponentProps } from 'react';
2
- import { Input, Textarea, Select, Autocomplete, Checkbox, Switch, RadioGroup, Slider, DateInput, Button } from '@heroui/react';
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';
5
- export { UseFormReturn, useFormContext } from 'react-hook-form';
6
- import * as zod from 'zod';
7
- import { z } from 'zod';
8
- import * as _internationalized_date from '@internationalized/date';
9
- import { CalendarDate } from '@internationalized/date';
10
-
11
- interface FieldBaseProps<TFieldValues extends FieldValues, TValue> {
12
- name: Path<TFieldValues>;
13
- label?: string;
14
- description?: string;
15
- className?: string;
16
- /** Additional validation rules */
17
- rules?: RegisterOptions<TFieldValues, Path<TFieldValues>>;
18
- /** Provide a default value when the form hasn't set one yet. */
19
- defaultValue?: TValue;
20
- /** Disable the input */
21
- isDisabled?: boolean;
22
- }
23
- interface WithControl<TFieldValues extends FieldValues> {
24
- control: Control<TFieldValues>;
25
- }
26
- interface BaseFormFieldConfig<TFieldValues extends FieldValues> {
27
- name: Path<TFieldValues>;
28
- label?: string;
29
- description?: string;
30
- className?: string;
31
- isDisabled?: boolean;
32
- rules?: RegisterOptions<TFieldValues, Path<TFieldValues>>;
33
- condition?: (values: Partial<TFieldValues>) => boolean;
34
- dependsOn?: Path<TFieldValues>;
35
- dependsOnValue?: unknown;
36
- group?: string;
37
- ariaLabel?: string;
38
- ariaDescribedBy?: string;
39
- }
40
- interface StringFieldConfig<TFieldValues extends FieldValues> extends BaseFormFieldConfig<TFieldValues> {
41
- type: "input" | "textarea" | "select" | "autocomplete";
42
- defaultValue?: string;
43
- inputProps?: Omit<ComponentProps<typeof Input>, "value" | "onValueChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled">;
44
- textareaProps?: Omit<ComponentProps<typeof Textarea>, "value" | "onValueChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled">;
45
- selectProps?: Omit<ComponentProps<typeof Select>, "selectedKeys" | "onSelectionChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled">;
46
- autocompleteProps?: Omit<ComponentProps<typeof Autocomplete>, "selectedKey" | "onSelectionChange" | "inputValue" | "onInputChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled" | "children" | "items">;
47
- options?: {
48
- label: string;
49
- value: string | number;
50
- }[];
51
- }
52
- interface BooleanFieldConfig<TFieldValues extends FieldValues> extends BaseFormFieldConfig<TFieldValues> {
53
- type: "checkbox" | "switch";
54
- defaultValue?: boolean;
55
- checkboxProps?: Omit<ComponentProps<typeof Checkbox>, "isSelected" | "onValueChange" | "isInvalid" | "errorMessage" | "isDisabled">;
56
- switchProps?: Omit<ComponentProps<typeof Switch>, "isSelected" | "onValueChange" | "isInvalid" | "errorMessage" | "isDisabled">;
57
- }
58
- interface RadioFieldConfig<TFieldValues extends FieldValues> extends BaseFormFieldConfig<TFieldValues> {
59
- type: "radio";
60
- defaultValue?: string;
61
- radioProps?: Omit<ComponentProps<typeof RadioGroup>, "value" | "onValueChange" | "label">;
62
- radioOptions?: {
63
- label: string;
64
- value: string | number;
65
- }[];
66
- }
67
- interface SliderFieldConfig<TFieldValues extends FieldValues> extends BaseFormFieldConfig<TFieldValues> {
68
- type: "slider";
69
- defaultValue?: number;
70
- sliderProps?: Omit<ComponentProps<typeof Slider>, "value" | "onChange" | "label" | "isDisabled">;
71
- }
72
- interface DateFieldConfig<TFieldValues extends FieldValues> extends BaseFormFieldConfig<TFieldValues> {
73
- type: "date";
74
- defaultValue?: _internationalized_date.CalendarDate | null;
75
- dateProps?: Omit<ComponentProps<typeof DateInput>, "value" | "onChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled">;
76
- }
77
- interface FileFieldConfig<TFieldValues extends FieldValues> extends BaseFormFieldConfig<TFieldValues> {
78
- type: "file";
79
- defaultValue?: FileList | null;
80
- fileProps?: Omit<ComponentProps<typeof Input>, "value" | "onValueChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled" | "type">;
81
- multiple?: boolean;
82
- accept?: string;
83
- }
84
- interface FontPickerFieldConfig<TFieldValues extends FieldValues> extends BaseFormFieldConfig<TFieldValues> {
85
- type: "fontPicker";
86
- defaultValue?: string;
87
- fontPickerProps?: {
88
- showFontPreview?: boolean;
89
- loadAllVariants?: boolean;
90
- onFontsLoaded?: (loaded: boolean) => void;
91
- fontsLoadedTimeout?: number;
92
- };
93
- }
94
- interface CustomFieldConfig<TFieldValues extends FieldValues> extends BaseFormFieldConfig<TFieldValues> {
95
- type: "custom";
96
- render: (field: {
97
- name: Path<TFieldValues>;
98
- control: Control<TFieldValues>;
99
- form: UseFormReturn<TFieldValues>;
100
- errors: FieldErrors<TFieldValues>;
101
- isSubmitting: boolean;
102
- }) => React.ReactNode;
103
- }
104
- interface ConditionalFieldConfig<TFieldValues extends FieldValues> extends BaseFormFieldConfig<TFieldValues> {
105
- type: "conditional";
106
- condition: (formData: Partial<TFieldValues>) => boolean;
107
- field: ZodFormFieldConfig<TFieldValues>;
108
- }
109
- interface FieldArrayConfig<TFieldValues extends FieldValues> extends BaseFormFieldConfig<TFieldValues> {
110
- type: "fieldArray";
111
- fields: ZodFormFieldConfig<TFieldValues>[];
112
- min?: number;
113
- max?: number;
114
- addButtonText?: string;
115
- removeButtonText?: string;
116
- }
117
- interface DynamicSectionConfig<TFieldValues extends FieldValues> extends BaseFormFieldConfig<TFieldValues> {
118
- type: "dynamicSection";
119
- title?: string;
120
- description?: string;
121
- condition: (formData: Partial<TFieldValues>) => boolean;
122
- fields: ZodFormFieldConfig<TFieldValues>[];
123
- }
124
- interface ContentFieldConfig<TFieldValues extends FieldValues = FieldValues> {
125
- type: "content";
126
- name?: string;
127
- title?: string;
128
- description?: string;
129
- render?: (field: {
130
- form: UseFormReturn<TFieldValues>;
131
- errors: FieldErrors<TFieldValues>;
132
- isSubmitting: boolean;
133
- }) => React.ReactNode;
134
- className?: string;
135
- }
136
- 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>;
137
- interface FormConfig<TFieldValues extends FieldValues> {
138
- fields: FormFieldConfig<TFieldValues>[];
139
- layout?: "vertical" | "horizontal" | "grid" | "custom";
140
- columns?: 1 | 2 | 3 | 4;
141
- spacing?: "sm" | "md" | "lg" | "xl";
142
- title?: string;
143
- subtitle?: string;
144
- showResetButton?: boolean;
145
- resetButtonText?: string;
146
- submitButtonText?: string;
147
- className?: string;
148
- defaultValues?: Partial<TFieldValues>;
149
- }
150
- 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>;
151
- interface ZodFormConfig<TFieldValues extends FieldValues> extends UseFormProps<TFieldValues> {
152
- schema: zod.ZodSchema<TFieldValues>;
153
- fields: ZodFormFieldConfig<TFieldValues>[];
154
- onError?: (errors: FieldErrors<TFieldValues>) => void;
155
- errorDisplay?: "inline" | "toast" | "modal" | "none";
156
- }
157
- interface FormValidationError {
158
- message: string;
159
- field?: string;
160
- }
161
- interface FormSubmissionState {
162
- isSubmitting: boolean;
163
- isSubmitted: boolean;
164
- isSuccess: boolean;
165
- error?: string;
166
- }
167
- interface FormStep<TFieldValues extends FieldValues> {
168
- id: string;
169
- title: string;
170
- description?: string;
171
- fields: FormFieldConfig<TFieldValues>[];
172
- validation?: (values: Partial<TFieldValues>) => boolean;
173
- }
174
- interface WizardFormConfig<TFieldValues extends FieldValues> {
175
- steps: FormStep<TFieldValues>[];
176
- allowStepNavigation?: boolean;
177
- showStepProgress?: boolean;
178
- }
179
- interface ConditionalValidation<TFieldValues extends FieldValues> {
180
- when: Path<TFieldValues>;
181
- is: string | number | boolean | null | undefined;
182
- then: RegisterOptions<TFieldValues, Path<TFieldValues>>;
183
- otherwise?: RegisterOptions<TFieldValues, Path<TFieldValues>>;
184
- }
185
- interface FieldGroup<TFieldValues extends FieldValues> {
186
- id: string;
187
- title?: string;
188
- description?: string;
189
- collapsible?: boolean;
190
- defaultCollapsed?: boolean;
191
- fields: FormFieldConfig<TFieldValues>[];
192
- }
193
- interface ValidationUtils {
194
- createMinLengthSchema: (min: number, fieldName: string) => zod.ZodString;
195
- createMaxLengthSchema: (max: number, fieldName: string) => zod.ZodString;
196
- createEmailSchema: () => zod.ZodString;
197
- createRequiredSchema: (fieldName: string) => zod.ZodString;
198
- createUrlSchema: () => zod.ZodString;
199
- createPhoneSchema: () => zod.ZodString;
200
- }
201
- interface FormTestUtils<TFieldValues extends FieldValues> {
202
- getField: (name: Path<TFieldValues>) => {
203
- value: unknown;
204
- error: unknown;
205
- isDirty: boolean;
206
- isTouched: boolean;
207
- };
208
- submitForm: () => Promise<void>;
209
- resetForm: () => void;
210
- getFormState: () => {
211
- values: TFieldValues;
212
- errors: FieldErrors<TFieldValues>;
213
- isSubmitting: boolean;
214
- isSubmitted: boolean;
215
- isSuccess: boolean;
216
- };
217
- setFieldValue: (name: Path<TFieldValues>, value: unknown) => void;
218
- triggerValidation: (name?: Path<TFieldValues>) => Promise<boolean>;
219
- }
220
-
221
- /**
222
- * Props for the Form component.
223
- *
224
- * @template T - The form data type
225
- */
226
- interface FormProps$1<T extends FieldValues> {
227
- className?: string;
228
- columns?: 1 | 2 | 3;
229
- fields: FormFieldConfig<T>[];
230
- layout?: "vertical" | "horizontal" | "grid";
231
- onError?: (error: FormValidationError) => void;
232
- onSubmit: SubmitHandler<T>;
233
- onSuccess?: (data: T) => void;
234
- resetButtonText?: string;
235
- showResetButton?: boolean;
236
- spacing?: "2" | "4" | "6" | "8" | "lg";
237
- submitButtonProps?: Partial<React$1.ComponentProps<typeof Button>>;
238
- submitButtonText?: string;
239
- subtitle?: string;
240
- title?: string;
241
- defaultValues?: Partial<T>;
242
- }
243
- /**
244
- * Base form component for building forms without Zod validation.
245
- *
246
- * @description
247
- * This component provides a flexible form solution using React Hook Form
248
- * without requiring Zod schemas. It's useful when you need more control over
249
- * validation or want to use React Hook Form's built-in validation rules.
250
- *
251
- * @template T - The form data type
252
- *
253
- * @param {FormProps<T>} props - Component props
254
- * @param {FormFieldConfig<T>[]} props.fields - Array of field configurations
255
- * @param {SubmitHandler<T>} props.onSubmit - Submit handler function
256
- * @param {Partial<T>} [props.defaultValues] - Default form values
257
- * @param {string} [props.title] - Optional form title
258
- * @param {string} [props.subtitle] - Optional form subtitle
259
- * @param {"vertical"|"horizontal"|"grid"} [props.layout="vertical"] - Form layout
260
- * @param {1|2|3} [props.columns=1] - Number of columns for grid layout
261
- * @param {"2"|"4"|"6"|"8"|"lg"} [props.spacing="4"] - Spacing between fields
262
- * @param {string} [props.submitButtonText="Submit"] - Submit button text
263
- * @param {boolean} [props.showResetButton=false] - Whether to show reset button
264
- * @param {(error: FormValidationError) => void} [props.onError] - Error callback
265
- * @param {(data: T) => void} [props.onSuccess] - Success callback
266
- *
267
- * @returns {JSX.Element} The rendered form component
268
- *
269
- * @example
270
- * ```tsx
271
- * import { ConfigurableForm, FormFieldHelpers } from "@rachelallyson/hero-hook-form";
272
- *
273
- * function MyForm() {
274
- * return (
275
- * <ConfigurableForm
276
- * fields={[
277
- * FormFieldHelpers.input("name", "Name"),
278
- * FormFieldHelpers.input("email", "Email", "email"),
279
- * ]}
280
- * defaultValues={{ name: "", email: "" }}
281
- * onSubmit={async (data) => {
282
- * console.log("Submitted:", data);
283
- * }}
284
- * title="Contact Form"
285
- * />
286
- * );
287
- * }
288
- * ```
289
- *
290
- * @see {@link ZodForm} for Zod-integrated form with automatic validation
291
- * @see {@link FormFieldHelpers} for field creation helpers
292
- * @category Components
293
- */
294
- 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;
295
-
296
- interface FormFieldProps<TFieldValues extends FieldValues> {
297
- config: FormFieldConfig<TFieldValues>;
298
- form: UseFormReturn<TFieldValues>;
299
- submissionState: FormSubmissionState;
300
- }
301
- declare const FormField: <TFieldValues extends FieldValues>(props: FormFieldProps<TFieldValues>) => React$1.JSX.Element;
302
-
303
- type ServerAction<TState = unknown, TFormData = FormData> = (state: TState | undefined, formData: TFormData) => Promise<TState>;
304
- interface ActionState {
305
- errors?: Record<string, string[]>;
306
- message?: string;
307
- success?: boolean;
308
- }
309
- interface ServerActionFormProps<T extends FieldValues> {
310
- /** Server Action function (Next.js pattern) */
311
- action: ServerAction<ActionState, FormData>;
312
- /** Optional: Zod schema for client-side validation before submission */
313
- clientValidationSchema?: z.ZodSchema<T>;
314
- className?: string;
315
- columns?: 1 | 2 | 3;
316
- /** Default values for form fields */
317
- defaultValues?: Partial<T>;
318
- fields: FormFieldConfig<T>[];
319
- /** Initial state for useActionState */
320
- initialState?: ActionState;
321
- layout?: "vertical" | "horizontal" | "grid";
322
- /** Callback when form submission encounters an error */
323
- onError?: (error: {
324
- errors?: Record<string, string[]>;
325
- message?: string;
326
- }) => void;
327
- /** Callback when form submission succeeds */
328
- onSuccess?: (data: FormData) => void;
329
- resetButtonText?: string;
330
- showResetButton?: boolean;
331
- spacing?: "2" | "4" | "6" | "8" | "lg";
332
- submitButtonProps?: Partial<React$1.ComponentProps<typeof Button>>;
333
- submitButtonText?: string;
334
- subtitle?: string;
335
- title?: string;
336
- }
337
- /**
338
- * ServerActionForm - A form component compatible with Next.js Server Actions.
339
- *
340
- * @description
341
- * This component works with Next.js authentication patterns by using native
342
- * HTML form submission with Server Actions, while still providing the
343
- * beautiful HeroUI field components. It uses React's useActionState hook
344
- * to manage form state and handle server responses.
345
- *
346
- * **Validation Options:**
347
- * - **Server-side only (default)**: Form submits directly to Server Action
348
- * - **Client + Server (optional)**: Pass `clientValidationSchema` for client-side
349
- * validation before submission. Server Action still validates (defense in depth).
350
- *
351
- * **Important Notes:**
352
- * - If your Server Action calls `redirect()`, success messages won't display
353
- * (the page navigates away). Use URL params or cookies for success messages
354
- * when redirecting.
355
- * - Server Actions receive FormData, not JSON, so field values are strings
356
- *
357
- * @template T - The form data type
358
- *
359
- * @param {ServerActionFormProps<T>} props - Component props
360
- * @param {ServerAction<ActionState, FormData>} props.action - Next.js Server Action function
361
- * @param {FormFieldConfig<T>[]} props.fields - Array of field configurations
362
- * @param {z.ZodSchema<T>} [props.clientValidationSchema] - Optional Zod schema for client-side validation
363
- * @param {Partial<T>} [props.defaultValues] - Default form values
364
- * @param {ActionState} [props.initialState] - Initial state for useActionState
365
- * @param {string} [props.title] - Optional form title
366
- * @param {string} [props.subtitle] - Optional form subtitle
367
- * @param {"vertical"|"horizontal"|"grid"} [props.layout="vertical"] - Form layout style
368
- * @param {1|2|3} [props.columns=1] - Number of columns for grid layout
369
- * @param {"2"|"4"|"6"|"8"|"lg"} [props.spacing="4"] - Spacing between form fields
370
- * @param {string} [props.submitButtonText="Submit"] - Text for the submit button
371
- * @param {boolean} [props.showResetButton=false] - Whether to show a reset button
372
- * @param {(error: {...}) => void} [props.onError] - Error callback
373
- * @param {(data: FormData) => void} [props.onSuccess] - Success callback
374
- *
375
- * @returns {JSX.Element} The rendered form component
376
- *
377
- * @example
378
- * Server-side only validation:
379
- * ```tsx
380
- * import { ServerActionForm, FormFieldHelpers } from "@rachelallyson/hero-hook-form";
381
- * import { signup } from "@/app/actions/auth";
382
- *
383
- * <ServerActionForm
384
- * action={signup}
385
- * fields={[
386
- * FormFieldHelpers.input("name", "Name"),
387
- * FormFieldHelpers.input("email", "Email", "email"),
388
- * FormFieldHelpers.input("password", "Password", "password"),
389
- * ]}
390
- * />
391
- * ```
392
- *
393
- * @example
394
- * Client + Server validation:
395
- * ```tsx
396
- * import { ServerActionForm, FormFieldHelpers } from "@rachelallyson/hero-hook-form";
397
- * import { signup } from "@/app/actions/auth";
398
- * import { z } from "zod";
399
- *
400
- * const signupSchema = z.object({
401
- * name: z.string().min(2),
402
- * email: z.string().email(),
403
- * password: z.string().min(8),
404
- * });
405
- *
406
- * <ServerActionForm
407
- * action={signup}
408
- * clientValidationSchema={signupSchema}
409
- * fields={[
410
- * FormFieldHelpers.input("name", "Name"),
411
- * FormFieldHelpers.input("email", "Email", "email"),
412
- * FormFieldHelpers.input("password", "Password", "password"),
413
- * ]}
414
- * onError={(error) => {
415
- * console.error("Form errors:", error.errors);
416
- * }}
417
- * onSuccess={(data) => {
418
- * console.log("Form submitted:", data);
419
- * }}
420
- * />
421
- * ```
422
- *
423
- * @see {@link ZodForm} for client-side only forms with Zod validation
424
- * @see {@link ConfigurableForm} for forms without Server Actions
425
- * @category Components
426
- */
427
- 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;
428
-
429
- /**
430
- * Configuration for an autocomplete option.
431
- *
432
- * @template TValue - The value type for the option
433
- */
434
- interface AutocompleteOption<TValue extends string | number> {
435
- /** Display label for the option */
436
- label: string;
437
- /** Value of the option */
438
- value: TValue;
439
- /** Optional description text */
440
- description?: string;
441
- /** Whether the option is disabled */
442
- disabled?: boolean;
443
- }
444
- /**
445
- * Props for the AutocompleteField component.
446
- *
447
- * @template TFieldValues - The form data type
448
- * @template TValue - The value type for the autocomplete field (string or number)
449
- *
450
- * @example
451
- * ```tsx
452
- * import { AutocompleteField } from "@rachelallyson/hero-hook-form";
453
- * import { useForm } from "react-hook-form";
454
- *
455
- * const form = useForm({
456
- * defaultValues: { country: "" },
457
- * });
458
- *
459
- * const options = [
460
- * { label: "United States", value: "us" },
461
- * { label: "Canada", value: "ca" },
462
- * { label: "Mexico", value: "mx" },
463
- * ];
464
- *
465
- * <AutocompleteField
466
- * control={form.control}
467
- * name="country"
468
- * label="Country"
469
- * items={options}
470
- * placeholder="Search for a country"
471
- * />
472
- * ```
473
- */
474
- type AutocompleteFieldProps<TFieldValues extends FieldValues, TValue extends string | number = string> = FieldBaseProps<TFieldValues, TValue> & WithControl<TFieldValues> & {
475
- /** Array of autocomplete options (for static lists) */
476
- items?: readonly AutocompleteOption<TValue>[];
477
- /** Placeholder text when no option is selected */
478
- placeholder?: string;
479
- /** Additional props to pass to the underlying Autocomplete component */
480
- autocompleteProps?: Omit<React$1.ComponentProps<typeof Autocomplete>, "selectedKey" | "onSelectionChange" | "inputValue" | "onInputChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled" | "children" | "items" | "defaultItems">;
481
- /** Custom render function for items (for async loading) */
482
- children?: (item: AutocompleteOption<TValue>) => React$1.JSX.Element;
483
- };
484
- /**
485
- * An autocomplete field component that integrates React Hook Form with HeroUI Autocomplete.
486
- *
487
- * This component provides a type-safe autocomplete field with validation support,
488
- * error handling, and accessibility features. It supports both static option lists
489
- * and async loading via the items prop or children render function.
490
- *
491
- * @template TFieldValues - The form data type
492
- * @template TValue - The value type for the autocomplete field (string or number)
493
- *
494
- * @param props - The autocomplete field props
495
- * @returns The rendered autocomplete field component
496
- *
497
- * @example
498
- * ```tsx
499
- * import { ZodForm, FormFieldHelpers } from "@rachelallyson/hero-hook-form";
500
- * import { z } from "zod";
501
- *
502
- * const schema = z.object({
503
- * country: z.string().min(1, "Please select a country"),
504
- * });
505
- *
506
- * const options = [
507
- * { label: "United States", value: "us" },
508
- * { label: "Canada", value: "ca" },
509
- * ];
510
- *
511
- * function MyForm() {
512
- * return (
513
- * <ZodForm
514
- * config={{
515
- * schema,
516
- * fields: [
517
- * FormFieldHelpers.autocomplete("country", "Country", options, "Search for a country"),
518
- * ],
519
- * }}
520
- * onSubmit={(data) => console.log(data)}
521
- * />
522
- * );
523
- * }
524
- * ```
525
- *
526
- * @example
527
- * ```tsx
528
- * // With async loading
529
- * <AutocompleteField
530
- * control={form.control}
531
- * name="country"
532
- * label="Country"
533
- * placeholder="Search for a country"
534
- * autocompleteProps={{
535
- * allowsCustomValue: true,
536
- * onInputChange={(value) => {
537
- * // Load options asynchronously based on input
538
- * loadOptions(value);
539
- * }},
540
- * }}
541
- * >
542
- * {(item) => (
543
- * <AutocompleteItem key={item.value}>{item.label}</AutocompleteItem>
544
- * )}
545
- * </AutocompleteField>
546
- * ```
547
- */
548
- declare function AutocompleteField<TFieldValues extends FieldValues, TValue extends string | number = string>(props: AutocompleteFieldProps<TFieldValues, TValue>): React$1.JSX.Element;
549
-
550
- /**
551
- * Props for the CheckboxField component.
552
- *
553
- * @template TFieldValues - The form data type
554
- *
555
- * @example
556
- * ```tsx
557
- * import { CheckboxField } from "@rachelallyson/hero-hook-form";
558
- * import { useForm } from "react-hook-form";
559
- *
560
- * const form = useForm({
561
- * defaultValues: { newsletter: false },
562
- * });
563
- *
564
- * <CheckboxField
565
- * control={form.control}
566
- * name="newsletter"
567
- * label="Subscribe to newsletter"
568
- * description="Receive weekly updates"
569
- * />
570
- * ```
571
- */
572
- type CheckboxFieldProps<TFieldValues extends FieldValues> = FieldBaseProps<TFieldValues, boolean> & WithControl<TFieldValues> & {
573
- /** Additional props to pass to the underlying Checkbox component */
574
- checkboxProps?: Omit<React$1.ComponentProps<typeof Checkbox>, "isSelected" | "onValueChange" | "isInvalid" | "errorMessage" | "isDisabled">;
575
- };
576
- /**
577
- * A checkbox field component that integrates React Hook Form with HeroUI Checkbox.
578
- *
579
- * This component provides a type-safe checkbox field with validation support,
580
- * error handling, and accessibility features. The field value is a boolean.
581
- *
582
- * @template TFieldValues - The form data type
583
- *
584
- * @param props - The checkbox field props
585
- * @returns The rendered checkbox field component
586
- *
587
- * @example
588
- * ```tsx
589
- * import { ZodForm, FormFieldHelpers } from "@rachelallyson/hero-hook-form";
590
- * import { z } from "zod";
591
- *
592
- * const schema = z.object({
593
- * terms: z.boolean().refine((val) => val === true, {
594
- * message: "You must accept the terms",
595
- * }),
596
- * newsletter: z.boolean().optional(),
597
- * });
598
- *
599
- * function MyForm() {
600
- * return (
601
- * <ZodForm
602
- * config={{
603
- * schema,
604
- * fields: [
605
- * FormFieldHelpers.checkbox("terms", "I accept the terms and conditions"),
606
- * FormFieldHelpers.checkbox("newsletter", "Subscribe to newsletter"),
607
- * ],
608
- * }}
609
- * onSubmit={(data) => console.log(data)}
610
- * />
611
- * );
612
- * }
613
- * ```
614
- *
615
- * @example
616
- * ```tsx
617
- * // With custom styling
618
- * <CheckboxField
619
- * control={form.control}
620
- * name="newsletter"
621
- * label="Subscribe"
622
- * checkboxProps={{
623
- * color: "primary",
624
- * size: "lg",
625
- * }}
626
- * />
627
- * ```
628
- */
629
- declare function CheckboxField<TFieldValues extends FieldValues>(props: CheckboxFieldProps<TFieldValues>): React$1.JSX.Element;
630
-
631
- /**
632
- * Props for the DateField component.
633
- *
634
- * @template TFieldValues - The form data type
635
- *
636
- * @example
637
- * ```tsx
638
- * import { DateField } from "@rachelallyson/hero-hook-form";
639
- * import { useForm } from "react-hook-form";
640
- * import { CalendarDate } from "@internationalized/date";
641
- *
642
- * const form = useForm({
643
- * defaultValues: { birthDate: null as CalendarDate | null },
644
- * });
645
- *
646
- * <DateField
647
- * control={form.control}
648
- * name="birthDate"
649
- * label="Birth Date"
650
- * description="Select your date of birth"
651
- * />
652
- * ```
653
- */
654
- type DateFieldProps<TFieldValues extends FieldValues> = FieldBaseProps<TFieldValues, CalendarDate | null> & WithControl<TFieldValues> & {
655
- /** Additional props to pass to the underlying DateInput component */
656
- dateProps?: Omit<React$1.ComponentProps<typeof DateInput>, "value" | "onChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled">;
657
- /** Transform function to modify the date value before it's set */
658
- transform?: (value: CalendarDate | null) => CalendarDate | null;
659
- };
660
- /**
661
- * A date input field component that integrates React Hook Form with HeroUI DateInput.
662
- *
663
- * This component provides a type-safe date field with validation support,
664
- * error handling, and accessibility features. Uses `@internationalized/date`
665
- * for date handling.
666
- *
667
- * @template TFieldValues - The form data type
668
- *
669
- * @param props - The date field props
670
- * @returns The rendered date field component
671
- *
672
- * @example
673
- * ```tsx
674
- * import { ZodForm, FormFieldHelpers } from "@rachelallyson/hero-hook-form";
675
- * import { z } from "zod";
676
- * import { CalendarDate } from "@internationalized/date";
677
- *
678
- * const schema = z.object({
679
- * birthDate: z.instanceof(CalendarDate).nullable(),
680
- * eventDate: z.instanceof(CalendarDate),
681
- * });
682
- *
683
- * function MyForm() {
684
- * return (
685
- * <ZodForm
686
- * config={{
687
- * schema,
688
- * fields: [
689
- * FormFieldHelpers.date("birthDate", "Birth Date"),
690
- * FormFieldHelpers.date("eventDate", "Event Date"),
691
- * ],
692
- * }}
693
- * onSubmit={(data) => console.log(data)}
694
- * />
695
- * );
696
- * }
697
- * ```
698
- *
699
- * @example
700
- * ```tsx
701
- * // With custom date format and min/max dates
702
- * <DateField
703
- * control={form.control}
704
- * name="eventDate"
705
- * label="Event Date"
706
- * dateProps={{
707
- * minValue: new CalendarDate(2024, 1, 1),
708
- * maxValue: new CalendarDate(2024, 12, 31),
709
- * }}
710
- * />
711
- * ```
712
- */
713
- declare function DateField<TFieldValues extends FieldValues>(props: DateFieldProps<TFieldValues>): React$1.JSX.Element;
714
-
715
- /**
716
- * Props for the FileField component.
717
- *
718
- * @template TFieldValues - The form data type
719
- *
720
- * @example
721
- * ```tsx
722
- * import { FileField } from "@rachelallyson/hero-hook-form";
723
- * import { useForm } from "react-hook-form";
724
- *
725
- * const form = useForm({
726
- * defaultValues: { avatar: null as FileList | null },
727
- * });
728
- *
729
- * <FileField
730
- * control={form.control}
731
- * name="avatar"
732
- * label="Upload Avatar"
733
- * accept="image/*"
734
- * description="Select an image file"
735
- * />
736
- * ```
737
- */
738
- type FileFieldProps<TFieldValues extends FieldValues> = FieldBaseProps<TFieldValues, FileList | null> & WithControl<TFieldValues> & {
739
- /** Additional props to pass to the underlying Input component */
740
- fileProps?: Omit<React$1.ComponentProps<typeof Input>, "value" | "onValueChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled" | "type">;
741
- /** Transform function to modify the file list before it's set */
742
- transform?: (value: FileList | null) => FileList | null;
743
- /** Whether multiple files can be selected */
744
- multiple?: boolean;
745
- /** Accepted file types (e.g., "image/*", ".pdf,.doc") */
746
- accept?: string;
747
- };
748
- /**
749
- * A file input field component that integrates React Hook Form with HeroUI Input.
750
- *
751
- * This component provides a type-safe file upload field with validation support,
752
- * error handling, and accessibility features. The field value is a `FileList` or `null`.
753
- *
754
- * @template TFieldValues - The form data type
755
- *
756
- * @param props - The file field props
757
- * @returns The rendered file field component
758
- *
759
- * @example
760
- * ```tsx
761
- * import { ZodForm, FormFieldHelpers } from "@rachelallyson/hero-hook-form";
762
- * import { z } from "zod";
763
- *
764
- * const schema = z.object({
765
- * avatar: z.instanceof(FileList).nullable(),
766
- * documents: z.instanceof(FileList).optional(),
767
- * });
768
- *
769
- * function MyForm() {
770
- * return (
771
- * <ZodForm
772
- * config={{
773
- * schema,
774
- * fields: [
775
- * FormFieldHelpers.file("avatar", "Upload Avatar", { accept: "image/*" }),
776
- * FormFieldHelpers.file("documents", "Upload Documents", {
777
- * multiple: true,
778
- * accept: ".pdf,.doc,.docx",
779
- * }),
780
- * ],
781
- * }}
782
- * onSubmit={(data) => console.log(data)}
783
- * />
784
- * );
785
- * }
786
- * ```
787
- *
788
- * @example
789
- * ```tsx
790
- * // With file size validation
791
- * <FileField
792
- * control={form.control}
793
- * name="avatar"
794
- * label="Upload Avatar"
795
- * accept="image/*"
796
- * transform={(files) => {
797
- * if (files && files[0] && files[0].size > 5 * 1024 * 1024) {
798
- * // File too large
799
- * return null;
800
- * }
801
- * return files;
802
- * }}
803
- * />
804
- * ```
805
- */
806
- declare function FileField<TFieldValues extends FieldValues>(props: FileFieldProps<TFieldValues>): React$1.JSX.Element;
807
-
808
- interface FontPickerProps {
809
- showFontPreview?: boolean;
810
- loadAllVariants?: boolean;
811
- onFontsLoaded?: (loaded: boolean) => void;
812
- fontsLoadedTimeout?: number;
813
- }
814
- type FontPickerFieldProps<TFieldValues extends FieldValues, TValue extends string = string> = FieldBaseProps<TFieldValues, TValue> & WithControl<TFieldValues> & {
815
- fontPickerProps?: FontPickerProps;
816
- };
817
- declare function FontPickerField<TFieldValues extends FieldValues, TValue extends string = string>(props: FontPickerFieldProps<TFieldValues, TValue>): React$1.JSX.Element;
818
-
819
- /**
820
- * Props for the InputField component.
821
- *
822
- * @template TFieldValues - The form data type
823
- */
824
- type InputFieldProps<TFieldValues extends FieldValues> = FieldBaseProps<TFieldValues, string> & WithControl<TFieldValues> & {
825
- inputProps?: Omit<React$1.ComponentProps<typeof Input>, "value" | "onValueChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled">;
826
- transform?: (value: string) => string;
827
- };
828
- /**
829
- * Input field component for text, email, password, tel, and number inputs.
830
- *
831
- * @description
832
- * A memoized input field component that integrates with React Hook Form
833
- * and HeroUI Input component. Supports all standard input types and
834
- * includes automatic validation error display.
835
- *
836
- * @template TFieldValues - The form data type
837
- *
838
- * @param {InputFieldProps<TFieldValues>} props - Component props
839
- * @param {Path<TFieldValues>} props.name - Field name path
840
- * @param {string} [props.label] - Field label
841
- * @param {string} [props.description] - Field description/help text
842
- * @param {Control<TFieldValues>} props.control - React Hook Form control
843
- * @param {boolean} [props.isDisabled] - Whether field is disabled
844
- * @param {RegisterOptions<TFieldValues>} [props.rules] - Validation rules
845
- * @param {Partial<InputProps>} [props.inputProps] - Additional Input component props
846
- * @param {(value: string) => string} [props.transform] - Value transformation function
847
- *
848
- * @returns {JSX.Element} The rendered input field
849
- *
850
- * @example
851
- * ```tsx
852
- * import { InputField } from "@rachelallyson/hero-hook-form";
853
- * import { useForm, Controller } from "react-hook-form";
854
- *
855
- * function MyForm() {
856
- * const { control } = useForm();
857
- *
858
- * return (
859
- * <InputField
860
- * name="email"
861
- * label="Email Address"
862
- * description="Enter your email address"
863
- * control={control}
864
- * inputProps={{
865
- * type: "email",
866
- * placeholder: "you@example.com",
867
- * }}
868
- * />
869
- * );
870
- * }
871
- * ```
872
- *
873
- * @see {@link FormFieldHelpers.input} for helper function to create input field config
874
- * @category Fields
875
- */
876
- declare const InputField: <TFieldValues extends FieldValues>(props: InputFieldProps<TFieldValues>) => React$1.JSX.Element;
877
-
878
- /**
879
- * Configuration for a radio option.
880
- *
881
- * @template TValue - The value type for the option
882
- */
883
- interface RadioOption<TValue extends string | number> {
884
- /** Display label for the option */
885
- label: string;
886
- /** Value of the option */
887
- value: TValue;
888
- /** Optional description text */
889
- description?: string;
890
- /** Whether the option is disabled */
891
- disabled?: boolean;
892
- }
893
- /**
894
- * Props for the RadioGroupField component.
895
- *
896
- * @template TFieldValues - The form data type
897
- * @template TValue - The value type for the radio group (string or number)
898
- *
899
- * @example
900
- * ```tsx
901
- * import { RadioGroupField } from "@rachelallyson/hero-hook-form";
902
- * import { useForm } from "react-hook-form";
903
- *
904
- * const form = useForm({
905
- * defaultValues: { plan: "" },
906
- * });
907
- *
908
- * const options = [
909
- * { label: "Basic", value: "basic" },
910
- * { label: "Pro", value: "pro" },
911
- * { label: "Enterprise", value: "enterprise" },
912
- * ];
913
- *
914
- * <RadioGroupField
915
- * control={form.control}
916
- * name="plan"
917
- * label="Select Plan"
918
- * options={options}
919
- * />
920
- * ```
921
- */
922
- type RadioGroupFieldProps<TFieldValues extends FieldValues, TValue extends string | number = string> = FieldBaseProps<TFieldValues, TValue> & WithControl<TFieldValues> & {
923
- /** Array of radio options */
924
- options: readonly RadioOption<TValue>[];
925
- /** Additional props to pass to the underlying RadioGroup component */
926
- radioGroupProps?: Omit<React$1.ComponentProps<typeof RadioGroup>, "value" | "onValueChange" | "label">;
927
- };
928
- /**
929
- * A radio group field component that integrates React Hook Form with HeroUI RadioGroup.
930
- *
931
- * This component provides a type-safe radio group field with validation support,
932
- * error handling, and accessibility features. Only one option can be selected at a time.
933
- *
934
- * @template TFieldValues - The form data type
935
- * @template TValue - The value type for the radio group (string or number)
936
- *
937
- * @param props - The radio group field props
938
- * @returns The rendered radio group field component
939
- *
940
- * @example
941
- * ```tsx
942
- * import { ZodForm, FormFieldHelpers } from "@rachelallyson/hero-hook-form";
943
- * import { z } from "zod";
944
- *
945
- * const schema = z.object({
946
- * plan: z.enum(["basic", "pro", "enterprise"], {
947
- * required_error: "Please select a plan",
948
- * }),
949
- * });
950
- *
951
- * const options = [
952
- * { label: "Basic - $9/month", value: "basic" },
953
- * { label: "Pro - $29/month", value: "pro" },
954
- * { label: "Enterprise - $99/month", value: "enterprise" },
955
- * ];
956
- *
957
- * function MyForm() {
958
- * return (
959
- * <ZodForm
960
- * config={{
961
- * schema,
962
- * fields: [
963
- * FormFieldHelpers.radioGroup("plan", "Select Plan", options),
964
- * ],
965
- * }}
966
- * onSubmit={(data) => console.log(data)}
967
- * />
968
- * );
969
- * }
970
- * ```
971
- *
972
- * @example
973
- * ```tsx
974
- * // With custom styling
975
- * <RadioGroupField
976
- * control={form.control}
977
- * name="plan"
978
- * label="Select Plan"
979
- * options={options}
980
- * radioGroupProps={{
981
- * orientation: "horizontal",
982
- * color: "primary",
983
- * }}
984
- * />
985
- * ```
986
- */
987
- declare function RadioGroupField<TFieldValues extends FieldValues, TValue extends string | number = string>(props: RadioGroupFieldProps<TFieldValues, TValue>): React$1.JSX.Element;
988
-
989
- /**
990
- * Configuration for a select option.
991
- *
992
- * @template TValue - The value type for the option
993
- */
994
- interface SelectOption<TValue extends string | number> {
995
- /** Display label for the option */
996
- label: string;
997
- /** Value of the option */
998
- value: TValue;
999
- /** Optional description text */
1000
- description?: string;
1001
- /** Whether the option is disabled */
1002
- disabled?: boolean;
1003
- }
1004
- /**
1005
- * Props for the SelectField component.
1006
- *
1007
- * @template TFieldValues - The form data type
1008
- * @template TValue - The value type for the select field (string or number)
1009
- *
1010
- * @example
1011
- * ```tsx
1012
- * import { SelectField } from "@rachelallyson/hero-hook-form";
1013
- * import { useForm } from "react-hook-form";
1014
- *
1015
- * const form = useForm({
1016
- * defaultValues: { country: "" },
1017
- * });
1018
- *
1019
- * const options = [
1020
- * { label: "United States", value: "us" },
1021
- * { label: "Canada", value: "ca" },
1022
- * { label: "Mexico", value: "mx" },
1023
- * ];
1024
- *
1025
- * <SelectField
1026
- * control={form.control}
1027
- * name="country"
1028
- * label="Country"
1029
- * options={options}
1030
- * placeholder="Select a country"
1031
- * />
1032
- * ```
1033
- */
1034
- type SelectFieldProps<TFieldValues extends FieldValues, TValue extends string | number = string> = FieldBaseProps<TFieldValues, TValue> & WithControl<TFieldValues> & {
1035
- /** Array of select options */
1036
- options: readonly SelectOption<TValue>[];
1037
- /** Placeholder text when no option is selected */
1038
- placeholder?: string;
1039
- /** Additional props to pass to the underlying Select component */
1040
- selectProps?: Omit<React$1.ComponentProps<typeof Select>, "selectedKeys" | "onSelectionChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled">;
1041
- };
1042
- /**
1043
- * A select dropdown field component that integrates React Hook Form with HeroUI Select.
1044
- *
1045
- * This component provides a type-safe select field with validation support,
1046
- * error handling, and accessibility features.
1047
- *
1048
- * @template TFieldValues - The form data type
1049
- * @template TValue - The value type for the select field (string or number)
1050
- *
1051
- * @param props - The select field props
1052
- * @returns The rendered select field component
1053
- *
1054
- * @example
1055
- * ```tsx
1056
- * import { ZodForm, FormFieldHelpers } from "@rachelallyson/hero-hook-form";
1057
- * import { z } from "zod";
1058
- *
1059
- * const schema = z.object({
1060
- * country: z.string().min(1, "Please select a country"),
1061
- * });
1062
- *
1063
- * const options = [
1064
- * { label: "United States", value: "us" },
1065
- * { label: "Canada", value: "ca" },
1066
- * ];
1067
- *
1068
- * function MyForm() {
1069
- * return (
1070
- * <ZodForm
1071
- * config={{
1072
- * schema,
1073
- * fields: [
1074
- * FormFieldHelpers.select("country", "Country", options, "Select a country"),
1075
- * ],
1076
- * }}
1077
- * onSubmit={(data) => console.log(data)}
1078
- * />
1079
- * );
1080
- * }
1081
- * ```
1082
- *
1083
- * @example
1084
- * ```tsx
1085
- * // With custom styling
1086
- * <SelectField
1087
- * control={form.control}
1088
- * name="country"
1089
- * label="Country"
1090
- * options={options}
1091
- * selectProps={{
1092
- * variant: "bordered",
1093
- * size: "lg",
1094
- * }}
1095
- * />
1096
- * ```
1097
- */
1098
- declare function SelectField<TFieldValues extends FieldValues, TValue extends string | number = string>(props: SelectFieldProps<TFieldValues, TValue>): React$1.JSX.Element;
1099
-
1100
- /**
1101
- * Props for the SliderField component.
1102
- *
1103
- * @template TFieldValues - The form data type
1104
- *
1105
- * @example
1106
- * ```tsx
1107
- * import { SliderField } from "@rachelallyson/hero-hook-form";
1108
- * import { useForm } from "react-hook-form";
1109
- *
1110
- * const form = useForm({
1111
- * defaultValues: { volume: 50 },
1112
- * });
1113
- *
1114
- * <SliderField
1115
- * control={form.control}
1116
- * name="volume"
1117
- * label="Volume"
1118
- * description="Adjust the volume level"
1119
- * />
1120
- * ```
1121
- */
1122
- type SliderFieldProps<TFieldValues extends FieldValues> = FieldBaseProps<TFieldValues, number> & WithControl<TFieldValues> & {
1123
- /** Additional props to pass to the underlying Slider component */
1124
- sliderProps?: Omit<React$1.ComponentProps<typeof Slider>, "value" | "onValueChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled">;
1125
- /** Transform function to modify the slider value before it's set */
1126
- transform?: (value: number) => number;
1127
- };
1128
- /**
1129
- * A slider field component that integrates React Hook Form with HeroUI Slider.
1130
- *
1131
- * This component provides a type-safe slider field with validation support,
1132
- * error handling, and accessibility features. The field value is a number.
1133
- *
1134
- * @template TFieldValues - The form data type
1135
- *
1136
- * @param props - The slider field props
1137
- * @returns The rendered slider field component
1138
- *
1139
- * @example
1140
- * ```tsx
1141
- * import { ZodForm, FormFieldHelpers } from "@rachelallyson/hero-hook-form";
1142
- * import { z } from "zod";
1143
- *
1144
- * const schema = z.object({
1145
- * volume: z.number().min(0).max(100),
1146
- * brightness: z.number().min(0).max(100),
1147
- * });
1148
- *
1149
- * function MyForm() {
1150
- * return (
1151
- * <ZodForm
1152
- * config={{
1153
- * schema,
1154
- * fields: [
1155
- * FormFieldHelpers.slider("volume", "Volume", { min: 0, max: 100 }),
1156
- * FormFieldHelpers.slider("brightness", "Brightness", { min: 0, max: 100 }),
1157
- * ],
1158
- * }}
1159
- * onSubmit={(data) => console.log(data)}
1160
- * />
1161
- * );
1162
- * }
1163
- * ```
1164
- *
1165
- * @example
1166
- * ```tsx
1167
- * // With custom step and marks
1168
- * <SliderField
1169
- * control={form.control}
1170
- * name="volume"
1171
- * label="Volume"
1172
- * sliderProps={{
1173
- * minValue: 0,
1174
- * maxValue: 100,
1175
- * step: 10,
1176
- * marks: [
1177
- * { value: 0, label: "0" },
1178
- * { value: 50, label: "50" },
1179
- * { value: 100, label: "100" },
1180
- * ],
1181
- * }}
1182
- * />
1183
- * ```
1184
- */
1185
- declare function SliderField<TFieldValues extends FieldValues>(props: SliderFieldProps<TFieldValues>): React$1.JSX.Element;
1186
-
1187
- /**
1188
- * Props for the SwitchField component.
1189
- *
1190
- * @template TFieldValues - The form data type
1191
- *
1192
- * @example
1193
- * ```tsx
1194
- * import { SwitchField } from "@rachelallyson/hero-hook-form";
1195
- * import { useForm } from "react-hook-form";
1196
- *
1197
- * const form = useForm({
1198
- * defaultValues: { notifications: false },
1199
- * });
1200
- *
1201
- * <SwitchField
1202
- * control={form.control}
1203
- * name="notifications"
1204
- * label="Enable notifications"
1205
- * description="Receive email notifications"
1206
- * />
1207
- * ```
1208
- */
1209
- type SwitchFieldProps<TFieldValues extends FieldValues> = FieldBaseProps<TFieldValues, boolean> & WithControl<TFieldValues> & {
1210
- /** Additional props to pass to the underlying Switch component */
1211
- switchProps?: Omit<React$1.ComponentProps<typeof Switch>, "isSelected" | "onValueChange" | "isInvalid" | "isDisabled">;
1212
- };
1213
- /**
1214
- * A switch/toggle field component that integrates React Hook Form with HeroUI Switch.
1215
- *
1216
- * This component provides a type-safe switch field with validation support,
1217
- * error handling, and accessibility features. The field value is a boolean.
1218
- *
1219
- * @template TFieldValues - The form data type
1220
- *
1221
- * @param props - The switch field props
1222
- * @returns The rendered switch field component
1223
- *
1224
- * @example
1225
- * ```tsx
1226
- * import { ZodForm, FormFieldHelpers } from "@rachelallyson/hero-hook-form";
1227
- * import { z } from "zod";
1228
- *
1229
- * const schema = z.object({
1230
- * notifications: z.boolean(),
1231
- * darkMode: z.boolean().default(false),
1232
- * });
1233
- *
1234
- * function MyForm() {
1235
- * return (
1236
- * <ZodForm
1237
- * config={{
1238
- * schema,
1239
- * fields: [
1240
- * FormFieldHelpers.switch("notifications", "Enable notifications", "Receive email notifications"),
1241
- * FormFieldHelpers.switch("darkMode", "Dark mode"),
1242
- * ],
1243
- * }}
1244
- * onSubmit={(data) => console.log(data)}
1245
- * />
1246
- * );
1247
- * }
1248
- * ```
1249
- *
1250
- * @example
1251
- * ```tsx
1252
- * // With custom styling
1253
- * <SwitchField
1254
- * control={form.control}
1255
- * name="notifications"
1256
- * label="Enable notifications"
1257
- * switchProps={{
1258
- * color: "success",
1259
- * size: "lg",
1260
- * }}
1261
- * />
1262
- * ```
1263
- */
1264
- declare function SwitchField<TFieldValues extends FieldValues>(props: SwitchFieldProps<TFieldValues>): React$1.JSX.Element;
1265
-
1266
- /**
1267
- * Props for the TextareaField component.
1268
- *
1269
- * @template TFieldValues - The form data type
1270
- *
1271
- * @example
1272
- * ```tsx
1273
- * import { TextareaField } from "@rachelallyson/hero-hook-form";
1274
- * import { useForm } from "react-hook-form";
1275
- *
1276
- * const form = useForm({
1277
- * defaultValues: { message: "" },
1278
- * });
1279
- *
1280
- * <TextareaField
1281
- * control={form.control}
1282
- * name="message"
1283
- * label="Message"
1284
- * description="Enter your message here"
1285
- * placeholder="Type your message..."
1286
- * />
1287
- * ```
1288
- */
1289
- type TextareaFieldProps<TFieldValues extends FieldValues> = FieldBaseProps<TFieldValues, string> & WithControl<TFieldValues> & {
1290
- /** Additional props to pass to the underlying Textarea component */
1291
- textareaProps?: Omit<React$1.ComponentProps<typeof Textarea>, "value" | "onValueChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled">;
1292
- };
1293
- /**
1294
- * A textarea field component that integrates React Hook Form with HeroUI Textarea.
1295
- *
1296
- * This component provides a type-safe textarea field with validation support,
1297
- * error handling, and accessibility features. Use this for multi-line text input.
1298
- *
1299
- * @template TFieldValues - The form data type
1300
- *
1301
- * @param props - The textarea field props
1302
- * @returns The rendered textarea field component
1303
- *
1304
- * @example
1305
- * ```tsx
1306
- * import { ZodForm, FormFieldHelpers } from "@rachelallyson/hero-hook-form";
1307
- * import { z } from "zod";
1308
- *
1309
- * const schema = z.object({
1310
- * message: z.string().min(10, "Message must be at least 10 characters"),
1311
- * feedback: z.string().max(500, "Feedback must be less than 500 characters"),
1312
- * });
1313
- *
1314
- * function MyForm() {
1315
- * return (
1316
- * <ZodForm
1317
- * config={{
1318
- * schema,
1319
- * fields: [
1320
- * FormFieldHelpers.textarea("message", "Message", "Enter your message"),
1321
- * FormFieldHelpers.textarea("feedback", "Feedback"),
1322
- * ],
1323
- * }}
1324
- * onSubmit={(data) => console.log(data)}
1325
- * />
1326
- * );
1327
- * }
1328
- * ```
1329
- *
1330
- * @example
1331
- * ```tsx
1332
- * // With custom styling and min/max rows
1333
- * <TextareaField
1334
- * control={form.control}
1335
- * name="message"
1336
- * label="Message"
1337
- * textareaProps={{
1338
- * minRows: 3,
1339
- * maxRows: 10,
1340
- * variant: "bordered",
1341
- * }}
1342
- * />
1343
- * ```
1344
- */
1345
- declare function TextareaField<TFieldValues extends FieldValues>(props: TextareaFieldProps<TFieldValues>): React$1.JSX.Element;
1346
-
1347
- /**
1348
- * Options for the useFormHelper hook.
1349
- *
1350
- * @template T - The form data type
1351
- */
1352
- interface UseFormHelperOptions<T extends FieldValues> {
1353
- onError?: (error: FormValidationError) => void;
1354
- onSubmit: SubmitHandler<T>;
1355
- onSuccess?: (data: T) => void;
1356
- defaultValues?: Partial<T>;
1357
- methods?: UseFormReturn<T>;
1358
- }
1359
- /**
1360
- * Hook for managing form state with enhanced features.
1361
- *
1362
- * @description
1363
- * Provides form state management with loading states, error handling,
1364
- * and submission tracking. Automatically handles form validation and
1365
- * provides callbacks for success and error cases. This hook wraps
1366
- * React Hook Form's useForm with additional state management.
1367
- *
1368
- * @template T - The form data type
1369
- *
1370
- * @param {UseFormHelperOptions<T>} options - Hook options
1371
- * @param {Partial<T>} [options.defaultValues] - Default form values
1372
- * @param {UseFormReturn<T>} [options.methods] - Optional existing form instance
1373
- * @param {SubmitHandler<T>} options.onSubmit - Submit handler function
1374
- * @param {(error: FormValidationError) => void} [options.onError] - Error handler callback
1375
- * @param {(data: T) => void} [options.onSuccess] - Success handler callback
1376
- *
1377
- * @returns {Object} Form helper with state and methods
1378
- * @returns {UseFormReturn<T>} form - React Hook Form instance
1379
- * @returns {() => Promise<void>} handleSubmit - Submit handler function
1380
- * @returns {() => void} resetForm - Reset form function
1381
- * @returns {boolean} isSubmitting - Whether form is currently submitting
1382
- * @returns {boolean} isSubmitted - Whether form has been submitted
1383
- * @returns {boolean} isSuccess - Whether last submission was successful
1384
- * @returns {string|undefined} error - Error message if submission failed
1385
- * @returns {FormSubmissionState} submissionState - Complete submission state object
1386
- *
1387
- * @example
1388
- * ```tsx
1389
- * import { useFormHelper } from "@rachelallyson/hero-hook-form";
1390
- *
1391
- * function MyForm() {
1392
- * const { form, handleSubmit, isSubmitting, error } = useFormHelper({
1393
- * defaultValues: { email: "", name: "" },
1394
- * onSubmit: async (data) => {
1395
- * await submitToServer(data);
1396
- * },
1397
- * onError: (error) => {
1398
- * console.error("Validation errors:", error);
1399
- * },
1400
- * onSuccess: (data) => {
1401
- * console.log("Success:", data);
1402
- * },
1403
- * });
1404
- *
1405
- * return (
1406
- * <form onSubmit={(e) => { e.preventDefault(); handleSubmit(); }}>
1407
- * <button disabled={isSubmitting}>
1408
- * {isSubmitting ? "Submitting..." : "Submit"}
1409
- * </button>
1410
- * {error && <div className="error">{error}</div>}
1411
- * </form>
1412
- * );
1413
- * }
1414
- * ```
1415
- *
1416
- * @example
1417
- * Using with existing form instance:
1418
- * ```tsx
1419
- * import { useForm } from "react-hook-form";
1420
- * import { useFormHelper } from "@rachelallyson/hero-hook-form";
1421
- *
1422
- * function MyForm() {
1423
- * const existingForm = useForm({ defaultValues: { email: "" } });
1424
- * const { handleSubmit, isSubmitting } = useFormHelper({
1425
- * methods: existingForm,
1426
- * onSubmit: async (data) => {
1427
- * await submitToServer(data);
1428
- * },
1429
- * });
1430
- *
1431
- * // Use existingForm and handleSubmit together
1432
- * }
1433
- * ```
1434
- *
1435
- * @see {@link useHeroForm} for alternative hook with different API
1436
- * @see {@link ConfigurableForm} for component that uses this hook
1437
- * @category Hooks
1438
- */
1439
- declare function useFormHelper<T extends FieldValues>({ defaultValues, methods, onError, onSubmit, onSuccess, }: UseFormHelperOptions<T>): {
1440
- error: string | undefined;
1441
- form: UseFormReturn<T>;
1442
- handleSubmit: () => Promise<void>;
1443
- isSubmitted: boolean;
1444
- isSubmitting: boolean;
1445
- isSuccess: boolean;
1446
- resetForm: () => void;
1447
- submissionState: FormSubmissionState;
1448
- };
1449
-
1450
- /**
1451
- * Enhanced hook that provides both form methods and styling defaults.
1452
- *
1453
- * @description
1454
- * This hook combines React Hook Form's useFormContext with Hero Hook Form's
1455
- * styling defaults, giving you access to both form functionality and
1456
- * component styling in one convenient hook. Must be used within a FormProvider
1457
- * context (provided by ZodForm, ConfigurableForm, or manual FormProvider).
1458
- *
1459
- * @template TFieldValues - The form data type
1460
- *
1461
- * @returns {Object} Enhanced form object with all React Hook Form methods and Hero Hook Form defaults
1462
- * @returns {UseFormReturn<TFieldValues>} All React Hook Form methods (formState, getValues, setValue, etc.)
1463
- * @returns {HeroHookFormDefaultsConfig} defaults - Hero Hook Form styling defaults
1464
- *
1465
- * @example
1466
- * ```tsx
1467
- * import { useHeroForm } from "@rachelallyson/hero-hook-form";
1468
- *
1469
- * function MyComponent() {
1470
- * const { formState, getValues, setValue, defaults } = useHeroForm();
1471
- *
1472
- * // Access form state
1473
- * const isSubmitting = formState.isSubmitting;
1474
- * const errors = formState.errors;
1475
- *
1476
- * // Access form methods
1477
- * const values = getValues();
1478
- * const handleReset = () => setValue('fieldName', '');
1479
- *
1480
- * // Access styling defaults
1481
- * const inputDefaults = defaults.input;
1482
- * const buttonDefaults = defaults.submitButton;
1483
- * }
1484
- * ```
1485
- *
1486
- * @see {@link useFormHelper} for form state management with callbacks
1487
- * @see {@link useFormContext} from React Hook Form for base functionality
1488
- * @category Hooks
1489
- */
1490
- declare function useHeroForm<TFieldValues extends FieldValues>(): {
1491
- defaults: Required<Pick<HeroHookFormDefaultsConfig, "input" | "textarea" | "select" | "switch" | "radioGroup" | "checkbox" | "slider" | "dateInput" | "submitButton">>;
1492
- watch: react_hook_form.UseFormWatch<TFieldValues>;
1493
- getValues: react_hook_form.UseFormGetValues<TFieldValues>;
1494
- getFieldState: react_hook_form.UseFormGetFieldState<TFieldValues>;
1495
- setError: react_hook_form.UseFormSetError<TFieldValues>;
1496
- clearErrors: react_hook_form.UseFormClearErrors<TFieldValues>;
1497
- setValue: react_hook_form.UseFormSetValue<TFieldValues>;
1498
- trigger: react_hook_form.UseFormTrigger<TFieldValues>;
1499
- formState: react_hook_form.FormState<TFieldValues>;
1500
- resetField: react_hook_form.UseFormResetField<TFieldValues>;
1501
- reset: react_hook_form.UseFormReset<TFieldValues>;
1502
- handleSubmit: react_hook_form.UseFormHandleSubmit<TFieldValues, TFieldValues>;
1503
- unregister: react_hook_form.UseFormUnregister<TFieldValues>;
1504
- control: react_hook_form.Control<TFieldValues, any, TFieldValues>;
1505
- register: react_hook_form.UseFormRegister<TFieldValues>;
1506
- setFocus: react_hook_form.UseFormSetFocus<TFieldValues>;
1507
- subscribe: react_hook_form.UseFormSubscribe<TFieldValues>;
1508
- };
1509
-
1510
- type InputProps = React$1.ComponentProps<typeof Input>;
1511
- type TextareaProps = React$1.ComponentProps<typeof Textarea>;
1512
- type SelectProps = React$1.ComponentProps<typeof Select>;
1513
- type SharedTextLikeColor = Extract<InputProps["color"], Extract<TextareaProps["color"], SelectProps["color"]>>;
1514
- type SharedTextLikeSize = Extract<InputProps["size"], Extract<TextareaProps["size"], SelectProps["size"]>>;
1515
- type SharedTextLikeVariant = Extract<InputProps["variant"], Extract<TextareaProps["variant"], SelectProps["variant"]>>;
1516
- type SharedTextLikeRadius = Extract<InputProps["radius"], Extract<TextareaProps["radius"], SelectProps["radius"]>>;
1517
- type SharedTextLikeLabelPlacement = Extract<InputProps["labelPlacement"], Extract<TextareaProps["labelPlacement"], SelectProps["labelPlacement"]>>;
1518
- type CommonFieldDefaults = Partial<{
1519
- color: SharedTextLikeColor;
1520
- size: SharedTextLikeSize;
1521
- variant: SharedTextLikeVariant;
1522
- radius: SharedTextLikeRadius;
1523
- labelPlacement: SharedTextLikeLabelPlacement;
1524
- }>;
1525
- type InputDefaults = Partial<Omit<InputProps, "value" | "onValueChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled">>;
1526
- type TextareaDefaults = Partial<Omit<TextareaProps, "value" | "onValueChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled">>;
1527
- type CheckboxDefaults = Partial<Omit<React$1.ComponentProps<typeof Checkbox>, "isSelected" | "onValueChange" | "isInvalid" | "errorMessage" | "isDisabled">>;
1528
- type RadioGroupDefaults = Partial<Omit<React$1.ComponentProps<typeof RadioGroup>, "value" | "onValueChange" | "label">>;
1529
- type SelectDefaults = Partial<Omit<SelectProps, "selectedKeys" | "onSelectionChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled">>;
1530
- type DateInputDefaults = Partial<Omit<React$1.ComponentProps<typeof DateInput>, "value" | "onValueChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled">>;
1531
- type SliderDefaults = Partial<Omit<React$1.ComponentProps<typeof Slider>, "value" | "onValueChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled">>;
1532
- type SwitchDefaults = Partial<Omit<React$1.ComponentProps<typeof Switch>, "isSelected" | "onValueChange" | "isInvalid" | "isDisabled">>;
1533
- type ButtonDefaults = Partial<Omit<React$1.ComponentProps<typeof Button>, "type" | "isLoading">>;
1534
- interface HeroHookFormDefaultsConfig {
1535
- common?: CommonFieldDefaults;
1536
- input?: InputDefaults;
1537
- textarea?: TextareaDefaults;
1538
- checkbox?: CheckboxDefaults;
1539
- radioGroup?: RadioGroupDefaults;
1540
- select?: SelectDefaults;
1541
- dateInput?: DateInputDefaults;
1542
- slider?: SliderDefaults;
1543
- switch?: SwitchDefaults;
1544
- submitButton?: ButtonDefaults;
1545
- }
1546
- interface HeroHookFormProviderProps {
1547
- children: React$1.ReactNode;
1548
- defaults?: HeroHookFormDefaultsConfig;
1549
- }
1550
- declare function HeroHookFormProvider(props: HeroHookFormProviderProps): React$1.JSX.Element;
1551
- declare function useHeroHookFormDefaults(): Required<Pick<HeroHookFormDefaultsConfig, "input" | "textarea" | "checkbox" | "radioGroup" | "select" | "dateInput" | "slider" | "switch" | "submitButton">>;
1552
-
1553
- interface FormProps<TFieldValues extends FieldValues> {
1554
- methods: UseFormReturn<TFieldValues>;
1555
- onSubmit: SubmitHandler<TFieldValues>;
1556
- className?: string;
1557
- children: React$1.ReactNode;
1558
- id?: string;
1559
- noValidate?: boolean;
1560
- }
1561
- declare function FormProvider<TFieldValues extends FieldValues>(props: FormProps<TFieldValues>): React$1.JSX.Element;
1562
-
1563
- /**
1564
- * Enhanced form state with submission tracking and error management.
1565
- *
1566
- * @template T - The form data type
1567
- */
1568
- interface EnhancedFormState<T extends FieldValues> {
1569
- status: "idle" | "submitting" | "success" | "error";
1570
- isSubmitting: boolean;
1571
- isSuccess: boolean;
1572
- isError: boolean;
1573
- error?: string;
1574
- submittedData?: T;
1575
- touchedFields: Set<Path<T>>;
1576
- dirtyFields: Set<Path<T>>;
1577
- hasErrors: boolean;
1578
- errorCount: number;
1579
- handleSuccess: (data: T) => void;
1580
- handleError: (error: string) => void;
1581
- reset: () => void;
1582
- }
1583
- /**
1584
- * Options for the useEnhancedFormState hook.
1585
- *
1586
- * @template T - The form data type
1587
- */
1588
- interface UseEnhancedFormStateOptions<T extends FieldValues> {
1589
- onSuccess?: (data: T) => void;
1590
- onError?: (error: string) => void;
1591
- successMessage?: string;
1592
- errorMessage?: string;
1593
- autoReset?: boolean;
1594
- resetDelay?: number;
1595
- }
1596
- /**
1597
- * Hook for managing enhanced form state with submission tracking.
1598
- *
1599
- * @description
1600
- * Provides advanced form state management including submission status,
1601
- * error tracking, touched/dirty field tracking, and automatic reset
1602
- * functionality. Useful for building forms with rich UI feedback.
1603
- *
1604
- * @template T - The form data type
1605
- *
1606
- * @param {UseFormReturn<T>} form - React Hook Form instance
1607
- * @param {UseEnhancedFormStateOptions<T>} [options] - Configuration options
1608
- * @param {(data: T) => void} [options.onSuccess] - Success callback
1609
- * @param {(error: string) => void} [options.onError] - Error callback
1610
- * @param {string} [options.successMessage] - Custom success message
1611
- * @param {string} [options.errorMessage] - Custom error message
1612
- * @param {boolean} [options.autoReset=true] - Automatically reset after success
1613
- * @param {number} [options.resetDelay=3000] - Delay before auto-reset (ms)
1614
- *
1615
- * @returns {EnhancedFormState<T>} Enhanced form state object
1616
- * @returns {"idle"|"submitting"|"success"|"error"} status - Current submission status
1617
- * @returns {boolean} isSubmitting - Whether form is currently submitting
1618
- * @returns {boolean} isSuccess - Whether last submission was successful
1619
- * @returns {boolean} isError - Whether last submission had an error
1620
- * @returns {string|undefined} error - Error message if submission failed
1621
- * @returns {T|undefined} submittedData - Data from last successful submission
1622
- * @returns {Set<Path<T>>} touchedFields - Set of touched field paths
1623
- * @returns {Set<Path<T>>} dirtyFields - Set of dirty field paths
1624
- * @returns {boolean} hasErrors - Whether form has validation errors
1625
- * @returns {number} errorCount - Number of validation errors
1626
- * @returns {(data: T) => void} handleSuccess - Function to mark submission as successful
1627
- * @returns {(error: string) => void} handleError - Function to mark submission as failed
1628
- * @returns {() => void} reset - Function to reset state to idle
1629
- *
1630
- * @example
1631
- * ```tsx
1632
- * import { useEnhancedFormState } from "@rachelallyson/hero-hook-form";
1633
- * import { useForm } from "react-hook-form";
1634
- *
1635
- * function MyForm() {
1636
- * const form = useForm();
1637
- * const state = useEnhancedFormState(form, {
1638
- * onSuccess: (data) => {
1639
- * console.log("Success:", data);
1640
- * },
1641
- * onError: (error) => {
1642
- * console.error("Error:", error);
1643
- * },
1644
- * autoReset: true,
1645
- * resetDelay: 3000,
1646
- * });
1647
- *
1648
- * const handleSubmit = async (data) => {
1649
- * try {
1650
- * await submitToServer(data);
1651
- * state.handleSuccess(data);
1652
- * } catch (error) {
1653
- * state.handleError(error.message);
1654
- * }
1655
- * };
1656
- *
1657
- * return (
1658
- * <form onSubmit={form.handleSubmit(handleSubmit)}>
1659
- * {/* form fields *\/}
1660
- * {state.isSubmitting && <div>Submitting...</div>}
1661
- * {state.isSuccess && <div>Success!</div>}
1662
- * {state.error && <div>Error: {state.error}</div>}
1663
- * </form>
1664
- * );
1665
- * }
1666
- * ```
1667
- *
1668
- * @see {@link ZodForm} which uses this hook internally
1669
- * @category Hooks
1670
- */
1671
- declare function useEnhancedFormState<T extends FieldValues>(form: UseFormReturn<T>, options?: UseEnhancedFormStateOptions<T>): EnhancedFormState<T>;
1672
-
1673
- interface SubmitButtonProps {
1674
- children: React$1.ReactNode;
1675
- isLoading?: boolean;
1676
- isSuccess?: boolean;
1677
- successText?: string;
1678
- loadingText?: string;
1679
- enhancedState?: EnhancedFormState<any>;
1680
- buttonProps?: Omit<React$1.ComponentProps<typeof Button>, "type" | "isLoading">;
1681
- }
1682
- declare function SubmitButton(props: SubmitButtonProps): React$1.JSX.Element;
1683
-
1684
- /**
1685
- * Server field error structure.
1686
- *
1687
- * @template TFieldValues - The form data type
1688
- */
1689
- interface ServerFieldError<TFieldValues extends FieldValues> {
1690
- path: Path<TFieldValues>;
1691
- message: string;
1692
- type?: string;
1693
- }
1694
- /**
1695
- * Server form error structure containing field errors.
1696
- *
1697
- * @template TFieldValues - The form data type
1698
- */
1699
- interface ServerFormError<TFieldValues extends FieldValues> {
1700
- message?: string;
1701
- fieldErrors?: readonly ServerFieldError<TFieldValues>[];
1702
- }
1703
- /**
1704
- * Applies server-side validation errors to a React Hook Form instance.
1705
- *
1706
- * @description
1707
- * Maps server-returned field errors to React Hook Form's error state.
1708
- * Useful for displaying validation errors from API responses. This function
1709
- * iterates through the field errors and sets them on the form using
1710
- * React Hook Form's setError function.
1711
- *
1712
- * @template TFieldValues - The form data type
1713
- *
1714
- * @param {UseFormSetError<TFieldValues>} setError - React Hook Form's setError function
1715
- * @param {ServerFormError<TFieldValues>} serverError - Server error containing field errors
1716
- *
1717
- * @example
1718
- * ```tsx
1719
- * import { applyServerErrors } from "@rachelallyson/hero-hook-form";
1720
- * import { useForm } from "react-hook-form";
1721
- *
1722
- * function MyForm() {
1723
- * const form = useForm();
1724
- *
1725
- * const handleSubmit = async (data) => {
1726
- * try {
1727
- * const response = await fetch("/api/submit", {
1728
- * method: "POST",
1729
- * body: JSON.stringify(data),
1730
- * });
1731
- *
1732
- * if (!response.ok) {
1733
- * const errorData = await response.json();
1734
- * applyServerErrors(form.setError, errorData);
1735
- * }
1736
- * } catch (error) {
1737
- * console.error("Error:", error);
1738
- * }
1739
- * };
1740
- *
1741
- * return (
1742
- * <form onSubmit={form.handleSubmit(handleSubmit)}>
1743
- * {/* form fields go here *\/}
1744
- * </form>
1745
- * );
1746
- * }
1747
- * ```
1748
- *
1749
- * @example
1750
- * With ZodForm error handling:
1751
- * ```tsx
1752
- * import { ZodForm, applyServerErrors } from "@rachelallyson/hero-hook-form";
1753
- *
1754
- * function MyForm() {
1755
- * const form = useForm();
1756
- *
1757
- * const handleSubmit = async (data) => {
1758
- * try {
1759
- * await submitToServer(data);
1760
- * } catch (error) {
1761
- * if (error.fieldErrors) {
1762
- * applyServerErrors(form.setError, {
1763
- * fieldErrors: error.fieldErrors,
1764
- * });
1765
- * }
1766
- * }
1767
- * };
1768
- *
1769
- * return <ZodForm config={{ schema, fields }} onSubmit={handleSubmit} />;
1770
- * }
1771
- * ```
1772
- *
1773
- * @see {@link ServerFormError} for error structure
1774
- * @see {@link ServerFieldError} for field error structure
1775
- * @category Utilities
1776
- */
1777
- declare function applyServerErrors<TFieldValues extends FieldValues>(setError: UseFormSetError<TFieldValues>, serverError: ServerFormError<TFieldValues>): void;
1778
-
1779
- /**
1780
- * Testing utilities for forms
1781
- * These utilities help with testing form behavior and state
1782
- */
1783
- /**
1784
- * Creates form test utilities for a given form instance
1785
- */
1786
- declare function createFormTestUtils<TFieldValues extends FieldValues>(form: UseFormReturn<TFieldValues>): FormTestUtils<TFieldValues>;
1787
- /**
1788
- * Mock form data for testing
1789
- */
1790
- declare function createMockFormData<TFieldValues extends FieldValues>(overrides?: Partial<TFieldValues>): TFieldValues;
1791
- /**
1792
- * Mock form errors for testing
1793
- */
1794
- declare function createMockFormErrors<TFieldValues extends FieldValues>(overrides?: Partial<FieldErrors<TFieldValues>>): FieldErrors<TFieldValues>;
1795
- /**
1796
- * Wait for form state to change (useful for async operations)
1797
- */
1798
- declare function waitForFormState<TFieldValues extends FieldValues>(form: UseFormReturn<TFieldValues>, condition: (state: unknown) => boolean, timeout?: number): Promise<void>;
1799
- /**
1800
- * Simulate user input on a field
1801
- */
1802
- declare function simulateFieldInput<TFieldValues extends FieldValues>(form: UseFormReturn<TFieldValues>, name: Path<TFieldValues>, value: unknown): void;
1803
- /**
1804
- * Simulate form submission
1805
- */
1806
- declare function simulateFormSubmission<TFieldValues extends FieldValues>(form: UseFormReturn<TFieldValues>, onSubmit: (data: TFieldValues) => void | Promise<void>): Promise<void>;
1807
- /**
1808
- * Check if form has validation errors
1809
- */
1810
- declare function hasFormErrors<TFieldValues extends FieldValues>(form: UseFormReturn<TFieldValues>): boolean;
1811
- /**
1812
- * Get all form errors as a flat array
1813
- */
1814
- declare function getFormErrors<TFieldValues extends FieldValues>(form: UseFormReturn<TFieldValues>): string[];
1815
- /**
1816
- * Check if a specific field has an error
1817
- */
1818
- declare function hasFieldError<TFieldValues extends FieldValues>(form: UseFormReturn<TFieldValues>, name: Path<TFieldValues>): boolean;
1819
- /**
1820
- * Get error message for a specific field
1821
- */
1822
- declare function getFieldError<TFieldValues extends FieldValues>(form: UseFormReturn<TFieldValues>, name: Path<TFieldValues>): string | undefined;
1823
-
1824
- /**
1825
- * Validation utility functions for common form validation patterns
1826
- * These utilities help create consistent validation schemas across forms
1827
- */
1828
- /**
1829
- * Creates a minimum length validation schema
1830
- */
1831
- declare const createMinLengthSchema: (min: number, fieldName: string) => z.ZodString;
1832
- /**
1833
- * Creates a maximum length validation schema
1834
- */
1835
- declare const createMaxLengthSchema: (max: number, fieldName: string) => z.ZodString;
1836
- /**
1837
- * Creates an email validation schema
1838
- */
1839
- declare const createEmailSchema: () => z.ZodEmail;
1840
- /**
1841
- * Creates a required field validation schema
1842
- */
1843
- declare const createRequiredSchema: (fieldName: string) => z.ZodString;
1844
- /**
1845
- * Creates a URL validation schema
1846
- */
1847
- declare const createUrlSchema: () => z.ZodString;
1848
- /**
1849
- * Creates a phone number validation schema
1850
- */
1851
- declare const createPhoneSchema: () => z.ZodString;
1852
- /**
1853
- * Creates a password validation schema with common requirements
1854
- */
1855
- declare const createPasswordSchema: (minLength?: number) => z.ZodString;
1856
- /**
1857
- * Creates a number validation schema with range
1858
- */
1859
- declare const createNumberRangeSchema: (min: number, max: number, fieldName: string) => z.ZodNumber;
1860
- /**
1861
- * Creates a date validation schema
1862
- */
1863
- declare const createDateSchema: (fieldName: string) => z.ZodDate;
1864
- /**
1865
- * Creates a future date validation schema
1866
- */
1867
- declare const createFutureDateSchema: (fieldName: string) => z.ZodDate;
1868
- /**
1869
- * Creates a past date validation schema
1870
- */
1871
- declare const createPastDateSchema: (fieldName: string) => z.ZodDate;
1872
- /**
1873
- * Creates a file validation schema
1874
- */
1875
- declare const createFileSchema: (maxSizeInMB?: number, allowedTypes?: string[]) => z.ZodCustom<File, File>;
1876
- /**
1877
- * Creates a checkbox validation schema (must be checked)
1878
- */
1879
- declare const createRequiredCheckboxSchema: (fieldName: string) => z.ZodBoolean;
1880
- /**
1881
- * Cross-field validation helpers
1882
- */
1883
- declare const crossFieldValidation: {
1884
- /**
1885
- * Conditional required field validation
1886
- */
1887
- conditionalRequired: (field: string, conditionField: string, conditionValue: any) => z.ZodObject<{
1888
- [x: string]: z.ZodString | z.ZodAny;
1889
- }, z.core.$strip>;
1890
- /**
1891
- * Date range validation
1892
- */
1893
- dateRange: (startField: string, endField: string) => z.ZodObject<{
1894
- [x: string]: z.ZodString;
1895
- }, z.core.$strip>;
1896
- /**
1897
- * Password confirmation validation
1898
- */
1899
- passwordConfirmation: (passwordField: string, confirmField: string) => z.ZodObject<{
1900
- [x: string]: z.ZodString;
1901
- }, z.core.$strip>;
1902
- };
1903
- /**
1904
- * Common validation patterns for forms
1905
- */
1906
- declare const commonValidations: {
1907
- confirmPassword: (passwordField: string, confirmField: string) => z.ZodObject<{
1908
- [x: string]: z.ZodString;
1909
- }, z.core.$strip>;
1910
- date: (fieldName: string) => z.ZodDate;
1911
- email: z.ZodEmail;
1912
- file: (maxSizeInMB?: number, allowedTypes?: string[]) => z.ZodCustom<File, File>;
1913
- futureDate: (fieldName: string) => z.ZodDate;
1914
- maxLength: (max: number, fieldName: string) => z.ZodString;
1915
- minLength: (min: number, fieldName: string) => z.ZodString;
1916
- numberRange: (min: number, max: number, fieldName: string) => z.ZodNumber;
1917
- password: (minLength?: number) => z.ZodString;
1918
- pastDate: (fieldName: string) => z.ZodDate;
1919
- phone: z.ZodString;
1920
- required: (fieldName: string) => z.ZodString;
1921
- requiredCheckbox: (fieldName: string) => z.ZodBoolean;
1922
- url: z.ZodString;
1923
- };
1924
-
1925
- /**
1926
- * Props for the ZodForm component.
1927
- *
1928
- * @template T - The form data type inferred from the Zod schema
1929
- */
1930
- interface ZodFormProps<T extends FieldValues> {
1931
- className?: string;
1932
- columns?: 1 | 2 | 3;
1933
- config: ZodFormConfig<T>;
1934
- layout?: "vertical" | "horizontal" | "grid";
1935
- onError?: (error: FormValidationError) => void;
1936
- onSubmit: SubmitHandler<T>;
1937
- onSuccess?: (data: T) => void;
1938
- resetButtonText?: string;
1939
- showResetButton?: boolean;
1940
- spacing?: "2" | "4" | "6" | "8" | "lg";
1941
- submitButtonProps?: Partial<React$1.ComponentProps<typeof Button>>;
1942
- submitButtonText?: string;
1943
- subtitle?: string;
1944
- title?: string;
1945
- }
1946
- /**
1947
- * ZodForm component for building type-safe forms with Zod validation.
1948
- *
1949
- * @description
1950
- * This component provides a complete form solution with automatic validation,
1951
- * error handling, and type safety. It integrates React Hook Form with Zod
1952
- * schemas and HeroUI components. The form automatically validates inputs based
1953
- * on the provided Zod schema and displays error messages inline.
1954
- *
1955
- * @template T - The form data type inferred from the Zod schema
1956
- *
1957
- * @param {ZodFormProps<T>} props - Component props
1958
- * @param {ZodFormConfig<T>} props.config - Form configuration with schema and fields
1959
- * @param {SubmitHandler<T>} props.onSubmit - Submit handler function called with validated data
1960
- * @param {string} [props.title] - Optional form title displayed above the form
1961
- * @param {string} [props.subtitle] - Optional form subtitle displayed below the title
1962
- * @param {"vertical"|"horizontal"|"grid"} [props.layout="vertical"] - Form layout style
1963
- * @param {1|2|3} [props.columns=1] - Number of columns for grid layout (only applies when layout="grid")
1964
- * @param {"2"|"4"|"6"|"8"|"lg"} [props.spacing="4"] - Spacing between form fields
1965
- * @param {string} [props.submitButtonText="Submit"] - Text for the submit button
1966
- * @param {boolean} [props.showResetButton=false] - Whether to show a reset button
1967
- * @param {string} [props.resetButtonText="Reset"] - Text for the reset button
1968
- * @param {(error: FormValidationError) => void} [props.onError] - Error callback for validation errors
1969
- * @param {(data: T) => void} [props.onSuccess] - Success callback called after successful submission
1970
- *
1971
- * @returns {JSX.Element} The rendered form component with validation and error handling
1972
- *
1973
- * @example
1974
- * ```tsx
1975
- * import { ZodForm, FormFieldHelpers } from "@rachelallyson/hero-hook-form";
1976
- * import { z } from "zod";
1977
- *
1978
- * const schema = z.object({
1979
- * email: z.string().email("Please enter a valid email"),
1980
- * name: z.string().min(2, "Name must be at least 2 characters"),
1981
- * message: z.string().min(10, "Message must be at least 10 characters"),
1982
- * });
1983
- *
1984
- * function ContactForm() {
1985
- * const handleSubmit = async (data) => {
1986
- * console.log("Form submitted:", data);
1987
- * // Handle form submission (e.g., API call)
1988
- * };
1989
- *
1990
- * return (
1991
- * <ZodForm
1992
- * config={{
1993
- * schema,
1994
- * fields: [
1995
- * FormFieldHelpers.input("name", "Name"),
1996
- * FormFieldHelpers.input("email", "Email", "email"),
1997
- * FormFieldHelpers.textarea("message", "Message"),
1998
- * ],
1999
- * }}
2000
- * onSubmit={handleSubmit}
2001
- * title="Contact Us"
2002
- * subtitle="Send us a message and we'll get back to you"
2003
- * />
2004
- * );
2005
- * }
2006
- * ```
2007
- *
2008
- * @example
2009
- * Grid layout with multiple columns:
2010
- * ```tsx
2011
- * <ZodForm
2012
- * config={{ schema, fields }}
2013
- * layout="grid"
2014
- * columns={2}
2015
- * spacing="6"
2016
- * />
2017
- * ```
2018
- *
2019
- * @see {@link Form} for the base form component without Zod
2020
- * @see {@link FormFieldHelpers} for field creation helpers
2021
- * @see {@link createBasicFormBuilder} for builder pattern alternative
2022
- * @category Components
2023
- */
2024
- 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;
2025
-
2026
- /**
2027
- * Hook for using Zod validation with React Hook Form
2028
- */
2029
- declare function useZodForm<TFieldValues extends FieldValues>(config: ZodFormConfig<TFieldValues>): react_hook_form.UseFormReturn<TFieldValues, any, TFieldValues>;
2030
- /**
2031
- * Helper function to create Zod form configurations
2032
- */
2033
- declare function createZodFormConfig<TFieldValues extends FieldValues>(schema: z.ZodSchema<TFieldValues>, fields: ZodFormFieldConfig<TFieldValues>[], defaultValues?: Partial<TFieldValues>): ZodFormConfig<TFieldValues>;
2034
-
2035
- /**
2036
- * Basic form field builder for creating form field configurations.
2037
- *
2038
- * @description
2039
- * Provides a fluent API for building form field configurations. This builder
2040
- * focuses on the most common use cases and eliminates the need for "as const"
2041
- * assertions. Use this for simple forms with standard field types.
2042
- *
2043
- * @template T - The form data type
2044
- *
2045
- * @example
2046
- * ```tsx
2047
- * import { createBasicFormBuilder } from "@rachelallyson/hero-hook-form";
2048
- *
2049
- * const fields = createBasicFormBuilder()
2050
- * .input("name", "Name")
2051
- * .input("email", "Email", "email")
2052
- * .textarea("message", "Message")
2053
- * .select("country", "Country", [
2054
- * { label: "US", value: "us" },
2055
- * { label: "CA", value: "ca" },
2056
- * ])
2057
- * .checkbox("newsletter", "Subscribe to newsletter")
2058
- * .build();
2059
- * ```
2060
- *
2061
- * @see {@link createAdvancedBuilder} for more advanced features
2062
- * @see {@link FormFieldHelpers} for helper function alternative
2063
- * @category Builders
2064
- */
2065
- declare class BasicFormBuilder<T extends FieldValues> {
2066
- private fields;
2067
- /**
2068
- * Add an input field
2069
- */
2070
- input(name: Path<T>, label: string, type?: "text" | "email" | "tel" | "password"): this;
2071
- /**
2072
- * Add a textarea field
2073
- */
2074
- textarea(name: Path<T>, label: string, placeholder?: string): this;
2075
- /**
2076
- * Add a select field
2077
- */
2078
- select(name: Path<T>, label: string, options: {
2079
- label: string;
2080
- value: string | number;
2081
- }[]): this;
2082
- /**
2083
- * Add an autocomplete field
2084
- */
2085
- autocomplete(name: Path<T>, label: string, items: {
2086
- label: string;
2087
- value: string | number;
2088
- }[], placeholder?: string): this;
2089
- /**
2090
- * Add a checkbox field
2091
- */
2092
- checkbox(name: Path<T>, label: string): this;
2093
- /**
2094
- * Add a content field for headers, questions, or custom content between fields
2095
- */
2096
- content(title?: string | null, description?: string | null, options?: {
2097
- render?: (field: {
2098
- form: any;
2099
- errors: any;
2100
- isSubmitting: boolean;
2101
- }) => React$1.ReactNode;
2102
- className?: string;
2103
- name?: Path<T>;
2104
- }): this;
2105
- /**
2106
- * Add a switch field
2107
- */
2108
- switch(name: Path<T>, label: string, description?: string): this;
2109
- /**
2110
- * Build the final field configuration array
2111
- */
2112
- build(): ZodFormFieldConfig<T>[];
2113
- }
2114
- /**
2115
- * Creates a basic form builder for simple form construction.
2116
- *
2117
- * @description
2118
- * Provides a fluent API for building form field configurations. Best for
2119
- * simple forms with standard field types. Returns a builder instance with
2120
- * chainable methods for adding fields.
2121
- *
2122
- * @template T - The form data type
2123
- *
2124
- * @returns {BasicFormBuilder<T>} Builder instance with chainable methods
2125
- *
2126
- * @example
2127
- * ```tsx
2128
- * import { createBasicFormBuilder } from "@rachelallyson/hero-hook-form";
2129
- *
2130
- * const fields = createBasicFormBuilder()
2131
- * .input("name", "Name")
2132
- * .input("email", "Email", "email")
2133
- * .textarea("message", "Message")
2134
- * .select("country", "Country", [
2135
- * { label: "US", value: "us" },
2136
- * { label: "CA", value: "ca" },
2137
- * ])
2138
- * .checkbox("newsletter", "Subscribe to newsletter")
2139
- * .build();
2140
- *
2141
- * // Use with ZodForm
2142
- * <ZodForm config={{ schema, fields }} onSubmit={handleSubmit} />
2143
- * ```
2144
- *
2145
- * @see {@link createAdvancedBuilder} for more advanced features
2146
- * @see {@link FormFieldHelpers} for helper function alternative
2147
- * @see {@link defineInferredForm} for type-inferred forms
2148
- * @category Builders
2149
- */
2150
- declare function createBasicFormBuilder<T extends FieldValues>(): BasicFormBuilder<T>;
2151
- /**
2152
- * Helper functions for creating form field configurations.
2153
- *
2154
- * @description
2155
- * Simple helper functions for common field types. This is the recommended
2156
- * approach for most use cases as it's straightforward and doesn't require
2157
- * method chaining. Each helper returns a field configuration object.
2158
- *
2159
- * @example
2160
- * ```tsx
2161
- * import { FormFieldHelpers } from "@rachelallyson/hero-hook-form";
2162
- *
2163
- * const fields = [
2164
- * FormFieldHelpers.input("name", "Name"),
2165
- * FormFieldHelpers.input("email", "Email", "email"),
2166
- * FormFieldHelpers.textarea("message", "Message"),
2167
- * FormFieldHelpers.select("country", "Country", [
2168
- * { label: "US", value: "us" },
2169
- * { label: "CA", value: "ca" },
2170
- * ]),
2171
- * FormFieldHelpers.checkbox("newsletter", "Subscribe to newsletter"),
2172
- * FormFieldHelpers.conditional(
2173
- * "phone",
2174
- * (values) => values.hasPhone === true,
2175
- * FormFieldHelpers.input("phone", "Phone Number", "tel")
2176
- * ),
2177
- * ];
2178
- * ```
2179
- *
2180
- * @see {@link createBasicFormBuilder} for builder pattern alternative
2181
- * @category Builders
2182
- */
2183
- declare const FormFieldHelpers: {
2184
- /**
2185
- * Create an autocomplete field
2186
- *
2187
- * @example
2188
- * ```tsx
2189
- * // Simple autocomplete
2190
- * FormFieldHelpers.autocomplete("country", "Country", options)
2191
- *
2192
- * // With placeholder
2193
- * FormFieldHelpers.autocomplete("country", "Country", options, "Search countries")
2194
- *
2195
- * // With full customization
2196
- * FormFieldHelpers.autocomplete("country", "Country", options, "Search countries", {
2197
- * classNames: { base: "custom-autocomplete" },
2198
- * allowsCustomValue: true
2199
- * })
2200
- * ```
2201
- */
2202
- autocomplete: <T extends FieldValues>(name: Path<T>, label: string, items: {
2203
- label: string;
2204
- value: string | number;
2205
- }[], placeholder?: string, autocompleteProps?: Omit<React$1.ComponentProps<typeof Autocomplete>, "selectedKey" | "onSelectionChange" | "inputValue" | "onInputChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled" | "children" | "items">) => ZodFormFieldConfig<T>;
2206
- /**
2207
- * Create a checkbox field
2208
- *
2209
- * @example
2210
- * ```tsx
2211
- * // Simple checkbox
2212
- * FormFieldHelpers.checkbox("newsletter", "Subscribe to newsletter")
2213
- *
2214
- * // With full customization
2215
- * FormFieldHelpers.checkbox("newsletter", "Subscribe to newsletter", {
2216
- * classNames: { base: "custom-checkbox" },
2217
- * size: "lg"
2218
- * })
2219
- * ```
2220
- */
2221
- checkbox: <T extends FieldValues>(name: Path<T>, label: string, checkboxProps?: Omit<React$1.ComponentProps<typeof Checkbox>, "isSelected" | "onValueChange" | "isInvalid" | "errorMessage" | "isDisabled">) => ZodFormFieldConfig<T>;
2222
- /**
2223
- * Create a conditional field that shows/hides based on form data
2224
- *
2225
- * @example
2226
- * ```tsx
2227
- * FormFieldHelpers.conditional(
2228
- * "phone",
2229
- * (values) => values.hasPhone === true,
2230
- * FormFieldHelpers.input("phone", "Phone Number", "tel")
2231
- * )
2232
- * ```
2233
- *
2234
- * @example
2235
- * With explicit type in condition function (similar to content helper pattern):
2236
- * ```tsx
2237
- * FormFieldHelpers.conditional(
2238
- * "options",
2239
- * (formData: Partial<z.infer<typeof fieldSchema>>) =>
2240
- * formData.fieldType === 'DROPDOWN',
2241
- * FormFieldHelpers.textarea("options", "Dropdown Options", "One per line")
2242
- * )
2243
- * ```
2244
- */
2245
- conditional: <T extends FieldValues = FieldValues>(name: Path<T>, condition: (formData: Partial<T>) => boolean, field: ZodFormFieldConfig<T>) => ZodFormFieldConfig<T>;
2246
- /**
2247
- * Create a content field for headers, questions, or custom content between fields
2248
- *
2249
- * @example
2250
- * ```tsx
2251
- * // Simple header
2252
- * FormFieldHelpers.content("Personal Information", "Please provide your details")
2253
- *
2254
- * // Custom render
2255
- * FormFieldHelpers.content(null, null, {
2256
- * render: () => <div>Custom content</div>
2257
- * })
2258
- * ```
2259
- */
2260
- content: <T extends FieldValues = FieldValues>(title?: string | null, description?: string | null, options?: {
2261
- render?: (field: {
2262
- form: UseFormReturn<T>;
2263
- errors: FieldErrors<T>;
2264
- isSubmitting: boolean;
2265
- }) => React$1.ReactNode;
2266
- className?: string;
2267
- name?: string;
2268
- }) => ZodFormFieldConfig<T>;
2269
- /**
2270
- * Create a date field
2271
- *
2272
- * @example
2273
- * ```tsx
2274
- * // Simple date field
2275
- * FormFieldHelpers.date("birthDate", "Birth Date")
2276
- *
2277
- * // With full customization
2278
- * FormFieldHelpers.date("birthDate", "Birth Date", {
2279
- * label: "Select your birth date",
2280
- * granularity: "day",
2281
- * minValue: new CalendarDate(1900, 1, 1)
2282
- * })
2283
- * ```
2284
- */
2285
- date: <T extends FieldValues>(name: Path<T>, label: string, dateProps?: Omit<React$1.ComponentProps<typeof DateInput>, "value" | "onChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled">) => ZodFormFieldConfig<T>;
2286
- /**
2287
- * Create a file upload field
2288
- *
2289
- * @example
2290
- * ```tsx
2291
- * // Simple file field
2292
- * FormFieldHelpers.file("avatar", "Profile Picture")
2293
- *
2294
- * // With accept and multiple
2295
- * FormFieldHelpers.file("avatar", "Profile Picture", {
2296
- * accept: "image/*",
2297
- * multiple: true
2298
- * })
2299
- *
2300
- * // With full customization
2301
- * FormFieldHelpers.file("avatar", "Profile Picture", {
2302
- * accept: "image/*",
2303
- * multiple: false,
2304
- * fileProps: { className: "custom-file-input" }
2305
- * })
2306
- * ```
2307
- */
2308
- file: <T extends FieldValues>(name: Path<T>, label: string, options?: {
2309
- accept?: string;
2310
- fileProps?: Omit<React$1.ComponentProps<typeof Input>, "value" | "onValueChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled" | "type">;
2311
- multiple?: boolean;
2312
- }) => ZodFormFieldConfig<T>;
2313
- /**
2314
- * Create a font picker field
2315
- *
2316
- * @example
2317
- * ```tsx
2318
- * // Simple font picker
2319
- * FormFieldHelpers.fontPicker("font", "Choose Font")
2320
- *
2321
- * // With full customization
2322
- * FormFieldHelpers.fontPicker("font", "Choose Font", {
2323
- * showFontPreview: true,
2324
- * loadAllVariants: false,
2325
- * fontsLoadedTimeout: 5000
2326
- * })
2327
- * ```
2328
- */
2329
- fontPicker: <T extends FieldValues>(name: Path<T>, label: string, fontPickerProps?: {
2330
- showFontPreview?: boolean;
2331
- loadAllVariants?: boolean;
2332
- onFontsLoaded?: (loaded: boolean) => void;
2333
- fontsLoadedTimeout?: number;
2334
- }) => ZodFormFieldConfig<T>;
2335
- /**
2336
- * Create an input field
2337
- *
2338
- * @example
2339
- * ```tsx
2340
- * // Simple input
2341
- * FormFieldHelpers.input("name", "Name")
2342
- *
2343
- * // With type
2344
- * FormFieldHelpers.input("email", "Email", "email")
2345
- *
2346
- * // With full customization
2347
- * FormFieldHelpers.input("email", "Email", "email", {
2348
- * placeholder: "Enter your email",
2349
- * classNames: { input: "custom-input" },
2350
- * startContent: <MailIcon />,
2351
- * description: "We'll never share your email"
2352
- * })
2353
- * ```
2354
- */
2355
- 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>;
2356
- /**
2357
- * Create a radio group field
2358
- *
2359
- * @example
2360
- * ```tsx
2361
- * // Simple radio group
2362
- * FormFieldHelpers.radio("gender", "Gender", [
2363
- * { label: "Male", value: "male" },
2364
- * { label: "Female", value: "female" }
2365
- * ])
2366
- *
2367
- * // With full customization
2368
- * FormFieldHelpers.radio("gender", "Gender", options, {
2369
- * orientation: "horizontal",
2370
- * classNames: { base: "custom-radio" }
2371
- * })
2372
- * ```
2373
- */
2374
- radio: <T extends FieldValues>(name: Path<T>, label: string, options: {
2375
- label: string;
2376
- value: string | number;
2377
- }[], radioProps?: Omit<React$1.ComponentProps<typeof RadioGroup>, "value" | "onValueChange" | "label">) => ZodFormFieldConfig<T>;
2378
- /**
2379
- * Create a select field
2380
- *
2381
- * @example
2382
- * ```tsx
2383
- * // Simple select
2384
- * FormFieldHelpers.select("country", "Country", options)
2385
- *
2386
- * // With full customization
2387
- * FormFieldHelpers.select("country", "Country", options, {
2388
- * placeholder: "Select a country",
2389
- * classNames: { trigger: "custom-select" },
2390
- * selectionMode: "multiple"
2391
- * })
2392
- * ```
2393
- */
2394
- select: <T extends FieldValues>(name: Path<T>, label: string, options: {
2395
- label: string;
2396
- value: string | number;
2397
- }[], selectProps?: Omit<React$1.ComponentProps<typeof Select>, "selectedKeys" | "onSelectionChange" | "label" | "isInvalid" | "errorMessage" | "isDisabled">) => ZodFormFieldConfig<T>;
2398
- /**
2399
- * Create a slider field
2400
- *
2401
- * @example
2402
- * ```tsx
2403
- * // Simple slider
2404
- * FormFieldHelpers.slider("rating", "Rating")
2405
- *
2406
- * // With full customization
2407
- * FormFieldHelpers.slider("rating", "Rating", {
2408
- * minValue: 1,
2409
- * maxValue: 5,
2410
- * step: 1,
2411
- * showSteps: true,
2412
- * classNames: { base: "custom-slider" }
2413
- * })
2414
- * ```
2415
- */
2416
- slider: <T extends FieldValues>(name: Path<T>, label: string, sliderProps?: Omit<React$1.ComponentProps<typeof Slider>, "value" | "onChange" | "label" | "isDisabled">) => ZodFormFieldConfig<T>;
2417
- /**
2418
- * Create a switch field
2419
- *
2420
- * @example
2421
- * ```tsx
2422
- * // Simple switch
2423
- * FormFieldHelpers.switch("notifications", "Enable notifications")
2424
- *
2425
- * // With description
2426
- * FormFieldHelpers.switch("notifications", "Enable notifications", "Receive email notifications")
2427
- *
2428
- * // With full customization
2429
- * FormFieldHelpers.switch("notifications", "Enable notifications", "Receive email notifications", {
2430
- * classNames: { base: "custom-switch" },
2431
- * size: "lg",
2432
- * color: "primary"
2433
- * })
2434
- * ```
2435
- */
2436
- 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>;
2437
- /**
2438
- * Create a textarea field
2439
- *
2440
- * @example
2441
- * ```tsx
2442
- * // Simple textarea
2443
- * FormFieldHelpers.textarea("message", "Message")
2444
- *
2445
- * // With placeholder
2446
- * FormFieldHelpers.textarea("message", "Message", "Enter your message")
2447
- *
2448
- * // With full customization
2449
- * FormFieldHelpers.textarea("message", "Message", "Enter your message", {
2450
- * classNames: { input: "custom-textarea" },
2451
- * minRows: 3,
2452
- * maxRows: 10
2453
- * })
2454
- * ```
2455
- */
2456
- 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>;
2457
- };
2458
- /**
2459
- * Common field collections
2460
- */
2461
- declare const CommonFields: {
2462
- /**
2463
- * Address fields
2464
- */
2465
- address: <T extends FieldValues>() => ZodFormFieldConfig<T>[];
2466
- /**
2467
- * Personal information fields
2468
- */
2469
- personal: <T extends FieldValues>() => ZodFormFieldConfig<T>[];
2470
- /**
2471
- * Terms and conditions fields
2472
- */
2473
- terms: <T extends FieldValues>() => ZodFormFieldConfig<T>[];
2474
- };
2475
-
2476
- /**
2477
- * Unified field creation function
2478
- * Takes field type as first argument and delegates to appropriate helper
2479
- */
2480
- declare function createField<T extends FieldValues>(type: string, name: Path<T>, label: string, optionsOrProps?: any, props?: any): ZodFormFieldConfig<T>;
2481
- /**
2482
- * Builder pattern for advanced field creation
2483
- */
2484
- declare class AdvancedFieldBuilder<T extends FieldValues> {
2485
- private fields;
2486
- /**
2487
- * Add any field type using the unified API
2488
- */
2489
- field(type: "input", name: Path<T>, label: string, props?: Parameters<typeof createField<T>>[3]): this;
2490
- field(type: "textarea", name: Path<T>, label: string, props?: Parameters<typeof createField<T>>[3]): this;
2491
- field(type: "select", name: Path<T>, label: string, options: {
2492
- label: string;
2493
- value: string | number;
2494
- }[], props?: Parameters<typeof createField<T>>[4]): this;
2495
- field(type: "checkbox", name: Path<T>, label: string, props?: Parameters<typeof createField<T>>[3]): this;
2496
- field(type: "switch", name: Path<T>, label: string, props?: Parameters<typeof createField<T>>[3]): this;
2497
- field(type: "radio", name: Path<T>, label: string, options: {
2498
- label: string;
2499
- value: string | number;
2500
- }[], props?: Parameters<typeof createField<T>>[4]): this;
2501
- field(type: "slider", name: Path<T>, label: string, props?: Parameters<typeof createField<T>>[3]): this;
2502
- field(type: "date", name: Path<T>, label: string, props?: Parameters<typeof createField<T>>[3]): this;
2503
- field(type: "file", name: Path<T>, label: string, props?: Parameters<typeof createField<T>>[3]): this;
2504
- /**
2505
- * Add a conditional field that shows/hides based on form data
2506
- */
2507
- conditionalField(name: Path<T>, condition: (formData: Partial<T>) => boolean, field: ZodFormFieldConfig<T>): this;
2508
- /**
2509
- * Add a field array for dynamic repeating field groups
2510
- */
2511
- fieldArray(name: Path<T>, label: string, fields: ZodFormFieldConfig<any>[], options?: {
2512
- min?: number;
2513
- max?: number;
2514
- addButtonText?: string;
2515
- removeButtonText?: string;
2516
- }): this;
2517
- /**
2518
- * Add a dynamic section that shows/hides based on form data
2519
- */
2520
- dynamicSection(name: Path<T>, condition: (formData: Partial<T>) => boolean, fields: ZodFormFieldConfig<T>[], options?: {
2521
- title?: string;
2522
- description?: string;
2523
- }): this;
2524
- /**
2525
- * Build the final field configuration array
2526
- */
2527
- build(): ZodFormFieldConfig<T>[];
2528
- }
2529
- /**
2530
- * Field Array Builder for strongly-typed array item fields
2531
- */
2532
- declare class FieldArrayItemBuilder<TItem extends FieldValues> {
2533
- private fields;
2534
- /**
2535
- * Add any field type using the unified API for array items
2536
- */
2537
- field(type: "input", name: Path<TItem>, label: string, props?: Parameters<typeof createField<TItem>>[3]): this;
2538
- field(type: "textarea", name: Path<TItem>, label: string, props?: Parameters<typeof createField<TItem>>[3]): this;
2539
- field(type: "select", name: Path<TItem>, label: string, options: {
2540
- label: string;
2541
- value: string | number;
2542
- }[], props?: Parameters<typeof createField<TItem>>[4]): this;
2543
- field(type: "checkbox", name: Path<TItem>, label: string, props?: Parameters<typeof createField<TItem>>[3]): this;
2544
- field(type: "switch", name: Path<TItem>, label: string, props?: Parameters<typeof createField<TItem>>[3]): this;
2545
- field(type: "radio", name: Path<TItem>, label: string, options: {
2546
- label: string;
2547
- value: string | number;
2548
- }[], props?: Parameters<typeof createField<TItem>>[4]): this;
2549
- field(type: "slider", name: Path<TItem>, label: string, props?: Parameters<typeof createField<TItem>>[3]): this;
2550
- field(type: "date", name: Path<TItem>, label: string, props?: Parameters<typeof createField<TItem>>[3]): this;
2551
- field(type: "file", name: Path<TItem>, label: string, props?: Parameters<typeof createField<TItem>>[3]): this;
2552
- field(type: "fontPicker", name: Path<TItem>, label: string, props?: Parameters<typeof createField<TItem>>[3]): this;
2553
- /**
2554
- * Build the field array item configuration
2555
- */
2556
- build(): ZodFormFieldConfig<TItem>[];
2557
- }
2558
- /**
2559
- * Create a field array item builder for strongly-typed array fields
2560
- */
2561
- declare function createFieldArrayItemBuilder<TItem extends FieldValues>(): FieldArrayItemBuilder<TItem>;
2562
- /**
2563
- * Field Array Builder for constructing field arrays with proper paths
2564
- */
2565
- declare class FieldArrayBuilder<T extends FieldValues, TArrayName extends Path<T>> {
2566
- private arrayName;
2567
- private fields;
2568
- constructor(arrayName: TArrayName);
2569
- field(type: string, name: string, label: string, optionsOrProps?: any, props?: any): this;
2570
- build(): ZodFormFieldConfig<any>[];
2571
- }
2572
- /**
2573
- * Create a field array builder that constructs proper paths for array items
2574
- */
2575
- declare function createFieldArrayBuilder<T extends FieldValues, TArrayName extends Path<T>>(arrayName: TArrayName): FieldArrayBuilder<T, TArrayName>;
2576
- /**
2577
- * Create a new advanced field builder
2578
- */
2579
- declare function createAdvancedBuilder<T extends FieldValues>(): AdvancedFieldBuilder<T>;
2580
-
2581
- /**
2582
- * Type-inferred form builder that auto-generates both schema and field configs
2583
- */
2584
- declare class TypeInferredBuilder<T extends FieldValues> {
2585
- private schemaFields;
2586
- private formFields;
2587
- /**
2588
- * Add a text field
2589
- */
2590
- text(name: Path<T>, label: string, options?: {
2591
- placeholder?: string;
2592
- description?: string;
2593
- isDisabled?: boolean;
2594
- className?: string;
2595
- minLength?: number;
2596
- maxLength?: number;
2597
- pattern?: string;
2598
- }): this;
2599
- /**
2600
- * Add an email field
2601
- */
2602
- email(name: Path<T>, label: string, options?: {
2603
- placeholder?: string;
2604
- description?: string;
2605
- isDisabled?: boolean;
2606
- className?: string;
2607
- }): this;
2608
- /**
2609
- * Add a number field
2610
- */
2611
- number(name: Path<T>, label: string, options?: {
2612
- placeholder?: string;
2613
- description?: string;
2614
- isDisabled?: boolean;
2615
- className?: string;
2616
- min?: number;
2617
- max?: number;
2618
- step?: number;
2619
- }): this;
2620
- /**
2621
- * Add a textarea field
2622
- */
2623
- textarea(name: Path<T>, label: string, options?: {
2624
- placeholder?: string;
2625
- description?: string;
2626
- isDisabled?: boolean;
2627
- className?: string;
2628
- rows?: number;
2629
- minLength?: number;
2630
- }): this;
2631
- /**
2632
- * Add a select field
2633
- */
2634
- select(name: Path<T>, label: string, options: {
2635
- label: string;
2636
- value: string | number;
2637
- }[]): this;
2638
- /**
2639
- * Add a checkbox field
2640
- */
2641
- checkbox(name: Path<T>, label: string, options?: {
2642
- description?: string;
2643
- isDisabled?: boolean;
2644
- className?: string;
2645
- required?: boolean;
2646
- }): this;
2647
- /**
2648
- * Add a switch field
2649
- */
2650
- switch(name: Path<T>, label: string, options?: {
2651
- description?: string;
2652
- isDisabled?: boolean;
2653
- className?: string;
2654
- }): this;
2655
- /**
2656
- * Add a radio field
2657
- */
2658
- radio(name: Path<T>, label: string, options: {
2659
- label: string;
2660
- value: string | number;
2661
- }[], fieldOptions?: {
2662
- description?: string;
2663
- isDisabled?: boolean;
2664
- className?: string;
2665
- orientation?: "horizontal" | "vertical";
2666
- }): this;
2667
- /**
2668
- * Add a slider field
2669
- */
2670
- slider(name: Path<T>, label: string, options?: {
2671
- min?: number;
2672
- max?: number;
2673
- step?: number;
2674
- description?: string;
2675
- isDisabled?: boolean;
2676
- className?: string;
2677
- }): this;
2678
- /**
2679
- * Add a date field
2680
- */
2681
- date(name: Path<T>, label: string, options?: {
2682
- placeholder?: string;
2683
- description?: string;
2684
- isDisabled?: boolean;
2685
- className?: string;
2686
- }): this;
2687
- /**
2688
- * Add a file field
2689
- */
2690
- file(name: Path<T>, label: string, options?: {
2691
- accept?: string;
2692
- multiple?: boolean;
2693
- description?: string;
2694
- isDisabled?: boolean;
2695
- className?: string;
2696
- }): this;
2697
- /**
2698
- * Build the final schema and fields
2699
- */
2700
- build(): {
2701
- schema: z.ZodSchema<T>;
2702
- fields: ZodFormFieldConfig<T>[];
2703
- };
2704
- }
2705
- /**
2706
- * Create a new type-inferred form builder
2707
- */
2708
- declare function createTypeInferredBuilder<T extends FieldValues>(): TypeInferredBuilder<T>;
2709
- /**
2710
- * Define a form with type inference
2711
- */
2712
- declare function defineInferredForm<T extends FieldValues>(fieldDefinitions: (builder: TypeInferredBuilder<T>) => TypeInferredBuilder<T>): {
2713
- schema: z.ZodSchema<T>;
2714
- fields: ZodFormFieldConfig<T>[];
2715
- };
2716
- /**
2717
- * Field type builders for individual field creation
2718
- */
2719
- declare const field: {
2720
- checkbox: <T extends FieldValues>(name: Path<T>, label: string, options?: Parameters<TypeInferredBuilder<T>["checkbox"]>[2]) => TypeInferredBuilder<T>;
2721
- date: <T extends FieldValues>(name: Path<T>, label: string, options?: Parameters<TypeInferredBuilder<T>["date"]>[2]) => TypeInferredBuilder<T>;
2722
- email: <T extends FieldValues>(name: Path<T>, label: string, options?: Parameters<TypeInferredBuilder<T>["email"]>[2]) => TypeInferredBuilder<T>;
2723
- file: <T extends FieldValues>(name: Path<T>, label: string, options?: Parameters<TypeInferredBuilder<T>["file"]>[2]) => TypeInferredBuilder<T>;
2724
- number: <T extends FieldValues>(name: Path<T>, label: string, options?: Parameters<TypeInferredBuilder<T>["number"]>[2]) => TypeInferredBuilder<T>;
2725
- radio: <T extends FieldValues>(name: Path<T>, label: string, options: {
2726
- label: string;
2727
- value: string | number;
2728
- }[], fieldOptions?: Parameters<TypeInferredBuilder<T>["radio"]>[3]) => TypeInferredBuilder<T>;
2729
- select: <T extends FieldValues>(name: Path<T>, label: string, options: {
2730
- label: string;
2731
- value: string | number;
2732
- }[]) => TypeInferredBuilder<T>;
2733
- slider: <T extends FieldValues>(name: Path<T>, label: string, options?: Parameters<TypeInferredBuilder<T>["slider"]>[2]) => TypeInferredBuilder<T>;
2734
- switch: <T extends FieldValues>(name: Path<T>, label: string, options?: Parameters<TypeInferredBuilder<T>["switch"]>[2]) => TypeInferredBuilder<T>;
2735
- text: <T extends FieldValues>(name: Path<T>, label: string, options?: Parameters<TypeInferredBuilder<T>["text"]>[2]) => TypeInferredBuilder<T>;
2736
- textarea: <T extends FieldValues>(name: Path<T>, label: string, options?: Parameters<TypeInferredBuilder<T>["textarea"]>[2]) => TypeInferredBuilder<T>;
2737
- };
2738
-
2739
- /**
2740
- * Enhanced nested path builder with better syntax for complex nested structures
2741
- * Provides multiple approaches for handling nested field paths
2742
- */
2743
- declare class NestedPathBuilder<T extends FieldValues> {
2744
- private fields;
2745
- /**
2746
- * Create a nested object path builder
2747
- * Usage: builder.nest("address").field("street", "Street Address")
2748
- */
2749
- nest<TPath extends Path<T>>(path: TPath): NestedObjectBuilder<T, TPath>;
2750
- /**
2751
- * Create a section-based path builder
2752
- * Usage: builder.section("shipping").field("street", "Street Address")
2753
- */
2754
- section<TPath extends Path<T>>(path: TPath): SectionBuilder<T, TPath>;
2755
- /**
2756
- * Add a field with single path
2757
- * Usage: builder.field("firstName", "First Name")
2758
- */
2759
- field(name: Path<T>, label: string, type?: string, props?: any): this;
2760
- /**
2761
- * Add a field with path segments
2762
- * Usage: builder.fieldPath(["user", "profile", "name"], "Full Name")
2763
- */
2764
- fieldPath(path: string[], label: string, type?: string, props?: any): this;
2765
- /**
2766
- * Add a field with template literal path
2767
- * Usage: builder.field`user.profile.name`("Full Name")
2768
- */
2769
- fieldTemplate(path: TemplateStringsArray): FieldTemplateBuilder<T>;
2770
- /**
2771
- * Return to the parent builder (no-op for root builder)
2772
- */
2773
- end(): this;
2774
- build(): ZodFormFieldConfig<T>[];
2775
- }
2776
- /**
2777
- * Nested object builder for chaining nested paths
2778
- */
2779
- declare class NestedObjectBuilder<T extends FieldValues, TPath extends Path<T>> {
2780
- private parent;
2781
- private path;
2782
- constructor(parent: NestedPathBuilder<T>, path: TPath);
2783
- /**
2784
- * Add a field to the current nested path
2785
- */
2786
- field<FName extends string>(fieldName: FName, label: string, type?: string, props?: any): NestedObjectBuilder<T, TPath>;
2787
- /**
2788
- * Nest deeper into the object
2789
- */
2790
- nest<SubPath extends string>(subPath: SubPath): NestedObjectBuilder<T, TPath>;
2791
- /**
2792
- * Return to the parent builder
2793
- */
2794
- end(): NestedPathBuilder<T>;
2795
- }
2796
- /**
2797
- * Section builder for grouping related fields
2798
- */
2799
- declare class SectionBuilder<T extends FieldValues, TPath extends Path<T>> {
2800
- private parent;
2801
- private path;
2802
- constructor(parent: NestedPathBuilder<T>, path: TPath);
2803
- /**
2804
- * Add a field to the current section
2805
- */
2806
- field<FName extends string>(fieldName: FName, label: string, type?: string, props?: any): SectionBuilder<T, TPath>;
2807
- /**
2808
- * Add multiple fields to the section
2809
- */
2810
- fields(fieldDefinitions: {
2811
- name: string;
2812
- label: string;
2813
- type?: string;
2814
- props?: any;
2815
- }[]): SectionBuilder<T, TPath>;
2816
- /**
2817
- * Nest deeper into the section
2818
- */
2819
- nest<SubPath extends string>(subPath: SubPath): NestedObjectBuilder<T, TPath>;
2820
- /**
2821
- * Return to the parent builder
2822
- */
2823
- end(): NestedPathBuilder<T>;
2824
- }
2825
- /**
2826
- * Template literal field builder
2827
- */
2828
- declare class FieldTemplateBuilder<T extends FieldValues> {
2829
- private parent;
2830
- private path;
2831
- constructor(parent: NestedPathBuilder<T>, path: string);
2832
- /**
2833
- * Complete the field definition
2834
- */
2835
- complete(label: string, type?: string, props?: any): NestedPathBuilder<T>;
2836
- }
2837
- /**
2838
- * Factory function for creating the nested path builder
2839
- */
2840
- declare function createNestedPathBuilder<T extends FieldValues>(): NestedPathBuilder<T>;
2841
-
2842
- /**
2843
- * Options for the useDebouncedValidation hook.
2844
- */
2845
- interface UseDebouncedValidationOptions {
2846
- delay?: number;
2847
- fields?: string[];
2848
- enabled?: boolean;
2849
- }
2850
- /**
2851
- * Hook for debouncing form validation to improve performance.
2852
- *
2853
- * @description
2854
- * Delays validation until the user stops typing, reducing unnecessary
2855
- * validation calls and improving form performance. Useful for forms with
2856
- * expensive validation logic or many fields.
2857
- *
2858
- * @template T - The form data type
2859
- *
2860
- * @param {UseFormReturn<T>} form - React Hook Form instance
2861
- * @param {UseDebouncedValidationOptions} [options] - Configuration options
2862
- * @param {number} [options.delay=300] - Delay in milliseconds before validation
2863
- * @param {string[]} [options.fields] - Specific fields to watch (if not provided, watches all)
2864
- * @param {boolean} [options.enabled=true] - Whether debouncing is enabled
2865
- *
2866
- * @returns {Object} Debounced validation utilities
2867
- * @returns {() => void} debouncedTrigger - Function to trigger debounced validation
2868
- * @returns {boolean} isDebouncing - Whether validation is currently debouncing
2869
- *
2870
- * @example
2871
- * ```tsx
2872
- * import { useDebouncedValidation } from "@rachelallyson/hero-hook-form";
2873
- * import { useForm } from "react-hook-form";
2874
- *
2875
- * function MyForm() {
2876
- * const form = useForm();
2877
- * const { debouncedTrigger, isDebouncing } = useDebouncedValidation(form, {
2878
- * delay: 500,
2879
- * fields: ["email", "username"], // Only watch these fields
2880
- * });
2881
- *
2882
- * return (
2883
- * <form>
2884
- * <input
2885
- * {...form.register("email")}
2886
- * onChange={(e) => {
2887
- * form.setValue("email", e.target.value);
2888
- * debouncedTrigger();
2889
- * }}
2890
- * />
2891
- * {isDebouncing && <span>Validating...</span>}
2892
- * </form>
2893
- * );
2894
- * }
2895
- * ```
2896
- *
2897
- * @see {@link useDebouncedFieldValidation} for single field debouncing
2898
- * @category Hooks
2899
- */
2900
- declare function useDebouncedValidation<T extends Record<string, any>>(form: UseFormReturn<T>, options?: UseDebouncedValidationOptions): {
2901
- debouncedTrigger: () => void;
2902
- isDebouncing: boolean;
2903
- };
2904
- /**
2905
- * Hook for debouncing validation of a single field.
2906
- *
2907
- * @description
2908
- * Similar to useDebouncedValidation but optimized for a single field.
2909
- * Automatically triggers validation when the specified field changes.
2910
- *
2911
- * @template T - The form data type
2912
- *
2913
- * @param {UseFormReturn<T>} form - React Hook Form instance
2914
- * @param {keyof T} fieldName - Name of the field to debounce
2915
- * @param {Object} [options] - Configuration options
2916
- * @param {number} [options.delay=300] - Delay in milliseconds before validation
2917
- * @param {boolean} [options.enabled=true] - Whether debouncing is enabled
2918
- *
2919
- * @returns {Object} Debounced field validation utilities
2920
- * @returns {() => void} debouncedFieldTrigger - Function to trigger debounced validation for this field
2921
- * @returns {boolean} isDebouncing - Whether validation is currently debouncing
2922
- *
2923
- * @example
2924
- * ```tsx
2925
- * import { useDebouncedFieldValidation } from "@rachelallyson/hero-hook-form";
2926
- * import { useForm } from "react-hook-form";
2927
- *
2928
- * function MyForm() {
2929
- * const form = useForm();
2930
- * const { debouncedFieldTrigger, isDebouncing } = useDebouncedFieldValidation(
2931
- * form,
2932
- * "email",
2933
- * { delay: 500 }
2934
- * );
2935
- *
2936
- * return (
2937
- * <input
2938
- * {...form.register("email")}
2939
- * onChange={(e) => {
2940
- * form.setValue("email", e.target.value);
2941
- * debouncedFieldTrigger();
2942
- * }}
2943
- * />
2944
- * );
2945
- * }
2946
- * ```
2947
- *
2948
- * @see {@link useDebouncedValidation} for multiple fields
2949
- * @category Hooks
2950
- */
2951
- declare function useDebouncedFieldValidation<T extends Record<string, any>>(form: UseFormReturn<T>, fieldName: keyof T, options?: {
2952
- delay?: number;
2953
- enabled?: boolean;
2954
- }): {
2955
- debouncedFieldTrigger: () => void;
2956
- isDebouncing: boolean;
2957
- };
2958
-
2959
- /**
2960
- * Options for the useInferredForm hook.
2961
- *
2962
- * @template T - The form data type
2963
- */
2964
- interface UseInferredFormOptions<T extends FieldValues> {
2965
- defaultValues?: Partial<T>;
2966
- mode?: "onChange" | "onBlur" | "onSubmit" | "onTouched" | "all";
2967
- reValidateMode?: "onChange" | "onBlur" | "onSubmit";
2968
- shouldFocusError?: boolean;
2969
- shouldUnregister?: boolean;
2970
- delayError?: number;
2971
- }
2972
- /**
2973
- * Hook for creating a form instance from an inferred form configuration.
2974
- *
2975
- * @description
2976
- * Creates a React Hook Form instance with Zod validation resolver
2977
- * from a type-inferred form configuration. Automatically sets up
2978
- * validation based on the provided schema and fields.
2979
- *
2980
- * @template T - The form data type
2981
- *
2982
- * @param {any} schema - Zod schema for validation
2983
- * @param {ZodFormFieldConfig<T>[]} fields - Field configurations
2984
- * @param {UseInferredFormOptions<T>} [options] - Form options
2985
- * @param {Partial<T>} [options.defaultValues] - Default form values
2986
- * @param {"onChange"|"onBlur"|"onSubmit"|"onTouched"|"all"} [options.mode="onChange"] - Validation mode
2987
- * @param {"onChange"|"onBlur"|"onSubmit"} [options.reValidateMode="onChange"] - Re-validation mode
2988
- * @param {boolean} [options.shouldFocusError=true] - Focus first error field
2989
- * @param {boolean} [options.shouldUnregister=false] - Unregister fields on unmount
2990
- * @param {number} [options.delayError=0] - Delay before showing errors
2991
- *
2992
- * @returns {UseFormReturn<T>} React Hook Form instance
2993
- *
2994
- * @example
2995
- * ```tsx
2996
- * import { useInferredForm, defineInferredForm, field } from "@rachelallyson/hero-hook-form";
2997
- *
2998
- * const formConfig = defineInferredForm({
2999
- * name: field.string("Name").min(2),
3000
- * email: field.email("Email"),
3001
- * });
3002
- *
3003
- * function MyForm() {
3004
- * const form = useInferredForm(
3005
- * formConfig.schema,
3006
- * formConfig.fields,
3007
- * { mode: "onBlur" }
3008
- * );
3009
- *
3010
- * return (
3011
- * <form onSubmit={form.handleSubmit(handleSubmit)}>
3012
- * {/* form fields *\/}
3013
- * </form>
3014
- * );
3015
- * }
3016
- * ```
3017
- *
3018
- * @see {@link defineInferredForm} for creating type-inferred form configurations
3019
- * @see {@link useTypeInferredForm} for alternative API
3020
- * @category Hooks
3021
- */
3022
- declare function useInferredForm<T extends FieldValues>(schema: any, fields: ZodFormFieldConfig<T>[], options?: UseInferredFormOptions<T>): UseFormReturn<T>;
3023
- /**
3024
- * Hook that works with type-inferred form configurations.
3025
- *
3026
- * @description
3027
- * Alternative API for useInferredForm that accepts a form configuration
3028
- * object instead of separate schema and fields parameters. Useful when
3029
- * working with defineInferredForm results.
3030
- *
3031
- * @template T - The form data type
3032
- *
3033
- * @param {Object} formConfig - Form configuration object
3034
- * @param {any} formConfig.schema - Zod schema for validation
3035
- * @param {ZodFormFieldConfig<T>[]} formConfig.fields - Field configurations
3036
- * @param {UseInferredFormOptions<T>} [options] - Form options
3037
- *
3038
- * @returns {UseFormReturn<T>} React Hook Form instance
3039
- *
3040
- * @example
3041
- * ```tsx
3042
- * import { useTypeInferredForm, defineInferredForm, field } from "@rachelallyson/hero-hook-form";
3043
- *
3044
- * const formConfig = defineInferredForm({
3045
- * name: field.string("Name").min(2),
3046
- * email: field.email("Email"),
3047
- * });
3048
- *
3049
- * function MyForm() {
3050
- * const form = useTypeInferredForm(formConfig);
3051
- *
3052
- * return (
3053
- * <form onSubmit={form.handleSubmit(handleSubmit)}>
3054
- * {/* form fields *\/}
3055
- * </form>
3056
- * );
3057
- * }
3058
- * ```
3059
- *
3060
- * @see {@link useInferredForm} for direct schema/fields API
3061
- * @see {@link defineInferredForm} for creating type-inferred form configurations
3062
- * @category Hooks
3063
- */
3064
- declare function useTypeInferredForm<T extends FieldValues>(formConfig: {
3065
- schema: any;
3066
- fields: ZodFormFieldConfig<T>[];
3067
- }, options?: UseInferredFormOptions<T>): UseFormReturn<T>;
3068
-
3069
- /**
3070
- * Props for the ConditionalField component.
3071
- *
3072
- * @template TFieldValues - The form data type
3073
- */
3074
- interface ConditionalFieldProps<TFieldValues extends FieldValues> {
3075
- config: ConditionalFieldConfig<TFieldValues>;
3076
- control: Control<TFieldValues>;
3077
- className?: string;
3078
- }
3079
- /**
3080
- * Conditional field component that shows/hides fields based on form values.
3081
- *
3082
- * @description
3083
- * Renders a field only when a condition function returns true based on
3084
- * current form values. Useful for creating dynamic forms that adapt to
3085
- * user input. The field is completely removed from the DOM when hidden.
3086
- *
3087
- * @template TFieldValues - The form data type
3088
- *
3089
- * @param {ConditionalFieldProps<TFieldValues>} props - Component props
3090
- * @param {ConditionalFieldConfig<TFieldValues>} props.config - Conditional field configuration
3091
- * @param {Control<TFieldValues>} props.control - React Hook Form control
3092
- * @param {string} [props.className] - Additional CSS class name
3093
- *
3094
- * @returns {JSX.Element|null} The rendered field or null if condition is not met
3095
- *
3096
- * @example
3097
- * ```tsx
3098
- * import { ConditionalField, FormFieldHelpers } from "@rachelallyson/hero-hook-form";
3099
- *
3100
- * const fields = [
3101
- * FormFieldHelpers.checkbox("hasPhone", "I have a phone number"),
3102
- * ConditionalField({
3103
- * config: {
3104
- * name: "phone",
3105
- * condition: (values) => values.hasPhone === true,
3106
- * field: FormFieldHelpers.input("phone", "Phone Number", "tel"),
3107
- * },
3108
- * control: form.control,
3109
- * }),
3110
- * ];
3111
- * ```
3112
- *
3113
- * @example
3114
- * Multiple conditions:
3115
- * ```tsx
3116
- * ConditionalField({
3117
- * config: {
3118
- * name: "businessDetails",
3119
- * condition: (values) =>
3120
- * values.userType === "business" && values.isRegistered === true,
3121
- * field: FormFieldHelpers.input("taxId", "Tax ID"),
3122
- * },
3123
- * control: form.control,
3124
- * }),
3125
- * ```
3126
- *
3127
- * @see {@link DynamicSectionField} for grouping multiple conditional fields
3128
- * @see {@link FieldArrayField} for repeating fields
3129
- * @category Fields
3130
- */
3131
- declare function ConditionalField<TFieldValues extends FieldValues>({ className, config, control, }: ConditionalFieldProps<TFieldValues>): React$1.JSX.Element | null;
3132
-
3133
- interface ContentFieldProps<TFieldValues extends FieldValues> {
3134
- config: ContentFieldConfig<TFieldValues>;
3135
- form: UseFormReturn<TFieldValues>;
3136
- submissionState: FormSubmissionState;
3137
- }
3138
- declare function ContentField<TFieldValues extends FieldValues>({ config, form, submissionState, }: ContentFieldProps<TFieldValues>): React$1.JSX.Element;
3139
-
3140
- /**
3141
- * Props for the FieldArrayField component.
3142
- *
3143
- * @template TFieldValues - The form data type
3144
- */
3145
- interface FieldArrayFieldProps<TFieldValues extends FieldValues> {
3146
- config: FieldArrayConfig<TFieldValues>;
3147
- className?: string;
3148
- }
3149
- /**
3150
- * Field array component for dynamic repeating field groups.
3151
- *
3152
- * @description
3153
- * Allows users to add and remove multiple instances of a field group.
3154
- * Useful for forms with repeating data like addresses, items, or contacts.
3155
- * Automatically manages field array state and provides add/remove buttons.
3156
- *
3157
- * @template TFieldValues - The form data type
3158
- *
3159
- * @param {FieldArrayFieldProps<TFieldValues>} props - Component props
3160
- * @param {FieldArrayConfig<TFieldValues>} props.config - Field array configuration
3161
- * @param {string} [props.className] - Additional CSS class name
3162
- *
3163
- * @returns {JSX.Element} The rendered field array with add/remove controls
3164
- *
3165
- * @example
3166
- * ```tsx
3167
- * import { FieldArrayField, FormFieldHelpers } from "@rachelallyson/hero-hook-form";
3168
- *
3169
- * const fields = [
3170
- * FormFieldHelpers.input("name", "Name"),
3171
- * FieldArrayField({
3172
- * config: {
3173
- * name: "addresses",
3174
- * label: "Address",
3175
- * fields: [
3176
- * FormFieldHelpers.input("street", "Street Address"),
3177
- * FormFieldHelpers.input("city", "City"),
3178
- * FormFieldHelpers.input("zipCode", "ZIP Code"),
3179
- * ],
3180
- * min: 1,
3181
- * max: 5,
3182
- * addButtonText: "Add Address",
3183
- * removeButtonText: "Remove Address",
3184
- * },
3185
- * }),
3186
- * ];
3187
- * ```
3188
- *
3189
- * @example
3190
- * With validation:
3191
- * ```tsx
3192
- * const schema = z.object({
3193
- * addresses: z.array(z.object({
3194
- * street: z.string().min(1, "Street is required"),
3195
- * city: z.string().min(1, "City is required"),
3196
- * })).min(1, "At least one address is required"),
3197
- * });
3198
- * ```
3199
- *
3200
- * @see {@link ConditionalField} for conditional single fields
3201
- * @see {@link DynamicSectionField} for conditional field groups
3202
- * @category Fields
3203
- */
3204
- declare function FieldArrayField<TFieldValues extends FieldValues>({ className, config, }: FieldArrayFieldProps<TFieldValues>): React$1.JSX.Element | null;
3205
-
3206
- /**
3207
- * Props for the DynamicSectionField component.
3208
- *
3209
- * @template TFieldValues - The form data type
3210
- */
3211
- interface DynamicSectionFieldProps<TFieldValues extends FieldValues> {
3212
- config: DynamicSectionConfig<TFieldValues>;
3213
- control: Control<TFieldValues>;
3214
- className?: string;
3215
- }
3216
- /**
3217
- * Dynamic section component that shows/hides groups of fields based on form values.
3218
- *
3219
- * @description
3220
- * Similar to ConditionalField but for groups of fields. Renders a section
3221
- * with title, description, and multiple fields when a condition is met.
3222
- * Useful for creating multi-step-like experiences or conditional form sections.
3223
- *
3224
- * @template TFieldValues - The form data type
3225
- *
3226
- * @param {DynamicSectionFieldProps<TFieldValues>} props - Component props
3227
- * @param {DynamicSectionConfig<TFieldValues>} props.config - Dynamic section configuration
3228
- * @param {Control<TFieldValues>} props.control - React Hook Form control
3229
- * @param {string} [props.className] - Additional CSS class name
3230
- *
3231
- * @returns {JSX.Element|null} The rendered section or null if condition is not met
3232
- *
3233
- * @example
3234
- * ```tsx
3235
- * import { DynamicSectionField, FormFieldHelpers } from "@rachelallyson/hero-hook-form";
3236
- *
3237
- * const fields = [
3238
- * FormFieldHelpers.checkbox("hasEmergencyContact", "Has Emergency Contact"),
3239
- * DynamicSectionField({
3240
- * config: {
3241
- * name: "emergencyContact",
3242
- * title: "Emergency Contact Information",
3243
- * description: "Please provide emergency contact details",
3244
- * condition: (values) => values.hasEmergencyContact === true,
3245
- * fields: [
3246
- * FormFieldHelpers.input("name", "Contact Name"),
3247
- * FormFieldHelpers.input("relationship", "Relationship"),
3248
- * FormFieldHelpers.input("phone", "Phone Number", "tel"),
3249
- * FormFieldHelpers.input("email", "Email", "email"),
3250
- * ],
3251
- * },
3252
- * control: form.control,
3253
- * }),
3254
- * ];
3255
- * ```
3256
- *
3257
- * @example
3258
- * Nested dynamic sections:
3259
- * ```tsx
3260
- * DynamicSectionField({
3261
- * config: {
3262
- * name: "businessInfo",
3263
- * title: "Business Information",
3264
- * condition: (values) => values.accountType === "business",
3265
- * fields: [
3266
- * FormFieldHelpers.input("businessName", "Business Name"),
3267
- * DynamicSectionField({
3268
- * config: {
3269
- * name: "billingAddress",
3270
- * title: "Billing Address",
3271
- * condition: (values) => values.businessName && values.taxId,
3272
- * fields: [
3273
- * FormFieldHelpers.input("street", "Street Address"),
3274
- * FormFieldHelpers.input("city", "City"),
3275
- * ],
3276
- * },
3277
- * control: form.control,
3278
- * }),
3279
- * ],
3280
- * },
3281
- * control: form.control,
3282
- * }),
3283
- * ```
3284
- *
3285
- * @see {@link ConditionalField} for single conditional fields
3286
- * @see {@link FieldArrayField} for repeating fields
3287
- * @category Fields
3288
- */
3289
- declare function DynamicSectionField<TFieldValues extends FieldValues>({ className, config, control, }: DynamicSectionFieldProps<TFieldValues>): React$1.JSX.Element | null;
3290
-
3291
- interface FormStatusProps<T extends Record<string, any>> {
3292
- state: EnhancedFormState<T>;
3293
- onDismiss?: () => void;
3294
- className?: string;
3295
- showDetails?: boolean;
3296
- }
3297
- declare function FormStatus<T extends Record<string, any>>({ className, onDismiss, showDetails, state, }: FormStatusProps<T>): React$1.JSX.Element | null;
3298
- interface FormToastProps<T extends Record<string, any>> {
3299
- state: EnhancedFormState<T>;
3300
- onDismiss?: () => void;
3301
- position?: "top-right" | "top-left" | "bottom-right" | "bottom-left";
3302
- duration?: number;
3303
- }
3304
- declare function FormToast<T extends Record<string, any>>({ duration, onDismiss, position, state, }: FormToastProps<T>): React$1.JSX.Element | null;
3305
-
3306
- /**
3307
- * Debounce function for field changes
3308
- */
3309
- declare function debounce<T extends (...args: any[]) => any>(func: T, delay: number): (...args: Parameters<T>) => void;
3310
- /**
3311
- * Throttle function for high-frequency events
3312
- */
3313
- declare function throttle<T extends (...args: any[]) => any>(func: T, limit: number): (...args: Parameters<T>) => void;
3314
- /**
3315
- * Memoization helper for expensive computations
3316
- */
3317
- declare function useMemoizedCallback<T extends (...args: any[]) => any>(callback: T, deps: React.DependencyList): T;
3318
- /**
3319
- * Shallow comparison for React.memo
3320
- */
3321
- declare function shallowEqual<T extends Record<string, any>>(prevProps: T, nextProps: T): boolean;
3322
- /**
3323
- * Deep comparison for complex objects
3324
- */
3325
- declare function deepEqual<T extends Record<string, any>>(prevProps: T, nextProps: T): boolean;
3326
- /**
3327
- * Performance monitoring utilities (dev mode only)
3328
- */
3329
- declare function usePerformanceMonitor(componentName: string, enabled?: boolean): {
3330
- renderCount: number;
3331
- resetRenderCount: () => void;
3332
- };
3333
- /**
3334
- * Optimized field change handler
3335
- */
3336
- declare function createOptimizedFieldHandler<T>(onChange: (value: T) => void, options?: {
3337
- debounce?: number;
3338
- throttle?: number;
3339
- }): (value: T) => void;
3340
- /**
3341
- * Memoized field props to prevent unnecessary re-renders
3342
- */
3343
- declare function useMemoizedFieldProps<T extends Record<string, any>>(props: T, deps: React.DependencyList): T;
3344
-
3345
- /**
3346
- * Common validation patterns for forms
3347
- */
3348
- declare const validationPatterns: {
3349
- creditCard: z.ZodString;
3350
- date: z.ZodString;
3351
- email: z.ZodString;
3352
- password: z.ZodString;
3353
- phoneInternational: z.ZodString;
3354
- phoneUS: z.ZodString;
3355
- ssn: z.ZodString;
3356
- strongPassword: z.ZodString;
3357
- time: z.ZodString;
3358
- url: z.ZodString;
3359
- zipCode: z.ZodString;
3360
- };
3361
- /**
3362
- * Async validation helpers
3363
- */
3364
- declare const asyncValidation: {
3365
- /**
3366
- * Email availability check
3367
- */
3368
- emailAvailability: (email: string) => Promise<boolean>;
3369
- /**
3370
- * Username availability check
3371
- */
3372
- usernameAvailability: (username: string) => Promise<boolean>;
3373
- };
3374
- /**
3375
- * Custom error messages
3376
- */
3377
- declare const errorMessages: {
3378
- date: () => string;
3379
- email: () => string;
3380
- max: (fieldName: string, max: number) => string;
3381
- maxLength: (fieldName: string, max: number) => string;
3382
- min: (fieldName: string, min: number) => string;
3383
- minLength: (fieldName: string, min: number) => string;
3384
- pattern: (fieldName: string) => string;
3385
- phone: () => string;
3386
- required: (fieldName: string) => string;
3387
- time: () => string;
3388
- url: () => string;
3389
- };
3390
- /**
3391
- * Server-side validation integration
3392
- */
3393
- declare const serverValidation: {
3394
- /**
3395
- * Apply server errors to form
3396
- */
3397
- applyServerErrors: (errors: Record<string, string[]>, setError: any) => void;
3398
- /**
3399
- * Clear server errors
3400
- */
3401
- clearServerErrors: (fields: string[], clearErrors: any) => void;
3402
- };
3403
- /**
3404
- * Form validation utilities
3405
- */
3406
- declare const validationUtils: {
3407
- /**
3408
- * Debounced validation
3409
- */
3410
- debounceValidation: (fn: (...args: any[]) => void, delay?: number) => (...args: any[]) => void;
3411
- /**
3412
- * Get field error message
3413
- */
3414
- getFieldError: (errors: Record<string, string>, field: string) => string | undefined;
3415
- /**
3416
- * Check if field has error
3417
- */
3418
- hasFieldError: (errors: Record<string, string>, field: string) => boolean;
3419
- /**
3420
- * Validate form data against schema
3421
- */
3422
- validateForm: (data: any, schema: z.ZodSchema) => Promise<{
3423
- errors: Record<string, string>;
3424
- success: boolean;
3425
- }>;
3426
- };
3427
-
3428
- 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 };