@opensite/ui 2.1.9 → 2.2.1

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.
@@ -1,14 +1,14 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var React = require('react');
5
- var forms = require('@page-speed/forms');
4
+ var React3 = require('react');
5
+ var framerMotion = require('framer-motion');
6
6
  var integration = require('@page-speed/forms/integration');
7
7
  var clsx = require('clsx');
8
8
  var tailwindMerge = require('tailwind-merge');
9
- var classVarianceAuthority = require('class-variance-authority');
10
- var jsxRuntime = require('react/jsx-runtime');
11
9
  var img = require('@page-speed/img');
10
+ var icon = require('@page-speed/icon');
11
+ var jsxRuntime = require('react/jsx-runtime');
12
12
 
13
13
  function _interopNamespace(e) {
14
14
  if (e && e.__esModule) return e;
@@ -28,452 +28,15 @@ function _interopNamespace(e) {
28
28
  return Object.freeze(n);
29
29
  }
30
30
 
31
- var React__namespace = /*#__PURE__*/_interopNamespace(React);
31
+ var React3__namespace = /*#__PURE__*/_interopNamespace(React3);
32
32
 
33
33
  // components/blocks/contact/contact-image.tsx
34
34
  function cn(...inputs) {
35
35
  return tailwindMerge.twMerge(clsx.clsx(inputs));
36
36
  }
37
- function normalizePhoneNumber(input) {
38
- const trimmed = input.trim();
39
- if (trimmed.toLowerCase().startsWith("tel:")) {
40
- return trimmed;
41
- }
42
- const match = trimmed.match(/^[\s\+\-\(\)]*(\d[\d\s\-\(\)\.]*\d)[\s\-]*(x|ext\.?|extension)?[\s\-]*(\d+)?$/i);
43
- if (match) {
44
- const mainNumber = match[1].replace(/[\s\-\(\)\.]/g, "");
45
- const extension = match[3];
46
- const normalized = mainNumber.length >= 10 && !trimmed.startsWith("+") ? `+${mainNumber}` : mainNumber;
47
- const withExtension = extension ? `${normalized};ext=${extension}` : normalized;
48
- return `tel:${withExtension}`;
49
- }
50
- const cleaned = trimmed.replace(/[\s\-\(\)\.]/g, "");
51
- return `tel:${cleaned}`;
52
- }
53
- function normalizeEmail(input) {
54
- const trimmed = input.trim();
55
- if (trimmed.toLowerCase().startsWith("mailto:")) {
56
- return trimmed;
57
- }
58
- return `mailto:${trimmed}`;
59
- }
60
- function isEmail(input) {
61
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
62
- return emailRegex.test(input.trim());
63
- }
64
- function isPhoneNumber(input) {
65
- const trimmed = input.trim();
66
- if (trimmed.toLowerCase().startsWith("tel:")) {
67
- return true;
68
- }
69
- const phoneRegex = /^[\s\+\-\(\)]*\d[\d\s\-\(\)\.]*\d[\s\-]*(x|ext\.?|extension)?[\s\-]*\d*$/i;
70
- return phoneRegex.test(trimmed);
71
- }
72
- function isInternalUrl(href) {
73
- if (typeof window === "undefined") {
74
- return href.startsWith("/") && !href.startsWith("//");
75
- }
76
- const trimmed = href.trim();
77
- if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
78
- return true;
79
- }
80
- try {
81
- const url = new URL(trimmed, window.location.href);
82
- const currentOrigin = window.location.origin;
83
- const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
84
- return normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin);
85
- } catch {
86
- return false;
87
- }
88
- }
89
- function toRelativePath(href) {
90
- if (typeof window === "undefined") {
91
- return href;
92
- }
93
- const trimmed = href.trim();
94
- if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
95
- return trimmed;
96
- }
97
- try {
98
- const url = new URL(trimmed, window.location.href);
99
- const currentOrigin = window.location.origin;
100
- const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
101
- if (normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin)) {
102
- return url.pathname + url.search + url.hash;
103
- }
104
- } catch {
105
- }
106
- return trimmed;
107
- }
108
- function useNavigation({
109
- href,
110
- onClick
111
- } = {}) {
112
- const linkType = React__namespace.useMemo(() => {
113
- if (!href || href.trim() === "") {
114
- return onClick ? "none" : "none";
115
- }
116
- const trimmed = href.trim();
117
- if (trimmed.toLowerCase().startsWith("mailto:") || isEmail(trimmed)) {
118
- return "mailto";
119
- }
120
- if (trimmed.toLowerCase().startsWith("tel:") || isPhoneNumber(trimmed)) {
121
- return "tel";
122
- }
123
- if (isInternalUrl(trimmed)) {
124
- return "internal";
125
- }
126
- try {
127
- new URL(trimmed, typeof window !== "undefined" ? window.location.href : "http://localhost");
128
- return "external";
129
- } catch {
130
- return "internal";
131
- }
132
- }, [href, onClick]);
133
- const normalizedHref = React__namespace.useMemo(() => {
134
- if (!href || href.trim() === "") {
135
- return void 0;
136
- }
137
- const trimmed = href.trim();
138
- switch (linkType) {
139
- case "tel":
140
- return normalizePhoneNumber(trimmed);
141
- case "mailto":
142
- return normalizeEmail(trimmed);
143
- case "internal":
144
- return toRelativePath(trimmed);
145
- case "external":
146
- return trimmed;
147
- default:
148
- return trimmed;
149
- }
150
- }, [href, linkType]);
151
- const target = React__namespace.useMemo(() => {
152
- switch (linkType) {
153
- case "external":
154
- return "_blank";
155
- case "internal":
156
- return "_self";
157
- case "mailto":
158
- case "tel":
159
- return void 0;
160
- default:
161
- return void 0;
162
- }
163
- }, [linkType]);
164
- const rel = React__namespace.useMemo(() => {
165
- if (linkType === "external") {
166
- return "noopener noreferrer";
167
- }
168
- return void 0;
169
- }, [linkType]);
170
- const isExternal = linkType === "external";
171
- const isInternal = linkType === "internal";
172
- const shouldUseRouter = isInternal && typeof normalizedHref === "string" && normalizedHref.startsWith("/");
173
- const handleClick = React__namespace.useCallback(
174
- (event) => {
175
- if (onClick) {
176
- try {
177
- onClick(event);
178
- } catch (error) {
179
- console.error("Error in user onClick handler:", error);
180
- }
181
- }
182
- if (event.defaultPrevented) {
183
- return;
184
- }
185
- if (shouldUseRouter && normalizedHref && event.button === 0 && // left-click only
186
- !event.metaKey && !event.altKey && !event.ctrlKey && !event.shiftKey) {
187
- if (typeof window !== "undefined") {
188
- const handler = window.__opensiteNavigationHandler;
189
- if (typeof handler === "function") {
190
- try {
191
- const handled = handler(normalizedHref, event.nativeEvent || event);
192
- if (handled !== false) {
193
- event.preventDefault();
194
- }
195
- } catch (error) {
196
- console.error("Error in navigation handler:", error);
197
- }
198
- }
199
- }
200
- }
201
- },
202
- [onClick, shouldUseRouter, normalizedHref]
203
- );
204
- return {
205
- linkType,
206
- normalizedHref,
207
- target,
208
- rel,
209
- isExternal,
210
- isInternal,
211
- shouldUseRouter,
212
- handleClick
213
- };
214
- }
215
- var baseStyles = [
216
- // Layout
217
- "inline-flex items-center justify-center gap-2 whitespace-nowrap shrink-0",
218
- // Typography - using CSS variables with sensible defaults
219
- "font-[var(--button-font-family,inherit)]",
220
- "font-[var(--button-font-weight,500)]",
221
- "tracking-[var(--button-letter-spacing,0)]",
222
- "leading-[var(--button-line-height,1.25)]",
223
- "[text-transform:var(--button-text-transform,none)]",
224
- "text-sm",
225
- // Border radius
226
- "rounded-[var(--button-radius,var(--radius,0.375rem))]",
227
- // Smooth transition - using [transition:...] to set full shorthand property (not just transition-property)
228
- "[transition:var(--button-transition,all_250ms_cubic-bezier(0.4,0,0.2,1))]",
229
- // Box shadow (master level) - using [box-shadow:...] for complex multi-value shadows
230
- "[box-shadow:var(--button-shadow,none)]",
231
- "hover:[box-shadow:var(--button-shadow-hover,var(--button-shadow,none))]",
232
- // Disabled state
233
- "disabled:pointer-events-none disabled:opacity-50",
234
- // SVG handling
235
- "[&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0",
236
- // Focus styles
237
- "outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
238
- // Invalid state
239
- "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive"
240
- ].join(" ");
241
- var buttonVariants = classVarianceAuthority.cva(baseStyles, {
242
- variants: {
243
- variant: {
244
- // Default (Primary) variant - full customization
245
- default: [
246
- "bg-[var(--button-default-bg,hsl(var(--primary)))]",
247
- "text-[var(--button-default-fg,hsl(var(--primary-foreground)))]",
248
- "border-[length:var(--button-default-border-width,0px)]",
249
- "border-[color:var(--button-default-border,transparent)]",
250
- "[box-shadow:var(--button-default-shadow,var(--button-shadow,none))]",
251
- "hover:bg-[var(--button-default-hover-bg,hsl(var(--primary)/0.9))]",
252
- "hover:text-[var(--button-default-hover-fg,var(--button-default-fg,hsl(var(--primary-foreground))))]",
253
- "hover:border-[color:var(--button-default-hover-border,var(--button-default-border,transparent))]",
254
- "hover:[box-shadow:var(--button-default-shadow-hover,var(--button-shadow-hover,var(--button-default-shadow,var(--button-shadow,none))))]"
255
- ].join(" "),
256
- // Destructive variant - full customization
257
- destructive: [
258
- "bg-[var(--button-destructive-bg,hsl(var(--destructive)))]",
259
- "text-[var(--button-destructive-fg,white)]",
260
- "border-[length:var(--button-destructive-border-width,0px)]",
261
- "border-[color:var(--button-destructive-border,transparent)]",
262
- "[box-shadow:var(--button-destructive-shadow,var(--button-shadow,none))]",
263
- "hover:bg-[var(--button-destructive-hover-bg,hsl(var(--destructive)/0.9))]",
264
- "hover:text-[var(--button-destructive-hover-fg,var(--button-destructive-fg,white))]",
265
- "hover:border-[color:var(--button-destructive-hover-border,var(--button-destructive-border,transparent))]",
266
- "hover:[box-shadow:var(--button-destructive-shadow-hover,var(--button-shadow-hover,var(--button-destructive-shadow,var(--button-shadow,none))))]",
267
- "focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40",
268
- "dark:bg-destructive/60"
269
- ].join(" "),
270
- // Outline variant - full customization with proper border handling
271
- outline: [
272
- "bg-[var(--button-outline-bg,hsl(var(--background)))]",
273
- "text-[var(--button-outline-fg,inherit)]",
274
- "border-[length:var(--button-outline-border-width,1px)]",
275
- "border-[color:var(--button-outline-border,hsl(var(--border)))]",
276
- "[box-shadow:var(--button-outline-shadow,var(--button-shadow,0_1px_2px_0_rgb(0_0_0/0.05)))]",
277
- "hover:bg-[var(--button-outline-hover-bg,hsl(var(--accent)))]",
278
- "hover:text-[var(--button-outline-hover-fg,hsl(var(--accent-foreground)))]",
279
- "hover:border-[color:var(--button-outline-hover-border,var(--button-outline-border,hsl(var(--border))))]",
280
- "hover:[box-shadow:var(--button-outline-shadow-hover,var(--button-shadow-hover,var(--button-outline-shadow,var(--button-shadow,none))))]",
281
- "dark:bg-input/30 dark:border-input dark:hover:bg-input/50"
282
- ].join(" "),
283
- // Secondary variant - full customization
284
- secondary: [
285
- "bg-[var(--button-secondary-bg,hsl(var(--secondary)))]",
286
- "text-[var(--button-secondary-fg,hsl(var(--secondary-foreground)))]",
287
- "border-[length:var(--button-secondary-border-width,0px)]",
288
- "border-[color:var(--button-secondary-border,transparent)]",
289
- "[box-shadow:var(--button-secondary-shadow,var(--button-shadow,none))]",
290
- "hover:bg-[var(--button-secondary-hover-bg,hsl(var(--secondary)/0.8))]",
291
- "hover:text-[var(--button-secondary-hover-fg,var(--button-secondary-fg,hsl(var(--secondary-foreground))))]",
292
- "hover:border-[color:var(--button-secondary-hover-border,var(--button-secondary-border,transparent))]",
293
- "hover:[box-shadow:var(--button-secondary-shadow-hover,var(--button-shadow-hover,var(--button-secondary-shadow,var(--button-shadow,none))))]"
294
- ].join(" "),
295
- // Ghost variant - full customization
296
- ghost: [
297
- "bg-[var(--button-ghost-bg,transparent)]",
298
- "text-[var(--button-ghost-fg,inherit)]",
299
- "border-[length:var(--button-ghost-border-width,0px)]",
300
- "border-[color:var(--button-ghost-border,transparent)]",
301
- "[box-shadow:var(--button-ghost-shadow,var(--button-shadow,none))]",
302
- "hover:bg-[var(--button-ghost-hover-bg,hsl(var(--accent)))]",
303
- "hover:text-[var(--button-ghost-hover-fg,hsl(var(--accent-foreground)))]",
304
- "hover:border-[color:var(--button-ghost-hover-border,var(--button-ghost-border,transparent))]",
305
- "hover:[box-shadow:var(--button-ghost-shadow-hover,var(--button-shadow-hover,var(--button-ghost-shadow,var(--button-shadow,none))))]",
306
- "dark:hover:bg-accent/50"
307
- ].join(" "),
308
- // Link variant - full customization
309
- link: [
310
- "bg-[var(--button-link-bg,transparent)]",
311
- "text-[var(--button-link-fg,hsl(var(--primary)))]",
312
- "border-[length:var(--button-link-border-width,0px)]",
313
- "border-[color:var(--button-link-border,transparent)]",
314
- "[box-shadow:var(--button-link-shadow,none)]",
315
- "hover:bg-[var(--button-link-hover-bg,transparent)]",
316
- "hover:text-[var(--button-link-hover-fg,var(--button-link-fg,hsl(var(--primary))))]",
317
- "hover:[box-shadow:var(--button-link-shadow-hover,none)]",
318
- "underline-offset-4 hover:underline"
319
- ].join(" ")
320
- },
321
- size: {
322
- default: [
323
- "h-[var(--button-height-md,2.25rem)]",
324
- "px-[var(--button-padding-x-md,1rem)]",
325
- "py-[var(--button-padding-y-md,0.5rem)]",
326
- "has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
327
- ].join(" "),
328
- sm: [
329
- "h-[var(--button-height-sm,2rem)]",
330
- "px-[var(--button-padding-x-sm,0.75rem)]",
331
- "py-[var(--button-padding-y-sm,0.25rem)]",
332
- "gap-1.5",
333
- "has-[>svg]:px-[calc(var(--button-padding-x-sm,0.75rem)*0.83)]"
334
- ].join(" "),
335
- md: [
336
- "h-[var(--button-height-md,2.25rem)]",
337
- "px-[var(--button-padding-x-md,1rem)]",
338
- "py-[var(--button-padding-y-md,0.5rem)]",
339
- "has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
340
- ].join(" "),
341
- lg: [
342
- "h-[var(--button-height-lg,2.5rem)]",
343
- "px-[var(--button-padding-x-lg,1.5rem)]",
344
- "py-[var(--button-padding-y-lg,0.5rem)]",
345
- "has-[>svg]:px-[calc(var(--button-padding-x-lg,1.5rem)*0.67)]"
346
- ].join(" "),
347
- icon: "size-[var(--button-height-md,2.25rem)]",
348
- "icon-sm": "size-[var(--button-height-sm,2rem)]",
349
- "icon-lg": "size-[var(--button-height-lg,2.5rem)]"
350
- }
351
- },
352
- defaultVariants: {
353
- variant: "default",
354
- size: "default"
355
- }
356
- });
357
- var Pressable = React__namespace.forwardRef(
358
- ({
359
- children,
360
- className,
361
- href,
362
- onClick,
363
- variant,
364
- size,
365
- asButton = false,
366
- fallbackComponentType = "span",
367
- componentType,
368
- "aria-label": ariaLabel,
369
- "aria-describedby": ariaDescribedby,
370
- id,
371
- ...props
372
- }, ref) => {
373
- const navigation = useNavigation({ href, onClick });
374
- const {
375
- normalizedHref,
376
- target,
377
- rel,
378
- linkType,
379
- isInternal,
380
- handleClick
381
- } = navigation;
382
- const shouldRenderLink = normalizedHref && linkType !== "none";
383
- const shouldRenderButton = !shouldRenderLink && onClick;
384
- const effectiveComponentType = componentType || (shouldRenderLink ? "a" : shouldRenderButton ? "button" : fallbackComponentType);
385
- const finalComponentType = isInternal && shouldRenderLink ? "a" : effectiveComponentType;
386
- const shouldApplyButtonStyles = asButton || variant || size;
387
- const combinedClassName = cn(
388
- shouldApplyButtonStyles && buttonVariants({ variant, size }),
389
- className
390
- );
391
- const dataProps = Object.fromEntries(
392
- Object.entries(props).filter(([key]) => key.startsWith("data-"))
393
- );
394
- const buttonDataAttributes = shouldApplyButtonStyles ? {
395
- "data-slot": "button",
396
- "data-variant": variant ?? "default",
397
- "data-size": size ?? "default"
398
- } : {};
399
- const commonProps = {
400
- className: combinedClassName,
401
- onClick: handleClick,
402
- "aria-label": ariaLabel,
403
- "aria-describedby": ariaDescribedby,
404
- id,
405
- ...dataProps,
406
- ...buttonDataAttributes
407
- };
408
- if (finalComponentType === "a" && shouldRenderLink) {
409
- return /* @__PURE__ */ jsxRuntime.jsx(
410
- "a",
411
- {
412
- ref,
413
- href: normalizedHref,
414
- target,
415
- rel,
416
- ...commonProps,
417
- ...props,
418
- children
419
- }
420
- );
421
- }
422
- if (finalComponentType === "button") {
423
- return /* @__PURE__ */ jsxRuntime.jsx(
424
- "button",
425
- {
426
- ref,
427
- type: props.type || "button",
428
- ...commonProps,
429
- ...props,
430
- children
431
- }
432
- );
433
- }
434
- if (finalComponentType === "div") {
435
- return /* @__PURE__ */ jsxRuntime.jsx(
436
- "div",
437
- {
438
- ref,
439
- ...commonProps,
440
- children
441
- }
442
- );
443
- }
444
- return /* @__PURE__ */ jsxRuntime.jsx(
445
- "span",
446
- {
447
- ref,
448
- ...commonProps,
449
- children
450
- }
451
- );
452
- }
453
- );
454
- Pressable.displayName = "Pressable";
455
- function Card({ className, ...props }) {
456
- return /* @__PURE__ */ jsxRuntime.jsx(
457
- "div",
458
- {
459
- "data-slot": "card",
460
- className: cn(
461
- "bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm",
462
- className
463
- ),
464
- ...props
465
- }
466
- );
467
- }
468
- function CardContent({ className, ...props }) {
469
- return /* @__PURE__ */ jsxRuntime.jsx(
470
- "div",
471
- {
472
- "data-slot": "card-content",
473
- className: cn("px-6", className),
474
- ...props
475
- }
476
- );
37
+ var DEFAULT_ICON_API_KEY = "au382bi7fsh96w9h9xlrnat2jglx";
38
+ function DynamicIcon({ apiKey, ...props }) {
39
+ return /* @__PURE__ */ jsxRuntime.jsx(icon.Icon, { ...props, apiKey: apiKey ?? DEFAULT_ICON_API_KEY });
477
40
  }
478
41
  var maxWidthStyles = {
479
42
  sm: "max-w-screen-sm",
@@ -484,7 +47,7 @@ var maxWidthStyles = {
484
47
  "4xl": "max-w-[1536px]",
485
48
  full: "max-w-full"
486
49
  };
487
- var Container = React__namespace.default.forwardRef(
50
+ var Container = React3__namespace.default.forwardRef(
488
51
  ({ children, maxWidth = "xl", className, as = "div", ...props }, ref) => {
489
52
  const Component = as;
490
53
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -789,7 +352,7 @@ var spacingStyles = {
789
352
  };
790
353
  var predefinedSpacings = ["none", "sm", "md", "lg", "xl"];
791
354
  var isPredefinedSpacing = (spacing) => predefinedSpacings.includes(spacing);
792
- var Section = React__namespace.default.forwardRef(
355
+ var Section = React3__namespace.default.forwardRef(
793
356
  ({
794
357
  id,
795
358
  title,
@@ -850,6 +413,12 @@ var Section = React__namespace.default.forwardRef(
850
413
  }
851
414
  );
852
415
  Section.displayName = "Section";
416
+ var DEFAULT_STYLE_RULES = {
417
+ formContainer: "",
418
+ fieldsContainer: "",
419
+ fieldClassName: "",
420
+ formClassName: "space-y-4"
421
+ };
853
422
  var DEFAULT_FORM_FIELDS = [
854
423
  {
855
424
  name: "first_name",
@@ -894,207 +463,186 @@ var DEFAULT_FORM_FIELDS = [
894
463
  }
895
464
  ];
896
465
  function ContactImage({
466
+ eyebrow,
897
467
  heading,
898
468
  description,
899
- buttonText = "Submit",
469
+ buttonText = "Send Message",
900
470
  buttonIcon,
901
- actions,
902
- actionsSlot,
903
- formFields = DEFAULT_FORM_FIELDS,
904
- successMessage = "Thank you! Your message has been sent successfully.",
471
+ image,
472
+ contactOverlays,
473
+ contactOverlaysSlot,
474
+ formEngineSetup,
475
+ className,
476
+ containerClassName = "px-6 sm:px-6 md:px-8 lg:px-8",
477
+ contentClassName,
478
+ eyebrowClassName,
905
479
  headingClassName,
906
480
  descriptionClassName,
907
- cardClassName,
908
- cardContentClassName,
909
- formClassName,
910
- submitClassName,
911
- successMessageClassName,
912
- errorMessageClassName,
913
- backgroundImage,
481
+ imageClassName,
482
+ contactOverlaysClassName,
914
483
  background,
915
- optixFlowConfig,
916
- spacing = "none",
917
- className,
918
- containerClassName = "px-0 sm:px-0 lg:px-0 max-w-full relative z-10 h-screen w-screen flex justify-center items-center",
919
- contentClassName = "",
484
+ spacing = "py-16 md:py-32",
920
485
  pattern,
921
- patternOpacity = 0.1,
922
- formConfig,
923
- onSubmit,
924
- onSuccess,
925
- onError
486
+ patternOpacity,
487
+ optixFlowConfig
926
488
  }) {
927
- const {
928
- uploadTokens,
929
- uploadProgress,
930
- isUploading,
931
- uploadFiles,
932
- removeFile,
933
- resetUpload
934
- } = integration.useFileUpload({ onError });
935
- const { form, submissionError, formMethod, resetSubmissionState } = integration.useContactForm({
936
- formFields,
937
- formConfig,
938
- onSubmit,
939
- onSuccess: (data) => {
940
- resetUpload();
941
- onSuccess?.(data);
942
- },
943
- onError,
944
- resetOnSuccess: formConfig?.resetOnSuccess !== false,
945
- uploadTokens
946
- });
947
- const actionsContent = React.useMemo(() => {
948
- if (actionsSlot) return actionsSlot;
949
- if (actions && actions.length > 0) {
950
- return actions.map((action, index) => {
951
- const {
952
- label,
953
- icon,
954
- iconAfter,
955
- children,
956
- className: actionClassName,
957
- ...pressableProps
958
- } = action;
489
+ const formStyleRules = React3__namespace.useMemo(() => {
490
+ return {
491
+ formContainer: formEngineSetup?.formLayoutSettings?.styleRules?.formContainer ?? DEFAULT_STYLE_RULES.formContainer,
492
+ fieldsContainer: formEngineSetup?.formLayoutSettings?.styleRules?.fieldsContainer ?? DEFAULT_STYLE_RULES.fieldsContainer,
493
+ fieldClassName: formEngineSetup?.formLayoutSettings?.styleRules?.fieldClassName ?? DEFAULT_STYLE_RULES.fieldClassName,
494
+ formClassName: formEngineSetup?.formLayoutSettings?.styleRules?.formClassName ?? DEFAULT_STYLE_RULES.formClassName,
495
+ successMessageClassName: formEngineSetup?.formLayoutSettings?.styleRules?.successMessageClassName ?? DEFAULT_STYLE_RULES.successMessageClassName,
496
+ errorMessageClassName: formEngineSetup?.formLayoutSettings?.styleRules?.errorMessageClassName ?? DEFAULT_STYLE_RULES.errorMessageClassName
497
+ };
498
+ }, [formEngineSetup?.formLayoutSettings?.styleRules]);
499
+ const formFields = React3__namespace.useMemo(() => {
500
+ if (formEngineSetup?.fields && formEngineSetup.fields.length > 0) {
501
+ return formEngineSetup.fields;
502
+ }
503
+ return DEFAULT_FORM_FIELDS;
504
+ }, [formEngineSetup?.fields]);
505
+ const contactOverlaysContent = React3__namespace.useMemo(() => {
506
+ if (contactOverlaysSlot) return contactOverlaysSlot;
507
+ if (!contactOverlays || contactOverlays.length === 0) return null;
508
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex flex-col gap-3", contactOverlaysClassName), children: contactOverlays.map((item, index) => {
509
+ const content = /* @__PURE__ */ jsxRuntime.jsxs(
510
+ "div",
511
+ {
512
+ className: cn(
513
+ "rounded-2xl border border-white/10 bg-foreground/80 p-4 backdrop-blur-sm",
514
+ item.className
515
+ ),
516
+ children: [
517
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
518
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex size-fit p-2 items-center justify-center rounded-full bg-primary text-primary-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: item.icon, size: 18 }) }),
519
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
520
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-bold uppercase tracking-[0.15em] text-background/70", children: item.label }),
521
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-semibold text-background", children: item.title })
522
+ ] })
523
+ ] }),
524
+ item.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-sm text-background/80", children: item.description })
525
+ ]
526
+ }
527
+ );
528
+ if (item.href) {
959
529
  return /* @__PURE__ */ jsxRuntime.jsx(
960
- Pressable,
530
+ "a",
961
531
  {
962
- asButton: true,
963
- className: actionClassName,
964
- ...pressableProps,
965
- children: children ?? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
966
- icon,
967
- label,
968
- iconAfter
969
- ] })
532
+ href: item.href,
533
+ className: "block transition-transform hover:scale-[1.02]",
534
+ children: content
970
535
  },
971
536
  index
972
537
  );
973
- });
974
- }
975
- return null;
976
- }, [actionsSlot, actions]);
977
- const renderBackground = React.useMemo(() => {
978
- if (!backgroundImage) return null;
979
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute inset-0", children: [
980
- /* @__PURE__ */ jsxRuntime.jsx(
981
- img.Img,
982
- {
983
- src: backgroundImage,
984
- alt: "Full screen background image",
985
- className: "h-full w-full object-cover",
986
- loading: "eager",
987
- optixFlowConfig
988
- }
989
- ),
990
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-linear-to-b from-black/80 via-black/65 to-black/20" })
991
- ] });
992
- }, [backgroundImage, optixFlowConfig]);
993
- return /* @__PURE__ */ jsxRuntime.jsxs(
538
+ }
539
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { children: content }, index);
540
+ }) });
541
+ }, [contactOverlaysSlot, contactOverlays, contactOverlaysClassName]);
542
+ return /* @__PURE__ */ jsxRuntime.jsx(
994
543
  Section,
995
544
  {
996
545
  background,
997
546
  spacing,
547
+ className,
548
+ containerClassName,
998
549
  pattern,
999
550
  patternOpacity,
1000
- className: cn(
1001
- "relative flex h-full min-h-screen w-screen items-center justify-center overflow-hidden bg-black pb-0 pt-0 md:pt-0 px-0",
1002
- className
1003
- ),
1004
- containerClassName,
1005
- children: [
1006
- renderBackground,
1007
- /* @__PURE__ */ jsxRuntime.jsx(
1008
- "div",
1009
- {
1010
- className: cn(
1011
- "flex flex-col gap-4 md:gap-6 px-6 pt-28 pb-6 md:pt-0 md:pb-0",
1012
- "relative z-30 m-auto max-w-full md:max-w-md flex-col items-center justify-center text-center",
1013
- contentClassName
1014
- ),
1015
- children: /* @__PURE__ */ jsxRuntime.jsx(Card, { className: cn("mx-auto max-w-xl", cardClassName), children: /* @__PURE__ */ jsxRuntime.jsxs(CardContent, { className: cn("p-6 lg:p-8", cardContentClassName), children: [
1016
- heading && (typeof heading === "string" ? /* @__PURE__ */ jsxRuntime.jsx(
1017
- "h2",
1018
- {
1019
- className: cn(
1020
- "text-5xl md:text-6xl lg:text-7xl text-card-foreground text-shadow-2xl font-semibold",
1021
- headingClassName
1022
- ),
1023
- children: heading
1024
- }
1025
- ) : heading),
1026
- description && (typeof description === "string" ? /* @__PURE__ */ jsxRuntime.jsx(
1027
- "p",
1028
- {
1029
- className: cn(
1030
- "text-center text-base text-balance text-card-foreground text-shadow-2xl",
1031
- descriptionClassName
551
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
552
+ "div",
553
+ {
554
+ className: cn(
555
+ "grid grid-cols-1 items-center gap-12 lg:grid-cols-2",
556
+ contentClassName
557
+ ),
558
+ children: [
559
+ image && /* @__PURE__ */ jsxRuntime.jsx(
560
+ framerMotion.motion.div,
561
+ {
562
+ initial: { opacity: 0, x: -20 },
563
+ whileInView: { opacity: 1, x: 0 },
564
+ viewport: { once: true, margin: "-50px" },
565
+ transition: { duration: 0.5 },
566
+ className: "order-2 lg:order-1",
567
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative overflow-hidden rounded-3xl border border-white/10 shadow-2xl", children: [
568
+ /* @__PURE__ */ jsxRuntime.jsx(
569
+ img.Img,
570
+ {
571
+ src: image.src,
572
+ alt: image.alt,
573
+ className: cn("h-full w-full object-cover", imageClassName),
574
+ optixFlowConfig
575
+ }
1032
576
  ),
1033
- children: description
1034
- }
1035
- ) : description),
1036
- /* @__PURE__ */ jsxRuntime.jsxs(
1037
- forms.Form,
1038
- {
1039
- form,
1040
- notificationConfig: {
1041
- submissionError,
1042
- successMessage
1043
- },
1044
- styleConfig: {
1045
- formClassName: cn("space-y-4", formClassName),
1046
- successMessageClassName,
1047
- errorMessageClassName
1048
- },
1049
- formConfig: {
1050
- endpoint: formConfig?.endpoint,
1051
- method: formMethod,
1052
- submissionConfig: formConfig?.submissionConfig
1053
- },
1054
- onNewSubmission: () => {
1055
- resetUpload();
1056
- resetSubmissionState();
1057
- },
1058
- children: [
1059
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-12 gap-6", children: formFields.map((field) => /* @__PURE__ */ jsxRuntime.jsx(
1060
- "div",
1061
- {
1062
- className: integration.getColumnSpanClass(field.columnSpan),
1063
- children: /* @__PURE__ */ jsxRuntime.jsx(
1064
- integration.DynamicFormField,
1065
- {
1066
- field,
1067
- uploadProgress,
1068
- onFileUpload: uploadFiles,
1069
- onFileRemove: removeFile,
1070
- isUploading
1071
- }
1072
- )
577
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-linear-to-tr from-black/70 via-transparent to-transparent" }),
578
+ contactOverlaysContent && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-6 left-6 right-6", children: contactOverlaysContent })
579
+ ] })
580
+ }
581
+ ),
582
+ /* @__PURE__ */ jsxRuntime.jsxs(
583
+ framerMotion.motion.div,
584
+ {
585
+ initial: { opacity: 0, x: 20 },
586
+ whileInView: { opacity: 1, x: 0 },
587
+ viewport: { once: true, margin: "-50px" },
588
+ transition: { duration: 0.5 },
589
+ className: "order-1 lg:order-2",
590
+ children: [
591
+ eyebrow && (typeof eyebrow === "string" ? /* @__PURE__ */ jsxRuntime.jsx(
592
+ "p",
593
+ {
594
+ className: cn(
595
+ "text-sm font-semibold uppercase tracking-[0.2em] text-muted-foreground",
596
+ eyebrowClassName
597
+ ),
598
+ children: eyebrow
599
+ }
600
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: eyebrowClassName, children: eyebrow })),
601
+ heading && (typeof heading === "string" ? /* @__PURE__ */ jsxRuntime.jsx(
602
+ "h2",
603
+ {
604
+ className: cn(
605
+ "mt-2 text-3xl font-bold md:text-4xl lg:text-5xl",
606
+ headingClassName
607
+ ),
608
+ children: heading
609
+ }
610
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("mt-2", headingClassName), children: heading })),
611
+ description && (typeof description === "string" ? /* @__PURE__ */ jsxRuntime.jsx(
612
+ "p",
613
+ {
614
+ className: cn(
615
+ "mt-4 text-lg text-muted-foreground",
616
+ descriptionClassName
617
+ ),
618
+ children: description
619
+ }
620
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("mt-4", descriptionClassName), children: description })),
621
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-8", children: formEngineSetup ? /* @__PURE__ */ jsxRuntime.jsx(
622
+ integration.FormEngine,
623
+ {
624
+ ...formEngineSetup,
625
+ formLayoutSettings: {
626
+ ...formEngineSetup.formLayoutSettings,
627
+ formLayout: "standard",
628
+ submitButtonSetup: {
629
+ ...formEngineSetup.formLayoutSettings?.submitButtonSetup,
630
+ submitLabel: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
631
+ buttonIcon,
632
+ buttonText
633
+ ] })
634
+ },
635
+ styleRules: formStyleRules
1073
636
  },
1074
- field.name
1075
- )) }),
1076
- actionsSlot || actions && actions.length > 0 ? actionsContent : /* @__PURE__ */ jsxRuntime.jsxs(
1077
- Pressable,
1078
- {
1079
- componentType: "button",
1080
- type: "submit",
1081
- className: cn("w-full", submitClassName),
1082
- size: "lg",
1083
- asButton: true,
1084
- disabled: form.isSubmitting,
1085
- children: [
1086
- buttonIcon,
1087
- buttonText
1088
- ]
1089
- }
1090
- )
1091
- ]
1092
- }
1093
- )
1094
- ] }) })
1095
- }
1096
- )
1097
- ]
637
+ fields: formFields
638
+ }
639
+ ) : null })
640
+ ]
641
+ }
642
+ )
643
+ ]
644
+ }
645
+ )
1098
646
  }
1099
647
  );
1100
648
  }