@flamingo-stack/openframe-frontend-core 0.0.664 → 0.0.665-2372.7066.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 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/meeting-scheduler/index.tsx"],"names":[],"mappings":"AA0CA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKtD,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,WAAW,EACjB,MAAM,sCAAsC,CAAC;AAI9C,OAAO,EAA0D,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAwB/G,MAAM,WAAW,4BAA4B;IAC3C,kFAAkF;IAClF,SAAS,EAAE,MAAM,CAAC;IAClB,2FAA2F;IAC3F,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iFAAiF;IACjF,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAC1C,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,mEAAmE;IACnE,KAAK,CAAC,EAAE,WAAW,EAAE,CAAC;IACtB,sFAAsF;IACtF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,yFAAyF;IACzF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAC5C;;;;;OAKG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;;;;OAUG;IACH,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB;;;;;;;;;;;;;;;;;OAiBG;IACH,WAAW,CAAC,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC9C;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,WAAW,GAAG,SAAS,CAAC,CAAC;CACpE;AAED,KAAK,IAAI,GAAG,MAAM,GAAG,SAAS,GAAG,WAAW,CAAC;AAC7C,mFAAmF;AACnF,MAAM,MAAM,cAAc,GAAG,IAAI,GAAG,aAAa,CAAC;AA4ClD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,eAAO,MAAM,mBAAmB,qCAAqC,CAAC;AAEtE;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,iCAAiC,kCAAkC,CAAC;AAEjF,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,eAAe,CAAC;AAE3D,4EAA4E;AAC5E,eAAO,MAAM,sBAAsB,EAAE,aAA4B,CAAC;AAElE;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,CACzC,aAAa,EACb;IAAE,WAAW,EAAE,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAStG,CAAC;AAqDF;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,IAA6B,EAC7B,SAAS,EACT,OAAO,EACP,MAAM,EACN,QAAQ,GACT,EAAE;IACD,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gHAAgH;IAChH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,+BAQA;AAkBD,wBAAgB,uBAAuB,CAAC,EACtC,SAAS,EACT,UAAe,EACf,mBAAmB,EACnB,KAAK,EACL,WAAW,EACX,KAAK,EACL,eAAe,EACf,WAAW,EACX,MAAM,EACN,QAAQ,EACR,aAAa,EACb,SAAS,EACT,IAA6B,EAC7B,WAAW,EAAE,WAAyB,EACtC,gBAAgB,GACjB,EAAE,4BAA4B,+BAmjB9B;AAKD,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,GACxB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,yBAAyB,EACzB,oCAAoC,EACpC,KAAK,8BAA8B,GACpC,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,WAAW,EAAE,CAAC;AAC/F,YAAY,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/meeting-scheduler/index.tsx"],"names":[],"mappings":"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"}
@@ -101,6 +101,18 @@ var optionValidator = (field, base) => base.refine((v) => !v || (field.options ?
101
101
  message: `Please choose a valid option for ${field.label}`
102
102
  });
103
103
  var DECIMAL_LITERAL_RE = /^-?\d+(\.\d+)?$/;
