@opensite/ui 1.9.8 → 2.0.0

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 (131) hide show
  1. package/dist/contact-demo.cjs +106 -406
  2. package/dist/contact-demo.d.cts +36 -111
  3. package/dist/contact-demo.d.ts +36 -111
  4. package/dist/contact-demo.js +108 -405
  5. package/dist/contact-emergency.cjs +129 -158
  6. package/dist/contact-emergency.d.cts +23 -12
  7. package/dist/contact-emergency.d.ts +23 -12
  8. package/dist/contact-emergency.js +131 -159
  9. package/dist/contact-event.cjs +106 -147
  10. package/dist/contact-event.d.cts +36 -66
  11. package/dist/contact-event.d.ts +36 -66
  12. package/dist/contact-event.js +108 -148
  13. package/dist/contact-feedback.cjs +109 -102
  14. package/dist/contact-feedback.d.cts +36 -63
  15. package/dist/contact-feedback.d.ts +36 -63
  16. package/dist/contact-feedback.js +111 -103
  17. package/dist/contact-fitness.cjs +107 -148
  18. package/dist/contact-fitness.d.cts +36 -66
  19. package/dist/contact-fitness.d.ts +36 -66
  20. package/dist/contact-fitness.js +109 -149
  21. package/dist/contact-guest.cjs +107 -148
  22. package/dist/contact-guest.d.cts +35 -65
  23. package/dist/contact-guest.d.ts +35 -65
  24. package/dist/contact-guest.js +109 -149
  25. package/dist/contact-image.cjs +108 -149
  26. package/dist/contact-image.d.cts +35 -65
  27. package/dist/contact-image.d.ts +35 -65
  28. package/dist/contact-image.js +110 -150
  29. package/dist/contact-insurance.cjs +107 -148
  30. package/dist/contact-insurance.d.cts +36 -66
  31. package/dist/contact-insurance.d.ts +36 -66
  32. package/dist/contact-insurance.js +109 -149
  33. package/dist/contact-interview.cjs +106 -147
  34. package/dist/contact-interview.d.cts +20 -12
  35. package/dist/contact-interview.d.ts +20 -12
  36. package/dist/contact-interview.js +108 -148
  37. package/dist/contact-locations.cjs +106 -147
  38. package/dist/contact-locations.d.cts +21 -13
  39. package/dist/contact-locations.d.ts +21 -13
  40. package/dist/contact-locations.js +108 -148
  41. package/dist/contact-maintenance.cjs +103 -143
  42. package/dist/contact-maintenance.d.cts +21 -13
  43. package/dist/contact-maintenance.d.ts +21 -13
  44. package/dist/contact-maintenance.js +105 -144
  45. package/dist/contact-map.cjs +103 -143
  46. package/dist/contact-map.d.cts +20 -12
  47. package/dist/contact-map.d.ts +20 -12
  48. package/dist/contact-map.js +105 -144
  49. package/dist/contact-minimal.cjs +126 -242
  50. package/dist/contact-minimal.d.cts +36 -70
  51. package/dist/contact-minimal.d.ts +36 -70
  52. package/dist/contact-minimal.js +128 -243
  53. package/dist/contact-moving.cjs +103 -143
  54. package/dist/contact-moving.d.cts +20 -12
  55. package/dist/contact-moving.d.ts +20 -12
  56. package/dist/contact-moving.js +105 -144
  57. package/dist/contact-multistep.cjs +104 -144
  58. package/dist/contact-multistep.d.cts +21 -13
  59. package/dist/contact-multistep.d.ts +21 -13
  60. package/dist/contact-multistep.js +106 -145
  61. package/dist/contact-partnership.cjs +103 -143
  62. package/dist/contact-partnership.d.cts +19 -11
  63. package/dist/contact-partnership.d.ts +19 -11
  64. package/dist/contact-partnership.js +105 -144
  65. package/dist/contact-press.cjs +144 -150
  66. package/dist/contact-press.d.cts +21 -13
  67. package/dist/contact-press.d.ts +21 -13
  68. package/dist/contact-press.js +146 -151
  69. package/dist/contact-quote.cjs +144 -150
  70. package/dist/contact-quote.d.cts +19 -11
  71. package/dist/contact-quote.d.ts +19 -11
  72. package/dist/contact-quote.js +146 -151
  73. package/dist/contact-referral.cjs +144 -150
  74. package/dist/contact-referral.d.cts +20 -12
  75. package/dist/contact-referral.d.ts +20 -12
  76. package/dist/contact-referral.js +146 -151
  77. package/dist/contact-report.cjs +144 -150
  78. package/dist/contact-report.d.cts +21 -13
  79. package/dist/contact-report.d.ts +21 -13
  80. package/dist/contact-report.js +146 -151
  81. package/dist/contact-reservation.cjs +144 -150
  82. package/dist/contact-reservation.d.cts +20 -12
  83. package/dist/contact-reservation.d.ts +20 -12
  84. package/dist/contact-reservation.js +146 -151
  85. package/dist/contact-retreat.cjs +144 -150
  86. package/dist/contact-retreat.d.cts +21 -13
  87. package/dist/contact-retreat.d.ts +21 -13
  88. package/dist/contact-retreat.js +146 -151
  89. package/dist/contact-rsvp.cjs +144 -150
  90. package/dist/contact-rsvp.d.cts +20 -12
  91. package/dist/contact-rsvp.d.ts +20 -12
  92. package/dist/contact-rsvp.js +146 -151
  93. package/dist/contact-sales.cjs +131 -146
  94. package/dist/contact-sales.d.cts +34 -65
  95. package/dist/contact-sales.d.ts +34 -65
  96. package/dist/contact-sales.js +133 -147
  97. package/dist/contact-schedule.cjs +144 -150
  98. package/dist/contact-schedule.d.cts +20 -12
  99. package/dist/contact-schedule.d.ts +20 -12
  100. package/dist/contact-schedule.js +146 -151
  101. package/dist/contact-sponsorship.cjs +144 -150
  102. package/dist/contact-sponsorship.d.cts +21 -13
  103. package/dist/contact-sponsorship.d.ts +21 -13
  104. package/dist/contact-sponsorship.js +146 -151
  105. package/dist/contact-support.cjs +147 -120
  106. package/dist/contact-support.d.cts +21 -12
  107. package/dist/contact-support.d.ts +21 -12
  108. package/dist/contact-support.js +149 -121
  109. package/dist/contact-tenant.cjs +144 -150
  110. package/dist/contact-tenant.d.cts +20 -12
  111. package/dist/contact-tenant.d.ts +20 -12
  112. package/dist/contact-tenant.js +146 -151
  113. package/dist/contact-vendor.cjs +144 -150
  114. package/dist/contact-vendor.d.cts +20 -12
  115. package/dist/contact-vendor.d.ts +20 -12
  116. package/dist/contact-vendor.js +146 -151
  117. package/dist/contact-volunteer.cjs +144 -150
  118. package/dist/contact-volunteer.d.cts +20 -12
  119. package/dist/contact-volunteer.d.ts +20 -12
  120. package/dist/contact-volunteer.js +146 -151
  121. package/dist/contact-warranty.cjs +144 -150
  122. package/dist/contact-warranty.d.cts +20 -12
  123. package/dist/contact-warranty.d.ts +20 -12
  124. package/dist/contact-warranty.js +146 -151
  125. package/dist/contact-wedding.cjs +144 -150
  126. package/dist/contact-wedding.d.cts +20 -12
  127. package/dist/contact-wedding.d.ts +20 -12
  128. package/dist/contact-wedding.js +146 -151
  129. package/dist/registry.cjs +5791 -5883
  130. package/dist/registry.js +4527 -4619
  131. package/package.json +2 -2
