@lime-bundles/widget 2.0.0 → 2.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 +167 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +167 -21
- package/dist/index.js.map +1 -1
- package/dist/lime-bundle.global.js +146 -16
- package/dist/lime-bundle.global.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -544,7 +544,20 @@ function renderMixMatchBundle(container, bundle, onAddToCart, onCleanup) {
|
|
|
544
544
|
})
|
|
545
545
|
);
|
|
546
546
|
container.appendChild(root);
|
|
547
|
-
|
|
547
|
+
const firstEligible = eligible.find((ep) => !ep.isOos);
|
|
548
|
+
const firstVariant = firstEligible?.firstAvailableVariant ?? firstEligible?.variants[0];
|
|
549
|
+
if (firstEligible && firstVariant) {
|
|
550
|
+
selections.push({
|
|
551
|
+
productId: firstEligible.product.id,
|
|
552
|
+
productTitle: firstEligible.product.title,
|
|
553
|
+
variantId: firstVariant.id,
|
|
554
|
+
variantTitle: firstVariant.title,
|
|
555
|
+
imageUrl: firstEligible.product.featuredImage?.url ?? null,
|
|
556
|
+
priceCents: parseCents(firstVariant.price.amount),
|
|
557
|
+
compareCents: firstVariant.compareAtPrice ? parseCents(firstVariant.compareAtPrice.amount) : null
|
|
558
|
+
});
|
|
559
|
+
}
|
|
560
|
+
afterMutation();
|
|
548
561
|
function addSelection(product, variant) {
|
|
549
562
|
if (selections.length >= maxQty) return;
|
|
550
563
|
selections.push({
|
|
@@ -1089,15 +1102,15 @@ function renderVolumeBundle(container, bundle, onAddToCart, onCleanup) {
|
|
|
1089
1102
|
if (!variant && wc.outOfStockBehavior === "hide") return;
|
|
1090
1103
|
const basePriceCents = variant ? parseCents(variant.price.amount) : 0;
|
|
1091
1104
|
const currency = variant?.price.currencyCode ?? "USD";
|
|
1105
|
+
const discountType = bundle.discountConfig.discountType;
|
|
1092
1106
|
const resolved = bundle.volumeTiers.map((tier, index) => {
|
|
1093
1107
|
let perUnit;
|
|
1094
|
-
if (
|
|
1095
|
-
const amt = Math.round(tier.
|
|
1108
|
+
if (discountType === "fixed_amount") {
|
|
1109
|
+
const amt = Math.round((tier.amount ?? 0) * 100);
|
|
1096
1110
|
perUnit = Math.max(0, basePriceCents - amt);
|
|
1097
1111
|
} else {
|
|
1098
|
-
const
|
|
1099
|
-
|
|
1100
|
-
);
|
|
1112
|
+
const pct = tier.percentage ?? 0;
|
|
1113
|
+
const discount = Math.floor(basePriceCents * pct / 100);
|
|
1101
1114
|
perUnit = Math.max(0, basePriceCents - discount);
|
|
1102
1115
|
}
|
|
1103
1116
|
return {
|
|
@@ -1115,7 +1128,9 @@ function renderVolumeBundle(container, bundle, onAddToCart, onCleanup) {
|
|
|
1115
1128
|
}
|
|
1116
1129
|
const popularIndex = wc.popularBadge.tierIndex !== void 0 ? clamp(wc.popularBadge.tierIndex, 0, resolved.length - 1) : bestTierIndex;
|
|
1117
1130
|
const root = el("div", "lb-volume");
|
|
1118
|
-
root.appendChild(
|
|
1131
|
+
root.appendChild(
|
|
1132
|
+
renderHeader3(bundle, resolved, selectedIndex, currency, discountType)
|
|
1133
|
+
);
|
|
1119
1134
|
if (wc.countdown.showCountdown && bundle.endsAt) {
|
|
1120
1135
|
const countdown = renderCountdown(bundle.endsAt);
|
|
1121
1136
|
if (countdown) {
|
|
@@ -1216,7 +1231,7 @@ function renderVolumeBundle(container, bundle, onAddToCart, onCleanup) {
|
|
|
1216
1231
|
}
|
|
1217
1232
|
const badgeEl = root.querySelector("[data-header-badge]");
|
|
1218
1233
|
if (badgeEl) {
|
|
1219
|
-
const label = badgeFor(resolved[idx], currency);
|
|
1234
|
+
const label = badgeFor(resolved[idx], currency, discountType);
|
|
1220
1235
|
if (label) {
|
|
1221
1236
|
badgeEl.textContent = label;
|
|
1222
1237
|
badgeEl.style.display = "";
|
|
@@ -1226,7 +1241,7 @@ function renderVolumeBundle(container, bundle, onAddToCart, onCleanup) {
|
|
|
1226
1241
|
}
|
|
1227
1242
|
}
|
|
1228
1243
|
}
|
|
1229
|
-
function renderHeader3(bundle, resolved, selectedIndex, currency) {
|
|
1244
|
+
function renderHeader3(bundle, resolved, selectedIndex, currency, discountType) {
|
|
1230
1245
|
const wc = bundle.widgetConfig;
|
|
1231
1246
|
const header = el("div", "lb-bundle-header");
|
|
1232
1247
|
const content = el("div", "lb-bundle-header__content");
|
|
@@ -1235,7 +1250,7 @@ function renderHeader3(bundle, resolved, selectedIndex, currency) {
|
|
|
1235
1250
|
content.appendChild(title);
|
|
1236
1251
|
header.appendChild(content);
|
|
1237
1252
|
if (wc.pricing.showSaveBadge) {
|
|
1238
|
-
const badge = badgeFor(resolved[selectedIndex], currency);
|
|
1253
|
+
const badge = badgeFor(resolved[selectedIndex], currency, discountType);
|
|
1239
1254
|
if (badge) {
|
|
1240
1255
|
const badgeEl = el("span", "lb-bundle-header__badge", {
|
|
1241
1256
|
"data-header-badge": ""
|
|
@@ -1348,14 +1363,18 @@ function renderCta2(bundle, onClick) {
|
|
|
1348
1363
|
});
|
|
1349
1364
|
return button;
|
|
1350
1365
|
}
|
|
1351
|
-
function badgeFor(resolved, currency) {
|
|
1366
|
+
function badgeFor(resolved, currency, discountType) {
|
|
1352
1367
|
if (!resolved) return null;
|
|
1353
1368
|
const { tier } = resolved;
|
|
1354
|
-
if (
|
|
1355
|
-
|
|
1369
|
+
if (discountType === "fixed_amount") {
|
|
1370
|
+
const amount = tier.amount ?? 0;
|
|
1371
|
+
if (amount > 0) return `-${formatCents(Math.round(amount * 100), currency)}`;
|
|
1372
|
+
return null;
|
|
1356
1373
|
}
|
|
1357
|
-
if (
|
|
1358
|
-
|
|
1374
|
+
if (discountType === "percentage") {
|
|
1375
|
+
const pct = tier.percentage ?? 0;
|
|
1376
|
+
if (pct > 0) return `-${Math.round(pct)}%`;
|
|
1377
|
+
return null;
|
|
1359
1378
|
}
|
|
1360
1379
|
return null;
|
|
1361
1380
|
}
|
|
@@ -1400,6 +1419,10 @@ var BUNDLE_BASE_CSS = `/* Lime Bundles \u2014 shared base styles for all bundle
|
|
|
1400
1419
|
border-radius: var(--lb-radius);
|
|
1401
1420
|
padding: var(--lb-widget-pad) var(--lb-widget-pad) 20px;
|
|
1402
1421
|
box-sizing: border-box;
|
|
1422
|
+
/* Cap the widget at a comfortable reading width on desktop. Below
|
|
1423
|
+
440px viewports the container is already narrower than the cap,
|
|
1424
|
+
so the rule is inert on mobile. */
|
|
1425
|
+
max-width: 440px;
|
|
1403
1426
|
}
|
|
1404
1427
|
|
|
1405
1428
|
/* Countdown timer bar \u2014 sits below the gradient header */
|
|
@@ -2464,6 +2487,103 @@ var BUNDLE_VOLUME_CSS = `/* Lime Bundles \u2014 Volume / Quantity Breaks styles
|
|
|
2464
2487
|
}
|
|
2465
2488
|
|
|
2466
2489
|
|
|
2490
|
+
`;
|
|
2491
|
+
var BUNDLE_SKELETON_CSS = `/* Lime Bundles \u2014 web-component loading skeleton (not mirrored to theme assets) */
|
|
2492
|
+
|
|
2493
|
+
.lb-bundle-widget--loading {
|
|
2494
|
+
display: block;
|
|
2495
|
+
padding: var(--lb-widget-pad, 20px);
|
|
2496
|
+
border: 1px solid var(--lb-border, #E5E5E5);
|
|
2497
|
+
border-radius: var(--lb-radius, 12px);
|
|
2498
|
+
background: var(--lb-bg, #FFFFFF);
|
|
2499
|
+
/* Contain layout/paint so the skeleton doesn't influence ancestor
|
|
2500
|
+
layout once the real content swaps in. */
|
|
2501
|
+
contain: layout paint;
|
|
2502
|
+
}
|
|
2503
|
+
|
|
2504
|
+
.lb-bundle-widget--loading .lb-skeleton {
|
|
2505
|
+
background: linear-gradient(
|
|
2506
|
+
90deg,
|
|
2507
|
+
rgba(0, 0, 0, 0.06) 0%,
|
|
2508
|
+
rgba(0, 0, 0, 0.10) 50%,
|
|
2509
|
+
rgba(0, 0, 0, 0.06) 100%
|
|
2510
|
+
);
|
|
2511
|
+
background-size: 200% 100%;
|
|
2512
|
+
border-radius: 6px;
|
|
2513
|
+
animation: lb-skeleton-pulse 1.4s ease-in-out infinite;
|
|
2514
|
+
}
|
|
2515
|
+
|
|
2516
|
+
.lb-bundle-widget--loading .lb-skeleton--title {
|
|
2517
|
+
height: 28px;
|
|
2518
|
+
width: 60%;
|
|
2519
|
+
margin-bottom: 16px;
|
|
2520
|
+
}
|
|
2521
|
+
|
|
2522
|
+
.lb-bundle-widget--loading .lb-skeleton--products {
|
|
2523
|
+
display: grid;
|
|
2524
|
+
gap: 12px;
|
|
2525
|
+
margin-bottom: 16px;
|
|
2526
|
+
}
|
|
2527
|
+
|
|
2528
|
+
.lb-bundle-widget--loading .lb-skeleton--row {
|
|
2529
|
+
display: grid;
|
|
2530
|
+
grid-template-columns: 56px 1fr 60px;
|
|
2531
|
+
gap: 12px;
|
|
2532
|
+
align-items: center;
|
|
2533
|
+
}
|
|
2534
|
+
|
|
2535
|
+
.lb-bundle-widget--loading .lb-skeleton--thumb {
|
|
2536
|
+
height: 56px;
|
|
2537
|
+
width: 56px;
|
|
2538
|
+
border-radius: 8px;
|
|
2539
|
+
}
|
|
2540
|
+
|
|
2541
|
+
.lb-bundle-widget--loading .lb-skeleton--line {
|
|
2542
|
+
height: 14px;
|
|
2543
|
+
border-radius: 4px;
|
|
2544
|
+
}
|
|
2545
|
+
|
|
2546
|
+
.lb-bundle-widget--loading .lb-skeleton--line + .lb-skeleton--line {
|
|
2547
|
+
margin-top: 8px;
|
|
2548
|
+
width: 70%;
|
|
2549
|
+
}
|
|
2550
|
+
|
|
2551
|
+
.lb-bundle-widget--loading .lb-skeleton--price {
|
|
2552
|
+
height: 20px;
|
|
2553
|
+
width: 60px;
|
|
2554
|
+
}
|
|
2555
|
+
|
|
2556
|
+
.lb-bundle-widget--loading .lb-skeleton--footer {
|
|
2557
|
+
margin-top: 16px;
|
|
2558
|
+
padding-top: 16px;
|
|
2559
|
+
border-top: 1px solid var(--lb-border, #E5E5E5);
|
|
2560
|
+
display: grid;
|
|
2561
|
+
grid-template-columns: 1fr auto;
|
|
2562
|
+
gap: 12px;
|
|
2563
|
+
align-items: center;
|
|
2564
|
+
}
|
|
2565
|
+
|
|
2566
|
+
.lb-bundle-widget--loading .lb-skeleton--total {
|
|
2567
|
+
height: 24px;
|
|
2568
|
+
width: 40%;
|
|
2569
|
+
}
|
|
2570
|
+
|
|
2571
|
+
.lb-bundle-widget--loading .lb-skeleton--cta {
|
|
2572
|
+
height: 44px;
|
|
2573
|
+
width: 140px;
|
|
2574
|
+
border-radius: var(--lb-cta-radius, 8px);
|
|
2575
|
+
}
|
|
2576
|
+
|
|
2577
|
+
@keyframes lb-skeleton-pulse {
|
|
2578
|
+
0% { background-position: 0% 50%; }
|
|
2579
|
+
100% { background-position: -200% 50%; }
|
|
2580
|
+
}
|
|
2581
|
+
|
|
2582
|
+
@media (prefers-reduced-motion: reduce) {
|
|
2583
|
+
.lb-bundle-widget--loading .lb-skeleton {
|
|
2584
|
+
animation: none;
|
|
2585
|
+
}
|
|
2586
|
+
}
|
|
2467
2587
|
`;
|
|
2468
2588
|
|
|
2469
2589
|
// src/lime-bundle.ts
|
|
@@ -2513,7 +2633,6 @@ var LimeBundleElement = class extends HTMLElement {
|
|
|
2513
2633
|
this.shadow = this.attachShadow({ mode: "open" });
|
|
2514
2634
|
}
|
|
2515
2635
|
connectedCallback() {
|
|
2516
|
-
this.render();
|
|
2517
2636
|
this.fetchBundle();
|
|
2518
2637
|
}
|
|
2519
2638
|
disconnectedCallback() {
|
|
@@ -2868,9 +2987,39 @@ var LimeBundleElement = class extends HTMLElement {
|
|
|
2868
2987
|
renderLoading() {
|
|
2869
2988
|
this.shadow.innerHTML = `
|
|
2870
2989
|
<style>${BUNDLE_BASE_CSS}</style>
|
|
2871
|
-
<
|
|
2990
|
+
<style>${BUNDLE_SKELETON_CSS}</style>
|
|
2991
|
+
<div class="lb-bundle-widget lb-bundle-widget--loading" aria-busy="true" aria-label="Loading bundle">
|
|
2872
2992
|
<div class="lb-skeleton lb-skeleton--title"></div>
|
|
2873
|
-
<div class="lb-skeleton
|
|
2993
|
+
<div class="lb-skeleton--products">
|
|
2994
|
+
<div class="lb-skeleton--row">
|
|
2995
|
+
<div class="lb-skeleton lb-skeleton--thumb"></div>
|
|
2996
|
+
<div>
|
|
2997
|
+
<div class="lb-skeleton lb-skeleton--line"></div>
|
|
2998
|
+
<div class="lb-skeleton lb-skeleton--line"></div>
|
|
2999
|
+
</div>
|
|
3000
|
+
<div class="lb-skeleton lb-skeleton--price"></div>
|
|
3001
|
+
</div>
|
|
3002
|
+
<div class="lb-skeleton--row">
|
|
3003
|
+
<div class="lb-skeleton lb-skeleton--thumb"></div>
|
|
3004
|
+
<div>
|
|
3005
|
+
<div class="lb-skeleton lb-skeleton--line"></div>
|
|
3006
|
+
<div class="lb-skeleton lb-skeleton--line"></div>
|
|
3007
|
+
</div>
|
|
3008
|
+
<div class="lb-skeleton lb-skeleton--price"></div>
|
|
3009
|
+
</div>
|
|
3010
|
+
<div class="lb-skeleton--row">
|
|
3011
|
+
<div class="lb-skeleton lb-skeleton--thumb"></div>
|
|
3012
|
+
<div>
|
|
3013
|
+
<div class="lb-skeleton lb-skeleton--line"></div>
|
|
3014
|
+
<div class="lb-skeleton lb-skeleton--line"></div>
|
|
3015
|
+
</div>
|
|
3016
|
+
<div class="lb-skeleton lb-skeleton--price"></div>
|
|
3017
|
+
</div>
|
|
3018
|
+
</div>
|
|
3019
|
+
<div class="lb-skeleton--footer">
|
|
3020
|
+
<div class="lb-skeleton lb-skeleton--total"></div>
|
|
3021
|
+
<div class="lb-skeleton lb-skeleton--cta"></div>
|
|
3022
|
+
</div>
|
|
2874
3023
|
</div>
|
|
2875
3024
|
`;
|
|
2876
3025
|
}
|
|
@@ -2884,9 +3033,6 @@ var LimeBundleElement = class extends HTMLElement {
|
|
|
2884
3033
|
})
|
|
2885
3034
|
);
|
|
2886
3035
|
}
|
|
2887
|
-
render() {
|
|
2888
|
-
this.shadow.innerHTML = `<style>${BUNDLE_BASE_CSS}</style>`;
|
|
2889
|
-
}
|
|
2890
3036
|
};
|
|
2891
3037
|
|
|
2892
3038
|
// src/index.ts
|