@cimplify/sdk 0.46.3 → 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.
Files changed (39) hide show
  1. package/dist/advanced.d.mts +1 -1
  2. package/dist/advanced.d.ts +1 -1
  3. package/dist/advanced.js +20 -20
  4. package/dist/advanced.mjs +1 -1
  5. package/dist/{chunk-6HYKWYUF.mjs → chunk-24FK7VFL.mjs} +1 -1
  6. package/dist/{chunk-Z2MLAIID.js → chunk-CYGLTD7D.js} +35 -35
  7. package/dist/{chunk-TW4OFRWV.js → chunk-D22UVSFN.js} +2 -2
  8. package/dist/{chunk-7ZACMER7.js → chunk-DR4UPU6P.js} +0 -1
  9. package/dist/{chunk-WUIERJ6J.mjs → chunk-MBR2DBEN.mjs} +1 -1
  10. package/dist/{chunk-CKRMA5F7.mjs → chunk-OFNVLUH4.mjs} +0 -1
  11. package/dist/{client-QVINYu1X.d.ts → client-B8tJnOde.d.ts} +0 -1
  12. package/dist/{client-G2WCoxv2.d.mts → client-BZZK1txR.d.mts} +0 -1
  13. package/dist/{client-B76ZNW5r.d.ts → client-BdbvMtOU.d.ts} +1 -1
  14. package/dist/{client-CT9NwIDX.d.mts → client-BqCAm5vI.d.mts} +1 -1
  15. package/dist/index.d.mts +1 -1
  16. package/dist/index.d.ts +1 -1
  17. package/dist/index.js +61 -61
  18. package/dist/index.mjs +2 -2
  19. package/dist/react.d.mts +113 -10
  20. package/dist/react.d.ts +113 -10
  21. package/dist/react.js +420 -248
  22. package/dist/react.mjs +405 -235
  23. package/dist/server.d.mts +2 -2
  24. package/dist/server.d.ts +2 -2
  25. package/dist/server.js +3 -3
  26. package/dist/server.mjs +2 -2
  27. package/dist/styles.css +1 -1
  28. package/dist/testing/suite.d.mts +2 -2
  29. package/dist/testing/suite.d.ts +2 -2
  30. package/dist/testing/suite.js +22 -22
  31. package/dist/testing/suite.mjs +3 -3
  32. package/dist/testing.d.mts +2 -2
  33. package/dist/testing.d.ts +2 -2
  34. package/dist/testing.js +78 -78
  35. package/dist/testing.mjs +4 -4
  36. package/package.json +3 -1
  37. package/registry/customer-input-fields.json +1 -1
  38. package/registry/date-slot-picker.json +1 -1
  39. package/registry/slot-picker.json +1 -1
package/dist/react.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
  import { DURATION_UNIT, getVariantDisplayName, INPUT_FIELD_TYPE, PRODUCT_TYPE, RENDER_HINT } from './chunk-NRDRVZ62.mjs';
3
3
  export { getVariantDisplayName } from './chunk-NRDRVZ62.mjs';
4
- import { createCimplifyClient } from './chunk-WUIERJ6J.mjs';
5
- import { ELEMENT_TYPES, EVENT_TYPES } from './chunk-CKRMA5F7.mjs';
4
+ import { createCimplifyClient } from './chunk-MBR2DBEN.mjs';
5
+ import { ELEMENT_TYPES, EVENT_TYPES } from './chunk-OFNVLUH4.mjs';
6
6
  import { formatPrice, parsePrice, getUnitPriceAtQuantity, isOnSale, getDiscountPercentage, getBasePrice, getPriceRange, formatPriceRange } from './chunk-XY2DFX5K.mjs';
7
7
  import { isSupportedCurrency } from './chunk-Z2AYLZDF.mjs';
8
8
  import React10, { createContext, useRef, useState, useCallback, useEffect, useContext, useMemo, useId, useSyncExternalStore } from 'react';
@@ -14,6 +14,9 @@ import { RadioGroup } from '@base-ui/react/radio-group';
14
14
  import { Radio } from '@base-ui/react/radio';
15
15
  import { Checkbox } from '@base-ui/react/checkbox';
16
16
  import { Button } from '@base-ui/react/button';
17
+ import { Popover } from '@base-ui/react/popover';
18
+ import { DayPicker } from 'react-day-picker';
19
+ import { format, parseISO, isValid } from 'date-fns';
17
20
  import { Tabs } from '@base-ui/react/tabs';
18
21
  import { Dialog } from '@base-ui/react/dialog';
19
22
  import { Field } from '@base-ui/react/field';
@@ -621,7 +624,8 @@ function useCollectionStore(collection) {
621
624
  }
622
625
 
623
626
  // src/react/hooks/use-cart.ts
624
- var CART_STORAGE_PREFIX = "cimplify:cart:v3";
627
+ var LEGACY_CART_STORAGE_PREFIX = "cimplify:cart:v3";
628
+ var legacyCachesPurged = false;
625
629
  var cartStores = /* @__PURE__ */ new Map();
626
630
  var ROLLBACK_VISIBLE_DELAY_MS = 3e3;
627
631
  function clearAllCartStores() {
@@ -631,34 +635,35 @@ function clearAllCartStores() {
631
635
  clearTimeout(handle);
632
636
  }
633
637
  entry.failedOpRemovers.clear();
634
- if (entry.persistTimer) {
635
- clearTimeout(entry.persistTimer);
636
- entry.persistTimer = null;
637
- }
638
638
  }
639
639
  cartStores.clear();
640
640
  }
641
641
  function emptyBase(currency, isLoading = true) {
642
642
  return { items: [], subtotal: 0, tax: 0, total: 0, currency, isLoading };
643
643
  }