@@ -1,20 +1,16 @@
1
1
  "use client";
2
2
  import * as React from 'react';
3
- import React__default from 'react';
4
- import { useForm, Form, Field } from '@page-speed/forms';
5
- import { TextInput as TextInput$1, TextArea as TextArea$1 } from '@page-speed/forms/inputs';
3
+ import React__default, { useMemo } from 'react';
4
+ import { Form, Field } from '@page-speed/forms';
5
+ import { useFileUpload, useContactForm, getColumnSpanClass, DynamicFormField } from '@page-speed/forms/integration';
6
6
  import { clsx } from 'clsx';
7
7
  import { twMerge } from 'tailwind-merge';
8
8
  import { cva } from 'class-variance-authority';
9
9
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
10
- import * as LabelPrimitive from '@radix-ui/react-label';
11
10
  import * as SeparatorPrimitive from '@radix-ui/react-separator';
12
11
  import { Slot } from '@radix-ui/react-slot';
13
- import { submitPageSpeedForm, PageSpeedFormSubmissionError } from '@page-speed/forms/integration';
14
12
 
15
13
  // components/blocks/contact/contact-emergency.tsx
16
- var TextInput = TextInput$1;
17
- var TextArea = TextArea$1;
18
14
  function cn(...inputs) {
19
15
  return twMerge(clsx(inputs));
20
16
  }
