@cimplify/sdk 0.47.0 → 0.48.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.
package/dist/react.js CHANGED
@@ -15,6 +15,9 @@ var radioGroup = require('@base-ui/react/radio-group');
15
15
  var radio = require('@base-ui/react/radio');
16
16
  var checkbox = require('@base-ui/react/checkbox');
17
17
  var button = require('@base-ui/react/button');
18
+ var popover = require('@base-ui/react/popover');
19
+ var reactDayPicker = require('react-day-picker');
20
+ var dateFns = require('date-fns');
18
21
  var tabs = require('@base-ui/react/tabs');
19
22
  var dialog = require('@base-ui/react/dialog');
20
23
  var field = require('@base-ui/react/field');
@@ -1338,16 +1341,10 @@ function useCimplifyClient() {
1338
1341
  function useOptionalCimplifyClient() {
1339
1342
  return React10.useContext(CimplifyClientContext);
1340
1343
  }
1341
- var SPACE = { sm: 8};
1342
- function shellColors(isDark, primaryColor) {
1344
+ function shellColors(isDark) {
1343
1345
  return {
1344
- text: isDark ? "#f4f4f5" : "#1a1a1a",
1345
1346
  textSecondary: isDark ? "#a1a1aa" : "#52525b",
1346
- textMuted: isDark ? "#71717a" : "#a1a1aa",
1347
- border: isDark ? "#27272a" : "#e4e4e7",
1348
- surface: isDark ? "#18181b" : "#fafafa",
1349
- error: "#dc2626",
1350
- primary: primaryColor
1347
+ error: "#dc2626"
1351
1348
  };
1352
1349
  }
1353
1350
  function statusToLabel(status) {
@@ -1432,7 +1429,6 @@ function CimplifyCheckout({
1432
1429
  fxOptionsRef.current = fxOptions;
1433
1430
  const resolvedCartRef = React10.useRef(resolvedCart);
1434
1431
  resolvedCartRef.current = resolvedCart;
1435
- const primaryColor = appearance?.variables?.primaryColor || "#0a2540";
1436
1432
  const isDark = appearance?.theme === "dark";
1437
1433
  const emitStatus = React10__default.default.useEffectEvent(
1438
1434
  (nextStatus, context = {}) => {
@@ -1635,7 +1631,7 @@ function CimplifyCheckout({
1635
1631
  checkoutElement.setCart(transformToCheckoutCart(resolvedCart, fxOptions));
1636
1632
  }
1637
1633
  }, [resolvedCart, fxOptions]);
1638
- const colors = shellColors(isDark ?? false, primaryColor);
1634
+ const colors = shellColors(isDark ?? false);
1639
1635
  if (isInitializing) {
1640
1636
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className, "data-cimplify-checkout": "", children: /* @__PURE__ */ jsxRuntime.jsx("p", { "data-cimplify-status": "", style: { fontSize: 13, color: colors.textSecondary }, children: "Preparing checkout..." }) });
1641
1637
  }
@@ -1657,8 +1653,8 @@ function CimplifyCheckout({
1657
1653
  }
1658
1654
  ),
1659
1655
  /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-section": "checkout", children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: checkoutMountRef }) }),
1660
- status && /* @__PURE__ */ jsxRuntime.jsx("p", { "data-cimplify-status": "", style: { marginTop: SPACE.sm, fontSize: 13, color: colors.textSecondary }, children: statusText || statusToLabel(status) }),
1661
- errorMessage && /* @__PURE__ */ jsxRuntime.jsx("p", { "data-cimplify-error": "", style: { marginTop: SPACE.sm, fontSize: 13, color: colors.error }, children: errorMessage })
1656
+ status && /* @__PURE__ */ jsxRuntime.jsx("p", { "data-cimplify-status": "", style: { marginTop: 8, fontSize: 13, color: colors.textSecondary }, children: statusText || statusToLabel(status) }),
1657
+ errorMessage && /* @__PURE__ */ jsxRuntime.jsx("p", { "data-cimplify-error": "", style: { marginTop: 8, fontSize: 13, color: colors.error }, children: errorMessage })
1662
1658
  ] });
1663
1659
  }