644
- function advanceBaseWithPatch(entry, patch) {
645
- const current = entry.collection.getBase() ?? emptyBase(entry.currency, false);
646
- entry.collection.setBase({ ...applyCartPatch(current, patch), isLoading: false });
647
- persistBase(entry);
648
- }
649
- function buildStoreKey(client, locationId, isDemoMode) {
644
+ function buildStoreKey(client, locationId) {
650
645
  return [
651
- client.getPublicKey() || "__demo__",
652
- locationId || "__no_location__",
653
- isDemoMode ? "demo" : "live"
646
+ client.getPublicKey() || "__no_public_key__",
647
+ locationId || "__no_location__"
654
648
  ].join(":");
655
649
  }
656
- function buildStorageKey(storeKey) {
657
- return `${CART_STORAGE_PREFIX}:${storeKey}`;
658
- }
659
- function stripInternalItemMetadata(item) {
660
- const { _lineKey, isOptimistic, ...rest } = item;
661
- return rest;
650
+ function purgeLegacyCartCachesOnce() {
651
+ if (legacyCachesPurged) return;
652
+ legacyCachesPurged = true;
653
+ if (typeof window === "undefined" || !window.localStorage) return;
654
+ try {
655
+ const keys = [];
656
+ for (let i = 0; i < window.localStorage.length; i += 1) {
657
+ const key = window.localStorage.key(i);
658
+ if (key && key.startsWith(LEGACY_CART_STORAGE_PREFIX)) {
659
+ keys.push(key);
660
+ }
661
+ }
662
+ for (const key of keys) {
663
+ window.localStorage.removeItem(key);
664
+ }
665
+ } catch {
666
+ }
662
667
  }
663
668
  function toProductFromServerItem(item, businessId) {
664
669
  return {
@@ -753,69 +758,13 @@ function deriveView(base, ops) {
753
758
  pendingOpCount: ops.length
754
759
  };
755
760
  }
756
- function persistBase(entry) {
757
- if (typeof window === "undefined" || !window.localStorage) return;
758
- if (!entry.isDemoMode) return;
759
- if (entry.persistTimer) return;
760
- entry.persistTimer = setTimeout(() => {
761
- entry.persistTimer = null;
762
- if (typeof window === "undefined" || !window.localStorage) return;
763
- const base = entry.collection.getBase();
764
- if (!base) return;
765
- try {
766
- window.localStorage.setItem(
767
- entry.storageKey,
768
- JSON.stringify({
769
- items: base.items.map((item) => stripInternalItemMetadata(item)),
770
- subtotal: base.subtotal,
771
- tax: base.tax,
772
- total: base.total,
773
- currency: base.currency
774
- })
775
- );
776
- } catch {
777
- }
778
- }, 100);
779
- }
780
- function hydrateFromStorage(entry) {
781
- if (typeof window === "undefined" || !window.localStorage) return;
782
- if (!entry.isDemoMode) {
783
- try {
784
- window.localStorage.removeItem(entry.storageKey);
785
- } catch {
786
- }
787
- return;
788
- }
789
- try {
790
- const raw = window.localStorage.getItem(entry.storageKey);
791
- if (!raw) return;
792
- const parsed = JSON.parse(raw);
793
- if (!parsed || !Array.isArray(parsed.items)) return;
794
- const items = parsed.items.map((item) => attachInternalItemMetadata(item));
795
- entry.collection.setBase({
796
- items,
797
- subtotal: toNumber(parsed.subtotal),
798
- tax: toNumber(parsed.tax),
799
- total: toNumber(parsed.total),
800
- currency: typeof parsed.currency === "string" && parsed.currency ? parsed.currency : entry.currency,
801
- isLoading: !entry.isDemoMode
802
- });
803
- } catch {
804
- }
805
- }
806
761
  async function syncFromServer(entry) {
807
- if (entry.isDemoMode) {
808
- const base = entry.collection.getBase() ?? emptyBase(entry.currency);
809
- entry.collection.setBase({ ...base, isLoading: false });
810
- return;
811
- }
812
762
  if (entry.syncing) return;
813
763
  entry.syncing = true;
814
764
  try {
815
765
  const result = await entry.client.cart.get();
816
766
  if (!result.ok) throw result.error;
817
767
  entry.collection.setBase(mapServerCart(result.value, entry.currency));
818
- persistBase(entry);
819
768
  } finally {
820
769
  entry.syncing = false;
821
770
  }
@@ -837,8 +786,9 @@ function scheduleFailedOpRemoval(entry, opId) {
837
786
  entry.failedOpRemovers.add(handle);
838
787
  }
839
788
  function getOrCreateStore(params) {
840
- const { client, locationId, isDemoMode, currency, optimisticEnabled } = params;
841
- const storeKey = buildStoreKey(client, locationId, isDemoMode);
789
+ const { client, locationId, currency, optimisticEnabled } = params;
790
+ purgeLegacyCartCachesOnce();
791
+ const storeKey = buildStoreKey(client, locationId);
842
792
  const existing = cartStores.get(storeKey);
843
793
  if (existing) {
844
794
  existing.optimisticEnabled = optimisticEnabled;
@@ -852,14 +802,11 @@ function getOrCreateStore(params) {
852
802
  const entry = {
853
803
  collection,
854
804
  client,
855
- storageKey: buildStorageKey(storeKey),
856
805
  locationId,
857
806
  currency,
858
- isDemoMode,
859
807
  optimisticEnabled,
860
808
  initialized: false,
861
809
  initializePromise: null,
862
- persistTimer: null,
863
810
  syncing: false,
864
811
  failedOpRemovers: /* @__PURE__ */ new Set()
865
812
  };
@@ -872,12 +819,6 @@ async function ensureInitialized(entry) {
872
819
  return;
873
820
  }
874
821
  entry.initialized = true;
875
- hydrateFromStorage(entry);
876
- if (entry.isDemoMode) {
877
- const base = entry.collection.getBase() ?? emptyBase(entry.currency);
878
- entry.collection.setBase({ ...base, isLoading: false });
879
- return;
880
- }
881
822
  entry.initializePromise = syncFromServer(entry).catch(() => {
882
823
  const base = entry.collection.getBase() ?? emptyBase(entry.currency);
883
824
  entry.collection.setBase({ ...base, isLoading: false });
@@ -891,7 +832,7 @@ async function maybeResolveQuoteId(entry, product, quantity, options) {
891
832
  const requiresQuote = Boolean(
892
833
  options.variantId || addOnOptionIds && addOnOptionIds.length > 0 || options.bundleSelections && options.bundleSelections.length > 0 || options.compositeSelections && options.compositeSelections.length > 0
893
834
  );
894
- if (!requiresQuote || entry.isDemoMode) return void 0;
835
+ if (!requiresQuote) return void 0;
895
836
  const quoteResult = await entry.client.catalogue.fetchQuote({
896
837
  product_id: product.id,
897
838
  quantity,
@@ -931,10 +872,6 @@ async function performAddItem(entry, product, quantity, options) {
931
872
  });
932
873
  const idempotencyKey = `idem_${typeof crypto !== "undefined" && crypto.randomUUID ? crypto.randomUUID() : `${Date.now()}_${Math.random().toString(36).slice(2, 10)}`}`;
933
874
  const patch = { kind: "add_item", tempItem, lineKey };
934
- if (entry.isDemoMode) {
935
- advanceBaseWithPatch(entry, patch);
936
- return;
937
- }
938
875
  const useOptimistic = entry.optimisticEnabled;
939
876
  const opId = useOptimistic ? entry.collection.enqueue(patch, idempotencyKey) : null;
940
877
  try {
@@ -973,10 +910,6 @@ async function performAddItem(entry, product, quantity, options) {
973
910
  async function performRemoveItem(entry, itemId) {
974
911
  const idempotencyKey = "";
975
912
  const patch = { kind: "remove_item", itemId };
976
- if (entry.isDemoMode) {
977
- advanceBaseWithPatch(entry, patch);
978
- return;
979
- }
980
913
  const useOptimistic = entry.optimisticEnabled;
981
914
  const opId = useOptimistic ? entry.collection.enqueue(patch, idempotencyKey) : null;
982
915
  try {
@@ -1001,10 +934,6 @@ async function performUpdateQuantity(entry, itemId, quantity) {
1001
934
  const resolved = clampQuantity(quantity);
1002
935
  const idempotencyKey = "";
1003
936
  const patch = { kind: "set_quantity", itemId, quantity: resolved };
1004
- if (entry.isDemoMode) {
1005
- advanceBaseWithPatch(entry, patch);
1006
- return;
1007
- }
1008
937
  const useOptimistic = entry.optimisticEnabled;
1009
938
  const opId = useOptimistic ? entry.collection.enqueue(patch, idempotencyKey) : null;
1010
939
  try {
@@ -1025,10 +954,6 @@ async function performUpdateQuantity(entry, itemId, quantity) {
1025
954
  async function performClear(entry) {
1026
955
  const idempotencyKey = "";
1027
956
  const patch = { kind: "clear" };
1028
- if (entry.isDemoMode) {
1029
- advanceBaseWithPatch(entry, patch);
1030
- return;
1031
- }
1032
957
  const useOptimistic = entry.optimisticEnabled;
1033
958
  const opId = useOptimistic ? entry.collection.enqueue(patch, idempotencyKey) : null;
1034
959
  try {
@@ -1059,18 +984,16 @@ function useCart(options = {}) {
1059
984
  throw new Error("useCart must be used within CimplifyProvider or passed { client }.");
1060
985
  }
1061
986
  const locationId = options.locationId ?? client.getLocationId();
1062
- const isDemoMode = options.demoMode ?? context?.isDemoMode ?? client.getPublicKey().trim().length === 0;
1063
987
  const currency = options.currency ?? context?.currency ?? "USD";
1064
988
  const optimisticEnabled = context?.optimistic ?? true;
1065
989
  const entry = useMemo(
1066
990
  () => getOrCreateStore({
1067
991
  client,
1068
992
  locationId,
1069
- isDemoMode,
1070
993
  currency,
1071
994
  optimisticEnabled
1072
995
  }),
1073
- [client, currency, isDemoMode, locationId, optimisticEnabled]
996
+ [client, currency, locationId, optimisticEnabled]
1074
997
  );
1075
998
  const view = useCollectionStore(entry.collection);
1076
999
  useEffect(() => {
@@ -1230,7 +1153,6 @@ function CimplifyProvider({
1230
1153
  useEffect(() => {
1231
1154
  onLocationChangeRef.current = onLocationChange;
1232
1155
  }, [onLocationChange]);
1233
- const isDemoMode = resolvedClient.getPublicKey().trim().length === 0;
1234
1156
  const baseCurrency = business?.default_currency || DEFAULT_CURRENCY;
1235
1157
  const [displayCurrencyOverride, setDisplayCurrencyOverride] = useState(
1236
1158
  () => getStoredDisplayCurrency()
@@ -1252,7 +1174,7 @@ function CimplifyProvider({
1252
1174
  [baseCurrency]
1253
1175
  );
1254
1176
  useEffect(() => {
1255
- if (displayCurrency === baseCurrency || isDemoMode) {
1177
+ if (displayCurrency === baseCurrency) {
1256
1178
  setFxRate(null);
1257
1179
  return;
1258
1180
  }
@@ -1275,7 +1197,7 @@ function CimplifyProvider({
1275
1197
  cancelled = true;
1276
1198
  clearInterval(intervalId);
1277
1199
  };
1278
- }, [resolvedClient, baseCurrency, displayCurrency, isDemoMode]);
1200
+ }, [resolvedClient, baseCurrency, displayCurrency]);
1279
1201
  const convertPrice = useCallback(
1280
1202
  (amount) => {
1281
1203
  const num = typeof amount === "string" ? parseFloat(amount) : amount;
@@ -1302,17 +1224,6 @@ function CimplifyProvider({
1302
1224
  let cancelled = false;
1303
1225
  async function bootstrap() {
1304
1226
  setIsReady(false);
1305
- if (isDemoMode) {
1306
- if (!cancelled) {
1307
- setBusiness(null);
1308
- setLocations([]);
1309
- setCurrentLocationState(null);
1310
- resolvedClient.setLocationId(null);
1311
- setStoredLocationId(null);
1312
- setIsReady(true);
1313
- }
1314
- return;
1315
- }
1316
1227
  const [businessResult, locationsResult] = await Promise.all([
1317
1228
  resolvedClient.business.getInfo(),
1318
1229
  resolvedClient.business.getLocations()
@@ -1353,7 +1264,7 @@ function CimplifyProvider({
1353
1264
  return () => {
1354
1265
  cancelled = true;
1355
1266
  };
1356
- }, [resolvedClient, isDemoMode]);
1267
+ }, [resolvedClient]);
1357
1268
  const clientContextValue = useMemo(
1358
1269
  () => ({
1359
1270
  client: resolvedClient,
@@ -1362,7 +1273,6 @@ function CimplifyProvider({
1362
1273
  country: business?.country_code || DEFAULT_COUNTRY,
1363
1274
  locations,
1364
1275
  isReady,
1365
- isDemoMode,
1366
1276
  baseCurrency,
1367
1277
  optimistic
1368
1278
  }),
@@ -1372,7 +1282,6 @@ function CimplifyProvider({
1372
1282
  baseCurrency,
1373
1283
  locations,
1374
1284
  isReady,
1375
- isDemoMode,
1376
1285
  optimistic
1377
1286
  ]
1378
1287
  );
@@ -1427,16 +1336,10 @@ function useCimplifyClient() {
1427
1336
  function useOptionalCimplifyClient() {
1428
1337
  return useContext(CimplifyClientContext);
1429
1338
  }
1430
- var SPACE = { sm: 8};
1431
- function shellColors(isDark, primaryColor) {
1339
+ function shellColors(isDark) {
1432
1340
  return {
1433
- text: isDark ? "#f4f4f5" : "#1a1a1a",
1434
1341
  textSecondary: isDark ? "#a1a1aa" : "#52525b",
1435
- textMuted: isDark ? "#71717a" : "#a1a1aa",
1436
- border: isDark ? "#27272a" : "#e4e4e7",
1437
- surface: isDark ? "#18181b" : "#fafafa",
1438
- error: "#dc2626",
1439
- primary: primaryColor
1342
+ error: "#dc2626"
1440
1343
  };
1441
1344
  }
1442
1345
  function statusToLabel(status) {
@@ -1480,7 +1383,6 @@ function CimplifyCheckout({
1480
1383
  onError,
1481
1384
  onStatusChange,
1482
1385
  appearance,
1483
- demoMode,
1484
1386
  className
1485
1387
  }) {
1486
1388
  const resolvedOrderTypes = useMemo(
@@ -1508,8 +1410,6 @@ function CimplifyCheckout({
1508
1410
  const initialAppearanceRef = useRef(appearance);
1509
1411
  const hasWarnedInlineAppearanceRef = useRef(false);
1510
1412
  const isMountedRef = useRef(true);
1511
- const demoRunRef = useRef(0);
1512
- const isDemoCheckout = demoMode ?? client.getPublicKey().trim().length === 0;
1513
1413
  const isTestMode = client.isTestMode();
1514
1414
  const cimplifyCtx = useOptionalCimplify();
1515
1415
  const fxOptions = useMemo(() => {
@@ -1524,7 +1424,6 @@ function CimplifyCheckout({
1524
1424
  fxOptionsRef.current = fxOptions;
1525
1425
  const resolvedCartRef = useRef(resolvedCart);
1526
1426
  resolvedCartRef.current = resolvedCart;
1527
- const primaryColor = appearance?.variables?.primaryColor || "#0a2540";
1528
1427
  const isDark = appearance?.theme === "dark";
1529
1428
  const emitStatus = React10.useEffectEvent(
1530
1429
  (nextStatus, context = {}) => {
@@ -1554,15 +1453,6 @@ function CimplifyCheckout({
1554
1453
  useEffect(() => {
1555
1454
  let cancelled = false;
1556
1455
  async function bootstrap() {
1557
- if (isDemoCheckout) {
1558
- if (!cancelled) {
1559
- setResolvedBusinessId(businessId ?? null);
1560
- setResolvedCartId(cartId ?? "cart_demo");
1561
- setIsInitializing(false);
1562
- setErrorMessage(null);
1563
- }
1564
- return;
1565
- }
1566
1456
  const needsBusinessResolve = !businessId;
1567
1457
  const needsCartResolve = !cartId;
1568
1458
  if (!needsBusinessResolve && !needsCartResolve) {
@@ -1630,11 +1520,10 @@ function CimplifyCheckout({
1630
1520
  return () => {
1631
1521
  cancelled = true;
1632
1522
  };
1633
- }, [businessId, cartId, client, isDemoCheckout]);
1523
+ }, [businessId, cartId, client]);
1634
1524
  useEffect(() => {
1635
1525
  return () => {
1636
1526
  isMountedRef.current = false;
1637
- demoRunRef.current += 1;
1638
1527
  activeCheckoutRef.current?.abort();
1639
1528
  activeCheckoutRef.current = null;
1640
1529
  };
@@ -1651,42 +1540,6 @@ function CimplifyCheckout({
1651
1540
  setErrorMessage(null);
1652
1541
  setIsSubmitting(true);
1653
1542
  emitStatus("preparing", { display_text: statusToLabel("preparing") });
1654
- if (isDemoCheckout) {
1655
- const runId = demoRunRef.current + 1;
1656
- demoRunRef.current = runId;
1657
- const wait = async (ms) => {
1658
- await new Promise((resolve) => setTimeout(resolve, ms));
1659
- return isMountedRef.current && runId === demoRunRef.current;
1660
- };
1661
- try {
1662
- if (!await wait(400)) return;
1663
- emitStatus("processing", { display_text: statusToLabel("processing") });
1664
- if (!await wait(900)) return;
1665
- emitStatus("polling", { display_text: statusToLabel("polling") });
1666
- if (!await wait(1200)) return;
1667
- const result = {
1668
- success: true,
1669
- order: {
1670
- id: `ord_demo_${Date.now()}`,
1671
- order_number: `DEMO-${Math.random().toString(36).slice(2, 8).toUpperCase()}`,
1672
- status: "confirmed",
1673
- total: "0.00",
1674
- currency: "USD"
1675
- }
1676
- };
1677
- emitStatus("success", {
1678
- order_id: result.order?.id,
1679
- order_number: result.order?.order_number,
1680
- display_text: statusToLabel("success")
1681
- });
1682
- onComplete(result);
1683
- } finally {
1684
- if (isMountedRef.current && runId === demoRunRef.current) {
1685
- setIsSubmitting(false);
1686
- }
1687
- }
1688
- return;
1689
- }
1690
1543
  if (!elementsRef.current) {
1691
1544
  const message = "Checkout is still initializing. Please try again.";
1692
1545
  setErrorMessage(message);
@@ -1721,7 +1574,7 @@ function CimplifyCheckout({
1721
1574
  }
1722
1575
  });
1723
1576
  useEffect(() => {
1724
- if (isDemoCheckout || !resolvedBusinessId) {
1577
+ if (!resolvedBusinessId) {
1725
1578
  elementsRef.current = null;
1726
1579
  return;
1727
1580
  }
@@ -1762,7 +1615,6 @@ function CimplifyCheckout({
1762
1615
  }, [
1763
1616
  client,
1764
1617
  resolvedBusinessId,
1765
- isDemoCheckout,
1766
1618
  resolvedOrderTypes,
1767
1619
  resolvedDefaultOrderType,
1768
1620
  submitLabel
@@ -1774,15 +1626,15 @@ function CimplifyCheckout({
1774
1626
  checkoutElement.setCart(transformToCheckoutCart(resolvedCart, fxOptions));
1775
1627
  }
1776
1628
  }, [resolvedCart, fxOptions]);
1777
- const colors = shellColors(isDark ?? false, primaryColor);
1629
+ const colors = shellColors(isDark ?? false);
1778
1630
  if (isInitializing) {
1779
1631
  return /* @__PURE__ */ jsx("div", { className, "data-cimplify-checkout": "", children: /* @__PURE__ */ jsx("p", { "data-cimplify-status": "", style: { fontSize: 13, color: colors.textSecondary }, children: "Preparing checkout..." }) });
1780
1632
  }
1781
- if (!isDemoCheckout && (!resolvedBusinessId || !resolvedCartId)) {
1633
+ if (!resolvedBusinessId || !resolvedCartId) {
1782
1634
  return /* @__PURE__ */ jsx("div", { className, "data-cimplify-checkout": "", children: /* @__PURE__ */ jsx("p", { "data-cimplify-error": "", style: { fontSize: 13, color: colors.error }, children: errorMessage || "Unable to initialize checkout. Please refresh and try again." }) });
1783
1635
  }
1784
1636
  return /* @__PURE__ */ jsxs("div", { className, "data-cimplify-checkout": "", children: [
1785
- isTestMode && !isDemoCheckout && /* @__PURE__ */ jsx(
1637
+ isTestMode && /* @__PURE__ */ jsx(
1786
1638
  "p",
1787
1639
  {
1788
1640
  "data-cimplify-test-mode": "",
@@ -1795,9 +1647,9 @@ function CimplifyCheckout({
1795
1647
  children: "Test mode - no real charges"
1796
1648
  }
1797
1649
  ),
1798
- /* @__PURE__ */ jsx("div", { "data-cimplify-section": "checkout", children: /* @__PURE__ */ jsx("div", { ref: isDemoCheckout ? void 0 : checkoutMountRef }) }),
1799
- status && /* @__PURE__ */ jsx("p", { "data-cimplify-status": "", style: { marginTop: SPACE.sm, fontSize: 13, color: colors.textSecondary }, children: statusText || statusToLabel(status) }),
1800
- errorMessage && /* @__PURE__ */ jsx("p", { "data-cimplify-error": "", style: { marginTop: SPACE.sm, fontSize: 13, color: colors.error }, children: errorMessage })
1650
+ /* @__PURE__ */ jsx("div", { "data-cimplify-section": "checkout", children: /* @__PURE__ */ jsx("div", { ref: checkoutMountRef }) }),
1651
+ status && /* @__PURE__ */ jsx("p", { "data-cimplify-status": "", style: { marginTop: 8, fontSize: 13, color: colors.textSecondary }, children: statusText || statusToLabel(status) }),
1652
+ errorMessage && /* @__PURE__ */ jsx("p", { "data-cimplify-error": "", style: { marginTop: 8, fontSize: 13, color: colors.error }, children: errorMessage })
1801
1653
  ] });
1802
1654
  }
1803
1655
  function cn(...inputs) {
@@ -5145,6 +4997,262 @@ function VolumePricing({
5145
4997
  }
5146
4998
  );
5147
4999
  }
5000
+ function parseValue(value) {
5001
+ if (!value) return void 0;
5002
+ const date = parseISO(value);
5003
+ return isValid(date) ? date : void 0;
5004
+ }
5005
+ function formatValue(date) {
5006
+ return format(date, "yyyy-MM-dd");
5007
+ }
5008
+ function DatePicker({
5009
+ value,
5010
+ onChange,
5011
+ placeholder = "Select a date",
5012
+ minDate,
5013
+ maxDate,
5014
+ disabled,
5015
+ triggerDisabled,
5016
+ name,
5017
+ required,
5018
+ className,
5019
+ classNames,
5020
+ "aria-label": ariaLabel
5021
+ }) {
5022
+ const [open, setOpen] = useState(false);
5023
+ const selected = parseValue(value);
5024
+ const disabledMatchers = [];
5025
+ if (minDate) disabledMatchers.push({ before: minDate });
5026
+ if (maxDate) disabledMatchers.push({ after: maxDate });
5027
+ if (Array.isArray(disabled)) {
5028
+ disabledMatchers.push(...disabled);
5029
+ } else if (disabled) {
5030
+ disabledMatchers.push(disabled);
5031
+ }
5032
+ return /* @__PURE__ */ jsxs("div", { "data-cimplify-date-picker": true, className: cn(className, classNames?.root), children: [
5033
+ /* @__PURE__ */ jsxs(Popover.Root, { open, onOpenChange: setOpen, children: [
5034
+ /* @__PURE__ */ jsxs(
5035
+ Popover.Trigger,
5036
+ {
5037
+ type: "button",
5038
+ "aria-label": ariaLabel ?? placeholder,
5039
+ disabled: triggerDisabled,
5040
+ className: cn(
5041
+ "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",
5042
+ classNames?.trigger
5043
+ ),
5044
+ children: [
5045
+ /* @__PURE__ */ jsx("span", { className: cn(!selected && "text-muted-foreground"), children: selected ? format(selected, "EEE, MMM d, yyyy") : placeholder }),
5046
+ /* @__PURE__ */ jsxs(
5047
+ "svg",
5048
+ {
5049
+ width: "16",
5050
+ height: "16",
5051
+ viewBox: "0 0 24 24",
5052
+ fill: "none",
5053
+ stroke: "currentColor",
5054
+ strokeWidth: "2",
5055
+ strokeLinecap: "round",
5056
+ strokeLinejoin: "round",
5057
+ "aria-hidden": "true",
5058
+ className: "shrink-0 text-muted-foreground",
5059
+ children: [
5060
+ /* @__PURE__ */ jsx("rect", { x: "3", y: "4", width: "18", height: "18", rx: "2" }),
5061
+ /* @__PURE__ */ jsx("line", { x1: "16", y1: "2", x2: "16", y2: "6" }),
5062
+ /* @__PURE__ */ jsx("line", { x1: "8", y1: "2", x2: "8", y2: "6" }),
5063
+ /* @__PURE__ */ jsx("line", { x1: "3", y1: "10", x2: "21", y2: "10" })
5064
+ ]
5065
+ }
5066
+ )
5067
+ ]
5068
+ }
5069
+ ),
5070
+ /* @__PURE__ */ jsx(Popover.Portal, { children: /* @__PURE__ */ jsx(Popover.Positioner, { sideOffset: 6, align: "start", children: /* @__PURE__ */ jsx(
5071
+ Popover.Popup,
5072
+ {
5073
+ className: cn(
5074
+ "z-50 rounded-lg border border-border bg-background p-3 shadow-lg outline-none",
5075
+ classNames?.popup
5076
+ ),
5077
+ children: /* @__PURE__ */ jsx(
5078
+ DayPicker,
5079
+ {
5080
+ mode: "single",
5081
+ selected,
5082
+ onSelect: (date) => {
5083
+ onChange?.(date ? formatValue(date) : "");
5084
+ if (date) setOpen(false);
5085
+ },
5086
+ disabled: disabledMatchers.length > 0 ? disabledMatchers : void 0,
5087
+ showOutsideDays: true,
5088
+ weekStartsOn: 0,
5089
+ className: cn("p-0", classNames?.calendar),
5090
+ classNames: {
5091
+ months: "flex flex-col gap-3",
5092
+ month: "flex flex-col gap-3",
5093
+ caption: "flex items-center justify-between px-1",
5094
+ caption_label: "text-sm font-semibold",
5095
+ nav: "flex items-center gap-1",
5096
+ nav_button: "inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground hover:bg-muted transition-colors",
5097
+ table: "w-full border-collapse",
5098
+ head_row: "flex",
5099
+ head_cell: "w-9 text-center text-[10px] font-medium uppercase tracking-wider text-muted-foreground",
5100
+ row: "flex w-full mt-1",
5101
+ cell: "w-9 h-9 text-center text-sm p-0 relative",
5102
+ day: cn(
5103
+ "inline-flex h-9 w-9 items-center justify-center rounded-md text-sm font-normal text-foreground hover:bg-muted transition-colors",
5104
+ "aria-selected:bg-foreground aria-selected:text-background aria-selected:hover:bg-foreground/90"
5105
+ ),
5106
+ day_selected: cn(
5107
+ "bg-foreground text-background hover:bg-foreground/90 focus:bg-foreground",
5108
+ classNames?.daySelected
5109
+ ),
5110
+ day_today: cn(
5111
+ "ring-1 ring-inset ring-primary/40",
5112
+ classNames?.dayToday
5113
+ ),
5114
+ day_outside: "text-muted-foreground/50",
5115
+ day_disabled: cn(
5116
+ "text-muted-foreground/40 cursor-not-allowed line-through",
5117
+ classNames?.dayDisabled
5118
+ )
5119
+ }
5120
+ }
5121
+ )
5122
+ }
5123
+ ) }) })
5124
+ ] }),
5125
+ name ? /* @__PURE__ */ jsx("input", { type: "hidden", name, value: value ?? "", required }) : null
5126
+ ] });
5127
+ }
5128
+ function parseHHmm(value) {
5129
+ if (!value) return null;
5130
+ const match = /^(\d{1,2}):(\d{2})$/.exec(value);
5131
+ if (!match) return null;
5132
+ const hour = Number.parseInt(match[1] ?? "", 10);
5133
+ const minute = Number.parseInt(match[2] ?? "", 10);
5134
+ if (Number.isNaN(hour) || Number.isNaN(minute)) return null;
5135
+ if (hour < 0 || hour > 23 || minute < 0 || minute > 59) return null;
5136
+ return { hour, minute };
5137
+ }
5138
+ function formatHHmm(hour, minute) {
5139
+ return `${String(hour).padStart(2, "0")}:${String(minute).padStart(2, "0")}`;
5140
+ }
5141
+ function formatDisplay(hour, minute, displayFormat) {
5142
+ if (displayFormat === "24h") {
5143
+ return formatHHmm(hour, minute);
5144
+ }
5145
+ const period = hour >= 12 ? "PM" : "AM";
5146
+ const displayHour = hour % 12 || 12;
5147
+ return `${displayHour}:${String(minute).padStart(2, "0")} ${period}`;
5148
+ }
5149
+ function buildOptions(minTime, maxTime, stepMinutes) {
5150
+ const min = parseHHmm(minTime) ?? { hour: 0, minute: 0 };
5151
+ const max = parseHHmm(maxTime) ?? { hour: 23, minute: 59 };
5152
+ const minTotal = min.hour * 60 + min.minute;
5153
+ const maxTotal = max.hour * 60 + max.minute;
5154
+ const step = Math.max(1, stepMinutes);
5155
+ const out = [];
5156
+ for (let total = minTotal; total <= maxTotal; total += step) {
5157
+ out.push(formatHHmm(Math.floor(total / 60), total % 60));
5158
+ }
5159
+ return out;
5160
+ }
5161
+ function TimePicker({
5162
+ value,
5163
+ onChange,
5164
+ placeholder = "Select a time",
5165
+ minTime = "00:00",
5166
+ maxTime = "23:30",
5167
+ stepMinutes = 30,
5168
+ displayFormat = "12h",
5169
+ triggerDisabled,
5170
+ name,
5171
+ required,
5172
+ className,
5173
+ classNames,
5174
+ "aria-label": ariaLabel
5175
+ }) {
5176
+ const [open, setOpen] = useState(false);
5177
+ const parsed = parseHHmm(value);
5178
+ const options = useMemo(
5179
+ () => buildOptions(minTime, maxTime, stepMinutes),
5180
+ [minTime, maxTime, stepMinutes]
5181
+ );
5182
+ const triggerLabel = parsed ? formatDisplay(parsed.hour, parsed.minute, displayFormat) : placeholder;
5183
+ return /* @__PURE__ */ jsxs("div", { "data-cimplify-time-picker": true, className: cn(className, classNames?.root), children: [
5184
+ /* @__PURE__ */ jsxs(Popover.Root, { open, onOpenChange: setOpen, children: [
5185
+ /* @__PURE__ */ jsxs(
5186
+ Popover.Trigger,
5187
+ {
5188
+ type: "button",
5189
+ "aria-label": ariaLabel ?? placeholder,
5190
+ disabled: triggerDisabled,
5191
+ className: cn(
5192
+ "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",
5193
+ classNames?.trigger
5194
+ ),
5195
+ children: [
5196
+ /* @__PURE__ */ jsx("span", { className: cn(!parsed && "text-muted-foreground"), children: triggerLabel }),
5197
+ /* @__PURE__ */ jsxs(
5198
+ "svg",
5199
+ {
5200
+ width: "16",
5201
+ height: "16",
5202
+ viewBox: "0 0 24 24",
5203
+ fill: "none",
5204
+ stroke: "currentColor",
5205
+ strokeWidth: "2",
5206
+ strokeLinecap: "round",
5207
+ strokeLinejoin: "round",
5208
+ "aria-hidden": "true",
5209
+ className: "shrink-0 text-muted-foreground",
5210
+ children: [
5211
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "9" }),
5212
+ /* @__PURE__ */ jsx("polyline", { points: "12 7 12 12 15 14" })
5213
+ ]
5214
+ }
5215
+ )
5216
+ ]
5217
+ }
5218
+ ),
5219
+ /* @__PURE__ */ jsx(Popover.Portal, { children: /* @__PURE__ */ jsx(Popover.Positioner, { sideOffset: 6, align: "start", children: /* @__PURE__ */ jsx(
5220
+ Popover.Popup,
5221
+ {
5222
+ className: cn(
5223
+ "z-50 max-h-64 overflow-y-auto rounded-lg border border-border bg-background p-1 shadow-lg outline-none",
5224
+ classNames?.popup
5225
+ ),
5226
+ children: /* @__PURE__ */ jsx("ul", { role: "listbox", "aria-label": ariaLabel ?? placeholder, className: "flex flex-col", children: options.map((option) => {
5227
+ const isSelected = option === value;
5228
+ const opt = parseHHmm(option);
5229
+ if (!opt) return null;
5230
+ return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
5231
+ "button",
5232
+ {
5233
+ type: "button",
5234
+ role: "option",
5235
+ "aria-selected": isSelected,
5236
+ onClick: () => {
5237
+ onChange?.(option);
5238
+ setOpen(false);
5239
+ },
5240
+ className: cn(
5241
+ "w-full rounded-md px-3 py-2 text-left text-sm transition-colors hover:bg-muted",
5242
+ isSelected && "bg-foreground text-background hover:bg-foreground/90",
5243
+ classNames?.option,
5244
+ isSelected && classNames?.optionSelected
5245
+ ),
5246
+ children: formatDisplay(opt.hour, opt.minute, displayFormat)
5247
+ }
5248
+ ) }, option);
5249
+ }) })
5250
+ }
5251
+ ) }) })
5252
+ ] }),
5253
+ name ? /* @__PURE__ */ jsx("input", { type: "hidden", name, value: value ?? "", required }) : null
5254
+ ] });
5255
+ }
5148
5256
  function CustomerInputFields({
5149
5257
  fields,
5150
5258
  values,
@@ -5331,13 +5439,13 @@ function FieldInput({
5331
5439
  );
5332
5440
  case INPUT_FIELD_TYPE.Date:
5333
5441
  return /* @__PURE__ */ jsx(
5334
- "input",
5442
+ DatePicker,
5335
5443
  {
5336
- type: "date",
5337
5444
  value: typeof value === "string" ? value : "",
5338
- onChange: (e) => onValueChange(e.target.value || void 0),
5445
+ onChange: (next) => onValueChange(next || void 0),
5339
5446
  required: field.is_required,
5340
- className: inputClass
5447
+ placeholder: field.placeholder ?? "Select a date",
5448
+ "aria-label": field.name
5341
5449
  }
5342
5450
  );
5343
5451
  case INPUT_FIELD_TYPE.File:
@@ -5365,34 +5473,53 @@ function FieldInput({
5365
5473
  }
5366
5474
  );
5367
5475
  case INPUT_FIELD_TYPE.DateTime: {
5368
- const dtLocalValue = typeof value === "string" && value.includes("T") ? value.slice(0, 16) : typeof value === "string" ? value : "";
5369
- return /* @__PURE__ */ jsx(
5370
- "input",
5371
- {
5372
- type: "datetime-local",
5373
- value: dtLocalValue,
5374
- onChange: (e) => {
5375
- if (!e.target.value) {
5376
- onValueChange(void 0);
5377
- return;
5378
- }
5379
- const date = new Date(e.target.value);
5380
- onValueChange(Number.isNaN(date.getTime()) ? e.target.value : date.toISOString());
5381
- },
5382
- required: field.is_required,
5383
- className: inputClass
5476
+ const stringValue = typeof value === "string" ? value : "";
5477
+ const [datePart, timePartRaw] = stringValue.includes("T") ? stringValue.split("T", 2) : [stringValue, ""];
5478
+ const timePart = (timePartRaw ?? "").slice(0, 5);
5479
+ const commit = (nextDate, nextTime) => {
5480
+ if (!nextDate && !nextTime) {
5481
+ onValueChange(void 0);
5482
+ return;
5384
5483
  }
5385
- );
5484
+ if (!nextDate) {
5485
+ onValueChange(`${nextTime}`);
5486
+ return;
5487
+ }
5488
+ const combined = `${nextDate}T${nextTime || "00:00"}`;
5489
+ const parsed = new Date(combined);
5490
+ onValueChange(Number.isNaN(parsed.getTime()) ? combined : parsed.toISOString());
5491
+ };
5492
+ return /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-[1fr_auto] gap-2", children: [
5493
+ /* @__PURE__ */ jsx(
5494
+ DatePicker,
5495
+ {
5496
+ value: datePart ?? "",
5497
+ onChange: (next) => commit(next, timePart),
5498
+ placeholder: field.placeholder ?? "Select a date",
5499
+ "aria-label": `${field.name} date`,
5500
+ required: field.is_required
5501
+ }
5502
+ ),
5503
+ /* @__PURE__ */ jsx(
5504
+ TimePicker,
5505
+ {
5506
+ value: timePart,
5507
+ onChange: (next) => commit(datePart ?? "", next),
5508
+ placeholder: "Time",
5509
+ "aria-label": `${field.name} time`
5510
+ }
5511
+ )
5512
+ ] });
5386
5513
  }
5387
5514
  case INPUT_FIELD_TYPE.Time:
5388
5515
  return /* @__PURE__ */ jsx(
5389
- "input",
5516
+ TimePicker,
5390
5517
  {
5391
- type: "time",
5392
5518
  value: typeof value === "string" ? value : "",
5393
- onChange: (e) => onValueChange(e.target.value || void 0),
5519
+ onChange: (next) => onValueChange(next || void 0),
5394
5520
  required: field.is_required,
5395
- className: inputClass
5521
+ placeholder: field.placeholder ?? "Select a time",
5522
+ "aria-label": field.name
5396
5523
  }
5397
5524
  );
5398
5525
  case INPUT_FIELD_TYPE.MultiSelect:
@@ -5412,8 +5539,7 @@ function FieldInput({
5412
5539
  field,
5413
5540
  value,
5414
5541
  onValueChange,
5415
- classNames,
5416
- inputClass
5542
+ classNames
5417
5543
  }
5418
5544
  );
5419
5545
  case INPUT_FIELD_TYPE.Address:
@@ -5582,38 +5708,39 @@ function DateRangeInput({
5582
5708
  field,
5583
5709
  value,
5584
5710
  onValueChange,
5585
- classNames,
5586
- inputClass
5711
+ classNames
5587
5712
  }) {
5588
5713
  const range = value && typeof value === "object" ? value : {};
5589
5714
  const update = (key, v) => {
5590
5715
  const next = { ...range, [key]: v };
5591
5716
  onValueChange(next.start || next.end ? next : void 0);
5592
5717
  };
5593
- return /* @__PURE__ */ jsxs("div", { className: cn("grid grid-cols-2 gap-3", classNames?.dateRangeInput), children: [
5718
+ return /* @__PURE__ */ jsxs("div", { className: cn("grid grid-cols-1 sm:grid-cols-2 gap-3", classNames?.dateRangeInput), children: [
5594
5719
  /* @__PURE__ */ jsxs("div", { children: [
5595
5720
  /* @__PURE__ */ jsx("label", { className: "text-xs text-muted-foreground mb-1 block", children: "Start" }),
5596
5721
  /* @__PURE__ */ jsx(
5597
- "input",
5722
+ DatePicker,
5598
5723
  {
5599
- type: "date",
5600
5724
  value: range.start || "",
5601
- onChange: (e) => update("start", e.target.value),
5725
+ onChange: (next) => update("start", next),
5602
5726
  required: field.is_required,
5603
- className: inputClass
5727
+ placeholder: "Start date",
5728
+ "aria-label": `${field.name} start date`,
5729
+ maxDate: range.end ? /* @__PURE__ */ new Date(`${range.end}T00:00`) : void 0
5604
5730
  }
5605
5731
  )
5606
5732
  ] }),
5607
5733
  /* @__PURE__ */ jsxs("div", { children: [
5608
5734
  /* @__PURE__ */ jsx("label", { className: "text-xs text-muted-foreground mb-1 block", children: "End" }),
5609
5735
  /* @__PURE__ */ jsx(
5610
- "input",
5736
+ DatePicker,
5611
5737
  {
5612
- type: "date",
5613
5738
  value: range.end || "",
5614
- onChange: (e) => update("end", e.target.value),
5739
+ onChange: (next) => update("end", next),
5615
5740
  required: field.is_required,
5616
- className: inputClass
5741
+ placeholder: "End date",
5742
+ "aria-label": `${field.name} end date`,
5743
+ minDate: range.start ? /* @__PURE__ */ new Date(`${range.start}T00:00`) : void 0
5617
5744
  }
5618
5745
  )
5619
5746
  ] })
@@ -6057,6 +6184,39 @@ function formatTime(timeStr) {
6057
6184
  }
6058
6185
  return timeStr;
6059
6186
  }
6187
+ function pluralizeUnit(unit, value) {
6188
+ if (!unit) return value === 1 ? "day" : "days";
6189
+ const v = value ?? 1;
6190
+ if (unit === "minutes") return v === 1 ? "minute" : "minutes";
6191
+ if (unit === "hours") return v === 1 ? "hour" : "hours";
6192
+ if (unit === "days") return v === 1 ? "day" : "days";
6193
+ if (unit === "weeks") return v === 1 ? "week" : "weeks";
6194
+ if (unit === "months") return v === 1 ? "month" : "months";
6195
+ return unit;
6196
+ }
6197
+ function formatStaySummary(slot, durationUnit, durationValue) {
6198
+ const start = new Date(slot.start_time);
6199
+ const end = new Date(slot.end_time);
6200
+ const startLabel = start.toLocaleString(void 0, {
6201
+ weekday: "short",
6202
+ month: "short",
6203
+ day: "numeric",
6204
+ hour: "numeric",
6205
+ minute: "2-digit"
6206
+ });
6207
+ const endLabel = end.toLocaleString(void 0, {
6208
+ weekday: "short",
6209
+ month: "short",
6210
+ day: "numeric",
6211
+ hour: "numeric",
6212
+ minute: "2-digit"
6213
+ });
6214
+ const unitLabel = pluralizeUnit(durationUnit, durationValue);
6215
+ if (durationValue !== void 0) {
6216
+ return `${durationValue} ${unitLabel}: ${startLabel} \u2192 ${endLabel}`;
6217
+ }
6218
+ return `${startLabel} \u2192 ${endLabel}`;
6219
+ }
6060
6220
  function slotToValue(slot) {
6061
6221
  return `${slot.start_time}|${slot.end_time}`;
6062
6222
  }
@@ -6069,10 +6229,14 @@ function SlotPicker({
6069
6229
  onSlotSelect,
6070
6230
  groupByTimeOfDay = true,
6071
6231
  showPrice = true,
6232
+ schedulingMode = "intraday",
6233
+ durationUnit,
6234
+ durationValue,
6072
6235
  emptyMessage = "No available slots",
6073
6236
  className,
6074
6237
  classNames
6075
6238
  }) {
6239
+ const isMultiDay = schedulingMode === "multi_day";
6076
6240
  const { slots: fetched, isLoading } = useAvailableSlots(
6077
6241
  serviceId ?? null,
6078
6242
  date ?? null,
@@ -6103,7 +6267,7 @@ function SlotPicker({
6103
6267
  }
6104
6268
  );
6105
6269
  }
6106
- const groups = groupByTimeOfDay ? groupSlots(slots) : [{ label: "", slots }];
6270
+ const groups = groupByTimeOfDay && !isMultiDay ? groupSlots(slots) : [{ label: "", slots }];
6107
6271
  const slotsByValue = /* @__PURE__ */ new Map();
6108
6272
  for (const slot of slots) {
6109
6273
  slotsByValue.set(slotToValue(slot), slot);
@@ -6136,7 +6300,7 @@ function SlotPicker({
6136
6300
  "data-unavailable": !slot.is_available || void 0,
6137
6301
  className: classNames?.slot,
6138
6302
  children: [
6139
- /* @__PURE__ */ jsx("span", { "data-cimplify-slot-time": true, className: classNames?.slotTime, children: formatTime(slot.start_time) }),
6303
+ /* @__PURE__ */ jsx("span", { "data-cimplify-slot-time": true, className: classNames?.slotTime, children: isMultiDay ? formatStaySummary(slot, durationUnit, durationValue) : formatTime(slot.start_time) }),
6140
6304
  showPrice && slot.price && /* @__PURE__ */ jsx("span", { "data-cimplify-slot-price": true, className: classNames?.slotPrice, children: /* @__PURE__ */ jsx(Price, { amount: slot.price }) })
6141
6305
  ]
6142
6306
  },
@@ -6167,6 +6331,9 @@ function DateSlotPicker({
6167
6331
  onSlotSelect,
6168
6332
  availability: availabilityProp,
6169
6333
  showPrice = true,
6334
+ schedulingMode,
6335
+ durationUnit,
6336
+ durationValue,
6170
6337
  className,
6171
6338
  classNames
6172
6339
  }) {
@@ -6284,7 +6451,10 @@ function DateSlotPicker({
6284
6451
  participantCount,
6285
6452
  selectedSlot,
6286
6453
  onSlotSelect: handleSlotSelect,
6287
- showPrice
6454
+ showPrice,
6455
+ schedulingMode,
6456
+ durationUnit,
6457
+ durationValue
6288
6458
  }
6289
6459
  ) })
6290
6460
  ]
@@ -13370,4 +13540,4 @@ function SparkleIcon({ className }) {
13370
13540
  );
13371
13541
  }
13372
13542
 
13373
- export { AccommodationCard, Ad, AdProvider, AddOnSelector, AddressElement, AuthElement, AvailabilityBadge, BillingPlanSelector, BookingCard, BookingList, BookingPage, BookingsPage, BundleProductCard, BundleProductLayout, BundleSelector, CardImage, CardShell, CardVariant, CartDrawer, CartDrawerProvider, CartPage, CartSummary, CartTemplate, CatalogueCollectionLayout, CataloguePage, CatalogueTemplate, CategoryFilter, CategoryGrid, ChatWidget, CheckoutPage, CimplifyAccount, CimplifyCheckout, CimplifyProvider, CollectionPage, CollectionTemplate, CompactCartLayout, CompactCatalogueLayout, CompactSearchLayout, CompactServiceCard, CompositeProductCard, CompositeProductLayout, CompositeSelector, CurrencySelector, CustomAttributesTable, CustomerInputFields, DateSlotPicker, DealBanner, DealsPage, DefaultCartLayout, DefaultCatalogueLayout, DefaultCollectionLayout, DefaultProductLayout, DefaultSearchLayout, DeliveryEstimate, DigitalProductCard, DigitalProductLayout, DiscountInput, ElementsProvider, FeaturedCollectionLayout, FoodProductCard, FoodProductLayout, InventoryBadge, LeaseServiceCard, LocationPicker, MetadataStringList, OrderDetailPage, OrderHistory, OrderHistoryPage, OrderSummary, PaymentElement, Price, PriceRange, ProductCard, ProductCustomizer, ProductGrid, ProductImageGallery, ProductPage, ProductSheet, ProductTemplate, PropertiesTable, QuantitySelector, QuickAddButton, RecentlyViewed, RecommendationCarousel, RelatedProductsSection, RentalServiceCard, ResourcePicker, RetailProductCard, SaleBadge, ScheduleServiceCard, SearchInput, SearchPage, SearchTemplate, ServiceProductLayout, SessionMessageBanner, SlotPicker, SoldOutOverlay, StaffPicker, StandardServiceCard, StoreNav, SubscriptionCard, TagPills, TwoColumnGrid, VariantSelector, VolumePricing, WholesaleProductCard, WholesaleProductLayout, WishlistButton, cn, roomToResource, useActivityState, useAds, useAttributeDefinitions, useAvailableSlots, useBillingPlans, useBookings, useBootstrap, useBundles, useCart, useCartDrawer, useCategories, useChat, useCheckout, useCimplify, useCimplifyClient, useCollection, useCollections, useDeals, useDeliveryFee, useElements, useElementsReady, useFxRate, useLocations, useOptionalCimplify, useOrder, useOrders, useProduct, useProductAvailability, useProductDeals, useProductPrice, useProductSchedules, useProducts, useProductsOnSale, usePropertyFacets, useQuote, useRecommendations, useSearch, useServiceAvailability, useServices, useSubscription, useSubscriptions, useTaxonomies, useTaxonomy, useTaxonomyPath, useValidateDiscount, useVariantSelector };
13543
+ export { AccommodationCard, Ad, AdProvider, AddOnSelector, AddressElement, AuthElement, AvailabilityBadge, BillingPlanSelector, BookingCard, BookingList, BookingPage, BookingsPage, BundleProductCard, BundleProductLayout, BundleSelector, CardImage, CardShell, CardVariant, CartDrawer, CartDrawerProvider, CartPage, CartSummary, CartTemplate, CatalogueCollectionLayout, CataloguePage, CatalogueTemplate, CategoryFilter, CategoryGrid, ChatWidget, CheckoutPage, CimplifyAccount, CimplifyCheckout, CimplifyProvider, CollectionPage, CollectionTemplate, CompactCartLayout, CompactCatalogueLayout, CompactSearchLayout, CompactServiceCard, CompositeProductCard, CompositeProductLayout, CompositeSelector, CurrencySelector, CustomAttributesTable, CustomerInputFields, DatePicker, DateSlotPicker, DealBanner, DealsPage, DefaultCartLayout, DefaultCatalogueLayout, DefaultCollectionLayout, DefaultProductLayout, DefaultSearchLayout, DeliveryEstimate, DigitalProductCard, DigitalProductLayout, DiscountInput, ElementsProvider, FeaturedCollectionLayout, FoodProductCard, FoodProductLayout, InventoryBadge, LeaseServiceCard, LocationPicker, MetadataStringList, OrderDetailPage, OrderHistory, OrderHistoryPage, OrderSummary, PaymentElement, Price, PriceRange, ProductCard, ProductCustomizer, ProductGrid, ProductImageGallery, ProductPage, ProductSheet, ProductTemplate, PropertiesTable, QuantitySelector, QuickAddButton, RecentlyViewed, RecommendationCarousel, RelatedProductsSection, RentalServiceCard, ResourcePicker, RetailProductCard, SaleBadge, ScheduleServiceCard, SearchInput, SearchPage, SearchTemplate, ServiceProductLayout, SessionMessageBanner, SlotPicker, SoldOutOverlay, StaffPicker, StandardServiceCard, StoreNav, SubscriptionCard, TagPills, TimePicker, TwoColumnGrid, VariantSelector, VolumePricing, WholesaleProductCard, WholesaleProductLayout, WishlistButton, cn, roomToResource, useActivityState, useAds, useAttributeDefinitions, useAvailableSlots, useBillingPlans, useBookings, useBootstrap, useBundles, useCart, useCartDrawer, useCategories, useChat, useCheckout, useCimplify, useCimplifyClient, useCollection, useCollections, useDeals, useDeliveryFee, useElements, useElementsReady, useFxRate, useLocations, useOptionalCimplify, useOrder, useOrders, useProduct, useProductAvailability, useProductDeals, useProductPrice, useProductSchedules, useProducts, useProductsOnSale, usePropertyFacets, useQuote, useRecommendations, useSearch, useServiceAvailability, useServices, useSubscription, useSubscriptions, useTaxonomies, useTaxonomy, useTaxonomyPath, useValidateDiscount, useVariantSelector };