@opensite/ui 2.2.3 → 2.2.5

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 (149) hide show
  1. package/dist/about-culture-tabs.cjs +83 -17
  2. package/dist/about-culture-tabs.js +83 -17
  3. package/dist/components.cjs +83 -17
  4. package/dist/components.js +83 -17
  5. package/dist/contact-callback.cjs +38 -552
  6. package/dist/contact-callback.d.cts +6 -74
  7. package/dist/contact-callback.d.ts +6 -74
  8. package/dist/contact-callback.js +36 -535
  9. package/dist/contact-careers.cjs +19 -555
  10. package/dist/contact-careers.d.cts +6 -62
  11. package/dist/contact-careers.d.ts +6 -62
  12. package/dist/contact-careers.js +18 -539
  13. package/dist/contact-catering.cjs +19 -531
  14. package/dist/contact-catering.d.cts +6 -61
  15. package/dist/contact-catering.d.ts +6 -61
  16. package/dist/contact-catering.js +18 -515
  17. package/dist/contact-consultation.cjs +87 -543
  18. package/dist/contact-consultation.d.cts +6 -61
  19. package/dist/contact-consultation.d.ts +6 -61
  20. package/dist/contact-consultation.js +88 -544
  21. package/dist/contact-demo.cjs +20 -563
  22. package/dist/contact-demo.d.cts +10 -50
  23. package/dist/contact-demo.d.ts +10 -50
  24. package/dist/contact-demo.js +19 -547
  25. package/dist/contact-emergency.cjs +1 -1
  26. package/dist/contact-emergency.js +1 -1
  27. package/dist/contact-event.cjs +19 -562
  28. package/dist/contact-event.d.cts +10 -50
  29. package/dist/contact-event.d.ts +10 -50
  30. package/dist/contact-event.js +19 -547
  31. package/dist/contact-feedback.cjs +19 -562
  32. package/dist/contact-feedback.d.cts +10 -50
  33. package/dist/contact-feedback.d.ts +10 -50
  34. package/dist/contact-feedback.js +19 -547
  35. package/dist/contact-fitness.cjs +19 -562
  36. package/dist/contact-fitness.d.cts +10 -50
  37. package/dist/contact-fitness.d.ts +10 -50
  38. package/dist/contact-fitness.js +19 -547
  39. package/dist/contact-guest.cjs +19 -562
  40. package/dist/contact-guest.d.cts +10 -50
  41. package/dist/contact-guest.d.ts +10 -50
  42. package/dist/contact-guest.js +19 -547
  43. package/dist/contact-insurance.cjs +19 -562
  44. package/dist/contact-insurance.d.cts +10 -50
  45. package/dist/contact-insurance.d.ts +10 -50
  46. package/dist/contact-insurance.js +19 -547
  47. package/dist/contact-interview.cjs +19 -562
  48. package/dist/contact-interview.d.cts +11 -51
  49. package/dist/contact-interview.d.ts +11 -51
  50. package/dist/contact-interview.js +19 -547
  51. package/dist/contact-locations.cjs +19 -562
  52. package/dist/contact-locations.d.cts +11 -51
  53. package/dist/contact-locations.d.ts +11 -51
  54. package/dist/contact-locations.js +19 -547
  55. package/dist/contact-maintenance.cjs +19 -562
  56. package/dist/contact-maintenance.d.cts +10 -50
  57. package/dist/contact-maintenance.d.ts +10 -50
  58. package/dist/contact-maintenance.js +19 -547
  59. package/dist/contact-map.cjs +19 -562
  60. package/dist/contact-map.d.cts +11 -51
  61. package/dist/contact-map.d.ts +11 -51
  62. package/dist/contact-map.js +19 -547
  63. package/dist/contact-minimal.cjs +19 -562
  64. package/dist/contact-minimal.d.cts +10 -50
  65. package/dist/contact-minimal.d.ts +10 -50
  66. package/dist/contact-minimal.js +19 -547
  67. package/dist/contact-moving.cjs +19 -562
  68. package/dist/contact-moving.d.cts +11 -51
  69. package/dist/contact-moving.d.ts +11 -51
  70. package/dist/contact-moving.js +19 -547
  71. package/dist/contact-multistep.cjs +19 -562
  72. package/dist/contact-multistep.d.cts +11 -51
  73. package/dist/contact-multistep.d.ts +11 -51
  74. package/dist/contact-multistep.js +19 -547
  75. package/dist/contact-partnership.cjs +22 -565
  76. package/dist/contact-partnership.d.cts +10 -50
  77. package/dist/contact-partnership.d.ts +10 -50
  78. package/dist/contact-partnership.js +22 -550
  79. package/dist/contact-photography.cjs +19 -562
  80. package/dist/contact-photography.d.cts +7 -50
  81. package/dist/contact-photography.d.ts +7 -50
  82. package/dist/contact-photography.js +18 -546
  83. package/dist/contact-press.cjs +19 -562
  84. package/dist/contact-press.d.cts +10 -50
  85. package/dist/contact-press.d.ts +10 -50
  86. package/dist/contact-press.js +19 -547
  87. package/dist/contact-quote.cjs +19 -562
  88. package/dist/contact-quote.d.cts +11 -51
  89. package/dist/contact-quote.d.ts +11 -51
  90. package/dist/contact-quote.js +19 -547
  91. package/dist/contact-referral.cjs +19 -562
  92. package/dist/contact-referral.d.cts +10 -50
  93. package/dist/contact-referral.d.ts +10 -50
  94. package/dist/contact-referral.js +19 -547
  95. package/dist/contact-report.cjs +19 -562
  96. package/dist/contact-report.d.cts +10 -50
  97. package/dist/contact-report.d.ts +10 -50
  98. package/dist/contact-report.js +19 -547
  99. package/dist/contact-reservation.cjs +19 -562
  100. package/dist/contact-reservation.d.cts +10 -50
  101. package/dist/contact-reservation.d.ts +10 -50
  102. package/dist/contact-reservation.js +19 -547
  103. package/dist/contact-retreat.cjs +88 -567
  104. package/dist/contact-retreat.d.cts +11 -51
  105. package/dist/contact-retreat.d.ts +11 -51
  106. package/dist/contact-retreat.js +90 -569
  107. package/dist/contact-rsvp.cjs +19 -562
  108. package/dist/contact-rsvp.d.cts +11 -51
  109. package/dist/contact-rsvp.d.ts +11 -51
  110. package/dist/contact-rsvp.js +19 -547
  111. package/dist/contact-sales.cjs +19 -562
  112. package/dist/contact-sales.d.cts +10 -50
  113. package/dist/contact-sales.d.ts +10 -50
  114. package/dist/contact-sales.js +19 -547
  115. package/dist/contact-schedule.cjs +19 -562
  116. package/dist/contact-schedule.d.cts +11 -51
  117. package/dist/contact-schedule.d.ts +11 -51
  118. package/dist/contact-schedule.js +19 -547
  119. package/dist/contact-sponsorship.cjs +19 -562
  120. package/dist/contact-sponsorship.d.cts +11 -51
  121. package/dist/contact-sponsorship.d.ts +11 -51
  122. package/dist/contact-sponsorship.js +19 -547
  123. package/dist/contact-support.cjs +19 -562
  124. package/dist/contact-support.d.cts +11 -51
  125. package/dist/contact-support.d.ts +11 -51
  126. package/dist/contact-support.js +19 -547
  127. package/dist/contact-tenant.cjs +19 -562
  128. package/dist/contact-tenant.d.cts +11 -51
  129. package/dist/contact-tenant.d.ts +11 -51
  130. package/dist/contact-tenant.js +19 -547
  131. package/dist/contact-volunteer.cjs +19 -562
  132. package/dist/contact-volunteer.d.cts +11 -51
  133. package/dist/contact-volunteer.d.ts +11 -51
  134. package/dist/contact-volunteer.js +19 -547
  135. package/dist/contact-warranty.cjs +19 -562
  136. package/dist/contact-warranty.d.cts +10 -50
  137. package/dist/contact-warranty.d.ts +10 -50
  138. package/dist/contact-warranty.js +19 -547
  139. package/dist/contact-wedding.cjs +19 -562
  140. package/dist/contact-wedding.d.cts +10 -50
  141. package/dist/contact-wedding.d.ts +10 -50
  142. package/dist/contact-wedding.js +19 -547
  143. package/dist/hero-presentation-platform-video.cjs +76 -27
  144. package/dist/hero-presentation-platform-video.js +76 -27
  145. package/dist/index.cjs +83 -17
  146. package/dist/index.js +83 -17
  147. package/dist/registry.cjs +768 -4196
  148. package/dist/registry.js +769 -4197
  149. package/package.json +12 -2