1664
1660
  function cn(...inputs) {
@@ -5006,6 +5002,262 @@ function VolumePricing({
5006
5002
  }
5007
5003
  );
5008
5004
  }
5005
+ function parseValue(value) {
5006
+ if (!value) return void 0;
5007
+ const date = dateFns.parseISO(value);
5008
+ return dateFns.isValid(date) ? date : void 0;
5009
+ }
5010
+ function formatValue(date) {
5011
+ return dateFns.format(date, "yyyy-MM-dd");
5012
+ }
5013
+ function DatePicker({
5014
+ value,
5015
+ onChange,
5016
+ placeholder = "Select a date",
5017
+ minDate,
5018
+ maxDate,
5019
+ disabled,
5020
+ triggerDisabled,
5021
+ name,
5022
+ required,
5023
+ className,
5024
+ classNames,
5025
+ "aria-label": ariaLabel
5026
+ }) {
5027
+ const [open, setOpen] = React10.useState(false);
5028
+ const selected = parseValue(value);
5029
+ const disabledMatchers = [];
5030
+ if (minDate) disabledMatchers.push({ before: minDate });
5031
+ if (maxDate) disabledMatchers.push({ after: maxDate });
5032
+ if (Array.isArray(disabled)) {
5033
+ disabledMatchers.push(...disabled);
5034
+ } else if (disabled) {
5035
+ disabledMatchers.push(disabled);
5036
+ }
5037
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-date-picker": true, className: cn(className, classNames?.root), children: [
5038
+ /* @__PURE__ */ jsxRuntime.jsxs(popover.Popover.Root, { open, onOpenChange: setOpen, children: [
5039
+ /* @__PURE__ */ jsxRuntime.jsxs(
5040
+ popover.Popover.Trigger,
5041
+ {
5042
+ type: "button",
5043
+ "aria-label": ariaLabel ?? placeholder,
5044
+ disabled: triggerDisabled,
5045
+ className: cn(
5046
+ "w-full inline-flex items-center justify-between gap-2 rounded-md border border-input bg-background px-3 py-2 text-left text-sm transition-colors hover:bg-muted/40 focus:outline-none focus:ring-2 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
5047
+ classNames?.trigger
5048
+ ),
5049
+ children: [
5050
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(!selected && "text-muted-foreground"), children: selected ? dateFns.format(selected, "EEE, MMM d, yyyy") : placeholder }),
5051
+ /* @__PURE__ */ jsxRuntime.jsxs(
5052
+ "svg",
5053
+ {
5054
+ width: "16",
5055
+ height: "16",
5056
+ viewBox: "0 0 24 24",
5057
+ fill: "none",
5058
+ stroke: "currentColor",
5059
+ strokeWidth: "2",
5060
+ strokeLinecap: "round",
5061
+ strokeLinejoin: "round",
5062
+ "aria-hidden": "true",
5063
+ className: "shrink-0 text-muted-foreground",
5064
+ children: [
5065
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "3", y: "4", width: "18", height: "18", rx: "2" }),
5066
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "16", y1: "2", x2: "16", y2: "6" }),
5067
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "8", y1: "2", x2: "8", y2: "6" }),
5068
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "3", y1: "10", x2: "21", y2: "10" })
5069
+ ]
5070
+ }
5071
+ )
5072
+ ]
5073
+ }
5074
+ ),
5075
+ /* @__PURE__ */ jsxRuntime.jsx(popover.Popover.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(popover.Popover.Positioner, { sideOffset: 6, align: "start", children: /* @__PURE__ */ jsxRuntime.jsx(
5076
+ popover.Popover.Popup,
5077
+ {
5078
+ className: cn(
5079
+ "z-50 rounded-lg border border-border bg-background p-3 shadow-lg outline-none",
5080
+ classNames?.popup
5081
+ ),
5082
+ children: /* @__PURE__ */ jsxRuntime.jsx(
5083
+ reactDayPicker.DayPicker,
5084
+ {
5085
+ mode: "single",
5086
+ selected,
5087
+ onSelect: (date) => {
5088
+ onChange?.(date ? formatValue(date) : "");
5089
+ if (date) setOpen(false);
5090
+ },
5091
+ disabled: disabledMatchers.length > 0 ? disabledMatchers : void 0,
5092
+ showOutsideDays: true,
5093
+ weekStartsOn: 0,
5094
+ className: cn("p-0", classNames?.calendar),
5095
+ classNames: {
5096
+ months: "flex flex-col gap-3",
5097
+ month: "flex flex-col gap-3",
5098
+ caption: "flex items-center justify-between px-1",
5099
+ caption_label: "text-sm font-semibold",
5100
+ nav: "flex items-center gap-1",
5101
+ nav_button: "inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground hover:bg-muted transition-colors",
5102
+ table: "w-full border-collapse",
5103
+ head_row: "flex",
5104
+ head_cell: "w-9 text-center text-[10px] font-medium uppercase tracking-wider text-muted-foreground",
5105
+ row: "flex w-full mt-1",
5106
+ cell: "w-9 h-9 text-center text-sm p-0 relative",
5107
+ day: cn(
5108
+ "inline-flex h-9 w-9 items-center justify-center rounded-md text-sm font-normal text-foreground hover:bg-muted transition-colors",
5109
+ "aria-selected:bg-foreground aria-selected:text-background aria-selected:hover:bg-foreground/90"
5110
+ ),
5111
+ day_selected: cn(
5112
+ "bg-foreground text-background hover:bg-foreground/90 focus:bg-foreground",
5113
+ classNames?.daySelected
5114
+ ),
5115
+ day_today: cn(
5116
+ "ring-1 ring-inset ring-primary/40",
5117
+ classNames?.dayToday
5118
+ ),
5119
+ day_outside: "text-muted-foreground/50",
5120
+ day_disabled: cn(
5121
+ "text-muted-foreground/40 cursor-not-allowed line-through",
5122
+ classNames?.dayDisabled
5123
+ )
5124
+ }
5125
+ }
5126
+ )
5127
+ }
5128
+ ) }) })
5129
+ ] }),
5130
+ name ? /* @__PURE__ */ jsxRuntime.jsx("input", { type: "hidden", name, value: value ?? "", required }) : null
5131
+ ] });
5132
+ }
5133
+ function parseHHmm(value) {
5134
+ if (!value) return null;
5135
+ const match = /^(\d{1,2}):(\d{2})$/.exec(value);
5136
+ if (!match) return null;
5137
+ const hour = Number.parseInt(match[1] ?? "", 10);
5138
+ const minute = Number.parseInt(match[2] ?? "", 10);
5139
+ if (Number.isNaN(hour) || Number.isNaN(minute)) return null;
5140
+ if (hour < 0 || hour > 23 || minute < 0 || minute > 59) return null;
5141
+ return { hour, minute };
5142
+ }
5143
+ function formatHHmm(hour, minute) {
5144
+ return `${String(hour).padStart(2, "0")}:${String(minute).padStart(2, "0")}`;
5145
+ }
5146
+ function formatDisplay(hour, minute, displayFormat) {
5147
+ if (displayFormat === "24h") {
5148
+ return formatHHmm(hour, minute);
5149
+ }
5150
+ const period = hour >= 12 ? "PM" : "AM";
5151
+ const displayHour = hour % 12 || 12;
5152
+ return `${displayHour}:${String(minute).padStart(2, "0")} ${period}`;
5153
+ }
5154
+ function buildOptions(minTime, maxTime, stepMinutes) {
5155
+ const min = parseHHmm(minTime) ?? { hour: 0, minute: 0 };
5156
+ const max = parseHHmm(maxTime) ?? { hour: 23, minute: 59 };
5157
+ const minTotal = min.hour * 60 + min.minute;
5158
+ const maxTotal = max.hour * 60 + max.minute;
5159
+ const step = Math.max(1, stepMinutes);
5160
+ const out = [];
5161
+ for (let total = minTotal; total <= maxTotal; total += step) {
5162
+ out.push(formatHHmm(Math.floor(total / 60), total % 60));
5163
+ }
5164
+ return out;
5165
+ }
5166
+ function TimePicker({
5167
+ value,
5168
+ onChange,
5169
+ placeholder = "Select a time",
5170
+ minTime = "00:00",
5171
+ maxTime = "23:30",
5172
+ stepMinutes = 30,
5173
+ displayFormat = "12h",
5174
+ triggerDisabled,
5175
+ name,
5176
+ required,
5177
+ className,
5178
+ classNames,
5179
+ "aria-label": ariaLabel
5180
+ }) {
5181
+ const [open, setOpen] = React10.useState(false);
5182
+ const parsed = parseHHmm(value);
5183
+ const options = React10.useMemo(
5184
+ () => buildOptions(minTime, maxTime, stepMinutes),
5185
+ [minTime, maxTime, stepMinutes]
5186
+ );
5187
+ const triggerLabel = parsed ? formatDisplay(parsed.hour, parsed.minute, displayFormat) : placeholder;
5188
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-time-picker": true, className: cn(className, classNames?.root), children: [
5189
+ /* @__PURE__ */ jsxRuntime.jsxs(popover.Popover.Root, { open, onOpenChange: setOpen, children: [
5190
+ /* @__PURE__ */ jsxRuntime.jsxs(
5191
+ popover.Popover.Trigger,
5192
+ {
5193
+ type: "button",
5194
+ "aria-label": ariaLabel ?? placeholder,
5195
+ disabled: triggerDisabled,
5196
+ className: cn(
5197
+ "w-full inline-flex items-center justify-between gap-2 rounded-md border border-input bg-background px-3 py-2 text-left text-sm transition-colors hover:bg-muted/40 focus:outline-none focus:ring-2 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
5198
+ classNames?.trigger
5199
+ ),
5200
+ children: [
5201
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(!parsed && "text-muted-foreground"), children: triggerLabel }),
5202
+ /* @__PURE__ */ jsxRuntime.jsxs(
5203
+ "svg",
5204
+ {
5205
+ width: "16",
5206
+ height: "16",
5207
+ viewBox: "0 0 24 24",
5208
+ fill: "none",
5209
+ stroke: "currentColor",
5210
+ strokeWidth: "2",
5211
+ strokeLinecap: "round",
5212
+ strokeLinejoin: "round",
5213
+ "aria-hidden": "true",
5214
+ className: "shrink-0 text-muted-foreground",
5215
+ children: [
5216
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "9" }),
5217
+ /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "12 7 12 12 15 14" })
5218
+ ]
5219
+ }
5220
+ )
5221
+ ]
5222
+ }
5223
+ ),
5224
+ /* @__PURE__ */ jsxRuntime.jsx(popover.Popover.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(popover.Popover.Positioner, { sideOffset: 6, align: "start", children: /* @__PURE__ */ jsxRuntime.jsx(
5225
+ popover.Popover.Popup,
5226
+ {
5227
+ className: cn(
5228
+ "z-50 max-h-64 overflow-y-auto rounded-lg border border-border bg-background p-1 shadow-lg outline-none",
5229
+ classNames?.popup
5230
+ ),
5231
+ children: /* @__PURE__ */ jsxRuntime.jsx("ul", { role: "listbox", "aria-label": ariaLabel ?? placeholder, className: "flex flex-col", children: options.map((option) => {
5232
+ const isSelected = option === value;
5233
+ const opt = parseHHmm(option);
5234
+ if (!opt) return null;
5235
+ return /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsx(
5236
+ "button",
5237
+ {
5238
+ type: "button",
5239
+ role: "option",
5240
+ "aria-selected": isSelected,
5241
+ onClick: () => {
5242
+ onChange?.(option);
5243
+ setOpen(false);
5244
+ },
5245
+ className: cn(
5246
+ "w-full rounded-md px-3 py-2 text-left text-sm transition-colors hover:bg-muted",
5247
+ isSelected && "bg-foreground text-background hover:bg-foreground/90",
5248
+ classNames?.option,
5249
+ isSelected && classNames?.optionSelected
5250
+ ),
5251
+ children: formatDisplay(opt.hour, opt.minute, displayFormat)
5252
+ }
5253
+ ) }, option);
5254
+ }) })
5255
+ }
5256
+ ) }) })
5257
+ ] }),
5258
+ name ? /* @__PURE__ */ jsxRuntime.jsx("input", { type: "hidden", name, value: value ?? "", required }) : null
5259
+ ] });
5260
+ }
5009
5261
  function CustomerInputFields({
5010
5262
  fields,
5011
5263
  values,
@@ -5192,13 +5444,13 @@ function FieldInput({
5192
5444
  );
5193
5445
  case chunkMN4PNKJA_js.INPUT_FIELD_TYPE.Date:
5194
5446
  return /* @__PURE__ */ jsxRuntime.jsx(
5195
- "input",
5447
+ DatePicker,
5196
5448
  {
5197
- type: "date",
5198
5449
  value: typeof value === "string" ? value : "",
5199
- onChange: (e) => onValueChange(e.target.value || void 0),
5450
+ onChange: (next) => onValueChange(next || void 0),
5200
5451
  required: field.is_required,
5201
- className: inputClass
5452
+ placeholder: field.placeholder ?? "Select a date",
5453
+ "aria-label": field.name
5202
5454
  }
5203
5455
  );
5204
5456
  case chunkMN4PNKJA_js.INPUT_FIELD_TYPE.File:
@@ -5226,34 +5478,53 @@ function FieldInput({
5226
5478
  }
5227
5479
  );
5228
5480
  case chunkMN4PNKJA_js.INPUT_FIELD_TYPE.DateTime: {
5229
- const dtLocalValue = typeof value === "string" && value.includes("T") ? value.slice(0, 16) : typeof value === "string" ? value : "";
5230
- return /* @__PURE__ */ jsxRuntime.jsx(
5231
- "input",
5232
- {
5233
- type: "datetime-local",
5234
- value: dtLocalValue,
5235
- onChange: (e) => {
5236
- if (!e.target.value) {
5237
- onValueChange(void 0);
5238
- return;
5239
- }
5240
- const date = new Date(e.target.value);
5241
- onValueChange(Number.isNaN(date.getTime()) ? e.target.value : date.toISOString());
5242
- },
5243
- required: field.is_required,
5244
- className: inputClass
5481
+ const stringValue = typeof value === "string" ? value : "";
5482
+ const [datePart, timePartRaw] = stringValue.includes("T") ? stringValue.split("T", 2) : [stringValue, ""];
5483
+ const timePart = (timePartRaw ?? "").slice(0, 5);
5484
+ const commit = (nextDate, nextTime) => {
5485
+ if (!nextDate && !nextTime) {
5486
+ onValueChange(void 0);
5487
+ return;
5245
5488
  }
5246
- );
5489
+ if (!nextDate) {
5490
+ onValueChange(`${nextTime}`);
5491
+ return;
5492
+ }
5493
+ const combined = `${nextDate}T${nextTime || "00:00"}`;
5494
+ const parsed = new Date(combined);
5495
+ onValueChange(Number.isNaN(parsed.getTime()) ? combined : parsed.toISOString());
5496
+ };
5497
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-[1fr_auto] gap-2", children: [
5498
+ /* @__PURE__ */ jsxRuntime.jsx(
5499
+ DatePicker,
5500
+ {
5501
+ value: datePart ?? "",
5502
+ onChange: (next) => commit(next, timePart),
5503
+ placeholder: field.placeholder ?? "Select a date",
5504
+ "aria-label": `${field.name} date`,
5505
+ required: field.is_required
5506
+ }
5507
+ ),
5508
+ /* @__PURE__ */ jsxRuntime.jsx(
5509
+ TimePicker,
5510
+ {
5511
+ value: timePart,
5512
+ onChange: (next) => commit(datePart ?? "", next),
5513
+ placeholder: "Time",
5514
+ "aria-label": `${field.name} time`
5515
+ }
5516
+ )
5517
+ ] });
5247
5518
  }
5248
5519
  case chunkMN4PNKJA_js.INPUT_FIELD_TYPE.Time:
5249
5520
  return /* @__PURE__ */ jsxRuntime.jsx(
5250
- "input",
5521
+ TimePicker,
5251
5522
  {
5252
- type: "time",
5253
5523
  value: typeof value === "string" ? value : "",
5254
- onChange: (e) => onValueChange(e.target.value || void 0),
5524
+ onChange: (next) => onValueChange(next || void 0),
5255
5525
  required: field.is_required,
5256
- className: inputClass
5526
+ placeholder: field.placeholder ?? "Select a time",
5527
+ "aria-label": field.name
5257
5528
  }
5258
5529
  );
5259
5530
  case chunkMN4PNKJA_js.INPUT_FIELD_TYPE.MultiSelect:
@@ -5273,8 +5544,7 @@ function FieldInput({
5273
5544
  field,
5274
5545
  value,
5275
5546
  onValueChange,
5276
- classNames,
5277
- inputClass
5547
+ classNames
5278
5548
  }
5279
5549
  );
5280
5550
  case chunkMN4PNKJA_js.INPUT_FIELD_TYPE.Address:
@@ -5443,38 +5713,39 @@ function DateRangeInput({
5443
5713
  field,
5444
5714
  value,
5445
5715
  onValueChange,
5446
- classNames,
5447
- inputClass
5716
+ classNames
5448
5717
  }) {
5449
5718
  const range = value && typeof value === "object" ? value : {};
5450
5719
  const update = (key, v) => {
5451
5720
  const next = { ...range, [key]: v };
5452
5721
  onValueChange(next.start || next.end ? next : void 0);
5453
5722
  };
5454
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("grid grid-cols-2 gap-3", classNames?.dateRangeInput), children: [
5723
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("grid grid-cols-1 sm:grid-cols-2 gap-3", classNames?.dateRangeInput), children: [
5455
5724
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
5456
5725
  /* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-xs text-muted-foreground mb-1 block", children: "Start" }),
5457
5726
  /* @__PURE__ */ jsxRuntime.jsx(
5458
- "input",
5727
+ DatePicker,
5459
5728
  {
5460
- type: "date",
5461
5729
  value: range.start || "",
5462
- onChange: (e) => update("start", e.target.value),
5730
+ onChange: (next) => update("start", next),
5463
5731
  required: field.is_required,
5464
- className: inputClass
5732
+ placeholder: "Start date",
5733
+ "aria-label": `${field.name} start date`,
5734
+ maxDate: range.end ? /* @__PURE__ */ new Date(`${range.end}T00:00`) : void 0
5465
5735
  }
5466
5736
  )
5467
5737
  ] }),
5468
5738
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
5469
5739
  /* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-xs text-muted-foreground mb-1 block", children: "End" }),
5470
5740
  /* @__PURE__ */ jsxRuntime.jsx(
5471
- "input",
5741
+ DatePicker,
5472
5742
  {
5473
- type: "date",
5474
5743
  value: range.end || "",
5475
- onChange: (e) => update("end", e.target.value),
5744
+ onChange: (next) => update("end", next),
5476
5745
  required: field.is_required,
5477
- className: inputClass
5746
+ placeholder: "End date",
5747
+ "aria-label": `${field.name} end date`,
5748
+ minDate: range.start ? /* @__PURE__ */ new Date(`${range.start}T00:00`) : void 0
5478
5749
  }
5479
5750
  )
5480
5751
  ] })
