@page-speed/forms 0.5.6 → 0.5.8

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.
Files changed (53) hide show
  1. package/dist/FormContext-089h0j0Q.d.ts +153 -0
  2. package/dist/FormContext-iHzBALZa.d.cts +153 -0
  3. package/dist/{chunk-A7R6GEMA.js → chunk-455PI4LV.js} +84 -3
  4. package/dist/chunk-455PI4LV.js.map +1 -0
  5. package/dist/{chunk-QZ4PK62A.js → chunk-4ROWNTY6.js} +335 -417
  6. package/dist/chunk-4ROWNTY6.js.map +1 -0
  7. package/dist/{chunk-WVSLOSNU.cjs → chunk-ED4UK63G.cjs} +440 -523
  8. package/dist/chunk-ED4UK63G.cjs.map +1 -0
  9. package/dist/chunk-IXHDJ7E5.js +263 -0
  10. package/dist/chunk-IXHDJ7E5.js.map +1 -0
  11. package/dist/{chunk-Q7VR374Y.js → chunk-MJYEXJ3U.js} +3 -3
  12. package/dist/{chunk-Q7VR374Y.js.map → chunk-MJYEXJ3U.js.map} +1 -1
  13. package/dist/{chunk-KPHMVGTU.cjs → chunk-MUBEMXI7.cjs} +6 -6
  14. package/dist/{chunk-KPHMVGTU.cjs.map → chunk-MUBEMXI7.cjs.map} +1 -1
  15. package/dist/chunk-Q7WXLZN5.cjs +287 -0
  16. package/dist/chunk-Q7WXLZN5.cjs.map +1 -0
  17. package/dist/{chunk-QQSBW6N3.cjs → chunk-QRI5TMES.cjs} +85 -2
  18. package/dist/chunk-QRI5TMES.cjs.map +1 -0
  19. package/dist/core.cjs +13 -9
  20. package/dist/core.d.cts +66 -141
  21. package/dist/core.d.ts +66 -141
  22. package/dist/core.js +3 -3
  23. package/dist/index.cjs +14 -14
  24. package/dist/index.d.cts +2 -2
  25. package/dist/index.d.ts +2 -2
  26. package/dist/index.js +3 -3
  27. package/dist/inputs.cjs +16 -16
  28. package/dist/inputs.d.cts +1 -1
  29. package/dist/inputs.d.ts +1 -1
  30. package/dist/inputs.js +2 -2
  31. package/dist/integration.cjs +17 -17
  32. package/dist/integration.d.cts +1 -1
  33. package/dist/integration.d.ts +1 -1
  34. package/dist/integration.js +3 -3
  35. package/dist/{types-CnOCn7b3.d.ts → types-BemGfSPA.d.cts} +27 -1
  36. package/dist/{types-CnOCn7b3.d.cts → types-BemGfSPA.d.ts} +27 -1
  37. package/dist/validation-rules.d.cts +1 -1
  38. package/dist/validation-rules.d.ts +1 -1
  39. package/dist/validation-utils.d.cts +1 -1
  40. package/dist/validation-utils.d.ts +1 -1
  41. package/dist/validation-valibot.d.cts +1 -1
  42. package/dist/validation-valibot.d.ts +1 -1
  43. package/dist/validation.d.cts +1 -1
  44. package/dist/validation.d.ts +1 -1
  45. package/package.json +1 -1
  46. package/dist/chunk-A7R6GEMA.js.map +0 -1
  47. package/dist/chunk-N2HOVRRN.js +0 -150
  48. package/dist/chunk-N2HOVRRN.js.map +0 -1
  49. package/dist/chunk-O4ZLR7AN.cjs +0 -173
  50. package/dist/chunk-O4ZLR7AN.cjs.map +0 -1
  51. package/dist/chunk-QQSBW6N3.cjs.map +0 -1
  52. package/dist/chunk-QZ4PK62A.js.map +0 -1
  53. package/dist/chunk-WVSLOSNU.cjs.map +0 -1
package/dist/inputs.cjs CHANGED
@@ -1,57 +1,57 @@
1
1
  'use strict';
2
2
 
3
- var chunkWVSLOSNU_cjs = require('./chunk-WVSLOSNU.cjs');
4
- require('./chunk-QQSBW6N3.cjs');
3
+ var chunkED4UK63G_cjs = require('./chunk-ED4UK63G.cjs');
4
+ var chunkQRI5TMES_cjs = require('./chunk-QRI5TMES.cjs');
5
5
 
6
6
 
7
7
 
8
8
  Object.defineProperty(exports, "Checkbox", {
9
9
  enumerable: true,
10
- get: function () { return chunkWVSLOSNU_cjs.Checkbox; }
10
+ get: function () { return chunkED4UK63G_cjs.Checkbox; }
11
11
  });
12
12
  Object.defineProperty(exports, "CheckboxGroup", {
13
13
  enumerable: true,
14
- get: function () { return chunkWVSLOSNU_cjs.CheckboxGroup; }
14
+ get: function () { return chunkED4UK63G_cjs.CheckboxGroup; }
15
15
  });
16
16
  Object.defineProperty(exports, "DatePicker", {
17
17
  enumerable: true,
18
- get: function () { return chunkWVSLOSNU_cjs.DatePicker; }
18
+ get: function () { return chunkED4UK63G_cjs.DatePicker; }
19
19
  });
20
20
  Object.defineProperty(exports, "DateRangePicker", {
21
21
  enumerable: true,
22
- get: function () { return chunkWVSLOSNU_cjs.DateRangePicker; }
22
+ get: function () { return chunkED4UK63G_cjs.DateRangePicker; }
23
23
  });
24
24
  Object.defineProperty(exports, "FileInput", {
25
25
  enumerable: true,
26
- get: function () { return chunkWVSLOSNU_cjs.FileInput; }
26
+ get: function () { return chunkED4UK63G_cjs.FileInput; }
27
27
  });