@@ -1,436 +1,15 @@
1
1
  "use client";
2
- import * as React from 'react';
3
- import React__default, { useMemo } from 'react';
4
- import { Form } from '@page-speed/forms';
2
+ import * as React4 from 'react';
3
+ import React4__default, { useMemo } from 'react';
4
+ import { FormEngine } from '@page-speed/forms/integration';
5
5
  import { clsx } from 'clsx';
6
6
  import { twMerge } from 'tailwind-merge';
7
- import { cva } from 'class-variance-authority';
8
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
9
- import { useContactForm, getColumnSpanClass, DynamicFormField } from '@page-speed/forms/integration';
10
- import { Icon } from '@page-speed/icon';
7
+ import { jsx, jsxs } from 'react/jsx-runtime';
11
8
 
12
9
  // components/blocks/contact/contact-consultation.tsx
13
10
  function cn(...inputs) {
14
11
  return twMerge(clsx(inputs));
15
12
  }
16
- function normalizePhoneNumber(input) {
17
- const trimmed = input.trim();
18
- if (trimmed.toLowerCase().startsWith("tel:")) {
19
- return trimmed;
20
- }
21
- const match = trimmed.match(/^[\s\+\-\(\)]*(\d[\d\s\-\(\)\.]*\d)[\s\-]*(x|ext\.?|extension)?[\s\-]*(\d+)?$/i);
22
- if (match) {
23
- const mainNumber = match[1].replace(/[\s\-\(\)\.]/g, "");
24
- const extension = match[3];
25
- const normalized = mainNumber.length >= 10 && !trimmed.startsWith("+") ? `+${mainNumber}` : mainNumber;
26
- const withExtension = extension ? `${normalized};ext=${extension}` : normalized;
27
- return `tel:${withExtension}`;
28
- }
29
- const cleaned = trimmed.replace(/[\s\-\(\)\.]/g, "");
30
- return `tel:${cleaned}`;
31
- }
32
- function normalizeEmail(input) {
33
- const trimmed = input.trim();
34
- if (trimmed.toLowerCase().startsWith("mailto:")) {
35
- return trimmed;
36
- }
37
- return `mailto:${trimmed}`;
38
- }
39
- function isEmail(input) {
40
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
41
- return emailRegex.test(input.trim());
42
- }
43
- function isPhoneNumber(input) {
44
- const trimmed = input.trim();
45
- if (trimmed.toLowerCase().startsWith("tel:")) {
46
- return true;
47
- }
48
- const phoneRegex = /^[\s\+\-\(\)]*\d[\d\s\-\(\)\.]*\d[\s\-]*(x|ext\.?|extension)?[\s\-]*\d*$/i;
49
- return phoneRegex.test(trimmed);
50
- }
51
- function isInternalUrl(href) {
52
- if (typeof window === "undefined") {
53
- return href.startsWith("/") && !href.startsWith("//");
54
- }
55
- const trimmed = href.trim();
56
- if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
57
- return true;
58
- }
59
- try {
60
- const url = new URL(trimmed, window.location.href);
61
- const currentOrigin = window.location.origin;
62
- const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
63
- return normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin);
64
- } catch {
65
- return false;
66
- }
67
- }
68
- function toRelativePath(href) {
69
- if (typeof window === "undefined") {
70
- return href;
71
- }
72
- const trimmed = href.trim();
73
- if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
74
- return trimmed;
75
- }
76
- try {
77
- const url = new URL(trimmed, window.location.href);
78
- const currentOrigin = window.location.origin;
79
- const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
80
- if (normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin)) {
81
- return url.pathname + url.search + url.hash;
82
- }
83
- } catch {
84
- }
85
- return trimmed;
86
- }
87
- function useNavigation({
88
- href,
89
- onClick
90
- } = {}) {
91
- const linkType = React.useMemo(() => {
92
- if (!href || href.trim() === "") {
93
- return onClick ? "none" : "none";
94
- }
95
- const trimmed = href.trim();
96
- if (trimmed.toLowerCase().startsWith("mailto:") || isEmail(trimmed)) {
97
- return "mailto";
98
- }
99
- if (trimmed.toLowerCase().startsWith("tel:") || isPhoneNumber(trimmed)) {
100
- return "tel";
101
- }
102
- if (isInternalUrl(trimmed)) {
103
- return "internal";
104
- }
105
- try {
106
- new URL(trimmed, typeof window !== "undefined" ? window.location.href : "http://localhost");
107
- return "external";
108
- } catch {
109
- return "internal";
110
- }
111
- }, [href, onClick]);
112
- const normalizedHref = React.useMemo(() => {
113
- if (!href || href.trim() === "") {
114
- return void 0;
115
- }
116
- const trimmed = href.trim();
117
- switch (linkType) {
118
- case "tel":
119
- return normalizePhoneNumber(trimmed);
120
- case "mailto":
121
- return normalizeEmail(trimmed);
122
- case "internal":
123
- return toRelativePath(trimmed);
124
- case "external":
125
- return trimmed;
126
- default:
127
- return trimmed;
128
- }
129
- }, [href, linkType]);
130
- const target = React.useMemo(() => {
131
- switch (linkType) {
132
- case "external":
133
- return "_blank";
134
- case "internal":
135
- return "_self";
136
- case "mailto":
137
- case "tel":
138
- return void 0;
139
- default:
140
- return void 0;
141
- }
142
- }, [linkType]);
143
- const rel = React.useMemo(() => {
144
- if (linkType === "external") {
145
- return "noopener noreferrer";
146
- }
147
- return void 0;
148
- }, [linkType]);
149
- const isExternal = linkType === "external";
150
- const isInternal = linkType === "internal";
151
- const shouldUseRouter = isInternal && typeof normalizedHref === "string" && normalizedHref.startsWith("/");
152
- const handleClick = React.useCallback(
153
- (event) => {
154
- if (onClick) {
155
- try {
156
- onClick(event);
157
- } catch (error) {
158
- console.error("Error in user onClick handler:", error);
159
- }
160
- }
161
- if (event.defaultPrevented) {
162
- return;
163
- }
164
- if (shouldUseRouter && normalizedHref && event.button === 0 && // left-click only
165
- !event.metaKey && !event.altKey && !event.ctrlKey && !event.shiftKey) {
166
- if (typeof window !== "undefined") {
167
- const handler = window.__opensiteNavigationHandler;
168
- if (typeof handler === "function") {
169
- try {
170
- const handled = handler(normalizedHref, event.nativeEvent || event);
171
- if (handled !== false) {
172
- event.preventDefault();
173
- }
174
- } catch (error) {
175
- console.error("Error in navigation handler:", error);
176
- }
177
- }
178
- }
179
- }
180
- },
181
- [onClick, shouldUseRouter, normalizedHref]
182
- );
183
- return {
184
- linkType,
185
- normalizedHref,
186
- target,
187
- rel,
188
- isExternal,
189
- isInternal,
190
- shouldUseRouter,
191
- handleClick
192
- };
193
- }
194
- var baseStyles = [
195
- // Layout
196
- "inline-flex items-center justify-center gap-2 whitespace-nowrap shrink-0",
197
- // Typography - using CSS variables with sensible defaults
198
- "font-[var(--button-font-family,inherit)]",
199
- "font-[var(--button-font-weight,500)]",
200
- "tracking-[var(--button-letter-spacing,0)]",
201
- "leading-[var(--button-line-height,1.25)]",
202
- "[text-transform:var(--button-text-transform,none)]",
203
- "text-sm",
204
- // Border radius
205
- "rounded-[var(--button-radius,var(--radius,0.375rem))]",
206
- // Smooth transition - using [transition:...] to set full shorthand property (not just transition-property)
207
- "[transition:var(--button-transition,all_250ms_cubic-bezier(0.4,0,0.2,1))]",
208
- // Box shadow (master level) - using [box-shadow:...] for complex multi-value shadows
209
- "[box-shadow:var(--button-shadow,none)]",
210
- "hover:[box-shadow:var(--button-shadow-hover,var(--button-shadow,none))]",
211
- // Disabled state
212
- "disabled:pointer-events-none disabled:opacity-50",
213
- // SVG handling
214
- "[&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0",
215
- // Focus styles
216
- "outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
217
- // Invalid state
218
- "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive"
219
- ].join(" ");
220
- var buttonVariants = cva(baseStyles, {
221
- variants: {
222
- variant: {
223
- // Default (Primary) variant - full customization
224
- default: [
225
- "bg-[var(--button-default-bg,hsl(var(--primary)))]",
226
- "text-[var(--button-default-fg,hsl(var(--primary-foreground)))]",
227
- "border-[length:var(--button-default-border-width,0px)]",
228
- "border-[color:var(--button-default-border,transparent)]",
229
- "[box-shadow:var(--button-default-shadow,var(--button-shadow,none))]",
230
- "hover:bg-[var(--button-default-hover-bg,hsl(var(--primary)/0.9))]",
231
- "hover:text-[var(--button-default-hover-fg,var(--button-default-fg,hsl(var(--primary-foreground))))]",
232
- "hover:border-[color:var(--button-default-hover-border,var(--button-default-border,transparent))]",
233
- "hover:[box-shadow:var(--button-default-shadow-hover,var(--button-shadow-hover,var(--button-default-shadow,var(--button-shadow,none))))]"
234
- ].join(" "),
235
- // Destructive variant - full customization
236
- destructive: [
237
- "bg-[var(--button-destructive-bg,hsl(var(--destructive)))]",
238
- "text-[var(--button-destructive-fg,white)]",
239
- "border-[length:var(--button-destructive-border-width,0px)]",
240
- "border-[color:var(--button-destructive-border,transparent)]",
241
- "[box-shadow:var(--button-destructive-shadow,var(--button-shadow,none))]",
242
- "hover:bg-[var(--button-destructive-hover-bg,hsl(var(--destructive)/0.9))]",
243
- "hover:text-[var(--button-destructive-hover-fg,var(--button-destructive-fg,white))]",
244
- "hover:border-[color:var(--button-destructive-hover-border,var(--button-destructive-border,transparent))]",
245
- "hover:[box-shadow:var(--button-destructive-shadow-hover,var(--button-shadow-hover,var(--button-destructive-shadow,var(--button-shadow,none))))]",
246
- "focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40",
247
- "dark:bg-destructive/60"
248
- ].join(" "),
249
- // Outline variant - full customization with proper border handling
250
- outline: [
251
- "bg-[var(--button-outline-bg,hsl(var(--background)))]",
252
- "text-[var(--button-outline-fg,inherit)]",
253
- "border-[length:var(--button-outline-border-width,1px)]",
254
- "border-[color:var(--button-outline-border,hsl(var(--border)))]",
255
- "[box-shadow:var(--button-outline-shadow,var(--button-shadow,0_1px_2px_0_rgb(0_0_0/0.05)))]",
256
- "hover:bg-[var(--button-outline-hover-bg,hsl(var(--accent)))]",
257
- "hover:text-[var(--button-outline-hover-fg,hsl(var(--accent-foreground)))]",
258
- "hover:border-[color:var(--button-outline-hover-border,var(--button-outline-border,hsl(var(--border))))]",
259
- "hover:[box-shadow:var(--button-outline-shadow-hover,var(--button-shadow-hover,var(--button-outline-shadow,var(--button-shadow,none))))]",
260
- "dark:bg-input/30 dark:border-input dark:hover:bg-input/50"
261
- ].join(" "),
262
- // Secondary variant - full customization
263
- secondary: [
264
- "bg-[var(--button-secondary-bg,hsl(var(--secondary)))]",
265
- "text-[var(--button-secondary-fg,hsl(var(--secondary-foreground)))]",
266
- "border-[length:var(--button-secondary-border-width,0px)]",
267
- "border-[color:var(--button-secondary-border,transparent)]",
268
- "[box-shadow:var(--button-secondary-shadow,var(--button-shadow,none))]",
269
- "hover:bg-[var(--button-secondary-hover-bg,hsl(var(--secondary)/0.8))]",
270
- "hover:text-[var(--button-secondary-hover-fg,var(--button-secondary-fg,hsl(var(--secondary-foreground))))]",
271
- "hover:border-[color:var(--button-secondary-hover-border,var(--button-secondary-border,transparent))]",
272
- "hover:[box-shadow:var(--button-secondary-shadow-hover,var(--button-shadow-hover,var(--button-secondary-shadow,var(--button-shadow,none))))]"
273
- ].join(" "),
274
- // Ghost variant - full customization
275
- ghost: [
276
- "bg-[var(--button-ghost-bg,transparent)]",
277
- "text-[var(--button-ghost-fg,inherit)]",
278
- "border-[length:var(--button-ghost-border-width,0px)]",
279
- "border-[color:var(--button-ghost-border,transparent)]",
280
- "[box-shadow:var(--button-ghost-shadow,var(--button-shadow,none))]",
281
- "hover:bg-[var(--button-ghost-hover-bg,hsl(var(--accent)))]",
282
- "hover:text-[var(--button-ghost-hover-fg,hsl(var(--accent-foreground)))]",
283
- "hover:border-[color:var(--button-ghost-hover-border,var(--button-ghost-border,transparent))]",
284
- "hover:[box-shadow:var(--button-ghost-shadow-hover,var(--button-shadow-hover,var(--button-ghost-shadow,var(--button-shadow,none))))]",
285
- "dark:hover:bg-accent/50"
286
- ].join(" "),
287
- // Link variant - full customization
288
- link: [
289
- "bg-[var(--button-link-bg,transparent)]",
290
- "text-[var(--button-link-fg,hsl(var(--primary)))]",
291
- "border-[length:var(--button-link-border-width,0px)]",
292
- "border-[color:var(--button-link-border,transparent)]",
293
- "[box-shadow:var(--button-link-shadow,none)]",
294
- "hover:bg-[var(--button-link-hover-bg,transparent)]",
295
- "hover:text-[var(--button-link-hover-fg,var(--button-link-fg,hsl(var(--primary))))]",
296
- "hover:[box-shadow:var(--button-link-shadow-hover,none)]",
297
- "underline-offset-4 hover:underline"
298
- ].join(" ")
299
- },
300
- size: {
301
- default: [
302
- "h-[var(--button-height-md,2.25rem)]",
303
- "px-[var(--button-padding-x-md,1rem)]",
304
- "py-[var(--button-padding-y-md,0.5rem)]",
305
- "has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
306
- ].join(" "),
307
- sm: [
308
- "h-[var(--button-height-sm,2rem)]",
309
- "px-[var(--button-padding-x-sm,0.75rem)]",
310
- "py-[var(--button-padding-y-sm,0.25rem)]",
311
- "gap-1.5",
312
- "has-[>svg]:px-[calc(var(--button-padding-x-sm,0.75rem)*0.83)]"
313
- ].join(" "),
314
- md: [
315
- "h-[var(--button-height-md,2.25rem)]",
316
- "px-[var(--button-padding-x-md,1rem)]",
317
- "py-[var(--button-padding-y-md,0.5rem)]",
318
- "has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
319
- ].join(" "),
320
- lg: [
321
- "h-[var(--button-height-lg,2.5rem)]",
322
- "px-[var(--button-padding-x-lg,1.5rem)]",
323
- "py-[var(--button-padding-y-lg,0.5rem)]",
324
- "has-[>svg]:px-[calc(var(--button-padding-x-lg,1.5rem)*0.67)]"
325
- ].join(" "),
326
- icon: "size-[var(--button-height-md,2.25rem)]",
327
- "icon-sm": "size-[var(--button-height-sm,2rem)]",
328
- "icon-lg": "size-[var(--button-height-lg,2.5rem)]"
329
- }
330
- },
331
- defaultVariants: {
332
- variant: "default",
333
- size: "default"
334
- }
335
- });
336
- var Pressable = React.forwardRef(
337
- ({
338
- children,
339
- className,
340
- href,
341
- onClick,
342
- variant,
343
- size,
344
- asButton = false,
345
- fallbackComponentType = "span",
346
- componentType,
347
- "aria-label": ariaLabel,
348
- "aria-describedby": ariaDescribedby,
349
- id,
350
- ...props
351
- }, ref) => {
352
- const navigation = useNavigation({ href, onClick });
353
- const {
354
- normalizedHref,
355
- target,
356
- rel,
357
- linkType,
358
- isInternal,
359
- handleClick
360
- } = navigation;
361
- const shouldRenderLink = normalizedHref && linkType !== "none";
362
- const shouldRenderButton = !shouldRenderLink && onClick;
363
- const effectiveComponentType = componentType || (shouldRenderLink ? "a" : shouldRenderButton ? "button" : fallbackComponentType);
364
- const finalComponentType = isInternal && shouldRenderLink ? "a" : effectiveComponentType;
365
- const shouldApplyButtonStyles = asButton || variant || size;
366
- const combinedClassName = cn(
367
- shouldApplyButtonStyles && buttonVariants({ variant, size }),
368
- className
369
- );
370
- const dataProps = Object.fromEntries(
371
- Object.entries(props).filter(([key]) => key.startsWith("data-"))
372
- );
373
- const buttonDataAttributes = shouldApplyButtonStyles ? {
374
- "data-slot": "button",
375
- "data-variant": variant ?? "default",
376
- "data-size": size ?? "default"
377
- } : {};
378
- const commonProps = {
379
- className: combinedClassName,
380
- onClick: handleClick,
381
- "aria-label": ariaLabel,
382
- "aria-describedby": ariaDescribedby,
383
- id,
384
- ...dataProps,
385
- ...buttonDataAttributes
386
- };
387
- if (finalComponentType === "a" && shouldRenderLink) {
388
- return /* @__PURE__ */ jsx(
389
- "a",
390
- {
391
- ref,
392
- href: normalizedHref,
393
- target,
394
- rel,
395
- ...commonProps,
396
- ...props,
397
- children
398
- }
399
- );
400
- }
401
- if (finalComponentType === "button") {
402
- return /* @__PURE__ */ jsx(
403
- "button",
404
- {
405
- ref,
406
- type: props.type || "button",
407
- ...commonProps,
408
- ...props,
409
- children
410
- }
411
- );
412
- }
413
- if (finalComponentType === "div") {
414
- return /* @__PURE__ */ jsx(
415
- "div",
416
- {
417
- ref,
418
- ...commonProps,
419
- children
420
- }
421
- );
422
- }
423
- return /* @__PURE__ */ jsx(
424
- "span",
425
- {
426
- ref,
427
- ...commonProps,
428
- children
429
- }
430
- );
431
- }
432
- );
433
- Pressable.displayName = "Pressable";
434
13
  function Card({ className, ...props }) {
435
14
  return /* @__PURE__ */ jsx(
436
15
  "div",
@@ -454,10 +33,6 @@ function CardContent({ className, ...props }) {
454
33
  }
455
34
  );
456
35
  }
