@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.js
CHANGED
|
@@ -142,6 +142,7 @@ function bindDropdown(select) {
|
|
|
142
142
|
let optionEls = [];
|
|
143
143
|
let instance;
|
|
144
144
|
function syncFromSelect() {
|
|
145
|
+
trigger.disabled = select.disabled;
|
|
145
146
|
const opts = readOptions(select);
|
|
146
147
|
const idx = select.selectedIndex;
|
|
147
148
|
triggerLabel.textContent = idx >= 0 && opts[idx] ? opts[idx].label : "";
|
|
@@ -188,7 +189,7 @@ function bindDropdown(select) {
|
|
|
188
189
|
if (rect.width === 0) return false;
|
|
189
190
|
const visibleCount = Math.min(optionEls.length || 1, MAX_VISIBLE_ITEMS);
|
|
190
191
|
const desiredHeight = visibleCount * ITEM_HEIGHT_PX + LIST_PAD_Y;
|
|
191
|
-
const scrollable =
|
|
192
|
+
const scrollable = findScrollableAncestor(trigger);
|
|
192
193
|
const clip = scrollable ? (() => {
|
|
193
194
|
const r = scrollable.getBoundingClientRect();
|
|
194
195
|
return { top: r.top, bottom: r.bottom };
|
|
@@ -1051,30 +1052,26 @@ function renderMixMatchBundle(container, bundle, onAddToCart, onCleanup) {
|
|
|
1051
1052
|
root.appendChild(pricingSection.el);
|
|
1052
1053
|
const savingsBar = wc.savingsBar.visible ? renderSavingsBar2() : null;
|
|
1053
1054
|
if (savingsBar) root.appendChild(savingsBar.el);
|
|
1054
|
-
const
|
|
1055
|
-
|
|
1055
|
+
const cta = buildCtaButton(`Select ${requiredQty} items to unlock`);
|
|
1056
|
+
cta.disabled = true;
|
|
1057
|
+
cta.addEventListener("click", () => {
|
|
1058
|
+
if (cta.disabled) return;
|
|
1059
|
+
onAddToCart(buildCartLines(selections, bundle));
|
|
1056
1060
|
});
|
|
1057
|
-
const placeholderText = el(
|
|
1058
|
-
"span",
|
|
1059
|
-
"lb-mix-match__price-placeholder-text"
|
|
1060
|
-
);
|
|
1061
|
-
placeholderText.textContent = `Select ${requiredQty} items to see price`;
|
|
1062
|
-
placeholder.appendChild(placeholderText);
|
|
1063
|
-
root.appendChild(placeholder);
|
|
1064
1061
|
const modal = renderModal(bundle, eligible, currency, {
|
|
1065
1062
|
showSearch: wc.showSearch,
|
|
1066
1063
|
showQtySelector,
|
|
1067
1064
|
selections,
|
|
1068
1065
|
onAdd: (product, variant, quantity) => addSelection(product, variant, quantity),
|
|
1069
|
-
isComplete: () => selections.length >= requiredQty
|
|
1066
|
+
isComplete: () => selections.length >= requiredQty,
|
|
1067
|
+
getFocusAfterAdd: () => {
|
|
1068
|
+
const empty = slotsContainer.querySelector(
|
|
1069
|
+
".lb-mix-match__slot--empty"
|
|
1070
|
+
);
|
|
1071
|
+
return empty ?? cta;
|
|
1072
|
+
}
|
|
1070
1073
|
});
|
|
1071
1074
|
root.appendChild(modal.el);
|
|
1072
|
-
const cta = buildCtaButton(`Select ${requiredQty} items to unlock`);
|
|
1073
|
-
cta.disabled = true;
|
|
1074
|
-
cta.addEventListener("click", () => {
|
|
1075
|
-
if (cta.disabled) return;
|
|
1076
|
-
onAddToCart(buildCartLines(selections, bundle));
|
|
1077
|
-
});
|
|
1078
1075
|
root.appendChild(cta);
|
|
1079
1076
|
root.appendChild(
|
|
1080
1077
|
el("p", "lb-bundle-error", { "data-error": "", "aria-live": "polite" })
|
|
@@ -1125,7 +1122,6 @@ function renderMixMatchBundle(container, bundle, onAddToCart, onCleanup) {
|
|
|
1125
1122
|
progress.update(selections.length);
|
|
1126
1123
|
pricingSection.update(selections, bundle, currency);
|
|
1127
1124
|
if (savingsBar) savingsBar.update(selections, bundle, currency);
|
|
1128
|
-
placeholder.style.display = selections.length === 0 ? "" : "none";
|
|
1129
1125
|
modal.refreshCounts();
|
|
1130
1126
|
updateCta();
|
|
1131
1127
|
}
|
|
@@ -1207,12 +1203,14 @@ function renderProgress(requiredQty) {
|
|
|
1207
1203
|
const wrap = el("div", "lb-mix-match__progress");
|
|
1208
1204
|
const labels = el("div", "lb-mix-match__progress-labels");
|
|
1209
1205
|
const count = el("span", "lb-mix-match__progress-count", {
|
|
1210
|
-
"data-progress-count": ""
|
|
1206
|
+
"data-progress-count": "",
|
|
1207
|
+
"aria-live": "polite"
|
|
1211
1208
|
});
|
|
1212
1209
|
count.textContent = `0 of ${requiredQty} selected`;
|
|
1213
1210
|
labels.appendChild(count);
|
|
1214
1211
|
const remaining = el("span", "lb-mix-match__progress-remaining", {
|
|
1215
|
-
"data-progress-remaining": ""
|
|
1212
|
+
"data-progress-remaining": "",
|
|
1213
|
+
"aria-live": "polite"
|
|
1216
1214
|
});
|
|
1217
1215
|
remaining.textContent = `${requiredQty} more to go`;
|
|
1218
1216
|
labels.appendChild(remaining);
|
|
@@ -1565,14 +1563,12 @@ function renderModal(bundle, eligible, currency, handlers) {
|
|
|
1565
1563
|
return { min: rule.min, max, cap };
|
|
1566
1564
|
};
|
|
1567
1565
|
let stepper = null;
|
|
1566
|
+
let qtyGroup = null;
|
|
1568
1567
|
if (!ep.isOos && handlers.showQtySelector) {
|
|
1569
|
-
|
|
1568
|
+
qtyGroup = el(
|
|
1570
1569
|
"div",
|
|
1571
1570
|
"lb-bundle-variant-option-group lb-mix-match__qty-stepper-group"
|
|
1572
1571
|
);
|
|
1573
|
-
const qtyLabel = el("span", "lb-bundle-variant-option-label");
|
|
1574
|
-
qtyLabel.textContent = "Quantity";
|
|
1575
|
-
qtyGroup.appendChild(qtyLabel);
|
|
1576
1572
|
stepper = renderQtyStepper({
|
|
1577
1573
|
initial: rule.min,
|
|
1578
1574
|
getBounds: () => {
|
|
@@ -1581,7 +1577,6 @@ function renderModal(bundle, eligible, currency, handlers) {
|
|
|
1581
1577
|
}
|
|
1582
1578
|
});
|
|
1583
1579
|
qtyGroup.appendChild(stepper.el);
|
|
1584
|
-
info.appendChild(qtyGroup);
|
|
1585
1580
|
}
|
|
1586
1581
|
const row = {
|
|
1587
1582
|
el: productEl,
|
|
@@ -1590,12 +1585,12 @@ function renderModal(bundle, eligible, currency, handlers) {
|
|
|
1590
1585
|
refreshFromSelections: () => {
|
|
1591
1586
|
}
|
|
1592
1587
|
};
|
|
1588
|
+
const optionSelects = [];
|
|
1593
1589
|
if (availableVariants.length > 1) {
|
|
1594
1590
|
const optionNames = availableVariants[0].selectedOptions.map(
|
|
1595
1591
|
(o) => o.name
|
|
1596
1592
|
);
|
|
1597
1593
|
const productIdTail = ep.product.id.replace(/^.*\//, "");
|
|
1598
|
-
const optionSelects = [];
|
|
1599
1594
|
const resolveVariant = (values) => availableVariants.find(
|
|
1600
1595
|
(v) => v.selectedOptions.length === values.length && v.selectedOptions.every((o, i) => o.value === values[i])
|
|
1601
1596
|
) ?? null;
|
|
@@ -1704,7 +1699,13 @@ function renderModal(bundle, eligible, currency, handlers) {
|
|
|
1704
1699
|
productEl.appendChild(info);
|
|
1705
1700
|
let addBtn = null;
|
|
1706
1701
|
const refreshAddState = () => {
|
|
1707
|
-
if (!addBtn)
|
|
1702
|
+
if (!addBtn) {
|
|
1703
|
+
optionSelects.forEach((sel) => {
|
|
1704
|
+
sel.disabled = true;
|
|
1705
|
+
});
|
|
1706
|
+
if (stepper) stepper.setExternallyDisabled(true);
|
|
1707
|
+
return;
|
|
1708
|
+
}
|
|
1708
1709
|
const { cap } = computeStepperBounds();
|
|
1709
1710
|
const already = alreadyInBundleFor(
|
|
1710
1711
|
handlers.selections,
|
|
@@ -1717,24 +1718,46 @@ function renderModal(bundle, eligible, currency, handlers) {
|
|
|
1717
1718
|
} else {
|
|
1718
1719
|
countBadge.hidden = true;
|
|
1719
1720
|
}
|
|
1720
|
-
|
|
1721
|
+
const productInBundle = handlers.selections.some(
|
|
1722
|
+
(s) => s.productId === ep.product.id
|
|
1723
|
+
);
|
|
1724
|
+
if (productInBundle) {
|
|
1725
|
+
addBtn.disabled = true;
|
|
1726
|
+
addBtn.textContent = "Added";
|
|
1727
|
+
addBtn.setAttribute("aria-label", `Added ${ep.product.title}`);
|
|
1728
|
+
productEl.classList.add("lb-mix-match__modal-product--in-bundle");
|
|
1729
|
+
} else {
|
|
1730
|
+
addBtn.textContent = "Add";
|
|
1731
|
+
addBtn.setAttribute("aria-label", `Add ${ep.product.title}`);
|
|
1732
|
+
productEl.classList.remove("lb-mix-match__modal-product--in-bundle");
|
|
1733
|
+
addBtn.disabled = handlers.isComplete() || cap < rule.min;
|
|
1734
|
+
}
|
|
1735
|
+
const rowDisabled = addBtn.disabled;
|
|
1736
|
+
optionSelects.forEach((sel) => {
|
|
1737
|
+
sel.disabled = rowDisabled;
|
|
1738
|
+
});
|
|
1739
|
+
if (stepper) stepper.setExternallyDisabled(rowDisabled);
|
|
1721
1740
|
};
|
|
1722
1741
|
if (!ep.isOos) {
|
|
1723
1742
|
const actions = el("div", "lb-mix-match__modal-product-actions");
|
|
1743
|
+
if (qtyGroup) actions.appendChild(qtyGroup);
|
|
1724
1744
|
addBtn = document.createElement("button");
|
|
1725
1745
|
addBtn.type = "button";
|
|
1726
1746
|
addBtn.className = "lb-mix-match__modal-add";
|
|
1727
1747
|
addBtn.textContent = "Add";
|
|
1748
|
+
addBtn.setAttribute("aria-label", `Add ${ep.product.title}`);
|
|
1728
1749
|
addBtn.addEventListener("click", () => {
|
|
1729
1750
|
if (!addBtn || addBtn.disabled) return;
|
|
1730
1751
|
if (handlers.isComplete()) return;
|
|
1731
1752
|
const qty = stepper ? stepper.value() : rule.min;
|
|
1732
1753
|
handlers.onAdd(ep.product, currentVariant, qty);
|
|
1733
1754
|
if (stepper) stepper.reset(rule.min);
|
|
1755
|
+
const nextFocus = handlers.getFocusAfterAdd();
|
|
1756
|
+
if (nextFocus) lastFocused = nextFocus;
|
|
1734
1757
|
close();
|
|
1735
1758
|
});
|
|
1736
1759
|
actions.appendChild(addBtn);
|
|
1737
|
-
|
|
1760
|
+
info.appendChild(actions);
|
|
1738
1761
|
}
|
|
1739
1762
|
row.refreshFromSelections = () => {
|
|
1740
1763
|
if (stepper) stepper.refresh();
|
|
@@ -1826,6 +1849,7 @@ function renderQtyStepper(opts) {
|
|
|
1826
1849
|
plus.innerHTML = STEPPER_PLUS_SVG;
|
|
1827
1850
|
wrap.appendChild(plus);
|
|
1828
1851
|
let current = clamp2(opts.initial, opts.getBounds());
|
|
1852
|
+
let externallyDisabled = false;
|
|
1829
1853
|
function clamp2(n, b) {
|
|
1830
1854
|
return Math.max(b.min, Math.min(b.max, n));
|
|
1831
1855
|
}
|
|
@@ -1833,8 +1857,8 @@ function renderQtyStepper(opts) {
|
|
|
1833
1857
|
const b = opts.getBounds();
|
|
1834
1858
|
current = clamp2(current, b);
|
|
1835
1859
|
valueEl.textContent = String(current);
|
|
1836
|
-
minus.disabled = current <= b.min;
|
|
1837
|
-
plus.disabled = current >= b.max;
|
|
1860
|
+
minus.disabled = externallyDisabled || current <= b.min;
|
|
1861
|
+
plus.disabled = externallyDisabled || current >= b.max;
|
|
1838
1862
|
}
|
|
1839
1863
|
minus.addEventListener("click", () => {
|
|
1840
1864
|
const b = opts.getBounds();
|
|
@@ -1854,7 +1878,11 @@ function renderQtyStepper(opts) {
|
|
|
1854
1878
|
current = clamp2(qty, opts.getBounds());
|
|
1855
1879
|
paint();
|
|
1856
1880
|
},
|
|
1857
|
-
refresh: paint
|
|
1881
|
+
refresh: paint,
|
|
1882
|
+
setExternallyDisabled(disabled) {
|
|
1883
|
+
externallyDisabled = disabled;
|
|
1884
|
+
paint();
|
|
1885
|
+
}
|
|
1858
1886
|
};
|
|
1859
1887
|
}
|
|
1860
1888
|
function buildEligibleProducts(bundle, oosBehavior) {
|
|
@@ -2501,6 +2529,13 @@ var BUNDLE_BASE_CSS = `/* Lime Bundles \u2014 shared base styles for all bundle
|
|
|
2501
2529
|
text-decoration: underline;
|
|
2502
2530
|
}
|
|
2503
2531
|
|
|
2532
|
+
a.lb-bundle-product-name:focus-visible {
|
|
2533
|
+
outline: 2px solid var(--lb-primary-color);
|
|
2534
|
+
outline-offset: 0;
|
|
2535
|
+
box-shadow: none;
|
|
2536
|
+
border-radius: 2px;
|
|
2537
|
+
}
|
|
2538
|
+
|
|
2504
2539
|
.lb-bundle-product-price {
|
|
2505
2540
|
/* --lb-product-price-display fallback is the "on" branch; Liquid sets 'none' when merchant disables. */
|
|
2506
2541
|
display: var(--lb-product-price-display, block);
|
|
@@ -2574,7 +2609,7 @@ var BUNDLE_BASE_CSS = `/* Lime Bundles \u2014 shared base styles for all bundle
|
|
|
2574
2609
|
.lb-bundle-variant-option-groups {
|
|
2575
2610
|
display: flex;
|
|
2576
2611
|
flex-direction: column;
|
|
2577
|
-
gap:
|
|
2612
|
+
gap: 8px;
|
|
2578
2613
|
margin-top: 8px;
|
|
2579
2614
|
}
|
|
2580
2615
|
|
|
@@ -2596,7 +2631,23 @@ var BUNDLE_BASE_CSS = `/* Lime Bundles \u2014 shared base styles for all bundle
|
|
|
2596
2631
|
}
|
|
2597
2632
|
|
|
2598
2633
|
.lb-mix-match__modal-product-info .lb-bundle-variant-option-groups {
|
|
2599
|
-
margin-top:
|
|
2634
|
+
margin-top: 8px;
|
|
2635
|
+
}
|
|
2636
|
+
|
|
2637
|
+
/* Desktop: lay variant option groups in a wrapping row inside the modal
|
|
2638
|
+
(Size + Color side-by-side). Mobile keeps the column stack from the
|
|
2639
|
+
base rule above. The 768px breakpoint mirrors bundle-mix-match.css. */
|
|
2640
|
+
@media (min-width: 768px) {
|
|
2641
|
+
.lb-mix-match__modal-product-info .lb-bundle-variant-option-groups {
|
|
2642
|
+
flex-direction: row;
|
|
2643
|
+
flex-wrap: wrap;
|
|
2644
|
+
}
|
|
2645
|
+
/* Direct children only \u2014 the qty-stepper-group is also a
|
|
2646
|
+
.lb-bundle-variant-option-group but lives in the actions wrapper
|
|
2647
|
+
and must keep its natural width. */
|
|
2648
|
+
.lb-mix-match__modal-product-info .lb-bundle-variant-option-groups > .lb-bundle-variant-option-group {
|
|
2649
|
+
flex: 1;
|
|
2650
|
+
}
|
|
2600
2651
|
}
|
|
2601
2652
|
|
|
2602
2653
|
/* Focus-ring suppression for mouse users. A small JS helper \u2014 see
|
|
@@ -2933,6 +2984,7 @@ var BUNDLE_FIXED_CSS = `/* Lime Bundles \u2014 Fixed bundle styles */
|
|
|
2933
2984
|
.lb-bundle-variant-select:focus-visible {
|
|
2934
2985
|
outline: 2px solid var(--lb-primary-color);
|
|
2935
2986
|
outline-offset: 2px;
|
|
2987
|
+
box-shadow: none;
|
|
2936
2988
|
}
|
|
2937
2989
|
`;
|
|
2938
2990
|
var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
@@ -3010,7 +3062,8 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3010
3062
|
|
|
3011
3063
|
.lb-mix-match__slot--empty:focus-visible {
|
|
3012
3064
|
outline: 2px solid var(--lb-primary-color);
|
|
3013
|
-
outline-offset: 2px;
|
|
3065
|
+
outline-offset: -2px;
|
|
3066
|
+
box-shadow: none;
|
|
3014
3067
|
border-radius: 8px;
|
|
3015
3068
|
}
|
|
3016
3069
|
|
|
@@ -3077,6 +3130,13 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3077
3130
|
text-decoration: underline;
|
|
3078
3131
|
}
|
|
3079
3132
|
|
|
3133
|
+
.lb-mix-match__slot--filled a.lb-mix-match__filled-title:focus-visible {
|
|
3134
|
+
outline: 2px solid var(--lb-primary-color);
|
|
3135
|
+
outline-offset: 2px;
|
|
3136
|
+
box-shadow: none;
|
|
3137
|
+
border-radius: 2px;
|
|
3138
|
+
}
|
|
3139
|
+
|
|
3080
3140
|
/* .lb-mix-match__filled-variant \u2014 styled jointly with
|
|
3081
3141
|
.lb-bundle-variant-badge above to keep the variant text consistent
|
|
3082
3142
|
across mix-match and fixed bundle widgets. */
|
|
@@ -3122,18 +3182,8 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3122
3182
|
|
|
3123
3183
|
.lb-mix-match__slot-remove:focus-visible {
|
|
3124
3184
|
outline: 2px solid var(--lb-primary-color);
|
|
3125
|
-
outline-offset: 2px;
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
/* Price placeholder */
|
|
3129
|
-
.lb-mix-match__price-placeholder {
|
|
3130
|
-
padding: 4px 0 16px;
|
|
3131
|
-
text-align: center;
|
|
3132
|
-
}
|
|
3133
|
-
|
|
3134
|
-
.lb-mix-match__price-placeholder-text {
|
|
3135
|
-
font-size: 16px;
|
|
3136
|
-
color: var(--lb-text);
|
|
3185
|
+
outline-offset: -2px;
|
|
3186
|
+
box-shadow: none;
|
|
3137
3187
|
}
|
|
3138
3188
|
|
|
3139
3189
|
/* === Modal Overlay === */
|
|
@@ -3164,7 +3214,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3164
3214
|
border: var(--lb-picker-border-width) solid var(--lb-picker-border-color);
|
|
3165
3215
|
box-sizing: border-box;
|
|
3166
3216
|
width: 100%;
|
|
3167
|
-
max-width:
|
|
3217
|
+
max-width: 520px;
|
|
3168
3218
|
max-height: 70vh;
|
|
3169
3219
|
display: flex;
|
|
3170
3220
|
flex-direction: column;
|
|
@@ -3213,7 +3263,8 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3213
3263
|
|
|
3214
3264
|
.lb-mix-match__modal-close:focus-visible {
|
|
3215
3265
|
outline: 2px solid var(--lb-primary-color);
|
|
3216
|
-
outline-offset:
|
|
3266
|
+
outline-offset: 0;
|
|
3267
|
+
box-shadow: none;
|
|
3217
3268
|
}
|
|
3218
3269
|
|
|
3219
3270
|
/* === Modal Search === */
|
|
@@ -3241,9 +3292,10 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3241
3292
|
color: color-mix(in srgb, var(--lb-picker-text) 50%, transparent);
|
|
3242
3293
|
}
|
|
3243
3294
|
|
|
3244
|
-
.lb-mix-match__modal-search-input:focus {
|
|
3245
|
-
outline:
|
|
3246
|
-
|
|
3295
|
+
.lb-mix-match__modal-search-input:focus-visible {
|
|
3296
|
+
outline: 2px solid var(--lb-primary-color);
|
|
3297
|
+
outline-offset: 2px;
|
|
3298
|
+
box-shadow: none;
|
|
3247
3299
|
}
|
|
3248
3300
|
|
|
3249
3301
|
.lb-mix-match__modal-search-clear {
|
|
@@ -3274,10 +3326,12 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3274
3326
|
}
|
|
3275
3327
|
|
|
3276
3328
|
.lb-mix-match__modal-product {
|
|
3277
|
-
display:
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3329
|
+
display: grid;
|
|
3330
|
+
grid-template-columns: auto 1fr;
|
|
3331
|
+
align-items: start;
|
|
3332
|
+
column-gap: 20px;
|
|
3333
|
+
padding-top: 20px;
|
|
3334
|
+
padding-bottom: 16px;
|
|
3281
3335
|
border-bottom: 1px solid color-mix(in srgb, var(--lb-picker-text) 7%, transparent);
|
|
3282
3336
|
}
|
|
3283
3337
|
|
|
@@ -3374,6 +3428,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3374
3428
|
.lb-mix-match__variant-select:focus-visible {
|
|
3375
3429
|
outline: 2px solid var(--lb-primary-color);
|
|
3376
3430
|
outline-offset: 2px;
|
|
3431
|
+
box-shadow: none;
|
|
3377
3432
|
}
|
|
3378
3433
|
|
|
3379
3434
|
/* Per-pick quantity stepper inside the picker modal product row.
|
|
@@ -3390,10 +3445,11 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3390
3445
|
group from the unit-price / low-stock-badge above; the stepper itself
|
|
3391
3446
|
has no top margin so the group can be repositioned without coupling. */
|
|
3392
3447
|
.lb-mix-match__qty-stepper-group {
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3448
|
+
/* Override the base .lb-bundle-variant-option-group column flex so the
|
|
3449
|
+
stepper child stretches on the cross-axis (vertical) \u2014 this is what
|
|
3450
|
+
lets the group track the Add button's height in the action row
|
|
3451
|
+
without pinning a fixed pixel value. */
|
|
3452
|
+
flex-direction: row;
|
|
3397
3453
|
width: fit-content;
|
|
3398
3454
|
}
|
|
3399
3455
|
|
|
@@ -3401,7 +3457,6 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3401
3457
|
display: inline-flex;
|
|
3402
3458
|
align-items: stretch;
|
|
3403
3459
|
flex-shrink: 0;
|
|
3404
|
-
height: 32px;
|
|
3405
3460
|
border: var(--lb-picker-qty-stepper-border-width) solid var(--lb-picker-qty-stepper-border-color);
|
|
3406
3461
|
border-radius: var(--lb-picker-qty-stepper-radius);
|
|
3407
3462
|
background-color: var(--lb-picker-bg);
|
|
@@ -3428,13 +3483,10 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3428
3483
|
justify-content: center;
|
|
3429
3484
|
}
|
|
3430
3485
|
|
|
3431
|
-
.lb-mix-match__qty-stepper-button:hover:not(:disabled) {
|
|
3432
|
-
background: color-mix(in srgb, var(--lb-picker-text) 6%, transparent);
|
|
3433
|
-
}
|
|
3434
|
-
|
|
3435
3486
|
.lb-mix-match__qty-stepper-button:focus-visible {
|
|
3436
3487
|
outline: 2px solid var(--lb-primary-color);
|
|
3437
3488
|
outline-offset: -2px;
|
|
3489
|
+
box-shadow: none;
|
|
3438
3490
|
}
|
|
3439
3491
|
|
|
3440
3492
|
.lb-mix-match__qty-stepper-button:disabled {
|
|
@@ -3455,8 +3507,24 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3455
3507
|
box-sizing: border-box;
|
|
3456
3508
|
}
|
|
3457
3509
|
|
|
3510
|
+
/* Action row \u2014 qty stepper (left) + Add button (right). Sits at the
|
|
3511
|
+
bottom of the info column with a 12px top margin so it visually
|
|
3512
|
+
separates from the variant pickers / price block above. When the
|
|
3513
|
+
stepper is hidden, Add fills the row via flex: 1 below.
|
|
3514
|
+
align-items: stretch so the stepper-group tracks the Add button's
|
|
3515
|
+
height (driven by font size + button padding) without a pinned px. */
|
|
3516
|
+
.lb-mix-match__modal-product-actions {
|
|
3517
|
+
display: flex;
|
|
3518
|
+
flex-wrap: wrap;
|
|
3519
|
+
align-items: stretch;
|
|
3520
|
+
row-gap: 12px;
|
|
3521
|
+
column-gap: 8px;
|
|
3522
|
+
margin-top: 12px;
|
|
3523
|
+
}
|
|
3524
|
+
|
|
3458
3525
|
.lb-mix-match__modal-add {
|
|
3459
|
-
|
|
3526
|
+
flex: 1;
|
|
3527
|
+
padding: 10px 20px;
|
|
3460
3528
|
background: var(--lb-picker-add-bg);
|
|
3461
3529
|
color: var(--lb-picker-add-label);
|
|
3462
3530
|
border: var(--lb-picker-add-border-width) solid var(--lb-picker-add-border-color);
|
|
@@ -3465,8 +3533,6 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3465
3533
|
font-size: 12px;
|
|
3466
3534
|
font-weight: 600;
|
|
3467
3535
|
cursor: pointer;
|
|
3468
|
-
white-space: nowrap;
|
|
3469
|
-
flex-shrink: 0;
|
|
3470
3536
|
}
|
|
3471
3537
|
|
|
3472
3538
|
.lb-mix-match__modal-add:hover {
|
|
@@ -3476,6 +3542,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3476
3542
|
.lb-mix-match__modal-add:focus-visible {
|
|
3477
3543
|
outline: 2px solid var(--lb-primary-color);
|
|
3478
3544
|
outline-offset: 2px;
|
|
3545
|
+
box-shadow: none;
|
|
3479
3546
|
}
|
|
3480
3547
|
|
|
3481
3548
|
.lb-mix-match__modal-add:disabled {
|
|
@@ -3489,6 +3556,14 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3489
3556
|
opacity: 0.5;
|
|
3490
3557
|
}
|
|
3491
3558
|
|
|
3559
|
+
/* Already in a slot \u2014 prevents shoppers from filling multiple slots
|
|
3560
|
+
with the same product (which wouldn't qualify the discount: it
|
|
3561
|
+
counts distinct products, not slot occupancy). The thumb keeps
|
|
3562
|
+
its qty badge so the shopper sees what's already in the bundle. */
|
|
3563
|
+
.lb-mix-match__modal-product--in-bundle {
|
|
3564
|
+
opacity: 0.5;
|
|
3565
|
+
}
|
|
3566
|
+
|
|
3492
3567
|
.lb-mix-match__modal-product--sold-out .lb-mix-match__modal-sold-out-label {
|
|
3493
3568
|
font-size: 12px;
|
|
3494
3569
|
color: inherit;
|
|
@@ -3585,12 +3660,14 @@ var BUNDLE_VOLUME_CSS = `/* Lime Bundles \u2014 Volume / Quantity Breaks styles
|
|
|
3585
3660
|
border-color: var(--lb-tier-selected-border-color);
|
|
3586
3661
|
}
|
|
3587
3662
|
|
|
3588
|
-
/* Suppress the UA default focus outline so a
|
|
3589
|
-
tier doesn't briefly show the 1px focus ring
|
|
3590
|
-
|
|
3591
|
-
|
|
3663
|
+
/* Suppress the UA default focus outline + Dawn's focus shadow so a
|
|
3664
|
+
freshly-clicked selected tier doesn't briefly show the 1px focus ring
|
|
3665
|
+
or shadow on top of (or in place of) the custom selected-state
|
|
3666
|
+
outline below. Keyboard focus is still indicated by the
|
|
3667
|
+
:focus-visible rule. */
|
|
3592
3668
|
.lb-volume__tier:focus {
|
|
3593
3669
|
outline: none;
|
|
3670
|
+
box-shadow: none;
|
|
3594
3671
|
}
|
|
3595
3672
|
|
|
3596
3673
|
/* Keyboard focus indicator \u2014 explicitly excludes the selected tier so
|
|
@@ -3598,7 +3675,8 @@ var BUNDLE_VOLUME_CSS = `/* Lime Bundles \u2014 Volume / Quantity Breaks styles
|
|
|
3598
3675
|
outline property when both states apply at once. */
|
|
3599
3676
|
.lb-volume__tier:focus-visible:not([aria-checked="true"]) {
|
|
3600
3677
|
outline: 2px solid var(--lb-primary-color);
|
|
3601
|
-
outline-offset: 2px;
|
|
3678
|
+
outline-offset: -2px;
|
|
3679
|
+
box-shadow: none;
|
|
3602
3680
|
}
|
|
3603
3681
|
|
|
3604
3682
|
.lb-volume__tier[aria-checked="true"] {
|
|
@@ -3746,6 +3824,7 @@ var BUNDLE_DROPDOWN_CSS = `/**
|
|
|
3746
3824
|
.lb-dropdown-trigger:focus-visible {
|
|
3747
3825
|
outline: 2px solid var(--lb-primary-color);
|
|
3748
3826
|
outline-offset: 2px;
|
|
3827
|
+
box-shadow: none;
|
|
3749
3828
|
}
|
|
3750
3829
|
|
|
3751
3830
|
.lb-dropdown-trigger[aria-expanded="true"] {
|