28
28
  Object.defineProperty(exports, "MultiSelect", {
29
29
  enumerable: true,
30
- get: function () { return chunkWVSLOSNU_cjs.MultiSelect; }
30
+ get: function () { return chunkED4UK63G_cjs.MultiSelect; }
31
31
  });
32
32
  Object.defineProperty(exports, "Radio", {
33
33
  enumerable: true,
34
- get: function () { return chunkWVSLOSNU_cjs.Radio; }
34
+ get: function () { return chunkED4UK63G_cjs.Radio; }
35
35
  });
36
36
  Object.defineProperty(exports, "Select", {
37
37
  enumerable: true,
38
- get: function () { return chunkWVSLOSNU_cjs.Select; }
38
+ get: function () { return chunkED4UK63G_cjs.Select; }
39
39
  });
40
40
  Object.defineProperty(exports, "Switch", {
41
41
  enumerable: true,
42
- get: function () { return chunkWVSLOSNU_cjs.Switch; }
42
+ get: function () { return chunkED4UK63G_cjs.Switch; }
43
43
  });
44
44
  Object.defineProperty(exports, "TextArea", {
45
45
  enumerable: true,
46
- get: function () { return chunkWVSLOSNU_cjs.TextArea; }
46
+ get: function () { return chunkED4UK63G_cjs.TextArea; }
47
47
  });
