@mehdashti/forms 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,857 @@
1
+ import * as react_hook_form from 'react-hook-form';
2
+ import { FieldValues, DefaultValues, Path, UseFormReturn, Control, ArrayPath, FieldErrors } from 'react-hook-form';
3
+ export { FieldErrors, FieldValues, Path, PathValue } from 'react-hook-form';
4
+ import { z, ZodTypeAny } from 'zod';
5
+ export { z } from 'zod';
6
+ import * as react_jsx_runtime from 'react/jsx-runtime';
7
+ import * as React$1 from 'react';
8
+
9
+ interface SmartFormOptions<TFieldValues extends FieldValues = FieldValues> {
10
+ schema: z.ZodSchema<TFieldValues>;
11
+ onSubmit: (data: TFieldValues) => void | Promise<void>;
12
+ onError?: (errors: Record<string, unknown>) => void;
13
+ realtimeValidation?: boolean;
14
+ defaultValues?: DefaultValues<TFieldValues>;
15
+ mode?: 'onSubmit' | 'onBlur' | 'onChange' | 'onTouched' | 'all';
16
+ }
17
+ /**
18
+ * Enhanced React Hook Form with Zod validation and smart defaults
19
+ */
20
+ declare function useSmartForm<TFieldValues extends FieldValues = FieldValues>(options: SmartFormOptions<TFieldValues>): {
21
+ handleSubmit: (e?: React.BaseSyntheticEvent) => Promise<void>;
22
+ isSubmitting: boolean;
23
+ hasErrors: boolean;
24
+ getError: (name: Path<TFieldValues>) => string | undefined;
25
+ watch: react_hook_form.UseFormWatch<TFieldValues>;
26
+ getValues: react_hook_form.UseFormGetValues<TFieldValues>;
27
+ getFieldState: react_hook_form.UseFormGetFieldState<TFieldValues>;
28
+ setError: react_hook_form.UseFormSetError<TFieldValues>;
29
+ clearErrors: react_hook_form.UseFormClearErrors<TFieldValues>;
30
+ setValue: react_hook_form.UseFormSetValue<TFieldValues>;
31
+ trigger: react_hook_form.UseFormTrigger<TFieldValues>;
32
+ formState: react_hook_form.FormState<TFieldValues>;
33
+ resetField: react_hook_form.UseFormResetField<TFieldValues>;
34
+ reset: react_hook_form.UseFormReset<TFieldValues>;
35
+ unregister: react_hook_form.UseFormUnregister<TFieldValues>;
36
+ control: react_hook_form.Control<TFieldValues, any, TFieldValues>;
37
+ register: react_hook_form.UseFormRegister<TFieldValues>;
38
+ setFocus: react_hook_form.UseFormSetFocus<TFieldValues>;
39
+ subscribe: react_hook_form.UseFormSubscribe<TFieldValues>;
40
+ };
41
+ type SmartFormReturn<TFieldValues extends FieldValues = FieldValues> = ReturnType<typeof useSmartForm<TFieldValues>>;
42
+
43
+ /**
44
+ * Form field component props
45
+ */
46
+ interface FormFieldProps<TFieldValues extends FieldValues = FieldValues> {
47
+ name: Path<TFieldValues>;
48
+ label: string;
49
+ type?: 'text' | 'email' | 'password' | 'number' | 'tel' | 'url';
50
+ placeholder?: string;
51
+ required?: boolean;
52
+ helpText?: string;
53
+ disabled?: boolean;
54
+ className?: string;
55
+ control: UseFormReturn<TFieldValues>['control'];
56
+ render?: (field: {
57
+ value: unknown;
58
+ onChange: (...event: unknown[]) => void;
59
+ onBlur: () => void;
60
+ name: string;
61
+ }) => React.ReactElement;
62
+ }
63
+ /**
64
+ * Select field option
65
+ */
66
+ interface SelectOption {
67
+ label: string;
68
+ value: string | number;
69
+ disabled?: boolean;
70
+ }
71
+ /**
72
+ * Select field component props
73
+ */
74
+ interface FormSelectProps<TFieldValues extends FieldValues = FieldValues> extends Omit<FormFieldProps<TFieldValues>, 'type' | 'placeholder'> {
75
+ options: SelectOption[];
76
+ placeholder?: string;
77
+ }
78
+ /**
79
+ * Checkbox field component props
80
+ */
81
+ interface FormCheckboxProps<TFieldValues extends FieldValues = FieldValues> extends Omit<FormFieldProps<TFieldValues>, 'type' | 'placeholder'> {
82
+ description?: string;
83
+ }
84
+
85
+ /**
86
+ * Smart Form Field component with automatic error handling
87
+ *
88
+ * @example
89
+ * ```tsx
90
+ * <FormField
91
+ * name="email"
92
+ * label="Email"
93
+ * type="email"
94
+ * required
95
+ * control={form.control}
96
+ * placeholder="Enter your email"
97
+ * />
98
+ * ```
99
+ */
100
+ declare function FormField<TFieldValues extends FieldValues = FieldValues>({ name, label, type, placeholder, required, helpText, disabled, className, control, render, }: FormFieldProps<TFieldValues>): react_jsx_runtime.JSX.Element;
101
+
102
+ /**
103
+ * Smart Form Select component
104
+ *
105
+ * @example
106
+ * ```tsx
107
+ * <FormSelect
108
+ * name="country"
109
+ * label="Country"
110
+ * required
111
+ * control={form.control}
112
+ * options={[
113
+ * { value: 'us', label: 'United States' },
114
+ * { value: 'uk', label: 'United Kingdom' },
115
+ * ]}
116
+ * />
117
+ * ```
118
+ */
119
+ declare function FormSelect<TFieldValues extends FieldValues = FieldValues>({ name, label, options, placeholder, required, helpText, disabled, className, control, }: FormSelectProps<TFieldValues>): react_jsx_runtime.JSX.Element;
120
+
121
+ /**
122
+ * Smart Form Checkbox component
123
+ *
124
+ * @example
125
+ * ```tsx
126
+ * <FormCheckbox
127
+ * name="acceptTerms"
128
+ * label="I accept the terms and conditions"
129
+ * required
130
+ * control={form.control}
131
+ * description="You must accept the terms to continue"
132
+ * />
133
+ * ```
134
+ */
135
+ declare function FormCheckbox<TFieldValues extends FieldValues = FieldValues>({ name, label, description, required, helpText, disabled, className, control, }: FormCheckboxProps<TFieldValues>): react_jsx_runtime.JSX.Element;
136
+
137
+ interface FormTextareaProps<TFieldValues extends FieldValues = FieldValues> {
138
+ name: Path<TFieldValues>;
139
+ label: string;
140
+ placeholder?: string;
141
+ required?: boolean;
142
+ helpText?: string;
143
+ disabled?: boolean;
144
+ className?: string;
145
+ control: Control<TFieldValues>;
146
+ rows?: number;
147
+ maxLength?: number;
148
+ showCharacterCount?: boolean;
149
+ resize?: 'none' | 'vertical' | 'horizontal' | 'both';
150
+ }
151
+ /**
152
+ * Smart Form Textarea component with character counter
153
+ *
154
+ * @example
155
+ * ```tsx
156
+ * <FormTextarea
157
+ * name="description"
158
+ * label="Description"
159
+ * control={form.control}
160
+ * rows={4}
161
+ * maxLength={500}
162
+ * showCharacterCount
163
+ * />
164
+ * ```
165
+ */
166
+ declare function FormTextarea<TFieldValues extends FieldValues = FieldValues>({ name, label, placeholder, required, helpText, disabled, className, control, rows, maxLength, showCharacterCount, resize, }: FormTextareaProps<TFieldValues>): react_jsx_runtime.JSX.Element;
167
+
168
+ interface FormFileUploadProps<TFieldValues extends FieldValues = FieldValues> {
169
+ name: Path<TFieldValues>;
170
+ label: string;
171
+ required?: boolean;
172
+ helpText?: string;
173
+ disabled?: boolean;
174
+ className?: string;
175
+ control: Control<TFieldValues>;
176
+ accept?: string;
177
+ multiple?: boolean;
178
+ maxSize?: number;
179
+ showPreview?: boolean;
180
+ onFileChange?: (files: FileList | null) => void;
181
+ }
182
+ /**
183
+ * Smart Form File Upload component with preview
184
+ *
185
+ * @example
186
+ * ```tsx
187
+ * <FormFileUpload
188
+ * name="avatar"
189
+ * label="Profile Picture"
190
+ * control={form.control}
191
+ * accept="image/*"
192
+ * maxSize={5 * 1024 * 1024} // 5MB
193
+ * showPreview
194
+ * />
195
+ * ```
196
+ */
197
+ declare function FormFileUpload<TFieldValues extends FieldValues = FieldValues>({ name, label, required, helpText, disabled, className, control, accept, multiple, maxSize, showPreview, onFileChange, }: FormFileUploadProps<TFieldValues>): react_jsx_runtime.JSX.Element;
198
+
199
+ interface FormDatePickerProps<TFieldValues extends FieldValues = FieldValues> {
200
+ name: Path<TFieldValues>;
201
+ label: string;
202
+ placeholder?: string;
203
+ required?: boolean;
204
+ helpText?: string;
205
+ disabled?: boolean;
206
+ className?: string;
207
+ control: Control<TFieldValues>;
208
+ min?: string;
209
+ max?: string;
210
+ mode?: 'single' | 'range';
211
+ }
212
+ /**
213
+ * Smart Form Date Picker component
214
+ *
215
+ * @example
216
+ * ```tsx
217
+ * <FormDatePicker
218
+ * name="birthDate"
219
+ * label="Birth Date"
220
+ * control={form.control}
221
+ * max={new Date().toISOString().split('T')[0]}
222
+ * />
223
+ * ```
224
+ */
225
+ declare function FormDatePicker<TFieldValues extends FieldValues = FieldValues>({ name, label, placeholder, required, helpText, disabled, className, control, min, max, mode, }: FormDatePickerProps<TFieldValues>): react_jsx_runtime.JSX.Element;
226
+
227
+ interface MultiSelectOption {
228
+ value: string | number;
229
+ label: string;
230
+ disabled?: boolean;
231
+ }
232
+ interface FormMultiSelectProps<TFieldValues extends FieldValues = FieldValues> {
233
+ name: Path<TFieldValues>;
234
+ label: string;
235
+ options: MultiSelectOption[];
236
+ required?: boolean;
237
+ helpText?: string;
238
+ disabled?: boolean;
239
+ className?: string;
240
+ control: Control<TFieldValues>;
241
+ layout?: 'vertical' | 'horizontal' | 'grid';
242
+ maxSelection?: number;
243
+ }
244
+ /**
245
+ * Smart Form Multi-Select component
246
+ *
247
+ * @example
248
+ * ```tsx
249
+ * <FormMultiSelect
250
+ * name="interests"
251
+ * label="Interests"
252
+ * control={form.control}
253
+ * options={[
254
+ * { value: 'sports', label: 'Sports' },
255
+ * { value: 'music', label: 'Music' },
256
+ * { value: 'tech', label: 'Technology' },
257
+ * ]}
258
+ * layout="grid"
259
+ * />
260
+ * ```
261
+ */
262
+ declare function FormMultiSelect<TFieldValues extends FieldValues = FieldValues>({ name, label, options, required, helpText, disabled, className, control, layout, maxSelection, }: FormMultiSelectProps<TFieldValues>): react_jsx_runtime.JSX.Element;
263
+
264
+ interface RadioOption {
265
+ value: string;
266
+ label: string;
267
+ description?: string;
268
+ disabled?: boolean;
269
+ }
270
+ interface FormRadioGroupProps<TFieldValues extends FieldValues> {
271
+ /**
272
+ * Field name (registered with react-hook-form)
273
+ */
274
+ name: Path<TFieldValues>;
275
+ /**
276
+ * Radio group label
277
+ */
278
+ label?: string;
279
+ /**
280
+ * Radio options
281
+ */
282
+ options: RadioOption[];
283
+ /**
284
+ * Layout orientation
285
+ */
286
+ orientation?: "vertical" | "horizontal";
287
+ /**
288
+ * Help text shown below the radio group
289
+ */
290
+ helperText?: string;
291
+ /**
292
+ * Whether the field is required
293
+ */
294
+ required?: boolean;
295
+ /**
296
+ * Whether the field is disabled
297
+ */
298
+ disabled?: boolean;
299
+ /**
300
+ * Custom className
301
+ */
302
+ className?: string;
303
+ }
304
+ declare function FormRadioGroup<TFieldValues extends FieldValues>({ name, label, options, orientation, helperText, required, disabled, className, }: FormRadioGroupProps<TFieldValues>): react_jsx_runtime.JSX.Element;
305
+
306
+ interface FormSwitchProps<TFieldValues extends FieldValues> {
307
+ /**
308
+ * Field name (registered with react-hook-form)
309
+ */
310
+ name: Path<TFieldValues>;
311
+ /**
312
+ * Switch label
313
+ */
314
+ label?: string;
315
+ /**
316
+ * Description shown below the label
317
+ */
318
+ description?: string;
319
+ /**
320
+ * Help text shown below the switch
321
+ */
322
+ helperText?: string;
323
+ /**
324
+ * Whether the field is required
325
+ */
326
+ required?: boolean;
327
+ /**
328
+ * Whether the field is disabled
329
+ */
330
+ disabled?: boolean;
331
+ /**
332
+ * Custom className
333
+ */
334
+ className?: string;
335
+ /**
336
+ * Callback when value changes
337
+ */
338
+ onChange?: (checked: boolean) => void;
339
+ }
340
+ declare function FormSwitch<TFieldValues extends FieldValues>({ name, label, description, helperText, required, disabled, className, onChange, }: FormSwitchProps<TFieldValues>): react_jsx_runtime.JSX.Element;
341
+
342
+ interface FormTagInputProps<TFieldValues extends FieldValues> {
343
+ /**
344
+ * Field name (registered with react-hook-form)
345
+ */
346
+ name: Path<TFieldValues>;
347
+ /**
348
+ * Field label
349
+ */
350
+ label?: string;
351
+ /**
352
+ * Placeholder text
353
+ */
354
+ placeholder?: string;
355
+ /**
356
+ * Help text shown below the input
357
+ */
358
+ helperText?: string;
359
+ /**
360
+ * Whether the field is required
361
+ */
362
+ required?: boolean;
363
+ /**
364
+ * Whether the field is disabled
365
+ */
366
+ disabled?: boolean;
367
+ /**
368
+ * Maximum number of tags allowed
369
+ */
370
+ maxTags?: number;
371
+ /**
372
+ * Separator keys (default: Enter, comma)
373
+ */
374
+ separators?: string[];
375
+ /**
376
+ * Validate individual tags before adding
377
+ */
378
+ validateTag?: (tag: string) => boolean | string;
379
+ /**
380
+ * Custom className
381
+ */
382
+ className?: string;
383
+ }
384
+ declare function FormTagInput<TFieldValues extends FieldValues>({ name, label, placeholder, helperText, required, disabled, maxTags, separators, validateTag, className, }: FormTagInputProps<TFieldValues>): react_jsx_runtime.JSX.Element;
385
+
386
+ /**
387
+ * FormErrorSummary Component
388
+ *
389
+ * Displays all form errors in a summary box with links to fields.
390
+ */
391
+ interface FormErrorSummaryProps {
392
+ /**
393
+ * Title for the error summary
394
+ */
395
+ title?: string;
396
+ /**
397
+ * Custom field labels (for better error messages)
398
+ */
399
+ fieldLabels?: Record<string, string>;
400
+ /**
401
+ * Whether to show the error summary
402
+ * Defaults to showing when there are errors
403
+ */
404
+ show?: boolean;
405
+ /**
406
+ * Custom className
407
+ */
408
+ className?: string;
409
+ /**
410
+ * Callback when an error link is clicked
411
+ */
412
+ onErrorClick?: (fieldName: string) => void;
413
+ }
414
+ declare function FormErrorSummary({ title, fieldLabels, show, className, onErrorClick, }: FormErrorSummaryProps): react_jsx_runtime.JSX.Element | null;
415
+
416
+ interface FormLayoutProps extends React$1.HTMLAttributes<HTMLDivElement> {
417
+ /**
418
+ * Number of columns for the form layout
419
+ * @default 1
420
+ */
421
+ columns?: 1 | 2 | 3 | 4;
422
+ /**
423
+ * Spacing between form fields
424
+ * @default "md"
425
+ */
426
+ spacing?: 'sm' | 'md' | 'lg';
427
+ /**
428
+ * Make the layout responsive (mobile: 1 col, tablet: 2 cols, desktop: specified cols)
429
+ * @default true
430
+ */
431
+ responsive?: boolean;
432
+ }
433
+ /**
434
+ * FormLayout - Ready-to-use form grid layout
435
+ *
436
+ * @example
437
+ * ```tsx
438
+ * <FormLayout columns={2}>
439
+ * <FormField name="firstName" label="First Name" control={form.control} />
440
+ * <FormField name="lastName" label="Last Name" control={form.control} />
441
+ * </FormLayout>
442
+ * ```
443
+ */
444
+ declare function FormLayout({ columns, spacing, responsive, className, children, ...props }: FormLayoutProps): react_jsx_runtime.JSX.Element;
445
+ declare namespace FormLayout {
446
+ var displayName: string;
447
+ }
448
+
449
+ interface FormSectionProps extends React$1.HTMLAttributes<HTMLDivElement> {
450
+ /**
451
+ * Section title
452
+ */
453
+ title?: string;
454
+ /**
455
+ * Section description
456
+ */
457
+ description?: string;
458
+ /**
459
+ * Number of columns for this section
460
+ * @default 1
461
+ */
462
+ columns?: 1 | 2 | 3 | 4;
463
+ /**
464
+ * Spacing between fields
465
+ * @default "md"
466
+ */
467
+ spacing?: 'sm' | 'md' | 'lg';
468
+ }
469
+ /**
470
+ * FormSection - Section with title and grid layout
471
+ *
472
+ * @example
473
+ * ```tsx
474
+ * <FormSection title="Personal Info" description="Enter your details" columns={2}>
475
+ * <FormField name="name" label="Name" control={form.control} />
476
+ * <FormField name="email" label="Email" control={form.control} />
477
+ * </FormSection>
478
+ * ```
479
+ */
480
+ declare function FormSection({ title, description, columns, spacing, className, children, ...props }: FormSectionProps): react_jsx_runtime.JSX.Element;
481
+ declare namespace FormSection {
482
+ var displayName: string;
483
+ }
484
+
485
+ interface FormGridProps extends React$1.HTMLAttributes<HTMLDivElement> {
486
+ /**
487
+ * Spacing between items
488
+ * @default "md"
489
+ */
490
+ spacing?: 'sm' | 'md' | 'lg';
491
+ }
492
+ interface FormGridItemProps extends React$1.HTMLAttributes<HTMLDivElement> {
493
+ /**
494
+ * Column span for the item
495
+ * @default 1
496
+ */
497
+ colSpan?: 1 | 2 | 3 | 4 | 'full';
498
+ }
499
+ /**
500
+ * FormGrid - Advanced grid layout with col-span support
501
+ *
502
+ * @example
503
+ * ```tsx
504
+ * <FormGrid>
505
+ * <FormGridItem>
506
+ * <FormField name="firstName" label="First Name" control={form.control} />
507
+ * </FormGridItem>
508
+ * <FormGridItem>
509
+ * <FormField name="lastName" label="Last Name" control={form.control} />
510
+ * </FormGridItem>
511
+ * <FormGridItem colSpan="full">
512
+ * <FormField name="bio" label="Bio" control={form.control} />
513
+ * </FormGridItem>
514
+ * </FormGrid>
515
+ * ```
516
+ */
517
+ declare function FormGrid({ spacing, className, children, ...props }: FormGridProps): react_jsx_runtime.JSX.Element;
518
+ declare namespace FormGrid {
519
+ var displayName: string;
520
+ }
521
+ /**
522
+ * FormGridItem - Item within FormGrid with custom column span
523
+ */
524
+ declare function FormGridItem({ colSpan, className, children, ...props }: FormGridItemProps): react_jsx_runtime.JSX.Element;
525
+ declare namespace FormGridItem {
526
+ var displayName: string;
527
+ }
528
+
529
+ interface FormWizardStep {
530
+ title: string;
531
+ description?: string;
532
+ content: React$1.ReactNode;
533
+ onValidate?: () => boolean | Promise<boolean>;
534
+ }
535
+ interface FormWizardProps {
536
+ steps: FormWizardStep[];
537
+ onComplete: () => void | Promise<void>;
538
+ onCancel?: () => void;
539
+ className?: string;
540
+ showStepNumbers?: boolean;
541
+ }
542
+ /**
543
+ * Form Wizard component for multi-step forms
544
+ *
545
+ * @example
546
+ * ```tsx
547
+ * <FormWizard
548
+ * steps={[
549
+ * {
550
+ * title: 'Personal Info',
551
+ * content: <PersonalInfoForm />,
552
+ * onValidate: () => form.trigger(['name', 'email']),
553
+ * },
554
+ * {
555
+ * title: 'Address',
556
+ * content: <AddressForm />,
557
+ * },
558
+ * ]}
559
+ * onComplete={() => form.handleSubmit(onSubmit)()}
560
+ * />
561
+ * ```
562
+ */
563
+ declare function FormWizard({ steps, onComplete, onCancel, className, showStepNumbers, }: FormWizardProps): react_jsx_runtime.JSX.Element;
564
+
565
+ /**
566
+ * Field array options
567
+ */
568
+ interface FieldArrayOptions<TFieldValues extends FieldValues = FieldValues> {
569
+ /**
570
+ * Field array name
571
+ */
572
+ name: ArrayPath<TFieldValues>;
573
+ /**
574
+ * Form control instance
575
+ */
576
+ control: UseFormReturn<TFieldValues>['control'];
577
+ /**
578
+ * Default value for new items
579
+ */
580
+ defaultValue?: unknown;
581
+ }
582
+ /**
583
+ * Wrapper around React Hook Form's useFieldArray with smart defaults
584
+ *
585
+ * @example
586
+ * ```tsx
587
+ * const { fields, append, remove } = useSmartFieldArray({
588
+ * name: 'items',
589
+ * control: form.control,
590
+ * defaultValue: { name: '', quantity: 0 }
591
+ * })
592
+ * ```
593
+ */
594
+ declare function useSmartFieldArray<TFieldValues extends FieldValues = FieldValues>({ name, control, defaultValue, }: FieldArrayOptions<TFieldValues>): {
595
+ append: (value?: unknown) => void;
596
+ swap: react_hook_form.UseFieldArraySwap;
597
+ move: react_hook_form.UseFieldArrayMove;
598
+ prepend: react_hook_form.UseFieldArrayPrepend<TFieldValues, ArrayPath<TFieldValues>>;
599
+ remove: react_hook_form.UseFieldArrayRemove;
600
+ insert: react_hook_form.UseFieldArrayInsert<TFieldValues, ArrayPath<TFieldValues>>;
601
+ update: react_hook_form.UseFieldArrayUpdate<TFieldValues, ArrayPath<TFieldValues>>;
602
+ replace: react_hook_form.UseFieldArrayReplace<TFieldValues, ArrayPath<TFieldValues>>;
603
+ fields: react_hook_form.FieldArrayWithId<TFieldValues, ArrayPath<TFieldValues>, "id">[];
604
+ };
605
+
606
+ /**
607
+ * useUnsavedChanges Hook
608
+ *
609
+ * Warns users before leaving the page if form has unsaved changes.
610
+ */
611
+ interface UseUnsavedChangesOptions {
612
+ /**
613
+ * Custom message for the confirmation dialog
614
+ */
615
+ message?: string;
616
+ /**
617
+ * Whether to enable the warning
618
+ * Defaults to true
619
+ */
620
+ enabled?: boolean;
621
+ /**
622
+ * Callback when user tries to leave with unsaved changes
623
+ */
624
+ onBeforeUnload?: (isDirty: boolean) => void;
625
+ }
626
+ /**
627
+ * Hook to warn users before leaving the page with unsaved form changes
628
+ *
629
+ * @example
630
+ * ```tsx
631
+ * function MyForm() {
632
+ * const form = useSmartForm({ schema: mySchema });
633
+ *
634
+ * useUnsavedChanges({
635
+ * message: "You have unsaved changes. Are you sure you want to leave?",
636
+ * enabled: true
637
+ * });
638
+ *
639
+ * return <FormProvider {...form}>...</FormProvider>;
640
+ * }
641
+ * ```
642
+ */
643
+ declare function useUnsavedChanges(options?: UseUnsavedChangesOptions): {
644
+ hasUnsavedChanges: boolean;
645
+ isDirty: boolean;
646
+ };
647
+ /**
648
+ * Hook variant for React Router integration
649
+ *
650
+ * @example
651
+ * ```tsx
652
+ * function MyForm() {
653
+ * const form = useSmartForm({ schema: mySchema });
654
+ * const blocker = useUnsavedChangesBlocker();
655
+ *
656
+ * if (blocker.state === "blocked") {
657
+ * return (
658
+ * <ConfirmDialog
659
+ * title="Unsaved changes"
660
+ * message="You have unsaved changes. Are you sure you want to leave?"
661
+ * onConfirm={blocker.proceed}
662
+ * onCancel={blocker.reset}
663
+ * />
664
+ * );
665
+ * }
666
+ *
667
+ * return <FormProvider {...form}>...</FormProvider>;
668
+ * }
669
+ * ```
670
+ */
671
+ declare function useUnsavedChangesBlocker(): {
672
+ hasUnsavedChanges: boolean;
673
+ isDirty: boolean;
674
+ shouldBlock: boolean;
675
+ };
676
+
677
+ /**
678
+ * Common Validation Schemas
679
+ *
680
+ * Reusable Zod schemas for common validation patterns.
681
+ */
682
+
683
+ /**
684
+ * Email validation schema
685
+ */
686
+ declare const emailSchema: z.ZodString;
687
+ /**
688
+ * Password validation schema
689
+ * At least 8 characters, 1 uppercase, 1 lowercase, 1 number
690
+ */
691
+ declare const passwordSchema: z.ZodString;
692
+ /**
693
+ * Strong password validation schema
694
+ * At least 12 characters, 1 uppercase, 1 lowercase, 1 number, 1 special character
695
+ */
696
+ declare const strongPasswordSchema: z.ZodString;
697
+ /**
698
+ * Phone number validation schema (international format)
699
+ */
700
+ declare const phoneSchema: z.ZodString;
701
+ /**
702
+ * URL validation schema
703
+ */
704
+ declare const urlSchema: z.ZodString;
705
+ /**
706
+ * Username validation schema
707
+ * 3-20 characters, alphanumeric and underscores only
708
+ */
709
+ declare const usernameSchema: z.ZodString;
710
+ /**
711
+ * Slug validation schema
712
+ * Lowercase letters, numbers, and hyphens only
713
+ */
714
+ declare const slugSchema: z.ZodString;
715
+ /**
716
+ * Positive number schema
717
+ */
718
+ declare const positiveNumberSchema: z.ZodNumber;
719
+ /**
720
+ * Positive integer schema
721
+ */
722
+ declare const positiveIntegerSchema: z.ZodNumber;
723
+ /**
724
+ * Price schema (two decimal places)
725
+ */
726
+ declare const priceSchema: z.ZodNumber;
727
+ /**
728
+ * Percentage schema (0-100)
729
+ */
730
+ declare const percentageSchema: z.ZodNumber;
731
+ /**
732
+ * Date string schema (ISO format)
733
+ */
734
+ declare const dateStringSchema: z.ZodString;
735
+ /**
736
+ * Future date schema
737
+ */
738
+ declare const futureDateSchema: z.ZodEffects<z.ZodString, string, string>;
739
+ /**
740
+ * Past date schema
741
+ */
742
+ declare const pastDateSchema: z.ZodEffects<z.ZodString, string, string>;
743
+ /**
744
+ * File size validation helper
745
+ */
746
+ declare const createFileSizeSchema: (maxSizeInBytes: number, message?: string) => z.ZodEffects<z.ZodType<File, z.ZodTypeDef, File>, File, File>;
747
+ /**
748
+ * File type validation helper
749
+ */
750
+ declare const createFileTypeSchema: (allowedTypes: string[], message?: string) => z.ZodEffects<z.ZodType<File, z.ZodTypeDef, File>, File, File>;
751
+ /**
752
+ * Image file schema (common image types, max 5MB)
753
+ */
754
+ declare const imageFileSchema: z.ZodEffects<z.ZodEffects<z.ZodType<File, z.ZodTypeDef, File>, File, File>, File, File>;
755
+ /**
756
+ * Confirm password schema helper
757
+ */
758
+ declare const createConfirmPasswordSchema: (passwordField: string) => z.ZodEffects<z.ZodObject<{
759
+ [x: string]: z.ZodString;
760
+ confirmPassword: z.ZodString;
761
+ }, "strip", z.ZodTypeAny, {
762
+ [x: string]: string;
763
+ confirmPassword?: unknown;
764
+ }, {
765
+ [x: string]: string;
766
+ confirmPassword?: unknown;
767
+ }>, {
768
+ [x: string]: string;
769
+ confirmPassword?: unknown;
770
+ }, {
771
+ [x: string]: string;
772
+ confirmPassword?: unknown;
773
+ }>;
774
+ /**
775
+ * Optional email schema (can be empty or valid email)
776
+ */
777
+ declare const optionalEmailSchema: z.ZodUnion<[z.ZodString, z.ZodString]>;
778
+ /**
779
+ * Optional URL schema
780
+ */
781
+ declare const optionalUrlSchema: z.ZodUnion<[z.ZodString, z.ZodString]>;
782
+
783
+ /**
784
+ * Validation Helper Utilities
785
+ *
786
+ * Helper functions for common validation patterns.
787
+ */
788
+
789
+ /**
790
+ * Get error message from field errors
791
+ */
792
+ declare function getErrorMessage(errors: FieldErrors, fieldName: string): string | undefined;
793
+ /**
794
+ * Check if field has error
795
+ */
796
+ declare function hasError(errors: FieldErrors, fieldName: string): boolean;
797
+ /**
798
+ * Get all error messages as array
799
+ */
800
+ declare function getAllErrors(errors: FieldErrors): string[];
801
+ /**
802
+ * Create a conditional schema based on another field
803
+ *
804
+ * @example
805
+ * ```ts
806
+ * const schema = z.object({
807
+ * type: z.enum(['individual', 'company']),
808
+ * companyName: conditionalSchema(
809
+ * 'type',
810
+ * (type) => type === 'company',
811
+ * z.string().min(1, 'Company name is required')
812
+ * ),
813
+ * })
814
+ * ```
815
+ */
816
+ declare function conditionalSchema<T extends ZodTypeAny>(_dependentField: string, _condition: (value: any) => boolean, schema: T): ZodTypeAny;
817
+ /**
818
+ * Create min/max length message
819
+ */
820
+ declare function lengthMessage(field: string, min?: number, max?: number): string;
821
+ /**
822
+ * Create required field message
823
+ */
824
+ declare function requiredMessage(field: string): string;
825
+ /**
826
+ * Create invalid format message
827
+ */
828
+ declare function invalidFormatMessage(field: string): string;
829
+ /**
830
+ * Validate credit card using Luhn algorithm
831
+ */
832
+ declare function validateCreditCard(cardNumber: string): boolean;
833
+ /**
834
+ * Validate IBAN (International Bank Account Number)
835
+ */
836
+ declare function validateIBAN(iban: string): boolean;
837
+ /**
838
+ * Validate strong password requirements
839
+ */
840
+ declare function validatePasswordStrength(password: string): {
841
+ isStrong: boolean;
842
+ missingRequirements: string[];
843
+ };
844
+ /**
845
+ * Sanitize string input (remove HTML, trim, normalize whitespace)
846
+ */
847
+ declare function sanitizeString(input: string): string;
848
+ /**
849
+ * Validate file extension
850
+ */
851
+ declare function validateFileExtension(filename: string, allowedExtensions: string[]): boolean;
852
+ /**
853
+ * Format validation error for display
854
+ */
855
+ declare function formatValidationError(error: z.ZodError): Record<string, string>;
856
+
857
+ export { type FieldArrayOptions, FormCheckbox, type FormCheckboxProps, FormDatePicker, type FormDatePickerProps, FormErrorSummary, type FormErrorSummaryProps, FormField, type FormFieldProps, FormFileUpload, type FormFileUploadProps, FormGrid, FormGridItem, type FormGridItemProps, type FormGridProps, FormLayout, type FormLayoutProps, FormMultiSelect, type FormMultiSelectProps, FormRadioGroup, type FormRadioGroupProps, FormSection, type FormSectionProps, FormSelect, type FormSelectProps, FormSwitch, type FormSwitchProps, FormTagInput, type FormTagInputProps, FormTextarea, type FormTextareaProps, FormWizard, type FormWizardProps, type FormWizardStep, type MultiSelectOption, type RadioOption, type SelectOption, type SmartFormOptions, type SmartFormReturn, type UseUnsavedChangesOptions, conditionalSchema, createConfirmPasswordSchema, createFileSizeSchema, createFileTypeSchema, dateStringSchema, emailSchema, formatValidationError, futureDateSchema, getAllErrors, getErrorMessage, hasError, imageFileSchema, invalidFormatMessage, lengthMessage, optionalEmailSchema, optionalUrlSchema, passwordSchema, pastDateSchema, percentageSchema, phoneSchema, positiveIntegerSchema, positiveNumberSchema, priceSchema, requiredMessage, sanitizeString, slugSchema, strongPasswordSchema, urlSchema, useSmartFieldArray, useSmartForm, useUnsavedChanges, useUnsavedChangesBlocker, usernameSchema, validateCreditCard, validateFileExtension, validateIBAN, validatePasswordStrength };