@opensite/ui 1.8.2 → 1.8.4

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 (171) hide show
  1. package/dist/about-story-gallery.cjs +3 -30
  2. package/dist/about-story-gallery.d.cts +1 -1
  3. package/dist/about-story-gallery.d.ts +1 -1
  4. package/dist/about-story-gallery.js +3 -30
  5. package/dist/components.d.cts +1 -1
  6. package/dist/components.d.ts +1 -1
  7. package/dist/contact-callback.cjs +526 -273
  8. package/dist/contact-callback.d.cts +39 -59
  9. package/dist/contact-callback.d.ts +39 -59
  10. package/dist/contact-callback.js +528 -274
  11. package/dist/contact-card.cjs +459 -183
  12. package/dist/contact-card.d.cts +26 -49
  13. package/dist/contact-card.d.ts +26 -49
  14. package/dist/contact-card.js +461 -183
  15. package/dist/contact-careers.cjs +614 -510
  16. package/dist/contact-careers.d.cts +32 -55
  17. package/dist/contact-careers.d.ts +32 -55
  18. package/dist/contact-careers.js +616 -510
  19. package/dist/contact-catering.cjs +507 -501
  20. package/dist/contact-catering.d.cts +27 -61
  21. package/dist/contact-catering.d.ts +27 -61
  22. package/dist/contact-catering.js +509 -500
  23. package/dist/contact-consultation.cjs +484 -253
  24. package/dist/contact-consultation.d.cts +29 -56
  25. package/dist/contact-consultation.d.ts +29 -56
  26. package/dist/contact-consultation.js +486 -253
  27. package/dist/contact-dark.cjs +296 -296
  28. package/dist/contact-dark.d.cts +1 -1
  29. package/dist/contact-dark.d.ts +1 -1
  30. package/dist/contact-dark.js +297 -296
  31. package/dist/contact-demo.d.cts +1 -1
  32. package/dist/contact-demo.d.ts +1 -1
  33. package/dist/contact-emergency.d.cts +1 -1
  34. package/dist/contact-emergency.d.ts +1 -1
  35. package/dist/contact-event.d.cts +1 -1
  36. package/dist/contact-event.d.ts +1 -1
  37. package/dist/contact-faq.cjs +247 -250
  38. package/dist/contact-faq.d.cts +1 -1
  39. package/dist/contact-faq.d.ts +1 -1
  40. package/dist/contact-faq.js +248 -250
  41. package/dist/contact-feedback.d.cts +1 -1
  42. package/dist/contact-feedback.d.ts +1 -1
  43. package/dist/contact-fitness.d.cts +1 -1
  44. package/dist/contact-fitness.d.ts +1 -1
  45. package/dist/contact-guest.d.cts +1 -1
  46. package/dist/contact-guest.d.ts +1 -1
  47. package/dist/contact-image.d.cts +1 -1
  48. package/dist/contact-image.d.ts +1 -1
  49. package/dist/contact-insurance.d.cts +1 -1
  50. package/dist/contact-insurance.d.ts +1 -1
  51. package/dist/contact-interview.d.cts +1 -1
  52. package/dist/contact-interview.d.ts +1 -1
  53. package/dist/contact-locations.d.cts +1 -1
  54. package/dist/contact-locations.d.ts +1 -1
  55. package/dist/contact-maintenance.d.cts +1 -1
  56. package/dist/contact-maintenance.d.ts +1 -1
  57. package/dist/contact-map.d.cts +1 -1
  58. package/dist/contact-map.d.ts +1 -1
  59. package/dist/contact-minimal.d.cts +1 -1
  60. package/dist/contact-minimal.d.ts +1 -1
  61. package/dist/contact-moving.d.cts +1 -1
  62. package/dist/contact-moving.d.ts +1 -1
  63. package/dist/contact-multistep.d.cts +1 -1
  64. package/dist/contact-multistep.d.ts +1 -1
  65. package/dist/contact-partnership.d.cts +1 -1
  66. package/dist/contact-partnership.d.ts +1 -1
  67. package/dist/contact-photography.cjs +247 -250
  68. package/dist/contact-photography.d.cts +1 -1
  69. package/dist/contact-photography.d.ts +1 -1
  70. package/dist/contact-photography.js +248 -250
  71. package/dist/contact-press.d.cts +1 -1
  72. package/dist/contact-press.d.ts +1 -1
  73. package/dist/contact-quote.d.cts +1 -1
  74. package/dist/contact-quote.d.ts +1 -1
  75. package/dist/contact-referral.d.cts +1 -1
  76. package/dist/contact-referral.d.ts +1 -1
  77. package/dist/contact-report.d.cts +1 -1
  78. package/dist/contact-report.d.ts +1 -1
  79. package/dist/contact-reservation.d.cts +1 -1
  80. package/dist/contact-reservation.d.ts +1 -1
  81. package/dist/contact-retreat.d.cts +1 -1
  82. package/dist/contact-retreat.d.ts +1 -1
  83. package/dist/contact-rsvp.d.cts +1 -1
  84. package/dist/contact-rsvp.d.ts +1 -1
  85. package/dist/contact-sales.d.cts +1 -1
  86. package/dist/contact-sales.d.ts +1 -1
  87. package/dist/contact-schedule.d.cts +1 -1
  88. package/dist/contact-schedule.d.ts +1 -1
  89. package/dist/contact-sponsorship.d.cts +1 -1
  90. package/dist/contact-sponsorship.d.ts +1 -1
  91. package/dist/contact-support.d.cts +1 -1
  92. package/dist/contact-support.d.ts +1 -1
  93. package/dist/contact-tenant.d.cts +1 -1
  94. package/dist/contact-tenant.d.ts +1 -1
  95. package/dist/contact-vendor.d.cts +1 -1
  96. package/dist/contact-vendor.d.ts +1 -1
  97. package/dist/contact-volunteer.d.cts +1 -1
  98. package/dist/contact-volunteer.d.ts +1 -1
  99. package/dist/contact-warranty.d.cts +1 -1
  100. package/dist/contact-warranty.d.ts +1 -1
  101. package/dist/contact-wedding.d.cts +1 -1
  102. package/dist/contact-wedding.d.ts +1 -1
  103. package/dist/cta-app-download-newsletter.d.cts +1 -1
  104. package/dist/cta-app-download-newsletter.d.ts +1 -1
  105. package/dist/cta-newsletter-features.d.cts +1 -1
  106. package/dist/cta-newsletter-features.d.ts +1 -1
  107. package/dist/footer-accordion-social.d.cts +1 -1
  108. package/dist/footer-accordion-social.d.ts +1 -1
  109. package/dist/footer-newsletter-contact.d.cts +1 -1
  110. package/dist/footer-newsletter-contact.d.ts +1 -1
  111. package/dist/footer-newsletter-minimal.d.cts +1 -1
  112. package/dist/footer-newsletter-minimal.d.ts +1 -1
  113. package/dist/footer-split-image-accordion.d.cts +1 -1
  114. package/dist/footer-split-image-accordion.d.ts +1 -1
  115. package/dist/{forms-nGgHUTBw.d.cts → forms-CStlFhnh.d.cts} +41 -0
  116. package/dist/{forms-nGgHUTBw.d.ts → forms-CStlFhnh.d.ts} +41 -0
  117. package/dist/hero-conversation-intelligence.cjs +1 -2
  118. package/dist/hero-conversation-intelligence.d.cts +1 -5
  119. package/dist/hero-conversation-intelligence.d.ts +1 -5
  120. package/dist/hero-conversation-intelligence.js +1 -2
  121. package/dist/hero-conversion-video-play.cjs +2 -2
  122. package/dist/hero-conversion-video-play.js +2 -2
  123. package/dist/hero-design-system-3d.cjs +162 -82
  124. package/dist/hero-design-system-3d.js +162 -82
  125. package/dist/hero-ecommerce-product-showcase.cjs +103 -81
  126. package/dist/hero-ecommerce-product-showcase.d.cts +5 -1
  127. package/dist/hero-ecommerce-product-showcase.d.ts +5 -1
  128. package/dist/hero-ecommerce-product-showcase.js +103 -81
  129. package/dist/hero-floating-images.cjs +1 -1
  130. package/dist/hero-floating-images.js +1 -1
  131. package/dist/hero-hiring-animated-text.cjs +4 -4
  132. package/dist/hero-hiring-animated-text.js +4 -4
  133. package/dist/hero-minimal-centered-dark.cjs +111 -82
  134. package/dist/hero-minimal-centered-dark.d.cts +1 -1
  135. package/dist/hero-minimal-centered-dark.d.ts +1 -1
  136. package/dist/hero-minimal-centered-dark.js +111 -82
  137. package/dist/hero-mobile-app-download.cjs +1 -1
  138. package/dist/hero-mobile-app-download.js +1 -1
  139. package/dist/hero-overlay-cta-grid.cjs +1 -1
  140. package/dist/hero-overlay-cta-grid.js +1 -1
  141. package/dist/hero-spiral-pattern-cards.cjs +1 -1
  142. package/dist/hero-spiral-pattern-cards.js +1 -1
  143. package/dist/hero-startup-launch-cta.cjs +1 -1
  144. package/dist/hero-startup-launch-cta.js +1 -1
  145. package/dist/hero-stats-social-proof.cjs +106 -90
  146. package/dist/hero-stats-social-proof.js +106 -90
  147. package/dist/hero-testimonial-image-grid.cjs +1 -1
  148. package/dist/hero-testimonial-image-grid.js +1 -1
  149. package/dist/hero-therapy-testimonial-grid.cjs +1 -1
  150. package/dist/hero-therapy-testimonial-grid.js +1 -1
  151. package/dist/hero-ui-library-showcase.cjs +63 -15
  152. package/dist/hero-ui-library-showcase.d.cts +5 -1
  153. package/dist/hero-ui-library-showcase.d.ts +5 -1
  154. package/dist/hero-ui-library-showcase.js +63 -15
  155. package/dist/index.cjs +44 -6
  156. package/dist/index.d.cts +3 -2
  157. package/dist/index.d.ts +3 -2
  158. package/dist/index.js +44 -6
  159. package/dist/link-page-newsletter-social.d.cts +1 -1
  160. package/dist/link-page-newsletter-social.d.ts +1 -1
  161. package/dist/offer-modal-membership-image.d.cts +1 -1
  162. package/dist/offer-modal-membership-image.d.ts +1 -1
  163. package/dist/offer-modal-newsletter-discount.d.cts +1 -1
  164. package/dist/offer-modal-newsletter-discount.d.ts +1 -1
  165. package/dist/offer-modal-sheet-newsletter.d.cts +1 -1
  166. package/dist/offer-modal-sheet-newsletter.d.ts +1 -1
  167. package/dist/registry.cjs +14465 -14767
  168. package/dist/registry.js +12664 -12966
  169. package/dist/resource-list-hero-filter.d.cts +1 -1
  170. package/dist/resource-list-hero-filter.d.ts +1 -1
  171. package/package.json +3 -3