48
- Object.defineProperty(exports, "TextInput", {
48
+ Object.defineProperty(exports, "TimePicker", {
49
49
  enumerable: true,
50
- get: function () { return chunkWVSLOSNU_cjs.TextInput; }
50
+ get: function () { return chunkED4UK63G_cjs.TimePicker; }
51
51
  });
52
- Object.defineProperty(exports, "TimePicker", {
52
+ Object.defineProperty(exports, "TextInput", {
53
53
  enumerable: true,
54
- get: function () { return chunkWVSLOSNU_cjs.TimePicker; }
54
+ get: function () { return chunkQRI5TMES_cjs.TextInput; }
55
55
  });
56
56
  //# sourceMappingURL=inputs.cjs.map
57
57
  //# sourceMappingURL=inputs.cjs.map
package/dist/inputs.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { I as InputProps } from './types-CnOCn7b3.cjs';
2
+ import { I as InputProps } from './types-BemGfSPA.cjs';
3
3
 
4
4
  /**
5
5
  * TextInput - High-performance text input component (ShadCN-based)
package/dist/inputs.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { I as InputProps } from './types-CnOCn7b3.js';
2
+ import { I as InputProps } from './types-BemGfSPA.js';
3
3
 
4
4
  /**
5
5
  * TextInput - High-performance text input component (ShadCN-based)
package/dist/inputs.js CHANGED
@@ -1,4 +1,4 @@
1
- export { Checkbox, CheckboxGroup, DatePicker, DateRangePicker, FileInput, MultiSelect, Radio, Select, Switch, TextArea, TextInput, TimePicker } from './chunk-QZ4PK62A.js';
2
- import './chunk-A7R6GEMA.js';
1
+ export { Checkbox, CheckboxGroup, DatePicker, DateRangePicker, FileInput, MultiSelect, Radio, Select, Switch, TextArea, TimePicker } from './chunk-4ROWNTY6.js';
2
+ export { TextInput } from './chunk-455PI4LV.js';
3
3
  //# sourceMappingURL=inputs.js.map
4
4
  //# sourceMappingURL=inputs.js.map
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- var chunkKPHMVGTU_cjs = require('./chunk-KPHMVGTU.cjs');
4
- var chunkWVSLOSNU_cjs = require('./chunk-WVSLOSNU.cjs');
5
- require('./chunk-QQSBW6N3.cjs');
3
+ var chunkMUBEMXI7_cjs = require('./chunk-MUBEMXI7.cjs');
4
+ var chunkED4UK63G_cjs = require('./chunk-ED4UK63G.cjs');
5
+ var chunkQRI5TMES_cjs = require('./chunk-QRI5TMES.cjs');
6
6
  var React2 = require('react');
7
7
 
8
8
  function _interopNamespace(e) {
@@ -565,7 +565,7 @@ function useContactForm(options) {
565
565
  window.location.assign(destination);
566
566
  }, 150);
567
567
  }, [navigate, redirectUrl]);
568
- const form = chunkKPHMVGTU_cjs.useForm({
568
+ const form = chunkMUBEMXI7_cjs.useForm({
569
569
  initialValues: React2.useMemo(
570
570
  () => generateInitialValues(formFields),
571
571
  [formFields]
@@ -643,7 +643,7 @@ function DynamicFormField({
643
643
  const usesInlineCheckboxLabel = field.type === "checkbox";
644
644
  const shouldRenderFieldLabel = renderLabel && !usesGroupLegend && !usesInlineCheckboxLabel;
645
645
  return /* @__PURE__ */ React2__namespace.createElement(
646
- chunkKPHMVGTU_cjs.Field,
646
+ chunkMUBEMXI7_cjs.Field,
647
647
  {
648
648
  name: field.name,
649
649
  label: shouldRenderFieldLabel ? field.label : void 0,
@@ -652,7 +652,7 @@ function DynamicFormField({
652
652
  className
653
653
  },
654
654
  ({ field: formField, meta }) => /* @__PURE__ */ React2__namespace.createElement("div", null, (field.type === "text" || field.type === "email" || field.type === "tel" || field.type === "search" || field.type === "password" || field.type === "url") && /* @__PURE__ */ React2__namespace.createElement(
655
- chunkWVSLOSNU_cjs.TextInput,
655
+ chunkQRI5TMES_cjs.TextInput,
656
656
  {
657
657
  ...formField,
658
658
  id: fieldId,
@@ -663,7 +663,7 @@ function DynamicFormField({
663
663
  "aria-label": field.label
664
664
  }
665
665
  ), field.type === "number" && /* @__PURE__ */ React2__namespace.createElement(
666
- chunkWVSLOSNU_cjs.TextInput,
666
+ chunkQRI5TMES_cjs.TextInput,
667
667
  {
668
668
  ...formField,
669
669
  id: fieldId,
@@ -674,7 +674,7 @@ function DynamicFormField({
674
674
  "aria-label": field.label
675
675
  }
676
676
  ), field.type === "textarea" && /* @__PURE__ */ React2__namespace.createElement(
677
- chunkWVSLOSNU_cjs.TextArea,
677
+ chunkED4UK63G_cjs.TextArea,
678
678
  {
679
679
  ...formField,
680
680
  id: fieldId,
@@ -685,7 +685,7 @@ function DynamicFormField({
685
685
  "aria-label": field.label
686
686
  }
687
687
  ), field.type === "select" && field.options && /* @__PURE__ */ React2__namespace.createElement(
688
- chunkWVSLOSNU_cjs.Select,
688
+ chunkED4UK63G_cjs.Select,
689
689
  {
690
690
  ...formField,
691
691
  id: fieldId,
@@ -696,7 +696,7 @@ function DynamicFormField({
696
696
  "aria-label": field.label
697
697
  }
698
698
  ), field.type === "multi-select" && field.options && /* @__PURE__ */ React2__namespace.createElement(
699
- chunkWVSLOSNU_cjs.MultiSelect,
699
+ chunkED4UK63G_cjs.MultiSelect,
700
700
  {
701
701
  ...formField,
702
702
  id: fieldId,
@@ -707,7 +707,7 @@ function DynamicFormField({
707
707
  "aria-label": field.label
708
708
  }
709
709
  ), field.type === "radio" && field.options && /* @__PURE__ */ React2__namespace.createElement(
710
- chunkWVSLOSNU_cjs.Radio,
710
+ chunkED4UK63G_cjs.Radio,
711
711
  {
712
712
  ...formField,
713
713
  id: fieldId,
@@ -721,7 +721,7 @@ function DynamicFormField({
721
721
  "aria-label": field.label
722
722
  }
723
723
  ), field.type === "checkbox" && /* @__PURE__ */ React2__namespace.createElement(
724
- chunkWVSLOSNU_cjs.Checkbox,
724
+ chunkED4UK63G_cjs.Checkbox,
725
725
  {
726
726
  ...formField,
727
727
  id: fieldId,
@@ -735,7 +735,7 @@ function DynamicFormField({
735
735
  "aria-label": field.label
736
736
  }
737
737
  ), field.type === "checkbox-group" && field.options && /* @__PURE__ */ React2__namespace.createElement(
738
- chunkWVSLOSNU_cjs.CheckboxGroup,
738
+ chunkED4UK63G_cjs.CheckboxGroup,
739
739
  {
740
740
  ...formField,
741
741
  id: fieldId,
@@ -749,7 +749,7 @@ function DynamicFormField({
749
749
  "aria-label": field.label
750
750
  }
751
751
  ), (field.type === "date-picker" || field.type === "date") && /* @__PURE__ */ React2__namespace.createElement(
752
- chunkWVSLOSNU_cjs.DatePicker,
752
+ chunkED4UK63G_cjs.DatePicker,
753
753
  {
754
754
  ...formField,
755
755
  id: fieldId,
@@ -759,7 +759,7 @@ function DynamicFormField({
759
759
  "aria-label": field.label
760
760
  }
761
761
  ), field.type === "date-range" && /* @__PURE__ */ React2__namespace.createElement(
762
- chunkWVSLOSNU_cjs.DateRangePicker,
762
+ chunkED4UK63G_cjs.DateRangePicker,
763
763
  {
764
764
  ...formField,
765
765
  id: fieldId,
@@ -769,7 +769,7 @@ function DynamicFormField({
769
769
  "aria-label": field.label
770
770
  }
771
771
  ), field.type === "time" && /* @__PURE__ */ React2__namespace.createElement(
772
- chunkWVSLOSNU_cjs.TimePicker,
772
+ chunkED4UK63G_cjs.TimePicker,
773
773
  {
774
774
  ...formField,
775
775
  id: fieldId,
@@ -779,7 +779,7 @@ function DynamicFormField({
779
779
  "aria-label": field.label
780
780
  }
781
781
  ), field.type === "file" && /* @__PURE__ */ React2__namespace.createElement(
782
- chunkWVSLOSNU_cjs.FileInput,
782
+ chunkED4UK63G_cjs.FileInput,
783
783
  {
784
784
  ...formField,
785
785
  id: fieldId,
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { ReactNode } from 'react';
3
- import { d as FormSubmissionBehavior, N as NewFormSubmissionActionConfig, m as UseFormReturn } from './types-CnOCn7b3.cjs';
3
+ import { d as FormSubmissionBehavior, N as NewFormSubmissionActionConfig, m as UseFormReturn } from './types-BemGfSPA.cjs';
4
4
 
5
5
  /**
6
6
  * @page-speed/forms - Rails API Serializer
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { ReactNode } from 'react';
3
- import { d as FormSubmissionBehavior, N as NewFormSubmissionActionConfig, m as UseFormReturn } from './types-CnOCn7b3.js';
3
+ import { d as FormSubmissionBehavior, N as NewFormSubmissionActionConfig, m as UseFormReturn } from './types-BemGfSPA.js';
4
4
 
5
5
  /**
6
6
  * @page-speed/forms - Rails API Serializer
@@ -1,6 +1,6 @@
1
- import { useForm, Field } from './chunk-Q7VR374Y.js';
2
- import { TextInput, TextArea, Select, MultiSelect, Radio, Checkbox, CheckboxGroup, DatePicker, DateRangePicker, TimePicker, FileInput } from './chunk-QZ4PK62A.js';
3
- import './chunk-A7R6GEMA.js';
1
+ import { useForm, Field } from './chunk-MJYEXJ3U.js';
2
+ import { TextArea, Select, MultiSelect, Radio, Checkbox, CheckboxGroup, DatePicker, DateRangePicker, TimePicker, FileInput } from './chunk-4ROWNTY6.js';
3
+ import { TextInput } from './chunk-455PI4LV.js';
4
4
  import * as React2 from 'react';
5
5
  import { useState, useCallback, useMemo } from 'react';
6
6
 
@@ -340,6 +340,27 @@ interface FormRenderConfig {
340
340
  * Optional submission behavior configuration.
341
341
  */
342
342
  submissionConfig?: FormSubmissionConfig;
343
+ /**
344
+ * Optional layout configuration. If button-group, the form will be rendered with an input field and submit button.
345
+ * "button-group" is most commonly used for newsletter type forms.
346
+ * @default "standard"
347
+ */
348
+ formLayout?: "standard" | "button-group";
349
+ /**
350
+ * Size for button-group layout (only applies when formLayout is "button-group")
351
+ * @default "default"
352
+ */
353
+ buttonGroupSize?: "xs" | "sm" | "default" | "lg";
354
+ /**
355
+ * Submit button label for button-group layout
356
+ * @default "Submit"
357
+ */
358
+ submitLabel?: React.ReactNode;
359
+ /**
360
+ * Submit button variant for button-group layout
361
+ * @default "default"
362
+ */
363
+ submitVariant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost";
343
364
  }
344
365
  /**
345
366
  * Form component props
@@ -352,7 +373,12 @@ interface FormProps<T extends FormValues = FormValues> {
352
373
  /**
353
374
  * Form children
354
375
  */
355
- children: ReactNode;
376
+ children?: ReactNode;
377
+ /**
378
+ * Optional form fields for button-group layout rendering
379
+ * Required when using formLayout="button-group"
380
+ */
381
+ fields?: any[];
356
382
  /**
357
383
  * Additional className
358
384
  */
@@ -340,6 +340,27 @@ interface FormRenderConfig {
340
340
  * Optional submission behavior configuration.
341
341
  */
342
342
  submissionConfig?: FormSubmissionConfig;
343
+ /**
344
+ * Optional layout configuration. If button-group, the form will be rendered with an input field and submit button.
345
+ * "button-group" is most commonly used for newsletter type forms.
346
+ * @default "standard"
347
+ */
348
+ formLayout?: "standard" | "button-group";
349
+ /**
350
+ * Size for button-group layout (only applies when formLayout is "button-group")
351
+ * @default "default"
352
+ */
353
+ buttonGroupSize?: "xs" | "sm" | "default" | "lg";
354
+ /**
355
+ * Submit button label for button-group layout
356
+ * @default "Submit"
357
+ */
358
+ submitLabel?: React.ReactNode;
359
+ /**
360
+ * Submit button variant for button-group layout
361
+ * @default "default"
362
+ */
363
+ submitVariant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost";
343
364
  }
344
365
  /**
345
366
  * Form component props
@@ -352,7 +373,12 @@ interface FormProps<T extends FormValues = FormValues> {
352
373
  /**
353
374
  * Form children
354
375
  */
355
- children: ReactNode;
376
+ children?: ReactNode;
377
+ /**
378
+ * Optional form fields for button-group layout rendering
379
+ * Required when using formLayout="button-group"
380
+ */
381
+ fields?: any[];
356
382
  /**
357
383
  * Additional className
358
384
  */
@@ -1,4 +1,4 @@
1
- import { F as FieldValidator } from './types-CnOCn7b3.cjs';
1
+ import { F as FieldValidator } from './types-BemGfSPA.cjs';
2
2
  import 'react';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { F as FieldValidator } from './types-CnOCn7b3.js';
1
+ import { F as FieldValidator } from './types-BemGfSPA.js';
2
2
  import 'react';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { F as FieldValidator, b as FormValues } from './types-CnOCn7b3.cjs';
1
+ import { F as FieldValidator, b as FormValues } from './types-BemGfSPA.cjs';
2
2
  import 'react';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { F as FieldValidator, b as FormValues } from './types-CnOCn7b3.js';
1
+ import { F as FieldValidator, b as FormValues } from './types-BemGfSPA.js';
2
2
  import 'react';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { b as FormValues, V as ValidationSchema, F as FieldValidator } from './types-CnOCn7b3.cjs';
1
+ import { b as FormValues, V as ValidationSchema, F as FieldValidator } from './types-BemGfSPA.cjs';
2
2
  import 'react';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { b as FormValues, V as ValidationSchema, F as FieldValidator } from './types-CnOCn7b3.js';
1
+ import { b as FormValues, V as ValidationSchema, F as FieldValidator } from './types-BemGfSPA.js';
2
2
  import 'react';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- export { F as FieldValidator, a as ValidationMode, V as ValidationSchema } from './types-CnOCn7b3.cjs';
1
+ export { F as FieldValidator, a as ValidationMode, V as ValidationSchema } from './types-BemGfSPA.cjs';
2
2
  export { ErrorMessageFn, ValidationRuleOptions, alpha, alphanumeric, compose, creditCard, email, integer, matches, max, maxLength, min, minLength, numeric, oneOf, pattern, phone, postalCode, required, url } from './validation-rules.cjs';
3
3
  export { DebounceOptions, ErrorMessages, MessageTemplate, asyncValidator, crossFieldValidator, debounce, defaultMessages, getErrorMessage, messageRegistry, resetErrorMessages, setErrorMessages, when, withRaceConditionPrevention } from './validation-utils.cjs';
4
4
  import 'react';
@@ -1,4 +1,4 @@
1
- export { F as FieldValidator, a as ValidationMode, V as ValidationSchema } from './types-CnOCn7b3.js';
1
+ export { F as FieldValidator, a as ValidationMode, V as ValidationSchema } from './types-BemGfSPA.js';
2
2
  export { ErrorMessageFn, ValidationRuleOptions, alpha, alphanumeric, compose, creditCard, email, integer, matches, max, maxLength, min, minLength, numeric, oneOf, pattern, phone, postalCode, required, url } from './validation-rules.js';
3
3
  export { DebounceOptions, ErrorMessages, MessageTemplate, asyncValidator, crossFieldValidator, debounce, defaultMessages, getErrorMessage, messageRegistry, resetErrorMessages, setErrorMessages, when, withRaceConditionPrevention } from './validation-utils.js';
4
4
  import 'react';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@page-speed/forms",
3
- "version": "0.5.6",
3
+ "version": "0.5.8",
4
4
  "description": "Ultra-high-performance React form library with field-level reactivity and tree-shakable architecture",
5
5
  "keywords": [
6
6
  "react",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/lib/utils.ts","../src/components/ui/label.tsx","../src/components/ui/field.tsx","../src/components/ui/button.tsx","../src/core/label-group.tsx"],"names":["React","LabelPrimitive","React3","React4"],"mappings":"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","file":"chunk-A7R6GEMA.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\n/**\n * Normalizes browser autofill colors so inputs keep theme colors.\n */\nexport const INPUT_AUTOFILL_RESET_CLASSES =\n \"autofill:bg-transparent autofill:text-foreground \" +\n \"[&:-webkit-autofill]:[-webkit-text-fill-color:hsl(var(--foreground))] \" +\n \"[&:-webkit-autofill]:[caret-color:hsl(var(--foreground))] \" +\n \"[&:-webkit-autofill]:[box-shadow:0_0_0px_1000px_hsl(var(--background))_inset] \" +\n \"[&:-webkit-autofill:hover]:[box-shadow:0_0_0px_1000px_hsl(var(--background))_inset] \" +\n \"[&:-webkit-autofill:focus]:[box-shadow:0_0_0px_1000px_hsl(var(--background))_inset] \" +\n \"[&:-webkit-autofill]:[transition:background-color_9999s_ease-out,color_9999s_ease-out]\";\n","import * as React from \"react\"\nimport { Label as LabelPrimitive } from \"radix-ui\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Label({\n className,\n ...props\n}: React.ComponentProps<typeof LabelPrimitive.Root>) {\n return (\n <LabelPrimitive.Root\n data-slot=\"label\"\n className={cn(\n \"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Label }\n","import * as React from \"react\";\nimport { Label } from \"./label\";\nimport { cn } from \"../../lib/utils\";\n\ntype FieldOrientation = \"vertical\" | \"horizontal\";\n\ninterface FieldProps extends React.HTMLAttributes<HTMLDivElement> {\n orientation?: FieldOrientation;\n invalid?: boolean;\n}\n\n/**\n * Field - Container component for form inputs with validation display\n *\n * Provides consistent layout and spacing for form fields with labels,\n * inputs, descriptions, and error messages.\n */\nconst Field = React.forwardRef<HTMLDivElement, FieldProps>(\n({ className, orientation = \"vertical\", invalid = false, ...props }, ref) => {\n return (\n <div\n ref={ref}\n data-slot=\"field\"\n data-orientation={orientation}\n data-invalid={invalid || undefined}\n className={cn(\n // Use space-y instead of flex to avoid interfering with parent grid layouts\n orientation === \"horizontal\"\n ? \"flex items-center gap-2\"\n : \"space-y-1.5\",\n className,\n )}\n {...props}\n />\n );\n});\nField.displayName = \"Field\";\n\n/**\n * FieldGroup - Container for multiple related fields\n *\n * Used to group fields together (e.g., first name + last name in a row)\n */\nconst FieldGroup = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n data-slot=\"field-group\"\n className={cn(\"flex flex-col gap-4\", className)}\n {...props}\n />\n );\n});\nFieldGroup.displayName = \"FieldGroup\";\n\n/**\n * FieldLabel - Label component for form fields\n *\n * Wrapper around ShadCN Label with consistent styling\n */\nconst FieldLabel = React.forwardRef<\n HTMLLabelElement,\n React.LabelHTMLAttributes<HTMLLabelElement> & {\n required?: boolean;\n }\n>(({ className, required, children, ...props }, ref) => {\n return (\n <Label\n ref={ref}\n data-slot=\"field-label\"\n className={cn(\n \"text-sm font-medium leading-none select-none\",\n \"peer-disabled:cursor-not-allowed peer-disabled:opacity-50\",\n className,\n )}\n {...props}\n >\n {children}\n {required && <span className=\"text-destructive ml-1\">*</span>}\n </Label>\n );\n});\nFieldLabel.displayName = \"FieldLabel\";\n\n/**\n * FieldDescription - Helper text for form fields\n *\n * Displays additional information or instructions for the field\n */\nconst FieldDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => {\n return (\n <p\n ref={ref}\n data-slot=\"field-description\"\n className={cn(\"text-sm opacity-70\", className)}\n {...props}\n />\n );\n});\nFieldDescription.displayName = \"FieldDescription\";\n\n/**\n * FieldError - Error message display for form fields\n *\n * Shows validation errors with proper styling and accessibility\n */\nconst FieldError = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => {\n return (\n <p\n ref={ref}\n data-slot=\"field-error\"\n role=\"alert\"\n aria-live=\"polite\"\n className={cn(\"text-sm text-destructive\", className)}\n {...props}\n />\n );\n});\nFieldError.displayName = \"FieldError\";\n\nexport { Field, FieldGroup, FieldLabel, FieldDescription, FieldError };\n","import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot } from \"radix-ui\"\n\nimport { cn } from \"../../lib/utils\"\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 aria-invalid:border-destructive\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20\",\n outline:\n \"border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground\",\n secondary:\n \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n ghost:\n \"hover:bg-accent hover:text-accent-foreground\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n xs: \"h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3\",\n sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n icon: \"size-9\",\n \"icon-xs\": \"size-6 rounded-md [&_svg:not([class*='size-'])]:size-3\",\n \"icon-sm\": \"size-8\",\n \"icon-lg\": \"size-10\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction Button({\n className,\n variant = \"default\",\n size = \"default\",\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean\n }) {\n const Comp = asChild ? Slot.Root : \"button\"\n\n return (\n <Comp\n data-slot=\"button\"\n data-variant={variant}\n data-size={size}\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n )\n}\n\nexport { Button, buttonVariants }\n","\"use client\";\n\nimport * as React from \"react\";\nimport type { ReactNode } from \"react\";\nimport {\n FieldDescription,\n FieldLabel,\n} from \"../components/ui/field\";\nimport { cn } from \"../lib/utils\";\n\nexport type LabelGroupProps = {\n variant?: \"legend\" | \"label\" | \"text\";\n secondary?: ReactNode;\n secondaryId?: string;\n primary?: ReactNode;\n labelHtmlFor?: string;\n required?: boolean;\n primaryClassName?: string;\n secondaryClassName?: string;\n};\n\nconst LabelGroup = ({\n labelHtmlFor,\n required = false,\n variant = \"label\",\n secondaryId,\n secondary,\n primary,\n primaryClassName,\n secondaryClassName,\n}: LabelGroupProps) => {\n const primaryClasses = cn(\n \"text-sm font-medium leading-snug\",\n variant === \"legend\" ? \"mb-1.5\" : \"mb-1 block\",\n primaryClassName,\n );\n\n const requiredIndicator =\n required && variant !== \"label\" ? (\n <span className=\"text-destructive pl-0.5\" aria-label=\"required\">\n *\n </span>\n ) : null;\n\n let primaryElement: ReactNode = null;\n if (primary) {\n if (variant === \"label\") {\n primaryElement = (\n <FieldLabel\n htmlFor={labelHtmlFor}\n required={required}\n className={primaryClasses}\n >\n {primary}\n </FieldLabel>\n );\n } else if (variant === \"legend\") {\n primaryElement = (\n <legend data-slot=\"field-legend\" className={primaryClasses}>\n {primary}\n {requiredIndicator}\n </legend>\n );\n } else {\n primaryElement = (\n <div data-slot=\"field-label\" className={primaryClasses}>\n {primary}\n {requiredIndicator}\n </div>\n );\n }\n }\n\n const secondaryElement = secondary ? (\n <FieldDescription\n id={secondaryId}\n className={cn(\"leading-normal font-normal\", secondaryClassName)}\n >\n {secondary}\n </FieldDescription>\n ) : null;\n\n if (!primaryElement && !secondaryElement) return null;\n\n // Legend should remain a direct child of fieldset for proper semantics.\n if (variant === \"legend\") {\n return (\n <>\n {primaryElement}\n {secondaryElement}\n </>\n );\n }\n\n return (\n <div className=\"flex flex-1 flex-col gap-0.5\">\n {primaryElement}\n {secondaryElement}\n </div>\n );\n};\n\nexport { LabelGroup };\n"]}
@@ -1,150 +0,0 @@
1
- import { FormContext } from './chunk-Q7VR374Y.js';
2
- import { cn, Button } from './chunk-A7R6GEMA.js';
3
- import * as React2 from 'react';
4
-
5
- function renderMessage(message, fallbackClassName, className) {
6
- if (typeof message === "string") {
7
- return /* @__PURE__ */ React2.createElement(
8
- "p",
9
- {
10
- className: cn(
11
- "text-sm font-medium text-center text-balance",
12
- className
13
- )
14
- },
15
- message
16
- );
17
- }
18
- return /* @__PURE__ */ React2.createElement("div", { className: cn(fallbackClassName, className) }, message);
19
- }
20
- function FormFeedback({
21
- successMessage,
22
- submissionError,
23
- successMessageClassName,
24
- errorMessageClassName
25
- }) {
26
- if (!successMessage && !submissionError) {
27
- return null;
28
- }
29
- return /* @__PURE__ */ React2.createElement(React2.Fragment, null, successMessage ? /* @__PURE__ */ React2.createElement(
30
- "div",
31
- {
32
- className: cn(
33
- "rounded-md border border-primary bg-primary px-4 py-3 shadow-sm",
34
- successMessageClassName
35
- ),
36
- role: "status",
37
- "aria-live": "polite"
38
- },
39
- renderMessage(
40
- successMessage,
41
- "text-primary-foreground",
42
- "text-primary-foreground"
43
- )
44
- ) : null, submissionError ? /* @__PURE__ */ React2.createElement(
45
- "div",
46
- {
47
- className: cn(
48
- "rounded-md border border-destructive bg-destructive px-4 py-3 shadow-sm",
49
- errorMessageClassName
50
- ),
51
- role: "alert",
52
- "aria-live": "assertive"
53
- },
54
- renderMessage(
55
- submissionError,
56
- "text-destructive-foreground",
57
- "text-destructive-foreground"
58
- )
59
- ) : null);
60
- }
61
- FormFeedback.displayName = "FormFeedback";
62
-
63
- // src/core/Form.tsx
64
- function Form({
65
- form,
66
- children,
67
- className,
68
- action,
69
- method,
70
- noValidate = true,
71
- submissionConfig,
72
- successMessage,
73
- submissionError,
74
- successMessageClassName,
75
- errorMessageClassName,
76
- onNewSubmission,
77
- notificationConfig,
78
- styleConfig,
79
- formConfig,
80
- ...props
81
- }) {
82
- const handleFormSubmit = React2.useCallback(
83
- async (e) => {
84
- try {
85
- await form.handleSubmit(e);
86
- } catch {
87
- }
88
- },
89
- [form]
90
- );
91
- const resolvedClassName = className ?? styleConfig?.formClassName;
92
- const resolvedAction = action ?? formConfig?.endpoint;
93
- const resolvedMethod = method ?? formConfig?.method ?? "post";
94
- const resolvedSubmissionConfig = submissionConfig ?? formConfig?.submissionConfig;
95
- const resolvedSuccessMessage = successMessage ?? notificationConfig?.successMessage;
96
- const resolvedSubmissionError = submissionError ?? notificationConfig?.submissionError;
97
- const resolvedSuccessMessageClassName = successMessageClassName ?? styleConfig?.successMessageClassName;
98
- const resolvedErrorMessageClassName = errorMessageClassName ?? styleConfig?.errorMessageClassName;
99
- const behavior = resolvedSubmissionConfig?.behavior || "showConfirmation";
100
- const shouldManageSubmissionUi = resolvedSubmissionConfig !== void 0 || resolvedSuccessMessage !== void 0 || resolvedSuccessMessageClassName !== void 0 || resolvedErrorMessageClassName !== void 0 || resolvedSubmissionError != null || onNewSubmission !== void 0;
101
- const hasSubmissionError = Boolean(resolvedSubmissionError);
102
- const isSubmissionSuccessful = shouldManageSubmissionUi && form.status === "success" && !hasSubmissionError;
103
- const defaultSuccessMessage = behavior === "redirect" ? "Form submitted successfully. Redirecting..." : "Thank you. Your form has been submitted successfully.";
104
- const finalSuccessMessage = resolvedSuccessMessage ?? defaultSuccessMessage;
105
- const shouldRenderCustomComponent = isSubmissionSuccessful && behavior === "renderCustomComponent" && Boolean(resolvedSubmissionConfig?.customComponent);
106
- const newSubmissionAction = resolvedSubmissionConfig?.newFormSubmissionAction;
107
- const showNewSubmissionAction = isSubmissionSuccessful && (typeof newSubmissionAction?.enable === "boolean" ? newSubmissionAction.enable : Boolean(newSubmissionAction?.label));
108
- const newSubmissionLabel = newSubmissionAction?.label ?? "Submit another response";
109
- const handleNewSubmission = React2.useCallback(() => {
110
- form.resetForm();
111
- onNewSubmission?.();
112
- }, [form, onNewSubmission]);
113
- return /* @__PURE__ */ React2.createElement(FormContext.Provider, { value: form }, /* @__PURE__ */ React2.createElement(
114
- "form",
115
- {
116
- onSubmit: handleFormSubmit,
117
- action: resolvedAction,
118
- method: resolvedMethod,
119
- noValidate,
120
- className: resolvedClassName,
121
- ...props
122
- },
123
- isSubmissionSuccessful ? /* @__PURE__ */ React2.createElement("div", { className: "space-y-4" }, shouldRenderCustomComponent ? resolvedSubmissionConfig?.customComponent : /* @__PURE__ */ React2.createElement(
124
- FormFeedback,
125
- {
126
- successMessage: finalSuccessMessage,
127
- successMessageClassName: resolvedSuccessMessageClassName
128
- }
129
- ), showNewSubmissionAction ? /* @__PURE__ */ React2.createElement(
130
- Button,
131
- {
132
- type: "button",
133
- variant: "outline",
134
- onClick: handleNewSubmission
135
- },
136
- newSubmissionLabel
137
- ) : null) : /* @__PURE__ */ React2.createElement(React2.Fragment, null, children, resolvedSubmissionError ? /* @__PURE__ */ React2.createElement("div", { className: "mt-4" }, /* @__PURE__ */ React2.createElement(
138
- FormFeedback,
139
- {
140
- submissionError: resolvedSubmissionError,
141
- errorMessageClassName: resolvedErrorMessageClassName
142
- }
143
- )) : null)
144
- ));
145
- }
146
- Form.displayName = "Form";
147
-
148
- export { Form, FormFeedback };
149
- //# sourceMappingURL=chunk-N2HOVRRN.js.map
150
- //# sourceMappingURL=chunk-N2HOVRRN.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/form-feedback.tsx","../src/core/Form.tsx"],"names":["React"],"mappings":"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","file":"chunk-N2HOVRRN.js","sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../lib/utils\";\n\nexport interface FormFeedbackProps {\n successMessage?: React.ReactNode;\n submissionError?: React.ReactNode;\n successMessageClassName?: string;\n errorMessageClassName?: string;\n}\n\nfunction renderMessage(\n message: React.ReactNode,\n fallbackClassName: string,\n className?: string,\n) {\n if (typeof message === \"string\") {\n return (\n <p\n className={cn(\n \"text-sm font-medium text-center text-balance\",\n className,\n )}\n >\n {message}\n </p>\n );\n }\n\n return <div className={cn(fallbackClassName, className)}>{message}</div>;\n}\n\nexport function FormFeedback({\n successMessage,\n submissionError,\n successMessageClassName,\n errorMessageClassName,\n}: FormFeedbackProps) {\n if (!successMessage && !submissionError) {\n return null;\n }\n\n return (\n <>\n {successMessage ? (\n <div\n className={cn(\n \"rounded-md border border-primary bg-primary px-4 py-3 shadow-sm\",\n successMessageClassName,\n )}\n role=\"status\"\n aria-live=\"polite\"\n >\n {renderMessage(\n successMessage,\n \"text-primary-foreground\",\n \"text-primary-foreground\",\n )}\n </div>\n ) : null}\n\n {submissionError ? (\n <div\n className={cn(\n \"rounded-md border border-destructive bg-destructive px-4 py-3 shadow-sm\",\n errorMessageClassName,\n )}\n role=\"alert\"\n aria-live=\"assertive\"\n >\n {renderMessage(\n submissionError,\n \"text-destructive-foreground\",\n \"text-destructive-foreground\",\n )}\n </div>\n ) : null}\n </>\n );\n}\n\nFormFeedback.displayName = \"FormFeedback\";\n","\"use client\";\n\nimport * as React from \"react\";\nimport { FormContext } from \"./FormContext\";\nimport type { FormProps, FormValues } from \"./types\";\nimport { FormFeedback } from \"./form-feedback\";\nimport { Button } from \"../components/ui/button\";\n\n/**\n * Form - Progressive enhancement form component\n *\n * Provides form context to child components and handles form submission.\n * Supports progressive enhancement with server-side fallback.\n *\n * Features:\n * - Provides FormContext for useField hook\n * - Handles form submission with validation\n * - Progressive enhancement support (works without JavaScript)\n * - Accessible form semantics\n *\n * @example\n * ```tsx\n * const form = useForm({\n * initialValues: { email: '' },\n * onSubmit: async (values) => {\n * await submitForm(values);\n * },\n * });\n *\n * return (\n * <Form form={form} action=\"/api/submit\" method=\"post\">\n * <input {...form.getFieldProps('email')} />\n * <button type=\"submit\">Submit</button>\n * </Form>\n * );\n * ```\n *\n * @see https://opensite.ai/developers/page-speed/forms/form\n */\nexport function Form<T extends FormValues = FormValues>({\n form,\n children,\n className,\n action,\n method,\n noValidate = true,\n submissionConfig,\n successMessage,\n submissionError,\n successMessageClassName,\n errorMessageClassName,\n onNewSubmission,\n notificationConfig,\n styleConfig,\n formConfig,\n ...props\n}: FormProps<T> & React.FormHTMLAttributes<HTMLFormElement>) {\n // Wrap handleSubmit to catch any unhandled rejections\n const handleFormSubmit = React.useCallback(\n async (e: React.FormEvent) => {\n try {\n await form.handleSubmit(e);\n } catch {\n // Error is already handled by useForm, just prevent unhandled rejection\n // The form status and errors are already set by useForm's error handling\n }\n },\n [form],\n );\n\n const resolvedClassName = className ?? styleConfig?.formClassName;\n const resolvedAction = action ?? formConfig?.endpoint;\n const resolvedMethod = method ?? formConfig?.method ?? \"post\";\n const resolvedSubmissionConfig = submissionConfig ?? formConfig?.submissionConfig;\n const resolvedSuccessMessage =\n successMessage ?? notificationConfig?.successMessage;\n const resolvedSubmissionError =\n submissionError ?? notificationConfig?.submissionError;\n const resolvedSuccessMessageClassName =\n successMessageClassName ?? styleConfig?.successMessageClassName;\n const resolvedErrorMessageClassName =\n errorMessageClassName ?? styleConfig?.errorMessageClassName;\n\n const behavior = resolvedSubmissionConfig?.behavior || \"showConfirmation\";\n\n const shouldManageSubmissionUi =\n resolvedSubmissionConfig !== undefined ||\n resolvedSuccessMessage !== undefined ||\n resolvedSuccessMessageClassName !== undefined ||\n resolvedErrorMessageClassName !== undefined ||\n resolvedSubmissionError != null ||\n onNewSubmission !== undefined;\n\n const hasSubmissionError = Boolean(resolvedSubmissionError);\n\n const isSubmissionSuccessful =\n shouldManageSubmissionUi &&\n form.status === \"success\" &&\n !hasSubmissionError;\n\n const defaultSuccessMessage =\n behavior === \"redirect\"\n ? \"Form submitted successfully. Redirecting...\"\n : \"Thank you. Your form has been submitted successfully.\";\n\n const finalSuccessMessage = resolvedSuccessMessage ?? defaultSuccessMessage;\n\n const shouldRenderCustomComponent =\n isSubmissionSuccessful &&\n behavior === \"renderCustomComponent\" &&\n Boolean(resolvedSubmissionConfig?.customComponent);\n\n const newSubmissionAction = resolvedSubmissionConfig?.newFormSubmissionAction;\n\n const showNewSubmissionAction =\n isSubmissionSuccessful &&\n (typeof newSubmissionAction?.enable === \"boolean\"\n ? newSubmissionAction.enable\n : Boolean(newSubmissionAction?.label));\n\n const newSubmissionLabel =\n newSubmissionAction?.label ?? \"Submit another response\";\n\n const handleNewSubmission = React.useCallback(() => {\n form.resetForm();\n onNewSubmission?.();\n }, [form, onNewSubmission]);\n\n return (\n <FormContext.Provider value={form}>\n <form\n onSubmit={handleFormSubmit}\n action={resolvedAction}\n method={resolvedMethod}\n noValidate={noValidate}\n className={resolvedClassName}\n {...props}\n >\n {isSubmissionSuccessful ? (\n <div className=\"space-y-4\">\n {shouldRenderCustomComponent ? (\n resolvedSubmissionConfig?.customComponent\n ) : (\n <FormFeedback\n successMessage={finalSuccessMessage}\n successMessageClassName={resolvedSuccessMessageClassName}\n />\n )}\n\n {showNewSubmissionAction ? (\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={handleNewSubmission}\n >\n {newSubmissionLabel}\n </Button>\n ) : null}\n </div>\n ) : (\n <>\n {children}\n {resolvedSubmissionError ? (\n <div className=\"mt-4\">\n <FormFeedback\n submissionError={resolvedSubmissionError}\n errorMessageClassName={resolvedErrorMessageClassName}\n />\n </div>\n ) : null}\n </>\n )}\n </form>\n </FormContext.Provider>\n );\n}\n\nForm.displayName = \"Form\";\n"]}