104
+ var MULTI_VALUE_SEPARATOR = ";";
105
+ var splitMultiValue = (value) => typeof value === "string" && value ? value.split(MULTI_VALUE_SEPARATOR) : [];
106
+ var PHONE_RE = /^\+?[\d\s().\-/]+(?:\s*(?:x|ext\.?)\s*\d+)?$/i;
107
+ var PHONE_MIN_DIGITS = 5;
108
+ var PHONE_MAX_DIGITS = 20;
109
+ var phoneDigits = (v) => v.replace(/\D/g, "").length;
110
+ var ISO_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
111
+ var isRealIsoDate = (v) => {
112
+ if (!ISO_DATE_RE.test(v)) return false;
113
+ const d = /* @__PURE__ */ new Date(`${v}T00:00:00Z`);
114
+ return !Number.isNaN(d.getTime()) && d.toISOString().slice(0, 10) === v;
115
+ };
104
116
  var FORM_FIELD_TYPES = {
105
117
  text: {
106
118
  kind: "string",
@@ -121,16 +133,88 @@ var FORM_FIELD_TYPES = {
121
133
  // accepts (`1e3`, `007`) to this before it is validated or sent.
122
134
  validator: (field, base) => base.max(32, { message: `${field.label} is too long` }).regex(DECIMAL_LITERAL_RE, { message: `${field.label} must be a number` })
123
135
  },
136
+ phone: {
137
+ kind: "string",
138
+ hasOptions: false,
139
+ validator: (field, base) => base.max(40, { message: `${field.label} is too long` }).refine(
140
+ (v) => !v || PHONE_RE.test(v) && phoneDigits(v) >= PHONE_MIN_DIGITS && phoneDigits(v) <= PHONE_MAX_DIGITS,
141
+ { message: `Please enter a valid phone number for ${field.label}` }
142
+ ),
143
+ placeholder: (field) => `Enter ${field.label}`
144
+ },
145
+ date: {
146
+ kind: "string",
147
+ hasOptions: false,
148
+ validator: (field, base) => base.refine((v) => !v || isRealIsoDate(v), { message: `${field.label} must be a date` })
149
+ },
124
150
  select: { kind: "string", hasOptions: true, validator: optionValidator },
125
151
  radio: { kind: "string", hasOptions: true, validator: optionValidator },
152
+ multiselect: {
153
+ kind: "string",
154
+ hasOptions: true,
155
+ validator: (field, base) => base.refine((v) => splitMultiValue(v).every((part) => (field.options ?? []).includes(part)), {
156
+ message: `Please choose valid options for ${field.label}`
157
+ })
158
+ },
126
159
  checkbox: { kind: "boolean", hasOptions: false, validator: () => z.boolean() }
127
160
  };
128
161
  var SUPPORTED_FORM_FIELD_TYPES = Object.keys(FORM_FIELD_TYPES);
162
+ var FIELD_TYPE_CONTROLS = {
163
+ text: "text",
164
+ textarea: "textarea",
165
+ number: "number",
166
+ select: "select",
167
+ radio: "radio",
168
+ booleancheckbox: "checkbox",
169
+ phonenumber: "phone",
170
+ date: "date",
171
+ html: "display",
172
+ file: "unanswerable"
173
+ };
174
+ var DATA_TYPE_CONTROLS = {
175
+ string: "text",
176
+ number: "number",
177
+ enumeration: "select",
178
+ bool: "checkbox",
179
+ date: "date",
180
+ datetime: "date",
181
+ phone_number: "phone"
182
+ };
183
+ var hasDeclaredOptions = (field) => (field.options?.length ?? 0) > 0;
184
+ function resolveFormFieldControl(field) {
185
+ const fieldType = (field.type ?? "").toLowerCase();
186
+ const withOptions = hasDeclaredOptions(field);
187
+ const usable = (r) => {
188
+ if (!r || r === "display" || r === "unanswerable") return r;
189
+ return FORM_FIELD_TYPES[r].hasOptions && !withOptions ? "text" : r;
190
+ };
191
+ if (fieldType === "checkbox") return withOptions ? "multiselect" : "checkbox";
192
+ if (fieldType.startsWith("calculation")) return "display";
193
+ const asControl = Object.prototype.hasOwnProperty.call(FORM_FIELD_TYPES, fieldType) ? fieldType : void 0;
194
+ return usable(FIELD_TYPE_CONTROLS[fieldType] ?? asControl) ?? usable(DATA_TYPE_CONTROLS[(field.dataType ?? "").toLowerCase()]) ?? (withOptions ? "select" : "text");
195
+ }
129
196
  var FORM_FIELD_TYPES_WITH_OPTIONS = SUPPORTED_FORM_FIELD_TYPES.filter(
130
197
  (type) => FORM_FIELD_TYPES[type].hasOptions
131
198
  );
132
- function isSupportedFormField(field) {
133
- return Object.prototype.hasOwnProperty.call(FORM_FIELD_TYPES, field.type);
199
+ function normalizeFormField(field) {
200
+ const control = resolveFormFieldControl(field);
201
+ if (control === "display" || control === "unanswerable") return null;
202
+ const normalized = {
203
+ ...field,
204
+ type: control,
205
+ hubspotType: field.hubspotType ?? field.type
206
+ };
207
+ if (!FORM_FIELD_TYPES[control].hasOptions) {
208
+ delete normalized.options;
209
+ delete normalized.optionLabels;
210
+ }
211
+ return normalized;
212
+ }
213
+ function normalizeFormFields(fields) {
214
+ return fields.flatMap((f) => normalizeFormField(f) ?? []);
215
+ }
216
+ function blocksNativeBooking(field) {
217
+ return field.required && resolveFormFieldControl(field) === "unanswerable";
134
218
  }
135
219
  var BUILT_IN_BOOKING_FIELDS = [
136
220
  {
@@ -188,8 +272,8 @@ function isValidBcp47Locale(locale) {
188
272
  }
189
273
  function buildBookingSchema(formFields, legalConsent, slot) {
190
274
  const answers = {};
191
- for (const field of formFields) {
192
- if (!isSupportedFormField(field)) continue;
275
+ const drawn = normalizeFormFields(formFields);
276
+ for (const field of drawn) {
193
277
  const spec = FORM_FIELD_TYPES[field.type];
194
278
  let validator;
195
279
  if (spec.kind === "boolean") {
@@ -202,7 +286,7 @@ function buildBookingSchema(formFields, legalConsent, slot) {
202
286
  answers[field.name] = validator;
203
287
  }
204
288
  const requiredConsentIds = (legalConsent?.communicationConsentCheckboxes ?? []).filter((c) => c.required).map((c) => c.communicationTypeId);
205
- const hasRequiredAnswers = formFields.some((f) => isSupportedFormField(f) && f.required);
289
+ const hasRequiredAnswers = drawn.some((f) => f.required);
206
290
  const answersObject = z.object(answers);
207
291
  return z.object({
208
292
  meetingId: z.string().min(1),
@@ -362,6 +446,8 @@ var evenSpan = (count, index) => {
362
446
  };
363
447
  var slotColumnClass = (row, slot, index) => cn(row.length === 2 ? "col-span-1" : "col-span-2", SPAN_CLASS[slot.span ?? evenSpan(row.length, index)]);
364
448
  var placeholderFor = (field) => field.placeholder ?? fieldTypeSpec(field.type).placeholder?.(field);
449
+ var optionLabel = (field, value) => field.optionLabels?.[value] ?? value;
450
+ var trimmed = (v) => String(v ?? "").trim();
365
451
  var canonicalNumber = (v) => {
366
452
  const s = String(v ?? "").trim();
367
453
  if (s === "" || DECIMAL_LITERAL_RE.test(s)) return s;
@@ -405,6 +491,32 @@ var FIELD_CONTROLS = {
405
491
  ...register(registerName, { setValueAs: canonicalNumber })
406
492
  }
407
493
  ),
494
+ phone: ({ field, id, registerName, error, register }) => /* @__PURE__ */ jsx(
495
+ Input,
496
+ {
497
+ id,
498
+ type: "tel",
499
+ inputMode: "tel",
500
+ autoComplete: "tel",
501
+ required: field.required,
502
+ "aria-invalid": Boolean(error),
503
+ placeholder: placeholderFor(field),
504
+ ...register(registerName, { setValueAs: trimmed })
505
+ }
506
+ ),
507
+ date: ({ field, id, registerName, error, register }) => (
508
+ // The native picker emits exactly the wire shape (`YYYY-MM-DD`).
509
+ /* @__PURE__ */ jsx(
510
+ Input,
511
+ {
512
+ id,
513
+ type: "date",
514
+ required: field.required,
515
+ "aria-invalid": Boolean(error),
516
+ ...register(registerName)
517
+ }
518
+ )
519
+ ),
408
520
  select: ({ field, id, registerName, error, control }) => /* @__PURE__ */ jsx(
409
521
  Controller,
410
522
  {
@@ -412,7 +524,7 @@ var FIELD_CONTROLS = {
412
524
  name: registerName,
413
525
  render: ({ field: rhf }) => /* @__PURE__ */ jsxs(Select, { value: rhf.value ?? "", onValueChange: rhf.onChange, children: [
414
526
  /* @__PURE__ */ jsx(SelectTrigger, { id, "aria-required": field.required || void 0, "aria-invalid": Boolean(error), children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select\u2026" }) }),
415
- /* @__PURE__ */ jsx(SelectContent, { children: (field.options ?? []).map((opt) => /* @__PURE__ */ jsx(SelectItem, { value: opt, children: opt }, opt)) })
527
+ /* @__PURE__ */ jsx(SelectContent, { children: (field.options ?? []).map((opt) => /* @__PURE__ */ jsx(SelectItem, { value: opt, children: optionLabel(field, opt) }, opt)) })
416
528
  ] })
417
529
  }
418
530
  ),
@@ -430,12 +542,42 @@ var FIELD_CONTROLS = {
430
542
  "aria-invalid": Boolean(error),
431
543
  children: (field.options ?? []).map((opt) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-[var(--spacing-system-xs)]", children: [
432
544
  /* @__PURE__ */ jsx(RadioGroupItem, { id: `${id}-${opt}`, value: opt }),
433
- /* @__PURE__ */ jsx(Label, { htmlFor: `${id}-${opt}`, children: opt })
545
+ /* @__PURE__ */ jsx(Label, { htmlFor: `${id}-${opt}`, children: optionLabel(field, opt) })
434
546
  ] }, opt))
435
547
  }
436
548
  )
437
549
  }
438
550
  ),
551
+ multiselect: ({ field, id, registerName, error, control }) => (
552
+ // HubSpot's "multiple checkboxes": the answer is its `;`-joined value list,
553
+ // held in that wire shape so the validator and the POST see one string.
554
+ /* @__PURE__ */ jsx(
555
+ Controller,
556
+ {
557
+ control,
558
+ name: registerName,
559
+ render: ({ field: rhf }) => {
560
+ const selected = splitMultiValue(rhf.value);
561
+ const toggle = (opt, on) => {
562
+ const next = (field.options ?? []).filter((o) => o === opt ? on : selected.includes(o));
563
+ rhf.onChange(next.join(MULTI_VALUE_SEPARATOR));
564
+ };
565
+ return /* @__PURE__ */ jsx("div", { id, role: "group", className: "flex flex-col gap-[var(--spacing-system-xs)]", children: (field.options ?? []).map((opt) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-[var(--spacing-system-xs)]", children: [
566
+ /* @__PURE__ */ jsx(
567
+ Checkbox,
568
+ {
569
+ id: `${id}-${opt}`,
570
+ checked: selected.includes(opt),
571
+ onCheckedChange: (v) => toggle(opt, v === true),
572
+ "aria-invalid": Boolean(error)
573
+ }
574
+ ),
575
+ /* @__PURE__ */ jsx(Label, { htmlFor: `${id}-${opt}`, children: optionLabel(field, opt) })
576
+ ] }, opt)) });
577
+ }
578
+ }
579
+ )
580
+ ),
439
581
  checkbox: ({ field, id, registerName, error, control }) => /* @__PURE__ */ jsx(
440
582
  Controller,
441
583
  {
@@ -478,7 +620,7 @@ function BookingForm({
478
620
  getSignals
479
621
  }) {
480
622
  const { formFields, legalConsent } = availability;
481
- const supportedFields = useMemo(() => formFields.filter(isSupportedFormField), [formFields]);
623
+ const supportedFields = useMemo(() => normalizeFormFields(formFields), [formFields]);
482
624
  const schema = useMemo(
483
625
  () => makeDeferredBookingSchema(supportedFields, legalConsent),
484
626
  [supportedFields, legalConsent]
@@ -1293,7 +1435,7 @@ function SchedulerDegradedCard({
1293
1435
  ] });
1294
1436
  }
1295
1437
  function isNativelyBookable(availability) {
1296
- if (!availability.formFields.every(isSupportedFormField)) return false;
1438
+ if (availability.formFields.some(blocksNativeBooking)) return false;
1297
1439
  const consent = availability.legalConsent;
1298
1440
  if (consent) {
1299
1441
  if (typeof consent.processingConsentText !== "string") return false;