@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.
- package/dist/components/meeting-scheduler/booking-form.d.ts.map +1 -1
- package/dist/components/meeting-scheduler/index.cjs +177 -35
- package/dist/components/meeting-scheduler/index.cjs.map +1 -1
- package/dist/components/meeting-scheduler/index.d.ts.map +1 -1
- package/dist/components/meeting-scheduler/index.js +151 -9
- package/dist/components/meeting-scheduler/index.js.map +1 -1
- package/dist/schemas/meeting-booking-schema.cjs +107 -6
- package/dist/schemas/meeting-booking-schema.cjs.map +1 -1
- package/dist/schemas/meeting-booking-schema.d.ts +105 -19
- package/dist/schemas/meeting-booking-schema.d.ts.map +1 -1
- package/dist/schemas/meeting-booking-schema.js +99 -7
- package/dist/schemas/meeting-booking-schema.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/meeting-booking-schema.test.ts +2 -2
- package/src/__tests__/meeting-form-field-types.test.tsx +240 -0
- package/src/__tests__/meeting-scheduler-details-first.test.tsx +33 -0
- package/src/components/meeting-scheduler/booking-form.tsx +67 -4
- package/src/components/meeting-scheduler/index.tsx +9 -6
- package/src/schemas/meeting-booking-schema.ts +231 -25
- package/src/utils/__tests__/hubspot-meetings-convention.test.ts +15 -6
|
@@ -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;
|
|
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
|
|
133
|
-
|
|
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
|
-
|
|
192
|
-
|
|
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 =
|
|
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
|
|
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 (
|
|
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;
|