457
- var DEFAULT_ICON_API_KEY = "au382bi7fsh96w9h9xlrnat2jglx";
458
- function DynamicIcon({ apiKey, ...props }) {
459
- return /* @__PURE__ */ jsx(Icon, { ...props, apiKey: apiKey ?? DEFAULT_ICON_API_KEY });
460
- }
461
36
  var maxWidthStyles = {
462
37
  sm: "max-w-screen-sm",
463
38
  md: "max-w-screen-md",
@@ -467,7 +42,7 @@ var maxWidthStyles = {
467
42
  "4xl": "max-w-[1536px]",
468
43
  full: "max-w-full"
469
44
  };
470
- var Container = React__default.forwardRef(
45
+ var Container = React4__default.forwardRef(
471
46
  ({ children, maxWidth = "xl", className, as = "div", ...props }, ref) => {
472
47
  const Component = as;
473
48
  return /* @__PURE__ */ jsx(
@@ -772,7 +347,7 @@ var spacingStyles = {
772
347
  };
773
348
  var predefinedSpacings = ["none", "sm", "md", "lg", "xl"];
774
349
  var isPredefinedSpacing = (spacing) => predefinedSpacings.includes(spacing);
775
- var Section = React__default.forwardRef(
350
+ var Section = React4__default.forwardRef(
776
351
  ({
777
352
  id,
778
353
  title,
@@ -833,6 +408,44 @@ var Section = React__default.forwardRef(
833
408
  }
834
409
  );
835
410
  Section.displayName = "Section";
411
+ function TextInner({ as, className, children, ...props }, ref) {
412
+ const Component = as || "span";
413
+ return /* @__PURE__ */ jsx(Component, { ref, className: cn(className), ...props, children });
414
+ }
415
+ var Text = React4.forwardRef(TextInner);
416
+ Text.displayName = "Text";
417
+ function isContentTextItem(item) {
418
+ return item !== null && typeof item === "object" && !React4.isValidElement(item) && "_type" in item && item._type === "text";
419
+ }
420
+ var ContentGroup = React4.forwardRef(
421
+ ({ items, className, children, ...props }, ref) => {
422
+ const hasContent = items && items.length > 0;
423
+ if (!hasContent) {
424
+ return null;
425
+ }
426
+ return /* @__PURE__ */ jsxs("div", { ref, className: cn(className), ...props, children: [
427
+ items.map((item, idx) => {
428
+ if (isContentTextItem(item)) {
429
+ const { _type, ...textProps } = item;
430
+ return /* @__PURE__ */ jsx(Text, { ...textProps }, idx);
431
+ }
432
+ const reactNode = item;
433
+ if (React4.isValidElement(reactNode)) {
434
+ return React4.cloneElement(reactNode, { key: reactNode.key ?? idx });
435
+ }
436
+ return /* @__PURE__ */ jsx(React4.Fragment, { children: reactNode }, idx);
437
+ }),
438
+ children
439
+ ] });
440
+ }
441
+ );
442
+ ContentGroup.displayName = "ContentGroup";
443
+ var DEFAULT_STYLE_RULES = {
444
+ formContainer: "",
445
+ fieldsContainer: "",
446
+ fieldClassName: "",
447
+ formClassName: "space-y-6"
448
+ };
836
449
  var SERVICES = [
837
450
  { value: "strategy", label: "Business Strategy" },
838
451
  { value: "marketing", label: "Marketing Consultation" },
@@ -935,73 +548,50 @@ var DEFAULT_FORM_FIELDS = [
935
548
  function ContactConsultation({
936
549
  heading,
937
550
  description,
938
- buttonText = "Book Consultation",
939
- buttonIcon,
940
- actions,
941
- actionsSlot,
942
- formFields,
943
- successMessage = "Thank you for your consultation request! We'll be in touch within 24 hours to schedule your session.",
944
551
  className,
945
552
  headerClassName,
946
553
  headingClassName,
947
554
  descriptionClassName,
948
555
  cardClassName,
949
556
  cardContentClassName,
950
- formClassName,
951
- successMessageClassName,
952
- errorMessageClassName,
953
- submitClassName,
954
557
  spacing = "py-8 md:py-32",
955
558
  containerClassName = "px-6 sm:px-6 md:px-8 lg:px-8",
956
559
  background,
957
560
  pattern,
958
561
  patternOpacity,
959
- formConfig,
960
- onSubmit,
961
- onSuccess,
962
- onError
562
+ formEngineSetup
963
563
  }) {
964
- const fields = useMemo(
965
- () => formFields || DEFAULT_FORM_FIELDS,
966
- [formFields]
967
- );
968
- const { form, submissionError, formMethod, resetSubmissionState } = useContactForm({
969
- formFields: fields,
970
- formConfig,
971
- onSubmit,
972
- onSuccess,
973
- onError
974
- });
975
- const actionsContent = React.useMemo(() => {
976
- if (actionsSlot) return actionsSlot;
977
- if (actions && actions.length > 0) {
978
- return actions.map((action, index) => {
979
- const {
980
- label,
981
- icon,
982
- iconAfter,
983
- children,
984
- className: actionClassName,
985
- ...pressableProps
986
- } = action;
987
- return /* @__PURE__ */ jsx(
988
- Pressable,
989
- {
990
- asButton: true,
991
- className: actionClassName,
992
- ...pressableProps,
993
- children: children ?? /* @__PURE__ */ jsxs(Fragment, { children: [
994
- icon,
995
- label,
996
- iconAfter
997
- ] })
998
- },
999
- index
1000
- );
1001
- });
564
+ const headerItems = useMemo(() => {
565
+ const items = [];
566
+ if (heading) {
567
+ if (typeof heading === "string") {
568
+ items.push({
569
+ _type: "text",
570
+ as: "h2",
571
+ className: cn(
572
+ "mb-3 text-3xl font-bold tracking-tight text-balance",
573
+ headingClassName
574
+ ),
575
+ children: heading
576
+ });
577
+ } else {
578
+ items.push(heading);
579
+ }
1002
580
  }
1003
- return null;
1004
- }, [actionsSlot, actions]);
581
+ if (description) {
582
+ if (typeof description === "string") {
583
+ items.push({
584
+ _type: "text",
585
+ as: "p",
586
+ className: cn("leading-relaxed text-balance", descriptionClassName),
587
+ children: description
588
+ });
589
+ } else {
590
+ items.push(description);
591
+ }
592
+ }
593
+ return items;
594
+ }, [heading, headingClassName, description, descriptionClassName]);
1005
595
  return /* @__PURE__ */ jsx(
1006
596
  Section,
1007
597
  {
@@ -1012,67 +602,21 @@ function ContactConsultation({
1012
602
  className,
1013
603
  containerClassName,
1014
604
  children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
1015
- /* @__PURE__ */ jsxs("div", { className: cn("mb-10 text-center", headerClassName), children: [
1016
- heading && (typeof heading === "string" ? /* @__PURE__ */ jsx(
1017
- "h2",
1018
- {
1019
- className: cn(
1020
- "mb-3 text-3xl font-bold tracking-tight text-balance",
1021
- headingClassName
1022
- ),
1023
- children: heading
1024
- }
1025
- ) : /* @__PURE__ */ jsx("div", { className: headingClassName, children: heading })),
1026
- description && (typeof description === "string" ? /* @__PURE__ */ jsx(
1027
- "p",
1028
- {
1029
- className: cn(
1030
- "leading-relaxed text-balance",
1031
- descriptionClassName
1032
- ),
1033
- children: description
1034
- }
1035
- ) : /* @__PURE__ */ jsx("div", { className: descriptionClassName, children: description }))
1036
- ] }),
1037
- /* @__PURE__ */ jsx(Card, { className: cardClassName, children: /* @__PURE__ */ jsx(CardContent, { className: cn("p-6 lg:p-8", cardContentClassName), children: /* @__PURE__ */ jsxs(
1038
- Form,
605
+ /* @__PURE__ */ jsx(
606
+ ContentGroup,
607
+ {
608
+ items: headerItems,
609
+ className: cn("mb-10 text-center", headerClassName)
610
+ }
611
+ ),
612
+ /* @__PURE__ */ jsx(Card, { className: cardClassName, children: /* @__PURE__ */ jsx(CardContent, { className: cn("p-6 lg:p-8", cardContentClassName), children: formEngineSetup ? /* @__PURE__ */ jsx(
613
+ FormEngine,
1039
614
  {
1040
- form,
1041
- action: formConfig?.endpoint,
1042
- method: formMethod,
1043
- submissionError,
1044
- successMessage,
1045
- successMessageClassName,
1046
- errorMessageClassName,
1047
- submissionConfig: formConfig?.submissionConfig,
1048
- onNewSubmission: resetSubmissionState,
1049
- className: cn("space-y-6", formClassName),
1050
- children: [
1051
- /* @__PURE__ */ jsx("div", { className: "grid grid-cols-12 gap-6", children: fields.map((field) => /* @__PURE__ */ jsx("div", { className: getColumnSpanClass(field.columnSpan), children: /* @__PURE__ */ jsx(DynamicFormField, { field }) }, field.name)) }),
1052
- actionsSlot || actions && actions.length > 0 ? actionsContent : /* @__PURE__ */ jsxs(
1053
- Pressable,
1054
- {
1055
- componentType: "button",
1056
- type: "submit",
1057
- className: cn("w-full", submitClassName),
1058
- asButton: true,
1059
- disabled: form.isSubmitting,
1060
- children: [
1061
- buttonIcon ?? /* @__PURE__ */ jsx(
1062
- DynamicIcon,
1063
- {
1064
- name: "lucide/calendar-check",
1065
- size: 16,
1066
- className: "mr-2"
1067
- }
1068
- ),
1069
- buttonText
1070
- ]
1071
- }
1072
- )
1073
- ]
615
+ formEngineSetup,
616
+ defaultFields: DEFAULT_FORM_FIELDS,
617
+ defaultStyleRules: DEFAULT_STYLE_RULES
1074
618
  }
1075
- ) }) })
619
+ ) : null }) })
1076
620
  ] })
1077
621
  }
1078
622
  );