@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
@@ -9,7 +9,6 @@ var classVarianceAuthority = require('class-variance-authority');
9
9
  var jsxRuntime = require('react/jsx-runtime');
10
10
  var img = require('@page-speed/img');
11
11
  var inputs = require('@page-speed/forms/inputs');
12
- var LabelPrimitive = require('@radix-ui/react-label');
13
12
  var integration = require('@page-speed/forms/integration');
14
13
 
15
14
  function _interopNamespace(e) {
@@ -31,7 +30,6 @@ function _interopNamespace(e) {
31
30
  }
32
31
 
33
32
  var React__namespace = /*#__PURE__*/_interopNamespace(React);
34
- var LabelPrimitive__namespace = /*#__PURE__*/_interopNamespace(LabelPrimitive);
35
33
 
36
34
  // components/blocks/contact/contact-photography.tsx
37
35
  function cn(...inputs) {
@@ -410,6 +408,7 @@ var Pressable = React__namespace.forwardRef(
410
408
  rel,
411
409
  linkType,
412
410
  isInternal,
411
+ isExternal,
413
412
  handleClick
414
413
  } = navigation;
415
414
  const shouldRenderLink = normalizedHref && linkType !== "none";
@@ -485,22 +484,6 @@ var Pressable = React__namespace.forwardRef(
485
484
  }
486
485
  );
487
486
  Pressable.displayName = "Pressable";
488
- function Label({
489
- className,
490
- ...props
491
- }) {
492
- return /* @__PURE__ */ jsxRuntime.jsx(
493
- LabelPrimitive__namespace.Root,
494
- {
495
- "data-slot": "label",
496
- className: cn(
497
- "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",
498
- className
499
- ),
500
- ...props
501
- }
502
- );
503
- }
504
487
  function DynamicFormField({
505
488
  field,
506
489
  className,
@@ -509,190 +492,199 @@ function DynamicFormField({
509
492
  onFileRemove,
510
493
  isUploading = false
511
494
  }) {
512
- const fieldId = `field-${field.name}`;
513
- return /* @__PURE__ */ jsxRuntime.jsx(forms.Field, { name: field.name, children: ({ field: formField, meta }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-2", className), children: [
514
- field.type !== "checkbox" && /* @__PURE__ */ jsxRuntime.jsxs(Label, { htmlFor: fieldId, children: [
515
- field.label,
516
- field.required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-destructive ml-1", children: "*" })
517
- ] }),
518
- (field.type === "text" || field.type === "email" || field.type === "tel" || field.type === "search" || field.type === "password" || field.type === "url") && /* @__PURE__ */ jsxRuntime.jsx(
519
- inputs.TextInput,
520
- {
521
- ...formField,
522
- id: fieldId,
523
- type: field.type,
524
- placeholder: field.placeholder,
525
- error: meta.touched && !!meta.error,
526
- disabled: field.disabled,
527
- "aria-label": field.label
528
- }
529
- ),
530
- field.type === "number" && /* @__PURE__ */ jsxRuntime.jsx(
531
- inputs.TextInput,
532
- {
533
- ...formField,
534
- id: fieldId,
535
- type: "text",
536
- placeholder: field.placeholder,
537
- error: meta.touched && !!meta.error,
538
- disabled: field.disabled,
539
- "aria-label": field.label
540
- }
541
- ),
542
- field.type === "textarea" && /* @__PURE__ */ jsxRuntime.jsx(
543
- inputs.TextArea,
544
- {
545
- ...formField,
546
- id: fieldId,
547
- placeholder: field.placeholder,
548
- rows: field.rows || 4,
549
- error: meta.touched && !!meta.error,
550
- disabled: field.disabled,
551
- "aria-label": field.label
552
- }
553
- ),
554
- field.type === "select" && field.options && /* @__PURE__ */ jsxRuntime.jsx(
555
- inputs.Select,
556
- {
557
- ...formField,
558
- id: fieldId,
559
- options: field.options,
560
- placeholder: field.placeholder || `Select ${field.label.toLowerCase()}`,
561
- error: meta.touched && !!meta.error,
562
- disabled: field.disabled,
563
- "aria-label": field.label
564
- }
565
- ),
566
- field.type === "multi-select" && field.options && /* @__PURE__ */ jsxRuntime.jsx(
567
- inputs.Select,
568
- {
569
- ...formField,
570
- id: fieldId,
571
- options: field.options,
572
- placeholder: field.placeholder || `Select ${field.label.toLowerCase()}`,
573
- error: meta.touched && !!meta.error,
574
- disabled: field.disabled,
575
- "aria-label": field.label,
576
- multiple: true
577
- }
578
- ),
579
- field.type === "radio" && field.options && /* @__PURE__ */ jsxRuntime.jsx(
580
- inputs.Radio,
581
- {
582
- ...formField,
583
- id: fieldId,
584
- options: field.options,
585
- disabled: field.disabled,
586
- layout: field.layout || "stacked",
587
- error: meta.touched && !!meta.error,
588
- "aria-label": field.label
589
- }
590
- ),
591
- field.type === "checkbox" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start space-x-2", children: [
592
- /* @__PURE__ */ jsxRuntime.jsx(
593
- inputs.Checkbox,
594
- {
595
- ...formField,
596
- id: fieldId,
597
- value: formField.value === true || formField.value === "true",
598
- onChange: (checked) => formField.onChange(checked),
599
- disabled: field.disabled,
600
- error: meta.touched && !!meta.error,
601
- "aria-label": field.label
602
- }
603
- ),
604
- /* @__PURE__ */ jsxRuntime.jsxs(
605
- Label,
606
- {
607
- htmlFor: fieldId,
608
- className: "font-normal cursor-pointer leading-relaxed",
609
- children: [
610
- field.label,
611
- field.required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-destructive ml-1", children: "*" })
612
- ]
613
- }
614
- )
615
- ] }),
616
- field.type === "checkbox-group" && field.options && /* @__PURE__ */ jsxRuntime.jsx(
617
- inputs.CheckboxGroup,
618
- {
619
- ...formField,
620
- id: fieldId,
621
- options: field.options,
622
- disabled: field.disabled,
623
- layout: field.layout || "stacked",
624
- error: meta.touched && !!meta.error,
625
- "aria-label": field.label
626
- }
627
- ),
628
- (field.type === "date-picker" || field.type === "date") && /* @__PURE__ */ jsxRuntime.jsx(
629
- inputs.DatePicker,
630
- {
631
- ...formField,
632
- id: fieldId,
633
- placeholder: field.placeholder,
634
- error: meta.touched && !!meta.error,
635
- disabled: field.disabled,
636
- "aria-label": field.label
637
- }
638
- ),
639
- field.type === "date-range" && /* @__PURE__ */ jsxRuntime.jsx(
640
- inputs.DateRangePicker,
641
- {
642
- ...formField,
643
- id: fieldId,
644
- error: meta.touched && !!meta.error,
645
- disabled: field.disabled,
646
- "aria-label": field.label
647
- }
648
- ),
649
- field.type === "time" && /* @__PURE__ */ jsxRuntime.jsx(
650
- inputs.TimePicker,
651
- {
652
- ...formField,
653
- id: fieldId,
654
- placeholder: field.placeholder,
655
- error: meta.touched && !!meta.error,
656
- disabled: field.disabled,
657
- "aria-label": field.label
658
- }
659
- ),
660
- field.type === "file" && /* @__PURE__ */ jsxRuntime.jsx(
661
- inputs.FileInput,
662
- {
663
- ...formField,
664
- id: fieldId,
665
- accept: field.accept,
666
- maxSize: field.maxSize || 5 * 1024 * 1024,
667
- maxFiles: field.maxFiles || 1,
668
- multiple: field.multiple || false,
669
- placeholder: field.placeholder || "Choose file(s)...",
670
- error: meta.touched && !!meta.error,
671
- disabled: field.disabled || isUploading,
672
- showProgress: true,
673
- uploadProgress,
674
- onChange: (files) => {
675
- formField.onChange(files);
676
- if (files.length > 0 && onFileUpload) {
677
- onFileUpload(files);
495
+ const fieldId = field.name;
496
+ const usesGroupLegend = field.type === "radio" || field.type === "checkbox-group";
497
+ const usesInlineCheckboxLabel = field.type === "checkbox";
498
+ const shouldRenderFieldLabel = !usesGroupLegend && !usesInlineCheckboxLabel;
499
+ const checkboxLabel = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
500
+ field.label,
501
+ field.required ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-destructive ml-1", children: "*" }) : null
502
+ ] });
503
+ return /* @__PURE__ */ jsxRuntime.jsx(
504
+ forms.Field,
505
+ {
506
+ name: field.name,
507
+ label: shouldRenderFieldLabel ? field.label : void 0,
508
+ description: shouldRenderFieldLabel ? field.description : void 0,
509
+ required: field.required,
510
+ className: cn("space-y-2", className),
511
+ children: ({ field: formField, meta }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
512
+ (field.type === "text" || field.type === "email" || field.type === "tel" || field.type === "search" || field.type === "password" || field.type === "url") && /* @__PURE__ */ jsxRuntime.jsx(
513
+ inputs.TextInput,
514
+ {
515
+ ...formField,
516
+ id: fieldId,
517
+ type: field.type,
518
+ placeholder: field.placeholder,
519
+ error: meta.touched && !!meta.error,
520
+ disabled: field.disabled,
521
+ "aria-label": field.label
678
522
  }
679
- },
680
- onFileRemove,
681
- "aria-label": field.label
682
- }
683
- ),
684
- field.type === "rich-text" && /* @__PURE__ */ jsxRuntime.jsx(
685
- inputs.RichTextEditor,
686
- {
687
- ...formField,
688
- id: fieldId,
689
- placeholder: field.placeholder,
690
- error: meta.touched && !!meta.error,
691
- disabled: field.disabled,
692
- "aria-label": field.label
693
- }
694
- )
695
- ] }) });
523
+ ),
524
+ field.type === "number" && /* @__PURE__ */ jsxRuntime.jsx(
525
+ inputs.TextInput,
526
+ {
527
+ ...formField,
528
+ id: fieldId,
529
+ type: "text",
530
+ placeholder: field.placeholder,
531
+ error: meta.touched && !!meta.error,
532
+ disabled: field.disabled,
533
+ "aria-label": field.label
534
+ }
535
+ ),
536
+ field.type === "textarea" && /* @__PURE__ */ jsxRuntime.jsx(
537
+ inputs.TextArea,
538
+ {
539
+ ...formField,
540
+ id: fieldId,
541
+ placeholder: field.placeholder,
542
+ rows: field.rows || 4,
543
+ error: meta.touched && !!meta.error,
544
+ disabled: field.disabled,
545
+ "aria-label": field.label
546
+ }
547
+ ),
548
+ field.type === "select" && field.options && /* @__PURE__ */ jsxRuntime.jsx(
549
+ inputs.Select,
550
+ {
551
+ ...formField,
552
+ id: fieldId,
553
+ options: field.options,
554
+ placeholder: field.placeholder || `Select ${field.label.toLowerCase()}`,
555
+ error: meta.touched && !!meta.error,
556
+ disabled: field.disabled,
557
+ "aria-label": field.label
558
+ }
559
+ ),
560
+ field.type === "multi-select" && field.options && /* @__PURE__ */ jsxRuntime.jsx(
561
+ inputs.MultiSelect,
562
+ {
563
+ ...formField,
564
+ id: fieldId,
565
+ options: field.options,
566
+ placeholder: field.placeholder || `Select ${field.label.toLowerCase()}`,
567
+ error: meta.touched && !!meta.error,
568
+ disabled: field.disabled,
569
+ "aria-label": field.label
570
+ }
571
+ ),
572
+ field.type === "radio" && field.options && /* @__PURE__ */ jsxRuntime.jsx(
573
+ inputs.Radio,
574
+ {
575
+ ...formField,
576
+ id: fieldId,
577
+ options: field.options,
578
+ label: field.label,
579
+ description: field.description,
580
+ required: field.required,
581
+ disabled: field.disabled,
582
+ layout: field.layout || "stacked",
583
+ error: meta.touched && !!meta.error,
584
+ "aria-label": field.label
585
+ }
586
+ ),
587
+ field.type === "checkbox" && /* @__PURE__ */ jsxRuntime.jsx(
588
+ inputs.Checkbox,
589
+ {
590
+ ...formField,
591
+ id: fieldId,
592
+ value: formField.value === true || formField.value === "true",
593
+ onChange: (checked) => formField.onChange(checked),
594
+ label: checkboxLabel,
595
+ description: field.description,
596
+ disabled: field.disabled,
597
+ required: field.required,
598
+ error: meta.touched && !!meta.error,
599
+ "aria-label": field.label
600
+ }
601
+ ),
602
+ field.type === "checkbox-group" && field.options && /* @__PURE__ */ jsxRuntime.jsx(
603
+ inputs.CheckboxGroup,
604
+ {
605
+ ...formField,
606
+ id: fieldId,
607
+ options: field.options,
608
+ label: field.label,
609
+ description: field.description,
610
+ required: field.required,
611
+ disabled: field.disabled,
612
+ layout: field.layout || "stacked",
613
+ error: meta.touched && !!meta.error,
614
+ "aria-label": field.label
615
+ }
616
+ ),
617
+ (field.type === "date-picker" || field.type === "date") && /* @__PURE__ */ jsxRuntime.jsx(
618
+ inputs.DatePicker,
619
+ {
620
+ ...formField,
621
+ id: fieldId,
622
+ placeholder: field.placeholder,
623
+ error: meta.touched && !!meta.error,
624
+ disabled: field.disabled,
625
+ "aria-label": field.label
626
+ }
627
+ ),
628
+ field.type === "date-range" && /* @__PURE__ */ jsxRuntime.jsx(
629
+ inputs.DateRangePicker,
630
+ {
631
+ ...formField,
632
+ id: fieldId,
633
+ placeholder: field.placeholder,
634
+ error: meta.touched && !!meta.error,
635
+ disabled: field.disabled,
636
+ "aria-label": field.label
637
+ }
638
+ ),
639
+ field.type === "time" && /* @__PURE__ */ jsxRuntime.jsx(
640
+ inputs.TimePicker,
641
+ {
642
+ ...formField,
643
+ id: fieldId,
644
+ placeholder: field.placeholder,
645
+ error: meta.touched && !!meta.error,
646
+ disabled: field.disabled,
647
+ "aria-label": field.label
648
+ }
649
+ ),
650
+ field.type === "file" && /* @__PURE__ */ jsxRuntime.jsx(
651
+ inputs.FileInput,
652
+ {
653
+ ...formField,
654
+ id: fieldId,
655
+ accept: field.accept,
656
+ maxSize: field.maxSize || 5 * 1024 * 1024,
657
+ maxFiles: field.maxFiles || 1,
658
+ multiple: field.multiple || false,
659
+ placeholder: field.placeholder || "Choose file(s)...",
660
+ error: meta.touched && !!meta.error,
661
+ disabled: field.disabled || isUploading,
662
+ showProgress: true,
663
+ uploadProgress,
664
+ onChange: (files) => {
665
+ formField.onChange(files);
666
+ if (files.length > 0 && onFileUpload) {
667
+ onFileUpload(files);
668
+ }
669
+ },
670
+ onFileRemove,
671
+ "aria-label": field.label
672
+ }
673
+ ),
674
+ field.type === "rich-text" && /* @__PURE__ */ jsxRuntime.jsx(
675
+ inputs.RichTextEditor,
676
+ {
677
+ ...formField,
678
+ id: fieldId,
679
+ placeholder: field.placeholder,
680
+ error: meta.touched && !!meta.error,
681
+ disabled: field.disabled,
682
+ "aria-label": field.label
683
+ }
684
+ )
685
+ ] })
686
+ }
687
+ );
696
688
  }
