@lime-bundles/widget 4.1.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 +148 -53
- package/dist/index.d.cts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +126 -27
- package/dist/lime-bundle.global.js +18 -18
- package/dist/lime-bundle.global.js.map +1 -1
- package/docs/hydrogen.md +28 -3
- package/docs/react-nextjs.md +23 -3
- package/package.json +2 -2
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
|
|
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 ?? "
|
|
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
|
|
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
|
-
|
|
604
|
-
|
|
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:
|
|
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
|
|
1226
|
+
label.textContent = formatItemsOutOfStock(t, oosProducts.length);
|
|
1195
1227
|
}
|
|
1196
1228
|
} else {
|
|
1197
1229
|
shell.cta.addEventListener("click", () => {
|
|
@@ -2556,17 +2588,17 @@ function buildPickerModal(opts) {
|
|
|
2556
2588
|
}
|
|
2557
2589
|
|
|
2558
2590
|
// src/renderers/mix-match.ts
|
|
2559
|
-
function renderMixMatchBundle(container, bundle, outOfStockBehavior, onAddToCart, onCleanup) {
|
|
2591
|
+
function renderMixMatchBundle(container, bundle, outOfStockBehavior, onAddToCart, onCleanup, currentProductHandle) {
|
|
2560
2592
|
const wc = bundle.widgetConfig;
|
|
2561
2593
|
const t = DEFAULT_STRINGS;
|
|
2562
2594
|
const requiredQty = bundle.minQuantity || 1;
|
|
2563
2595
|
const rulesMap = mergeRuleMaps(bundle.productRules, bundle.variantRules);
|
|
2564
2596
|
const adapted = adaptProducts(bundle);
|
|
2565
|
-
const eligibleProducts = adapted.map((p) => ({
|
|
2597
|
+
const eligibleProducts = adapted.map((p, i) => ({
|
|
2566
2598
|
id: Number(p.productId),
|
|
2567
2599
|
title: p.title ?? "",
|
|
2568
2600
|
url: p.url ?? null,
|
|
2569
|
-
type: "",
|
|
2601
|
+
type: bundle.products[i]?.productType ?? "",
|
|
2570
2602
|
featuredImage: p.featuredImage ?? null,
|
|
2571
2603
|
available: p.variants.some((v) => v.available),
|
|
2572
2604
|
optionNames: p.optionNames,
|
|
@@ -2611,16 +2643,21 @@ function renderMixMatchBundle(container, bundle, outOfStockBehavior, onAddToCart
|
|
|
2611
2643
|
const overlay = buildPickerModal({
|
|
2612
2644
|
bundleGid: bundle.id,
|
|
2613
2645
|
domId: bundle.id.replace(/\D/g, ""),
|
|
2614
|
-
showSearch:
|
|
2615
|
-
showTypeFilters: false,
|
|
2646
|
+
showSearch: wc.showSearch !== false,
|
|
2647
|
+
showTypeFilters: wc.mixMatchShowTypeFilters !== false,
|
|
2616
2648
|
segmentCount: requiredQty,
|
|
2617
2649
|
wizard: false
|
|
2618
2650
|
});
|
|
2619
2651
|
shell.root.appendChild(overlay);
|
|
2652
|
+
const currentIdx = currentProductHandle ? bundle.products.findIndex((p) => p.handle === currentProductHandle) : -1;
|
|
2620
2653
|
const selectedItems = seedSelection(
|
|
2621
2654
|
eligibleProducts,
|
|
2622
2655
|
rulesMap,
|
|
2623
|
-
requiredQty
|
|
2656
|
+
requiredQty,
|
|
2657
|
+
{
|
|
2658
|
+
enabled: !!currentProductHandle,
|
|
2659
|
+
currentProductId: currentIdx !== -1 ? eligibleProducts[currentIdx]?.id ?? null : null
|
|
2660
|
+
}
|
|
2624
2661
|
);
|
|
2625
2662
|
const rowCapacity = {
|
|
2626
2663
|
remainingSpots: () => remainingUnits(selectedItems, requiredQty),
|
|
@@ -2657,7 +2694,13 @@ function renderMixMatchBundle(container, bundle, outOfStockBehavior, onAddToCart
|
|
|
2657
2694
|
shell.root,
|
|
2658
2695
|
selectedItems,
|
|
2659
2696
|
requiredQty,
|
|
2660
|
-
|
|
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
|
+
},
|
|
2661
2704
|
(total, type, value) => (0, import_core3.calculateDiscount)(total, type, value),
|
|
2662
2705
|
updatePricing2(formatMoney)
|
|
2663
2706
|
);
|
|
@@ -2670,7 +2713,7 @@ function renderMixMatchBundle(container, bundle, outOfStockBehavior, onAddToCart
|
|
|
2670
2713
|
rulesMap,
|
|
2671
2714
|
eligibleProducts,
|
|
2672
2715
|
requiredQty,
|
|
2673
|
-
showQtySelector:
|
|
2716
|
+
showQtySelector: wc.mixMatchShowQuantitySelector !== false,
|
|
2674
2717
|
items: selectedItems,
|
|
2675
2718
|
formatMoney,
|
|
2676
2719
|
rowCapacity,
|
|
@@ -2733,6 +2776,9 @@ function renderMixMatchBundle(container, bundle, outOfStockBehavior, onAddToCart
|
|
|
2733
2776
|
onCleanup?.(bindDropdowns(shell.root));
|
|
2734
2777
|
}
|
|
2735
2778
|
|
|
2779
|
+
// src/renderers/volume.ts
|
|
2780
|
+
var import_core4 = require("@lime-bundles/core");
|
|
2781
|
+
|
|
2736
2782
|
// ../render/src/volume/pricing.ts
|
|
2737
2783
|
function calcTierPrice(basePrice, discountType, tierEl) {
|
|
2738
2784
|
if (discountType === "fixed_amount") {
|
|
@@ -2761,6 +2807,23 @@ function formatItemCount(qty, translations) {
|
|
|
2761
2807
|
const tpl = translations.itemCount[form] || translations.itemCount.other || "__COUNT__";
|
|
2762
2808
|
return " (" + tpl.split("__COUNT__").join(String(qty)) + ")";
|
|
2763
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
|
+
}
|
|
2764
2827
|
function selectTier(container, allTiers, basePrice, discountType, index, translations, formatMoney) {
|
|
2765
2828
|
for (let i = 0; i < allTiers.length; i++) {
|
|
2766
2829
|
allTiers[i].setAttribute("aria-checked", i === index ? "true" : "false");
|
|
@@ -2818,8 +2881,17 @@ function renderVolumeBundle(container, bundle, outOfStockBehavior, onAddToCart)
|
|
|
2818
2881
|
const discountType = bundle.discountConfig.discountType;
|
|
2819
2882
|
const formatMoney = intlFormatMoney(product.priceRange.minVariantPrice.currencyCode);
|
|
2820
2883
|
const t = DEFAULT_STRINGS;
|
|
2821
|
-
const
|
|
2822
|
-
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
|
+
);
|
|
2823
2895
|
const tiers = bundle.volumeTiers.map((tier, i) => {
|
|
2824
2896
|
const percent = discountType === "fixed_amount" ? 0 : Math.round(tier.percentage ?? 0);
|
|
2825
2897
|
const amountCents = discountType === "fixed_amount" ? Math.round((tier.amount ?? 0) * 100) : 0;
|
|
@@ -2840,16 +2912,21 @@ function renderVolumeBundle(container, bundle, outOfStockBehavior, onAddToCart)
|
|
|
2840
2912
|
title: bundle.title,
|
|
2841
2913
|
subtitle: bundle.description,
|
|
2842
2914
|
summaryLabel: "Total",
|
|
2843
|
-
withItemCount:
|
|
2915
|
+
withItemCount: wc.pricing?.showItemCount !== false,
|
|
2844
2916
|
totalPriceSlot: true,
|
|
2845
2917
|
showSavingsBar: wc.savingsBar?.visible !== false,
|
|
2846
2918
|
showComparePrice: wc.pricing?.showCompareAtPrice !== false,
|
|
2847
2919
|
ctaText: wc.cta?.ctaText || t.addToCart || "Add to cart",
|
|
2848
2920
|
endsAt: wc.countdown?.showCountdown === false ? null : bundle.endsAt
|
|
2849
2921
|
});
|
|
2850
|
-
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
|
+
});
|
|
2851
2927
|
shell.products.replaceWith(group);
|
|
2852
2928
|
const tierEls = group.querySelectorAll("[data-tier-index]");
|
|
2929
|
+
updateAllTierPrices(tierEls, basePrice, discountType, formatMoney);
|
|
2853
2930
|
let selectedIndex = defaultIdx;
|
|
2854
2931
|
const apply = () => selectTier(shell.root, tierEls, basePrice, discountType, selectedIndex, t, formatMoney);
|
|
2855
2932
|
group.addEventListener("click", (e) => {
|
|
@@ -2999,6 +3076,13 @@ function buildBogoCartItems(sides, percent, buyQty, getQty) {
|
|
|
2999
3076
|
}
|
|
3000
3077
|
|
|
3001
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
|
+
}
|
|
3002
3086
|
function renderBogoBundle(container, bundle, outOfStockBehavior, onAddToCart, onCleanup) {
|
|
3003
3087
|
const wc = bundle.widgetConfig;
|
|
3004
3088
|
const buyProduct = bundle.products.find((p) => p.id === bundle.buyProductId);
|
|
@@ -3047,6 +3131,7 @@ function renderBogoBundle(container, bundle, outOfStockBehavior, onAddToCart, on
|
|
|
3047
3131
|
const badgeText = percent >= 100 ? "Free" : percent + "% off";
|
|
3048
3132
|
sides.forEach((side, i) => {
|
|
3049
3133
|
const isGet = i === 1;
|
|
3134
|
+
if (isGet) shell.products.appendChild(buildBogoPlus());
|
|
3050
3135
|
const isOos = !side.variants.some((v) => v.available);
|
|
3051
3136
|
const row = buildRowSkeleton(side, t, {
|
|
3052
3137
|
isOos,
|
|
@@ -3075,7 +3160,7 @@ function renderBogoBundle(container, bundle, outOfStockBehavior, onAddToCart, on
|
|
|
3075
3160
|
shell.cta.disabled = true;
|
|
3076
3161
|
const label = shell.cta.querySelector("[data-cta-label]");
|
|
3077
3162
|
if (label) {
|
|
3078
|
-
label.textContent = (t
|
|
3163
|
+
label.textContent = formatItemsOutOfStock(t, oosCount);
|
|
3079
3164
|
}
|
|
3080
3165
|
} else {
|
|
3081
3166
|
shell.cta.addEventListener("click", () => {
|
|
@@ -3095,7 +3180,7 @@ function renderBogoBundle(container, bundle, outOfStockBehavior, onAddToCart, on
|
|
|
3095
3180
|
}
|
|
3096
3181
|
|
|
3097
3182
|
// src/renderers/multi-step.ts
|
|
3098
|
-
var
|
|
3183
|
+
var import_core5 = require("@lime-bundles/core");
|
|
3099
3184
|
|
|
3100
3185
|
// ../render/src/multi-step/i18n.ts
|
|
3101
3186
|
function stepOfLabel(i, total, t) {
|
|
@@ -3724,7 +3809,7 @@ function renderMultiStepBundle(container, bundle, outOfStockBehavior, onAddToCar
|
|
|
3724
3809
|
variantQuantities: bundle.variantQuantities
|
|
3725
3810
|
};
|
|
3726
3811
|
const pools = steps.map(
|
|
3727
|
-
(_, i) => (0,
|
|
3812
|
+
(_, i) => (0, import_core5.productsForStep)(bundle, i).map((product) => {
|
|
3728
3813
|
const p = adaptProduct(product, bundle.id, {
|
|
3729
3814
|
quantities,
|
|
3730
3815
|
allowedVariantIds: null
|
|
@@ -3798,8 +3883,8 @@ function renderMultiStepBundle(container, bundle, outOfStockBehavior, onAddToCar
|
|
|
3798
3883
|
const overlay = buildPickerModal({
|
|
3799
3884
|
bundleGid: bundle.id,
|
|
3800
3885
|
domId: bundle.id.replace(/\D/g, ""),
|
|
3801
|
-
showSearch:
|
|
3802
|
-
showTypeFilters:
|
|
3886
|
+
showSearch: wc.showSearch !== false,
|
|
3887
|
+
showTypeFilters: wc.mixMatchShowTypeFilters !== false,
|
|
3803
3888
|
segmentCount: null,
|
|
3804
3889
|
wizard: true
|
|
3805
3890
|
});
|
|
@@ -3834,7 +3919,7 @@ function renderMultiStepBundle(container, bundle, outOfStockBehavior, onAddToCar
|
|
|
3834
3919
|
discountType: bundle.discountConfig.discountType,
|
|
3835
3920
|
discountValue: bundle.discountConfig.discountValue
|
|
3836
3921
|
},
|
|
3837
|
-
(total, type, value) => (0,
|
|
3922
|
+
(total, type, value) => (0, import_core5.calculateDiscount)(total, type, value),
|
|
3838
3923
|
updatePricing2(formatMoney)
|
|
3839
3924
|
);
|
|
3840
3925
|
updateProgress2(bodyDeps);
|
|
@@ -3846,8 +3931,8 @@ function renderMultiStepBundle(container, bundle, outOfStockBehavior, onAddToCar
|
|
|
3846
3931
|
selections,
|
|
3847
3932
|
t,
|
|
3848
3933
|
rulesMap,
|
|
3849
|
-
showQtySelector:
|
|
3850
|
-
showTypeFilters:
|
|
3934
|
+
showQtySelector: wc.mixMatchShowQuantitySelector !== false,
|
|
3935
|
+
showTypeFilters: wc.mixMatchShowTypeFilters !== false,
|
|
3851
3936
|
formatMoney,
|
|
3852
3937
|
dropdown: void 0,
|
|
3853
3938
|
portalTarget: null,
|
|
@@ -3897,7 +3982,7 @@ function renderMultiStepBundle(container, bundle, outOfStockBehavior, onAddToCar
|
|
|
3897
3982
|
}
|
|
3898
3983
|
|
|
3899
3984
|
// src/lime-bundle.ts
|
|
3900
|
-
var
|
|
3985
|
+
var import_core7 = require("@lime-bundles/core");
|
|
3901
3986
|
|
|
3902
3987
|
// src/utils/input-mode.ts
|
|
3903
3988
|
var NAV_KEYS = /* @__PURE__ */ new Set([
|
|
@@ -6553,6 +6638,13 @@ var LimeBundleElement = class extends HTMLElement {
|
|
|
6553
6638
|
buyer = void 0;
|
|
6554
6639
|
shadow;
|
|
6555
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;
|
|
6556
6648
|
abortController = null;
|
|
6557
6649
|
impressionCleanups = [];
|
|
6558
6650
|
/**
|
|
@@ -6572,7 +6664,7 @@ var LimeBundleElement = class extends HTMLElement {
|
|
|
6572
6664
|
* before the first render. Defaults to `show_greyed_out` so a failed or
|
|
6573
6665
|
* missing fetch degrades to "bundles still render".
|
|
6574
6666
|
*/
|
|
6575
|
-
outOfStockBehavior =
|
|
6667
|
+
outOfStockBehavior = import_core6.DEFAULT_OUT_OF_STOCK_BEHAVIOR;
|
|
6576
6668
|
constructor() {
|
|
6577
6669
|
super();
|
|
6578
6670
|
this.shadow = this.attachShadow({ mode: "open" });
|
|
@@ -6634,13 +6726,13 @@ var LimeBundleElement = class extends HTMLElement {
|
|
|
6634
6726
|
* no buyer/country/language is set.
|
|
6635
6727
|
*/
|
|
6636
6728
|
wrapQueryForContext(query) {
|
|
6637
|
-
return (0,
|
|
6729
|
+
return (0, import_core6.hasInContext)({
|
|
6638
6730
|
shopDomain: this.shopDomain,
|
|
6639
6731
|
accessToken: this.storefrontToken,
|
|
6640
6732
|
country: this.country,
|
|
6641
6733
|
language: this.language,
|
|
6642
6734
|
buyer: this.buyer
|
|
6643
|
-
}) ? (0,
|
|
6735
|
+
}) ? (0, import_core6.withInContext)(query) : query;
|
|
6644
6736
|
}
|
|
6645
6737
|
/**
|
|
6646
6738
|
* Returns true if this bundle should be hidden for the current market.
|
|
@@ -6649,7 +6741,7 @@ var LimeBundleElement = class extends HTMLElement {
|
|
|
6649
6741
|
* marketIds doesn't include the configured market.
|
|
6650
6742
|
*/
|
|
6651
6743
|
isMarketHidden(bundle) {
|
|
6652
|
-
return !(0,
|
|
6744
|
+
return !(0, import_core6.isVisibleInMarket)(bundle, this.marketId);
|
|
6653
6745
|
}
|
|
6654
6746
|
async fetchBundle() {
|
|
6655
6747
|
if (!this.shopDomain || !this.storefrontToken) {
|
|
@@ -6662,7 +6754,7 @@ var LimeBundleElement = class extends HTMLElement {
|
|
|
6662
6754
|
const controller = new AbortController();
|
|
6663
6755
|
this.abortController = controller;
|
|
6664
6756
|
this.renderLoading();
|
|
6665
|
-
const client = (0,
|
|
6757
|
+
const client = (0, import_core6.createStorefrontClient)({
|
|
6666
6758
|
shopDomain: this.shopDomain,
|
|
6667
6759
|
accessToken: this.storefrontToken,
|
|
6668
6760
|
country: this.country,
|
|
@@ -6672,11 +6764,12 @@ var LimeBundleElement = class extends HTMLElement {
|
|
|
6672
6764
|
try {
|
|
6673
6765
|
let bundlePromise;
|
|
6674
6766
|
let singleBundleMode = false;
|
|
6767
|
+
this.currentProductHandle = resolveProductHandle(this.productHandleAttr);
|
|
6675
6768
|
if (this.bundleGid) {
|
|
6676
6769
|
singleBundleMode = true;
|
|
6677
6770
|
bundlePromise = this.fetchSingleBundle(client, controller.signal);
|
|
6678
6771
|
} else {
|
|
6679
|
-
const handle =
|
|
6772
|
+
const handle = this.currentProductHandle;
|
|
6680
6773
|
if (!handle) {
|
|
6681
6774
|
this.teardownImpressions();
|
|
6682
6775
|
this.renderError(
|
|
@@ -6690,7 +6783,7 @@ var LimeBundleElement = class extends HTMLElement {
|
|
|
6690
6783
|
handle
|
|
6691
6784
|
);
|
|
6692
6785
|
}
|
|
6693
|
-
const shopSettingsPromise = client.query(
|
|
6786
|
+
const shopSettingsPromise = client.query(import_core6.SHOP_SETTINGS_QUERY, void 0, {
|
|
6694
6787
|
signal: controller.signal
|
|
6695
6788
|
}).catch(() => null);
|
|
6696
6789
|
await bundlePromise;
|
|
@@ -6703,11 +6796,11 @@ var LimeBundleElement = class extends HTMLElement {
|
|
|
6703
6796
|
const shopSettings = await shopSettingsPromise;
|
|
6704
6797
|
const customCss = shopSettings?.shop?.customCss?.value;
|
|
6705
6798
|
if (customCss) {
|
|
6706
|
-
(0,
|
|
6707
|
-
const sanitized = (0,
|
|
6799
|
+
(0, import_core6.injectCustomCss)(this.shopDomain, customCss);
|
|
6800
|
+
const sanitized = (0, import_core6.sanitizeCustomCss)(customCss);
|
|
6708
6801
|
if (sanitized.ok) this.shopCustomCss = sanitized.css;
|
|
6709
6802
|
}
|
|
6710
|
-
this.outOfStockBehavior = (0,
|
|
6803
|
+
this.outOfStockBehavior = (0, import_core6.parseOutOfStockBehavior)(
|
|
6711
6804
|
shopSettings?.shop?.outOfStockBehavior?.value
|
|
6712
6805
|
);
|
|
6713
6806
|
this.renderBundles();
|
|
@@ -6722,7 +6815,7 @@ var LimeBundleElement = class extends HTMLElement {
|
|
|
6722
6815
|
}
|
|
6723
6816
|
async fetchSingleBundle(client, signal) {
|
|
6724
6817
|
const data = await client.query(
|
|
6725
|
-
this.wrapQueryForContext(
|
|
6818
|
+
this.wrapQueryForContext(import_core6.BUNDLE_METAOBJECT_QUERY),
|
|
6726
6819
|
{ id: this.bundleGid },
|
|
6727
6820
|
{ signal }
|
|
6728
6821
|
);
|
|
@@ -6730,7 +6823,7 @@ var LimeBundleElement = class extends HTMLElement {
|
|
|
6730
6823
|
this.bundles = [];
|
|
6731
6824
|
return;
|
|
6732
6825
|
}
|
|
6733
|
-
const parsed = (0,
|
|
6826
|
+
const parsed = (0, import_core6.parseMetaobjectBundle)(
|
|
6734
6827
|
data.metaobject.id,
|
|
6735
6828
|
data.metaobject.fields
|
|
6736
6829
|
);
|
|
@@ -6738,7 +6831,7 @@ var LimeBundleElement = class extends HTMLElement {
|
|
|
6738
6831
|
}
|
|
6739
6832
|
async fetchProductBundles(client, signal, productHandle) {
|
|
6740
6833
|
const data = await client.query(
|
|
6741
|
-
this.wrapQueryForContext(
|
|
6834
|
+
this.wrapQueryForContext(import_core6.BUNDLES_FOR_PRODUCT_QUERY),
|
|
6742
6835
|
{ handle: productHandle },
|
|
6743
6836
|
{ signal }
|
|
6744
6837
|
);
|
|
@@ -6749,10 +6842,10 @@ var LimeBundleElement = class extends HTMLElement {
|
|
|
6749
6842
|
const refs = data.product.metafield?.references?.nodes ?? [];
|
|
6750
6843
|
const bundles = [];
|
|
6751
6844
|
for (const ref of refs) {
|
|
6752
|
-
const parsed = (0,
|
|
6845
|
+
const parsed = (0, import_core6.parseMetaobjectBundle)(ref.id, ref.fields);
|
|
6753
6846
|
if (parsed && !this.isMarketHidden(parsed)) bundles.push(parsed);
|
|
6754
6847
|
}
|
|
6755
|
-
this.bundles = (0,
|
|
6848
|
+
this.bundles = (0, import_core6.resolveAbTests)(bundles, (0, import_core6.getVisitorId)());
|
|
6756
6849
|
}
|
|
6757
6850
|
/**
|
|
6758
6851
|
* Dispatch add-to-cart with a cancelable event, then — unless a listener
|
|
@@ -6782,7 +6875,7 @@ var LimeBundleElement = class extends HTMLElement {
|
|
|
6782
6875
|
*/
|
|
6783
6876
|
async defaultAddToCart(lines) {
|
|
6784
6877
|
if (typeof window === "undefined") return;
|
|
6785
|
-
const client = (0,
|
|
6878
|
+
const client = (0, import_core6.createStorefrontClient)({
|
|
6786
6879
|
shopDomain: this.shopDomain,
|
|
6787
6880
|
accessToken: this.storefrontToken
|
|
6788
6881
|
});
|
|
@@ -6793,7 +6886,7 @@ var LimeBundleElement = class extends HTMLElement {
|
|
|
6793
6886
|
let checkoutUrl = null;
|
|
6794
6887
|
if (existingCartId) {
|
|
6795
6888
|
const res = await client.query(
|
|
6796
|
-
|
|
6889
|
+
import_core6.CART_LINES_ADD_MUTATION,
|
|
6797
6890
|
{ cartId: existingCartId, lines }
|
|
6798
6891
|
);
|
|
6799
6892
|
const payload = res.cartLinesAdd;
|
|
@@ -6805,7 +6898,7 @@ var LimeBundleElement = class extends HTMLElement {
|
|
|
6805
6898
|
}
|
|
6806
6899
|
if (!checkoutUrl) {
|
|
6807
6900
|
const res = await client.query(
|
|
6808
|
-
|
|
6901
|
+
import_core6.CART_CREATE_MUTATION,
|
|
6809
6902
|
{ input: { lines } }
|
|
6810
6903
|
);
|
|
6811
6904
|
const payload = res.cartCreate;
|
|
@@ -6851,7 +6944,7 @@ var LimeBundleElement = class extends HTMLElement {
|
|
|
6851
6944
|
const price = variant ? parseFloat(variant.price.amount) : 0;
|
|
6852
6945
|
return sum + price * line.quantity;
|
|
6853
6946
|
}, 0);
|
|
6854
|
-
(0,
|
|
6947
|
+
(0, import_core6.reportAddToCart)(
|
|
6855
6948
|
{ shopDomain: this.shopDomain, appUrl: this.appUrl },
|
|
6856
6949
|
{
|
|
6857
6950
|
bundleGid: bundle.id,
|
|
@@ -6890,7 +6983,8 @@ var LimeBundleElement = class extends HTMLElement {
|
|
|
6890
6983
|
container.setAttribute("aria-label", bundle.title);
|
|
6891
6984
|
container.setAttribute("data-bundle-type", bundle.bundleType);
|
|
6892
6985
|
container.setAttribute("data-bundle-gid", bundle.id);
|
|
6893
|
-
(
|
|
6986
|
+
if (bundle.endsAt) container.setAttribute("data-ends-at", bundle.endsAt);
|
|
6987
|
+
(0, import_core7.applyWidgetConfigVars)(container, bundle.widgetConfig);
|
|
6894
6988
|
this.renderCleanups.push(trackInputMode(container));
|
|
6895
6989
|
const dispatch = (lines) => this.handleAddToCart(bundle, lines);
|
|
6896
6990
|
const registerCleanup = (fn) => this.renderCleanups.push(fn);
|
|
@@ -6910,7 +7004,8 @@ var LimeBundleElement = class extends HTMLElement {
|
|
|
6910
7004
|
bundle,
|
|
6911
7005
|
this.outOfStockBehavior,
|
|
6912
7006
|
dispatch,
|
|
6913
|
-
registerCleanup
|
|
7007
|
+
registerCleanup,
|
|
7008
|
+
this.currentProductHandle
|
|
6914
7009
|
);
|
|
6915
7010
|
break;
|
|
6916
7011
|
case "volume":
|
|
@@ -6956,8 +7051,8 @@ var LimeBundleElement = class extends HTMLElement {
|
|
|
6956
7051
|
}
|
|
6957
7052
|
setupImpressionFor(bundle, element) {
|
|
6958
7053
|
if (!this.analyticsEnabled || !this.appUrl) return;
|
|
6959
|
-
const cleanup = (0,
|
|
6960
|
-
(0,
|
|
7054
|
+
const cleanup = (0, import_core6.observeImpression)(element, () => {
|
|
7055
|
+
(0, import_core6.reportImpression)(
|
|
6961
7056
|
{ shopDomain: this.shopDomain, appUrl: this.appUrl },
|
|
6962
7057
|
{
|
|
6963
7058
|
bundleGid: bundle.id,
|
package/dist/index.d.cts
CHANGED
|
@@ -61,6 +61,13 @@ declare class LimeBundleElement extends HTMLElement {
|
|
|
61
61
|
buyer: BuyerResolver | undefined;
|
|
62
62
|
private shadow;
|
|
63
63
|
private bundles;
|
|
64
|
+
/**
|
|
65
|
+
* The product handle this embed is standing on, when one can be resolved
|
|
66
|
+
* (attribute → meta tag → /products/<handle> path). The mix-and-match
|
|
67
|
+
* courtesy seed uses it to pre-add the current product the way the theme
|
|
68
|
+
* widget does; null on pages with no product context.
|
|
69
|
+
*/
|
|
70
|
+
private currentProductHandle;
|
|
64
71
|
private abortController;
|
|
65
72
|
private impressionCleanups;
|
|
66
73
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -61,6 +61,13 @@ declare class LimeBundleElement extends HTMLElement {
|
|
|
61
61
|
buyer: BuyerResolver | undefined;
|
|
62
62
|
private shadow;
|
|
63
63
|
private bundles;
|
|
64
|
+
/**
|
|
65
|
+
* The product handle this embed is standing on, when one can be resolved
|
|
66
|
+
* (attribute → meta tag → /products/<handle> path). The mix-and-match
|
|
67
|
+
* courtesy seed uses it to pre-add the current product the way the theme
|
|
68
|
+
* widget does; null on pages with no product context.
|
|
69
|
+
*/
|
|
70
|
+
private currentProductHandle;
|
|
64
71
|
private abortController;
|
|
65
72
|
private impressionCleanups;
|
|
66
73
|
/**
|