@@ -5918,6 +6189,39 @@ function formatTime(timeStr) {
5918
6189
  }
5919
6190
  return timeStr;
5920
6191
  }
6192
+ function pluralizeUnit(unit, value) {
6193
+ if (!unit) return value === 1 ? "day" : "days";
6194
+ const v = value ?? 1;
6195
+ if (unit === "minutes") return v === 1 ? "minute" : "minutes";
6196
+ if (unit === "hours") return v === 1 ? "hour" : "hours";
6197
+ if (unit === "days") return v === 1 ? "day" : "days";
6198
+ if (unit === "weeks") return v === 1 ? "week" : "weeks";
6199
+ if (unit === "months") return v === 1 ? "month" : "months";
6200
+ return unit;
6201
+ }
6202
+ function formatStaySummary(slot, durationUnit, durationValue) {
6203
+ const start = new Date(slot.start_time);
6204
+ const end = new Date(slot.end_time);
6205
+ const startLabel = start.toLocaleString(void 0, {
6206
+ weekday: "short",
6207
+ month: "short",
6208
+ day: "numeric",
6209
+ hour: "numeric",
6210
+ minute: "2-digit"
6211
+ });
6212
+ const endLabel = end.toLocaleString(void 0, {
6213
+ weekday: "short",
6214
+ month: "short",
6215
+ day: "numeric",
6216
+ hour: "numeric",
6217
+ minute: "2-digit"
6218
+ });
6219
+ const unitLabel = pluralizeUnit(durationUnit, durationValue);
6220
+ if (durationValue !== void 0) {
6221
+ return `${durationValue} ${unitLabel}: ${startLabel} \u2192 ${endLabel}`;
6222
+ }
6223
+ return `${startLabel} \u2192 ${endLabel}`;
6224
+ }
5921
6225
  function slotToValue(slot) {
5922
6226
  return `${slot.start_time}|${slot.end_time}`;
5923
6227
  }