697
689
 
698
690
  // lib/form-field-types.ts
@@ -824,8 +816,36 @@ function useContactForm(options) {
824
816
  resetOnSuccess = true,
825
817
  uploadTokens = []
826
818
  } = options;
827
- const [isSubmitted, setIsSubmitted] = React.useState(false);
828
819
  const [submissionError, setSubmissionError] = React.useState(null);
820
+ const submissionConfig = formConfig?.submissionConfig;
821
+ const redirectUrl = submissionConfig?.redirectUrl;
822
+ const redirectNavigation = useNavigation({ href: redirectUrl });
823
+ const resetSubmissionState = React.useCallback(() => {
824
+ setSubmissionError(null);
825
+ }, []);
826
+ const performRedirect = React.useCallback(() => {
827
+ if (!redirectUrl || typeof window === "undefined") {
828
+ return;
829
+ }
830
+ const navigate = () => {
831
+ if (redirectNavigation.shouldUseRouter && redirectNavigation.normalizedHref) {
832
+ const handler = window.__opensiteNavigationHandler;
833
+ if (typeof handler === "function") {
834
+ try {
835
+ const handled = handler(redirectNavigation.normalizedHref, void 0);
836
+ if (handled !== false) {
837
+ return;
838
+ }
839
+ } catch (error) {
840
+ console.error("Internal redirect handler failed:", error);
841
+ }
842
+ }
843
+ }
844
+ const destination = redirectNavigation.normalizedHref || redirectUrl;
845
+ window.location.assign(destination);
846
+ };
847
+ window.setTimeout(navigate, 150);
848
+ }, [redirectNavigation, redirectUrl]);
829
849
  const form = forms.useForm({
830
850
  initialValues: React.useMemo(
831
851
  () => generateInitialValues(formFields),
@@ -836,7 +856,7 @@ function useContactForm(options) {
836
856
  [formFields]
837
857
  ),
838
858
  onSubmit: async (values, helpers) => {
839
- setSubmissionError(null);
859
+ resetSubmissionState();
840
860
  const shouldAutoSubmit = Boolean(formConfig?.endpoint);
841
861
  if (!shouldAutoSubmit && !onSubmit) {
842
862
  return;
@@ -856,12 +876,21 @@ function useContactForm(options) {
856
876
  await onSubmit(submissionValues);
857
877
  }
858
878
  if (shouldAutoSubmit || onSubmit) {
859
- setIsSubmitted(true);
879
+ try {
880
+ await submissionConfig?.handleFormSubmission?.({
881
+ formData: submissionValues,
882
+ responseData: result
883
+ });
884
+ } catch (callbackError) {
885
+ console.error("handleFormSubmission callback failed:", callbackError);
886
+ }
860
887
  if (resetOnSuccess) {
861
888
  helpers.resetForm();
862
889
  }
863
890
  onSuccess?.(result);
864
- setTimeout(() => setIsSubmitted(false), 1e4);
891
+ if (submissionConfig?.behavior === "redirect" && submissionConfig.redirectUrl) {
892
+ performRedirect();
893
+ }
865
894
  }
866
895
  } catch (error) {
867
896
  if (error instanceof PageSpeedFormSubmissionError && error.formErrors) {
@@ -876,9 +905,10 @@ function useContactForm(options) {
876
905
  const formMethod = formConfig?.method?.toLowerCase() === "get" ? "get" : "post";
877
906
  return {
878
907
  form,
879
- isSubmitted,
908
+ isSubmitted: form.status === "success",
880
909
  submissionError,
881
- formMethod
910
+ formMethod,
911
+ resetSubmissionState
882
912
  };
883
913
  }
884
914
 
@@ -1264,38 +1294,6 @@ function PatternBackground({
1264
1294
  }
1265
1295
  );
1266
1296
  }
1267
- var FormFeedback = ({
1268
- isSubmitted,
1269
- successMessageClassName,
1270
- successMessage,
1271
- submissionError,
1272
- errorMessageClassName
1273
- }) => {
1274
- if (!isSubmitted && !submissionError) return null;
1275
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1276
- isSubmitted && !submissionError && /* @__PURE__ */ jsxRuntime.jsx(
1277
- "div",
1278
- {
1279
- className: cn(
1280
- "mb-6 p-4 bg-primary/10 border border-primary rounded-md",
1281
- successMessageClassName
1282
- ),
1283
- children: typeof successMessage === "string" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-primary-foreground/90 text-center", children: successMessage }) : successMessage
1284
- }
1285
- ),
1286
- submissionError && /* @__PURE__ */ jsxRuntime.jsx(
1287
- "div",
1288
- {
1289
- className: cn(
1290
- "mb-6 p-4 bg-destructive/10 border border-destructive rounded-md",
1291
- errorMessageClassName
1292
- ),
1293
- children: typeof submissionError === "string" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-destructive text-center", children: submissionError }) : submissionError
1294
- }
1295
- )
1296
- ] });
1297
- };
1298
- var form_feedback_default = FormFeedback;
1299
1297
  var DEFAULT_FORM_FIELDS = [
1300
1298
  {
1301
1299
  name: "first_name",
@@ -1377,7 +1375,7 @@ function ContactPhotography({
1377
1375
  removeFile,
1378
1376
  resetUpload
1379
1377
  } = useFileUpload({ onError });
1380
- const { form, isSubmitted, submissionError, formMethod } = useContactForm({
1378
+ const { form, submissionError, formMethod, resetSubmissionState } = useContactForm({
1381
1379
  formFields,
1382
1380
  formConfig,
1383
1381
  onSubmit,
@@ -1467,22 +1465,21 @@ function ContactPhotography({
1467
1465
  children: description
1468
1466
  }
1469
1467
  ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: descriptionClassName, children: description })),
1470
- /* @__PURE__ */ jsxRuntime.jsx(
1471
- form_feedback_default,
1472
- {
1473
- isSubmitted,
1474
- successMessageClassName,
1475
- successMessage,
1476
- submissionError,
1477
- errorMessageClassName
1478
- }
1479
- ),
1480
1468
  /* @__PURE__ */ jsxRuntime.jsxs(
1481
1469
  forms.Form,
1482
1470
  {
1483
1471
  form,
1484
1472
  action: formConfig?.endpoint,
1485
1473
  method: formMethod,
1474
+ submissionError,
1475
+ successMessage,
1476
+ successMessageClassName,
1477
+ errorMessageClassName,
1478
+ submissionConfig: formConfig?.submissionConfig,
1479
+ onNewSubmission: () => {
1480
+ resetUpload();
1481
+ resetSubmissionState();
1482
+ },
1486
1483
  className: cn("space-y-4", formClassName),
1487
1484
  children: [
1488
1485
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-12 gap-6", children: formFields.map((field) => /* @__PURE__ */ jsxRuntime.jsx(
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { F as FormFieldConfig } from './form-field-types-flMXhIjG.cjs';
3
- import { P as PageSpeedFormConfig } from './forms-nGgHUTBw.cjs';
3
+ import { P as PageSpeedFormConfig } from './forms-CStlFhnh.cjs';
4
4
  import { f as SectionBackground, s as PatternName } from './community-initiatives-k1_FqqBQ.cjs';
5
5
  import { A as ActionConfig, O as OptixFlowConfig } from './blocks-rgCERYOC.cjs';
6
6
  import '@page-speed/forms/integration';
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { F as FormFieldConfig } from './form-field-types-flMXhIjG.js';
3
- import { P as PageSpeedFormConfig } from './forms-nGgHUTBw.js';
3
+ import { P as PageSpeedFormConfig } from './forms-CStlFhnh.js';
4
4
  import { f as SectionBackground, s as PatternName } from './community-initiatives-AwBlQu1a.js';
5
5
  import { A as ActionConfig, O as OptixFlowConfig } from './blocks-ClXAGlHQ.js';
6
6
  import '@page-speed/forms/integration';