@lime-bundles/widget 3.2.0 → 3.2.2
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 +152 -73
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +152 -73
- package/dist/index.js.map +1 -1
- package/dist/lime-bundle.global.js +115 -64
- package/dist/lime-bundle.global.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -150,6 +150,7 @@ function bindDropdown(select) {
|
|
|
150
150
|
let optionEls = [];
|
|
151
151
|
let instance;
|
|
152
152
|
function syncFromSelect() {
|
|
153
|
+
trigger.disabled = select.disabled;
|
|
153
154
|
const opts = readOptions(select);
|
|
154
155
|
const idx = select.selectedIndex;
|
|
155
156
|
triggerLabel.textContent = idx >= 0 && opts[idx] ? opts[idx].label : "";
|
|
@@ -196,7 +197,7 @@ function bindDropdown(select) {
|
|
|
196
197
|
if (rect.width === 0) return false;
|
|
197
198
|
const visibleCount = Math.min(optionEls.length || 1, MAX_VISIBLE_ITEMS);
|
|
198
199
|
const desiredHeight = visibleCount * ITEM_HEIGHT_PX + LIST_PAD_Y;
|
|
199
|
-
const scrollable =
|
|
200
|
+
const scrollable = findScrollableAncestor(trigger);
|
|
200
201
|
const clip = scrollable ? (() => {
|
|
201
202
|
const r = scrollable.getBoundingClientRect();
|
|
202
203
|
return { top: r.top, bottom: r.bottom };
|
|
@@ -1044,30 +1045,26 @@ function renderMixMatchBundle(container, bundle, onAddToCart, onCleanup) {
|
|
|
1044
1045
|
root.appendChild(pricingSection.el);
|
|
1045
1046
|
const savingsBar = wc.savingsBar.visible ? renderSavingsBar2() : null;
|
|
1046
1047
|
if (savingsBar) root.appendChild(savingsBar.el);
|
|
1047
|
-
const
|
|
1048
|
-
|
|
1048
|
+
const cta = buildCtaButton(`Select ${requiredQty} items to unlock`);
|
|
1049
|
+
cta.disabled = true;
|
|
1050
|
+
cta.addEventListener("click", () => {
|
|
1051
|
+
if (cta.disabled) return;
|
|
1052
|
+
onAddToCart(buildCartLines(selections, bundle));
|
|
1049
1053
|
});
|
|
1050
|
-
const placeholderText = el(
|
|
1051
|
-
"span",
|
|
1052
|
-
"lb-mix-match__price-placeholder-text"
|
|
1053
|
-
);
|
|
1054
|
-
placeholderText.textContent = `Select ${requiredQty} items to see price`;
|
|
1055
|
-
placeholder.appendChild(placeholderText);
|
|
1056
|
-
root.appendChild(placeholder);
|
|
1057
1054
|
const modal = renderModal(bundle, eligible, currency, {
|
|
1058
1055
|
showSearch: wc.showSearch,
|
|
1059
1056
|
showQtySelector,
|
|
1060
1057
|
selections,
|
|
1061
1058
|
onAdd: (product, variant, quantity) => addSelection(product, variant, quantity),
|
|
1062
|
-
isComplete: () => selections.length >= requiredQty
|
|
1059
|
+
isComplete: () => selections.length >= requiredQty,
|
|
1060
|
+
getFocusAfterAdd: () => {
|
|
1061
|
+
const empty = slotsContainer.querySelector(
|
|
1062
|
+
".lb-mix-match__slot--empty"
|
|
1063
|
+
);
|
|
1064
|
+
return empty ?? cta;
|
|
1065
|
+
}
|
|
1063
1066
|
});
|
|
1064
1067
|
root.appendChild(modal.el);
|
|
1065
|
-
const cta = buildCtaButton(`Select ${requiredQty} items to unlock`);
|
|
1066
|
-
cta.disabled = true;
|
|
1067
|
-
cta.addEventListener("click", () => {
|
|
1068
|
-
if (cta.disabled) return;
|
|
1069
|
-
onAddToCart(buildCartLines(selections, bundle));
|
|
1070
|
-
});
|
|
1071
1068
|
root.appendChild(cta);
|
|
1072
1069
|
root.appendChild(
|
|
1073
1070
|
el("p", "lb-bundle-error", { "data-error": "", "aria-live": "polite" })
|
|
@@ -1118,7 +1115,6 @@ function renderMixMatchBundle(container, bundle, onAddToCart, onCleanup) {
|
|
|
1118
1115
|
progress.update(selections.length);
|
|
1119
1116
|
pricingSection.update(selections, bundle, currency);
|
|
1120
1117
|
if (savingsBar) savingsBar.update(selections, bundle, currency);
|
|
1121
|
-
placeholder.style.display = selections.length === 0 ? "" : "none";
|
|
1122
1118
|
modal.refreshCounts();
|
|
1123
1119
|
updateCta();
|
|
1124
1120
|
}
|
|
@@ -1200,12 +1196,14 @@ function renderProgress(requiredQty) {
|
|
|
1200
1196
|
const wrap = el("div", "lb-mix-match__progress");
|
|
1201
1197
|
const labels = el("div", "lb-mix-match__progress-labels");
|
|
1202
1198
|
const count = el("span", "lb-mix-match__progress-count", {
|
|
1203
|
-
"data-progress-count": ""
|
|
1199
|
+
"data-progress-count": "",
|
|
1200
|
+
"aria-live": "polite"
|
|
1204
1201
|
});
|
|
1205
1202
|
count.textContent = `0 of ${requiredQty} selected`;
|
|
1206
1203
|
labels.appendChild(count);
|
|
1207
1204
|
const remaining = el("span", "lb-mix-match__progress-remaining", {
|
|
1208
|
-
"data-progress-remaining": ""
|
|
1205
|
+
"data-progress-remaining": "",
|
|
1206
|
+
"aria-live": "polite"
|
|
1209
1207
|
});
|
|
1210
1208
|
remaining.textContent = `${requiredQty} more to go`;
|
|
1211
1209
|
labels.appendChild(remaining);
|
|
@@ -1558,14 +1556,12 @@ function renderModal(bundle, eligible, currency, handlers) {
|
|
|
1558
1556
|
return { min: rule.min, max, cap };
|
|
1559
1557
|
};
|
|
1560
1558
|
let stepper = null;
|
|
1559
|
+
let qtyGroup = null;
|
|
1561
1560
|
if (!ep.isOos && handlers.showQtySelector) {
|
|
1562
|
-
|
|
1561
|
+
qtyGroup = el(
|
|
1563
1562
|
"div",
|
|
1564
1563
|
"lb-bundle-variant-option-group lb-mix-match__qty-stepper-group"
|
|
1565
1564
|
);
|
|
1566
|
-
const qtyLabel = el("span", "lb-bundle-variant-option-label");
|
|
1567
|
-
qtyLabel.textContent = "Quantity";
|
|
1568
|
-
qtyGroup.appendChild(qtyLabel);
|
|
1569
1565
|
stepper = renderQtyStepper({
|
|
1570
1566
|
initial: rule.min,
|
|
1571
1567
|
getBounds: () => {
|
|
@@ -1574,7 +1570,6 @@ function renderModal(bundle, eligible, currency, handlers) {
|
|
|
1574
1570
|
}
|
|
1575
1571
|
});
|
|
1576
1572
|
qtyGroup.appendChild(stepper.el);
|
|
1577
|
-
info.appendChild(qtyGroup);
|
|
1578
1573
|
}
|
|
1579
1574
|
const row = {
|
|
1580
1575
|
el: productEl,
|
|
@@ -1583,12 +1578,12 @@ function renderModal(bundle, eligible, currency, handlers) {
|
|
|
1583
1578
|
refreshFromSelections: () => {
|
|
1584
1579
|
}
|
|
1585
1580
|
};
|
|
1581
|
+
const optionSelects = [];
|
|
1586
1582
|
if (availableVariants.length > 1) {
|
|
1587
1583
|
const optionNames = availableVariants[0].selectedOptions.map(
|
|
1588
1584
|
(o) => o.name
|
|
1589
1585
|
);
|
|
1590
1586
|
const productIdTail = ep.product.id.replace(/^.*\//, "");
|
|
1591
|
-
const optionSelects = [];
|
|
1592
1587
|
const resolveVariant = (values) => availableVariants.find(
|
|
1593
1588
|
(v) => v.selectedOptions.length === values.length && v.selectedOptions.every((o, i) => o.value === values[i])
|
|
1594
1589
|
) ?? null;
|
|
@@ -1697,7 +1692,13 @@ function renderModal(bundle, eligible, currency, handlers) {
|
|
|
1697
1692
|
productEl.appendChild(info);
|
|
1698
1693
|
let addBtn = null;
|
|
1699
1694
|
const refreshAddState = () => {
|
|
1700
|
-
if (!addBtn)
|
|
1695
|
+
if (!addBtn) {
|
|
1696
|
+
optionSelects.forEach((sel) => {
|
|
1697
|
+
sel.disabled = true;
|
|
1698
|
+
});
|
|
1699
|
+
if (stepper) stepper.setExternallyDisabled(true);
|
|
1700
|
+
return;
|
|
1701
|
+
}
|
|
1701
1702
|
const { cap } = computeStepperBounds();
|
|
1702
1703
|
const already = alreadyInBundleFor(
|
|
1703
1704
|
handlers.selections,
|
|
@@ -1710,24 +1711,46 @@ function renderModal(bundle, eligible, currency, handlers) {
|
|
|
1710
1711
|
} else {
|
|
1711
1712
|
countBadge.hidden = true;
|
|
1712
1713
|
}
|
|
1713
|
-
|
|
1714
|
+
const productInBundle = handlers.selections.some(
|
|
1715
|
+
(s) => s.productId === ep.product.id
|
|
1716
|
+
);
|
|
1717
|
+
if (productInBundle) {
|
|
1718
|
+
addBtn.disabled = true;
|
|
1719
|
+
addBtn.textContent = "Added";
|
|
1720
|
+
addBtn.setAttribute("aria-label", `Added ${ep.product.title}`);
|
|
1721
|
+
productEl.classList.add("lb-mix-match__modal-product--in-bundle");
|
|
1722
|
+
} else {
|
|
1723
|
+
addBtn.textContent = "Add";
|
|
1724
|
+
addBtn.setAttribute("aria-label", `Add ${ep.product.title}`);
|
|
1725
|
+
productEl.classList.remove("lb-mix-match__modal-product--in-bundle");
|
|
1726
|
+
addBtn.disabled = handlers.isComplete() || cap < rule.min;
|
|
1727
|
+
}
|
|
1728
|
+
const rowDisabled = addBtn.disabled;
|
|
1729
|
+
optionSelects.forEach((sel) => {
|
|
1730
|
+
sel.disabled = rowDisabled;
|
|
1731
|
+
});
|
|
1732
|
+
if (stepper) stepper.setExternallyDisabled(rowDisabled);
|
|
1714
1733
|
};
|
|
1715
1734
|
if (!ep.isOos) {
|
|
1716
1735
|
const actions = el("div", "lb-mix-match__modal-product-actions");
|
|
1736
|
+
if (qtyGroup) actions.appendChild(qtyGroup);
|
|
1717
1737
|
addBtn = document.createElement("button");
|
|
1718
1738
|
addBtn.type = "button";
|
|
1719
1739
|
addBtn.className = "lb-mix-match__modal-add";
|
|
1720
1740
|
addBtn.textContent = "Add";
|
|
1741
|
+
addBtn.setAttribute("aria-label", `Add ${ep.product.title}`);
|
|
1721
1742
|
addBtn.addEventListener("click", () => {
|
|
1722
1743
|
if (!addBtn || addBtn.disabled) return;
|
|
1723
1744
|
if (handlers.isComplete()) return;
|
|
1724
1745
|
const qty = stepper ? stepper.value() : rule.min;
|
|
1725
1746
|
handlers.onAdd(ep.product, currentVariant, qty);
|
|
1726
1747
|
if (stepper) stepper.reset(rule.min);
|
|
1748
|
+
const nextFocus = handlers.getFocusAfterAdd();
|
|
1749
|
+
if (nextFocus) lastFocused = nextFocus;
|
|
1727
1750
|
close();
|
|
1728
1751
|
});
|
|
1729
1752
|
actions.appendChild(addBtn);
|
|
1730
|
-
|
|
1753
|
+
info.appendChild(actions);
|
|
1731
1754
|
}
|
|
1732
1755
|
row.refreshFromSelections = () => {
|
|
1733
1756
|
if (stepper) stepper.refresh();
|
|
@@ -1819,6 +1842,7 @@ function renderQtyStepper(opts) {
|
|
|
1819
1842
|
plus.innerHTML = STEPPER_PLUS_SVG;
|
|
1820
1843
|
wrap.appendChild(plus);
|
|
1821
1844
|
let current = clamp2(opts.initial, opts.getBounds());
|
|
1845
|
+
let externallyDisabled = false;
|
|
1822
1846
|
function clamp2(n, b) {
|
|
1823
1847
|
return Math.max(b.min, Math.min(b.max, n));
|
|
1824
1848
|
}
|
|
@@ -1826,8 +1850,8 @@ function renderQtyStepper(opts) {
|
|
|
1826
1850
|
const b = opts.getBounds();
|
|
1827
1851
|
current = clamp2(current, b);
|
|
1828
1852
|
valueEl.textContent = String(current);
|
|
1829
|
-
minus.disabled = current <= b.min;
|
|
1830
|
-
plus.disabled = current >= b.max;
|
|
1853
|
+
minus.disabled = externallyDisabled || current <= b.min;
|
|
1854
|
+
plus.disabled = externallyDisabled || current >= b.max;
|
|
1831
1855
|
}
|
|
1832
1856
|
minus.addEventListener("click", () => {
|
|
1833
1857
|
const b = opts.getBounds();
|
|
@@ -1847,7 +1871,11 @@ function renderQtyStepper(opts) {
|
|
|
1847
1871
|
current = clamp2(qty, opts.getBounds());
|
|
1848
1872
|
paint();
|
|
1849
1873
|
},
|
|
1850
|
-
refresh: paint
|
|
1874
|
+
refresh: paint,
|
|
1875
|
+
setExternallyDisabled(disabled) {
|
|
1876
|
+
externallyDisabled = disabled;
|
|
1877
|
+
paint();
|
|
1878
|
+
}
|
|
1851
1879
|
};
|
|
1852
1880
|
}
|
|
1853
1881
|
function buildEligibleProducts(bundle, oosBehavior) {
|
|
@@ -2494,6 +2522,13 @@ var BUNDLE_BASE_CSS = `/* Lime Bundles \u2014 shared base styles for all bundle
|
|
|
2494
2522
|
text-decoration: underline;
|
|
2495
2523
|
}
|
|
2496
2524
|
|
|
2525
|
+
a.lb-bundle-product-name:focus-visible {
|
|
2526
|
+
outline: 2px solid var(--lb-primary-color);
|
|
2527
|
+
outline-offset: 0;
|
|
2528
|
+
box-shadow: none;
|
|
2529
|
+
border-radius: 2px;
|
|
2530
|
+
}
|
|
2531
|
+
|
|
2497
2532
|
.lb-bundle-product-price {
|
|
2498
2533
|
/* --lb-product-price-display fallback is the "on" branch; Liquid sets 'none' when merchant disables. */
|
|
2499
2534
|
display: var(--lb-product-price-display, block);
|
|
@@ -2567,7 +2602,7 @@ var BUNDLE_BASE_CSS = `/* Lime Bundles \u2014 shared base styles for all bundle
|
|
|
2567
2602
|
.lb-bundle-variant-option-groups {
|
|
2568
2603
|
display: flex;
|
|
2569
2604
|
flex-direction: column;
|
|
2570
|
-
gap:
|
|
2605
|
+
gap: 8px;
|
|
2571
2606
|
margin-top: 8px;
|
|
2572
2607
|
}
|
|
2573
2608
|
|
|
@@ -2589,7 +2624,23 @@ var BUNDLE_BASE_CSS = `/* Lime Bundles \u2014 shared base styles for all bundle
|
|
|
2589
2624
|
}
|
|
2590
2625
|
|
|
2591
2626
|
.lb-mix-match__modal-product-info .lb-bundle-variant-option-groups {
|
|
2592
|
-
margin-top:
|
|
2627
|
+
margin-top: 8px;
|
|
2628
|
+
}
|
|
2629
|
+
|
|
2630
|
+
/* Desktop: lay variant option groups in a wrapping row inside the modal
|
|
2631
|
+
(Size + Color side-by-side). Mobile keeps the column stack from the
|
|
2632
|
+
base rule above. The 768px breakpoint mirrors bundle-mix-match.css. */
|
|
2633
|
+
@media (min-width: 768px) {
|
|
2634
|
+
.lb-mix-match__modal-product-info .lb-bundle-variant-option-groups {
|
|
2635
|
+
flex-direction: row;
|
|
2636
|
+
flex-wrap: wrap;
|
|
2637
|
+
}
|
|
2638
|
+
/* Direct children only \u2014 the qty-stepper-group is also a
|
|
2639
|
+
.lb-bundle-variant-option-group but lives in the actions wrapper
|
|
2640
|
+
and must keep its natural width. */
|
|
2641
|
+
.lb-mix-match__modal-product-info .lb-bundle-variant-option-groups > .lb-bundle-variant-option-group {
|
|
2642
|
+
flex: 1;
|
|
2643
|
+
}
|
|
2593
2644
|
}
|
|
2594
2645
|
|
|
2595
2646
|
/* Focus-ring suppression for mouse users. A small JS helper \u2014 see
|
|
@@ -2926,6 +2977,7 @@ var BUNDLE_FIXED_CSS = `/* Lime Bundles \u2014 Fixed bundle styles */
|
|
|
2926
2977
|
.lb-bundle-variant-select:focus-visible {
|
|
2927
2978
|
outline: 2px solid var(--lb-primary-color);
|
|
2928
2979
|
outline-offset: 2px;
|
|
2980
|
+
box-shadow: none;
|
|
2929
2981
|
}
|
|
2930
2982
|
`;
|
|
2931
2983
|
var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
@@ -3003,7 +3055,8 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3003
3055
|
|
|
3004
3056
|
.lb-mix-match__slot--empty:focus-visible {
|
|
3005
3057
|
outline: 2px solid var(--lb-primary-color);
|
|
3006
|
-
outline-offset: 2px;
|
|
3058
|
+
outline-offset: -2px;
|
|
3059
|
+
box-shadow: none;
|
|
3007
3060
|
border-radius: 8px;
|
|
3008
3061
|
}
|
|
3009
3062
|
|
|
@@ -3070,6 +3123,13 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3070
3123
|
text-decoration: underline;
|
|
3071
3124
|
}
|
|
3072
3125
|
|
|
3126
|
+
.lb-mix-match__slot--filled a.lb-mix-match__filled-title:focus-visible {
|
|
3127
|
+
outline: 2px solid var(--lb-primary-color);
|
|
3128
|
+
outline-offset: 2px;
|
|
3129
|
+
box-shadow: none;
|
|
3130
|
+
border-radius: 2px;
|
|
3131
|
+
}
|
|
3132
|
+
|
|
3073
3133
|
/* .lb-mix-match__filled-variant \u2014 styled jointly with
|
|
3074
3134
|
.lb-bundle-variant-badge above to keep the variant text consistent
|
|
3075
3135
|
across mix-match and fixed bundle widgets. */
|
|
@@ -3115,18 +3175,8 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3115
3175
|
|
|
3116
3176
|
.lb-mix-match__slot-remove:focus-visible {
|
|
3117
3177
|
outline: 2px solid var(--lb-primary-color);
|
|
3118
|
-
outline-offset: 2px;
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
/* Price placeholder */
|
|
3122
|
-
.lb-mix-match__price-placeholder {
|
|
3123
|
-
padding: 4px 0 16px;
|
|
3124
|
-
text-align: center;
|
|
3125
|
-
}
|
|
3126
|
-
|
|
3127
|
-
.lb-mix-match__price-placeholder-text {
|
|
3128
|
-
font-size: 16px;
|
|
3129
|
-
color: var(--lb-text);
|
|
3178
|
+
outline-offset: -2px;
|
|
3179
|
+
box-shadow: none;
|
|
3130
3180
|
}
|
|
3131
3181
|
|
|
3132
3182
|
/* === Modal Overlay === */
|
|
@@ -3157,7 +3207,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3157
3207
|
border: var(--lb-picker-border-width) solid var(--lb-picker-border-color);
|
|
3158
3208
|
box-sizing: border-box;
|
|
3159
3209
|
width: 100%;
|
|
3160
|
-
max-width:
|
|
3210
|
+
max-width: 520px;
|
|
3161
3211
|
max-height: 70vh;
|
|
3162
3212
|
display: flex;
|
|
3163
3213
|
flex-direction: column;
|
|
@@ -3206,7 +3256,8 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3206
3256
|
|
|
3207
3257
|
.lb-mix-match__modal-close:focus-visible {
|
|
3208
3258
|
outline: 2px solid var(--lb-primary-color);
|
|
3209
|
-
outline-offset:
|
|
3259
|
+
outline-offset: 0;
|
|
3260
|
+
box-shadow: none;
|
|
3210
3261
|
}
|
|
3211
3262
|
|
|
3212
3263
|
/* === Modal Search === */
|
|
@@ -3234,9 +3285,10 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3234
3285
|
color: color-mix(in srgb, var(--lb-picker-text) 50%, transparent);
|
|
3235
3286
|
}
|
|
3236
3287
|
|
|
3237
|
-
.lb-mix-match__modal-search-input:focus {
|
|
3238
|
-
outline:
|
|
3239
|
-
|
|
3288
|
+
.lb-mix-match__modal-search-input:focus-visible {
|
|
3289
|
+
outline: 2px solid var(--lb-primary-color);
|
|
3290
|
+
outline-offset: 2px;
|
|
3291
|
+
box-shadow: none;
|
|
3240
3292
|
}
|
|
3241
3293
|
|
|
3242
3294
|
.lb-mix-match__modal-search-clear {
|
|
@@ -3267,10 +3319,12 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3267
3319
|
}
|
|
3268
3320
|
|
|
3269
3321
|
.lb-mix-match__modal-product {
|
|
3270
|
-
display:
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3322
|
+
display: grid;
|
|
3323
|
+
grid-template-columns: auto 1fr;
|
|
3324
|
+
align-items: start;
|
|
3325
|
+
column-gap: 20px;
|
|
3326
|
+
padding-top: 20px;
|
|
3327
|
+
padding-bottom: 16px;
|
|
3274
3328
|
border-bottom: 1px solid color-mix(in srgb, var(--lb-picker-text) 7%, transparent);
|
|
3275
3329
|
}
|
|
3276
3330
|
|
|
@@ -3367,6 +3421,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3367
3421
|
.lb-mix-match__variant-select:focus-visible {
|
|
3368
3422
|
outline: 2px solid var(--lb-primary-color);
|
|
3369
3423
|
outline-offset: 2px;
|
|
3424
|
+
box-shadow: none;
|
|
3370
3425
|
}
|
|
3371
3426
|
|
|
3372
3427
|
/* Per-pick quantity stepper inside the picker modal product row.
|
|
@@ -3383,10 +3438,11 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3383
3438
|
group from the unit-price / low-stock-badge above; the stepper itself
|
|
3384
3439
|
has no top margin so the group can be repositioned without coupling. */
|
|
3385
3440
|
.lb-mix-match__qty-stepper-group {
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3441
|
+
/* Override the base .lb-bundle-variant-option-group column flex so the
|
|
3442
|
+
stepper child stretches on the cross-axis (vertical) \u2014 this is what
|
|
3443
|
+
lets the group track the Add button's height in the action row
|
|
3444
|
+
without pinning a fixed pixel value. */
|
|
3445
|
+
flex-direction: row;
|
|
3390
3446
|
width: fit-content;
|
|
3391
3447
|
}
|
|
3392
3448
|
|
|
@@ -3394,7 +3450,6 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3394
3450
|
display: inline-flex;
|
|
3395
3451
|
align-items: stretch;
|
|
3396
3452
|
flex-shrink: 0;
|
|
3397
|
-
height: 32px;
|
|
3398
3453
|
border: var(--lb-picker-qty-stepper-border-width) solid var(--lb-picker-qty-stepper-border-color);
|
|
3399
3454
|
border-radius: var(--lb-picker-qty-stepper-radius);
|
|
3400
3455
|
background-color: var(--lb-picker-bg);
|
|
@@ -3421,13 +3476,10 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3421
3476
|
justify-content: center;
|
|
3422
3477
|
}
|
|
3423
3478
|
|
|
3424
|
-
.lb-mix-match__qty-stepper-button:hover:not(:disabled) {
|
|
3425
|
-
background: color-mix(in srgb, var(--lb-picker-text) 6%, transparent);
|
|
3426
|
-
}
|
|
3427
|
-
|
|
3428
3479
|
.lb-mix-match__qty-stepper-button:focus-visible {
|
|
3429
3480
|
outline: 2px solid var(--lb-primary-color);
|
|
3430
3481
|
outline-offset: -2px;
|
|
3482
|
+
box-shadow: none;
|
|
3431
3483
|
}
|
|
3432
3484
|
|
|
3433
3485
|
.lb-mix-match__qty-stepper-button:disabled {
|
|
@@ -3448,8 +3500,24 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3448
3500
|
box-sizing: border-box;
|
|
3449
3501
|
}
|
|
3450
3502
|
|
|
3503
|
+
/* Action row \u2014 qty stepper (left) + Add button (right). Sits at the
|
|
3504
|
+
bottom of the info column with a 12px top margin so it visually
|
|
3505
|
+
separates from the variant pickers / price block above. When the
|
|
3506
|
+
stepper is hidden, Add fills the row via flex: 1 below.
|
|
3507
|
+
align-items: stretch so the stepper-group tracks the Add button's
|
|
3508
|
+
height (driven by font size + button padding) without a pinned px. */
|
|
3509
|
+
.lb-mix-match__modal-product-actions {
|
|
3510
|
+
display: flex;
|
|
3511
|
+
flex-wrap: wrap;
|
|
3512
|
+
align-items: stretch;
|
|
3513
|
+
row-gap: 12px;
|
|
3514
|
+
column-gap: 8px;
|
|
3515
|
+
margin-top: 12px;
|
|
3516
|
+
}
|
|
3517
|
+
|
|
3451
3518
|
.lb-mix-match__modal-add {
|
|
3452
|
-
|
|
3519
|
+
flex: 1;
|
|
3520
|
+
padding: 10px 20px;
|
|
3453
3521
|
background: var(--lb-picker-add-bg);
|
|
3454
3522
|
color: var(--lb-picker-add-label);
|
|
3455
3523
|
border: var(--lb-picker-add-border-width) solid var(--lb-picker-add-border-color);
|
|
@@ -3458,8 +3526,6 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3458
3526
|
font-size: 12px;
|
|
3459
3527
|
font-weight: 600;
|
|
3460
3528
|
cursor: pointer;
|
|
3461
|
-
white-space: nowrap;
|
|
3462
|
-
flex-shrink: 0;
|
|
3463
3529
|
}
|
|
3464
3530
|
|
|
3465
3531
|
.lb-mix-match__modal-add:hover {
|
|
@@ -3469,6 +3535,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3469
3535
|
.lb-mix-match__modal-add:focus-visible {
|
|
3470
3536
|
outline: 2px solid var(--lb-primary-color);
|
|
3471
3537
|
outline-offset: 2px;
|
|
3538
|
+
box-shadow: none;
|
|
3472
3539
|
}
|
|
3473
3540
|
|
|
3474
3541
|
.lb-mix-match__modal-add:disabled {
|
|
@@ -3482,6 +3549,14 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3482
3549
|
opacity: 0.5;
|
|
3483
3550
|
}
|
|
3484
3551
|
|
|
3552
|
+
/* Already in a slot \u2014 prevents shoppers from filling multiple slots
|
|
3553
|
+
with the same product (which wouldn't qualify the discount: it
|
|
3554
|
+
counts distinct products, not slot occupancy). The thumb keeps
|
|
3555
|
+
its qty badge so the shopper sees what's already in the bundle. */
|
|
3556
|
+
.lb-mix-match__modal-product--in-bundle {
|
|
3557
|
+
opacity: 0.5;
|
|
3558
|
+
}
|
|
3559
|
+
|
|
3485
3560
|
.lb-mix-match__modal-product--sold-out .lb-mix-match__modal-sold-out-label {
|
|
3486
3561
|
font-size: 12px;
|
|
3487
3562
|
color: inherit;
|
|
@@ -3578,12 +3653,14 @@ var BUNDLE_VOLUME_CSS = `/* Lime Bundles \u2014 Volume / Quantity Breaks styles
|
|
|
3578
3653
|
border-color: var(--lb-tier-selected-border-color);
|
|
3579
3654
|
}
|
|
3580
3655
|
|
|
3581
|
-
/* Suppress the UA default focus outline so a
|
|
3582
|
-
tier doesn't briefly show the 1px focus ring
|
|
3583
|
-
|
|
3584
|
-
|
|
3656
|
+
/* Suppress the UA default focus outline + Dawn's focus shadow so a
|
|
3657
|
+
freshly-clicked selected tier doesn't briefly show the 1px focus ring
|
|
3658
|
+
or shadow on top of (or in place of) the custom selected-state
|
|
3659
|
+
outline below. Keyboard focus is still indicated by the
|
|
3660
|
+
:focus-visible rule. */
|
|
3585
3661
|
.lb-volume__tier:focus {
|
|
3586
3662
|
outline: none;
|
|
3663
|
+
box-shadow: none;
|
|
3587
3664
|
}
|
|
3588
3665
|
|
|
3589
3666
|
/* Keyboard focus indicator \u2014 explicitly excludes the selected tier so
|
|
@@ -3591,7 +3668,8 @@ var BUNDLE_VOLUME_CSS = `/* Lime Bundles \u2014 Volume / Quantity Breaks styles
|
|
|
3591
3668
|
outline property when both states apply at once. */
|
|
3592
3669
|
.lb-volume__tier:focus-visible:not([aria-checked="true"]) {
|
|
3593
3670
|
outline: 2px solid var(--lb-primary-color);
|
|
3594
|
-
outline-offset: 2px;
|
|
3671
|
+
outline-offset: -2px;
|
|
3672
|
+
box-shadow: none;
|
|
3595
3673
|
}
|
|
3596
3674
|
|
|
3597
3675
|
.lb-volume__tier[aria-checked="true"] {
|
|
@@ -3739,6 +3817,7 @@ var BUNDLE_DROPDOWN_CSS = `/**
|
|
|
3739
3817
|
.lb-dropdown-trigger:focus-visible {
|
|
3740
3818
|
outline: 2px solid var(--lb-primary-color);
|
|
3741
3819
|
outline-offset: 2px;
|
|
3820
|
+
box-shadow: none;
|
|
3742
3821
|
}
|
|
3743
3822
|
|
|
3744
3823
|
.lb-dropdown-trigger[aria-expanded="true"] {
|