@lime-bundles/widget 4.0.0 → 4.1.1

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
@@ -26,7 +26,7 @@ __export(index_exports, {
26
26
  module.exports = __toCommonJS(index_exports);
27
27
 
28
28
  // src/lime-bundle.ts
29
- var import_core5 = require("@lime-bundles/core");
29
+ var import_core6 = require("@lime-bundles/core");
30
30
 
31
31
  // ../render/src/adapt.ts
32
32
  var import_core = require("@lime-bundles/core");
@@ -511,7 +511,7 @@ function buildWidgetShell(typeClass, opts) {
511
511
  "data-countdown": ""
512
512
  });
513
513
  const label2 = box("span", "lb-bundle-countdown-label");
514
- label2.textContent = opts.countdownLabel ?? "Ends in";
514
+ label2.textContent = opts.countdownLabel ?? "Limited time offer";
515
515
  countdown.appendChild(label2);
516
516
  countdown.appendChild(
517
517
  box("span", "lb-bundle-countdown-timer", {
@@ -523,10 +523,12 @@ function buildWidgetShell(typeClass, opts) {
523
523
  const products = box("div", typeClass + "__products lb-edge-fade");
524
524
  root.appendChild(products);
525
525
  root.appendChild(box("div", "lb-bundle-divider"));
526
- const summary = box("div", "lb-bundle-summary");
526
+ const summary = box("div", "lb-bundle-summary", {
527
+ "data-pricing-section": ""
528
+ });
527
529
  const text = box("div", "lb-bundle-summary__text");
528
530
  const label = box("span", "lb-bundle-summary__label");
529
- label.textContent = opts.summaryLabel ?? "Bundle price";
531
+ label.textContent = opts.summaryLabel ?? "Bundle total";
530
532
  text.appendChild(label);
531
533
  if (opts.withItemCount) {
532
534
  label.appendChild(box("span", "", { "data-item-count": "" }));
@@ -557,6 +559,7 @@ function buildWidgetShell(typeClass, opts) {
557
559
  summary.appendChild(prices);
558
560
  root.appendChild(summary);
559
561
  const cta = box("button", "lb-bundle-cta", {
562
+ "data-cta-text": opts.ctaText,
560
563
  type: "button",
561
564
  "data-add-bundle": ""
562
565
  });
@@ -575,7 +578,9 @@ function buildWidgetShell(typeClass, opts) {
575
578
  );
576
579
  return { root, products, cta };
577
580
  }
578
- function buildVolumeTiers(tiers, groupLabel) {
581
+ function buildVolumeTiers(tiers, groupLabel, opts = {}) {
582
+ const showCompare = opts.showCompare !== false;
583
+ const showPriceEach = opts.showPriceEach !== false;
579
584
  const group = box("div", "lb-volume__tiers lb-edge-fade", {
580
585
  role: "radiogroup",
581
586
  "aria-label": groupLabel,
@@ -600,8 +605,17 @@ function buildVolumeTiers(tiers, groupLabel) {
600
605
  label.textContent = tier.label;
601
606
  info.appendChild(label);
602
607
  const price = box("span", "lb-volume__tier-price");
603
- price.appendChild(box("span", "lb-volume__tier-compare"));
604
- price.appendChild(box("span", "", { "data-tier-price-each": "" }));
608
+ if (showCompare && (tier.percent > 0 || tier.amountCents > 0)) {
609
+ price.appendChild(box("span", "lb-volume__tier-compare"));
610
+ }
611
+ if (showPriceEach) {
612
+ price.appendChild(box("span", "", { "data-tier-price-each": "" }));
613
+ if (opts.unitLabel) {
614
+ const unit = box("span", "lb-volume__tier-unit");
615
+ unit.textContent = opts.unitLabel;
616
+ price.appendChild(unit);
617
+ }
618
+ }
605
619
  info.appendChild(price);
606
620
  el2.appendChild(info);
607
621
  if (tier.badgeLabel || tier.savingsLabel) {
@@ -710,7 +724,10 @@ var DEFAULT_STRINGS = {
710
724
  required: "Required",
711
725
  soldOut: "Sold out",
712
726
  outOfStock: "Out of stock",
713
- itemsOutOfStock: "__COUNT__ items out of stock",
727
+ itemsOutOfStock: {
728
+ one: "__COUNT__ item out of stock",
729
+ other: "__COUNT__ items out of stock"
730
+ },
714
731
  quantity: "Quantity",
715
732
  increaseQuantity: "Increase quantity",
716
733
  decreaseQuantity: "Decrease quantity",
@@ -730,11 +747,26 @@ var DEFAULT_STRINGS = {
730
747
  stepsCompleted: "__COUNT__ of __TOTAL__ steps completed",
731
748
  each: " each",
732
749
  buyQty: "Buy __COUNT__",
750
+ itemCount: {
751
+ one: "__COUNT__ item",
752
+ other: "__COUNT__ items"
753
+ },
733
754
  needsSpots: {
734
755
  one: "Needs __COUNT__ spot",
735
756
  other: "Needs __COUNT__ spots"
736
757
  }
737
758
  };
759
+ function formatItemsOutOfStock(t, count) {
760
+ const raw = t.itemsOutOfStock;
761
+ let tpl;
762
+ if (raw && typeof raw === "object") {
763
+ const form = new Intl.PluralRules(t.locale || "en").select(count);
764
+ tpl = raw[form] || raw.other;
765
+ } else {
766
+ tpl = raw;
767
+ }
768
+ return (tpl || "__COUNT__ items out of stock").split("__COUNT__").join(String(count));
769
+ }
738
770
 
739
771
  // ../render/src/dropdown/bind.ts
740
772
  var import_core2 = require("@lime-bundles/core");
@@ -1191,7 +1223,7 @@ function renderFixedBundle(container, bundle, outOfStockBehavior, onAddToCart, o
1191
1223
  shell.cta.disabled = true;
1192
1224
  const label = shell.cta.querySelector("[data-cta-label]");
1193
1225
  if (label) {
1194
- label.textContent = (t.itemsOutOfStock || "__COUNT__ items out of stock").split("__COUNT__").join(String(oosProducts.length));
1226
+ label.textContent = formatItemsOutOfStock(t, oosProducts.length);
1195
1227
  }
1196
1228
  } else {
1197
1229
  shell.cta.addEventListener("click", () => {
@@ -1249,15 +1281,38 @@ function formatSubtitle(remaining, discountType, discountValue, t) {
1249
1281
 
1250
1282
  // ../render/src/picker/rules.ts
1251
1283
  var DEFAULT_RULE = { min: 1, max: 99 };
1252
- function ruleFor(productId, rulesMap) {
1284
+ function ruleFor(productId, rulesMap, variantId) {
1285
+ if (variantId != null) {
1286
+ const vRule = rulesMap["gid://shopify/ProductVariant/" + variantId];
1287
+ if (vRule && typeof vRule.min === "number" && typeof vRule.max === "number") {
1288
+ return vRule;
1289
+ }
1290
+ }
1253
1291
  const rule = rulesMap["gid://shopify/Product/" + productId];
1254
1292
  if (!rule || typeof rule.min !== "number" || typeof rule.max !== "number") {
1255
1293
  return DEFAULT_RULE;
1256
1294
  }
1257
1295
  return rule;
1258
1296
  }
1259
- function defaultPickQuantity(productId, rulesMap) {
1260
- return ruleFor(productId, rulesMap).min;
1297
+ function variantRuleFor(variantId, rulesMap) {
1298
+ if (variantId == null) return void 0;
1299
+ const rule = rulesMap["gid://shopify/ProductVariant/" + variantId];
1300
+ if (!rule || typeof rule.min !== "number" || typeof rule.max !== "number") {
1301
+ return void 0;
1302
+ }
1303
+ return rule;
1304
+ }
1305
+ function mergeRuleMaps(productRules, variantRules) {
1306
+ const products = productRules ?? {};
1307
+ if (!variantRules) return products;
1308
+ const keys = Object.keys(variantRules);
1309
+ if (keys.length === 0) return products;
1310
+ const merged = { ...products };
1311
+ for (const key of keys) merged[key] = variantRules[key];
1312
+ return merged;
1313
+ }
1314
+ function defaultPickQuantity(productId, rulesMap, variantId) {
1315
+ return ruleFor(productId, rulesMap, variantId).min;
1261
1316
  }
1262
1317
  function totalUnits(items) {
1263
1318
  let qty = 0;
@@ -1277,11 +1332,9 @@ function committedQtyForVariant(items, variantId) {
1277
1332
  function isRowAddable(rule, remainingSpots) {
1278
1333
  return rule.min <= remainingSpots;
1279
1334
  }
1280
- function stepperCeiling(rule, remainingSpots, stock, ownQty = 0, productOtherUnits = 0) {
1281
- const ceiling = Math.min(
1282
- rule.max - productOtherUnits,
1283
- ownQty + remainingSpots
1284
- );
1335
+ function stepperCeiling(rule, remainingSpots, stock, ownQty = 0, productOtherUnits = 0, variantMax) {
1336
+ let ceiling = Math.min(rule.max - productOtherUnits, ownQty + remainingSpots);
1337
+ if (typeof variantMax === "number") ceiling = Math.min(ceiling, variantMax);
1285
1338
  return typeof stock === "number" ? Math.min(ceiling, stock) : ceiling;
1286
1339
  }
1287
1340
 
@@ -1360,7 +1413,8 @@ function buildPickerRow(p, rowIndex, ctx) {
1360
1413
  }
1361
1414
  infoDiv.appendChild(titleEl);
1362
1415
  let currentVariant = firstAvailable ?? (p.variants.length > 0 ? p.variants[0] : null);
1363
- const modalQty = currentVariant ? pRule.min : 1;
1416
+ const ruleForVariant = (v) => ruleFor(p.id, rulesMap, v ? v.id : null);
1417
+ const modalQty = currentVariant ? ruleForVariant(currentVariant).min : 1;
1364
1418
  const priceEl = document.createElement("p");
1365
1419
  priceEl.className = "lb-mix-match__modal-product-price";
1366
1420
  priceEl.setAttribute("data-row-price", "");
@@ -1396,8 +1450,8 @@ function buildPickerRow(p, rowIndex, ctx) {
1396
1450
  infoDiv.appendChild(unitPriceEl);
1397
1451
  let qtyGroup = null;
1398
1452
  let qtyValueEl = null;
1399
- let current = pRule.min;
1400
- let effectiveMax = pRule.max;
1453
+ let current = ruleForVariant(currentVariant).min;
1454
+ let effectiveMax = ruleForVariant(currentVariant).max;
1401
1455
  let paint = null;
1402
1456
  let setBoundsForVariant = null;
1403
1457
  if (p.available && ctx.showQtySelector) {
@@ -1419,7 +1473,7 @@ function buildPickerRow(p, rowIndex, ctx) {
1419
1473
  qtyValueEl.className = "lb-mix-match__qty-stepper-value";
1420
1474
  qtyValueEl.setAttribute("data-row-qty", "");
1421
1475
  qtyValueEl.setAttribute("aria-live", "polite");
1422
- qtyValueEl.textContent = String(pRule.min);
1476
+ qtyValueEl.textContent = String(ruleForVariant(currentVariant).min);
1423
1477
  const qtyPlusBtn = document.createElement("button");
1424
1478
  qtyPlusBtn.type = "button";
1425
1479
  qtyPlusBtn.className = "lb-mix-match__qty-stepper-button lb-mix-match__qty-stepper-button--plus";
@@ -1436,7 +1490,7 @@ function buildPickerRow(p, rowIndex, ctx) {
1436
1490
  paint = () => {
1437
1491
  valueEl.textContent = String(current);
1438
1492
  valueEl.setAttribute("data-qty", String(current));
1439
- qtyMinusBtn.disabled = stepperDisabled || current <= pRule.min;
1493
+ qtyMinusBtn.disabled = stepperDisabled || current <= ruleForVariant(currentVariant).min;
1440
1494
  qtyPlusBtn.disabled = stepperDisabled || current >= effectiveMax;
1441
1495
  };
1442
1496
  setBoundsForVariant = (variant, alreadyInBundle = 0) => {
@@ -1447,18 +1501,21 @@ function buildPickerRow(p, rowIndex, ctx) {
1447
1501
  const stock = variant ? variant.inventoryQuantity : null;
1448
1502
  const othersInBundle = Math.max(0, alreadyInBundle - ownQty);
1449
1503
  const stockCap = typeof stock === "number" ? Math.max(0, stock - othersInBundle) : void 0;
1504
+ const vMax = variantRuleFor(variantId, rulesMap)?.max;
1505
+ const rMin = ruleForVariant(variant).min;
1450
1506
  effectiveMax = swapUnits > 0 ? typeof stockCap === "number" ? Math.min(swapUnits, stockCap) : swapUnits : stepperCeiling(
1451
1507
  pRule,
1452
1508
  capacity.remainingSpots(),
1453
1509
  stockCap,
1454
1510
  ownQty,
1455
- otherUnits
1511
+ otherUnits,
1512
+ vMax
1456
1513
  );
1457
- if (effectiveMax < pRule.min) {
1458
- current = pRule.min;
1514
+ if (effectiveMax < rMin) {
1515
+ current = rMin;
1459
1516
  } else {
1460
1517
  if (current > effectiveMax) current = effectiveMax;
1461
- if (current < pRule.min) current = pRule.min;
1518
+ if (current < rMin) current = rMin;
1462
1519
  }
1463
1520
  paint();
1464
1521
  };
@@ -1469,7 +1526,7 @@ function buildPickerRow(p, rowIndex, ctx) {
1469
1526
  }
1470
1527
  };
1471
1528
  qtyMinusBtn.addEventListener("click", () => {
1472
- if (current > pRule.min) current -= 1;
1529
+ if (current > ruleForVariant(currentVariant).min) current -= 1;
1473
1530
  paint();
1474
1531
  commitQtyToBundle();
1475
1532
  });
@@ -1539,7 +1596,7 @@ function buildPickerRow(p, rowIndex, ctx) {
1539
1596
  }
1540
1597
  currentVariant = v;
1541
1598
  row.setAttribute("data-selected-variant-id", String(v.id));
1542
- const resolvedQty = pRule.min;
1599
+ const resolvedQty = ruleForVariant(v).min;
1543
1600
  priceSaleEl.textContent = formatMoney(v.price * resolvedQty);
1544
1601
  paintRowCompare(priceCompareEl, v, resolvedQty);
1545
1602
  if (v.unitPrice) {
@@ -1641,17 +1698,19 @@ function buildPickerRow(p, rowIndex, ctx) {
1641
1698
  if (setBoundsForVariant) {
1642
1699
  const committed = capacity.ownQty(variant.id);
1643
1700
  if (committed > 0) current = committed;
1644
- else if (lastVariantId !== variant.id) current = pRule.min;
1701
+ else if (lastVariantId !== variant.id)
1702
+ current = ruleForVariant(variant).min;
1645
1703
  lastVariantId = variant.id;
1646
1704
  setBoundsForVariant(variant, already);
1647
1705
  }
1648
1706
  const rowSwapUnits = capacity.swapUnits(p.id, variant.id);
1649
- const inSwapState = rowSwapUnits >= pRule.min;
1707
+ const vRule = ruleForVariant(variant);
1708
+ const inSwapState = rowSwapUnits >= vRule.min;
1650
1709
  const remaining = capacity.remainingSpots();
1651
- const needsMoreSpots = !inBundle && !inSwapState && !isRowAddable(pRule, remaining);
1710
+ const needsMoreSpots = !inBundle && !inSwapState && !isRowAddable(vRule, remaining);
1652
1711
  if (needsSpotsEl) {
1653
1712
  if (needsMoreSpots && remaining > 0) {
1654
- needsSpotsEl.textContent = formatNeedsSpots(pRule.min, t);
1713
+ needsSpotsEl.textContent = formatNeedsSpots(vRule.min, t);
1655
1714
  needsSpotsEl.hidden = false;
1656
1715
  } else {
1657
1716
  needsSpotsEl.hidden = true;
@@ -1688,11 +1747,11 @@ function buildPickerRow(p, rowIndex, ctx) {
1688
1747
  addBtn.classList.remove("lb-mix-match__modal-add--required");
1689
1748
  row.classList.remove("lb-mix-match__modal-product--in-bundle");
1690
1749
  addedBadge.hidden = true;
1691
- const noStock = typeof stock === "number" ? Math.max(0, stock - already) < pRule.min : false;
1750
+ const noStock = typeof stock === "number" ? Math.max(0, stock - already) < vRule.min : false;
1692
1751
  if (inSwapState) {
1693
1752
  addBtn.disabled = noStock;
1694
1753
  } else {
1695
- const productMaxed = pRule.max - capacity.productUnitsElsewhere(p.id, variant.id) < pRule.min;
1754
+ const productMaxed = pRule.max - capacity.productUnitsElsewhere(p.id, variant.id) < vRule.min;
1696
1755
  addBtn.disabled = noStock || productMaxed || needsMoreSpots || capacity.isFull();
1697
1756
  }
1698
1757
  }
@@ -1844,7 +1903,7 @@ function createPickerModal(deps) {
1844
1903
  rowQtyEl.getAttribute("data-qty") || rowQtyEl.textContent || "",
1845
1904
  10
1846
1905
  ) || 1
1847
- ) : defaultPickQuantity(prod.id, deps.rulesMap);
1906
+ ) : defaultPickQuantity(prod.id, deps.rulesMap, selectedVariant.id);
1848
1907
  const newItem = {
1849
1908
  productId: prod.id,
1850
1909
  variantId: selectedVariant.id,
@@ -2053,6 +2112,7 @@ function productUnitsInOtherSlots(items, productId, excludeVariantId) {
2053
2112
  return qty;
2054
2113
  }
2055
2114
  function canRemovePick(items, item, rulesMap) {
2115
+ if (variantRuleFor(item.variantId, rulesMap)?.required) return false;
2056
2116
  const rule = ruleFor(item.productId, rulesMap);
2057
2117
  if (!rule.required) return true;
2058
2118
  let unitsElsewhere = 0;
@@ -2317,8 +2377,17 @@ function seedSelection(eligibleProducts, rulesMap, requiredQty, courtesy) {
2317
2377
  });
2318
2378
  const required = [];
2319
2379
  for (const p of eligibleProducts) {
2380
+ if (!p.available || !p.variants) continue;
2381
+ let seededVariant = false;
2382
+ for (const v3 of p.variants) {
2383
+ const vRule = variantRuleFor(v3.id, rulesMap);
2384
+ if (!vRule?.required || !v3.available) continue;
2385
+ required.push(pick(p, v3, Math.max(1, vRule.min)));
2386
+ seededVariant = true;
2387
+ }
2388
+ if (seededVariant) continue;
2320
2389
  const rule = ruleFor(p.id, rulesMap);
2321
- if (!rule.required || !p.available || !p.variants) continue;
2390
+ if (!rule.required) continue;
2322
2391
  const v2 = firstAvailable(p);
2323
2392
  if (!v2) continue;
2324
2393
  required.push(pick(p, v2, Math.max(1, rule.min)));
@@ -2519,17 +2588,17 @@ function buildPickerModal(opts) {
2519
2588
  }
2520
2589
 
2521
2590
  // src/renderers/mix-match.ts
2522
- function renderMixMatchBundle(container, bundle, outOfStockBehavior, onAddToCart, onCleanup) {
2591
+ function renderMixMatchBundle(container, bundle, outOfStockBehavior, onAddToCart, onCleanup, currentProductHandle) {
2523
2592
  const wc = bundle.widgetConfig;
2524
2593
  const t = DEFAULT_STRINGS;
2525
2594
  const requiredQty = bundle.minQuantity || 1;
2526
- const rulesMap = bundle.productRules ?? {};
2595
+ const rulesMap = mergeRuleMaps(bundle.productRules, bundle.variantRules);
2527
2596
  const adapted = adaptProducts(bundle);
2528
- const eligibleProducts = adapted.map((p) => ({
2597
+ const eligibleProducts = adapted.map((p, i) => ({
2529
2598
  id: Number(p.productId),
2530
2599
  title: p.title ?? "",
2531
2600
  url: p.url ?? null,
2532
- type: "",
2601
+ type: bundle.products[i]?.productType ?? "",
2533
2602
  featuredImage: p.featuredImage ?? null,
2534
2603
  available: p.variants.some((v) => v.available),
2535
2604
  optionNames: p.optionNames,
@@ -2574,16 +2643,21 @@ function renderMixMatchBundle(container, bundle, outOfStockBehavior, onAddToCart
2574
2643
  const overlay = buildPickerModal({
2575
2644
  bundleGid: bundle.id,
2576
2645
  domId: bundle.id.replace(/\D/g, ""),
2577
- showSearch: true,
2578
- showTypeFilters: false,
2646
+ showSearch: wc.showSearch !== false,
2647
+ showTypeFilters: wc.mixMatchShowTypeFilters !== false,
2579
2648
  segmentCount: requiredQty,
2580
2649
  wizard: false
2581
2650
  });
2582
2651
  shell.root.appendChild(overlay);
2652
+ const currentIdx = currentProductHandle ? bundle.products.findIndex((p) => p.handle === currentProductHandle) : -1;
2583
2653
  const selectedItems = seedSelection(
2584
2654
  eligibleProducts,
2585
2655
  rulesMap,
2586
- requiredQty
2656
+ requiredQty,
2657
+ {
2658
+ enabled: !!currentProductHandle,
2659
+ currentProductId: currentIdx !== -1 ? eligibleProducts[currentIdx]?.id ?? null : null
2660
+ }
2587
2661
  );
2588
2662
  const rowCapacity = {
2589
2663
  remainingSpots: () => remainingUnits(selectedItems, requiredQty),
@@ -2620,7 +2694,13 @@ function renderMixMatchBundle(container, bundle, outOfStockBehavior, onAddToCart
2620
2694
  shell.root,
2621
2695
  selectedItems,
2622
2696
  requiredQty,
2623
- bundle,
2697
+ // The shared updater reads the theme data-block shape: discount fields
2698
+ // flat, not nested under discountConfig. Passing the bundle itself left
2699
+ // `discountType` undefined, so the summary never painted.
2700
+ {
2701
+ discountType: bundle.discountConfig.discountType,
2702
+ discountValue: bundle.discountConfig.discountValue
2703
+ },
2624
2704
  (total, type, value) => (0, import_core3.calculateDiscount)(total, type, value),
2625
2705
  updatePricing2(formatMoney)
2626
2706
  );
@@ -2633,7 +2713,7 @@ function renderMixMatchBundle(container, bundle, outOfStockBehavior, onAddToCart
2633
2713
  rulesMap,
2634
2714
  eligibleProducts,
2635
2715
  requiredQty,
2636
- showQtySelector: true,
2716
+ showQtySelector: wc.mixMatchShowQuantitySelector !== false,
2637
2717
  items: selectedItems,
2638
2718
  formatMoney,
2639
2719
  rowCapacity,
@@ -2644,7 +2724,9 @@ function renderMixMatchBundle(container, bundle, outOfStockBehavior, onAddToCart
2644
2724
  onSelectionChanged: updateAll,
2645
2725
  addSelection: (item) => {
2646
2726
  if (totalUnits(selectedItems) + (item.quantity || 1) > requiredQty) return;
2647
- const headroom = ruleFor(item.productId, rulesMap).max - productUnitsInOtherSlots(selectedItems, item.productId, item.variantId);
2727
+ const vMax = variantRuleFor(item.variantId, rulesMap)?.max;
2728
+ let headroom = ruleFor(item.productId, rulesMap).max - productUnitsInOtherSlots(selectedItems, item.productId, item.variantId);
2729
+ if (typeof vMax === "number") headroom = Math.min(headroom, vMax);
2648
2730
  if ((item.quantity || 1) > headroom) return;
2649
2731
  selectedItems.push(item);
2650
2732
  updateAll();
@@ -2694,6 +2776,9 @@ function renderMixMatchBundle(container, bundle, outOfStockBehavior, onAddToCart
2694
2776
  onCleanup?.(bindDropdowns(shell.root));
2695
2777
  }
2696
2778
 
2779
+ // src/renderers/volume.ts
2780
+ var import_core4 = require("@lime-bundles/core");
2781
+
2697
2782
  // ../render/src/volume/pricing.ts
2698
2783
  function calcTierPrice(basePrice, discountType, tierEl) {
2699
2784
  if (discountType === "fixed_amount") {
@@ -2722,6 +2807,23 @@ function formatItemCount(qty, translations) {
2722
2807
  const tpl = translations.itemCount[form] || translations.itemCount.other || "__COUNT__";
2723
2808
  return " (" + tpl.split("__COUNT__").join(String(qty)) + ")";
2724
2809
  }
2810
+ function updateAllTierPrices(allTiers, basePrice, discountType, formatMoney) {
2811
+ for (let i = 0; i < allTiers.length; i++) {
2812
+ const tierEl = allTiers[i];
2813
+ const priceEachEl = tierEl.querySelector(
2814
+ "[data-tier-price-each]"
2815
+ );
2816
+ if (priceEachEl) {
2817
+ priceEachEl.textContent = formatMoney(
2818
+ calcTierPrice(basePrice, discountType, tierEl)
2819
+ );
2820
+ }
2821
+ const compareEl = tierEl.querySelector(
2822
+ ".lb-volume__tier-compare"
2823
+ );
2824
+ if (compareEl) compareEl.textContent = formatMoney(basePrice);
2825
+ }
2826
+ }
2725
2827
  function selectTier(container, allTiers, basePrice, discountType, index, translations, formatMoney) {
2726
2828
  for (let i = 0; i < allTiers.length; i++) {
2727
2829
  allTiers[i].setAttribute("aria-checked", i === index ? "true" : "false");
@@ -2779,8 +2881,17 @@ function renderVolumeBundle(container, bundle, outOfStockBehavior, onAddToCart)
2779
2881
  const discountType = bundle.discountConfig.discountType;
2780
2882
  const formatMoney = intlFormatMoney(product.priceRange.minVariantPrice.currencyCode);
2781
2883
  const t = DEFAULT_STRINGS;
2782
- const popularIdx = wc.popularBadge?.visible ? Math.floor((bundle.volumeTiers.length - 1) / 2) : -1;
2783
- const defaultIdx = 0;
2884
+ const bestIdx = (0, import_core4.bestValueTierIndex)(bundle.volumeTiers, discountType);
2885
+ const defaultIdx = (0, import_core4.resolveDefaultTierIndex)(
2886
+ wc.defaultTier,
2887
+ bundle.volumeTiers.length,
2888
+ bestIdx
2889
+ );
2890
+ const popularIdx = (0, import_core4.resolvePopularTierIndex)(
2891
+ wc.popularBadge?.tierIndex,
2892
+ wc.popularBadge?.visible !== false,
2893
+ bestIdx
2894
+ );
2784
2895
  const tiers = bundle.volumeTiers.map((tier, i) => {
2785
2896
  const percent = discountType === "fixed_amount" ? 0 : Math.round(tier.percentage ?? 0);
2786
2897
  const amountCents = discountType === "fixed_amount" ? Math.round((tier.amount ?? 0) * 100) : 0;
@@ -2801,16 +2912,21 @@ function renderVolumeBundle(container, bundle, outOfStockBehavior, onAddToCart)
2801
2912
  title: bundle.title,
2802
2913
  subtitle: bundle.description,
2803
2914
  summaryLabel: "Total",
2804
- withItemCount: true,
2915
+ withItemCount: wc.pricing?.showItemCount !== false,
2805
2916
  totalPriceSlot: true,
2806
2917
  showSavingsBar: wc.savingsBar?.visible !== false,
2807
2918
  showComparePrice: wc.pricing?.showCompareAtPrice !== false,
2808
2919
  ctaText: wc.cta?.ctaText || t.addToCart || "Add to cart",
2809
2920
  endsAt: wc.countdown?.showCountdown === false ? null : bundle.endsAt
2810
2921
  });
2811
- const group = buildVolumeTiers(tiers, "Select quantity");
2922
+ const group = buildVolumeTiers(tiers, "Select quantity", {
2923
+ showCompare: wc.pricing?.showComparePrice !== false,
2924
+ showPriceEach: wc.pricing?.showPerUnitPrice !== false,
2925
+ unitLabel: (t.each || "each").trim()
2926
+ });
2812
2927
  shell.products.replaceWith(group);
2813
2928
  const tierEls = group.querySelectorAll("[data-tier-index]");
2929
+ updateAllTierPrices(tierEls, basePrice, discountType, formatMoney);
2814
2930
  let selectedIndex = defaultIdx;
2815
2931
  const apply = () => selectTier(shell.root, tierEls, basePrice, discountType, selectedIndex, t, formatMoney);
2816
2932
  group.addEventListener("click", (e) => {
@@ -2960,6 +3076,13 @@ function buildBogoCartItems(sides, percent, buyQty, getQty) {
2960
3076
  }
2961
3077
 
2962
3078
  // src/renderers/bogo.ts
3079
+ function buildBogoPlus() {
3080
+ const plus = document.createElement("div");
3081
+ plus.className = "lb-bogo__plus";
3082
+ plus.setAttribute("aria-hidden", "true");
3083
+ plus.innerHTML = '<svg width="12" height="12" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><line x1="9" y1="3" x2="9" y2="15" stroke="currentColor" stroke-width="2" stroke-linecap="round"/><line x1="3" y1="9" x2="15" y2="9" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>';
3084
+ return plus;
3085
+ }
2963
3086
  function renderBogoBundle(container, bundle, outOfStockBehavior, onAddToCart, onCleanup) {
2964
3087
  const wc = bundle.widgetConfig;
2965
3088
  const buyProduct = bundle.products.find((p) => p.id === bundle.buyProductId);
@@ -3008,6 +3131,7 @@ function renderBogoBundle(container, bundle, outOfStockBehavior, onAddToCart, on
3008
3131
  const badgeText = percent >= 100 ? "Free" : percent + "% off";
3009
3132
  sides.forEach((side, i) => {
3010
3133
  const isGet = i === 1;
3134
+ if (isGet) shell.products.appendChild(buildBogoPlus());
3011
3135
  const isOos = !side.variants.some((v) => v.available);
3012
3136
  const row = buildRowSkeleton(side, t, {
3013
3137
  isOos,
@@ -3036,7 +3160,7 @@ function renderBogoBundle(container, bundle, outOfStockBehavior, onAddToCart, on
3036
3160
  shell.cta.disabled = true;
3037
3161
  const label = shell.cta.querySelector("[data-cta-label]");
3038
3162
  if (label) {
3039
- label.textContent = (t.itemsOutOfStock || "__COUNT__ items out of stock").split("__COUNT__").join(String(oosCount));
3163
+ label.textContent = formatItemsOutOfStock(t, oosCount);
3040
3164
  }
3041
3165
  } else {
3042
3166
  shell.cta.addEventListener("click", () => {
@@ -3056,7 +3180,7 @@ function renderBogoBundle(container, bundle, outOfStockBehavior, onAddToCart, on
3056
3180
  }
3057
3181
 
3058
3182
  // src/renderers/multi-step.ts
3059
- var import_core4 = require("@lime-bundles/core");
3183
+ var import_core5 = require("@lime-bundles/core");
3060
3184
 
3061
3185
  // ../render/src/multi-step/i18n.ts
3062
3186
  function stepOfLabel(i, total, t) {
@@ -3104,6 +3228,7 @@ function allSatisfied(selections, steps) {
3104
3228
  return true;
3105
3229
  }
3106
3230
  function canRemovePick2(selections, item, rulesMap) {
3231
+ if (variantRuleFor(item.variantId, rulesMap)?.required) return false;
3107
3232
  const rule = ruleFor(item.productId, rulesMap);
3108
3233
  if (!rule.required) return true;
3109
3234
  let unitsElsewhere = 0;
@@ -3456,7 +3581,7 @@ function createWizard(deps) {
3456
3581
  rowQtyEl.getAttribute("data-qty") || rowQtyEl.textContent || "",
3457
3582
  10
3458
3583
  ) || 1
3459
- ) : defaultPickQuantity(prod.id, deps.rulesMap);
3584
+ ) : defaultPickQuantity(prod.id, deps.rulesMap, selectedVariant.id);
3460
3585
  const newItem = {
3461
3586
  productId: prod.id,
3462
3587
  variantId: selectedVariant.id,
@@ -3676,7 +3801,7 @@ function createWizard(deps) {
3676
3801
  function renderMultiStepBundle(container, bundle, outOfStockBehavior, onAddToCart, onCleanup) {
3677
3802
  const wc = bundle.widgetConfig;
3678
3803
  const t = DEFAULT_STRINGS;
3679
- const rulesMap = bundle.productRules ?? {};
3804
+ const rulesMap = mergeRuleMaps(bundle.productRules, bundle.variantRules);
3680
3805
  const steps = bundle.steps ?? [];
3681
3806
  if (!steps.length) return;
3682
3807
  const quantities = {
@@ -3684,7 +3809,7 @@ function renderMultiStepBundle(container, bundle, outOfStockBehavior, onAddToCar
3684
3809
  variantQuantities: bundle.variantQuantities
3685
3810
  };
3686
3811
  const pools = steps.map(
3687
- (_, i) => (0, import_core4.productsForStep)(bundle, i).map((product) => {
3812
+ (_, i) => (0, import_core5.productsForStep)(bundle, i).map((product) => {
3688
3813
  const p = adaptProduct(product, bundle.id, {
3689
3814
  quantities,
3690
3815
  allowedVariantIds: null
@@ -3758,8 +3883,8 @@ function renderMultiStepBundle(container, bundle, outOfStockBehavior, onAddToCar
3758
3883
  const overlay = buildPickerModal({
3759
3884
  bundleGid: bundle.id,
3760
3885
  domId: bundle.id.replace(/\D/g, ""),
3761
- showSearch: true,
3762
- showTypeFilters: true,
3886
+ showSearch: wc.showSearch !== false,
3887
+ showTypeFilters: wc.mixMatchShowTypeFilters !== false,
3763
3888
  segmentCount: null,
3764
3889
  wizard: true
3765
3890
  });
@@ -3794,7 +3919,7 @@ function renderMultiStepBundle(container, bundle, outOfStockBehavior, onAddToCar
3794
3919
  discountType: bundle.discountConfig.discountType,
3795
3920
  discountValue: bundle.discountConfig.discountValue
3796
3921
  },
3797
- (total, type, value) => (0, import_core4.calculateDiscount)(total, type, value),
3922
+ (total, type, value) => (0, import_core5.calculateDiscount)(total, type, value),
3798
3923
  updatePricing2(formatMoney)
3799
3924
  );
3800
3925
  updateProgress2(bodyDeps);
@@ -3806,8 +3931,8 @@ function renderMultiStepBundle(container, bundle, outOfStockBehavior, onAddToCar
3806
3931
  selections,
3807
3932
  t,
3808
3933
  rulesMap,
3809
- showQtySelector: true,
3810
- showTypeFilters: true,
3934
+ showQtySelector: wc.mixMatchShowQuantitySelector !== false,
3935
+ showTypeFilters: wc.mixMatchShowTypeFilters !== false,
3811
3936
  formatMoney,
3812
3937
  dropdown: void 0,
3813
3938
  portalTarget: null,
@@ -3857,7 +3982,7 @@ function renderMultiStepBundle(container, bundle, outOfStockBehavior, onAddToCar
3857
3982
  }
3858
3983
 
3859
3984
  // src/lime-bundle.ts
3860
- var import_core6 = require("@lime-bundles/core");
3985
+ var import_core7 = require("@lime-bundles/core");
3861
3986
 
3862
3987
  // src/utils/input-mode.ts
3863
3988
  var NAV_KEYS = /* @__PURE__ */ new Set([
@@ -4196,7 +4321,10 @@ a.lb-bundle-product-name:focus-visible {
4196
4321
  toggle: present in admin \u2192 shown; absent \u2192 hidden. Styled as muted
4197
4322
  secondary text beneath the price row so it doesn't compete visually. */
4198
4323
  .lb-bundle-product-unit-price {
4199
- display: block;
4324
+ /* Fallback is the "on" branch; Liquid sets 'none' when the merchant disables
4325
+ productList.showUnitPrice. The [hidden] rule below still wins for rows
4326
+ whose variant has no unit price at all. */
4327
+ display: var(--lb-product-unit-price-display, block);
4200
4328
  font-size: 12px;
4201
4329
  line-height: 16px;
4202
4330
  color: color-mix(in srgb, var(--lb-text) 60%, transparent);
@@ -4375,6 +4503,10 @@ a.lb-bundle-product-name:focus-visible {
4375
4503
  cards). Quiet, theme-inherited; the fixed widget uses .lb-bundle-qty-chip in
4376
4504
  the card's right slot instead. */
4377
4505
  .lb-bundle-qty-inline {
4506
+ /* Fallback is the "on" branch; Liquid sets 'none' when the merchant disables
4507
+ productList.showQuantity. The fixed widget's chip carries its own var
4508
+ because it is a flex box, not inline text. */
4509
+ display: var(--lb-product-qty-inline-display, inline);
4378
4510
  font-size: 13px;
4379
4511
  font-weight: 400;
4380
4512
  color: color-mix(in srgb, var(--lb-text) 55%, transparent);
@@ -4607,6 +4739,10 @@ a.lb-bundle-product-name:focus-visible {
4607
4739
  .lb-bundle-thumbnail[style*="--lb-row-thumb-ratio"] {
4608
4740
  aspect-ratio: var(--lb-row-thumb-ratio);
4609
4741
  }
4742
+ /* This selector outranks the \`.lb-bundle-thumbnail\` rule above, so Liquid must
4743
+ emit the inline var for the "original" ratio and nothing else. Emitting it
4744
+ unconditionally silently replaced every merchant ratio with the image's own,
4745
+ which looks like the setting being ignored. */
4610
4746
  `;
4611
4747
  var BUNDLE_FIXED_CSS = `/* Lime Bundles \u2014 Fixed bundle styles */
4612
4748
 
@@ -4656,7 +4792,10 @@ var BUNDLE_FIXED_CSS = `/* Lime Bundles \u2014 Fixed bundle styles */
4656
4792
  min-width: 34px;
4657
4793
  height: 28px;
4658
4794
  padding: 0 8px;
4659
- display: inline-flex;
4795
+ /* Fallback is the "on" branch; Liquid sets 'none' when the merchant disables
4796
+ productList.showQuantity. Separate from --lb-product-qty-inline-display
4797
+ because this chip is a flex box and the other counts are inline text. */
4798
+ display: var(--lb-product-qty-chip-display, inline-flex);
4660
4799
  align-items: center;
4661
4800
  justify-content: center;
4662
4801
  border-radius: var(--lb-radius-sm);
@@ -6499,6 +6638,13 @@ var LimeBundleElement = class extends HTMLElement {
6499
6638
  buyer = void 0;
6500
6639
  shadow;
6501
6640
  bundles = [];
6641
+ /**
6642
+ * The product handle this embed is standing on, when one can be resolved
6643
+ * (attribute → meta tag → /products/<handle> path). The mix-and-match
6644
+ * courtesy seed uses it to pre-add the current product the way the theme
6645
+ * widget does; null on pages with no product context.
6646
+ */
6647
+ currentProductHandle = null;
6502
6648
  abortController = null;
6503
6649
  impressionCleanups = [];
6504
6650
  /**
@@ -6518,7 +6664,7 @@ var LimeBundleElement = class extends HTMLElement {
6518
6664
  * before the first render. Defaults to `show_greyed_out` so a failed or
6519
6665
  * missing fetch degrades to "bundles still render".
6520
6666
  */
6521
- outOfStockBehavior = import_core5.DEFAULT_OUT_OF_STOCK_BEHAVIOR;
6667
+ outOfStockBehavior = import_core6.DEFAULT_OUT_OF_STOCK_BEHAVIOR;
6522
6668
  constructor() {
6523
6669
  super();
6524
6670
  this.shadow = this.attachShadow({ mode: "open" });
@@ -6580,13 +6726,13 @@ var LimeBundleElement = class extends HTMLElement {
6580
6726
  * no buyer/country/language is set.
6581
6727
  */
6582
6728
  wrapQueryForContext(query) {
6583
- return (0, import_core5.hasInContext)({
6729
+ return (0, import_core6.hasInContext)({
6584
6730
  shopDomain: this.shopDomain,
6585
6731
  accessToken: this.storefrontToken,
6586
6732
  country: this.country,
6587
6733
  language: this.language,
6588
6734
  buyer: this.buyer
6589
- }) ? (0, import_core5.withInContext)(query) : query;
6735
+ }) ? (0, import_core6.withInContext)(query) : query;
6590
6736
  }
6591
6737
  /**
6592
6738
  * Returns true if this bundle should be hidden for the current market.
@@ -6595,7 +6741,7 @@ var LimeBundleElement = class extends HTMLElement {
6595
6741
  * marketIds doesn't include the configured market.
6596
6742
  */
6597
6743
  isMarketHidden(bundle) {
6598
- return !(0, import_core5.isVisibleInMarket)(bundle, this.marketId);
6744
+ return !(0, import_core6.isVisibleInMarket)(bundle, this.marketId);
6599
6745
  }
6600
6746
  async fetchBundle() {
6601
6747
  if (!this.shopDomain || !this.storefrontToken) {
@@ -6608,7 +6754,7 @@ var LimeBundleElement = class extends HTMLElement {
6608
6754
  const controller = new AbortController();
6609
6755
  this.abortController = controller;
6610
6756
  this.renderLoading();
6611
- const client = (0, import_core5.createStorefrontClient)({
6757
+ const client = (0, import_core6.createStorefrontClient)({
6612
6758
  shopDomain: this.shopDomain,
6613
6759
  accessToken: this.storefrontToken,
6614
6760
  country: this.country,
@@ -6618,11 +6764,12 @@ var LimeBundleElement = class extends HTMLElement {
6618
6764
  try {
6619
6765
  let bundlePromise;
6620
6766
  let singleBundleMode = false;
6767
+ this.currentProductHandle = resolveProductHandle(this.productHandleAttr);
6621
6768
  if (this.bundleGid) {
6622
6769
  singleBundleMode = true;
6623
6770
  bundlePromise = this.fetchSingleBundle(client, controller.signal);
6624
6771
  } else {
6625
- const handle = resolveProductHandle(this.productHandleAttr);
6772
+ const handle = this.currentProductHandle;
6626
6773
  if (!handle) {
6627
6774
  this.teardownImpressions();
6628
6775
  this.renderError(
@@ -6636,7 +6783,7 @@ var LimeBundleElement = class extends HTMLElement {
6636
6783
  handle
6637
6784
  );
6638
6785
  }
6639
- const shopSettingsPromise = client.query(import_core5.SHOP_SETTINGS_QUERY, void 0, {
6786
+ const shopSettingsPromise = client.query(import_core6.SHOP_SETTINGS_QUERY, void 0, {
6640
6787
  signal: controller.signal
6641
6788
  }).catch(() => null);
6642
6789
  await bundlePromise;
@@ -6649,11 +6796,11 @@ var LimeBundleElement = class extends HTMLElement {
6649
6796
  const shopSettings = await shopSettingsPromise;
6650
6797
  const customCss = shopSettings?.shop?.customCss?.value;
6651
6798
  if (customCss) {
6652
- (0, import_core5.injectCustomCss)(this.shopDomain, customCss);
6653
- const sanitized = (0, import_core5.sanitizeCustomCss)(customCss);
6799
+ (0, import_core6.injectCustomCss)(this.shopDomain, customCss);
6800
+ const sanitized = (0, import_core6.sanitizeCustomCss)(customCss);
6654
6801
  if (sanitized.ok) this.shopCustomCss = sanitized.css;
6655
6802
  }
6656
- this.outOfStockBehavior = (0, import_core5.parseOutOfStockBehavior)(
6803
+ this.outOfStockBehavior = (0, import_core6.parseOutOfStockBehavior)(
6657
6804
  shopSettings?.shop?.outOfStockBehavior?.value
6658
6805
  );
6659
6806
  this.renderBundles();
@@ -6668,7 +6815,7 @@ var LimeBundleElement = class extends HTMLElement {
6668
6815
  }
6669
6816
  async fetchSingleBundle(client, signal) {
6670
6817
  const data = await client.query(
6671
- this.wrapQueryForContext(import_core5.BUNDLE_METAOBJECT_QUERY),
6818
+ this.wrapQueryForContext(import_core6.BUNDLE_METAOBJECT_QUERY),
6672
6819
  { id: this.bundleGid },
6673
6820
  { signal }
6674
6821
  );
@@ -6676,7 +6823,7 @@ var LimeBundleElement = class extends HTMLElement {
6676
6823
  this.bundles = [];
6677
6824
  return;
6678
6825
  }
6679
- const parsed = (0, import_core5.parseMetaobjectBundle)(
6826
+ const parsed = (0, import_core6.parseMetaobjectBundle)(
6680
6827
  data.metaobject.id,
6681
6828
  data.metaobject.fields
6682
6829
  );
@@ -6684,7 +6831,7 @@ var LimeBundleElement = class extends HTMLElement {
6684
6831
  }
6685
6832
  async fetchProductBundles(client, signal, productHandle) {
6686
6833
  const data = await client.query(
6687
- this.wrapQueryForContext(import_core5.BUNDLES_FOR_PRODUCT_QUERY),
6834
+ this.wrapQueryForContext(import_core6.BUNDLES_FOR_PRODUCT_QUERY),
6688
6835
  { handle: productHandle },
6689
6836
  { signal }
6690
6837
  );
@@ -6695,10 +6842,10 @@ var LimeBundleElement = class extends HTMLElement {
6695
6842
  const refs = data.product.metafield?.references?.nodes ?? [];
6696
6843
  const bundles = [];
6697
6844
  for (const ref of refs) {
6698
- const parsed = (0, import_core5.parseMetaobjectBundle)(ref.id, ref.fields);
6845
+ const parsed = (0, import_core6.parseMetaobjectBundle)(ref.id, ref.fields);
6699
6846
  if (parsed && !this.isMarketHidden(parsed)) bundles.push(parsed);
6700
6847
  }
6701
- this.bundles = bundles;
6848
+ this.bundles = (0, import_core6.resolveAbTests)(bundles, (0, import_core6.getVisitorId)());
6702
6849
  }
6703
6850
  /**
6704
6851
  * Dispatch add-to-cart with a cancelable event, then — unless a listener
@@ -6728,7 +6875,7 @@ var LimeBundleElement = class extends HTMLElement {
6728
6875
  */
6729
6876
  async defaultAddToCart(lines) {
6730
6877
  if (typeof window === "undefined") return;
6731
- const client = (0, import_core5.createStorefrontClient)({
6878
+ const client = (0, import_core6.createStorefrontClient)({
6732
6879
  shopDomain: this.shopDomain,
6733
6880
  accessToken: this.storefrontToken
6734
6881
  });
@@ -6739,7 +6886,7 @@ var LimeBundleElement = class extends HTMLElement {
6739
6886
  let checkoutUrl = null;
6740
6887
  if (existingCartId) {
6741
6888
  const res = await client.query(
6742
- import_core5.CART_LINES_ADD_MUTATION,
6889
+ import_core6.CART_LINES_ADD_MUTATION,
6743
6890
  { cartId: existingCartId, lines }
6744
6891
  );
6745
6892
  const payload = res.cartLinesAdd;
@@ -6751,7 +6898,7 @@ var LimeBundleElement = class extends HTMLElement {
6751
6898
  }
6752
6899
  if (!checkoutUrl) {
6753
6900
  const res = await client.query(
6754
- import_core5.CART_CREATE_MUTATION,
6901
+ import_core6.CART_CREATE_MUTATION,
6755
6902
  { input: { lines } }
6756
6903
  );
6757
6904
  const payload = res.cartCreate;
@@ -6797,7 +6944,7 @@ var LimeBundleElement = class extends HTMLElement {
6797
6944
  const price = variant ? parseFloat(variant.price.amount) : 0;
6798
6945
  return sum + price * line.quantity;
6799
6946
  }, 0);
6800
- (0, import_core5.reportAddToCart)(
6947
+ (0, import_core6.reportAddToCart)(
6801
6948
  { shopDomain: this.shopDomain, appUrl: this.appUrl },
6802
6949
  {
6803
6950
  bundleGid: bundle.id,
@@ -6836,7 +6983,8 @@ var LimeBundleElement = class extends HTMLElement {
6836
6983
  container.setAttribute("aria-label", bundle.title);
6837
6984
  container.setAttribute("data-bundle-type", bundle.bundleType);
6838
6985
  container.setAttribute("data-bundle-gid", bundle.id);
6839
- (0, import_core6.applyWidgetConfigVars)(container, bundle.widgetConfig);
6986
+ if (bundle.endsAt) container.setAttribute("data-ends-at", bundle.endsAt);
6987
+ (0, import_core7.applyWidgetConfigVars)(container, bundle.widgetConfig);
6840
6988
  this.renderCleanups.push(trackInputMode(container));
6841
6989
  const dispatch = (lines) => this.handleAddToCart(bundle, lines);
6842
6990
  const registerCleanup = (fn) => this.renderCleanups.push(fn);
@@ -6856,7 +7004,8 @@ var LimeBundleElement = class extends HTMLElement {
6856
7004
  bundle,
6857
7005
  this.outOfStockBehavior,
6858
7006
  dispatch,
6859
- registerCleanup
7007
+ registerCleanup,
7008
+ this.currentProductHandle
6860
7009
  );
6861
7010
  break;
6862
7011
  case "volume":
@@ -6902,8 +7051,8 @@ var LimeBundleElement = class extends HTMLElement {
6902
7051
  }
6903
7052
  setupImpressionFor(bundle, element) {
6904
7053
  if (!this.analyticsEnabled || !this.appUrl) return;
6905
- const cleanup = (0, import_core5.observeImpression)(element, () => {
6906
- (0, import_core5.reportImpression)(
7054
+ const cleanup = (0, import_core6.observeImpression)(element, () => {
7055
+ (0, import_core6.reportImpression)(
6907
7056
  { shopDomain: this.shopDomain, appUrl: this.appUrl },
6908
7057
  {
6909
7058
  bundleGid: bundle.id,