@@ -8,7 +8,6 @@ var tailwindMerge = require('tailwind-merge');
8
8
  var classVarianceAuthority = require('class-variance-authority');
9
9
  var jsxRuntime = require('react/jsx-runtime');
10
10
  var inputs = require('@page-speed/forms/inputs');
11
- var LabelPrimitive = require('@radix-ui/react-label');
12
11
  var integration = require('@page-speed/forms/integration');
13
12
 
14
13
  function _interopNamespace(e) {
@@ -30,7 +29,6 @@ function _interopNamespace(e) {
30
29
  }
31
30
 
32
31
  var React__namespace = /*#__PURE__*/_interopNamespace(React);
33
- var LabelPrimitive__namespace = /*#__PURE__*/_interopNamespace(LabelPrimitive);
34
32
 
35
33
  // components/blocks/contact/contact-dark.tsx
36
34
  function cn(...inputs) {
@@ -379,6 +377,7 @@ var Pressable = React__namespace.forwardRef(
379
377
  rel,
380
378
  linkType,
381
379
  isInternal,
380
+ isExternal,
382
381
  handleClick
383
382
  } = navigation;
384
383
  const shouldRenderLink = normalizedHref && linkType !== "none";
@@ -572,22 +571,6 @@ function Card({ className, ...props }) {
572
571
  }
573
572
  );
574
573
  }
