@lime-bundles/react 6.2.0 → 7.1.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 {
@@ -2353,7 +2336,8 @@ function VolumeBundle(props) {
2353
2336
  analyticsEnabled,
2354
2337
  onAddToCart,
2355
2338
  onError,
2356
- className
2339
+ className,
2340
+ productId
2357
2341
  } = props;
2358
2342
  const result = useBundleData({
2359
2343
  shopDomain,
@@ -2367,21 +2351,21 @@ function VolumeBundle(props) {
2367
2351
  bundleType: "volume",
2368
2352
  enabled: analyticsEnabled !== false
2369
2353
  });
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);
2354
+ const [quantity, setQuantity] = (0, import_react13.useState)(1);
2355
+ const [addingToCart, setAddingToCart] = (0, import_react13.useState)(false);
2356
+ const [cartError, setCartError] = (0, import_react13.useState)(null);
2357
+ const [seededFor, setSeededFor] = (0, import_react13.useState)(null);
2374
2358
  const bundle = result.status === "success" && result.bundle.bundleType === "volume" ? result.bundle : null;
2375
- (0, import_react14.useEffect)(() => {
2359
+ (0, import_react13.useEffect)(() => {
2376
2360
  if (!bundle || seededFor === bundle.id) return;
2377
2361
  setSeededFor(bundle.id);
2378
2362
  const tiers = bundle.volumeTiers;
2379
2363
  if (tiers.length === 0) return;
2380
- const best = (0, import_core12.bestValueTierIndex)(
2364
+ const best = (0, import_core11.bestValueTierIndex)(
2381
2365
  tiers,
2382
2366
  bundle.discountConfig.discountType
2383
2367
  );
2384
- const idx = (0, import_core12.resolveDefaultTierIndex)(
2368
+ const idx = (0, import_core11.resolveDefaultTierIndex)(
2385
2369
  bundle.widgetConfig.defaultTier,
2386
2370
  tiers.length,
2387
2371
  best
@@ -2390,7 +2374,7 @@ function VolumeBundle(props) {
2390
2374
  }, [bundle, seededFor]);
2391
2375
  const setConfigVarsRef = useWidgetConfigVars(bundle?.widgetConfig);
2392
2376
  const tiersEdgeFadeRef = useEdgeFade();
2393
- (0, import_react14.useEffect)(() => {
2377
+ (0, import_react13.useEffect)(() => {
2394
2378
  if (result.status === "error") {
2395
2379
  onError?.(result.error);
2396
2380
  return;
@@ -2403,27 +2387,32 @@ function VolumeBundle(props) {
2403
2387
  );
2404
2388
  }
2405
2389
  }, [result, onError]);
2406
- 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 product = bundle ? (0, import_core11.resolveContextProduct)(bundle.products, { productId }) : void 0;
2391
+ const variants = (0, import_react13.useMemo)(() => product?.variants.nodes ?? [], [product]);
2392
+ const optionNames = (0, import_react13.useMemo)(() => {
2409
2393
  const first = variants[0];
2410
2394
  return first ? first.selectedOptions.map((o) => o.name) : [];
2411
2395
  }, [variants]);
2412
2396
  const showPicker = variants.length > 1 && optionNames.length > 0;
2413
2397
  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];
2398
+ const minTierQty = bundle ? (0, import_core11.getMinTierQuantity)(bundle.volumeTiers) : 1;
2399
+ const isSoldOut = variants.length > 0 && !variants.some((v) => (0, import_core11.isVariantFulfillable)(v, minTierQty));
2400
+ const displayVariant = selectedVariant ?? variants.find((v) => (0, import_core11.isVariantFulfillable)(v, minTierQty)) ?? variants[0];
2401
+ const tierAvailable = (0, import_react13.useCallback)(
2402
+ (tierQty) => Boolean(displayVariant && (0, import_core11.isVariantFulfillable)(displayVariant, tierQty)),
2403
+ [displayVariant]
2404
+ );
2405
+ const selectedTierUnavailable = !isSoldOut && !tierAvailable(quantity);
2417
2406
  const basePrice = displayVariant ? parseFloat(displayVariant.price.amount) : product ? parseFloat(product.priceRange.minVariantPrice.amount) : 0;
2418
2407
  const currency = product?.priceRange.minVariantPrice.currencyCode ?? "USD";
2419
2408
  const thumbImage = displayVariant?.image ?? product?.featuredImage ?? null;
2420
- const unitPriceText = displayVariant ? (0, import_core12.formatUnitPrice)(
2409
+ const unitPriceText = displayVariant ? (0, import_core11.formatUnitPrice)(
2421
2410
  displayVariant.unitPrice,
2422
2411
  displayVariant.unitPriceMeasurement,
2423
2412
  currency
2424
2413
  ) : null;
2425
- const tierSavings = (0, import_react14.useMemo)(
2426
- () => bundle ? (0, import_core12.calculateTierSavings)(
2414
+ const tierSavings = (0, import_react13.useMemo)(
2415
+ () => bundle ? (0, import_core11.calculateTierSavings)(
2427
2416
  bundle.volumeTiers,
2428
2417
  basePrice,
2429
2418
  quantity,
@@ -2431,13 +2420,13 @@ function VolumeBundle(props) {
2431
2420
  ) : [],
2432
2421
  [bundle, basePrice, quantity]
2433
2422
  );
2434
- const activeTier = bundle ? (0, import_core12.getActiveTier)(bundle.volumeTiers, quantity) : null;
2435
- const popularTierIndex = (0, import_react14.useMemo)(() => {
2423
+ const activeTier = bundle ? (0, import_core11.getActiveTier)(bundle.volumeTiers, quantity) : null;
2424
+ const popularTierIndex = (0, import_react13.useMemo)(() => {
2436
2425
  if (!bundle || bundle.volumeTiers.length === 0) return -1;
2437
- return (0, import_core12.resolvePopularTierIndex)(
2426
+ return (0, import_core11.resolvePopularTierIndex)(
2438
2427
  bundle.widgetConfig.popularBadge.tierIndex,
2439
2428
  bundle.widgetConfig.popularBadge.visible !== false,
2440
- (0, import_core12.bestValueTierIndex)(
2429
+ (0, import_core11.bestValueTierIndex)(
2441
2430
  bundle.volumeTiers,
2442
2431
  bundle.discountConfig.discountType
2443
2432
  )
@@ -2448,10 +2437,10 @@ function VolumeBundle(props) {
2448
2437
  const volumeTotal = activeUnitPrice * quantity;
2449
2438
  const volumeSavings = Math.max(0, undiscountedTotal - volumeTotal);
2450
2439
  const volumeSavingsPercent = undiscountedTotal > 0 && volumeSavings > 0 ? Math.round(volumeSavings / undiscountedTotal * 100) : 0;
2451
- const handleAddToCart = (0, import_react14.useCallback)(async () => {
2440
+ const handleAddToCart = (0, import_react13.useCallback)(async () => {
2452
2441
  if (!bundle || !product) return;
2453
2442
  const variant = selectedVariant ?? product.variants.nodes.find(
2454
- (v) => (0, import_core12.isVariantFulfillable)(v, quantity)
2443
+ (v) => (0, import_core11.isVariantFulfillable)(v, quantity)
2455
2444
  );
2456
2445
  if (!variant) return;
2457
2446
  const lines = [
@@ -2537,7 +2526,7 @@ function VolumeBundle(props) {
2537
2526
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "lb-bundle__product-info", children: [
2538
2527
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "lb-bundle__product-title", children: product.title }),
2539
2528
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { className: "lb-bundle__product-price", children: [
2540
- (0, import_core12.formatMoney)(basePrice, currency),
2529
+ (0, import_core11.formatMoney)(basePrice, currency),
2541
2530
  " each"
2542
2531
  ] }),
2543
2532
  unitPriceText && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "lb-bundle__product-unit-price", children: unitPriceText }),
@@ -2571,16 +2560,20 @@ function VolumeBundle(props) {
2571
2560
  const savingsPercent = Math.round(ts.savingsPercent);
2572
2561
  const showCompare = bundle.widgetConfig.pricing.showComparePrice && ts.savings > 0;
2573
2562
  const isChecked = activeTier === ts.tier;
2563
+ const available = tierAvailable(ts.tier.minQuantity);
2574
2564
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
2575
2565
  "div",
2576
2566
  {
2577
- className: `lb-bundle__tier ${ts.isActive ? "lb-bundle__tier--active" : ""}`,
2567
+ className: `lb-bundle__tier ${ts.isActive ? "lb-bundle__tier--active" : ""} ${available ? "" : "lb-bundle__tier--oos"}`,
2578
2568
  role: "radio",
2579
2569
  "aria-checked": isChecked,
2570
+ "aria-disabled": available ? void 0 : true,
2580
2571
  tabIndex: isChecked ? 0 : -1,
2581
- onClick: () => setQuantity(ts.tier.minQuantity),
2572
+ onClick: () => {
2573
+ if (available) setQuantity(ts.tier.minQuantity);
2574
+ },
2582
2575
  onKeyDown: (e) => {
2583
- if (e.key === "Enter" || e.key === " ") {
2576
+ if ((e.key === "Enter" || e.key === " ") && available) {
2584
2577
  e.preventDefault();
2585
2578
  setQuantity(ts.tier.minQuantity);
2586
2579
  }
@@ -2593,8 +2586,8 @@ function VolumeBundle(props) {
2593
2586
  ts.tier.minQuantity
2594
2587
  ] }),
2595
2588
  /* @__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) }),
2589
+ showCompare && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "lb-bundle__tier-compare", children: (0, import_core11.formatMoney)(basePrice, currency) }),
2590
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: (0, import_core11.formatMoney)(ts.unitPrice, currency) }),
2598
2591
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "lb-bundle__tier-unit", children: "each" })
2599
2592
  ] })
2600
2593
  ] }),
@@ -2649,7 +2642,7 @@ function VolumeBundle(props) {
2649
2642
  ] })
2650
2643
  ] }),
2651
2644
  cartError && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "lb-bundle__error", role: "alert", children: cartError }),
2652
- bundle && displayVariant && (0, import_core12.shouldShowLowStockBadge)(
2645
+ bundle && displayVariant && (0, import_core11.shouldShowLowStockBadge)(
2653
2646
  displayVariant,
2654
2647
  minTierQty,
2655
2648
  bundle.widgetConfig.lowStockThreshold,
@@ -2676,7 +2669,7 @@ function VolumeBundle(props) {
2676
2669
  bundle.widgetConfig.savingsBar.visible && volumeSavings > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { className: "lb-bundle-savings-line", "data-savings-bar": true, children: [
2677
2670
  "You save",
2678
2671
  " ",
2679
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { "data-savings-amount": true, children: (0, import_core12.formatMoney)(volumeSavings, currency) }),
2672
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { "data-savings-amount": true, children: (0, import_core11.formatMoney)(volumeSavings, currency) }),
2680
2673
  " ",
2681
2674
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { "data-savings-percent": true, children: [
2682
2675
  "(",
@@ -2686,8 +2679,8 @@ function VolumeBundle(props) {
2686
2679
  ] })
2687
2680
  ] }),
2688
2681
  /* @__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) })
2682
+ 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) }),
2683
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "lb-bundle-sale-price", "data-total-price": true, children: (0, import_core11.formatMoney)(volumeTotal, currency) })
2691
2684
  ] })
2692
2685
  ] }),
2693
2686
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
@@ -2695,9 +2688,9 @@ function VolumeBundle(props) {
2695
2688
  {
2696
2689
  className: "lb-bundle__cta",
2697
2690
  onClick: handleAddToCart,
2698
- disabled: addingToCart || isSoldOut,
2691
+ disabled: addingToCart || isSoldOut || selectedTierUnavailable,
2699
2692
  "aria-busy": addingToCart,
2700
- children: addingToCart ? "Adding..." : isSoldOut ? "Sold out" : bundle.widgetConfig.cta.ctaText ?? `Add ${quantity} to Cart`
2693
+ children: addingToCart ? "Adding..." : isSoldOut || selectedTierUnavailable ? "Sold out" : bundle.widgetConfig.cta.ctaText ?? `Add ${quantity} to Cart`
2701
2694
  }
2702
2695
  )
2703
2696
  ]
@@ -2706,8 +2699,8 @@ function VolumeBundle(props) {
2706
2699
  }
2707
2700
 
2708
2701
  // src/components/BogoBundle.tsx
2709
- var import_react15 = require("react");
2710
- var import_core13 = require("@lime-bundles/core");
2702
+ var import_react14 = require("react");
2703
+ var import_core12 = require("@lime-bundles/core");
2711
2704
  var import_jsx_runtime7 = require("react/jsx-runtime");
2712
2705
  function discountedUnit(price, percent) {
2713
2706
  const cents = Math.round(price * 100);
@@ -2737,10 +2730,10 @@ function BogoBundle(props) {
2737
2730
  bundleType: "bogo",
2738
2731
  enabled: analyticsEnabled !== false
2739
2732
  });
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)(
2733
+ const [addingToCart, setAddingToCart] = (0, import_react14.useState)(false);
2734
+ const [cartError, setCartError] = (0, import_react14.useState)(null);
2735
+ const [selectedVariants, setSelectedVariants] = (0, import_react14.useState)({ buy: null, get: null });
2736
+ const handleVariantChange = (0, import_react14.useCallback)(
2744
2737
  (role, variant) => {
2745
2738
  setSelectedVariants((prev) => {
2746
2739
  if (prev[role] === variant) return prev;
@@ -2751,7 +2744,7 @@ function BogoBundle(props) {
2751
2744
  );
2752
2745
  const bundle = result.status === "success" && result.bundle.bundleType === "bogo" ? result.bundle : null;
2753
2746
  const setConfigVarsRef = useWidgetConfigVars(bundle?.widgetConfig);
2754
- (0, import_react15.useEffect)(() => {
2747
+ (0, import_react14.useEffect)(() => {
2755
2748
  if (result.status === "error") {
2756
2749
  onError?.(result.error);
2757
2750
  return;
@@ -2764,28 +2757,28 @@ function BogoBundle(props) {
2764
2757
  );
2765
2758
  }
2766
2759
  }, [result, onError]);
2767
- const buyProduct = (0, import_react15.useMemo)(
2760
+ const buyProduct = (0, import_react14.useMemo)(
2768
2761
  () => bundle?.products.find((p) => p.id === bundle.buyProductId) ?? null,
2769
2762
  [bundle]
2770
2763
  );
2771
- const getProduct = (0, import_react15.useMemo)(
2764
+ const getProduct = (0, import_react14.useMemo)(
2772
2765
  () => bundle?.products.find((p) => p.id === bundle.getProductId) ?? null,
2773
2766
  [bundle]
2774
2767
  );
2775
2768
  const percent = bundle ? Math.min(100, Math.max(0, bundle.discountConfig.discountValue)) : 0;
2776
- const resolveVariant = (0, import_react15.useCallback)(
2769
+ const resolveVariant = (0, import_react14.useCallback)(
2777
2770
  (product, selected, qty) => {
2778
2771
  if (!product) return null;
2779
- return selected ?? product.variants.nodes.find((v) => (0, import_core13.isVariantFulfillable)(v, qty)) ?? product.variants.nodes[0] ?? null;
2772
+ return selected ?? product.variants.nodes.find((v) => (0, import_core12.isVariantFulfillable)(v, qty)) ?? product.variants.nodes[0] ?? null;
2780
2773
  },
2781
2774
  []
2782
2775
  );
2783
- const oosSides = (0, import_react15.useMemo)(() => {
2776
+ const oosSides = (0, import_react14.useMemo)(() => {
2784
2777
  if (!bundle) return 0;
2785
- const short = (product, qty) => !!product && !product.variants.nodes.some((v) => (0, import_core13.isVariantFulfillable)(v, qty));
2778
+ const short = (product, qty) => !!product && !product.variants.nodes.some((v) => (0, import_core12.isVariantFulfillable)(v, qty));
2786
2779
  return (short(buyProduct, bundle.buyQuantity) ? 1 : 0) + (short(getProduct, bundle.getQuantity) ? 1 : 0);
2787
2780
  }, [bundle, buyProduct, getProduct]);
2788
- const handleAddToCart = (0, import_react15.useCallback)(async () => {
2781
+ const handleAddToCart = (0, import_react14.useCallback)(async () => {
2789
2782
  if (!bundle || !buyProduct || !getProduct) return;
2790
2783
  const buyVariant2 = resolveVariant(buyProduct, selectedVariants.buy, bundle.buyQuantity);
2791
2784
  const getVariant2 = resolveVariant(getProduct, selectedVariants.get, bundle.getQuantity);
@@ -2910,7 +2903,7 @@ function BogoBundle(props) {
2910
2903
  showSavings && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { className: "lb-bundle-savings-line", "data-savings-bar": true, children: [
2911
2904
  "You save",
2912
2905
  " ",
2913
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { "data-savings-amount": true, children: (0, import_core13.formatMoney)(savings, currency) }),
2906
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { "data-savings-amount": true, children: (0, import_core12.formatMoney)(savings, currency) }),
2914
2907
  " ",
2915
2908
  /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { "data-savings-percent": true, children: [
2916
2909
  "(",
@@ -2920,8 +2913,8 @@ function BogoBundle(props) {
2920
2913
  ] })
2921
2914
  ] }),
2922
2915
  /* @__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) })
2916
+ showCompare && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "lb-bundle-compare-price", "data-compare-price": true, children: (0, import_core12.formatMoney)(comparePrice, currency) }),
2917
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "lb-bundle-sale-price", "data-sale-price": true, children: (0, import_core12.formatMoney)(salePrice, currency) })
2925
2918
  ] })
2926
2919
  ] }),
2927
2920
  cartError && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "lb-bundle__error", role: "alert", children: cartError }),
@@ -2941,7 +2934,7 @@ function BogoBundle(props) {
2941
2934
  }
2942
2935
  function BogoProductRow({ side, product, quantity, percent, badge, currency, onVariantChange }) {
2943
2936
  const variants = product.variants.nodes;
2944
- const optionNames = (0, import_react15.useMemo)(() => {
2937
+ const optionNames = (0, import_react14.useMemo)(() => {
2945
2938
  const first = variants[0];
2946
2939
  return first ? first.selectedOptions.map((o) => o.name) : [];
2947
2940
  }, [variants]);
@@ -2950,15 +2943,15 @@ function BogoProductRow({ side, product, quantity, percent, badge, currency, onV
2950
2943
  variants,
2951
2944
  optionNames
2952
2945
  });
2953
- (0, import_react15.useEffect)(() => {
2946
+ (0, import_react14.useEffect)(() => {
2954
2947
  onVariantChange(side, selectedVariant ?? null);
2955
2948
  }, [selectedVariant, side, onVariantChange]);
2956
- const displayVariant = selectedVariant ?? variants.find((v) => (0, import_core13.isVariantFulfillable)(v, quantity)) ?? variants[0];
2949
+ const displayVariant = selectedVariant ?? variants.find((v) => (0, import_core12.isVariantFulfillable)(v, quantity)) ?? variants[0];
2957
2950
  const unit = displayVariant ? parseFloat(displayVariant.price.amount) : 0;
2958
2951
  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)(
2952
+ const priceText = isGet ? (0, import_core12.formatMoney)(discountedUnit(unit, percent), currency) : (0, import_core12.formatMoney)(unit, currency);
2953
+ 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;
2954
+ const unitPriceText = displayVariant ? (0, import_core12.formatUnitPrice)(
2962
2955
  displayVariant.unitPrice,
2963
2956
  displayVariant.unitPriceMeasurement,
2964
2957
  currency
@@ -3023,20 +3016,20 @@ function BogoProductRow({ side, product, quantity, percent, badge, currency, onV
3023
3016
  }
3024
3017
 
3025
3018
  // src/components/MultiStepBundle.tsx
3026
- var import_react17 = require("react");
3027
- var import_core15 = require("@lime-bundles/core");
3019
+ var import_react16 = require("react");
3020
+ var import_core14 = require("@lime-bundles/core");
3028
3021
 
3029
3022
  // src/components/MultiStepPicker.tsx
3030
- var import_react16 = require("react");
3023
+ var import_react15 = require("react");
3031
3024
  var import_react_dom2 = require("react-dom");
3032
- var import_core14 = require("@lime-bundles/core");
3025
+ var import_core13 = require("@lime-bundles/core");
3033
3026
  var import_jsx_runtime8 = require("react/jsx-runtime");
3034
3027
  function ruleFor3(bundle, productId, variantId) {
3035
3028
  if (variantId) {
3036
3029
  const vRule = bundle.variantRules[variantId];
3037
3030
  if (vRule) return vRule;
3038
3031
  }
3039
- return bundle.productRules[productId] ?? import_core14.DEFAULT_PRODUCT_RULE;
3032
+ return bundle.productRules[productId] ?? import_core13.DEFAULT_PRODUCT_RULE;
3040
3033
  }
3041
3034
  function variantRuleFor3(bundle, variantId) {
3042
3035
  return variantId ? bundle.variantRules[variantId] : void 0;
@@ -3044,15 +3037,14 @@ function variantRuleFor3(bundle, variantId) {
3044
3037
  function sanitizeId2(gid) {
3045
3038
  return gid.replace(/[^a-zA-Z0-9_-]/g, "-");
3046
3039
  }
3047
- function buildEligibleProducts2(bundle, stepIndex, oosBehavior) {
3040
+ function buildEligibleProducts2(bundle, stepIndex) {
3048
3041
  const result = [];
3049
- for (const product of (0, import_core14.productsForStep)(bundle, stepIndex)) {
3042
+ for (const product of (0, import_core13.productsForStep)(bundle, stepIndex)) {
3050
3043
  const rule = ruleFor3(bundle, product.id);
3051
3044
  const available = product.variants.nodes.filter(
3052
- (v) => (0, import_core14.isVariantFulfillable)(v, rule.min)
3045
+ (v) => (0, import_core13.isVariantFulfillable)(v, rule.min)
3053
3046
  );
3054
3047
  const isOos = available.length === 0;
3055
- if (isOos && oosBehavior === "hide") continue;
3056
3048
  result.push({
3057
3049
  product,
3058
3050
  variants: product.variants.nodes,
@@ -3067,7 +3059,6 @@ function normalizeText2(str) {
3067
3059
  }
3068
3060
  var FILTERS_ALL2 = "__all__";
3069
3061
  function MultiStepPicker({
3070
- outOfStockBehavior,
3071
3062
  bundle,
3072
3063
  currency,
3073
3064
  initialStep,
@@ -3084,17 +3075,19 @@ function MultiStepPicker({
3084
3075
  }) {
3085
3076
  const wc = bundle.widgetConfig;
3086
3077
  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)(
3078
+ const overlayRef = (0, import_react15.useRef)(null);
3079
+ const dialogRef = (0, import_react15.useRef)(null);
3080
+ const titleRef = (0, import_react15.useRef)(null);
3081
+ const closeBtnRef = (0, import_react15.useRef)(null);
3082
+ const listRef = (0, import_react15.useRef)(null);
3083
+ const mouseDownTarget = (0, import_react15.useRef)(null);
3084
+ const [open, setOpen] = (0, import_react15.useState)(false);
3085
+ const [stepIndex, setStepIndex] = (0, import_react15.useState)(
3093
3086
  () => Math.max(0, Math.min(steps.length - 1, initialStep))
3094
3087
  );
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)("");
3088
+ const [query, setQuery] = (0, import_react15.useState)("");
3089
+ const [activeType, setActiveType] = (0, import_react15.useState)(FILTERS_ALL2);
3090
+ const [announcement, setAnnouncement] = (0, import_react15.useState)("");
3098
3091
  const step = steps[stepIndex];
3099
3092
  const stepMin = step?.minQuantity ?? 1;
3100
3093
  const stepPicks = selections[stepIndex] ?? [];
@@ -3102,11 +3095,11 @@ function MultiStepPicker({
3102
3095
  const stepIsSatisfied = unitsInStep >= stepMin;
3103
3096
  const isLastStep = stepIndex === steps.length - 1;
3104
3097
  const shownUnits = Math.min(unitsInStep, stepMin);
3105
- const eligible = (0, import_react16.useMemo)(
3106
- () => buildEligibleProducts2(bundle, stepIndex, outOfStockBehavior),
3107
- [bundle, stepIndex, outOfStockBehavior]
3098
+ const eligible = (0, import_react15.useMemo)(
3099
+ () => buildEligibleProducts2(bundle, stepIndex),
3100
+ [bundle, stepIndex]
3108
3101
  );
3109
- const productTypes = (0, import_react16.useMemo)(() => {
3102
+ const productTypes = (0, import_react15.useMemo)(() => {
3110
3103
  const types = [];
3111
3104
  const seen = /* @__PURE__ */ new Set();
3112
3105
  for (const ep of eligible) {
@@ -3119,7 +3112,7 @@ function MultiStepPicker({
3119
3112
  return types;
3120
3113
  }, [eligible]);
3121
3114
  const showFilters = wc.mixMatchShowTypeFilters && productTypes.length >= 2;
3122
- (0, import_react16.useEffect)(() => {
3115
+ (0, import_react15.useEffect)(() => {
3123
3116
  const id = requestAnimationFrame(() => setOpen(true));
3124
3117
  return () => cancelAnimationFrame(id);
3125
3118
  }, []);
@@ -3127,8 +3120,23 @@ function MultiStepPicker({
3127
3120
  useFocusTrap({
3128
3121
  active: true,
3129
3122
  containerRef: dialogRef,
3123
+ initialFocusRef: closeBtnRef,
3130
3124
  onEscape: onClose
3131
3125
  });
3126
+ (0, import_react15.useEffect)(() => {
3127
+ if (listRef.current) listRef.current.scrollTop = 0;
3128
+ }, [stepIndex]);
3129
+ const [selectedAtLoad, setSelectedAtLoad] = (0, import_react15.useState)(
3130
+ () => new Set((selections[stepIndex] ?? []).map((s) => s.productId))
3131
+ );
3132
+ const ordered = (0, import_react15.useMemo)(() => {
3133
+ const front = [];
3134
+ const back = [];
3135
+ for (const ep of eligible) {
3136
+ (selectedAtLoad.has(ep.product.id) ? back : front).push(ep);
3137
+ }
3138
+ return front.concat(back);
3139
+ }, [eligible, selectedAtLoad]);
3132
3140
  function goToStep(i) {
3133
3141
  const clamped = Math.max(0, Math.min(steps.length - 1, i));
3134
3142
  setStepIndex(clamped);
@@ -3136,6 +3144,7 @@ function MultiStepPicker({
3136
3144
  setActiveType(FILTERS_ALL2);
3137
3145
  const target = steps[clamped];
3138
3146
  const targetPicks = selections[clamped] ?? [];
3147
+ setSelectedAtLoad(new Set(targetPicks.map((s) => s.productId)));
3139
3148
  const targetUnits = targetPicks.reduce((sum, s) => sum + s.quantity, 0);
3140
3149
  setAnnouncement(
3141
3150
  `Step ${clamped + 1} of ${steps.length}. ${target.name}. ${Math.min(targetUnits, target.minQuantity)} of ${target.minQuantity} added`
@@ -3143,14 +3152,14 @@ function MultiStepPicker({
3143
3152
  titleRef.current?.focus();
3144
3153
  }
3145
3154
  const subtitle = `Step ${stepIndex + 1} of ${steps.length} \xB7 ${step?.name ?? ""}`;
3146
- const filtered = (0, import_react16.useMemo)(() => {
3155
+ const filtered = (0, import_react15.useMemo)(() => {
3147
3156
  const nq = normalizeText2(query.trim());
3148
- return eligible.filter((ep) => {
3157
+ return ordered.filter((ep) => {
3149
3158
  const matchesQuery = !nq || normalizeText2(ep.product.title).includes(nq);
3150
3159
  const matchesType = activeType === FILTERS_ALL2 || (ep.product.productType ?? "") === activeType;
3151
3160
  return matchesQuery && matchesType;
3152
3161
  });
3153
- }, [eligible, query, activeType]);
3162
+ }, [ordered, query, activeType]);
3154
3163
  const showEmpty = filtered.length === 0 && query.trim().length > 0;
3155
3164
  function onOverlayMouseDown(e) {
3156
3165
  mouseDownTarget.current = e.target;
@@ -3208,6 +3217,7 @@ function MultiStepPicker({
3208
3217
  /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3209
3218
  "button",
3210
3219
  {
3220
+ ref: closeBtnRef,
3211
3221
  type: "button",
3212
3222
  className: "lb-mix-match__modal-close",
3213
3223
  "data-modal-close": true,
@@ -3295,7 +3305,7 @@ function MultiStepPicker({
3295
3305
  })
3296
3306
  }
3297
3307
  ),
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)(
3308
+ /* @__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
3309
  MultiStepPickerRow,
3300
3310
  {
3301
3311
  bundle,
@@ -3386,27 +3396,27 @@ function MultiStepPickerRow({
3386
3396
  const { product, variants, isOos } = eligible;
3387
3397
  const rule = ruleFor3(bundle, product.id);
3388
3398
  const step = bundle.steps[stepIndex];
3389
- const optionNames = (0, import_react16.useMemo)(() => {
3399
+ const optionNames = (0, import_react15.useMemo)(() => {
3390
3400
  const first = variants[0];
3391
3401
  return first ? first.selectedOptions.map((o) => o.name) : [];
3392
3402
  }, [variants]);
3393
3403
  const showPicker = variants.length > 1 && optionNames.length > 0;
3394
3404
  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;
3405
+ const currentVariant = selectedVariant ?? variants.find((v) => (0, import_core13.isVariantFulfillable)(v, rule.min)) ?? eligible.firstAvailableVariant ?? variants[0] ?? null;
3396
3406
  const vRule = ruleFor3(bundle, product.id, currentVariant?.id);
3397
3407
  const variantMax = variantRuleFor3(bundle, currentVariant?.id)?.max;
3398
- const stepPicks = (0, import_react16.useMemo)(
3408
+ const stepPicks = (0, import_react15.useMemo)(
3399
3409
  () => selections[stepIndex] ?? [],
3400
3410
  [selections, stepIndex]
3401
3411
  );
3402
3412
  const unitsInStep = stepPicks.reduce((sum, s) => sum + s.quantity, 0);
3403
- const committedSelection = (0, import_react16.useMemo)(
3413
+ const committedSelection = (0, import_react15.useMemo)(
3404
3414
  () => currentVariant ? stepPicks.find((s) => s.variantId === currentVariant.id) ?? null : null,
3405
3415
  [stepPicks, currentVariant]
3406
3416
  );
3407
3417
  const variantInStep = committedSelection !== null;
3408
3418
  const committedQty = committedSelection?.quantity ?? 0;
3409
- const productOtherUnits = (0, import_react16.useMemo)(() => {
3419
+ const productOtherUnits = (0, import_react15.useMemo)(() => {
3410
3420
  if (!currentVariant) return 0;
3411
3421
  let sum = 0;
3412
3422
  for (let i = 0; i < selections.length; i++) {
@@ -3418,7 +3428,7 @@ function MultiStepPickerRow({
3418
3428
  }
3419
3429
  return sum;
3420
3430
  }, [selections, product.id, currentVariant, stepIndex]);
3421
- const variantOtherUnits = (0, import_react16.useMemo)(() => {
3431
+ const variantOtherUnits = (0, import_react15.useMemo)(() => {
3422
3432
  if (!currentVariant) return 0;
3423
3433
  let sum = 0;
3424
3434
  for (const picks of selections) {
@@ -3430,7 +3440,7 @@ function MultiStepPickerRow({
3430
3440
  }, [selections, currentVariant, committedQty]);
3431
3441
  const swapUnits = currentVariant ? swapUnitsFor?.(stepIndex, product.id, currentVariant.id) ?? 0 : 0;
3432
3442
  const inSwapState = swapUnits >= vRule.min;
3433
- const room = (0, import_core14.stepHeadroom)(step?.maxQuantity ?? null, unitsInStep);
3443
+ const room = (0, import_core13.stepHeadroom)(step?.maxQuantity ?? null, unitsInStep);
3434
3444
  const productHeadroom = Math.min(
3435
3445
  rule.max - productOtherUnits,
3436
3446
  variantMax ?? Infinity
@@ -3439,20 +3449,20 @@ function MultiStepPickerRow({
3439
3449
  productHeadroom,
3440
3450
  room === Number.POSITIVE_INFINITY ? productHeadroom : committedQty + room
3441
3451
  );
3442
- const stockRemaining = currentVariant ? (0, import_core14.maxAddableQuantity)(currentVariant, Number.MAX_SAFE_INTEGER, variantOtherUnits) : 0;
3452
+ const stockRemaining = currentVariant ? (0, import_core13.maxAddableQuantity)(currentVariant, Number.MAX_SAFE_INTEGER, variantOtherUnits) : 0;
3443
3453
  const cap = Math.max(0, Math.min(spotCeiling, stockRemaining));
3444
3454
  const stepperMax = Math.max(vRule.min, cap);
3445
- const [qty, setQty] = (0, import_react16.useState)(vRule.min);
3446
- (0, import_react16.useEffect)(() => {
3455
+ const [qty, setQty] = (0, import_react15.useState)(vRule.min);
3456
+ (0, import_react15.useEffect)(() => {
3447
3457
  setQty((prev) => Math.max(vRule.min, Math.min(prev, stepperMax)));
3448
3458
  }, [stepperMax, vRule.min]);
3449
3459
  const currentVariantId = currentVariant?.id ?? null;
3450
- (0, import_react16.useEffect)(() => {
3460
+ (0, import_react15.useEffect)(() => {
3451
3461
  if (!variantInStep) setQty(vRule.min);
3452
3462
  }, [variantInStep, currentVariantId, vRule.min]);
3453
3463
  if (!currentVariant || !step) return null;
3454
3464
  const thumbImage = currentVariant.image ?? product.featuredImage ?? null;
3455
- const unitPriceText = (0, import_core14.formatUnitPrice)(
3465
+ const unitPriceText = (0, import_core13.formatUnitPrice)(
3456
3466
  currentVariant.unitPrice,
3457
3467
  currentVariant.unitPriceMeasurement,
3458
3468
  currency
@@ -3522,8 +3532,8 @@ function MultiStepPickerRow({
3522
3532
  }
3523
3533
  ) }),
3524
3534
  /* @__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) })
3535
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { "data-row-price-sale": true, children: (0, import_core13.formatMoney)(priceCents, currency) }),
3536
+ 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
3537
  ] }),
3528
3538
  unitPriceText && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "lb-mix-match__modal-product-unit-price lb-bundle-product-unit-price", children: unitPriceText }),
3529
3539
  showPicker && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "lb-bundle-variant-option-groups", children: optionNames.map((optionName, optionIndex) => {
@@ -3676,7 +3686,7 @@ function ruleFor4(bundle, productId, variantId) {
3676
3686
  const vRule = bundle.variantRules[variantId];
3677
3687
  if (vRule) return vRule;
3678
3688
  }
3679
- return bundle.productRules[productId] ?? import_core15.DEFAULT_PRODUCT_RULE;
3689
+ return bundle.productRules[productId] ?? import_core14.DEFAULT_PRODUCT_RULE;
3680
3690
  }
3681
3691
  function variantRuleFor4(bundle, variantId) {
3682
3692
  return variantId ? bundle.variantRules[variantId] : void 0;
@@ -3718,10 +3728,6 @@ function MultiStepBundle(props) {
3718
3728
  storefrontAccessToken,
3719
3729
  bundleGid
3720
3730
  });
3721
- const { outOfStockBehavior } = useShopSettings({
3722
- shopDomain,
3723
- storefrontAccessToken
3724
- });
3725
3731
  const { elementRef, trackAddToCart } = useAnalytics({
3726
3732
  shopDomain,
3727
3733
  appUrl: appUrl ?? `https://${shopDomain}`,
@@ -3729,14 +3735,14 @@ function MultiStepBundle(props) {
3729
3735
  bundleType: "multi_step",
3730
3736
  enabled: analyticsEnabled !== false
3731
3737
  });
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);
3738
+ const [selections, setSelections] = (0, import_react16.useState)([]);
3739
+ const [pickerOpenAt, setPickerOpenAt] = (0, import_react16.useState)(null);
3740
+ const [addingToCart, setAddingToCart] = (0, import_react16.useState)(false);
3741
+ const [cartError, setCartError] = (0, import_react16.useState)(null);
3736
3742
  const bundle = result.status === "success" && result.bundle.bundleType === "multi_step" ? result.bundle : null;
3737
3743
  const setConfigVarsRef = useWidgetConfigVars(bundle?.widgetConfig);
3738
3744
  const setModalConfigVarsRef = useWidgetConfigVars(bundle?.widgetConfig);
3739
- (0, import_react17.useEffect)(() => {
3745
+ (0, import_react16.useEffect)(() => {
3740
3746
  if (result.status === "error") {
3741
3747
  onError?.(result.error);
3742
3748
  return;
@@ -3749,17 +3755,17 @@ function MultiStepBundle(props) {
3749
3755
  );
3750
3756
  }
3751
3757
  }, [result, onError]);
3752
- const steps = (0, import_react17.useMemo)(() => bundle?.steps ?? [], [bundle]);
3753
- (0, import_react17.useEffect)(() => {
3758
+ const steps = (0, import_react16.useMemo)(() => bundle?.steps ?? [], [bundle]);
3759
+ (0, import_react16.useEffect)(() => {
3754
3760
  const seeded = steps.map(() => []);
3755
3761
  if (bundle) {
3756
3762
  const seedCurrency = bundle.products[0]?.priceRange.minVariantPrice.currencyCode ?? "USD";
3757
3763
  for (const [pid, rule] of Object.entries(bundle.productRules)) {
3758
3764
  if (!rule.required) continue;
3759
3765
  for (let i = 0; i < steps.length; i++) {
3760
- const product = (0, import_core15.productsForStep)(bundle, i).find((p) => p.id === pid);
3766
+ const product = (0, import_core14.productsForStep)(bundle, i).find((p) => p.id === pid);
3761
3767
  const variant = product?.variants.nodes.find(
3762
- (v) => (0, import_core15.isVariantFulfillable)(v, rule.min)
3768
+ (v) => (0, import_core14.isVariantFulfillable)(v, rule.min)
3763
3769
  );
3764
3770
  if (!product || !variant) continue;
3765
3771
  seeded[i].push({
@@ -3771,7 +3777,7 @@ function MultiStepBundle(props) {
3771
3777
  featuredImage: variant.image?.url ?? product.featuredImage?.url ?? null,
3772
3778
  price: parseFloat(variant.price.amount),
3773
3779
  compareAtPrice: variant.compareAtPrice ? parseFloat(variant.compareAtPrice.amount) : null,
3774
- unitPrice: (0, import_core15.formatUnitPrice)(
3780
+ unitPrice: (0, import_core14.formatUnitPrice)(
3775
3781
  variant.unitPrice,
3776
3782
  variant.unitPriceMeasurement,
3777
3783
  seedCurrency
@@ -3785,26 +3791,26 @@ function MultiStepBundle(props) {
3785
3791
  setSelections(seeded);
3786
3792
  }, [bundle, steps]);
3787
3793
  const showStepper = bundle?.widgetConfig.mixMatchShowQuantitySelector !== false;
3788
- const totalMin = (0, import_react17.useMemo)(
3794
+ const totalMin = (0, import_react16.useMemo)(
3789
3795
  () => steps.reduce((sum, s) => sum + s.minQuantity, 0),
3790
3796
  [steps]
3791
3797
  );
3792
- const unitsByStep = (0, import_react17.useMemo)(
3798
+ const unitsByStep = (0, import_react16.useMemo)(
3793
3799
  () => selections.map((picks) => picks.reduce((sum, s) => sum + s.quantity, 0)),
3794
3800
  [selections]
3795
3801
  );
3796
- const totalQuantity = (0, import_react17.useMemo)(
3802
+ const totalQuantity = (0, import_react16.useMemo)(
3797
3803
  () => unitsByStep.reduce((sum, u) => sum + u, 0),
3798
3804
  [unitsByStep]
3799
3805
  );
3800
- const stepSatisfied = (0, import_react17.useCallback)(
3806
+ const stepSatisfied = (0, import_react16.useCallback)(
3801
3807
  (i) => (unitsByStep[i] ?? 0) >= (steps[i]?.minQuantity ?? 1),
3802
3808
  [unitsByStep, steps]
3803
3809
  );
3804
3810
  const allSatisfied = steps.length > 0 && steps.every((_, i) => stepSatisfied(i));
3805
3811
  const valid = !!bundle && allSatisfied;
3806
3812
  const completedSteps = steps.filter((_, i) => stepSatisfied(i)).length;
3807
- const summary = (0, import_react17.useMemo)(() => {
3813
+ const summary = (0, import_react16.useMemo)(() => {
3808
3814
  let comparePrice = 0;
3809
3815
  let salePrice = 0;
3810
3816
  for (const stepPicks of selections) {
@@ -3812,7 +3818,7 @@ function MultiStepBundle(props) {
3812
3818
  if (sel.quantity <= 0) continue;
3813
3819
  comparePrice += sel.price * sel.quantity;
3814
3820
  if (bundle) {
3815
- salePrice += (0, import_core15.calculateDiscount)(
3821
+ salePrice += (0, import_core14.calculateDiscount)(
3816
3822
  sel.price,
3817
3823
  bundle.discountConfig.discountType,
3818
3824
  bundle.discountConfig.discountValue
@@ -3824,7 +3830,7 @@ function MultiStepBundle(props) {
3824
3830
  const savingsPercent = comparePrice > 0 && savings > 0 ? Math.round(savings / comparePrice * 100) : 0;
3825
3831
  return { comparePrice, salePrice, savings, savingsPercent };
3826
3832
  }, [selections, bundle]);
3827
- const addSelection = (0, import_react17.useCallback)((step, item) => {
3833
+ const addSelection = (0, import_react16.useCallback)((step, item) => {
3828
3834
  setSelections((prev) => {
3829
3835
  if (step < 0 || step >= prev.length) return prev;
3830
3836
  if (prev[step].some((s) => s.variantId === item.variantId)) return prev;
@@ -3833,7 +3839,7 @@ function MultiStepBundle(props) {
3833
3839
  return next;
3834
3840
  });
3835
3841
  }, []);
3836
- const swapSelection = (0, import_react17.useCallback)(
3842
+ const swapSelection = (0, import_react16.useCallback)(
3837
3843
  (step, item) => {
3838
3844
  setSelections((prev) => {
3839
3845
  if (!bundle || step < 0 || step >= prev.length) return prev;
@@ -3868,7 +3874,7 @@ function MultiStepBundle(props) {
3868
3874
  },
3869
3875
  [bundle]
3870
3876
  );
3871
- const updateQuantity = (0, import_react17.useCallback)(
3877
+ const updateQuantity = (0, import_react16.useCallback)(
3872
3878
  (step, productId, variantId, quantity) => {
3873
3879
  setSelections((prev) => {
3874
3880
  if (step < 0 || step >= prev.length) return prev;
@@ -3887,7 +3893,7 @@ function MultiStepBundle(props) {
3887
3893
  },
3888
3894
  []
3889
3895
  );
3890
- const removeVariant = (0, import_react17.useCallback)(
3896
+ const removeVariant = (0, import_react16.useCallback)(
3891
3897
  (step, variantId) => {
3892
3898
  setSelections((prev) => {
3893
3899
  if (step < 0 || step >= prev.length) return prev;
@@ -3903,7 +3909,7 @@ function MultiStepBundle(props) {
3903
3909
  },
3904
3910
  [bundle]
3905
3911
  );
3906
- const removeSlot = (0, import_react17.useCallback)(
3912
+ const removeSlot = (0, import_react16.useCallback)(
3907
3913
  (step, index) => {
3908
3914
  setSelections((prev) => {
3909
3915
  if (step < 0 || step >= prev.length) return prev;
@@ -3919,7 +3925,7 @@ function MultiStepBundle(props) {
3919
3925
  },
3920
3926
  [bundle]
3921
3927
  );
3922
- const handleAddToCart = (0, import_react17.useCallback)(async () => {
3928
+ const handleAddToCart = (0, import_react16.useCallback)(async () => {
3923
3929
  if (!bundle || !valid) return;
3924
3930
  const grouped = /* @__PURE__ */ new Map();
3925
3931
  for (const stepPicks of selections) {
@@ -3974,8 +3980,8 @@ function MultiStepBundle(props) {
3974
3980
  ([pid, rule]) => {
3975
3981
  if (!rule.required) return false;
3976
3982
  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))
3983
+ (_, i) => (0, import_core14.productsForStep)(bundle, i).some(
3984
+ (p) => p.id === pid && p.variants.nodes.some((v) => (0, import_core14.isVariantFulfillable)(v, rule.min))
3979
3985
  )
3980
3986
  );
3981
3987
  }
@@ -4099,8 +4105,8 @@ function MultiStepBundle(props) {
4099
4105
  ),
4100
4106
  item.variantTitle && item.variantTitle !== "Default Title" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-mix-match__filled-variant", children: item.variantTitle }),
4101
4107
  /* @__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) }),
4108
+ 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) }),
4109
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-bundle-product-price", children: (0, import_core14.formatMoney)(item.price, currency) }),
4104
4110
  /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-bundle-qty-inline", children: `\xD7${item.quantity}` })
4105
4111
  ] }),
4106
4112
  item.unitPrice && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-bundle-product-unit-price", children: item.unitPrice })
@@ -4130,7 +4136,7 @@ function MultiStepBundle(props) {
4130
4136
  ))
4131
4137
  }
4132
4138
  ),
4133
- (0, import_core15.stepHeadroom)(step.maxQuantity, unitsByStep[i] ?? 0) !== 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4139
+ (0, import_core14.stepHeadroom)(step.maxQuantity, unitsByStep[i] ?? 0) !== 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4134
4140
  "button",
4135
4141
  {
4136
4142
  type: "button",
@@ -4162,7 +4168,7 @@ function MultiStepBundle(props) {
4162
4168
  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
4169
  "You save",
4164
4170
  " ",
4165
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { "data-savings-amount": true, children: (0, import_core15.formatMoney)(summary.savings, currency) }),
4171
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { "data-savings-amount": true, children: (0, import_core14.formatMoney)(summary.savings, currency) }),
4166
4172
  " ",
4167
4173
  /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { "data-savings-percent": true, children: [
4168
4174
  "(",
@@ -4172,8 +4178,8 @@ function MultiStepBundle(props) {
4172
4178
  ] })
4173
4179
  ] }),
4174
4180
  /* @__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) })
4181
+ 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) }),
4182
+ /* @__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
4183
  ] })
4178
4184
  ] }),
4179
4185
  cartError && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "lb-bundle__error", role: "alert", children: cartError }),
@@ -4190,7 +4196,6 @@ function MultiStepBundle(props) {
4190
4196
  pickerOpenAt !== null && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4191
4197
  MultiStepPicker,
4192
4198
  {
4193
- outOfStockBehavior,
4194
4199
  bundle,
4195
4200
  currency,
4196
4201
  initialStep: pickerOpenAt,
@@ -4217,9 +4222,9 @@ function MultiStepBundle(props) {
4217
4222
  );
4218
4223
  }
4219
4224
  function stepHasInStockProduct(bundle, stepIndex) {
4220
- return (0, import_core15.productsForStep)(bundle, stepIndex).some((product) => {
4225
+ return (0, import_core14.productsForStep)(bundle, stepIndex).some((product) => {
4221
4226
  const rule = ruleFor4(bundle, product.id);
4222
- return product.variants.nodes.some((v) => (0, import_core15.isVariantFulfillable)(v, rule.min));
4227
+ return product.variants.nodes.some((v) => (0, import_core14.isVariantFulfillable)(v, rule.min));
4223
4228
  });
4224
4229
  }
4225
4230
  function PlusIcon2() {
@@ -4264,21 +4269,21 @@ async function fetchShopCustomCss(options) {
4264
4269
  }
4265
4270
 
4266
4271
  // src/hooks/useBundlesForProduct.ts
4267
- var import_react18 = require("react");
4268
- var import_core16 = require("@lime-bundles/core");
4272
+ var import_react17 = require("react");
4273
+ var import_core15 = require("@lime-bundles/core");
4269
4274
  var INITIAL_STATE2 = {
4270
4275
  status: "loading",
4271
4276
  bundles: null,
4272
4277
  error: null
4273
4278
  };
4274
4279
  function useBundlesForProduct(options) {
4275
- const [state, setState] = (0, import_react18.useState)(
4280
+ const [state, setState] = (0, import_react17.useState)(
4276
4281
  INITIAL_STATE2
4277
4282
  );
4278
- (0, import_react18.useEffect)(() => {
4283
+ (0, import_react17.useEffect)(() => {
4279
4284
  const controller = new AbortController();
4280
4285
  setState(INITIAL_STATE2);
4281
- (0, import_core16.fetchBundlesForProduct)({
4286
+ (0, import_core15.fetchBundlesForProduct)({
4282
4287
  shopDomain: options.shopDomain,
4283
4288
  storefrontAccessToken: options.storefrontAccessToken,
4284
4289
  productHandle: options.productHandle,
@@ -4301,7 +4306,7 @@ function useBundlesForProduct(options) {
4301
4306
  signal: controller.signal
4302
4307
  }).then((settings) => {
4303
4308
  if (controller.signal.aborted) return;
4304
- (0, import_core16.injectCustomCss)(options.shopDomain, settings.customCss);
4309
+ (0, import_core15.injectCustomCss)(options.shopDomain, settings.customCss);
4305
4310
  }).catch(() => {
4306
4311
  });
4307
4312
  return () => {
@@ -4317,8 +4322,8 @@ function useBundlesForProduct(options) {
4317
4322
  }
4318
4323
 
4319
4324
  // src/index.ts
4325
+ var import_core16 = require("@lime-bundles/core");
4320
4326
  var import_core17 = require("@lime-bundles/core");
4321
- var import_core18 = require("@lime-bundles/core");
4322
4327
  // Annotate the CommonJS export names for ESM import in node:
4323
4328
  0 && (module.exports = {
4324
4329
  BUNDLES_FOR_PRODUCT_QUERY,
@@ -4326,7 +4331,6 @@ var import_core18 = require("@lime-bundles/core");
4326
4331
  BogoBundle,
4327
4332
  BundleCountdown,
4328
4333
  BundleParseError,
4329
- DEFAULT_OUT_OF_STOCK_BEHAVIOR,
4330
4334
  FixedBundle,
4331
4335
  MixMatchBundle,
4332
4336
  MultiStepBundle,
@@ -4357,7 +4361,6 @@ var import_core18 = require("@lime-bundles/core");
4357
4361
  parseCents,
4358
4362
  parseMetaobjectBundle,
4359
4363
  parseMetaobjectBundleStrict,
4360
- parseOutOfStockBehavior,
4361
4364
  percentageDiscountUnit,
4362
4365
  productsForStep,
4363
4366
  reportAddToCart,
@@ -4369,7 +4372,6 @@ var import_core18 = require("@lime-bundles/core");
4369
4372
  useAnalytics,
4370
4373
  useBundleData,
4371
4374
  useBundlesForProduct,
4372
- useShopSettings,
4373
4375
  useVariantSelection,
4374
4376
  useWidgetConfigVars,
4375
4377
  validateQuantity