@@ -564,22 +560,6 @@ function CardContent({ className, ...props }) {
564
560
  }
565
561
  );
566
562
  }
567
- function Label({
568
- className,
569
- ...props
570
- }) {
571
- return /* @__PURE__ */ jsx(
572
- LabelPrimitive.Root,
573
- {
574
- "data-slot": "label",
575
- className: cn(
576
- "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",
577
- className
578
- ),
579
- ...props
580
- }
581
- );
582
- }
583
563
  function Separator({
584
564
  className,
585
565
  orientation = "horizontal",
@@ -1027,13 +1007,66 @@ var PRIORITIES = [
1027
1007
  response: "24 hours"
1028
1008
  }
1029
1009
  ];
1010
+ var DEFAULT_FORM_FIELDS = [
1011
+ {
1012
+ name: "priority",
1013
+ type: "radio",
1014
+ label: "Priority Level",
1015
+ required: true,
1016
+ columnSpan: 12,
1017
+ options: PRIORITIES.map((p) => ({ value: p.value, label: p.label }))
1018
+ },
1019
+ {
1020
+ name: "name",
1021
+ type: "text",
1022
+ label: "Name",
1023
+ placeholder: "Your name",
1024
+ required: true,
1025
+ columnSpan: 6
1026
+ },
1027
+ {
1028
+ name: "email",
1029
+ type: "email",
1030
+ label: "Email",
1031
+ placeholder: "you@company.com",
1032
+ required: true,
1033
+ columnSpan: 6
1034
+ },
1035
+ {
1036
+ name: "phone",
1037
+ type: "tel",
1038
+ label: "Phone (Optional)",
1039
+ placeholder: "+1 (555) 000-0000",
1040
+ required: false,
1041
+ columnSpan: 12
1042
+ },
1043
+ {
1044
+ name: "subject",
1045
+ type: "text",
1046
+ label: "Subject",
1047
+ placeholder: "Brief summary of the issue",
1048
+ required: true,
1049
+ columnSpan: 12
1050
+ },
1051
+ {
1052
+ name: "description",
1053
+ type: "textarea",
1054
+ label: "Description",
1055
+ placeholder: "Describe the issue, what you've tried, and the impact...",
1056
+ required: true,
1057
+ rows: 4,
1058
+ columnSpan: 12
1059
+ }
1060
+ ];
1030
1061
  function ContactEmergency({
1031
1062
  heading,
1032
1063
  description,
1033
- buttonText,
1064
+ buttonText = "Submit Emergency Request",
1034
1065
  buttonIcon,
1035
1066
  actions,
1036
1067
  actionsSlot,
1068
+ formFields = DEFAULT_FORM_FIELDS,
1069
+ successMessage = "Thank you! Your emergency request has been received.",
1037
1070
  className,
1038
1071
  headerClassName,
1039
1072
  headingClassName,
@@ -1042,6 +1075,8 @@ function ContactEmergency({
1042
1075
  cardContentClassName,
1043
1076
  formClassName,
1044
1077
  submitClassName,
1078
+ successMessageClassName,
1079
+ errorMessageClassName,
1045
1080
  spacing = "py-8 md:py-32",
1046
1081
  containerClassName = "px-6 sm:px-6 md:px-8 lg:px-8",
1047
1082
  background,
@@ -1052,60 +1087,32 @@ function ContactEmergency({
1052
1087
  onSuccess,
1053
1088
  onError
1054
1089
  }) {
1055
- const form = useForm({
1056
- initialValues: {
1057
- priority: "normal",
1058
- name: "",
1059
- email: "",
1060
- phone: "",
1061
- subject: "",
1062
- description: ""
1063
- },
1064
- validationSchema: {
1065
- priority: (value) => !value ? "Priority is required" : void 0,
1066
- name: (value) => !value ? "Name is required" : void 0,
1067
- email: (value) => {
1068
- if (!value) return "Email is required";
1069
- if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value))
1070
- return "Please enter a valid email address";
1071
- return void 0;
1072
- },
1073
- subject: (value) => !value ? "Subject is required" : void 0,
1074
- description: (value) => !value ? "Description is required" : void 0
1090
+ const {
1091
+ uploadTokens,
1092
+ uploadProgress,
1093
+ isUploading,
1094
+ uploadFiles,
1095
+ removeFile,
1096
+ resetUpload
1097
+ } = useFileUpload({ onError });
1098
+ const { form, submissionError, formMethod, resetSubmissionState } = useContactForm({
1099
+ formFields,
1100
+ formConfig,
1101
+ onSubmit,
1102
+ onSuccess: (data) => {
1103
+ resetUpload();
1104
+ onSuccess?.(data);
1075
1105
  },
1076
- onSubmit: async (values, helpers) => {
1077
- const shouldAutoSubmit = Boolean(formConfig?.endpoint);
1078
- if (!shouldAutoSubmit && !onSubmit) {
1079
- return;
1080
- }
1081
- try {
1082
- let result;
1083
- if (shouldAutoSubmit) {
1084
- result = await submitPageSpeedForm(values, formConfig);
1085
- }
1086
- if (onSubmit) {
1087
- await onSubmit(values);
1088
- }
1089
- if (shouldAutoSubmit || onSubmit) {
1090
- if (formConfig?.resetOnSuccess !== false) {
1091
- helpers.resetForm();
1092
- }
1093
- onSuccess?.(result);
1094
- }
1095
- } catch (error) {
1096
- if (error instanceof PageSpeedFormSubmissionError && error.formErrors) {
1097
- helpers.setErrors(error.formErrors);
1098
- }
1099
- onError?.(error);
1100
- throw error;
1101
- }
1102
- }
1106
+ onError,
1107
+ resetOnSuccess: formConfig?.resetOnSuccess !== false,
1108
+ uploadTokens
1103
1109
  });
1104
- const formMethod = formConfig?.method?.toLowerCase() === "get" ? "get" : "post";
1110
+ const priorityField = formFields.find((f) => f.name === "priority");
1111
+ const otherFields = formFields.filter((f) => f.name !== "priority");
1105
1112
  PRIORITIES.find(
1106
1113
  (p) => p.value === form.values.priority
1107
1114
  );
1108
- const actionsContent = React.useMemo(() => {
1115
+ const actionsContent = useMemo(() => {
1109
1116
  if (actionsSlot) return actionsSlot;
1110
1117
  if (actions && actions.length > 0) {
1111
1118
  return actions.map((action, index) => {
@@ -1162,16 +1169,27 @@ function ContactEmergency({
1162
1169
  Form,
1163
1170
  {
1164
1171
  form,
1165
- action: formConfig?.endpoint,
1166
- method: formMethod,
1167
- className: formClassName,
1172
+ notificationConfig: {
1173
+ submissionError,
1174
+ successMessage
1175
+ },
1176
+ styleConfig: {
1177
+ formClassName,
1178
+ successMessageClassName,
1179
+ errorMessageClassName
1180
+ },
1181
+ formConfig: {
1182
+ endpoint: formConfig?.endpoint,
1183
+ method: formMethod,
1184
+ submissionConfig: formConfig?.submissionConfig
1185
+ },
1186
+ onNewSubmission: () => {
1187
+ resetUpload();
1188
+ resetSubmissionState();
1189
+ },
1168
1190
  children: /* @__PURE__ */ jsxs("div", { className: "grid md:grid-cols-2", children: [
1169
1191
  /* @__PURE__ */ jsxs("div", { className: "border-b p-6 md:border-b-0 md:border-r", children: [
1170
- /* @__PURE__ */ jsxs("div", { className: "mb-6 flex items-center gap-2", children: [
1171
- /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/alert-triangle", size: 20 }),
1172
- /* @__PURE__ */ jsx("h3", { className: "font-semibold", children: "Priority Level" })
1173
- ] }),
1174
- /* @__PURE__ */ jsx(Field, { name: "priority", children: ({ field }) => /* @__PURE__ */ jsx("div", { className: "space-y-3", children: PRIORITIES.map((item) => /* @__PURE__ */ jsxs(
1192
+ priorityField && /* @__PURE__ */ jsx(Field, { name: "priority", children: ({ field }) => /* @__PURE__ */ jsx("div", { className: "space-y-3", children: PRIORITIES.map((item) => /* @__PURE__ */ jsxs(
1175
1193
  "label",
1176
1194
  {
1177
1195
  htmlFor: `priority-${item.value}`,
@@ -1195,17 +1213,24 @@ function ContactEmergency({
1195
1213
  /* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
1196
1214
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
1197
1215
  /* @__PURE__ */ jsx("span", { className: "font-medium", children: item.label }),
1198
- /* @__PURE__ */ jsxs(Badge, { variant: "secondary", className: "text-xs", children: [
1199
- /* @__PURE__ */ jsx(
1200
- DynamicIcon,
1201
- {
1202
- name: "lucide/clock",
1203
- size: 12,
1204
- className: "mr-1"
1205
- }
1206
- ),
1207
- item.response
1208
- ] })
1216
+ /* @__PURE__ */ jsxs(
1217
+ Badge,
1218
+ {
1219
+ variant: "secondary",
1220
+ className: "text-xs",
1221
+ children: [
1222
+ /* @__PURE__ */ jsx(
1223
+ DynamicIcon,
1224
+ {
1225
+ name: "lucide/clock",
1226
+ size: 12,
1227
+ className: "mr-1"
1228
+ }
1229
+ ),
1230
+ item.response
1231
+ ]
1232
+ }
1233
+ )
1209
1234
  ] }),
1210
1235
  /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: item.description })
1211
1236
  ] })
@@ -1231,76 +1256,23 @@ function ContactEmergency({
1231
1256
  /* @__PURE__ */ jsx("h3", { className: "font-semibold", children: "Describe Your Issue" })
1232
1257
  ] }),
1233
1258
  /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
1234
- /* @__PURE__ */ jsxs("div", { className: "grid gap-4 sm:grid-cols-2", children: [
1235
- /* @__PURE__ */ jsx(Field, { name: "name", children: ({ field, meta }) => /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
1236
- /* @__PURE__ */ jsx(Label, { htmlFor: "name", children: "Name" }),
1237
- /* @__PURE__ */ jsx(
1238
- TextInput,
1239
- {
1240
- ...field,
1241
- id: "name",
1242
- placeholder: "Your name",
1243
- error: meta.touched && !!meta.error,
1244
- "aria-label": "Name"
1245
- }
1246
- )
1247
- ] }) }),
1248
- /* @__PURE__ */ jsx(Field, { name: "email", children: ({ field, meta }) => /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
1249
- /* @__PURE__ */ jsx(Label, { htmlFor: "email", children: "Email" }),
1250
- /* @__PURE__ */ jsx(
1251
- TextInput,
1259
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-12 gap-4", children: otherFields.map((field) => /* @__PURE__ */ jsx(
1260
+ "div",
1261
+ {
1262
+ className: getColumnSpanClass(field.columnSpan),
1263
+ children: /* @__PURE__ */ jsx(
1264
+ DynamicFormField,
1252
1265
  {
1253
- ...field,
1254
- id: "email",
1255
- type: "email",
1256
- placeholder: "you@company.com",
1257
- error: meta.touched && !!meta.error,
1258
- "aria-label": "Email"
1266
+ field,
1267
+ uploadProgress,
1268
+ onFileUpload: uploadFiles,
1269
+ onFileRemove: removeFile,
1270
+ isUploading
1259
1271
  }
1260
1272
  )
1261
- ] }) })
1262
- ] }),
1263
- /* @__PURE__ */ jsx(Field, { name: "phone", children: ({ field, meta }) => /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
1264
- /* @__PURE__ */ jsx(Label, { htmlFor: "phone", children: "Phone (Optional)" }),
1265
- /* @__PURE__ */ jsx(
1266
- TextInput,
1267
- {
1268
- ...field,
1269
- id: "phone",
1270
- type: "tel",
1271
- placeholder: "+1 (555) 000-0000",
1272
- error: meta.touched && !!meta.error,
1273
- "aria-label": "Phone"
1274
- }
1275
- )
1276
- ] }) }),
1277
- /* @__PURE__ */ jsx(Field, { name: "subject", children: ({ field, meta }) => /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
1278
- /* @__PURE__ */ jsx(Label, { htmlFor: "subject", children: "Subject" }),
1279
- /* @__PURE__ */ jsx(
1280
- TextInput,
1281
- {
1282
- ...field,
1283
- id: "subject",
1284
- placeholder: "Brief summary of the issue",
1285
- error: meta.touched && !!meta.error,
1286
- "aria-label": "Subject"
1287
- }
1288
- )
1289
- ] }) }),
1290
- /* @__PURE__ */ jsx(Field, { name: "description", children: ({ field, meta }) => /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
1291
- /* @__PURE__ */ jsx(Label, { htmlFor: "description", children: "Description" }),
1292
- /* @__PURE__ */ jsx(
1293
- TextArea,
1294
- {
1295
- ...field,
1296
- id: "description",
1297
- placeholder: "Describe the issue, what you've tried, and the impact...",
1298
- rows: 4,
1299
- error: meta.touched && !!meta.error,
1300
- "aria-label": "Description"
1301
- }
1302
- )
1303
- ] }) }),
1273
+ },
1274
+ field.name
1275
+ )) }),
1304
1276
  /* @__PURE__ */ jsx(Separator, {}),
1305
1277
  actionsSlot || actions && actions.length > 0 ? actionsContent : /* @__PURE__ */ jsxs(
1306
1278
  Pressable,