575
- function Label({
576
- className,
577
- ...props
578
- }) {
579
- return /* @__PURE__ */ jsxRuntime.jsx(
580
- LabelPrimitive__namespace.Root,
581
- {
582
- "data-slot": "label",
583
- className: cn(
584
- "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",
585
- className
586
- ),
587
- ...props
588
- }
589
- );
590
- }
591
574
  function DynamicFormField({
592
575
  field,
593
576
  className,
@@ -596,190 +579,199 @@ function DynamicFormField({
596
579
  onFileRemove,
597
580
  isUploading = false
598
581
  }) {
599
- const fieldId = `field-${field.name}`;
600
- return /* @__PURE__ */ jsxRuntime.jsx(forms.Field, { name: field.name, children: ({ field: formField, meta }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-2", className), children: [
601
- field.type !== "checkbox" && /* @__PURE__ */ jsxRuntime.jsxs(Label, { htmlFor: fieldId, children: [
602
- field.label,
603
- field.required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-destructive ml-1", children: "*" })
604
- ] }),
605
- (field.type === "text" || field.type === "email" || field.type === "tel" || field.type === "search" || field.type === "password" || field.type === "url") && /* @__PURE__ */ jsxRuntime.jsx(
606
- inputs.TextInput,
607
- {
608
- ...formField,
609
- id: fieldId,
610
- type: field.type,
611
- placeholder: field.placeholder,
612
- error: meta.touched && !!meta.error,
613
- disabled: field.disabled,
614
- "aria-label": field.label
615
- }
616
- ),
617
- field.type === "number" && /* @__PURE__ */ jsxRuntime.jsx(
618
- inputs.TextInput,
619
- {
620
- ...formField,
621
- id: fieldId,
622
- type: "text",
623
- placeholder: field.placeholder,
624
- error: meta.touched && !!meta.error,
625
- disabled: field.disabled,
626
- "aria-label": field.label
627
- }
628
- ),
629
- field.type === "textarea" && /* @__PURE__ */ jsxRuntime.jsx(
630
- inputs.TextArea,
631
- {
632
- ...formField,
633
- id: fieldId,
634
- placeholder: field.placeholder,
635
- rows: field.rows || 4,
636
- error: meta.touched && !!meta.error,
637
- disabled: field.disabled,
638
- "aria-label": field.label
639
- }
640
- ),
641
- field.type === "select" && field.options && /* @__PURE__ */ jsxRuntime.jsx(
642
- inputs.Select,
643
- {
644
- ...formField,
645
- id: fieldId,
646
- options: field.options,
647
- placeholder: field.placeholder || `Select ${field.label.toLowerCase()}`,
648
- error: meta.touched && !!meta.error,
649
- disabled: field.disabled,
650
- "aria-label": field.label
651
- }
652
- ),
653
- field.type === "multi-select" && field.options && /* @__PURE__ */ jsxRuntime.jsx(
654
- inputs.Select,
655
- {
656
- ...formField,
657
- id: fieldId,
658
- options: field.options,
659
- placeholder: field.placeholder || `Select ${field.label.toLowerCase()}`,
660
- error: meta.touched && !!meta.error,
661
- disabled: field.disabled,
662
- "aria-label": field.label,
663
- multiple: true
664
- }
665
- ),
666
- field.type === "radio" && field.options && /* @__PURE__ */ jsxRuntime.jsx(
667
- inputs.Radio,
668
- {
669
- ...formField,
670
- id: fieldId,
671
- options: field.options,
672
- disabled: field.disabled,
673
- layout: field.layout || "stacked",
674
- error: meta.touched && !!meta.error,
675
- "aria-label": field.label
676
- }
677
- ),
678
- field.type === "checkbox" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start space-x-2", children: [
679
- /* @__PURE__ */ jsxRuntime.jsx(
680
- inputs.Checkbox,
681
- {
682
- ...formField,
683
- id: fieldId,
684
- value: formField.value === true || formField.value === "true",
685
- onChange: (checked) => formField.onChange(checked),
686
- disabled: field.disabled,
687
- error: meta.touched && !!meta.error,
688
- "aria-label": field.label
689
- }
690
- ),
691
- /* @__PURE__ */ jsxRuntime.jsxs(
692
- Label,
693
- {
694
- htmlFor: fieldId,
695
- className: "font-normal cursor-pointer leading-relaxed",
696
- children: [
697
- field.label,
698
- field.required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-destructive ml-1", children: "*" })
699
- ]
700
- }
701
- )
702
- ] }),
703
- field.type === "checkbox-group" && field.options && /* @__PURE__ */ jsxRuntime.jsx(
704
- inputs.CheckboxGroup,
705
- {
706
- ...formField,
707
- id: fieldId,
708
- options: field.options,
709
- disabled: field.disabled,
710
- layout: field.layout || "stacked",
711
- error: meta.touched && !!meta.error,
712
- "aria-label": field.label
713
- }
714
- ),
715
- (field.type === "date-picker" || field.type === "date") && /* @__PURE__ */ jsxRuntime.jsx(
716
- inputs.DatePicker,
717
- {
718
- ...formField,
719
- id: fieldId,
720
- placeholder: field.placeholder,
721
- error: meta.touched && !!meta.error,
722
- disabled: field.disabled,
723
- "aria-label": field.label
724
- }
725
- ),
726
- field.type === "date-range" && /* @__PURE__ */ jsxRuntime.jsx(
727
- inputs.DateRangePicker,
728
- {
729
- ...formField,
730
- id: fieldId,
731
- error: meta.touched && !!meta.error,
732
- disabled: field.disabled,
733
- "aria-label": field.label
734
- }
735
- ),
736
- field.type === "time" && /* @__PURE__ */ jsxRuntime.jsx(
737
- inputs.TimePicker,
738
- {
739
- ...formField,
740
- id: fieldId,
741
- placeholder: field.placeholder,
742
- error: meta.touched && !!meta.error,
743
- disabled: field.disabled,
744
- "aria-label": field.label
745
- }
746
- ),
747
- field.type === "file" && /* @__PURE__ */ jsxRuntime.jsx(
748
- inputs.FileInput,
749
- {
750
- ...formField,
751
- id: fieldId,
752
- accept: field.accept,
753
- maxSize: field.maxSize || 5 * 1024 * 1024,
754
- maxFiles: field.maxFiles || 1,
755
- multiple: field.multiple || false,
756
- placeholder: field.placeholder || "Choose file(s)...",
757
- error: meta.touched && !!meta.error,
758
- disabled: field.disabled || isUploading,
759
- showProgress: true,
760
- uploadProgress,
761
- onChange: (files) => {
762
- formField.onChange(files);
763
- if (files.length > 0 && onFileUpload) {
764
- onFileUpload(files);
582
+ const fieldId = field.name;
583
+ const usesGroupLegend = field.type === "radio" || field.type === "checkbox-group";
584
+ const usesInlineCheckboxLabel = field.type === "checkbox";
585
+ const shouldRenderFieldLabel = !usesGroupLegend && !usesInlineCheckboxLabel;
586
+ const checkboxLabel = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
587
+ field.label,
588
+ field.required ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-destructive ml-1", children: "*" }) : null
589
+ ] });
590
+ return /* @__PURE__ */ jsxRuntime.jsx(
591
+ forms.Field,
592
+ {
593
+ name: field.name,
594
+ label: shouldRenderFieldLabel ? field.label : void 0,
595
+ description: shouldRenderFieldLabel ? field.description : void 0,
596
+ required: field.required,
597
+ className: cn("space-y-2", className),
598
+ children: ({ field: formField, meta }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
599
+ (field.type === "text" || field.type === "email" || field.type === "tel" || field.type === "search" || field.type === "password" || field.type === "url") && /* @__PURE__ */ jsxRuntime.jsx(
600
+ inputs.TextInput,
601
+ {
602
+ ...formField,
603
+ id: fieldId,
604
+ type: field.type,
605
+ placeholder: field.placeholder,
606
+ error: meta.touched && !!meta.error,
607
+ disabled: field.disabled,
608
+ "aria-label": field.label
765
609
  }
766
- },
767
- onFileRemove,
768
- "aria-label": field.label
769
- }
770
- ),
771
- field.type === "rich-text" && /* @__PURE__ */ jsxRuntime.jsx(
772
- inputs.RichTextEditor,
773
- {
774
- ...formField,
775
- id: fieldId,
776
- placeholder: field.placeholder,
777
- error: meta.touched && !!meta.error,
778
- disabled: field.disabled,
779
- "aria-label": field.label
780
- }
781
- )
782
- ] }) });
610
+ ),
611
+ field.type === "number" && /* @__PURE__ */ jsxRuntime.jsx(
612
+ inputs.TextInput,
613
+ {
614
+ ...formField,
615
+ id: fieldId,
616
+ type: "text",
617
+ placeholder: field.placeholder,
618
+ error: meta.touched && !!meta.error,
619
+ disabled: field.disabled,
620
+ "aria-label": field.label
621
+ }
622
+ ),
623
+ field.type === "textarea" && /* @__PURE__ */ jsxRuntime.jsx(
624
+ inputs.TextArea,
625
+ {
626
+ ...formField,
627
+ id: fieldId,
628
+ placeholder: field.placeholder,
629
+ rows: field.rows || 4,
630
+ error: meta.touched && !!meta.error,
631
+ disabled: field.disabled,
632
+ "aria-label": field.label
633
+ }
634
+ ),
635
+ field.type === "select" && field.options && /* @__PURE__ */ jsxRuntime.jsx(
636
+ inputs.Select,
637
+ {
638
+ ...formField,
639
+ id: fieldId,
640
+ options: field.options,
641
+ placeholder: field.placeholder || `Select ${field.label.toLowerCase()}`,
642
+ error: meta.touched && !!meta.error,
643
+ disabled: field.disabled,
644
+ "aria-label": field.label
645
+ }
646
+ ),
647
+ field.type === "multi-select" && field.options && /* @__PURE__ */ jsxRuntime.jsx(
648
+ inputs.MultiSelect,
649
+ {
650
+ ...formField,
651
+ id: fieldId,
652
+ options: field.options,
653
+ placeholder: field.placeholder || `Select ${field.label.toLowerCase()}`,
654
+ error: meta.touched && !!meta.error,
655
+ disabled: field.disabled,
656
+ "aria-label": field.label
657
+ }
658
+ ),
659
+ field.type === "radio" && field.options && /* @__PURE__ */ jsxRuntime.jsx(
660
+ inputs.Radio,
661
+ {
662
+ ...formField,
663
+ id: fieldId,
664
+ options: field.options,
665
+ label: field.label,
666
+ description: field.description,
667
+ required: field.required,
668
+ disabled: field.disabled,
669
+ layout: field.layout || "stacked",
670
+ error: meta.touched && !!meta.error,
671
+ "aria-label": field.label
672
+ }
673
+ ),
674
+ field.type === "checkbox" && /* @__PURE__ */ jsxRuntime.jsx(
675
+ inputs.Checkbox,
676
+ {
677
+ ...formField,
678
+ id: fieldId,
679
+ value: formField.value === true || formField.value === "true",
680
+ onChange: (checked) => formField.onChange(checked),
681
+ label: checkboxLabel,
682
+ description: field.description,
683
+ disabled: field.disabled,
684
+ required: field.required,
685
+ error: meta.touched && !!meta.error,
686
+ "aria-label": field.label
687
+ }
688
+ ),
689
+ field.type === "checkbox-group" && field.options && /* @__PURE__ */ jsxRuntime.jsx(
690
+ inputs.CheckboxGroup,
691
+ {
692
+ ...formField,
693
+ id: fieldId,
694
+ options: field.options,
695
+ label: field.label,
696
+ description: field.description,
697
+ required: field.required,
698
+ disabled: field.disabled,
699
+ layout: field.layout || "stacked",
700
+ error: meta.touched && !!meta.error,
701
+ "aria-label": field.label
702
+ }
703
+ ),
704
+ (field.type === "date-picker" || field.type === "date") && /* @__PURE__ */ jsxRuntime.jsx(
705
+ inputs.DatePicker,
706
+ {
707
+ ...formField,
708
+ id: fieldId,
709
+ placeholder: field.placeholder,
710
+ error: meta.touched && !!meta.error,
711
+ disabled: field.disabled,
712
+ "aria-label": field.label
713
+ }
714
+ ),
715
+ field.type === "date-range" && /* @__PURE__ */ jsxRuntime.jsx(
716
+ inputs.DateRangePicker,
717
+ {
718
+ ...formField,
719
+ id: fieldId,
720
+ placeholder: field.placeholder,
721
+ error: meta.touched && !!meta.error,
722
+ disabled: field.disabled,
723
+ "aria-label": field.label
724
+ }
725
+ ),
726
+ field.type === "time" && /* @__PURE__ */ jsxRuntime.jsx(
727
+ inputs.TimePicker,
728
+ {
729
+ ...formField,
730
+ id: fieldId,
731
+ placeholder: field.placeholder,
732
+ error: meta.touched && !!meta.error,
733
+ disabled: field.disabled,
734
+ "aria-label": field.label
735
+ }
736
+ ),
737
+ field.type === "file" && /* @__PURE__ */ jsxRuntime.jsx(
738
+ inputs.FileInput,
739
+ {
740
+ ...formField,
741
+ id: fieldId,
742
+ accept: field.accept,
743
+ maxSize: field.maxSize || 5 * 1024 * 1024,
744
+ maxFiles: field.maxFiles || 1,
745
+ multiple: field.multiple || false,
746
+ placeholder: field.placeholder || "Choose file(s)...",
747
+ error: meta.touched && !!meta.error,
748
+ disabled: field.disabled || isUploading,
749
+ showProgress: true,
750
+ uploadProgress,
751
+ onChange: (files) => {
752
+ formField.onChange(files);
753
+ if (files.length > 0 && onFileUpload) {
754
+ onFileUpload(files);
755
+ }
756
+ },
757
+ onFileRemove,
758
+ "aria-label": field.label
759
+ }
760
+ ),
761
+ field.type === "rich-text" && /* @__PURE__ */ jsxRuntime.jsx(
762
+ inputs.RichTextEditor,
763
+ {
764
+ ...formField,
765
+ id: fieldId,
766
+ placeholder: field.placeholder,
767
+ error: meta.touched && !!meta.error,
768
+ disabled: field.disabled,
769
+ "aria-label": field.label
770
+ }
771
+ )
772
+ ] })
773
+ }
774
+ );
783
775
  }
