@opensite/ui 2.1.2 → 2.1.3

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,8 +1,8 @@
1
1
  import * as React from 'react';
2
2
  import { FormFieldConfig, PageSpeedFormConfig } from '@page-speed/forms/integration';
3
3
  import { f as SectionBackground, g as SectionSpacing, t as PatternName } from './community-initiatives-DmVsuoHE.js';
4
- import { A as ActionConfig } from './blocks-XLPGq8A5.js';
5
4
  import 'react/jsx-runtime';
5
+ import './blocks-XLPGq8A5.js';
6
6
  import 'class-variance-authority';
7
7
  import './button-variants-CdNtNOuP.js';
8
8
  import 'class-variance-authority/types';
@@ -33,14 +33,6 @@ interface ContactFaqProps {
33
33
  * Icon to display in submit button
34
34
  */
35
35
  buttonIcon?: React.ReactNode;
36
- /**
37
- * Array of action configurations for custom buttons
38
- */
39
- actions?: ActionConfig[];
40
- /**
41
- * Custom slot for rendering actions (overrides actions array)
42
- */
43
- actionsSlot?: React.ReactNode;
44
36
  /**
45
37
  * Array of FAQ items to display alongside the contact form
46
38
  */
@@ -175,6 +167,6 @@ interface ContactFaqProps {
175
167
  /**
176
168
  * ContactFaq - FAQ contact form with flexible field configuration
177
169
  */
178
- declare function ContactFaq({ heading, description, formHeading, buttonText, buttonIcon, actions, actionsSlot, items, itemsSlot, faqHeading, formFields, successMessage, className, containerClassName, headerClassName, headingClassName, descriptionClassName, cardClassName, cardContentClassName, formHeadingClassName, formClassName, submitClassName, faqHeadingClassName, faqContainerClassName, accordionClassName, accordionItemClassName, accordionTriggerClassName, accordionContentClassName, gridClassName, successMessageClassName, errorMessageClassName, background, spacing, pattern, patternOpacity, formConfig, onSubmit, onSuccess, onError, }: ContactFaqProps): React.JSX.Element;
170
+ declare function ContactFaq({ heading, description, formHeading, buttonText, buttonIcon, items, itemsSlot, faqHeading, formFields, successMessage, className, containerClassName, headerClassName, headingClassName, descriptionClassName, cardClassName, cardContentClassName, formHeadingClassName, formClassName, faqHeadingClassName, faqContainerClassName, accordionClassName, accordionItemClassName, accordionTriggerClassName, accordionContentClassName, gridClassName, successMessageClassName, errorMessageClassName, background, spacing, pattern, patternOpacity, formConfig, onSubmit, onSuccess, onError, }: ContactFaqProps): React.JSX.Element;
179
171
 
180
172
  export { ContactFaq, type ContactFaqProps, type FaqItem };
@@ -1,11 +1,8 @@
1
1
  "use client";
2
- import * as React from 'react';
3
- import React__default, { useMemo } from 'react';
4
- import { Form } from '@page-speed/forms';
5
- import { useFileUpload, useContactForm, getColumnSpanClass, DynamicFormField } from '@page-speed/forms/integration';
2
+ import React, { useMemo } from 'react';
3
+ import { useFileUpload, FormEngine } from '@page-speed/forms/integration';
6
4
  import { clsx } from 'clsx';
7
5
  import { twMerge } from 'tailwind-merge';
8
- import { cva } from 'class-variance-authority';
9
6
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
10
7
  import * as AccordionPrimitive from '@radix-ui/react-accordion';
11
8
  import { Icon } from '@page-speed/icon';
@@ -14,424 +11,6 @@ import { Icon } from '@page-speed/icon';
14
11
  function cn(...inputs) {
15
12
  return twMerge(clsx(inputs));
16
13
  }
17
- function normalizePhoneNumber(input) {
18
- const trimmed = input.trim();
19
- if (trimmed.toLowerCase().startsWith("tel:")) {
20
- return trimmed;
21
- }
22
- const match = trimmed.match(/^[\s\+\-\(\)]*(\d[\d\s\-\(\)\.]*\d)[\s\-]*(x|ext\.?|extension)?[\s\-]*(\d+)?$/i);
23
- if (match) {
24
- const mainNumber = match[1].replace(/[\s\-\(\)\.]/g, "");
25
- const extension = match[3];
26
- const normalized = mainNumber.length >= 10 && !trimmed.startsWith("+") ? `+${mainNumber}` : mainNumber;
27
- const withExtension = extension ? `${normalized};ext=${extension}` : normalized;
28
- return `tel:${withExtension}`;
29
- }
30
- const cleaned = trimmed.replace(/[\s\-\(\)\.]/g, "");
31
- return `tel:${cleaned}`;
32
- }
33
- function normalizeEmail(input) {
34
- const trimmed = input.trim();
35
- if (trimmed.toLowerCase().startsWith("mailto:")) {
36
- return trimmed;
37
- }
38
- return `mailto:${trimmed}`;
39
- }
40
- function isEmail(input) {
41
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
42
- return emailRegex.test(input.trim());
43
- }
44
- function isPhoneNumber(input) {
45
- const trimmed = input.trim();
46
- if (trimmed.toLowerCase().startsWith("tel:")) {
47
- return true;
48
- }
49
- const phoneRegex = /^[\s\+\-\(\)]*\d[\d\s\-\(\)\.]*\d[\s\-]*(x|ext\.?|extension)?[\s\-]*\d*$/i;
50
- return phoneRegex.test(trimmed);
51
- }
52
- function isInternalUrl(href) {
53
- if (typeof window === "undefined") {
54
- return href.startsWith("/") && !href.startsWith("//");
55
- }
56
- const trimmed = href.trim();
57
- if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
58
- return true;
59
- }
60
- try {
61
- const url = new URL(trimmed, window.location.href);
62
- const currentOrigin = window.location.origin;
63
- const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
64
- return normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin);
65
- } catch {
66
- return false;
67
- }
68
- }
69
- function toRelativePath(href) {
70
- if (typeof window === "undefined") {
71
- return href;
72
- }
73
- const trimmed = href.trim();
74
- if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
75
- return trimmed;
76
- }
77
- try {
78
- const url = new URL(trimmed, window.location.href);
79
- const currentOrigin = window.location.origin;
80
- const normalizeOrigin = (origin) => origin.replace(/^(https?:\/\/)(www\.)?/, "$1");
81
- if (normalizeOrigin(url.origin) === normalizeOrigin(currentOrigin)) {
82
- return url.pathname + url.search + url.hash;
83
- }
84
- } catch {
85
- }
86
- return trimmed;
87
- }
88
- function useNavigation({
89
- href,
90
- onClick
91
- } = {}) {
92
- const linkType = React.useMemo(() => {
93
- if (!href || href.trim() === "") {
94
- return onClick ? "none" : "none";
95
- }
96
- const trimmed = href.trim();
97
- if (trimmed.toLowerCase().startsWith("mailto:") || isEmail(trimmed)) {
98
- return "mailto";
99
- }
100
- if (trimmed.toLowerCase().startsWith("tel:") || isPhoneNumber(trimmed)) {
101
- return "tel";
102
- }
103
- if (isInternalUrl(trimmed)) {
104
- return "internal";
105
- }
106
- try {
107
- new URL(trimmed, typeof window !== "undefined" ? window.location.href : "http://localhost");
108
- return "external";
109
- } catch {
110
- return "internal";
111
- }
112
- }, [href, onClick]);
113
- const normalizedHref = React.useMemo(() => {
114
- if (!href || href.trim() === "") {
115
- return void 0;
116
- }
117
- const trimmed = href.trim();
118
- switch (linkType) {
119
- case "tel":
120
- return normalizePhoneNumber(trimmed);
121
- case "mailto":
122
- return normalizeEmail(trimmed);
123
- case "internal":
124
- return toRelativePath(trimmed);
125
- case "external":
126
- return trimmed;
127
- default:
128
- return trimmed;
129
- }
130
- }, [href, linkType]);
131
- const target = React.useMemo(() => {
132
- switch (linkType) {
133
- case "external":
134
- return "_blank";
135
- case "internal":
136
- return "_self";
137
- case "mailto":
138
- case "tel":
139
- return void 0;
140
- default:
141
- return void 0;
142
- }
143
- }, [linkType]);
144
- const rel = React.useMemo(() => {
145
- if (linkType === "external") {
146
- return "noopener noreferrer";
147
- }
148
- return void 0;
149
- }, [linkType]);
150
- const isExternal = linkType === "external";
151
- const isInternal = linkType === "internal";
152
- const shouldUseRouter = isInternal && typeof normalizedHref === "string" && normalizedHref.startsWith("/");
153
- const handleClick = React.useCallback(
154
- (event) => {
155
- if (onClick) {
156
- try {
157
- onClick(event);
158
- } catch (error) {
159
- console.error("Error in user onClick handler:", error);
160
- }
161
- }
162
- if (event.defaultPrevented) {
163
- return;
164
- }
165
- if (shouldUseRouter && normalizedHref && event.button === 0 && // left-click only
166
- !event.metaKey && !event.altKey && !event.ctrlKey && !event.shiftKey) {
167
- if (typeof window !== "undefined") {
168
- const handler = window.__opensiteNavigationHandler;
169
- if (typeof handler === "function") {
170
- try {
171
- const handled = handler(normalizedHref, event.nativeEvent || event);
172
- if (handled !== false) {
173
- event.preventDefault();
174
- }
175
- } catch (error) {
176
- console.error("Error in navigation handler:", error);
177
- }
178
- }
179
- }
180
- }
181
- },
182
- [onClick, shouldUseRouter, normalizedHref]
183
- );
184
- return {
185
- linkType,
186
- normalizedHref,
187
- target,
188
- rel,
189
- isExternal,
190
- isInternal,
191
- shouldUseRouter,
192
- handleClick
193
- };
194
- }
195
- var baseStyles = [
196
- // Layout
197
- "inline-flex items-center justify-center gap-2 whitespace-nowrap shrink-0",
198
- // Typography - using CSS variables with sensible defaults
199
- "font-[var(--button-font-family,inherit)]",
200
- "font-[var(--button-font-weight,500)]",
201
- "tracking-[var(--button-letter-spacing,0)]",
202
- "leading-[var(--button-line-height,1.25)]",
203
- "[text-transform:var(--button-text-transform,none)]",
204
- "text-sm",
205
- // Border radius
206
- "rounded-[var(--button-radius,var(--radius,0.375rem))]",
207
- // Smooth transition - using [transition:...] to set full shorthand property (not just transition-property)
208
- "[transition:var(--button-transition,all_250ms_cubic-bezier(0.4,0,0.2,1))]",
209
- // Box shadow (master level) - using [box-shadow:...] for complex multi-value shadows
210
- "[box-shadow:var(--button-shadow,none)]",
211
- "hover:[box-shadow:var(--button-shadow-hover,var(--button-shadow,none))]",
212
- // Disabled state
213
- "disabled:pointer-events-none disabled:opacity-50",
214
- // SVG handling
215
- "[&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0",
216
- // Focus styles
217
- "outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
218
- // Invalid state
219
- "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive"
220
- ].join(" ");
221
- var buttonVariants = cva(baseStyles, {
222
- variants: {
223
- variant: {
224
- // Default (Primary) variant - full customization
225
- default: [
226
- "bg-[var(--button-default-bg,hsl(var(--primary)))]",
227
- "text-[var(--button-default-fg,hsl(var(--primary-foreground)))]",
228
- "border-[length:var(--button-default-border-width,0px)]",
229
- "border-[color:var(--button-default-border,transparent)]",
230
- "[box-shadow:var(--button-default-shadow,var(--button-shadow,none))]",
231
- "hover:bg-[var(--button-default-hover-bg,hsl(var(--primary)/0.9))]",
232
- "hover:text-[var(--button-default-hover-fg,var(--button-default-fg,hsl(var(--primary-foreground))))]",
233
- "hover:border-[color:var(--button-default-hover-border,var(--button-default-border,transparent))]",
234
- "hover:[box-shadow:var(--button-default-shadow-hover,var(--button-shadow-hover,var(--button-default-shadow,var(--button-shadow,none))))]"
235
- ].join(" "),
236
- // Destructive variant - full customization
237
- destructive: [
238
- "bg-[var(--button-destructive-bg,hsl(var(--destructive)))]",
239
- "text-[var(--button-destructive-fg,white)]",
240
- "border-[length:var(--button-destructive-border-width,0px)]",
241
- "border-[color:var(--button-destructive-border,transparent)]",
242
- "[box-shadow:var(--button-destructive-shadow,var(--button-shadow,none))]",
243
- "hover:bg-[var(--button-destructive-hover-bg,hsl(var(--destructive)/0.9))]",
244
- "hover:text-[var(--button-destructive-hover-fg,var(--button-destructive-fg,white))]",
245
- "hover:border-[color:var(--button-destructive-hover-border,var(--button-destructive-border,transparent))]",
246
- "hover:[box-shadow:var(--button-destructive-shadow-hover,var(--button-shadow-hover,var(--button-destructive-shadow,var(--button-shadow,none))))]",
247
- "focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40",
248
- "dark:bg-destructive/60"
249
- ].join(" "),
250
- // Outline variant - full customization with proper border handling
251
- outline: [
252
- "bg-[var(--button-outline-bg,hsl(var(--background)))]",
253
- "text-[var(--button-outline-fg,inherit)]",
254
- "border-[length:var(--button-outline-border-width,1px)]",
255
- "border-[color:var(--button-outline-border,hsl(var(--border)))]",
256
- "[box-shadow:var(--button-outline-shadow,var(--button-shadow,0_1px_2px_0_rgb(0_0_0/0.05)))]",
257
- "hover:bg-[var(--button-outline-hover-bg,hsl(var(--accent)))]",
258
- "hover:text-[var(--button-outline-hover-fg,hsl(var(--accent-foreground)))]",
259
- "hover:border-[color:var(--button-outline-hover-border,var(--button-outline-border,hsl(var(--border))))]",
260
- "hover:[box-shadow:var(--button-outline-shadow-hover,var(--button-shadow-hover,var(--button-outline-shadow,var(--button-shadow,none))))]",
261
- "dark:bg-input/30 dark:border-input dark:hover:bg-input/50"
262
- ].join(" "),
263
- // Secondary variant - full customization
264
- secondary: [
265
- "bg-[var(--button-secondary-bg,hsl(var(--secondary)))]",
266
- "text-[var(--button-secondary-fg,hsl(var(--secondary-foreground)))]",
267
- "border-[length:var(--button-secondary-border-width,0px)]",
268
- "border-[color:var(--button-secondary-border,transparent)]",
269
- "[box-shadow:var(--button-secondary-shadow,var(--button-shadow,none))]",
270
- "hover:bg-[var(--button-secondary-hover-bg,hsl(var(--secondary)/0.8))]",
271
- "hover:text-[var(--button-secondary-hover-fg,var(--button-secondary-fg,hsl(var(--secondary-foreground))))]",
272
- "hover:border-[color:var(--button-secondary-hover-border,var(--button-secondary-border,transparent))]",
273
- "hover:[box-shadow:var(--button-secondary-shadow-hover,var(--button-shadow-hover,var(--button-secondary-shadow,var(--button-shadow,none))))]"
274
- ].join(" "),
275
- // Ghost variant - full customization
276
- ghost: [
277
- "bg-[var(--button-ghost-bg,transparent)]",
278
- "text-[var(--button-ghost-fg,inherit)]",
279
- "border-[length:var(--button-ghost-border-width,0px)]",
280
- "border-[color:var(--button-ghost-border,transparent)]",
281
- "[box-shadow:var(--button-ghost-shadow,var(--button-shadow,none))]",
282
- "hover:bg-[var(--button-ghost-hover-bg,hsl(var(--accent)))]",
283
- "hover:text-[var(--button-ghost-hover-fg,hsl(var(--accent-foreground)))]",
284
- "hover:border-[color:var(--button-ghost-hover-border,var(--button-ghost-border,transparent))]",
285
- "hover:[box-shadow:var(--button-ghost-shadow-hover,var(--button-shadow-hover,var(--button-ghost-shadow,var(--button-shadow,none))))]",
286
- "dark:hover:bg-accent/50"
287
- ].join(" "),
288
- // Link variant - full customization
289
- link: [
290
- "bg-[var(--button-link-bg,transparent)]",
291
- "text-[var(--button-link-fg,hsl(var(--primary)))]",
292
- "border-[length:var(--button-link-border-width,0px)]",
293
- "border-[color:var(--button-link-border,transparent)]",
294
- "[box-shadow:var(--button-link-shadow,none)]",
295
- "hover:bg-[var(--button-link-hover-bg,transparent)]",
296
- "hover:text-[var(--button-link-hover-fg,var(--button-link-fg,hsl(var(--primary))))]",
297
- "hover:[box-shadow:var(--button-link-shadow-hover,none)]",
298
- "underline-offset-4 hover:underline"
299
- ].join(" ")
300
- },
301
- size: {
302
- default: [
303
- "h-[var(--button-height-md,2.25rem)]",
304
- "px-[var(--button-padding-x-md,1rem)]",
305
- "py-[var(--button-padding-y-md,0.5rem)]",
306
- "has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
307
- ].join(" "),
308
- sm: [
309
- "h-[var(--button-height-sm,2rem)]",
310
- "px-[var(--button-padding-x-sm,0.75rem)]",
311
- "py-[var(--button-padding-y-sm,0.25rem)]",
312
- "gap-1.5",
313
- "has-[>svg]:px-[calc(var(--button-padding-x-sm,0.75rem)*0.83)]"
314
- ].join(" "),
315
- md: [
316
- "h-[var(--button-height-md,2.25rem)]",
317
- "px-[var(--button-padding-x-md,1rem)]",
318
- "py-[var(--button-padding-y-md,0.5rem)]",
319
- "has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]"
320
- ].join(" "),
321
- lg: [
322
- "h-[var(--button-height-lg,2.5rem)]",
323
- "px-[var(--button-padding-x-lg,1.5rem)]",
324
- "py-[var(--button-padding-y-lg,0.5rem)]",
325
- "has-[>svg]:px-[calc(var(--button-padding-x-lg,1.5rem)*0.67)]"
326
- ].join(" "),
327
- icon: "size-[var(--button-height-md,2.25rem)]",
328
- "icon-sm": "size-[var(--button-height-sm,2rem)]",
329
- "icon-lg": "size-[var(--button-height-lg,2.5rem)]"
330
- }
331
- },
332
- defaultVariants: {
333
- variant: "default",
334
- size: "default"
335
- }
336
- });
337
- var Pressable = React.forwardRef(
338
- ({
339
- children,
340
- className,
341
- href,
342
- onClick,
343
- variant,
344
- size,
345
- asButton = false,
346
- fallbackComponentType = "span",
347
- componentType,
348
- "aria-label": ariaLabel,
349
- "aria-describedby": ariaDescribedby,
350
- id,
351
- ...props
352
- }, ref) => {
353
- const navigation = useNavigation({ href, onClick });
354
- const {
355
- normalizedHref,
356
- target,
357
- rel,
358
- linkType,
359
- isInternal,
360
- handleClick
361
- } = navigation;
362
- const shouldRenderLink = normalizedHref && linkType !== "none";
363
- const shouldRenderButton = !shouldRenderLink && onClick;
364
- const effectiveComponentType = componentType || (shouldRenderLink ? "a" : shouldRenderButton ? "button" : fallbackComponentType);
365
- const finalComponentType = isInternal && shouldRenderLink ? "a" : effectiveComponentType;
366
- const shouldApplyButtonStyles = asButton || variant || size;
367
- const combinedClassName = cn(
368
- shouldApplyButtonStyles && buttonVariants({ variant, size }),
369
- className
370
- );
371
- const dataProps = Object.fromEntries(
372
- Object.entries(props).filter(([key]) => key.startsWith("data-"))
373
- );
374
- const buttonDataAttributes = shouldApplyButtonStyles ? {
375
- "data-slot": "button",
376
- "data-variant": variant ?? "default",
377
- "data-size": size ?? "default"
378
- } : {};
379
- const commonProps = {
380
- className: combinedClassName,
381
- onClick: handleClick,
382
- "aria-label": ariaLabel,
383
- "aria-describedby": ariaDescribedby,
384
- id,
385
- ...dataProps,
386
- ...buttonDataAttributes
387
- };
388
- if (finalComponentType === "a" && shouldRenderLink) {
389
- return /* @__PURE__ */ jsx(
390
- "a",
391
- {
392
- ref,
393
- href: normalizedHref,
394
- target,
395
- rel,
396
- ...commonProps,
397
- ...props,
398
- children
399
- }
400
- );
401
- }
402
- if (finalComponentType === "button") {
403
- return /* @__PURE__ */ jsx(
404
- "button",
405
- {
406
- ref,
407
- type: props.type || "button",
408
- ...commonProps,
409
- ...props,
410
- children
411
- }
412
- );
413
- }
414
- if (finalComponentType === "div") {
415
- return /* @__PURE__ */ jsx(
416
- "div",
417
- {
418
- ref,
419
- ...commonProps,
420
- children
421
- }
422
- );
423
- }
424
- return /* @__PURE__ */ jsx(
425
- "span",
426
- {
427
- ref,
428
- ...commonProps,
429
- children
430
- }
431
- );
432
- }
433
- );
434
- Pressable.displayName = "Pressable";
435
14
  function Card({ className, ...props }) {
436
15
  return /* @__PURE__ */ jsx(
437
16
  "div",
@@ -528,7 +107,7 @@ var maxWidthStyles = {
528
107
  "4xl": "max-w-[1536px]",
529
108
  full: "max-w-full"
530
109
  };
531
- var Container = React__default.forwardRef(
110
+ var Container = React.forwardRef(
532
111
  ({ children, maxWidth = "xl", className, as = "div", ...props }, ref) => {
533
112
  const Component = as;
534
113
  return /* @__PURE__ */ jsx(
@@ -833,7 +412,7 @@ var spacingStyles = {
833
412
  };
834
413
  var predefinedSpacings = ["none", "sm", "md", "lg", "xl"];
835
414
  var isPredefinedSpacing = (spacing) => predefinedSpacings.includes(spacing);
836
- var Section = React__default.forwardRef(
415
+ var Section = React.forwardRef(
837
416
  ({
838
417
  id,
839
418
  title,
@@ -935,8 +514,6 @@ function ContactFaq({
935
514
  formHeading,
936
515
  buttonText = "Submit",
937
516
  buttonIcon,
938
- actions,
939
- actionsSlot,
940
517
  items,
941
518
  itemsSlot,
942
519
  faqHeading,
@@ -951,7 +528,6 @@ function ContactFaq({
951
528
  cardContentClassName,
952
529
  formHeadingClassName,
953
530
  formClassName,
954
- submitClassName,
955
531
  faqHeadingClassName,
956
532
  faqContainerClassName,
957
533
  accordionClassName,
@@ -978,48 +554,6 @@ function ContactFaq({
978
554
  removeFile,
979
555
  resetUpload
980
556
  } = useFileUpload({ onError });
981
- const { form, submissionError, formMethod, resetSubmissionState } = useContactForm({
982
- formFields,
983
- formConfig,
984
- onSubmit,
985
- onSuccess: (data) => {
986
- resetUpload();
987
- onSuccess?.(data);
988
- },
989
- onError,
990
- resetOnSuccess: formConfig?.resetOnSuccess !== false,
991
- uploadTokens
992
- });
993
- const actionsContent = useMemo(() => {
994
- if (actionsSlot) return actionsSlot;
995
- if (actions && actions.length > 0) {
996
- return actions.map((action, index) => {
997
- const {
998
- label,
999
- icon,
1000
- iconAfter,
1001
- children,
1002
- className: actionClassName,
1003
- ...pressableProps
1004
- } = action;
1005
- return /* @__PURE__ */ jsx(
1006
- Pressable,
1007
- {
1008
- asButton: true,
1009
- className: actionClassName,
1010
- ...pressableProps,
1011
- children: children ?? /* @__PURE__ */ jsxs(Fragment, { children: [
1012
- icon,
1013
- label,
1014
- iconAfter
1015
- ] })
1016
- },
1017
- index
1018
- );
1019
- });
1020
- }
1021
- return null;
1022
- }, [actionsSlot, actions]);
1023
557
  const hasFaqItems = itemsSlot || items && items.length > 0;
1024
558
  const faqContent = useMemo(() => {
1025
559
  if (itemsSlot) return itemsSlot;
@@ -1080,7 +614,7 @@ function ContactFaq({
1080
614
  ),
1081
615
  children: heading
1082
616
  }
1083
- ) : /* @__PURE__ */ jsx("div", { className: headingClassName, children: heading })),
617
+ ) : heading),
1084
618
  description && (typeof description === "string" ? /* @__PURE__ */ jsx(
1085
619
  "p",
1086
620
  {
@@ -1090,7 +624,7 @@ function ContactFaq({
1090
624
  ),
1091
625
  children: description
1092
626
  }
1093
- ) : /* @__PURE__ */ jsx("div", { className: descriptionClassName, children: description }))
627
+ ) : description)
1094
628
  ]
1095
629
  }
1096
630
  ),
@@ -1114,62 +648,38 @@ function ContactFaq({
1114
648
  children: formHeading
1115
649
  }
1116
650
  ) : /* @__PURE__ */ jsx("div", { className: formHeadingClassName, children: formHeading })),
1117
- /* @__PURE__ */ jsxs(
1118
- Form,
651
+ /* @__PURE__ */ jsx(
652
+ FormEngine,
1119
653
  {
1120
- form,
1121
- notificationConfig: {
1122
- submissionError,
1123
- successMessage
1124
- },
1125
- styleConfig: {
1126
- formClassName: cn("space-y-6", formClassName),
1127
- successMessageClassName,
1128
- errorMessageClassName
1129
- },
1130
- formConfig: {
1131
- endpoint: formConfig?.endpoint,
1132
- method: formMethod,
1133
- submissionConfig: formConfig?.submissionConfig
654
+ api: formConfig,
655
+ fields: formFields,
656
+ formLayoutSettings: {
657
+ formLayout: "standard",
658
+ submitButtonSetup: {
659
+ submitLabel: /* @__PURE__ */ jsxs(Fragment, { children: [
660
+ buttonIcon,
661
+ buttonText
662
+ ] })
663
+ },
664
+ styleRules: {
665
+ formClassName: cn("space-y-6", formClassName),
666
+ successMessageClassName,
667
+ errorMessageClassName
668
+ }
1134
669
  },
1135
- onNewSubmission: () => {
670
+ successMessage,
671
+ onSubmit,
672
+ onSuccess: (data) => {
1136
673
  resetUpload();
1137
- resetSubmissionState();
674
+ onSuccess?.(data);
1138
675
  },
1139
- children: [
1140
- /* @__PURE__ */ jsx("div", { className: "grid grid-cols-12 gap-6", children: formFields.map((field) => /* @__PURE__ */ jsx(
1141
- "div",
1142
- {
1143
- className: getColumnSpanClass(field.columnSpan),
1144
- children: /* @__PURE__ */ jsx(
1145
- DynamicFormField,
1146
- {
1147
- field,
1148
- uploadProgress,
1149
- onFileUpload: uploadFiles,
1150
- onFileRemove: removeFile,
1151
- isUploading
1152
- }
1153
- )
1154
- },
1155
- field.name
1156
- )) }),
1157
- actionsSlot || actions && actions.length > 0 ? actionsContent : /* @__PURE__ */ jsxs(
1158
- Pressable,
1159
- {
1160
- componentType: "button",
1161
- type: "submit",
1162
- className: cn("w-full", submitClassName),
1163
- size: "lg",
1164
- asButton: true,
1165
- disabled: form.isSubmitting,
1166
- children: [
1167
- buttonIcon,
1168
- buttonText
1169
- ]
1170
- }
1171
- )
1172
- ]
676
+ onError,
677
+ resetOnSuccess: formConfig?.resetOnSuccess !== false,
678
+ uploadTokens,
679
+ uploadProgress,
680
+ onFileUpload: uploadFiles,
681
+ onFileRemove: removeFile,
682
+ isUploading
1173
683
  }
1174
684
  )
1175
685
  ] }) }),