@flamingo-stack/openframe-frontend-core 0.0.664-snapshot.20260924171334 → 0.0.664

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":"booking-form.d.ts","sourceRoot":"","sources":["../../../src/components/meeting-scheduler/booking-form.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAa,SAAS,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAGvD,OAAO,EAEL,KAAK,uBAAuB,EAQ5B,KAAK,mBAAmB,EAKzB,MAAM,sCAAsC,CAAC;AAsB9C;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,yFAAyF;IACzF,IAAI,EAAE,uBAAuB,GAAG,CAAC,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;IAChE,gFAAgF;IAChF,IAAI,CAAC,EAAE,gBAAgB,CAAC;CACzB;AAED,+EAA+E;AAC/E,MAAM,MAAM,gBAAgB,GAAG,MAAM,OAAO,UAAU,CAAC;AAEvD,MAAM,MAAM,eAAe,GAAG,gBAAgB,EAAE,CAAC;AAEjD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAiBD;6CAC6C;AAC7C,QAAA,MAAM,UAAU;;;;;CAKN,CAAC;AAOX,0GAA0G;AAC1G,eAAO,MAAM,oBAAoB,oBAAoB,CAAC;AAYtD;iFACiF;AACjF,eAAO,MAAM,QAAQ,GAAI,OAAO,MAAM,EAAE,OAAO,MAAM,KAAG,gBAIvD,CAAC;AA+MF,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,mBAAmB,CAAC;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;qEACiE;IACjE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,eAAe,EAAE,CAAC;IAC9B,uFAAuF;IACvF,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D,mFAAmF;IACnF,kBAAkB,EAAE;QAAE,GAAG,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACjE,UAAU,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;CACnD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,EAC1B,YAAY,EACZ,SAAS,EACT,WAAW,EACX,UAAU,EACV,QAAQ,EACR,SAAiB,EACjB,aAAa,EACb,WAAW,EACX,UAAU,EACV,SAAS,EACT,OAAO,EACP,YAAY,EACZ,QAAQ,EACR,kBAAkB,EAClB,UAAU,GACX,EAAE,gBAAgB,+BAuTlB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,SAAS,EACT,OAAO,EACP,UAAU,GACX,EAAE;IACD,SAAS,CAAC,EAAE,eAAe,EAAE,CAAC;IAC9B;;qDAEiD;IACjD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,+BA2BA"}
1
+ {"version":3,"file":"booking-form.d.ts","sourceRoot":"","sources":["../../../src/components/meeting-scheduler/booking-form.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAa,SAAS,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAGvD,OAAO,EAEL,KAAK,uBAAuB,EAM5B,KAAK,mBAAmB,EAKzB,MAAM,sCAAsC,CAAC;AAsB9C;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,yFAAyF;IACzF,IAAI,EAAE,uBAAuB,GAAG,CAAC,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;IAChE,gFAAgF;IAChF,IAAI,CAAC,EAAE,gBAAgB,CAAC;CACzB;AAED,+EAA+E;AAC/E,MAAM,MAAM,gBAAgB,GAAG,MAAM,OAAO,UAAU,CAAC;AAEvD,MAAM,MAAM,eAAe,GAAG,gBAAgB,EAAE,CAAC;AAEjD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAiBD;6CAC6C;AAC7C,QAAA,MAAM,UAAU;;;;;CAKN,CAAC;AAOX,0GAA0G;AAC1G,eAAO,MAAM,oBAAoB,oBAAoB,CAAC;AAYtD;iFACiF;AACjF,eAAO,MAAM,QAAQ,GAAI,OAAO,MAAM,EAAE,OAAO,MAAM,KAAG,gBAIvD,CAAC;AAqJF,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,mBAAmB,CAAC;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;qEACiE;IACjE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,eAAe,EAAE,CAAC;IAC9B,uFAAuF;IACvF,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D,mFAAmF;IACnF,kBAAkB,EAAE;QAAE,GAAG,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACjE,UAAU,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;CACnD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,EAC1B,YAAY,EACZ,SAAS,EACT,WAAW,EACX,UAAU,EACV,QAAQ,EACR,SAAiB,EACjB,aAAa,EACb,WAAW,EACX,UAAU,EACV,SAAS,EACT,OAAO,EACP,YAAY,EACZ,QAAQ,EACR,kBAAkB,EAClB,UAAU,GACX,EAAE,gBAAgB,+BAoTlB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,SAAS,EACT,OAAO,EACP,UAAU,GACX,EAAE;IACD,SAAS,CAAC,EAAE,eAAe,EAAE,CAAC;IAC9B;;qDAEiD;IACjD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,+BA2BA"}
@@ -101,18 +101,6 @@ var optionValidator = (field, base) => base.refine((v) => !v || (_nullishCoalesc
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
- };
116
104
  var FORM_FIELD_TYPES = {
117
105
  text: {
118
106
  kind: "string",
@@ -133,88 +121,16 @@ var FORM_FIELD_TYPES = {
133
121
  // accepts (`1e3`, `007`) to this before it is validated or sent.
134
122
  validator: (field, base) => base.max(32, { message: `${field.label} is too long` }).regex(DECIMAL_LITERAL_RE, { message: `${field.label} must be a number` })
135
123
  },
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
- },
150
124
  select: { kind: "string", hasOptions: true, validator: optionValidator },
151
125
  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) => (_nullishCoalesce(field.options, () => ( []))).includes(part)), {
156
- message: `Please choose valid options for ${field.label}`
157
- })
158
- },
159
126
  checkbox: { kind: "boolean", hasOptions: false, validator: () => _zod.z.boolean() }