784
776
 
785
777
  // lib/form-field-types.ts
@@ -911,8 +903,36 @@ function useContactForm(options) {
911
903
  resetOnSuccess = true,
912
904
  uploadTokens = []
913
905
  } = options;
914
- const [isSubmitted, setIsSubmitted] = React.useState(false);
915
906
  const [submissionError, setSubmissionError] = React.useState(null);
907
+ const submissionConfig = formConfig?.submissionConfig;
908
+ const redirectUrl = submissionConfig?.redirectUrl;
909
+ const redirectNavigation = useNavigation({ href: redirectUrl });
910
+ const resetSubmissionState = React.useCallback(() => {
911
+ setSubmissionError(null);
912
+ }, []);
913
+ const performRedirect = React.useCallback(() => {
914
+ if (!redirectUrl || typeof window === "undefined") {
915
+ return;
916
+ }
917
+ const navigate = () => {
918
+ if (redirectNavigation.shouldUseRouter && redirectNavigation.normalizedHref) {
919
+ const handler = window.__opensiteNavigationHandler;
920
+ if (typeof handler === "function") {
921
+ try {
922
+ const handled = handler(redirectNavigation.normalizedHref, void 0);
923
+ if (handled !== false) {
924
+ return;
925
+ }
926
+ } catch (error) {
927
+ console.error("Internal redirect handler failed:", error);
928
+ }
929
+ }
930
+ }
931
+ const destination = redirectNavigation.normalizedHref || redirectUrl;
932
+ window.location.assign(destination);
933
+ };
934
+ window.setTimeout(navigate, 150);
935
+ }, [redirectNavigation, redirectUrl]);
916
936
  const form = forms.useForm({
917
937
  initialValues: React.useMemo(
918
938
  () => generateInitialValues(formFields),
@@ -923,7 +943,7 @@ function useContactForm(options) {
923
943
  [formFields]
924
944
  ),
925
945
  onSubmit: async (values, helpers) => {
926
- setSubmissionError(null);
946
+ resetSubmissionState();
927
947
  const shouldAutoSubmit = Boolean(formConfig?.endpoint);
928
948
  if (!shouldAutoSubmit && !onSubmit) {
929
949
  return;
@@ -943,12 +963,21 @@ function useContactForm(options) {
943
963
  await onSubmit(submissionValues);
944
964
  }
945
965
  if (shouldAutoSubmit || onSubmit) {
946
- setIsSubmitted(true);
966
+ try {
967
+ await submissionConfig?.handleFormSubmission?.({
968
+ formData: submissionValues,
969
+ responseData: result
970
+ });
971
+ } catch (callbackError) {
972
+ console.error("handleFormSubmission callback failed:", callbackError);
973
+ }
947
974
  if (resetOnSuccess) {
948
975
  helpers.resetForm();
949
976
  }
950
977
  onSuccess?.(result);
951
- setTimeout(() => setIsSubmitted(false), 1e4);
978
+ if (submissionConfig?.behavior === "redirect" && submissionConfig.redirectUrl) {
979
+ performRedirect();
980
+ }
952
981
  }
953
982
  } catch (error) {
954
983
  if (error instanceof PageSpeedFormSubmissionError && error.formErrors) {
@@ -963,9 +992,10 @@ function useContactForm(options) {
963
992
  const formMethod = formConfig?.method?.toLowerCase() === "get" ? "get" : "post";
964
993
  return {
965
994
  form,
966
- isSubmitted,
995
+ isSubmitted: form.status === "success",
967
996
  submissionError,
968
- formMethod
997
+ formMethod,
998
+ resetSubmissionState
969
999
  };
970
1000
  }
971
1001
 
@@ -1460,38 +1490,6 @@ var Section = React__namespace.default.forwardRef(
1460
1490
  }
1461
1491
  );
1462
1492
  Section.displayName = "Section";
1463
- var FormFeedback = ({
1464
- isSubmitted,
1465
- successMessageClassName,
1466
- successMessage,
1467
- submissionError,
1468
- errorMessageClassName
1469
- }) => {
1470
- if (!isSubmitted && !submissionError) return null;
1471
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1472
- isSubmitted && !submissionError && /* @__PURE__ */ jsxRuntime.jsx(
1473
- "div",
1474
- {
1475
- className: cn(
1476
- "mb-6 p-4 bg-primary/10 border border-primary rounded-md",
1477
- successMessageClassName
1478
- ),
1479
- children: typeof successMessage === "string" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-primary-foreground/90 text-center", children: successMessage }) : successMessage
1480
- }
1481
- ),
1482
- submissionError && /* @__PURE__ */ jsxRuntime.jsx(
1483
- "div",
1484
- {
1485
- className: cn(
1486
- "mb-6 p-4 bg-destructive/10 border border-destructive rounded-md",
1487
- errorMessageClassName
1488
- ),
1489
- children: typeof submissionError === "string" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-destructive text-center", children: submissionError }) : submissionError
1490
- }
1491
- )
1492
- ] });
1493
- };
1494
- var form_feedback_default = FormFeedback;
1495
1493
  var DEFAULT_FORM_FIELDS = [
1496
1494
  {
1497
1495
  name: "firstName",
@@ -1573,7 +1571,7 @@ function ContactDark({
1573
1571
  removeFile,
1574
1572
  resetUpload
1575
1573
  } = useFileUpload({ onError });
1576
- const { form, isSubmitted, submissionError, formMethod } = useContactForm({
1574
+ const { form, submissionError, formMethod, resetSubmissionState } = useContactForm({
1577
1575
  formFields,
1578
1576
  formConfig,
1579
1577
  onSubmit,
@@ -1646,9 +1644,14 @@ function ContactDark({
1646
1644
  Pressable,
1647
1645
  {
1648
1646
  href: social.href,
1649
- className: "flex h-9 w-9 items-center justify-center rounded-full border border-primary-foreground/20 text-primary-foreground/70 transition-colors hover:border-primary-foreground/40 hover:text-primary-foreground",
1647
+ className: cn(
1648
+ "flex h-9 w-9 items-center justify-center",
1649
+ "rounded-xl border-2 transition-shadow duration-1000",
1650
+ "bg-primary text-primary-foreground border-primary-foreground",
1651
+ "shadow-sm hover:shadow-xl"
1652
+ ),
1650
1653
  "aria-label": social.label,
1651
- children: /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: social.icon, size: 16 })
1654
+ children: /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: social.icon, size: 18 })
1652
1655
  },
1653
1656
  key
1654
1657
  ));
@@ -1695,60 +1698,57 @@ function ContactDark({
1695
1698
  cardClassName
1696
1699
  ),
1697
1700
  children: [
1698
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("p-6 lg:p-12", formPanelClassName), children: [
1699
- /* @__PURE__ */ jsxRuntime.jsx(
1700
- form_feedback_default,
1701
- {
1702
- isSubmitted,
1703
- successMessageClassName,
1704
- successMessage,
1705
- submissionError,
1706
- errorMessageClassName
1707
- }
1708
- ),
1709
- /* @__PURE__ */ jsxRuntime.jsxs(
1710
- forms.Form,
1711
- {
1712
- form,
1713
- action: formConfig?.endpoint,
1714
- method: formMethod,
1715
- className: cn("space-y-6", formClassName),
1716
- children: [
1717
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-12 gap-6", children: formFields.map((field) => /* @__PURE__ */ jsxRuntime.jsx(
1718
- "div",
1719
- {
1720
- className: getColumnSpanClass(field.columnSpan),
1721
- children: /* @__PURE__ */ jsxRuntime.jsx(
1722
- DynamicFormField,
1723
- {
1724
- field,
1725
- uploadProgress,
1726
- onFileUpload: uploadFiles,
1727
- onFileRemove: removeFile,
1728
- isUploading
1729
- }
1730
- )
1731
- },
1732
- field.name
1733
- )) }),
1734
- actionsSlot || actions && actions.length > 0 ? actionsContent : /* @__PURE__ */ jsxRuntime.jsxs(
1735
- Pressable,
1736
- {
1737
- componentType: "button",
1738
- type: "submit",
1739
- className: cn("w-full", submitClassName),
1740
- asButton: true,
1741
- disabled: form.isSubmitting,
1742
- children: [
1743
- buttonIcon,
1744
- buttonText
1745
- ]
1746
- }
1747
- )
1748
- ]
1749
- }
1750
- )
1751
- ] }),
1701
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("p-6 lg:p-12", formPanelClassName), children: /* @__PURE__ */ jsxRuntime.jsxs(
1702
+ forms.Form,
1703
+ {
1704
+ form,
1705
+ action: formConfig?.endpoint,
1706
+ method: formMethod,
1707
+ submissionError,
1708
+ successMessage,
1709
+ successMessageClassName,
1710
+ errorMessageClassName,
1711
+ submissionConfig: formConfig?.submissionConfig,
1712
+ onNewSubmission: () => {
1713
+ resetUpload();
1714
+ resetSubmissionState();
1715
+ },
1716
+ className: cn("space-y-6", formClassName),
1717
+ children: [
1718
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-12 gap-6", children: formFields.map((field) => /* @__PURE__ */ jsxRuntime.jsx(
1719
+ "div",
1720
+ {
1721
+ className: getColumnSpanClass(field.columnSpan),
1722
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1723
+ DynamicFormField,
1724
+ {
1725
+ field,
1726
+ uploadProgress,
1727
+ onFileUpload: uploadFiles,
1728
+ onFileRemove: removeFile,
1729
+ isUploading
1730
+ }
1731
+ )
1732
+ },
1733
+ field.name
1734
+ )) }),
1735
+ actionsSlot || actions && actions.length > 0 ? actionsContent : /* @__PURE__ */ jsxRuntime.jsxs(
1736
+ Pressable,
1737
+ {
1738
+ componentType: "button",
1739
+ type: "submit",
1740
+ className: cn("w-full", submitClassName),
1741
+ asButton: true,
1742
+ disabled: form.isSubmitting,
1743
+ children: [
1744
+ buttonIcon,
1745
+ buttonText
1746
+ ]
1747
+ }
1748
+ )
1749
+ ]
1750
+ }
1751
+ ) }),
1752
1752
  /* @__PURE__ */ jsxRuntime.jsxs(
1753
1753
  "div",
1754
1754
  {