@@ -5930,10 +6234,14 @@ function SlotPicker({
5930
6234
  onSlotSelect,
5931
6235
  groupByTimeOfDay = true,
5932
6236
  showPrice = true,
6237
+ schedulingMode = "intraday",
6238
+ durationUnit,
6239
+ durationValue,
5933
6240
  emptyMessage = "No available slots",
5934
6241
  className,
5935
6242
  classNames
5936
6243
  }) {
6244
+ const isMultiDay = schedulingMode === "multi_day";
5937
6245
  const { slots: fetched, isLoading } = useAvailableSlots(
5938
6246
  serviceId ?? null,
5939
6247
  date ?? null,
@@ -5964,7 +6272,7 @@ function SlotPicker({
5964
6272
  }
5965
6273
  );
5966
6274
  }
5967
- const groups = groupByTimeOfDay ? groupSlots(slots) : [{ label: "", slots }];
6275
+ const groups = groupByTimeOfDay && !isMultiDay ? groupSlots(slots) : [{ label: "", slots }];
5968
6276
  const slotsByValue = /* @__PURE__ */ new Map();
5969
6277
  for (const slot of slots) {
5970
6278
  slotsByValue.set(slotToValue(slot), slot);
@@ -5997,7 +6305,7 @@ function SlotPicker({
5997
6305
  "data-unavailable": !slot.is_available || void 0,
5998
6306
  className: classNames?.slot,
5999
6307
  children: [
6000
- /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-slot-time": true, className: classNames?.slotTime, children: formatTime(slot.start_time) }),
6308
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-slot-time": true, className: classNames?.slotTime, children: isMultiDay ? formatStaySummary(slot, durationUnit, durationValue) : formatTime(slot.start_time) }),
6001
6309
  showPrice && slot.price && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-slot-price": true, className: classNames?.slotPrice, children: /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: slot.price }) })
6002
6310
  ]
6003
6311
  },
@@ -6028,6 +6336,9 @@ function DateSlotPicker({
6028
6336
  onSlotSelect,
6029
6337
  availability: availabilityProp,
6030
6338
  showPrice = true,
6339
+ schedulingMode,
6340
+ durationUnit,
6341
+ durationValue,
6031
6342
  className,
6032
6343
  classNames
6033
6344
  }) {
@@ -6145,7 +6456,10 @@ function DateSlotPicker({
6145
6456
  participantCount,
6146
6457
  selectedSlot,
6147
6458
  onSlotSelect: handleSlotSelect,
6148
- showPrice
6459
+ showPrice,
6460
+ schedulingMode,
6461
+ durationUnit,
6462
+ durationValue
6149
6463
  }
6150
6464
  ) })
6151
6465
  ]
@@ -13280,6 +13594,7 @@ exports.CompositeSelector = CompositeSelector;
13280
13594
  exports.CurrencySelector = CurrencySelector;
13281
13595
  exports.CustomAttributesTable = CustomAttributesTable;
13282
13596
  exports.CustomerInputFields = CustomerInputFields;
13597
+ exports.DatePicker = DatePicker;
13283
13598
  exports.DateSlotPicker = DateSlotPicker;
13284
13599
  exports.DealBanner = DealBanner;
13285
13600
  exports.DealsPage = DealsPage;
@@ -13337,6 +13652,7 @@ exports.StandardServiceCard = StandardServiceCard;
13337
13652
  exports.StoreNav = StoreNav;
13338
13653
  exports.SubscriptionCard = SubscriptionCard;
13339
13654
  exports.TagPills = TagPills;
13655
+ exports.TimePicker = TimePicker;
13340
13656
  exports.TwoColumnGrid = TwoColumnGrid;
13341
13657
  exports.VariantSelector = VariantSelector;
13342
13658
  exports.VolumePricing = VolumePricing;