160
127
  };
161
128
  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) => (_nullishCoalesce(_optionalChain([field, 'access', _2 => _2.options, 'optionalAccess', _3 => _3.length]), () => ( 0))) > 0;
184
- function resolveFormFieldControl(field) {
185
- const fieldType = (_nullishCoalesce(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 _nullishCoalesce(_nullishCoalesce(usable(_nullishCoalesce(FIELD_TYPE_CONTROLS[fieldType], () => ( asControl))), () => ( usable(DATA_TYPE_CONTROLS[(_nullishCoalesce(field.dataType, () => ( ""))).toLowerCase()]))), () => ( (withOptions ? "select" : "text")));
195
- }
196
129
  var FORM_FIELD_TYPES_WITH_OPTIONS = SUPPORTED_FORM_FIELD_TYPES.filter(
197
130
  (type) => FORM_FIELD_TYPES[type].hasOptions
198
131
  );
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: _nullishCoalesce(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) => _nullishCoalesce(normalizeFormField(f), () => ( [])));
215
- }
216
- function blocksNativeBooking(field) {
217
- return field.required && resolveFormFieldControl(field) === "unanswerable";
132
+ function isSupportedFormField(field) {
133
+ return Object.prototype.hasOwnProperty.call(FORM_FIELD_TYPES, field.type);
218
134
  }
219
135
  var BUILT_IN_BOOKING_FIELDS = [
220
136
  {
@@ -272,8 +188,8 @@ function isValidBcp47Locale(locale) {
272
188
  }
273
189
  function buildBookingSchema(formFields, legalConsent, slot) {
274
190
  const answers = {};
275
- const drawn = normalizeFormFields(formFields);
276
- for (const field of drawn) {
191
+ for (const field of formFields) {
192
+ if (!isSupportedFormField(field)) continue;
277
193
  const spec = FORM_FIELD_TYPES[field.type];
278
194
  let validator;
279
195
  if (spec.kind === "boolean") {
@@ -285,8 +201,8 @@ function buildBookingSchema(formFields, legalConsent, slot) {
285
201
  }
286
202
  answers[field.name] = validator;
287
203
  }
288
- const requiredConsentIds = (_nullishCoalesce(_optionalChain([legalConsent, 'optionalAccess', _4 => _4.communicationConsentCheckboxes]), () => ( []))).filter((c) => c.required).map((c) => c.communicationTypeId);
289
- const hasRequiredAnswers = drawn.some((f) => f.required);
204
+ const requiredConsentIds = (_nullishCoalesce(_optionalChain([legalConsent, 'optionalAccess', _2 => _2.communicationConsentCheckboxes]), () => ( []))).filter((c) => c.required).map((c) => c.communicationTypeId);
205
+ const hasRequiredAnswers = formFields.some((f) => isSupportedFormField(f) && f.required);
290
206
  const answersObject = _zod.z.object(answers);
291
207
  return _zod.z.object({
292
208
  meetingId: _zod.z.string().min(1),
@@ -338,7 +254,7 @@ var BOOKING_IN_FLIGHT_MESSAGE = "Already submitting";
338
254
  function useMeetingBooking(options) {
339
255
  const { meetingId, apiBaseUrl = "", initialAvailability } = options;
340
256
  const queryClient = _reactquery.useQueryClient.call(void 0, );
341
- const seededOffset = _optionalChain([initialAvailability, 'optionalAccess', _5 => _5.meetingId]) === meetingId ? initialAvailability.monthOffset : void 0;
257
+ const seededOffset = _optionalChain([initialAvailability, 'optionalAccess', _3 => _3.meetingId]) === meetingId ? initialAvailability.monthOffset : void 0;
342
258
  const [monthOffset, setMonthOffsetState] = _react.useState.call(void 0, _nullishCoalesce(seededOffset, () => ( 0)));
343
259
  const setMonthOffset = _react.useCallback.call(void 0, (offset) => {
344
260
  setMonthOffsetState(Math.max(0, Math.min(_chunk6FD7ZEBYcjs.MAX_MONTH_OFFSET, offset)));
@@ -349,7 +265,7 @@ function useMeetingBooking(options) {
349
265
  prevMeetingIdRef.current = meetingId;
350
266
  setMonthOffsetState(0);
351
267
  }, [meetingId]);
352
- const seed = _optionalChain([initialAvailability, 'optionalAccess', _6 => _6.meetingId]) === meetingId && initialAvailability.monthOffset === monthOffset ? initialAvailability : void 0;
268
+ const seed = _optionalChain([initialAvailability, 'optionalAccess', _4 => _4.meetingId]) === meetingId && initialAvailability.monthOffset === monthOffset ? initialAvailability : void 0;
353
269
  const availabilityQuery = _reactquery.useQuery.call(void 0, {
354
270
  queryKey: meetingAvailabilityKey(apiBaseUrl, meetingId, monthOffset),
355
271
  queryFn: async ({ signal }) => {
@@ -445,9 +361,7 @@ var evenSpan = (count, index) => {
445
361
  return Math.min(GRID_COLUMNS, Math.max(1, index < extra ? base + 1 : base));
446
362
  };
447
363
  var slotColumnClass = (row, slot, index) => _chunkX7CEWD6Vcjs.cn.call(void 0, row.length === 2 ? "col-span-1" : "col-span-2", SPAN_CLASS[_nullishCoalesce(slot.span, () => ( evenSpan(row.length, index)))]);
448
- var placeholderFor = (field) => _nullishCoalesce(field.placeholder, () => ( _optionalChain([fieldTypeSpec, 'call', _7 => _7(field.type), 'access', _8 => _8.placeholder, 'optionalCall', _9 => _9(field)])));
449
- var optionLabel = (field, value) => _nullishCoalesce(_optionalChain([field, 'access', _10 => _10.optionLabels, 'optionalAccess', _11 => _11[value]]), () => ( value));
450
- var trimmed = (v) => String(_nullishCoalesce(v, () => ( ""))).trim();
364
+ var placeholderFor = (field) => _nullishCoalesce(field.placeholder, () => ( _optionalChain([fieldTypeSpec, 'call', _5 => _5(field.type), 'access', _6 => _6.placeholder, 'optionalCall', _7 => _7(field)])));
451
365
  var canonicalNumber = (v) => {
452
366
  const s = String(_nullishCoalesce(v, () => ( ""))).trim();
453
367
  if (s === "" || DECIMAL_LITERAL_RE.test(s)) return s;
@@ -491,32 +405,6 @@ var FIELD_CONTROLS = {
491
405
  ...register(registerName, { setValueAs: canonicalNumber })
492
406
  }
493
407
  ),
494
- phone: ({ field, id, registerName, error, register }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
495
- _chunkQVSVRG7Icjs.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__ */ _jsxruntime.jsx.call(void 0,
510
- _chunkQVSVRG7Icjs.Input,
511
- {
512
- id,
513
- type: "date",
514
- required: field.required,
515
- "aria-invalid": Boolean(error),
516
- ...register(registerName)
517
- }
518
- )
519
- ),
520
408
  select: ({ field, id, registerName, error, control }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
521
409
  _reacthookform.Controller,
522
410
  {
@@ -524,7 +412,7 @@ var FIELD_CONTROLS = {
524
412
  name: registerName,
525
413
  render: ({ field: rhf }) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk6FD7ZEBYcjs.Select, { value: _nullishCoalesce(rhf.value, () => ( "")), onValueChange: rhf.onChange, children: [
526
414
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6FD7ZEBYcjs.SelectTrigger, { id, "aria-required": field.required || void 0, "aria-invalid": Boolean(error), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6FD7ZEBYcjs.SelectValue, { placeholder: "Select\u2026" }) }),
527
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6FD7ZEBYcjs.SelectContent, { children: (_nullishCoalesce(field.options, () => ( []))).map((opt) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6FD7ZEBYcjs.SelectItem, { value: opt, children: optionLabel(field, opt) }, opt)) })
415
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6FD7ZEBYcjs.SelectContent, { children: (_nullishCoalesce(field.options, () => ( []))).map((opt) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6FD7ZEBYcjs.SelectItem, { value: opt, children: opt }, opt)) })
528
416
  ] })
529
417
  }
530
418
  ),
@@ -542,42 +430,12 @@ var FIELD_CONTROLS = {
542
430
  "aria-invalid": Boolean(error),
543
431
  children: (_nullishCoalesce(field.options, () => ( []))).map((opt) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-[var(--spacing-system-xs)]", children: [
544
432
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6FD7ZEBYcjs.RadioGroupItem, { id: `${id}-${opt}`, value: opt }),
545
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGSD62VAYcjs.Label, { htmlFor: `${id}-${opt}`, children: optionLabel(field, opt) })
433
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkGSD62VAYcjs.Label, { htmlFor: `${id}-${opt}`, children: opt })
546
434
  ] }, opt))
547
435
  }
548
436
  )
