@lime-bundles/widget 2.2.0 → 2.3.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 +100 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +86 -22
- package/dist/index.js.map +1 -1
- package/dist/lime-bundle.global.js +80 -33
- package/dist/lime-bundle.global.js.map +1 -1
- package/docs/css-variables.md +2 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -16,13 +16,19 @@ import {
|
|
|
16
16
|
applyABVariantB
|
|
17
17
|
} from "@lime-bundles/core";
|
|
18
18
|
|
|
19
|
+
// src/renderers/fixed.ts
|
|
20
|
+
import {
|
|
21
|
+
resolveBundleQty
|
|
22
|
+
} from "@lime-bundles/core";
|
|
23
|
+
|
|
19
24
|
// src/renderers/pricing.ts
|
|
20
25
|
import {
|
|
21
26
|
parseCents,
|
|
22
27
|
formatCents,
|
|
23
28
|
percentageDiscountUnit,
|
|
24
29
|
computeFixedPricing,
|
|
25
|
-
computeBundleSaleCents
|
|
30
|
+
computeBundleSaleCents,
|
|
31
|
+
formatUnitPrice
|
|
26
32
|
} from "@lime-bundles/core";
|
|
27
33
|
|
|
28
34
|
// src/renderers/countdown.ts
|
|
@@ -121,11 +127,7 @@ var PLACEHOLDER_THUMB_SVG = `
|
|
|
121
127
|
</svg>`;
|
|
122
128
|
function renderFixedBundle(container, bundle, onAddToCart, onCleanup) {
|
|
123
129
|
const wc = bundle.widgetConfig;
|
|
124
|
-
const qtyFor = (productId, variantId) =>
|
|
125
|
-
const vq = bundle.variantQuantities[variantId];
|
|
126
|
-
if (vq !== void 0) return vq;
|
|
127
|
-
return bundle.productQuantities[productId] ?? 1;
|
|
128
|
-
};
|
|
130
|
+
const qtyFor = (productId, variantId) => resolveBundleQty(bundle, productId, variantId);
|
|
129
131
|
const rows = [];
|
|
130
132
|
let oosCount = 0;
|
|
131
133
|
bundle.products.forEach((product, idx) => {
|
|
@@ -216,9 +218,7 @@ function buildRowState(bundle, product, productIndex) {
|
|
|
216
218
|
const eligibleVariants = selectedVariantIds && selectedVariantIds.length > 0 ? available.filter((v) => selectedVariantIds.includes(v.id)) : available;
|
|
217
219
|
const isOos = eligibleVariants.length === 0;
|
|
218
220
|
const selected = eligibleVariants[0] ?? null;
|
|
219
|
-
const
|
|
220
|
-
const variantQty = selected ? bundle.variantQuantities[selected.id] : void 0;
|
|
221
|
-
const qty = variantQty ?? productQty;
|
|
221
|
+
const qty = selected ? resolveBundleQty(bundle, product.id, selected.id) : 1;
|
|
222
222
|
return { product, eligibleVariants, selected, qty, isOos };
|
|
223
223
|
}
|
|
224
224
|
function renderHeader(bundle, currency) {
|
|
@@ -333,6 +333,11 @@ function renderProductRow(state, currency, qtyFor, onVariantChange) {
|
|
|
333
333
|
prices.appendChild(compare);
|
|
334
334
|
prices.appendChild(priceEl);
|
|
335
335
|
info.appendChild(prices);
|
|
336
|
+
const unitPriceEl = el("span", "lb-bundle-product-unit-price", {
|
|
337
|
+
"data-product-unit-price": ""
|
|
338
|
+
});
|
|
339
|
+
unitPriceEl.setAttribute("hidden", "");
|
|
340
|
+
info.appendChild(unitPriceEl);
|
|
336
341
|
const applyVariantToRow = (variant) => {
|
|
337
342
|
const unit = parseCents(variant.price.amount);
|
|
338
343
|
priceEl.textContent = formatCents(unit, currency);
|
|
@@ -347,6 +352,17 @@ function renderProductRow(state, currency, qtyFor, onVariantChange) {
|
|
|
347
352
|
} else {
|
|
348
353
|
compare.setAttribute("hidden", "");
|
|
349
354
|
}
|
|
355
|
+
const unitText = formatUnitPrice(
|
|
356
|
+
variant.unitPrice,
|
|
357
|
+
variant.unitPriceMeasurement,
|
|
358
|
+
currency
|
|
359
|
+
);
|
|
360
|
+
if (unitText) {
|
|
361
|
+
unitPriceEl.textContent = unitText;
|
|
362
|
+
unitPriceEl.removeAttribute("hidden");
|
|
363
|
+
} else {
|
|
364
|
+
unitPriceEl.setAttribute("hidden", "");
|
|
365
|
+
}
|
|
350
366
|
};
|
|
351
367
|
applyVariantToRow(state.selected);
|
|
352
368
|
if (state.eligibleVariants.length > 1) {
|
|
@@ -957,6 +973,19 @@ function renderModal(bundle, eligible, currency, handlers) {
|
|
|
957
973
|
const price = el("span", "lb-mix-match__modal-product-price");
|
|
958
974
|
price.textContent = formatCents(parseCents(variant.price.amount), currency);
|
|
959
975
|
info.appendChild(price);
|
|
976
|
+
const unitPriceText = formatUnitPrice(
|
|
977
|
+
variant.unitPrice,
|
|
978
|
+
variant.unitPriceMeasurement,
|
|
979
|
+
currency
|
|
980
|
+
);
|
|
981
|
+
if (unitPriceText) {
|
|
982
|
+
const unitPrice = el(
|
|
983
|
+
"span",
|
|
984
|
+
"lb-mix-match__modal-product-unit-price lb-bundle-product-unit-price"
|
|
985
|
+
);
|
|
986
|
+
unitPrice.textContent = unitPriceText;
|
|
987
|
+
info.appendChild(unitPrice);
|
|
988
|
+
}
|
|
960
989
|
if (ep.isOos) {
|
|
961
990
|
const soldOut = el("span", "lb-mix-match__modal-sold-out-label");
|
|
962
991
|
soldOut.textContent = "Sold out";
|
|
@@ -1422,7 +1451,6 @@ var BUNDLE_BASE_CSS = `/* Lime Bundles \u2014 shared base styles for all bundle
|
|
|
1422
1451
|
|
|
1423
1452
|
.lb-bundle-widget {
|
|
1424
1453
|
/* Internal CSS-only vars (not merchant-configurable). */
|
|
1425
|
-
--lb-text-muted: #666666;
|
|
1426
1454
|
--lb-thumbnail-bg: #F0F0F0;
|
|
1427
1455
|
--lb-widget-pad: 20px;
|
|
1428
1456
|
--lb-progress-color: var(--lb-primary-color);
|
|
@@ -1445,7 +1473,7 @@ var BUNDLE_BASE_CSS = `/* Lime Bundles \u2014 shared base styles for all bundle
|
|
|
1445
1473
|
margin: 0 calc(-1 * var(--lb-widget-pad)) 20px;
|
|
1446
1474
|
padding: 12px 20px;
|
|
1447
1475
|
background: var(--lb-countdown-bg);
|
|
1448
|
-
border-top: 1px solid
|
|
1476
|
+
border-top: 1px solid color-mix(in srgb, var(--lb-text) 6%, transparent);
|
|
1449
1477
|
display: flex;
|
|
1450
1478
|
align-items: center;
|
|
1451
1479
|
justify-content: space-between;
|
|
@@ -1485,11 +1513,20 @@ var BUNDLE_BASE_CSS = `/* Lime Bundles \u2014 shared base styles for all bundle
|
|
|
1485
1513
|
display: none;
|
|
1486
1514
|
}
|
|
1487
1515
|
|
|
1488
|
-
/*
|
|
1489
|
-
|
|
1516
|
+
/* Sibling widget spacing \u2014 separates multiple bundles on the same product page.
|
|
1517
|
+
Uses \`~\` (general sibling) rather than \`+\` (adjacent) because each Liquid
|
|
1518
|
+
loop iteration emits a {% style %} block before its widget div, so the
|
|
1519
|
+
rendered DOM alternates <style><widget><style><widget>. The \`+\` combinator
|
|
1520
|
+
requires immediate adjacency and would match nothing; \`~\` matches every
|
|
1521
|
+
widget after the first regardless of elements between. Single-widget pages
|
|
1522
|
+
stay unaffected (no prior \`.lb-bundle-widget\` sibling to match against).
|
|
1523
|
+
Only \`margin-top\` \u2014 do NOT override \`padding-top\` here. The gradient header
|
|
1524
|
+
uses \`margin-top: calc(-1 * var(--lb-widget-pad))\` to reach the widget's
|
|
1525
|
+
inner border edge, assuming padding-top == --lb-widget-pad. Changing
|
|
1526
|
+
padding-top on the subsequent widget breaks that math and leaves a visible
|
|
1527
|
+
gap above the header. */
|
|
1528
|
+
.lb-bundle-widget ~ .lb-bundle-widget {
|
|
1490
1529
|
margin-top: 24px;
|
|
1491
|
-
padding-top: 24px;
|
|
1492
|
-
border-top: 1px solid var(--lb-border);
|
|
1493
1530
|
}
|
|
1494
1531
|
|
|
1495
1532
|
/* Header \u2014 gradient banner with title + savings badge */
|
|
@@ -1532,7 +1569,7 @@ var BUNDLE_BASE_CSS = `/* Lime Bundles \u2014 shared base styles for all bundle
|
|
|
1532
1569
|
font-size: 16px;
|
|
1533
1570
|
font-weight: 400;
|
|
1534
1571
|
line-height: 20px;
|
|
1535
|
-
color: var(--lb-text
|
|
1572
|
+
color: color-mix(in srgb, var(--lb-text) 60%, transparent);
|
|
1536
1573
|
margin: 4px 0 0;
|
|
1537
1574
|
}
|
|
1538
1575
|
|
|
@@ -1601,7 +1638,7 @@ var BUNDLE_BASE_CSS = `/* Lime Bundles \u2014 shared base styles for all bundle
|
|
|
1601
1638
|
.lb-bundle-thumbnail svg {
|
|
1602
1639
|
width: 28px;
|
|
1603
1640
|
height: 28px;
|
|
1604
|
-
color:
|
|
1641
|
+
color: color-mix(in srgb, var(--lb-text) 35%, transparent);
|
|
1605
1642
|
}
|
|
1606
1643
|
|
|
1607
1644
|
.lb-bundle-product-info {
|
|
@@ -1656,6 +1693,22 @@ var BUNDLE_BASE_CSS = `/* Lime Bundles \u2014 shared base styles for all bundle
|
|
|
1656
1693
|
display: none;
|
|
1657
1694
|
}
|
|
1658
1695
|
|
|
1696
|
+
/* Unit price (e.g. "$0.50/100ml") \u2014 only rendered when the merchant has
|
|
1697
|
+
configured unit pricing on the variant in the Shopify admin. No merchant
|
|
1698
|
+
toggle: present in admin \u2192 shown; absent \u2192 hidden. Styled as muted
|
|
1699
|
+
secondary text beneath the price row so it doesn't compete visually. */
|
|
1700
|
+
.lb-bundle-product-unit-price {
|
|
1701
|
+
display: block;
|
|
1702
|
+
font-size: 11px;
|
|
1703
|
+
line-height: 16px;
|
|
1704
|
+
color: color-mix(in srgb, var(--lb-text) 60%, transparent);
|
|
1705
|
+
margin-top: 2px;
|
|
1706
|
+
}
|
|
1707
|
+
|
|
1708
|
+
.lb-bundle-product-unit-price[hidden] {
|
|
1709
|
+
display: none;
|
|
1710
|
+
}
|
|
1711
|
+
|
|
1659
1712
|
.lb-bundle-variant-badge {
|
|
1660
1713
|
display: inline-block;
|
|
1661
1714
|
border: var(--lb-variant-border-width) solid var(--lb-variant-border-color);
|
|
@@ -1663,14 +1716,14 @@ var BUNDLE_BASE_CSS = `/* Lime Bundles \u2014 shared base styles for all bundle
|
|
|
1663
1716
|
padding: 8px 12px;
|
|
1664
1717
|
font-size: 12px;
|
|
1665
1718
|
line-height: 16px;
|
|
1666
|
-
color: var(--lb-text
|
|
1719
|
+
color: color-mix(in srgb, var(--lb-text) 60%, transparent);
|
|
1667
1720
|
margin-top: 8px;
|
|
1668
1721
|
}
|
|
1669
1722
|
|
|
1670
1723
|
.lb-bundle-quantity {
|
|
1671
1724
|
font-size: 12px;
|
|
1672
1725
|
line-height: 16px;
|
|
1673
|
-
color: var(--lb-text
|
|
1726
|
+
color: color-mix(in srgb, var(--lb-text) 60%, transparent);
|
|
1674
1727
|
margin-left: 8px;
|
|
1675
1728
|
white-space: nowrap;
|
|
1676
1729
|
}
|
|
@@ -1725,7 +1778,7 @@ var BUNDLE_BASE_CSS = `/* Lime Bundles \u2014 shared base styles for all bundle
|
|
|
1725
1778
|
font-size: 16px;
|
|
1726
1779
|
font-weight: 600;
|
|
1727
1780
|
line-height: 20px;
|
|
1728
|
-
padding: 12px
|
|
1781
|
+
padding: 8px 12px;
|
|
1729
1782
|
border-radius: var(--lb-savings-bar-radius);
|
|
1730
1783
|
margin-bottom: 12px;
|
|
1731
1784
|
}
|
|
@@ -1870,7 +1923,7 @@ var BUNDLE_BASE_CSS = `/* Lime Bundles \u2014 shared base styles for all bundle
|
|
|
1870
1923
|
.lb-bundle-placeholder-icon {
|
|
1871
1924
|
width: 28px;
|
|
1872
1925
|
height: 28px;
|
|
1873
|
-
stroke:
|
|
1926
|
+
stroke: color-mix(in srgb, var(--lb-text) 35%, transparent);
|
|
1874
1927
|
stroke-width: 1.5;
|
|
1875
1928
|
fill: none;
|
|
1876
1929
|
}
|
|
@@ -2287,7 +2340,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
2287
2340
|
border: var(--lb-picker-product-border-width) solid var(--lb-picker-product-border-color);
|
|
2288
2341
|
box-sizing: border-box;
|
|
2289
2342
|
overflow: visible;
|
|
2290
|
-
background:
|
|
2343
|
+
background: var(--lb-thumbnail-bg);
|
|
2291
2344
|
}
|
|
2292
2345
|
|
|
2293
2346
|
/* Qty badge inside the picker modal inherits picker-product border (width + color) plus
|
|
@@ -2328,6 +2381,17 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
2328
2381
|
margin: 4px 0 0;
|
|
2329
2382
|
}
|
|
2330
2383
|
|
|
2384
|
+
.lb-mix-match__modal-product-unit-price {
|
|
2385
|
+
font-size: 11px;
|
|
2386
|
+
line-height: 16px;
|
|
2387
|
+
color: color-mix(in srgb, var(--lb-text) 60%, transparent);
|
|
2388
|
+
margin: 2px 0 0;
|
|
2389
|
+
}
|
|
2390
|
+
|
|
2391
|
+
.lb-mix-match__modal-product-unit-price[hidden] {
|
|
2392
|
+
display: none;
|
|
2393
|
+
}
|
|
2394
|
+
|
|
2331
2395
|
.lb-mix-match__variant-select {
|
|
2332
2396
|
font-size: 12px;
|
|
2333
2397
|
margin: 4px 0 0;
|