@lime-bundles/react 6.2.0 → 7.0.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/index.cjs CHANGED
@@ -20,58 +20,55 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
- BUNDLES_FOR_PRODUCT_QUERY: () => import_core18.BUNDLES_FOR_PRODUCT_QUERY,
24
- BUNDLE_METAOBJECT_QUERY: () => import_core18.BUNDLE_METAOBJECT_QUERY,
23
+ BUNDLES_FOR_PRODUCT_QUERY: () => import_core17.BUNDLES_FOR_PRODUCT_QUERY,
24
+ BUNDLE_METAOBJECT_QUERY: () => import_core17.BUNDLE_METAOBJECT_QUERY,
25
25
  BogoBundle: () => BogoBundle,
26
26
  BundleCountdown: () => BundleCountdown,
27
- BundleParseError: () => import_core17.BundleParseError,
28
- DEFAULT_OUT_OF_STOCK_BEHAVIOR: () => import_core18.DEFAULT_OUT_OF_STOCK_BEHAVIOR,
27
+ BundleParseError: () => import_core16.BundleParseError,
29
28
  FixedBundle: () => FixedBundle,
30
29
  MixMatchBundle: () => MixMatchBundle,
31
30
  MultiStepBundle: () => MultiStepBundle,
32
- SHOP_SETTINGS_QUERY: () => import_core18.SHOP_SETTINGS_QUERY,
33
- StorefrontApiError: () => import_core17.StorefrontApiError,
31
+ SHOP_SETTINGS_QUERY: () => import_core17.SHOP_SETTINGS_QUERY,
32
+ StorefrontApiError: () => import_core16.StorefrontApiError,
34
33
  VariantDropdown: () => VariantDropdown,
35
34
  VolumeBundle: () => VolumeBundle,
36
- WIDGET_CONFIG_DEFAULTS: () => import_core18.WIDGET_CONFIG_DEFAULTS,
37
- applyWidgetConfigVars: () => import_core18.applyWidgetConfigVars,
38
- calculateDiscount: () => import_core18.calculateDiscount,
39
- calculateTierSavings: () => import_core18.calculateTierSavings,
40
- computeBundleSaleCents: () => import_core18.computeBundleSaleCents,
41
- computeFixedPricing: () => import_core18.computeFixedPricing,
42
- createStorefrontClient: () => import_core18.createStorefrontClient,
35
+ WIDGET_CONFIG_DEFAULTS: () => import_core17.WIDGET_CONFIG_DEFAULTS,
36
+ applyWidgetConfigVars: () => import_core17.applyWidgetConfigVars,
37
+ calculateDiscount: () => import_core17.calculateDiscount,
38
+ calculateTierSavings: () => import_core17.calculateTierSavings,
39
+ computeBundleSaleCents: () => import_core17.computeBundleSaleCents,
40
+ computeFixedPricing: () => import_core17.computeFixedPricing,
41
+ createStorefrontClient: () => import_core17.createStorefrontClient,
43
42
  fetchBundleData: () => fetchBundleData,
44
- fetchBundlesForProduct: () => import_core18.fetchBundlesForProduct,
43
+ fetchBundlesForProduct: () => import_core17.fetchBundlesForProduct,
45
44
  fetchShopCustomCss: () => fetchShopCustomCss,
46
45
  fetchShopSettings: () => fetchShopSettings,
47
46
  fetchShopSettingsOrDefault: () => fetchShopSettingsOrDefault,
48
- formatCents: () => import_core18.formatCents,
49
- formatCountdown: () => import_core18.formatCountdown,
50
- formatMoney: () => import_core18.formatMoney,
51
- formatUnitPrice: () => import_core18.formatUnitPrice,
52
- getActiveTier: () => import_core18.getActiveTier,
53
- injectCustomCss: () => import_core18.injectCustomCss,
54
- mergeWidgetConfig: () => import_core18.mergeWidgetConfig,
55
- observeImpression: () => import_core18.observeImpression,
56
- parseCents: () => import_core18.parseCents,
57
- parseMetaobjectBundle: () => import_core18.parseMetaobjectBundle,
58
- parseMetaobjectBundleStrict: () => import_core18.parseMetaobjectBundleStrict,
59
- parseOutOfStockBehavior: () => import_core18.parseOutOfStockBehavior,
60
- percentageDiscountUnit: () => import_core18.percentageDiscountUnit,
61
- productsForStep: () => import_core18.productsForStep,
62
- reportAddToCart: () => import_core18.reportAddToCart,
63
- reportImpression: () => import_core18.reportImpression,
64
- sanitizeCustomCss: () => import_core18.sanitizeCustomCss,
65
- stepHeadroom: () => import_core18.stepHeadroom,
66
- thumbnailRatioVars: () => import_core18.thumbnailRatioVars,
67
- transformImageUrl: () => import_core18.transformImageUrl,
47
+ formatCents: () => import_core17.formatCents,
48
+ formatCountdown: () => import_core17.formatCountdown,
49
+ formatMoney: () => import_core17.formatMoney,
50
+ formatUnitPrice: () => import_core17.formatUnitPrice,
51
+ getActiveTier: () => import_core17.getActiveTier,
52
+ injectCustomCss: () => import_core17.injectCustomCss,
53
+ mergeWidgetConfig: () => import_core17.mergeWidgetConfig,
54
+ observeImpression: () => import_core17.observeImpression,
55
+ parseCents: () => import_core17.parseCents,
56
+ parseMetaobjectBundle: () => import_core17.parseMetaobjectBundle,
57
+ parseMetaobjectBundleStrict: () => import_core17.parseMetaobjectBundleStrict,
58
+ percentageDiscountUnit: () => import_core17.percentageDiscountUnit,
59
+ productsForStep: () => import_core17.productsForStep,
60
+ reportAddToCart: () => import_core17.reportAddToCart,
61
+ reportImpression: () => import_core17.reportImpression,
62
+ sanitizeCustomCss: () => import_core17.sanitizeCustomCss,
63
+ stepHeadroom: () => import_core17.stepHeadroom,
64
+ thumbnailRatioVars: () => import_core17.thumbnailRatioVars,
65
+ transformImageUrl: () => import_core17.transformImageUrl,
68
66
  useAnalytics: () => useAnalytics,
69
67
  useBundleData: () => useBundleData,
70
68
  useBundlesForProduct: () => useBundlesForProduct,
71
- useShopSettings: () => useShopSettings,
72
69
  useVariantSelection: () => useVariantSelection,
73
70
  useWidgetConfigVars: () => useWidgetConfigVars,
74
- validateQuantity: () => import_core18.validateQuantity
71
+ validateQuantity: () => import_core17.validateQuantity
75
72
  });
76
73
  module.exports = __toCommonJS(index_exports);
77
74
 
@@ -141,8 +138,7 @@ async function fetchBundleDataWithWarnings(options) {
141
138
  // src/fetchShopSettings.ts
142
139
  var import_core2 = require("@lime-bundles/core");
143
140
  var FALLBACK = {
144
- customCss: null,
145
- outOfStockBehavior: import_core2.DEFAULT_OUT_OF_STOCK_BEHAVIOR
141
+ customCss: null
146
142
  };
147
143
  var cache = /* @__PURE__ */ new Map();
148
144
  async function fetchShopSettings(options) {
@@ -160,10 +156,7 @@ async function fetchShopSettings(options) {
160
156
  { signal: options.signal }
161
157
  );
162
158
  return {
163
- customCss: data.shop?.customCss?.value ?? null,
164
- outOfStockBehavior: (0, import_core2.parseOutOfStockBehavior)(
165
- data.shop?.outOfStockBehavior?.value
166
- )
159
+ customCss: data.shop?.customCss?.value ?? null
167
160
  };
168
161
  })();
169
162
  cache.set(options.shopDomain, promise);