549
437
  }
550
438
  ),
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__ */ _jsxruntime.jsx.call(void 0,
555
- _reacthookform.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 = (_nullishCoalesce(field.options, () => ( []))).filter((o) => o === opt ? on : selected.includes(o));
563
- rhf.onChange(next.join(MULTI_VALUE_SEPARATOR));
564
- };
565
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { id, role: "group", className: "flex flex-col gap-[var(--spacing-system-xs)]", children: (_nullishCoalesce(field.options, () => ( []))).map((opt) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-[var(--spacing-system-xs)]", children: [
566
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
567
- _chunkQVSVRG7Icjs.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__ */ _jsxruntime.jsx.call(void 0, _chunkGSD62VAYcjs.Label, { htmlFor: `${id}-${opt}`, children: optionLabel(field, opt) })
576
- ] }, opt)) });
577
- }
578
- }
579
- )
580
- ),
581
439
  checkbox: ({ field, id, registerName, error, control }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
582
440
  _reacthookform.Controller,
583
441
  {
@@ -620,13 +478,13 @@ function BookingForm({
620
478
  getSignals
621
479
  }) {
622
480
  const { formFields, legalConsent } = availability;
623
- const supportedFields = _react.useMemo.call(void 0, () => normalizeFormFields(formFields), [formFields]);
481
+ const supportedFields = _react.useMemo.call(void 0, () => formFields.filter(isSupportedFormField), [formFields]);
624
482
  const schema = _react.useMemo.call(void 0,
625
483
  () => makeDeferredBookingSchema(supportedFields, legalConsent),
626
484
  [supportedFields, legalConsent]
627
485
  );
628
486
  const consentDefaults = _react.useMemo.call(void 0,
629
- () => (_nullishCoalesce(_optionalChain([legalConsent, 'optionalAccess', _12 => _12.communicationConsentCheckboxes]), () => ( []))).map((c) => ({
487
+ () => (_nullishCoalesce(_optionalChain([legalConsent, 'optionalAccess', _8 => _8.communicationConsentCheckboxes]), () => ( []))).map((c) => ({
630
488
  communicationTypeId: c.communicationTypeId,
631
489
  consented: false
632
490
  })),
@@ -657,8 +515,8 @@ function BookingForm({
657
515
  ..._nullishCoalesce(initialValues, () => ( {}))
658
516
  }
659
517
  });
660
- const priorConsents = _optionalChain([initialValues, 'optionalAccess', _13 => _13.legalConsentResponses]);
661
- const [consented, setConsented] = _react.useState.call(void 0, _optionalChain([initialValues, 'optionalAccess', _14 => _14[HOST_CONSENT_KEY]]) === true);
518
+ const priorConsents = _optionalChain([initialValues, 'optionalAccess', _9 => _9.legalConsentResponses]);
519
+ const [consented, setConsented] = _react.useState.call(void 0, _optionalChain([initialValues, 'optionalAccess', _10 => _10[HOST_CONSENT_KEY]]) === true);
662
520
  const [consentError, setConsentError] = _react.useState.call(void 0, null);
663
521
  const consentMissing = Boolean(consent) && !consented;
664
522
  _react.useEffect.call(void 0, () => {
@@ -667,7 +525,7 @@ function BookingForm({
667
525
  "legalConsentResponses",
668
526
  consentDefaults.map((next) => ({
669
527
  ...next,
670
- consented: _nullishCoalesce(_optionalChain([current, 'access', _15 => _15.find, 'call', _16 => _16((r) => r.communicationTypeId === next.communicationTypeId), 'optionalAccess', _17 => _17.consented]), () => ( false))
528
+ consented: _nullishCoalesce(_optionalChain([current, 'access', _11 => _11.find, 'call', _12 => _12((r) => r.communicationTypeId === next.communicationTypeId), 'optionalAccess', _13 => _13.consented]), () => ( false))
671
529
  })),
672
530
  { shouldDirty: false }
673
531
  );
@@ -689,12 +547,12 @@ function BookingForm({
689
547
  });
690
548
  });
691
549
  const submit = (event) => {
692
- if (consentMissing) setConsentError(_nullishCoalesce(_optionalChain([consent, 'optionalAccess', _18 => _18.errorMessage]), () => ( "Please agree to continue.")));
550
+ if (consentMissing) setConsentError(_nullishCoalesce(_optionalChain([consent, 'optionalAccess', _14 => _14.errorMessage]), () => ( "Please agree to continue.")));
693
551
  return submitValid(event);
694
552
  };
695
553
  const fieldError = (name) => {
696
- const err = _optionalChain([errors, 'access', _19 => _19.formFields, 'optionalAccess', _20 => _20[name]]);
697
- return _optionalChain([err, 'optionalAccess', _21 => _21.message]);
554
+ const err = _optionalChain([errors, 'access', _15 => _15.formFields, 'optionalAccess', _16 => _16[name]]);
555
+ return _optionalChain([err, 'optionalAccess', _17 => _17.message]);
698
556
  };
699
557
  const renderField = (field, where) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkQVSVRG7Icjs.FieldWrapper, { label: field.label, htmlFor: where.id, required: field.required, error: where.error, children: FIELD_CONTROLS[field.type]({
700
558
  field,
@@ -707,7 +565,7 @@ function BookingForm({
707
565
  const builtInFields = Object.fromEntries(
708
566
  BUILT_IN_BOOKING_FIELDS.map((field) => [
709
567
  field.name,
710
- renderField(field, { id: builtInId(field.name), registerName: field.name, error: _optionalChain([errors, 'access', _22 => _22[field.name], 'optionalAccess', _23 => _23.message]) })
568
+ renderField(field, { id: builtInId(field.name), registerName: field.name, error: _optionalChain([errors, 'access', _18 => _18[field.name], 'optionalAccess', _19 => _19.message]) })
711
569
  ])
712
570
  );
713
571
  const renderDeclaredField = (field) => renderField(field, {
@@ -768,7 +626,7 @@ function BookingForm({
768
626
  // box doesn't shove the submit button down the card. With no error the
769
627
  // wrapper is `display:contents` and the panel below is the flex item,
770
628
  // exactly as it was.
771
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkQVSVRG7Icjs.FieldWrapper, { error: _optionalChain([errors, 'access', _24 => _24.legalConsentResponses, 'optionalAccess', _25 => _25.message]), children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-[var(--spacing-system-xs)]", children: [
629
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkQVSVRG7Icjs.FieldWrapper, { error: _optionalChain([errors, 'access', _20 => _20.legalConsentResponses, 'optionalAccess', _21 => _21.message]), children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-[var(--spacing-system-xs)]", children: [
772
630
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-ods-text-secondary text-h6", children: legalConsent.processingConsentText }),
773
631
  legalConsent.communicationConsentText && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-ods-text-secondary text-h6", children: legalConsent.communicationConsentText }),
774
632
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
@@ -787,7 +645,7 @@ function BookingForm({
787
645
  _chunk6FD7ZEBYcjs.CheckboxBlock,
788
646
  {
789
647
  id: `ms-consent-${box.communicationTypeId}`,
790
- checked: _nullishCoalesce(_optionalChain([current, 'optionalAccess', _26 => _26.consented]), () => ( false)),
648
+ checked: _nullishCoalesce(_optionalChain([current, 'optionalAccess', _22 => _22.consented]), () => ( false)),
791
649
  onCheckedChange: (v) => rhf.onChange(
792
650
  responses.map(
793
651
  (r) => r.communicationTypeId === box.communicationTypeId ? { ...r, consented: v } : r
@@ -882,7 +740,7 @@ function zoneLabel(tz) {
882
740
  timeZone: tz,
883
741
  timeZoneName: "shortOffset"
884
742
  }).formatToParts(/* @__PURE__ */ new Date());
885
- const offset = _nullishCoalesce(_optionalChain([parts, 'access', _27 => _27.find, 'call', _28 => _28((p) => p.type === "timeZoneName"), 'optionalAccess', _29 => _29.value]), () => ( ""));
743
+ const offset = _nullishCoalesce(_optionalChain([parts, 'access', _23 => _23.find, 'call', _24 => _24((p) => p.type === "timeZoneName"), 'optionalAccess', _25 => _25.value]), () => ( ""));
886
744
  return offset ? `${tz.replace(/_/g, " ")} (${offset})` : tz.replace(/_/g, " ");
887
745
  } catch (e4) {
888
746
  return tz.replace(/_/g, " ");
@@ -1009,7 +867,7 @@ function SchedulerContextPanel({
1009
867
  value: timezone,
1010
868
  disabled,
1011
869
  onChange: (tz) => {
1012
- if (tz) _optionalChain([onTimezoneChange, 'optionalCall', _30 => _30(tz)]);
870
+ if (tz) _optionalChain([onTimezoneChange, 'optionalCall', _26 => _26(tz)]);
1013
871
  },
1014
872
  options: zoneOptions,
1015
873
  placeholder: "Search timezone\u2026",
@@ -1093,7 +951,7 @@ function DayCalendar({ monthOffset, onMonthOffsetChange, selectedDay, onSelectDa
1093
951
  const startMonth = new Date(now.getFullYear(), now.getMonth(), 1);
1094
952
  const endMonth = new Date(now.getFullYear(), now.getMonth() + _chunk6FD7ZEBYcjs.MAX_MONTH_OFFSET + 1, 0);
1095
953
  const visibleMonth = new Date(now.getFullYear(), now.getMonth() + monthOffset, 1);
1096
- const dayHasNoSlots = _react.useCallback.call(void 0, (day) => !_optionalChain([slotsByDay, 'optionalAccess', _31 => _31.has, 'call', _32 => _32(calendarDayKey(day))]), [slotsByDay]);
954
+ const dayHasNoSlots = _react.useCallback.call(void 0, (day) => !_optionalChain([slotsByDay, 'optionalAccess', _27 => _27.has, 'call', _28 => _28(calendarDayKey(day))]), [slotsByDay]);
1097
955
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex min-h-0 flex-1 flex-col", "aria-busy": slotsByDay === null, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1098
956
  _chunk6FD7ZEBYcjs.DatePickerCalendar,
1099
957
  {
@@ -1111,7 +969,7 @@ function DayCalendar({ monthOffset, onMonthOffsetChange, selectedDay, onSelectDa
1111
969
  const day = value;
1112
970
  if (!day) return;
1113
971
  const key = calendarDayKey(day);
1114
- if (_optionalChain([slotsByDay, 'optionalAccess', _33 => _33.has, 'call', _34 => _34(key)])) onSelectDay(key);
972
+ if (_optionalChain([slotsByDay, 'optionalAccess', _29 => _29.has, 'call', _30 => _30(key)])) onSelectDay(key);
1115
973
  },
1116
974
  disabledDays: slotsByDay === null ? DISABLE_EVERY_DAY : dayHasNoSlots
1117
975
  }
@@ -1335,7 +1193,7 @@ function MeetingSchedulerDirectory({
1335
1193
  };
1336
1194
  }, [initialData, includeAll, apiBaseUrl]);
1337
1195
  const rows = _react.useMemo.call(void 0, () => {
1338
- const purposes = _nullishCoalesce(_optionalChain([data, 'optionalAccess', _35 => _35.purposes]), () => ( []));
1196
+ const purposes = _nullishCoalesce(_optionalChain([data, 'optionalAccess', _31 => _31.purposes]), () => ( []));
1339
1197
  return purposes.flatMap((p) => p.links.map((link) => ({ link, audienceLabel: p.label })));
1340
1198
  }, [data]);
1341
1199
  const totalPages = _chunkVTYP25OWcjs.pageCount.call(void 0, rows.length, pageSize);
@@ -1435,7 +1293,7 @@ function SchedulerDegradedCard({
1435
1293
  ] });
1436
1294
  }
1437
1295
  function isNativelyBookable(availability) {
1438
- if (availability.formFields.some(blocksNativeBooking)) return false;
1296
+ if (!availability.formFields.every(isSupportedFormField)) return false;
1439
1297
  const consent = availability.legalConsent;
1440
1298
  if (consent) {
1441
1299
  if (typeof consent.processingConsentText !== "string") return false;
@@ -1491,7 +1349,7 @@ function HubSpotMeetingScheduler({
1491
1349
  onStageChangeRef.current = onStageChange;
1492
1350
  });
1493
1351
  _react.useEffect.call(void 0, () => {
1494
- _optionalChain([onStageChangeRef, 'access', _36 => _36.current, 'optionalCall', _37 => _37(stage)]);
1352
+ _optionalChain([onStageChangeRef, 'access', _32 => _32.current, 'optionalCall', _33 => _33(stage)]);
1495
1353
  }, [stage]);
1496
1354
  const [stash, setStash] = _react.useState.call(void 0, null);
1497
1355
  const inFlightRef = _react.useRef.call(void 0, false);
@@ -1522,8 +1380,8 @@ function HubSpotMeetingScheduler({
1522
1380
  _react.useEffect.call(void 0, () => {
1523
1381
  autoAdvanceCount.current = 0;
1524
1382
  }, [meetingId]);
1525
- const durations = _react.useMemo.call(void 0, () => _nullishCoalesce(_optionalChain([availability, 'optionalAccess', _38 => _38.durationsMs]), () => ( [])), [_optionalChain([availability, 'optionalAccess', _39 => _39.durationsMs])]);
1526
- const shownHosts = _nullishCoalesce(_nullishCoalesce(hosts, () => ( _optionalChain([availability, 'optionalAccess', _40 => _40.hosts]))), () => ( []));
1383
+ const durations = _react.useMemo.call(void 0, () => _nullishCoalesce(_optionalChain([availability, 'optionalAccess', _34 => _34.durationsMs]), () => ( [])), [_optionalChain([availability, 'optionalAccess', _35 => _35.durationsMs])]);
1384
+ const shownHosts = _nullishCoalesce(_nullishCoalesce(hosts, () => ( _optionalChain([availability, 'optionalAccess', _36 => _36.hosts]))), () => ( []));
1527
1385
  const durationMs = _nullishCoalesce(_nullishCoalesce(pickedDurationMs, () => ( durations[0])), () => ( null));
1528
1386
  const slots = _react.useMemo.call(void 0, () => {
1529
1387
  if (!availability || durationMs == null) return [];
@@ -1582,7 +1440,7 @@ function HubSpotMeetingScheduler({
1582
1440
  if (result.ok && result.confirmation) {
1583
1441
  setConfirmation(result.confirmation);
1584
1442
  setStep("confirmed");
1585
- _optionalChain([onBooked, 'optionalCall', _41 => _41(result.confirmation)]);
1443
+ _optionalChain([onBooked, 'optionalCall', _37 => _37(result.confirmation)]);
1586
1444
  return;
1587
1445
  }
1588
1446
  const code = _nullishCoalesce(result.code, () => ( "TEMPORARILY_UNAVAILABLE"));
@@ -1630,8 +1488,8 @@ function HubSpotMeetingScheduler({
1630
1488
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: stepPanelClass, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1631
1489
  BookingFormSkeleton,
1632
1490
  {
1633
- fieldRows: _optionalChain([detailsFormProps, 'optionalAccess', _42 => _42.fieldRows]),
1634
- consent: Boolean(_optionalChain([detailsFormProps, 'optionalAccess', _43 => _43.consent])),
1491
+ fieldRows: _optionalChain([detailsFormProps, 'optionalAccess', _38 => _38.fieldRows]),
1492
+ consent: Boolean(_optionalChain([detailsFormProps, 'optionalAccess', _39 => _39.consent])),
1635
1493
  footerNote: preset.footerNote
1636
1494
  }
1637
1495
  ) })
@@ -1692,7 +1550,7 @@ function HubSpotMeetingScheduler({
1692
1550
  deferSlot: detailsFirst,
1693
1551
  submitLabel: preset.submitLabel,
1694
1552
  footerNote: preset.footerNote,
1695
- initialValues: detailsFirst ? _optionalChain([stash, 'optionalAccess', _44 => _44.payload]) : void 0,
1553
+ initialValues: detailsFirst ? _optionalChain([stash, 'optionalAccess', _40 => _40.payload]) : void 0,
1696
1554
  isSubmitting,
1697
1555
  onSubmit: detailsFirst ? stashDetails : handleSubmit,
1698
1556
  honeypotInputProps,