@@ -317,19 +310,25 @@ function useWidgetConfigVars(config) {
317
310
  var import_react4 = require("react");
318
311
  var import_core6 = require("@lime-bundles/core");
319
312
  var { findVariantByOptions, isOptionValueAvailable, toPickerVariant } = import_core6.variants;
320
- function defaultInitial(variants) {
321
- return variants.find((v) => v.availableForSale) ?? variants[0] ?? null;
322
- }
323
313
  function useVariantSelection({
324
314
  variants,
325
315
  optionNames,
326
316
  initialVariant,
327
- optionValuesByPosition
317
+ optionValuesByPosition,
318
+ requiredQtyFor
328
319
  }) {
329
- const seed = (0, import_react4.useMemo)(
330
- () => initialVariant ?? defaultInitial(variants),
331
- [initialVariant, variants]
320
+ const pickerVariants = (0, import_react4.useMemo)(
321
+ () => variants.map((v) => toPickerVariant(v, requiredQtyFor?.(v.id))),
322
+ [variants, requiredQtyFor]
332
323
  );
324
+ const seed = (0, import_react4.useMemo)(() => {
325
+ if (initialVariant) return initialVariant;
326
+ const covered = pickerVariants.find((p) => p.available);
327
+ if (covered) {
328
+ return variants.find((v) => v.id === covered.id) ?? null;
329
+ }
330
+ return variants.find((v) => v.availableForSale) ?? variants[0] ?? null;
331
+ }, [initialVariant, variants, pickerVariants]);
333
332
  const [selectedValues, setSelectedValues] = (0, import_react4.useState)(
334
333
  () => seed ? seed.selectedOptions.map((o) => o.value) : optionNames.map(() => "")
335
334
  );
@@ -337,10 +336,6 @@ function useVariantSelection({
337
336
  if (!seed) return;
338
337
  setSelectedValues(seed.selectedOptions.map((o) => o.value));
339
338
  }, [seed?.id]);
340
- const pickerVariants = (0, import_react4.useMemo)(
341
- () => variants.map((v) => toPickerVariant(v)),
342
- [variants]
343
- );
344
339
  const selectedVariant = (0, import_react4.useMemo)(() => {
345
340
  if (selectedValues.length !== optionNames.length) return null;
346
341
  const match = findVariantByOptions(pickerVariants, selectedValues);
@@ -968,7 +963,11 @@ function FixedProductRow({ bundle, product, currency, isOos, onVariantChange })
968
963
  const showPicker = variants.length > 1 && optionNames.length > 0;
969
964
  const { selectedValues, selectedVariant, setOptionValue, optionsFor } = useVariantSelection({
970
965
  variants,
971
- optionNames
966
+ optionNames,
967
+ // Quantity-aware dropdown: a variant that can't cover this row's
968
+ // bundle quantity greys out instead of walking the shopper into a
969
+ // cart Shopify caps at add time.
970
+ requiredQtyFor: (variantId) => (0, import_core8.resolveBundleQty)(bundle, product.id, variantId)
972
971
  });
973
972
  (0, import_react8.useEffect)(() => {
974
973
  onVariantChange(product.id, selectedVariant ?? null);
@@ -1063,41 +1062,16 @@ function FixedProductRow({ bundle, product, currency, isOos, onVariantChange })
1063
1062
  }
1064
1063
 
1065
1064
  // src/components/MixMatchBundle.tsx
1066
- var import_react13 = require("react");
1067
- var import_core11 = require("@lime-bundles/core");
1068
-
1069
- // src/hooks/useShopSettings.ts
1070
- var import_react9 = require("react");
1071
- var import_core9 = require("@lime-bundles/core");
1072
- function useShopSettings(options) {
1073
- const [outOfStockBehavior, setOutOfStockBehavior] = (0, import_react9.useState)(import_core9.DEFAULT_OUT_OF_STOCK_BEHAVIOR);
1074
- const { shopDomain, storefrontAccessToken } = options;
1075
- (0, import_react9.useEffect)(() => {
1076
- const controller = new AbortController();
1077
- let active = true;
1078
- fetchShopSettingsOrDefault({
1079
- shopDomain,
1080
- storefrontAccessToken,
1081
- signal: controller.signal
1082
- }).then((settings) => {
1083
- if (!active || controller.signal.aborted) return;
1084
- setOutOfStockBehavior(settings.outOfStockBehavior);
1085
- });
1086
- return () => {
1087
- active = false;
1088
- controller.abort();
1089
- };
1090
- }, [shopDomain, storefrontAccessToken]);
1091
- return { outOfStockBehavior };
1092
- }
1065
+ var import_react12 = require("react");
1066
+ var import_core10 = require("@lime-bundles/core");
1093
1067
 
1094
1068
  // src/components/MixMatchPicker.tsx
1095
- var import_react12 = require("react");
1069
+ var import_react11 = require("react");
1096
1070
  var import_react_dom = require("react-dom");
1097
- var import_core10 = require("@lime-bundles/core");
1071
+ var import_core9 = require("@lime-bundles/core");
1098
1072
 
1099
1073
  // src/hooks/useScrollLock.ts
1100
- var import_react10 = require("react");
1074
+ var import_react9 = require("react");
1101
1075
  var lockCount = 0;
1102
1076
  var savedY = 0;
1103
1077
  function lock() {
@@ -1126,7 +1100,7 @@ function unlock() {
1126
1100
  window.scrollTo(0, savedY);
1127
1101
  }
1128
1102
  function useScrollLock(active) {
1129
- (0, import_react10.useEffect)(() => {
1103
+ (0, import_react9.useEffect)(() => {
1130
1104
  if (!active) return;
1131
1105
  lock();
1132
1106
  return unlock;
@@ -1134,7 +1108,7 @@ function useScrollLock(active) {
1134
1108
  }
1135
1109
 
1136
1110
  // src/hooks/useFocusTrap.ts
1137
- var import_react11 = require("react");
1111
+ var import_react10 = require("react");
1138
1112
  var FOCUSABLE_SELECTOR = [
1139
1113
  "a[href]",
1140
1114
  "button:not([disabled])",
@@ -1157,14 +1131,16 @@ function useFocusTrap({
1157
1131
  active,
1158
1132
  containerRef,
1159
1133
  onEscape,
1134
+ initialFocusRef,
1160
1135
  returnFocusRef
1161
1136
  }) {
1162
- const previouslyFocused = (0, import_react11.useRef)(null);
1163
- (0, import_react11.useEffect)(() => {
1137
+ const previouslyFocused = (0, import_react10.useRef)(null);
1138
+ (0, import_react10.useEffect)(() => {
1164
1139
  if (!active) return;
1165
1140
  const container = containerRef.current;
1166
1141
  previouslyFocused.current = document.activeElement ?? null;
1167
- container?.focus();
1142
+ const initial = initialFocusRef?.current ?? container;
1143
+ initial?.focus();
1168
1144
  function onKeyDown(e) {
1169
1145
  if (e.key === "Escape") {
1170
1146
  e.preventDefault();
@@ -1208,7 +1184,7 @@ function ruleFor(bundle, productId, variantId) {
1208
1184
  const vRule = bundle.variantRules[variantId];
1209
1185
  if (vRule) return vRule;
1210
1186
  }
1211
- return bundle.productRules[productId] ?? import_core10.DEFAULT_PRODUCT_RULE;
1187
+ return bundle.productRules[productId] ?? import_core9.DEFAULT_PRODUCT_RULE;
1212
1188
  }
1213
1189
  function variantRuleFor(bundle, variantId) {
1214
1190
  return variantId ? bundle.variantRules[variantId] : void 0;
@@ -1216,7 +1192,7 @@ function variantRuleFor(bundle, variantId) {
1216
1192
  function sanitizeId(gid) {
1217
1193
  return gid.replace(/[^a-zA-Z0-9_-]/g, "-");
1218
1194
  }
1219
- function buildEligibleProducts(bundle, oosBehavior) {
1195
+ function buildEligibleProducts(bundle) {
1220
1196
  const result = [];
1221
1197
  const seen = /* @__PURE__ */ new Set();
1222
1198
  for (const product of bundle.products) {
@@ -1224,10 +1200,9 @@ function buildEligibleProducts(bundle, oosBehavior) {
1224
1200
  seen.add(product.id);
1225
1201
  const rule = ruleFor(bundle, product.id);
1226
1202
  const available = product.variants.nodes.filter(
1227
- (v) => (0, import_core10.isVariantFulfillable)(v, rule.min)
1203
+ (v) => (0, import_core9.isVariantFulfillable)(v, rule.min)
1228
1204
  );
1229
1205
  const isOos = available.length === 0;
1230
- if (isOos && oosBehavior === "hide") continue;
1231
1206
  result.push({
1232
1207
  product,
1233
1208
  variants: product.variants.nodes,
@@ -1242,7 +1217,6 @@ function normalizeText(str) {
1242
1217
  }
1243
1218
  var FILTERS_ALL = "__all__";
1244
1219
  function MixMatchPicker({
1245
- outOfStockBehavior,
1246
1220
  bundle,
1247
1221
  currency,
1248
1222
  requiredQty,
@@ -1258,17 +1232,18 @@ function MixMatchPicker({
1258
1232
  styleVarsRef
1259
1233
  }) {
1260
1234
  const wc = bundle.widgetConfig;
1261
- const overlayRef = (0, import_react12.useRef)(null);
1262
- const dialogRef = (0, import_react12.useRef)(null);
1263
- const mouseDownTarget = (0, import_react12.useRef)(null);
1264
- const [open, setOpen] = (0, import_react12.useState)(false);
1265
- const [query, setQuery] = (0, import_react12.useState)("");
1266
- const [activeType, setActiveType] = (0, import_react12.useState)(FILTERS_ALL);
1267
- const eligible = (0, import_react12.useMemo)(
1268
- () => buildEligibleProducts(bundle, outOfStockBehavior),
1269
- [bundle, outOfStockBehavior]
1235
+ const overlayRef = (0, import_react11.useRef)(null);
1236
+ const dialogRef = (0, import_react11.useRef)(null);
1237
+ const closeBtnRef = (0, import_react11.useRef)(null);
1238
+ const mouseDownTarget = (0, import_react11.useRef)(null);
1239
+ const [open, setOpen] = (0, import_react11.useState)(false);
1240
+ const [query, setQuery] = (0, import_react11.useState)("");
1241
+ const [activeType, setActiveType] = (0, import_react11.useState)(FILTERS_ALL);
1242
+ const eligible = (0, import_react11.useMemo)(
1243
+ () => buildEligibleProducts(bundle),
1244
+ [bundle]
1270
1245
  );
1271
- const productTypes = (0, import_react12.useMemo)(() => {
1246
+ const productTypes = (0, import_react11.useMemo)(() => {
1272
1247
  const types = [];
1273
1248
  const seen = /* @__PURE__ */ new Set();
1274
1249
  for (const ep of eligible) {
@@ -1284,7 +1259,7 @@ function MixMatchPicker({
1284
1259
  const totalUnits = selections.reduce((sum, s) => sum + s.quantity, 0);
1285
1260
  const atCapacity = totalUnits >= requiredQty;
1286
1261
  const shownUnits = Math.min(totalUnits, requiredQty);
1287
- (0, import_react12.useEffect)(() => {
1262
+ (0, import_react11.useEffect)(() => {
1288
1263
  const id = requestAnimationFrame(() => setOpen(true));
1289
1264
  return () => cancelAnimationFrame(id);
1290
1265
  }, []);
@@ -1292,6 +1267,7 @@ function MixMatchPicker({
1292
1267
  useFocusTrap({
1293
1268
  active: true,
1294
1269
  containerRef: dialogRef,
1270
+ initialFocusRef: closeBtnRef,
1295
1271
  onEscape: onClose
1296
1272
  });
1297
1273
  const remaining = Math.max(0, requiredQty - shownUnits);
@@ -1300,14 +1276,25 @@ function MixMatchPicker({
1300
1276
  const pct = bundle.discountConfig.discountType === "percentage" && bundle.discountConfig.discountValue ? Math.round(bundle.discountConfig.discountValue) : 0;
1301
1277
  return pct > 0 ? `Choose ${remaining} more to unlock ${pct}% off` : `Choose ${remaining} more to complete your bundle`;
1302
1278
  })();
1303
- const filtered = (0, import_react12.useMemo)(() => {
1279
+ const [selectedAtOpen] = (0, import_react11.useState)(
1280
+ () => new Set(selections.map((s) => s.productId))
1281
+ );
1282
+ const ordered = (0, import_react11.useMemo)(() => {
1283
+ const front = [];
1284
+ const back = [];
1285
+ for (const ep of eligible) {
1286
+ (selectedAtOpen.has(ep.product.id) ? back : front).push(ep);
1287
+ }
1288
+ return front.concat(back);
1289
+ }, [eligible, selectedAtOpen]);
1290
+ const filtered = (0, import_react11.useMemo)(() => {
1304
1291
  const nq = normalizeText(query.trim());
1305
- return eligible.filter((ep) => {
1292
+ return ordered.filter((ep) => {
1306
1293
  const matchesQuery = !nq || normalizeText(ep.product.title).includes(nq);
1307
1294
  const matchesType = activeType === FILTERS_ALL || (ep.product.productType ?? "") === activeType;
1308
1295
  return matchesQuery && matchesType;
1309
1296
  });
1310
- }, [eligible, query, activeType]);
1297
+ }, [ordered, query, activeType]);
1311
1298
  const showEmpty = filtered.length === 0 && query.trim().length > 0;
1312
1299
  function onOverlayMouseDown(e) {
1313
1300
  mouseDownTarget.current = e.target;
@@ -1356,6 +1343,7 @@ function MixMatchPicker({
1356
1343
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1357
1344
  "button",
1358
1345
  {
1346
+ ref: closeBtnRef,
1359
1347
  type: "button",
1360
1348
  className: "lb-mix-match__modal-close",
1361
1349
  "data-modal-close": true,
@@ -1510,16 +1498,16 @@ function MixMatchPickerRow({
1510
1498
  }) {
1511
1499
  const { product, variants, isOos } = eligible;
1512
1500
  const rule = ruleFor(bundle, product.id);
1513
- const optionNames = (0, import_react12.useMemo)(() => {
1501
+ const optionNames = (0, import_react11.useMemo)(() => {
1514
1502
  const first = variants[0];
1515
1503
  return first ? first.selectedOptions.map((o) => o.name) : [];
1516
1504
  }, [variants]);
1517
1505
  const showPicker = variants.length > 1 && optionNames.length > 0;
1518
1506
  const { selectedValues, selectedVariant, setOptionValue, optionsFor } = useVariantSelection({ variants, optionNames });
1519
- const currentVariant = selectedVariant ?? variants.find((v) => (0, import_core10.isVariantFulfillable)(v, rule.min)) ?? eligible.firstAvailableVariant ?? variants[0] ?? null;
1507
+ const currentVariant = selectedVariant ?? variants.find((v) => (0, import_core9.isVariantFulfillable)(v, rule.min)) ?? eligible.firstAvailableVariant ?? variants[0] ?? null;
1520
1508
  const vRule = ruleFor(bundle, product.id, currentVariant?.id);
1521
1509
  const variantMax = variantRuleFor(bundle, currentVariant?.id)?.max;
1522
- const alreadyInBundle = (0, import_react12.useMemo)(() => {
1510
+ const alreadyInBundle = (0, import_react11.useMemo)(() => {
1523
1511
  if (!currentVariant) return 0;
1524
1512
  let sum = 0;
1525
1513
  for (const s of selections) {
@@ -1529,13 +1517,13 @@ function MixMatchPickerRow({
1529
1517
  }
1530
1518
  return sum;
1531
1519
  }, [selections, product.id, currentVariant]);
1532
- const committedSelection = (0, import_react12.useMemo)(
1520
+ const committedSelection = (0, import_react11.useMemo)(
1533
1521
  () => currentVariant ? selections.find((s) => s.variantId === currentVariant.id) ?? null : null,
1534
1522
  [selections, currentVariant]
1535
1523
  );
1536
1524
  const variantInBundle = committedSelection !== null;
1537
1525
  const committedQty = committedSelection?.quantity ?? 0;
1538
- const productOtherUnits = (0, import_react12.useMemo)(() => {
1526
+ const productOtherUnits = (0, import_react11.useMemo)(() => {
1539
1527
  if (!currentVariant) return 0;
1540
1528
  let sum = 0;
1541
1529
  for (const s of selections) {
@@ -1552,23 +1540,23 @@ function MixMatchPickerRow({
1552
1540
  committedQty + remainingUnits,
1553
1541
  variantMax ?? Infinity
1554
1542
  );
1555
- const cap = currentVariant ? (0, import_core10.maxAddableQuantity)(
1543
+ const cap = currentVariant ? (0, import_core9.maxAddableQuantity)(
1556
1544
  currentVariant,
1557
1545
  spotCeiling,
1558
1546
  Math.max(0, alreadyInBundle - committedQty)
1559
1547
  ) : 0;
1560
1548
  const stepperMax = Math.max(vRule.min, cap);
1561
- const [qty, setQty] = (0, import_react12.useState)(vRule.min);
1562
- (0, import_react12.useEffect)(() => {
1549
+ const [qty, setQty] = (0, import_react11.useState)(vRule.min);
1550
+ (0, import_react11.useEffect)(() => {
1563
1551
  setQty((prev) => Math.max(vRule.min, Math.min(prev, stepperMax)));
1564
1552
  }, [stepperMax, vRule.min]);
1565
1553
  const currentVariantId = currentVariant?.id ?? null;
1566
- (0, import_react12.useEffect)(() => {
1554
+ (0, import_react11.useEffect)(() => {
1567
1555
  if (!variantInBundle) setQty(vRule.min);
1568
1556
  }, [variantInBundle, currentVariantId, vRule.min]);
1569
1557
  if (!currentVariant) return null;
1570
1558
  const thumbImage = currentVariant.image ?? product.featuredImage ?? null;
1571
- const unitPriceText = (0, import_core10.formatUnitPrice)(
1559
+ const unitPriceText = (0, import_core9.formatUnitPrice)(
1572
1560
  currentVariant.unitPrice,
1573
1561
  currentVariant.unitPriceMeasurement,
1574
1562
  currency
@@ -1638,8 +1626,8 @@ function MixMatchPickerRow({
1638
1626
  }
1639
1627
  ) }),
1640
1628
  /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "lb-mix-match__modal-product-price", children: [
1641
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { "data-row-price-sale": true, children: (0, import_core10.formatMoney)(priceCents, currency) }),
1642
- compareCents !== null && compareCents > priceCents && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("s", { className: "lb-mix-match__modal-product-compare", "data-row-compare": true, children: (0, import_core10.formatMoney)(compareCents, currency) })
1629
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { "data-row-price-sale": true, children: (0, import_core9.formatMoney)(priceCents, currency) }),
1630
+ compareCents !== null && compareCents > priceCents && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("s", { className: "lb-mix-match__modal-product-compare", "data-row-compare": true, children: (0, import_core9.formatMoney)(compareCents, currency) })
1643
1631
  ] }),
1644
1632
  unitPriceText && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "lb-mix-match__modal-product-unit-price lb-bundle-product-unit-price", children: unitPriceText }),
1645
1633
  showPicker && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "lb-bundle-variant-option-groups", children: optionNames.map((optionName, optionIndex) => {
@@ -1790,7 +1778,7 @@ function ruleFor2(bundle, productId, variantId) {
1790
1778
  const vRule = bundle.variantRules[variantId];
1791
1779
  if (vRule) return vRule;
1792
1780
  }
1793
- return bundle.productRules[productId] ?? import_core11.DEFAULT_PRODUCT_RULE;
1781
+ return bundle.productRules[productId] ?? import_core10.DEFAULT_PRODUCT_RULE;
1794
1782
  }
1795
1783
  function variantRuleFor2(bundle, variantId) {
1796
1784
  return variantId ? bundle.variantRules[variantId] : void 0;
@@ -1825,10 +1813,6 @@ function MixMatchBundle(props) {
1825
1813
  storefrontAccessToken,
1826
1814
  bundleGid
1827
1815
  });
1828
- const { outOfStockBehavior } = useShopSettings({
1829
- shopDomain,
1830
- storefrontAccessToken
1831
- });
1832
1816
  const { elementRef, trackAddToCart } = useAnalytics({
1833
1817
  shopDomain,
1834
1818
  appUrl: appUrl ?? `https://${shopDomain}`,
@@ -1836,16 +1820,16 @@ function MixMatchBundle(props) {
1836
1820
  bundleType: "mix_match",
1837
1821
  enabled: analyticsEnabled !== false
1838
1822
  });
1839
- const [selections, setSelections] = (0, import_react13.useState)([]);
1840
- const [seededFor, setSeededFor] = (0, import_react13.useState)(null);
1841
- const [pickerOpen, setPickerOpen] = (0, import_react13.useState)(false);
1842
- const [addingToCart, setAddingToCart] = (0, import_react13.useState)(false);
1843
- const [cartError, setCartError] = (0, import_react13.useState)(null);
1823
+ const [selections, setSelections] = (0, import_react12.useState)([]);
1824
+ const [seededFor, setSeededFor] = (0, import_react12.useState)(null);
1825
+ const [pickerOpen, setPickerOpen] = (0, import_react12.useState)(false);
1826
+ const [addingToCart, setAddingToCart] = (0, import_react12.useState)(false);
1827
+ const [cartError, setCartError] = (0, import_react12.useState)(null);
1844
1828
  const bundle = result.status === "success" && result.bundle.bundleType === "mix_match" ? result.bundle : null;
1845
1829
  const setConfigVarsRef = useWidgetConfigVars(bundle?.widgetConfig);
1846
1830
  const setModalConfigVarsRef = useWidgetConfigVars(bundle?.widgetConfig);
1847
1831
  const slotsEdgeFadeRef = useEdgeFade();
1848
- (0, import_react13.useEffect)(() => {
1832
+ (0, import_react12.useEffect)(() => {
1849
1833
  if (result.status === "error") {
1850
1834
  onError?.(result.error);
1851
1835
  return;
@@ -1858,7 +1842,7 @@ function MixMatchBundle(props) {
1858
1842
  );
1859
1843
  }
1860
1844
  }, [result, onError]);
1861
- (0, import_react13.useEffect)(() => {
1845
+ (0, import_react12.useEffect)(() => {
1862
1846
  if (!bundle || seededFor === bundle.id) return;
1863
1847
  setSeededFor(bundle.id);
1864
1848
  const seedCurrency = bundle.products[0]?.priceRange.minVariantPrice.currencyCode ?? "USD";
@@ -1871,7 +1855,7 @@ function MixMatchBundle(props) {
1871
1855
  featuredImage: variant.image?.url ?? product.featuredImage?.url ?? null,
1872
1856
  price: parseFloat(variant.price.amount),
1873
1857
  compareAtPrice: variant.compareAtPrice ? parseFloat(variant.compareAtPrice.amount) : null,
1874
- unitPrice: (0, import_core11.formatUnitPrice)(
1858
+ unitPrice: (0, import_core10.formatUnitPrice)(
1875
1859
  variant.unitPrice,
1876
1860
  variant.unitPriceMeasurement,
1877
1861
  seedCurrency
@@ -1884,7 +1868,7 @@ function MixMatchBundle(props) {
1884
1868
  for (const variant2 of product.variants.nodes) {
1885
1869
  const vRule = bundle.variantRules[variant2.id];
1886
1870
  if (!vRule?.required) continue;
1887
- if (!(0, import_core11.isVariantFulfillable)(variant2, Math.max(1, vRule.min))) continue;
1871
+ if (!(0, import_core10.isVariantFulfillable)(variant2, Math.max(1, vRule.min))) continue;
1888
1872
  seeds.push(pick(product, variant2, Math.max(1, vRule.min)));
1889
1873
  seededVariant = true;
1890
1874
  }
@@ -1892,7 +1876,7 @@ function MixMatchBundle(props) {
1892
1876
  const rule = bundle.productRules[product.id];
1893
1877
  if (!rule?.required) continue;
1894
1878
  const variant = product.variants.nodes.find(
1895
- (v) => (0, import_core11.isVariantFulfillable)(v, rule.min)
1879
+ (v) => (0, import_core10.isVariantFulfillable)(v, rule.min)
1896
1880
  );
1897
1881
  if (!variant) continue;
1898
1882
  seeds.push(pick(product, variant, rule.min));
@@ -1901,7 +1885,7 @@ function MixMatchBundle(props) {
1901
1885
  const requiredUnits2 = bundle.minQuantity ?? 0;
1902
1886
  const qualifies = (p) => {
1903
1887
  const min = bundle.productRules[p.id]?.min ?? 1;
1904
- return min <= requiredUnits2 && p.variants.nodes.some((v) => (0, import_core11.isVariantFulfillable)(v, min));
1888
+ return min <= requiredUnits2 && p.variants.nodes.some((v) => (0, import_core10.isVariantFulfillable)(v, min));
1905
1889
  };
1906
1890
  const seed = bundle.products.find(
1907
1891
  (p) => p.handle === productHandle && qualifies(p)
@@ -1909,7 +1893,7 @@ function MixMatchBundle(props) {
1909
1893
  if (seed) {
1910
1894
  const min = bundle.productRules[seed.id]?.min ?? 1;
1911
1895
  const variant = seed.variants.nodes.find(
1912
- (v) => (0, import_core11.isVariantFulfillable)(v, min)
1896
+ (v) => (0, import_core10.isVariantFulfillable)(v, min)
1913
1897
  );
1914
1898
  if (variant) seeds.push(pick(seed, variant, min));
1915
1899
  }
@@ -1918,7 +1902,7 @@ function MixMatchBundle(props) {
1918
1902
  }, [bundle, seededFor, productHandle]);
1919
1903
  const showStepper = bundle?.widgetConfig.mixMatchShowQuantitySelector !== false;
1920
1904
  const requiredUnits = bundle?.minQuantity ?? 0;
1921
- const totalQuantity = (0, import_react13.useMemo)(
1905
+ const totalQuantity = (0, import_react12.useMemo)(
1922
1906
  () => selections.reduce((sum, s) => sum + s.quantity, 0),
1923
1907
  [selections]
1924
1908
  );
@@ -1926,14 +1910,14 @@ function MixMatchBundle(props) {
1926
1910
  const valid = !!bundle && meetsMinUnits;
1927
1911
  const shownUnits = Math.min(totalQuantity, requiredUnits);
1928
1912
  const remaining = Math.max(0, requiredUnits - shownUnits);
1929
- const summary = (0, import_react13.useMemo)(() => {
1913
+ const summary = (0, import_react12.useMemo)(() => {
1930
1914
  let comparePrice = 0;
1931
1915
  let salePrice = 0;
1932
1916
  for (const sel of selections) {
1933
1917
  if (sel.quantity <= 0) continue;
1934
1918
  comparePrice += sel.price * sel.quantity;
1935
1919
  if (bundle) {
1936
- salePrice += (0, import_core11.calculateDiscount)(
1920
+ salePrice += (0, import_core10.calculateDiscount)(
1937
1921
  sel.price,
1938
1922
  bundle.discountConfig.discountType,
1939
1923
  bundle.discountConfig.discountValue
@@ -1944,7 +1928,7 @@ function MixMatchBundle(props) {
1944
1928
  const savingsPercent = comparePrice > 0 && savings > 0 ? Math.round(savings / comparePrice * 100) : 0;
1945
1929
  return { comparePrice, salePrice, savings, savingsPercent };
1946
1930
  }, [selections, bundle]);
1947
- const addSelection = (0, import_react13.useCallback)(
1931
+ const addSelection = (0, import_react12.useCallback)(
1948
1932
  (item) => {
1949
1933
  setSelections((prev) => {
1950
1934
  const units = prev.reduce((sum, s) => sum + s.quantity, 0);
@@ -1955,7 +1939,7 @@ function MixMatchBundle(props) {
1955
1939
  },
1956
1940
  [requiredUnits]
1957
1941
  );
1958
- const updateQuantity = (0, import_react13.useCallback)(
1942
+ const updateQuantity = (0, import_react12.useCallback)(
1959
1943
  (productId, variantId, quantity) => {
1960
1944
  setSelections((prev) => {
1961
1945
  const idx = prev.findIndex(
@@ -1978,7 +1962,7 @@ function MixMatchBundle(props) {
1978
1962
  },
1979
1963
  [requiredUnits]
1980
1964
  );
1981
- const swapSelection = (0, import_react13.useCallback)(
1965
+ const swapSelection = (0, import_react12.useCallback)(
1982
1966
  (item) => {
1983
1967
  setSelections((prev) => {
1984
1968
  if (!bundle) return prev;
@@ -2010,7 +1994,7 @@ function MixMatchBundle(props) {
2010
1994
  },
2011
1995
  [bundle]
2012
1996
  );
2013
- const removeVariant = (0, import_react13.useCallback)(
1997
+ const removeVariant = (0, import_react12.useCallback)(
2014
1998
  (variantId) => {
2015
1999
  setSelections((prev) => {
2016
2000
  const idx = prev.findIndex((s) => s.variantId === variantId);
@@ -2023,7 +2007,7 @@ function MixMatchBundle(props) {
2023
2007
  },
2024
2008
  [bundle]
2025
2009
  );
2026
- const removeSlot = (0, import_react13.useCallback)(
2010
+ const removeSlot = (0, import_react12.useCallback)(
2027
2011
  (index) => {
2028
2012
  setSelections((prev) => {
2029
2013
  if (index < 0 || index >= prev.length) return prev;
@@ -2035,7 +2019,7 @@ function MixMatchBundle(props) {
2035
2019
  },
2036
2020
  [bundle]
2037
2021
  );
2038
- const handleAddToCart = (0, import_react13.useCallback)(async () => {
2022
+ const handleAddToCart = (0, import_react12.useCallback)(async () => {
2039
2023
  if (!bundle || !valid) return;
2040
2024
  const grouped = /* @__PURE__ */ new Map();
2041
2025
  for (const sel of selections) {
@@ -2089,7 +2073,7 @@ function MixMatchBundle(props) {
2089
2073
  if (!rule.required) return false;
2090
2074
  const product = bundle.products.find((p) => p.id === pid);
2091
2075
  return !product?.variants.nodes.some(
2092
- (v) => (0, import_core11.isVariantFulfillable)(v, rule.min)
2076
+ (v) => (0, import_core10.isVariantFulfillable)(v, rule.min)
2093
2077
  );
2094
2078
  }
2095
2079
  );
@@ -2189,8 +2173,8 @@ function MixMatchBundle(props) {
2189
2173
  ),
2190
2174
  item.variantTitle && item.variantTitle !== "Default Title" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "lb-mix-match__filled-variant", children: item.variantTitle }),
2191
2175
  /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "lb-mix-match__filled-price", children: [
2192
- item.compareAtPrice !== null && item.compareAtPrice > item.price && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("s", { className: "lb-mix-match__filled-compare", children: (0, import_core11.formatMoney)(item.compareAtPrice, currency) }),
2193
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "lb-bundle-product-price", children: (0, import_core11.formatMoney)(item.price, currency) }),
2176
+ item.compareAtPrice !== null && item.compareAtPrice > item.price && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("s", { className: "lb-mix-match__filled-compare", children: (0, import_core10.formatMoney)(item.compareAtPrice, currency) }),
2177
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "lb-bundle-product-price", children: (0, import_core10.formatMoney)(item.price, currency) }),
2194
2178
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "lb-bundle-qty-inline", children: `\xD7${item.quantity}` })
2195
2179
  ] }),
2196
2180
  item.unitPrice && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "lb-bundle-product-unit-price", children: item.unitPrice })
@@ -2240,7 +2224,7 @@ function MixMatchBundle(props) {
2240
2224
  bundle.widgetConfig.savingsBar.visible && summary.savings > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { className: "lb-bundle-savings-line", "data-savings-bar": true, children: [
2241
2225
  "You save",
2242
2226
  " ",
2243
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { "data-savings-amount": true, children: (0, import_core11.formatMoney)(summary.savings, currency) }),
2227
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { "data-savings-amount": true, children: (0, import_core10.formatMoney)(summary.savings, currency) }),
2244
2228
  " ",
2245
2229
  /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { "data-savings-percent": true, children: [
2246
2230
  "(",
@@ -2250,8 +2234,8 @@ function MixMatchBundle(props) {
2250
2234
  ] })
2251
2235
  ] }),
2252
2236
  /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "lb-bundle-summary__prices", children: [
2253
- bundle.widgetConfig.pricing.showComparePrice && summary.savings > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "lb-bundle-compare-price", "data-compare-price": true, children: (0, import_core11.formatMoney)(summary.comparePrice, currency) }),
2254
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "lb-bundle-sale-price", "data-sale-price": true, children: (0, import_core11.formatMoney)(summary.salePrice, currency) })
2237
+ bundle.widgetConfig.pricing.showComparePrice && summary.savings > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "lb-bundle-compare-price", "data-compare-price": true, children: (0, import_core10.formatMoney)(summary.comparePrice, currency) }),
2238
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "lb-bundle-sale-price", "data-sale-price": true, children: (0, import_core10.formatMoney)(summary.salePrice, currency) })
2255
2239
  ] })
2256
2240
  ] }),
2257
2241
  cartError && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "lb-bundle__error", role: "alert", children: cartError }),
@@ -2268,7 +2252,6 @@ function MixMatchBundle(props) {
2268
2252
  pickerOpen && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2269
2253
  MixMatchPicker,
2270
2254
  {
2271
- outOfStockBehavior,
2272
2255
  bundle,
2273
2256
  currency,
2274
2257
  requiredQty: requiredUnits,
@@ -2299,7 +2282,7 @@ function countInStockProducts(bundle) {
2299
2282
  seen.add(product.id);
2300
2283
  const rule = ruleFor2(bundle, product.id);
2301
2284
  const fulfillable = product.variants.nodes.some(
2302
- (v) => (0, import_core11.isVariantFulfillable)(v, rule.min)
2285
+ (v) => (0, import_core10.isVariantFulfillable)(v, rule.min)
2303
2286
  );
2304
2287
  if (fulfillable) count += 1;
2305
2288
  }
@@ -2341,8 +2324,8 @@ function CloseIcon2() {
2341
2324
  }
2342
2325
 
2343
2326
  // src/components/VolumeBundle.tsx
2344
- var import_react14 = require("react");
2345
- var import_core12 = require("@lime-bundles/core");
2327
+ var import_react13 = require("react");
2328
+ var import_core11 = require("@lime-bundles/core");
2346
2329
  var import_jsx_runtime6 = require("react/jsx-runtime");
2347
2330
  function VolumeBundle(props) {
2348
2331
  const {
@@ -2367,21 +2350,21 @@ function VolumeBundle(props) {
2367
2350
  bundleType: "volume",
2368
2351
  enabled: analyticsEnabled !== false
2369
2352
  });
2370
- const [quantity, setQuantity] = (0, import_react14.useState)(1);
2371
- const [addingToCart, setAddingToCart] = (0, import_react14.useState)(false);
2372
- const [cartError, setCartError] = (0, import_react14.useState)(null);
2373
- const [seededFor, setSeededFor] = (0, import_react14.useState)(null);
2353
+ const [quantity, setQuantity] = (0, import_react13.useState)(1);
2354
+ const [addingToCart, setAddingToCart] = (0, import_react13.useState)(false);
2355
+ const [cartError, setCartError] = (0, import_react13.useState)(null);
2356
+ const [seededFor, setSeededFor] = (0, import_react13.useState)(null);
2374
2357
  const bundle = result.status === "success" && result.bundle.bundleType === "volume" ? result.bundle : null;
2375
- (0, import_react14.useEffect)(() => {
2358
+ (0, import_react13.useEffect)(() => {
2376
2359
  if (!bundle || seededFor === bundle.id) return;
2377
2360
  setSeededFor(bundle.id);
2378
2361
  const tiers = bundle.volumeTiers;
2379
2362
  if (tiers.length === 0) return;
2380
- const best = (0, import_core12.bestValueTierIndex)(
2363
+ const best = (0, import_core11.bestValueTierIndex)(
2381
2364
  tiers,
2382
2365
  bundle.discountConfig.discountType
2383
2366
  );
2384
- const idx = (0, import_core12.resolveDefaultTierIndex)(
2367
+ const idx = (0, import_core11.resolveDefaultTierIndex)(
2385
2368
  bundle.widgetConfig.defaultTier,
2386
2369
  tiers.length,
2387
2370
  best
@@ -2390,7 +2373,7 @@ function VolumeBundle(props) {
2390
2373
  }, [bundle, seededFor]);
2391
2374
  const setConfigVarsRef = useWidgetConfigVars(bundle?.widgetConfig);
2392
2375
  const tiersEdgeFadeRef = useEdgeFade();
2393
- (0, import_react14.useEffect)(() => {
2376
+ (0, import_react13.useEffect)(() => {
2394
2377
  if (result.status === "error") {
2395
2378
  onError?.(result.error);
2396
2379
  return;
@@ -2404,26 +2387,31 @@ function VolumeBundle(props) {
2404
2387
  }
2405
2388
  }, [result, onError]);
2406
2389
  const product = bundle?.products[0];
2407
- const variants = (0, import_react14.useMemo)(() => product?.variants.nodes ?? [], [product]);
2408
- const optionNames = (0, import_react14.useMemo)(() => {
2390
+ const variants = (0, import_react13.useMemo)(() => product?.variants.nodes ?? [], [product]);
2391
+ const optionNames = (0, import_react13.useMemo)(() => {
2409
2392
  const first = variants[0];
2410
2393
  return first ? first.selectedOptions.map((o) => o.name) : [];
2411
2394
  }, [variants]);
2412
2395
  const showPicker = variants.length > 1 && optionNames.length > 0;
2413
2396
  const { selectedValues, selectedVariant, setOptionValue, optionsFor } = useVariantSelection({ variants, optionNames });
2414
- const minTierQty = bundle ? (0, import_core12.getMinTierQuantity)(bundle.volumeTiers) : 1;
2415
- const isSoldOut = variants.length > 0 && !variants.some((v) => (0, import_core12.isVariantFulfillable)(v, minTierQty));
2416
- const displayVariant = selectedVariant ?? variants.find((v) => (0, import_core12.isVariantFulfillable)(v, minTierQty)) ?? variants[0];
2397
+ const minTierQty = bundle ? (0, import_core11.getMinTierQuantity)(bundle.volumeTiers) : 1;
2398
+ const isSoldOut = variants.length > 0 && !variants.some((v) => (0, import_core11.isVariantFulfillable)(v, minTierQty));
2399
+ const displayVariant = selectedVariant ?? variants.find((v) => (0, import_core11.isVariantFulfillable)(v, minTierQty)) ?? variants[0];
2400
+ const tierAvailable = (0, import_react13.useCallback)(
2401
+ (tierQty) => Boolean(displayVariant && (0, import_core11.isVariantFulfillable)(displayVariant, tierQty)),
2402
+ [displayVariant]
2403
+ );
2404
+ const selectedTierUnavailable = !isSoldOut && !tierAvailable(quantity);
2417
2405
  const basePrice = displayVariant ? parseFloat(displayVariant.price.amount) : product ? parseFloat(product.priceRange.minVariantPrice.amount) : 0;
2418
2406
  const currency = product?.priceRange.minVariantPrice.currencyCode ?? "USD";
2419
2407
  const thumbImage = displayVariant?.image ?? product?.featuredImage ?? null;
2420
- const unitPriceText = displayVariant ? (0, import_core12.formatUnitPrice)(
2408
+ const unitPriceText = displayVariant ? (0, import_core11.formatUnitPrice)(
2421
2409
  displayVariant.unitPrice,
2422
2410
  displayVariant.unitPriceMeasurement,
2423
2411
  currency
2424
2412
  ) : null;
2425
- const tierSavings = (0, import_react14.useMemo)(
2426
- () => bundle ? (0, import_core12.calculateTierSavings)(
2413
+ const tierSavings = (0, import_react13.useMemo)(
2414
+ () => bundle ? (0, import_core11.calculateTierSavings)(
2427
2415
  bundle.volumeTiers,
2428
2416
  basePrice,
2429
2417
  quantity,
@@ -2431,13 +2419,13 @@ function VolumeBundle(props) {
2431
2419
  ) : [],
2432
2420
  [bundle, basePrice, quantity]
2433
2421
  );
2434
- const activeTier = bundle ? (0, import_core12.getActiveTier)(bundle.volumeTiers, quantity) : null;
2435
- const popularTierIndex = (0, import_react14.useMemo)(() => {
2422
+ const activeTier = bundle ? (0, import_core11.getActiveTier)(bundle.volumeTiers, quantity) : null;
2423
+ const popularTierIndex = (0, import_react13.useMemo)(() => {
2436
2424
  if (!bundle || bundle.volumeTiers.length === 0) return -1;
2437
- return (0, import_core12.resolvePopularTierIndex)(
2425
+ return (0, import_core11.resolvePopularTierIndex)(
2438
2426
  bundle.widgetConfig.popularBadge.tierIndex,
2439
2427
  bundle.widgetConfig.popularBadge.visible !== false,
2440
- (0, import_core12.bestValueTierIndex)(
2428
+ (0, import_core11.bestValueTierIndex)(
2441
2429
  bundle.volumeTiers,
2442
2430
  bundle.discountConfig.discountType
2443
2431
  )
@@ -2448,10 +2436,10 @@ function VolumeBundle(props) {
2448
2436
  const volumeTotal = activeUnitPrice * quantity;
2449
2437
  const volumeSavings = Math.max(0, undiscountedTotal - volumeTotal);
2450
2438
  const volumeSavingsPercent = undiscountedTotal > 0 && volumeSavings > 0 ? Math.round(volumeSavings / undiscountedTotal * 100) : 0;
2451
- const handleAddToCart = (0, import_react14.useCallback)(async () => {
2439
+ const handleAddToCart = (0, import_react13.useCallback)(async () => {
2452
2440
  if (!bundle || !product) return;
2453
2441
  const variant = selectedVariant ?? product.variants.nodes.find(
2454
- (v) => (0, import_core12.isVariantFulfillable)(v, quantity)
2442
+ (v) => (0, import_core11.isVariantFulfillable)(v, quantity)
2455
2443
  );
2456
2444
  if (!variant) return;
2457
2445
  const lines = [
@@ -2537,7 +2525,7 @@ function VolumeBundle(props) {
2537
2525
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "lb-bundle__product-info", children: [
2538
2526
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "lb-bundle__product-title", children: product.title }),
2539
2527
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { className: "lb-bundle__product-price", children: [
2540
- (0, import_core12.formatMoney)(basePrice, currency),
2528
+ (0, import_core11.formatMoney)(basePrice, currency),
2541
2529
  " each"
2542
2530
  ] }),
2543
2531
  unitPriceText && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "lb-bundle__product-unit-price", children: unitPriceText }),
@@ -2571,16 +2559,20 @@ function VolumeBundle(props) {
2571
2559
  const savingsPercent = Math.round(ts.savingsPercent);
2572
2560
  const showCompare = bundle.widgetConfig.pricing.showComparePrice && ts.savings > 0;
2573
2561
  const isChecked = activeTier === ts.tier;
2562
+ const available = tierAvailable(ts.tier.minQuantity);
2574
2563
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
2575
2564
  "div",
2576
2565
  {
2577
- className: `lb-bundle__tier ${ts.isActive ? "lb-bundle__tier--active" : ""}`,
2566
+ className: `lb-bundle__tier ${ts.isActive ? "lb-bundle__tier--active" : ""} ${available ? "" : "lb-bundle__tier--oos"}`,
2578
2567
  role: "radio",
2579
2568
  "aria-checked": isChecked,
2569
+ "aria-disabled": available ? void 0 : true,
2580
2570
  tabIndex: isChecked ? 0 : -1,
2581
- onClick: () => setQuantity(ts.tier.minQuantity),
2571
+ onClick: () => {
2572
+ if (available) setQuantity(ts.tier.minQuantity);
2573
+ },
2582
2574
  onKeyDown: (e) => {
2583
- if (e.key === "Enter" || e.key === " ") {
2575
+ if ((e.key === "Enter" || e.key === " ") && available) {
2584
2576
  e.preventDefault();
2585
2577
  setQuantity(ts.tier.minQuantity);
2586
2578
  }
@@ -2593,8 +2585,8 @@ function VolumeBundle(props) {
2593
2585
  ts.tier.minQuantity
2594
2586
  ] }),
2595
2587
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "lb-bundle__tier-price", children: [
2596
- showCompare && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "lb-bundle__tier-compare", children: (0, import_core12.formatMoney)(basePrice, currency) }),
2597
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: (0, import_core12.formatMoney)(ts.unitPrice, currency) }),
2588
+ showCompare && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "lb-bundle__tier-compare", children: (0, import_core11.formatMoney)(basePrice, currency) }),
2589
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: (0, import_core11.formatMoney)(ts.unitPrice, currency) }),
2598
2590
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "lb-bundle__tier-unit", children: "each" })
2599
2591
  ] })
2600
2592
  ] }),
@@ -2649,7 +2641,7 @@ function VolumeBundle(props) {
2649
2641
  ] })
2650
2642
  ] }),
2651
2643
  cartError && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "lb-bundle__error", role: "alert", children: cartError }),
2652
- bundle && displayVariant && (0, import_core12.shouldShowLowStockBadge)(
2644
+ bundle && displayVariant && (0, import_core11.shouldShowLowStockBadge)(
2653
2645
  displayVariant,
2654
2646
  minTierQty,
2655
2647
  bundle.widgetConfig.lowStockThreshold,
@@ -2676,7 +2668,7 @@ function VolumeBundle(props) {
2676
2668
  bundle.widgetConfig.savingsBar.visible && volumeSavings > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { className: "lb-bundle-savings-line", "data-savings-bar": true, children: [
2677
2669
  "You save",
2678
2670
  " ",
2679
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { "data-savings-amount": true, children: (0, import_core12.formatMoney)(volumeSavings, currency) }),
2671
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { "data-savings-amount": true, children: (0, import_core11.formatMoney)(volumeSavings, currency) }),
2680
2672
  " ",
2681
2673
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { "data-savings-percent": true, children: [
2682
2674
  "(",
@@ -2686,8 +2678,8 @@ function VolumeBundle(props) {
2686
2678
  ] })
2687
2679
  ] }),
2688
2680
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "lb-bundle-summary__prices", children: [
2689
- bundle.widgetConfig.pricing.showComparePrice && volumeSavings > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "lb-bundle-compare-price", "data-compare-price": true, children: (0, import_core12.formatMoney)(undiscountedTotal, currency) }),
2690
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "lb-bundle-sale-price", "data-total-price": true, children: (0, import_core12.formatMoney)(volumeTotal, currency) })
2681
+ bundle.widgetConfig.pricing.showComparePrice && volumeSavings > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "lb-bundle-compare-price", "data-compare-price": true, children: (0, import_core11.formatMoney)(undiscountedTotal, currency) }),
2682
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "lb-bundle-sale-price", "data-total-price": true, children: (0, import_core11.formatMoney)(volumeTotal, currency) })
2691
2683
  ] })
2692
2684
  ] }),
2693
2685
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
@@ -2695,9 +2687,9 @@ function VolumeBundle(props) {
2695
2687
  {
2696
2688
  className: "lb-bundle__cta",
2697
2689
  onClick: handleAddToCart,
2698
- disabled: addingToCart || isSoldOut,
2690
+ disabled: addingToCart || isSoldOut || selectedTierUnavailable,
2699
2691
  "aria-busy": addingToCart,
2700
- children: addingToCart ? "Adding..." : isSoldOut ? "Sold out" : bundle.widgetConfig.cta.ctaText ?? `Add ${quantity} to Cart`
2692
+ children: addingToCart ? "Adding..." : isSoldOut || selectedTierUnavailable ? "Sold out" : bundle.widgetConfig.cta.ctaText ?? `Add ${quantity} to Cart`
2701
2693
  }
2702
2694
  )
2703
2695
  ]
@@ -2706,8 +2698,8 @@ function VolumeBundle(props) {
2706
2698
  }
2707
2699
 
2708
2700
  // src/components/BogoBundle.tsx
2709
- var import_react15 = require("react");
2710
- var import_core13 = require("@lime-bundles/core");
2701
+ var import_react14 = require("react");
2702
+ var import_core12 = require("@lime-bundles/core");
2711
2703
  var import_jsx_runtime7 = require("react/jsx-runtime");
2712
2704
  function discountedUnit(price, percent) {
2713
2705
  const cents = Math.round(price * 100);
@@ -2737,10 +2729,10 @@ function BogoBundle(props) {
2737
2729
  bundleType: "bogo",
2738
2730
  enabled: analyticsEnabled !== false
2739
2731
  });
2740
- const [addingToCart, setAddingToCart] = (0, import_react15.useState)(false);
2741
- const [cartError, setCartError] = (0, import_react15.useState)(null);
2742
- const [selectedVariants, setSelectedVariants] = (0, import_react15.useState)({ buy: null, get: null });
2743
- const handleVariantChange = (0, import_react15.useCallback)(
2732
+ const [addingToCart, setAddingToCart] = (0, import_react14.useState)(false);
2733
+ const [cartError, setCartError] = (0, import_react14.useState)(null);
2734
+ const [selectedVariants, setSelectedVariants] = (0, import_react14.useState)({ buy: null, get: null });
2735
+ const handleVariantChange = (0, import_react14.useCallback)(
2744
2736
  (role, variant) => {
2745
2737
  setSelectedVariants((prev) => {
2746
2738
  if (prev[role] === variant) return prev;
@@ -2751,7 +2743,7 @@ function BogoBundle(props) {
2751
2743
  );
2752
2744
  const bundle = result.status === "success" && result.bundle.bundleType === "bogo" ? result.bundle : null;
2753
2745
  const setConfigVarsRef = useWidgetConfigVars(bundle?.widgetConfig);
2754
- (0, import_react15.useEffect)(() => {
2746
+ (0, import_react14.useEffect)(() => {
2755
2747
  if (result.status === "error") {
2756
2748
  onError?.(result.error);
2757
2749
  return;
@@ -2764,28 +2756,28 @@ function BogoBundle(props) {
2764
2756
  );
2765
2757
  }
2766
2758
  }, [result, onError]);
2767
- const buyProduct = (0, import_react15.useMemo)(
2759
+ const buyProduct = (0, import_react14.useMemo)(
2768
2760
  () => bundle?.products.find((p) => p.id === bundle.buyProductId) ?? null,
2769
2761
  [bundle]
2770
2762
  );
2771
- const getProduct = (0, import_react15.useMemo)(
2763
+ const getProduct = (0, import_react14.useMemo)(
2772
2764
  () => bundle?.products.find((p) => p.id === bundle.getProductId) ?? null,
2773
2765
  [bundle]
2774
2766
  );
2775
2767
  const percent = bundle ? Math.min(100, Math.max(0, bundle.discountConfig.discountValue)) : 0;
2776
- const resolveVariant = (0, import_react15.useCallback)(
2768
+ const resolveVariant = (0, import_react14.useCallback)(
2777
2769
  (product, selected, qty) => {
2778
2770
  if (!product) return null;
2779
- return selected ?? product.variants.nodes.find((v) => (0, import_core13.isVariantFulfillable)(v, qty)) ?? product.variants.nodes[0] ?? null;
2771
+ return selected ?? product.variants.nodes.find((v) => (0, import_core12.isVariantFulfillable)(v, qty)) ?? product.variants.nodes[0] ?? null;
2780
2772
  },
2781
2773
  []
2782
2774
  );
2783
- const oosSides = (0, import_react15.useMemo)(() => {
2775
+ const oosSides = (0, import_react14.useMemo)(() => {
2784
2776
  if (!bundle) return 0;
2785
- const short = (product, qty) => !!product && !product.variants.nodes.some((v) => (0, import_core13.isVariantFulfillable)(v, qty));
2777
+ const short = (product, qty) => !!product && !product.variants.nodes.some((v) => (0, import_core12.isVariantFulfillable)(v, qty));
2786
2778
  return (short(buyProduct, bundle.buyQuantity) ? 1 : 0) + (short(getProduct, bundle.getQuantity) ? 1 : 0);
2787
2779
  }, [bundle, buyProduct, getProduct]);
2788
- const handleAddToCart = (0, import_react15.useCallback)(async () => {
2780
+ const handleAddToCart = (0, import_react14.useCallback)(async () => {
2789
2781
  if (!bundle || !buyProduct || !getProduct) return;
2790
2782
  const buyVariant2 = resolveVariant(buyProduct, selectedVariants.buy, bundle.buyQuantity);
2791
2783
  const getVariant2 = resolveVariant(getProduct, selectedVariants.get, bundle.getQuantity);
@@ -2910,7 +2902,7 @@ function BogoBundle(props) {
2910
2902
  showSavings && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { className: "lb-bundle-savings-line", "data-savings-bar": true, children: [
2911
2903
  "You save",
2912
2904
  " ",
2913
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { "data-savings-amount": true, children: (0, import_core13.formatMoney)(savings, currency) }),
2905
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { "data-savings-amount": true, children: (0, import_core12.formatMoney)(savings, currency) }),
2914
2906
  " ",
2915
2907
  /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { "data-savings-percent": true, children: [
2916
2908
  "(",
@@ -2920,8 +2912,8 @@ function BogoBundle(props) {
2920
2912
  ] })
2921
2913
  ] }),
2922
2914
  /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "lb-bundle-summary__prices", children: [
2923
- showCompare && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "lb-bundle-compare-price", "data-compare-price": true, children: (0, import_core13.formatMoney)(comparePrice, currency) }),
2924
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "lb-bundle-sale-price", "data-sale-price": true, children: (0, import_core13.formatMoney)(salePrice, currency) })
2915
+ showCompare && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "lb-bundle-compare-price", "data-compare-price": true, children: (0, import_core12.formatMoney)(comparePrice, currency) }),
2916
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "lb-bundle-sale-price", "data-sale-price": true, children: (0, import_core12.formatMoney)(salePrice, currency) })
2925
2917
  ] })
2926
2918
  ] }),
2927
2919
  cartError && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "lb-bundle__error", role: "alert", children: cartError }),
@@ -2941,7 +2933,7 @@ function BogoBundle(props) {
2941
2933
  }
2942
2934
  function BogoProductRow({ side, product, quantity, percent, badge, currency, onVariantChange }) {
2943
2935
  const variants = product.variants.nodes;
2944
- const optionNames = (0, import_react15.useMemo)(() => {
2936
+ const optionNames = (0, import_react14.useMemo)(() => {
2945
2937
  const first = variants[0];
2946
2938
  return first ? first.selectedOptions.map((o) => o.name) : [];
2947
2939
  }, [variants]);
@@ -2950,15 +2942,15 @@ function BogoProductRow({ side, product, quantity, percent, badge, currency, onV
2950
2942
  variants,
2951
2943
  optionNames
2952
2944
  });
2953
- (0, import_react15.useEffect)(() => {
2945
+ (0, import_react14.useEffect)(() => {
2954
2946
  onVariantChange(side, selectedVariant ?? null);
2955
2947
  }, [selectedVariant, side, onVariantChange]);
2956
- const displayVariant = selectedVariant ?? variants.find((v) => (0, import_core13.isVariantFulfillable)(v, quantity)) ?? variants[0];
2948
+ const displayVariant = selectedVariant ?? variants.find((v) => (0, import_core12.isVariantFulfillable)(v, quantity)) ?? variants[0];
2957
2949
  const unit = displayVariant ? parseFloat(displayVariant.price.amount) : 0;
2958
2950
  const isGet = side === "get" && percent > 0;
2959
- const priceText = isGet ? (0, import_core13.formatMoney)(discountedUnit(unit, percent), currency) : (0, import_core13.formatMoney)(unit, currency);
2960
- const compareAt = isGet ? (0, import_core13.formatMoney)(unit, currency) : displayVariant?.compareAtPrice && parseFloat(displayVariant.compareAtPrice.amount) > unit ? (0, import_core13.formatMoney)(displayVariant.compareAtPrice.amount, currency) : null;
2961
- const unitPriceText = displayVariant ? (0, import_core13.formatUnitPrice)(
2951
+ const priceText = isGet ? (0, import_core12.formatMoney)(discountedUnit(unit, percent), currency) : (0, import_core12.formatMoney)(unit, currency);
2952
+ const compareAt = isGet ? (0, import_core12.formatMoney)(unit, currency) : displayVariant?.compareAtPrice && parseFloat(displayVariant.compareAtPrice.amount) > unit ? (0, import_core12.formatMoney)(displayVariant.compareAtPrice.amount, currency) : null;
2953
+ const unitPriceText = displayVariant ? (0, import_core12.formatUnitPrice)(
2962
2954
  displayVariant.unitPrice,
2963
2955
  displayVariant.unitPriceMeasurement,
2964
2956
  currency
@@ -3023,20 +3015,20 @@ function BogoProductRow({ side, product, quantity, percent, badge, currency, onV
3023
3015
  }
3024
3016
 
3025
3017
  // src/components/MultiStepBundle.tsx
3026
- var import_react17 = require("react");
3027
- var import_core15 = require("@lime-bundles/core");
3018
+ var import_react16 = require("react");
3019
+ var import_core14 = require("@lime-bundles/core");
3028
3020
 
3029
3021
  // src/components/MultiStepPicker.tsx
3030
- var import_react16 = require("react");
3022
+ var import_react15 = require("react");
3031
3023
  var import_react_dom2 = require("react-dom");
3032
- var import_core14 = require("@lime-bundles/core");
3024
+ var import_core13 = require("@lime-bundles/core");
3033
3025
  var import_jsx_runtime8 = require("react/jsx-runtime");
3034
3026
  function ruleFor3(bundle, productId, variantId) {
3035
3027
  if (variantId) {
3036
3028
  const vRule = bundle.variantRules[variantId];
3037
3029
  if (vRule) return vRule;
3038
3030
  }
3039
- return bundle.productRules[productId] ?? import_core14.DEFAULT_PRODUCT_RULE;
3031
+ return bundle.productRules[productId] ?? import_core13.DEFAULT_PRODUCT_RULE;
3040
3032
  }
3041
3033
  function variantRuleFor3(bundle, variantId) {
3042
3034
  return variantId ? bundle.variantRules[variantId] : void 0;
@@ -3044,15 +3036,14 @@ function variantRuleFor3(bundle, variantId) {
3044
3036
  function sanitizeId2(gid) {
3045
3037
  return gid.replace(/[^a-zA-Z0-9_-]/g, "-");
3046
3038
  }
3047
- function buildEligibleProducts2(bundle, stepIndex, oosBehavior) {
3039
+ function buildEligibleProducts2(bundle, stepIndex) {
3048
3040
  const result = [];
3049
- for (const product of (0, import_core14.productsForStep)(bundle, stepIndex)) {
3041
+ for (const product of (0, import_core13.productsForStep)(bundle, stepIndex)) {
3050
3042
  const rule = ruleFor3(bundle, product.id);
3051
3043
  const available = product.variants.nodes.filter(
3052
- (v) => (0, import_core14.isVariantFulfillable)(v, rule.min)
3044
+ (v) => (0, import_core13.isVariantFulfillable)(v, rule.min)
3053
3045
  );
3054
3046
  const isOos = available.length === 0;
3055
- if (isOos && oosBehavior === "hide") continue;
3056
3047
  result.push({
3057
3048
  product,
3058
3049
  variants: product.variants.nodes,
@@ -3067,7 +3058,6 @@ function normalizeText2(str) {
3067
3058
  }
3068
3059
  var FILTERS_ALL2 = "__all__";
3069
3060
  function MultiStepPicker({
3070
- outOfStockBehavior,
3071
3061
  bundle,
3072
3062
  currency,
3073
3063
  initialStep,
@@ -3084,17 +3074,19 @@ function MultiStepPicker({
3084
3074
  }) {
3085
3075
  const wc = bundle.widgetConfig;
3086
3076
  const steps = bundle.steps;
3087
- const overlayRef = (0, import_react16.useRef)(null);
3088
- const dialogRef = (0, import_react16.useRef)(null);
3089
- const titleRef = (0, import_react16.useRef)(null);
3090
- const mouseDownTarget = (0, import_react16.useRef)(null);
3091
- const [open, setOpen] = (0, import_react16.useState)(false);
3092
- const [stepIndex, setStepIndex] = (0, import_react16.useState)(
3077
+ const overlayRef = (0, import_react15.useRef)(null);
3078
+ const dialogRef = (0, import_react15.useRef)(null);
3079
+ const titleRef = (0, import_react15.useRef)(null);
3080
+ const closeBtnRef = (0, import_react15.useRef)(null);
3081
+ const listRef = (0, import_react15.useRef)(null);
3082
+ const mouseDownTarget = (0, import_react15.useRef)(null);
3083
+ const [open, setOpen] = (0, import_react15.useState)(false);
3084
+ const [stepIndex, setStepIndex] = (0, import_react15.useState)(
3093
3085
  () => Math.max(0, Math.min(steps.length - 1, initialStep))
3094
3086
  );
3095
- const [query, setQuery] = (0, import_react16.useState)("");
3096
- const [activeType, setActiveType] = (0, import_react16.useState)(FILTERS_ALL2);
3097
- const [announcement, setAnnouncement] = (0, import_react16.useState)("");
3087
+ const [query, setQuery] = (0, import_react15.useState)("");
3088
+ const [activeType, setActiveType] = (0, import_react15.useState)(FILTERS_ALL2);
3089
+ const [announcement, setAnnouncement] = (0, import_react15.useState)("");
3098
3090
  const step = steps[stepIndex];
3099
3091
  const stepMin = step?.minQuantity ?? 1;
3100
3092
  const stepPicks = selections[stepIndex] ?? [];
@@ -3102,11 +3094,11 @@ function MultiStepPicker({
3102
3094
  const stepIsSatisfied = unitsInStep >= stepMin;
3103
3095
  const isLastStep = stepIndex === steps.length - 1;
3104
3096
  const shownUnits = Math.min(unitsInStep, stepMin);
3105
- const eligible = (0, import_react16.useMemo)(
3106
- () => buildEligibleProducts2(bundle, stepIndex, outOfStockBehavior),
3107
- [bundle, stepIndex, outOfStockBehavior]
3097
+ const eligible = (0, import_react15.useMemo)(
3098
+ () => buildEligibleProducts2(bundle, stepIndex),
3099
+ [bundle, stepIndex]
3108
3100
  );
3109
- const productTypes = (0, import_react16.useMemo)(() => {
3101
+ const productTypes = (0, import_react15.useMemo)(() => {
3110
3102
  const types = [];
3111
3103
  const seen = /* @__PURE__ */ new Set();
3112
3104
  for (const ep of eligible) {
@@ -3119,7 +3111,7 @@ function MultiStepPicker({
3119
3111
  return types;
3120
3112
  }, [eligible]);
3121
3113
  const showFilters = wc.mixMatchShowTypeFilters && productTypes.length >= 2;
3122
- (0, import_react16.useEffect)(() => {
3114
+ (0, import_react15.useEffect)(() => {
3123
3115
  const id = requestAnimationFrame(() => setOpen(true));
3124
3116
  return () => cancelAnimationFrame(id);
3125
3117
  }, []);
@@ -3127,8 +3119,23 @@ function MultiStepPicker({
3127
3119
  useFocusTrap({
3128
3120
  active: true,
3129
3121
  containerRef: dialogRef,
3122
+ initialFocusRef: closeBtnRef,
3130
3123
  onEscape: onClose
3131
3124
  });
3125
+ (0, import_react15.useEffect)(() => {
3126
+ if (listRef.current) listRef.current.scrollTop = 0;
3127
+ }, [stepIndex]);
3128
+ const [selectedAtLoad, setSelectedAtLoad] = (0, import_react15.useState)(
3129
+ () => new Set((selections[stepIndex] ?? []).map((s) => s.productId))
3130
+ );
3131
+ const ordered = (0, import_react15.useMemo)(() => {
3132
+ const front = [];
3133
+ const back = [];
3134
+ for (const ep of eligible) {
3135
+ (selectedAtLoad.has(ep.product.id) ? back : front).push(ep);
3136
+ }
3137
+ return front.concat(back);
3138
+ }, [eligible, selectedAtLoad]);
3132
3139
  function goToStep(i) {
3133
3140
  const clamped = Math.max(0, Math.min(steps.length - 1, i));
3134
3141
  setStepIndex(clamped);
@@ -3136,6 +3143,7 @@ function MultiStepPicker({
3136
3143
  setActiveType(FILTERS_ALL2);
3137
3144
  const target = steps[clamped];
3138
3145
  const targetPicks = selections[clamped] ?? [];
3146
+ setSelectedAtLoad(new Set(targetPicks.map((s) => s.productId)));
3139
3147
  const targetUnits = targetPicks.reduce((sum, s) => sum + s.quantity, 0);
3140
3148
  setAnnouncement(
3141
3149
  `Step ${clamped + 1} of ${steps.length}. ${target.name}. ${Math.min(targetUnits, target.minQuantity)} of ${target.minQuantity} added`
@@ -3143,14 +3151,14 @@ function MultiStepPicker({
3143
3151
  titleRef.current?.focus();
3144
3152
  }
3145
3153
  const subtitle = `Step ${stepIndex + 1} of ${steps.length} \xB7 ${step?.name ?? ""}`;
3146
- const filtered = (0, import_react16.useMemo)(() => {
3154
+ const filtered = (0, import_react15.useMemo)(() => {
3147
3155
  const nq = normalizeText2(query.trim());
3148
- return eligible.filter((ep) => {
3156
+ return ordered.filter((ep) => {
3149
3157
  const matchesQuery = !nq || normalizeText2(ep.product.title).includes(nq);
3150
3158
  const matchesType = activeType === FILTERS_ALL2 || (ep.product.productType ?? "") === activeType;
3151
3159
  return matchesQuery && matchesType;
3152
3160
  });
3153
- }, [eligible, query, activeType]);
3161
+ }, [ordered, query, activeType]);
3154
3162
  const showEmpty = filtered.length === 0 && query.trim().length > 0;
3155
3163
  function onOverlayMouseDown(e) {
3156
3164
  mouseDownTarget.current = e.target;
@@ -3208,6 +3216,7 @@ function MultiStepPicker({
3208
3216
  /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3209
3217
  "button",
3210
3218
  {
3219
+ ref: closeBtnRef,
3211
3220
  type: "button",
3212
3221
  className: "lb-mix-match__modal-close",
3213
3222
  "data-modal-close": true,
@@ -3295,7 +3304,7 @@ function MultiStepPicker({
3295
3304
  })
3296
3305
  }
3297
3306
  ),
3298
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "lb-mix-match__modal-list", "data-modal-list": true, children: filtered.map((ep) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3307
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "lb-mix-match__modal-list", "data-modal-list": true, ref: listRef, children: filtered.map((ep) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3299
3308
  MultiStepPickerRow,
3300
3309
  {
3301
3310
  bundle,
@@ -3386,27 +3395,27 @@ function MultiStepPickerRow({
3386
3395
  const { product, variants, isOos } = eligible;
3387
3396
  const rule = ruleFor3(bundle, product.id);
3388
3397
  const step = bundle.steps[stepIndex];
3389
- const optionNames = (0, import_react16.useMemo)(() => {
3398
+ const optionNames = (0, import_react15.useMemo)(() => {
3390
3399
  const first = variants[0];
3391
3400
  return first ? first.selectedOptions.map((o) => o.name) : [];
3392
3401
  }, [variants]);
3393
3402
  const showPicker = variants.length > 1 && optionNames.length > 0;
3394
3403
  const { selectedValues, selectedVariant, setOptionValue, optionsFor } = useVariantSelection({ variants, optionNames });
3395
- const currentVariant = selectedVariant ?? variants.find((v) => (0, import_core14.isVariantFulfillable)(v, rule.min)) ?? eligible.firstAvailableVariant ?? variants[0] ?? null;
3404
+ const currentVariant = selectedVariant ?? variants.find((v) => (0, import_core13.isVariantFulfillable)(v, rule.min)) ?? eligible.firstAvailableVariant ?? variants[0] ?? null;
3396
3405
  const vRule = ruleFor3(bundle, product.id, currentVariant?.id);
3397
3406
  const variantMax = variantRuleFor3(bundle, currentVariant?.id)?.max;
3398
- const stepPicks = (0, import_react16.useMemo)(
3407
+ const stepPicks = (0, import_react15.useMemo)(
3399
3408
  () => selections[stepIndex] ?? [],
3400
3409
  [selections, stepIndex]
3401
3410
  );
3402
3411
  const unitsInStep = stepPicks.reduce((sum, s) => sum + s.quantity, 0);
3403
- const committedSelection = (0, import_react16.useMemo)(
3412
+ const committedSelection = (0, import_react15.useMemo)(
3404
3413
  () => currentVariant ? stepPicks.find((s) => s.variantId === currentVariant.id) ?? null : null,
3405
3414
  [stepPicks, currentVariant]
3406
3415
  );
3407
3416
  const variantInStep = committedSelection !== null;
3408
3417
  const committedQty = committedSelection?.quantity ?? 0;
3409
- const productOtherUnits = (0, import_react16.useMemo)(() => {
3418
+ const productOtherUnits = (0, import_react15.useMemo)(() => {
3410
3419
  if (!currentVariant) return 0;
3411
3420
  let sum = 0;
3412
3421
  for (let i = 0; i < selections.length; i++) {
@@ -3418,7 +3427,7 @@ function MultiStepPickerRow({
3418
3427
  }
3419
3428
  return sum;
3420
3429
  }, [selections, product.id, currentVariant, stepIndex]);
3421
- const variantOtherUnits = (0, import_react16.useMemo)(() => {
3430
+ const variantOtherUnits = (0, import_react15.useMemo)(() => {
3422
3431
  if (!currentVariant) return 0;
3423
3432
  let sum = 0;
3424
3433
  for (const picks of selections) {
@@ -3430,7 +3439,7 @@ function MultiStepPickerRow({
3430
3439
  }, [selections, currentVariant, committedQty]);
3431
3440
  const swapUnits = currentVariant ? swapUnitsFor?.(stepIndex, product.id, currentVariant.id) ?? 0 : 0;
3432
3441
  const inSwapState = swapUnits >= vRule.min;
3433
- const room = (0, import_core14.stepHeadroom)(step?.maxQuantity ?? null, unitsInStep);
3442
+ const room = (0, import_core13.stepHeadroom)(step?.maxQuantity ?? null, unitsInStep);
3434
3443
  const productHeadroom = Math.min(
3435
3444
  rule.max - productOtherUnits,
3436
3445
  variantMax ?? Infinity
@@ -3439,20 +3448,20 @@ function MultiStepPickerRow({
3439
3448
  productHeadroom,
3440
3449
  room === Number.POSITIVE_INFINITY ? productHeadroom : committedQty + room
3441
3450
  );
3442
- const stockRemaining = currentVariant ? (0, import_core14.maxAddableQuantity)(currentVariant, Number.MAX_SAFE_INTEGER, variantOtherUnits) : 0;
3451
+ const stockRemaining = currentVariant ? (0, import_core13.maxAddableQuantity)(currentVariant, Number.MAX_SAFE_INTEGER, variantOtherUnits) : 0;
3443
3452
  const cap = Math.max(0, Math.min(spotCeiling, stockRemaining));
3444
3453
  const stepperMax = Math.max(vRule.min, cap);
3445
- const [qty, setQty] = (0, import_react16.useState)(vRule.min);
3446
- (0, import_react16.useEffect)(() => {
3454
+ const [qty, setQty] = (0, import_react15.useState)(vRule.min);
3455
+ (0, import_react15.useEffect)(() => {
3447
3456
  setQty((prev) => Math.max(vRule.min, Math.min(prev, stepperMax)));
3448
3457
  }, [stepperMax, vRule.min]);
3449
3458
  const currentVariantId = currentVariant?.id ?? null;
3450
- (0, import_react16.useEffect)(() => {
3459
+ (0, import_react15.useEffect)(() => {
3451
3460
  if (!variantInStep) setQty(vRule.min);
3452
3461
  }, [variantInStep, currentVariantId, vRule.min]);
3453
3462
  if (!currentVariant || !step) return null;
3454
3463
  const thumbImage = currentVariant.image ?? product.featuredImage ?? null;
3455
- const unitPriceText = (0, import_core14.formatUnitPrice)(
3464
+ const unitPriceText = (0, import_core13.formatUnitPrice)(
3456
3465
  currentVariant.unitPrice,
3457
3466
  currentVariant.unitPriceMeasurement,
3458
3467
  currency
@@ -3522,8 +3531,8 @@ function MultiStepPickerRow({
3522
3531
  }
3523
3532
  ) }),
3524
3533
  /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("p", { className: "lb-mix-match__modal-product-price", children: [
3525
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { "data-row-price-sale": true, children: (0, import_core14.formatMoney)(priceCents, currency) }),
3526
- compareCents !== null && compareCents > priceCents && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("s", { className: "lb-mix-match__modal-product-compare", "data-row-compare": true, children: (0, import_core14.formatMoney)(compareCents, currency) })
3534
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { "data-row-price-sale": true, children: (0, import_core13.formatMoney)(priceCents, currency) }),
3535
+ compareCents !== null && compareCents > priceCents && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("s", { className: "lb-mix-match__modal-product-compare", "data-row-compare": true, children: (0, import_core13.formatMoney)(compareCents, currency) })
3527
3536
  ] }),
3528
3537
  unitPriceText && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "lb-mix-match__modal-product-unit-price lb-bundle-product-unit-price", children: unitPriceText }),
3529
3538
  showPicker && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "lb-bundle-variant-option-groups", children: optionNames.map((optionName, optionIndex) => {
@@ -3676,7 +3685,7 @@ function ruleFor4(bundle, productId, variantId) {
3676
3685
  const vRule = bundle.variantRules[variantId];
3677
3686
  if (vRule) return vRule;
3678
3687
  }
3679
- return bundle.productRules[productId] ?? import_core15.DEFAULT_PRODUCT_RULE;
3688
+ return bundle.productRules[productId] ?? import_core14.DEFAULT_PRODUCT_RULE;
3680
3689
  }
3681
3690
  function variantRuleFor4(bundle, variantId) {
3682
3691
  return variantId ? bundle.variantRules[variantId] : void 0;
@@ -3718,10 +3727,6 @@ function MultiStepBundle(props) {
3718
3727
  storefrontAccessToken,
3719
3728
  bundleGid
3720
3729
  });
3721
- const { outOfStockBehavior } = useShopSettings({
3722
- shopDomain,
3723
- storefrontAccessToken
3724
- });
3725
3730
  const { elementRef, trackAddToCart } = useAnalytics({
3726
3731
  shopDomain,
3727
3732
  appUrl: appUrl ?? `https://${shopDomain}`,
@@ -3729,14 +3734,14 @@ function MultiStepBundle(props) {
3729
3734
  bundleType: "multi_step",
3730
3735
  enabled: analyticsEnabled !== false
3731
3736
  });
3732
- const [selections, setSelections] = (0, import_react17.useState)([]);
3733
- const [pickerOpenAt, setPickerOpenAt] = (0, import_react17.useState)(null);
3734
- const [addingToCart, setAddingToCart] = (0, import_react17.useState)(false);
3735
- const [cartError, setCartError] = (0, import_react17.useState)(null);
3737
+ const [selections, setSelections] = (0, import_react16.useState)([]);
3738
+ const [pickerOpenAt, setPickerOpenAt] = (0, import_react16.useState)(null);
3739
+ const [addingToCart, setAddingToCart] = (0, import_react16.useState)(false);
3740
+ const [cartError, setCartError] = (0, import_react16.useState)(null);
3736
3741
  const bundle = result.status === "success" && result.bundle.bundleType === "multi_step" ? result.bundle : null;
3737
3742
  const setConfigVarsRef = useWidgetConfigVars(bundle?.widgetConfig);
3738
3743
  const setModalConfigVarsRef = useWidgetConfigVars(bundle?.widgetConfig);
3739
- (0, import_react17.useEffect)(() => {
3744
+ (0, import_react16.useEffect)(() => {
3740
3745
  if (result.status === "error") {
3741
3746
  onError?.(result.error);
3742
3747
  return;
@@ -3749,17 +3754,17 @@ function MultiStepBundle(props) {
3749
3754
  );
3750
3755
  }
3751
3756
  }, [result, onError]);
3752
- const steps = (0, import_react17.useMemo)(() => bundle?.steps ?? [], [bundle]);
3753
- (0, import_react17.useEffect)(() => {
3757
+ const steps = (0, import_react16.useMemo)(() => bundle?.steps ?? [], [bundle]);
3758
+ (0, import_react16.useEffect)(() => {
3754
3759
  const seeded = steps.map(() => []);
3755
3760
  if (bundle) {
3756
3761
  const seedCurrency = bundle.products[0]?.priceRange.minVariantPrice.currencyCode ?? "USD";
3757
3762
  for (const [pid, rule] of Object.entries(bundle.productRules)) {
3758
3763
  if (!rule.required) continue;
3759
3764
  for (let i = 0; i < steps.length; i++) {
3760
- const product = (0, import_core15.productsForStep)(bundle, i).find((p) => p.id === pid);
3765
+ const product = (0, import_core14.productsForStep)(bundle, i).find((p) => p.id === pid);
3761
3766
  const variant = product?.variants.nodes.find(
3762
- (v) => (0, import_core15.isVariantFulfillable)(v, rule.min)
3767
+ (v) => (0, import_core14.isVariantFulfillable)(v, rule.min)
3763
3768
  );
3764
3769
  if (!product || !variant) continue;
3765
3770
  seeded[i].push({
@@ -3771,7 +3776,7 @@ function MultiStepBundle(props) {
3771
3776
  featuredImage: variant.image?.url ?? product.featuredImage?.url ?? null,
3772
3777
  price: parseFloat(variant.price.amount),
3773
3778
  compareAtPrice: variant.compareAtPrice ? parseFloat(variant.compareAtPrice.amount) : null,
3774
- unitPrice: (0, import_core15.formatUnitPrice)(
3779
+ unitPrice: (0, import_core14.formatUnitPrice)(
3775
3780
  variant.unitPrice,
3776
3781
  variant.unitPriceMeasurement,
3777
3782
  seedCurrency
@@ -3785,26 +3790,26 @@ function MultiStepBundle(props) {
3785
3790
  setSelections(seeded);
3786
3791
  }, [bundle, steps]);
3787
3792
  const showStepper = bundle?.widgetConfig.mixMatchShowQuantitySelector !== false;
3788
- const totalMin = (0, import_react17.useMemo)(
3793
+ const totalMin = (0, import_react16.useMemo)(
3789
3794
  () => steps.reduce((sum, s) => sum + s.minQuantity, 0),
3790
3795
  [steps]
3791
3796
  );
3792
- const unitsByStep = (0, import_react17.useMemo)(
3797
+ const unitsByStep = (0, import_react16.useMemo)(
3793
3798
  () => selections.map((picks) => picks.reduce((sum, s) => sum + s.quantity, 0)),
3794
3799
  [selections]
3795
3800
  );
3796
- const totalQuantity = (0, import_react17.useMemo)(
3801
+ const totalQuantity = (0, import_react16.useMemo)(
3797
3802
  () => unitsByStep.reduce((sum, u) => sum + u, 0),
3798
3803
  [unitsByStep]
3799
3804
  );
3800
- const stepSatisfied = (0, import_react17.useCallback)(
3805
+ const stepSatisfied = (0, import_react16.useCallback)(
3801
3806
  (i) => (unitsByStep[i] ?? 0) >= (steps[i]?.minQuantity ?? 1),
3802
3807
  [unitsByStep, steps]
3803
3808
  );
3804
3809
  const allSatisfied = steps.length > 0 && steps.every((_, i) => stepSatisfied(i));
3805
3810
  const valid = !!bundle && allSatisfied;
3806
3811
  const completedSteps = steps.filter((_, i) => stepSatisfied(i)).length;
3807
- const summary = (0, import_react17.useMemo)(() => {
3812
+ const summary = (0, import_react16.useMemo)(() => {
3808
3813
  let comparePrice = 0;
3809
3814
  let salePrice = 0;
3810
3815
  for (const stepPicks of selections) {
@@ -3812,7 +3817,7 @@ function MultiStepBundle(props) {
3812
3817
  if (sel.quantity <= 0) continue;
3813
3818
  comparePrice += sel.price * sel.quantity;
3814
3819
  if (bundle) {
3815
- salePrice += (0, import_core15.calculateDiscount)(
3820
+ salePrice += (0, import_core14.calculateDiscount)(
3816
3821
  sel.price,
3817
3822
  bundle.discountConfig.discountType,
3818
3823
  bundle.discountConfig.discountValue
@@ -3824,7 +3829,7 @@ function MultiStepBundle(props) {
3824
3829
  const savingsPercent = comparePrice > 0 && savings > 0 ? Math.round(savings / comparePrice * 100) : 0;
3825
3830
  return { comparePrice, salePrice, savings, savingsPercent };
3826
3831
  }, [selections, bundle]);
3827
- const addSelection = (0, import_react17.useCallback)((step, item) => {
3832
+ const addSelection = (0, import_react16.useCallback)((step, item) => {
3828
3833
  setSelections((prev) => {
3829
3834
  if (step < 0 || step >= prev.length) return prev;
3830
3835
  if (prev[step].some((s) => s.variantId === item.variantId)) return prev;
@@ -3833,7 +3838,7 @@ function MultiStepBundle(props) {
3833
3838
  return next;
3834
3839
  });
3835
3840
  }, []);
3836
- const swapSelection = (0, import_react17.useCallback)(
3841
+ const swapSelection = (0, import_react16.useCallback)(
3837
3842
  (step, item) => {
3838
3843
  setSelections((prev) => {
3839
3844
  if (!bundle || step < 0 || step >= prev.length) return prev;
@@ -3868,7 +3873,7 @@ function MultiStepBundle(props) {
3868
3873
  },
3869
3874
  [bundle]
3870
3875
  );
3871
- const updateQuantity = (0, import_react17.useCallback)(
3876
+ const updateQuantity = (0, import_react16.useCallback)(
3872
3877
  (step, productId, variantId, quantity) => {
3873
3878
  setSelections((prev) => {
3874
3879
  if (step < 0 || step >= prev.length) return prev;
@@ -3887,7 +3892,7 @@ function MultiStepBundle(props) {
3887
3892
  },
3888
3893
  []
3889
3894
  );
3890
- const removeVariant = (0, import_react17.useCallback)(
3895
+ const removeVariant = (0, import_react16.useCallback)(
3891
3896
  (step, variantId) => {
3892
3897
  setSelections((prev) => {
3893
3898
  if (step < 0 || step >= prev.length) return prev;
@@ -3903,7 +3908,7 @@ function MultiStepBundle(props) {
3903
3908
  },
3904
3909
  [bundle]
3905
3910
  );
3906
- const removeSlot = (0, import_react17.useCallback)(
3911
+ const removeSlot = (0, import_react16.useCallback)(
3907
3912
  (step, index) => {
3908
3913
  setSelections((prev) => {
3909
3914
  if (step < 0 || step >= prev.length) return prev;
@@ -3919,7 +3924,7 @@ function MultiStepBundle(props) {
3919
3924
  },
3920
3925
  [bundle]
3921
3926
  );
3922
- const handleAddToCart = (0, import_react17.useCallback)(async () => {
3927
+ const handleAddToCart = (0, import_react16.useCallback)(async () => {
3923
3928
  if (!bundle || !valid) return;
3924
3929
  const grouped = /* @__PURE__ */ new Map();
3925
3930
  for (const stepPicks of selections) {
@@ -3974,8 +3979,8 @@ function MultiStepBundle(props) {
3974
3979
  ([pid, rule]) => {
3975
3980
  if (!rule.required) return false;
3976
3981
  return !steps.some(
3977
- (_, i) => (0, import_core15.productsForStep)(bundle, i).some(
3978
- (p) => p.id === pid && p.variants.nodes.some((v) => (0, import_core15.isVariantFulfillable)(v, rule.min))
3982
+ (_, i) => (0, import_core14.productsForStep)(bundle, i).some(
3983
+ (p) => p.id === pid && p.variants.nodes.some((v) => (0, import_core14.isVariantFulfillable)(v, rule.min))
3979
3984
  )
3980
3985
  );
3981
3986
  }
@@ -4099,8 +4104,8 @@ function MultiStepBundle(props) {
4099
4104
  ),
4100
4105
  item.variantTitle && item.variantTitle !== "Default Title" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-mix-match__filled-variant", children: item.variantTitle }),
4101
4106
  /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "lb-mix-match__filled-price", children: [
4102
- item.compareAtPrice !== null && item.compareAtPrice > item.price && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("s", { className: "lb-mix-match__filled-compare", children: (0, import_core15.formatMoney)(item.compareAtPrice, currency) }),
4103
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-bundle-product-price", children: (0, import_core15.formatMoney)(item.price, currency) }),
4107
+ item.compareAtPrice !== null && item.compareAtPrice > item.price && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("s", { className: "lb-mix-match__filled-compare", children: (0, import_core14.formatMoney)(item.compareAtPrice, currency) }),
4108
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-bundle-product-price", children: (0, import_core14.formatMoney)(item.price, currency) }),
4104
4109
  /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-bundle-qty-inline", children: `\xD7${item.quantity}` })
4105
4110
  ] }),
4106
4111
  item.unitPrice && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-bundle-product-unit-price", children: item.unitPrice })
@@ -4130,7 +4135,7 @@ function MultiStepBundle(props) {
4130
4135
  ))
4131
4136
  }
4132
4137
  ),
4133
- (0, import_core15.stepHeadroom)(step.maxQuantity, unitsByStep[i] ?? 0) !== 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4138
+ (0, import_core14.stepHeadroom)(step.maxQuantity, unitsByStep[i] ?? 0) !== 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4134
4139
  "button",
4135
4140
  {
4136
4141
  type: "button",
@@ -4162,7 +4167,7 @@ function MultiStepBundle(props) {
4162
4167
  bundle.widgetConfig.savingsBar.visible && summary.savings > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("p", { className: "lb-bundle-savings-line", "data-savings-bar": true, children: [
4163
4168
  "You save",
4164
4169
  " ",
4165
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { "data-savings-amount": true, children: (0, import_core15.formatMoney)(summary.savings, currency) }),
4170
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { "data-savings-amount": true, children: (0, import_core14.formatMoney)(summary.savings, currency) }),
4166
4171
  " ",
4167
4172
  /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { "data-savings-percent": true, children: [
4168
4173
  "(",
@@ -4172,8 +4177,8 @@ function MultiStepBundle(props) {
4172
4177
  ] })
4173
4178
  ] }),
4174
4179
  /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "lb-bundle-summary__prices", children: [
4175
- bundle.widgetConfig.pricing.showComparePrice && summary.savings > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-bundle-compare-price", "data-compare-price": true, children: (0, import_core15.formatMoney)(summary.comparePrice, currency) }),
4176
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-bundle-sale-price", "data-sale-price": true, children: (0, import_core15.formatMoney)(summary.salePrice, currency) })
4180
+ bundle.widgetConfig.pricing.showComparePrice && summary.savings > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-bundle-compare-price", "data-compare-price": true, children: (0, import_core14.formatMoney)(summary.comparePrice, currency) }),
4181
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-bundle-sale-price", "data-sale-price": true, children: (0, import_core14.formatMoney)(summary.salePrice, currency) })
4177
4182
  ] })
4178
4183
  ] }),
4179
4184
  cartError && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "lb-bundle__error", role: "alert", children: cartError }),
@@ -4190,7 +4195,6 @@ function MultiStepBundle(props) {
4190
4195
  pickerOpenAt !== null && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4191
4196
  MultiStepPicker,
4192
4197
  {
4193
- outOfStockBehavior,
4194
4198
  bundle,
4195
4199
  currency,
4196
4200
  initialStep: pickerOpenAt,
@@ -4217,9 +4221,9 @@ function MultiStepBundle(props) {
4217
4221
  );
4218
4222
  }
4219
4223
  function stepHasInStockProduct(bundle, stepIndex) {
4220
- return (0, import_core15.productsForStep)(bundle, stepIndex).some((product) => {
4224
+ return (0, import_core14.productsForStep)(bundle, stepIndex).some((product) => {
4221
4225
  const rule = ruleFor4(bundle, product.id);
4222
- return product.variants.nodes.some((v) => (0, import_core15.isVariantFulfillable)(v, rule.min));
4226
+ return product.variants.nodes.some((v) => (0, import_core14.isVariantFulfillable)(v, rule.min));
4223
4227
  });
4224
4228
  }
4225
4229
  function PlusIcon2() {
@@ -4264,21 +4268,21 @@ async function fetchShopCustomCss(options) {
4264
4268
  }
4265
4269
 
4266
4270
  // src/hooks/useBundlesForProduct.ts
4267
- var import_react18 = require("react");
4268
- var import_core16 = require("@lime-bundles/core");
4271
+ var import_react17 = require("react");
4272
+ var import_core15 = require("@lime-bundles/core");
4269
4273
  var INITIAL_STATE2 = {
4270
4274
  status: "loading",
4271
4275
  bundles: null,
4272
4276
  error: null
4273
4277
  };
4274
4278
  function useBundlesForProduct(options) {
4275
- const [state, setState] = (0, import_react18.useState)(
4279
+ const [state, setState] = (0, import_react17.useState)(
4276
4280
  INITIAL_STATE2
4277
4281
  );
4278
- (0, import_react18.useEffect)(() => {
4282
+ (0, import_react17.useEffect)(() => {
4279
4283
  const controller = new AbortController();
4280
4284
  setState(INITIAL_STATE2);
4281
- (0, import_core16.fetchBundlesForProduct)({
4285
+ (0, import_core15.fetchBundlesForProduct)({
4282
4286
  shopDomain: options.shopDomain,
4283
4287
  storefrontAccessToken: options.storefrontAccessToken,
4284
4288
  productHandle: options.productHandle,
@@ -4301,7 +4305,7 @@ function useBundlesForProduct(options) {
4301
4305
  signal: controller.signal
4302
4306
  }).then((settings) => {
4303
4307
  if (controller.signal.aborted) return;
4304
- (0, import_core16.injectCustomCss)(options.shopDomain, settings.customCss);
4308
+ (0, import_core15.injectCustomCss)(options.shopDomain, settings.customCss);
4305
4309
  }).catch(() => {
4306
4310
  });
4307
4311
  return () => {
@@ -4317,8 +4321,8 @@ function useBundlesForProduct(options) {
4317
4321
  }
4318
4322
 
4319
4323
  // src/index.ts
4324
+ var import_core16 = require("@lime-bundles/core");
4320
4325
  var import_core17 = require("@lime-bundles/core");
4321
- var import_core18 = require("@lime-bundles/core");
4322
4326
  // Annotate the CommonJS export names for ESM import in node:
4323
4327
  0 && (module.exports = {
4324
4328
  BUNDLES_FOR_PRODUCT_QUERY,
@@ -4326,7 +4330,6 @@ var import_core18 = require("@lime-bundles/core");
4326
4330
  BogoBundle,
4327
4331
  BundleCountdown,
4328
4332
  BundleParseError,
4329
- DEFAULT_OUT_OF_STOCK_BEHAVIOR,
4330
4333
  FixedBundle,
4331
4334
  MixMatchBundle,
4332
4335
  MultiStepBundle,
@@ -4357,7 +4360,6 @@ var import_core18 = require("@lime-bundles/core");
4357
4360
  parseCents,
4358
4361
  parseMetaobjectBundle,
4359
4362
  parseMetaobjectBundleStrict,
4360
- parseOutOfStockBehavior,
4361
4363
  percentageDiscountUnit,
4362
4364
  productsForStep,
4363
4365
  reportAddToCart,
@@ -4369,7 +4371,6 @@ var import_core18 = require("@lime-bundles/core");
4369
4371
  useAnalytics,
4370
4372
  useBundleData,
4371
4373
  useBundlesForProduct,
4372
- useShopSettings,
4373
4374
  useVariantSelection,
4374
4375
  useWidgetConfigVars,
4375
4376
  validateQuantity