@lime-bundles/widget 3.2.1 → 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 +81 -29
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +81 -29
- package/dist/index.js.map +1 -1
- package/dist/lime-bundle.global.js +56 -34
- 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 : "";
|
|
@@ -1051,20 +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);
|
|
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));
|
|
1060
|
+
});
|
|
1054
1061
|
const modal = renderModal(bundle, eligible, currency, {
|
|
1055
1062
|
showSearch: wc.showSearch,
|
|
1056
1063
|
showQtySelector,
|
|
1057
1064
|
selections,
|
|
1058
1065
|
onAdd: (product, variant, quantity) => addSelection(product, variant, quantity),
|
|
1059
|
-
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
|
+
}
|
|
1060
1073
|
});
|
|
1061
1074
|
root.appendChild(modal.el);
|
|
1062
|
-
const cta = buildCtaButton(`Select ${requiredQty} items to unlock`);
|
|
1063
|
-
cta.disabled = true;
|
|
1064
|
-
cta.addEventListener("click", () => {
|
|
1065
|
-
if (cta.disabled) return;
|
|
1066
|
-
onAddToCart(buildCartLines(selections, bundle));
|
|
1067
|
-
});
|
|
1068
1075
|
root.appendChild(cta);
|
|
1069
1076
|
root.appendChild(
|
|
1070
1077
|
el("p", "lb-bundle-error", { "data-error": "", "aria-live": "polite" })
|
|
@@ -1196,12 +1203,14 @@ function renderProgress(requiredQty) {
|
|
|
1196
1203
|
const wrap = el("div", "lb-mix-match__progress");
|
|
1197
1204
|
const labels = el("div", "lb-mix-match__progress-labels");
|
|
1198
1205
|
const count = el("span", "lb-mix-match__progress-count", {
|
|
1199
|
-
"data-progress-count": ""
|
|
1206
|
+
"data-progress-count": "",
|
|
1207
|
+
"aria-live": "polite"
|
|
1200
1208
|
});
|
|
1201
1209
|
count.textContent = `0 of ${requiredQty} selected`;
|
|
1202
1210
|
labels.appendChild(count);
|
|
1203
1211
|
const remaining = el("span", "lb-mix-match__progress-remaining", {
|
|
1204
|
-
"data-progress-remaining": ""
|
|
1212
|
+
"data-progress-remaining": "",
|
|
1213
|
+
"aria-live": "polite"
|
|
1205
1214
|
});
|
|
1206
1215
|
remaining.textContent = `${requiredQty} more to go`;
|
|
1207
1216
|
labels.appendChild(remaining);
|
|
@@ -1576,12 +1585,12 @@ function renderModal(bundle, eligible, currency, handlers) {
|
|
|
1576
1585
|
refreshFromSelections: () => {
|
|
1577
1586
|
}
|
|
1578
1587
|
};
|
|
1588
|
+
const optionSelects = [];
|
|
1579
1589
|
if (availableVariants.length > 1) {
|
|
1580
1590
|
const optionNames = availableVariants[0].selectedOptions.map(
|
|
1581
1591
|
(o) => o.name
|
|
1582
1592
|
);
|
|
1583
1593
|
const productIdTail = ep.product.id.replace(/^.*\//, "");
|
|
1584
|
-
const optionSelects = [];
|
|
1585
1594
|
const resolveVariant = (values) => availableVariants.find(
|
|
1586
1595
|
(v) => v.selectedOptions.length === values.length && v.selectedOptions.every((o, i) => o.value === values[i])
|
|
1587
1596
|
) ?? null;
|
|
@@ -1690,7 +1699,13 @@ function renderModal(bundle, eligible, currency, handlers) {
|
|
|
1690
1699
|
productEl.appendChild(info);
|
|
1691
1700
|
let addBtn = null;
|
|
1692
1701
|
const refreshAddState = () => {
|
|
1693
|
-
if (!addBtn)
|
|
1702
|
+
if (!addBtn) {
|
|
1703
|
+
optionSelects.forEach((sel) => {
|
|
1704
|
+
sel.disabled = true;
|
|
1705
|
+
});
|
|
1706
|
+
if (stepper) stepper.setExternallyDisabled(true);
|
|
1707
|
+
return;
|
|
1708
|
+
}
|
|
1694
1709
|
const { cap } = computeStepperBounds();
|
|
1695
1710
|
const already = alreadyInBundleFor(
|
|
1696
1711
|
handlers.selections,
|
|
@@ -1709,12 +1724,19 @@ function renderModal(bundle, eligible, currency, handlers) {
|
|
|
1709
1724
|
if (productInBundle) {
|
|
1710
1725
|
addBtn.disabled = true;
|
|
1711
1726
|
addBtn.textContent = "Added";
|
|
1727
|
+
addBtn.setAttribute("aria-label", `Added ${ep.product.title}`);
|
|
1712
1728
|
productEl.classList.add("lb-mix-match__modal-product--in-bundle");
|
|
1713
1729
|
} else {
|
|
1714
1730
|
addBtn.textContent = "Add";
|
|
1731
|
+
addBtn.setAttribute("aria-label", `Add ${ep.product.title}`);
|
|
1715
1732
|
productEl.classList.remove("lb-mix-match__modal-product--in-bundle");
|
|
1716
1733
|
addBtn.disabled = handlers.isComplete() || cap < rule.min;
|
|
1717
1734
|
}
|
|
1735
|
+
const rowDisabled = addBtn.disabled;
|
|
1736
|
+
optionSelects.forEach((sel) => {
|
|
1737
|
+
sel.disabled = rowDisabled;
|
|
1738
|
+
});
|
|
1739
|
+
if (stepper) stepper.setExternallyDisabled(rowDisabled);
|
|
1718
1740
|
};
|
|
1719
1741
|
if (!ep.isOos) {
|
|
1720
1742
|
const actions = el("div", "lb-mix-match__modal-product-actions");
|
|
@@ -1723,12 +1745,15 @@ function renderModal(bundle, eligible, currency, handlers) {
|
|
|
1723
1745
|
addBtn.type = "button";
|
|
1724
1746
|
addBtn.className = "lb-mix-match__modal-add";
|
|
1725
1747
|
addBtn.textContent = "Add";
|
|
1748
|
+
addBtn.setAttribute("aria-label", `Add ${ep.product.title}`);
|
|
1726
1749
|
addBtn.addEventListener("click", () => {
|
|
1727
1750
|
if (!addBtn || addBtn.disabled) return;
|
|
1728
1751
|
if (handlers.isComplete()) return;
|
|
1729
1752
|
const qty = stepper ? stepper.value() : rule.min;
|
|
1730
1753
|
handlers.onAdd(ep.product, currentVariant, qty);
|
|
1731
1754
|
if (stepper) stepper.reset(rule.min);
|
|
1755
|
+
const nextFocus = handlers.getFocusAfterAdd();
|
|
1756
|
+
if (nextFocus) lastFocused = nextFocus;
|
|
1732
1757
|
close();
|
|
1733
1758
|
});
|
|
1734
1759
|
actions.appendChild(addBtn);
|
|
@@ -1824,6 +1849,7 @@ function renderQtyStepper(opts) {
|
|
|
1824
1849
|
plus.innerHTML = STEPPER_PLUS_SVG;
|
|
1825
1850
|
wrap.appendChild(plus);
|
|
1826
1851
|
let current = clamp2(opts.initial, opts.getBounds());
|
|
1852
|
+
let externallyDisabled = false;
|
|
1827
1853
|
function clamp2(n, b) {
|
|
1828
1854
|
return Math.max(b.min, Math.min(b.max, n));
|
|
1829
1855
|
}
|
|
@@ -1831,8 +1857,8 @@ function renderQtyStepper(opts) {
|
|
|
1831
1857
|
const b = opts.getBounds();
|
|
1832
1858
|
current = clamp2(current, b);
|
|
1833
1859
|
valueEl.textContent = String(current);
|
|
1834
|
-
minus.disabled = current <= b.min;
|
|
1835
|
-
plus.disabled = current >= b.max;
|
|
1860
|
+
minus.disabled = externallyDisabled || current <= b.min;
|
|
1861
|
+
plus.disabled = externallyDisabled || current >= b.max;
|
|
1836
1862
|
}
|
|
1837
1863
|
minus.addEventListener("click", () => {
|
|
1838
1864
|
const b = opts.getBounds();
|
|
@@ -1852,7 +1878,11 @@ function renderQtyStepper(opts) {
|
|
|
1852
1878
|
current = clamp2(qty, opts.getBounds());
|
|
1853
1879
|
paint();
|
|
1854
1880
|
},
|
|
1855
|
-
refresh: paint
|
|
1881
|
+
refresh: paint,
|
|
1882
|
+
setExternallyDisabled(disabled) {
|
|
1883
|
+
externallyDisabled = disabled;
|
|
1884
|
+
paint();
|
|
1885
|
+
}
|
|
1856
1886
|
};
|
|
1857
1887
|
}
|
|
1858
1888
|
function buildEligibleProducts(bundle, oosBehavior) {
|
|
@@ -2499,6 +2529,13 @@ var BUNDLE_BASE_CSS = `/* Lime Bundles \u2014 shared base styles for all bundle
|
|
|
2499
2529
|
text-decoration: underline;
|
|
2500
2530
|
}
|
|
2501
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
|
+
|
|
2502
2539
|
.lb-bundle-product-price {
|
|
2503
2540
|
/* --lb-product-price-display fallback is the "on" branch; Liquid sets 'none' when merchant disables. */
|
|
2504
2541
|
display: var(--lb-product-price-display, block);
|
|
@@ -2947,6 +2984,7 @@ var BUNDLE_FIXED_CSS = `/* Lime Bundles \u2014 Fixed bundle styles */
|
|
|
2947
2984
|
.lb-bundle-variant-select:focus-visible {
|
|
2948
2985
|
outline: 2px solid var(--lb-primary-color);
|
|
2949
2986
|
outline-offset: 2px;
|
|
2987
|
+
box-shadow: none;
|
|
2950
2988
|
}
|
|
2951
2989
|
`;
|
|
2952
2990
|
var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
@@ -3024,7 +3062,8 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3024
3062
|
|
|
3025
3063
|
.lb-mix-match__slot--empty:focus-visible {
|
|
3026
3064
|
outline: 2px solid var(--lb-primary-color);
|
|
3027
|
-
outline-offset: 2px;
|
|
3065
|
+
outline-offset: -2px;
|
|
3066
|
+
box-shadow: none;
|
|
3028
3067
|
border-radius: 8px;
|
|
3029
3068
|
}
|
|
3030
3069
|
|
|
@@ -3091,6 +3130,13 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3091
3130
|
text-decoration: underline;
|
|
3092
3131
|
}
|
|
3093
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
|
+
|
|
3094
3140
|
/* .lb-mix-match__filled-variant \u2014 styled jointly with
|
|
3095
3141
|
.lb-bundle-variant-badge above to keep the variant text consistent
|
|
3096
3142
|
across mix-match and fixed bundle widgets. */
|
|
@@ -3136,7 +3182,8 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3136
3182
|
|
|
3137
3183
|
.lb-mix-match__slot-remove:focus-visible {
|
|
3138
3184
|
outline: 2px solid var(--lb-primary-color);
|
|
3139
|
-
outline-offset: 2px;
|
|
3185
|
+
outline-offset: -2px;
|
|
3186
|
+
box-shadow: none;
|
|
3140
3187
|
}
|
|
3141
3188
|
|
|
3142
3189
|
/* === Modal Overlay === */
|
|
@@ -3216,7 +3263,8 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3216
3263
|
|
|
3217
3264
|
.lb-mix-match__modal-close:focus-visible {
|
|
3218
3265
|
outline: 2px solid var(--lb-primary-color);
|
|
3219
|
-
outline-offset:
|
|
3266
|
+
outline-offset: 0;
|
|
3267
|
+
box-shadow: none;
|
|
3220
3268
|
}
|
|
3221
3269
|
|
|
3222
3270
|
/* === Modal Search === */
|
|
@@ -3244,9 +3292,10 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3244
3292
|
color: color-mix(in srgb, var(--lb-picker-text) 50%, transparent);
|
|
3245
3293
|
}
|
|
3246
3294
|
|
|
3247
|
-
.lb-mix-match__modal-search-input:focus {
|
|
3248
|
-
outline:
|
|
3249
|
-
|
|
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;
|
|
3250
3299
|
}
|
|
3251
3300
|
|
|
3252
3301
|
.lb-mix-match__modal-search-clear {
|
|
@@ -3379,6 +3428,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3379
3428
|
.lb-mix-match__variant-select:focus-visible {
|
|
3380
3429
|
outline: 2px solid var(--lb-primary-color);
|
|
3381
3430
|
outline-offset: 2px;
|
|
3431
|
+
box-shadow: none;
|
|
3382
3432
|
}
|
|
3383
3433
|
|
|
3384
3434
|
/* Per-pick quantity stepper inside the picker modal product row.
|
|
@@ -3433,13 +3483,10 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3433
3483
|
justify-content: center;
|
|
3434
3484
|
}
|
|
3435
3485
|
|
|
3436
|
-
.lb-mix-match__qty-stepper-button:hover:not(:disabled) {
|
|
3437
|
-
background: color-mix(in srgb, var(--lb-picker-text) 6%, transparent);
|
|
3438
|
-
}
|
|
3439
|
-
|
|
3440
3486
|
.lb-mix-match__qty-stepper-button:focus-visible {
|
|
3441
3487
|
outline: 2px solid var(--lb-primary-color);
|
|
3442
3488
|
outline-offset: -2px;
|
|
3489
|
+
box-shadow: none;
|
|
3443
3490
|
}
|
|
3444
3491
|
|
|
3445
3492
|
.lb-mix-match__qty-stepper-button:disabled {
|
|
@@ -3495,6 +3542,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3495
3542
|
.lb-mix-match__modal-add:focus-visible {
|
|
3496
3543
|
outline: 2px solid var(--lb-primary-color);
|
|
3497
3544
|
outline-offset: 2px;
|
|
3545
|
+
box-shadow: none;
|
|
3498
3546
|
}
|
|
3499
3547
|
|
|
3500
3548
|
.lb-mix-match__modal-add:disabled {
|
|
@@ -3612,12 +3660,14 @@ var BUNDLE_VOLUME_CSS = `/* Lime Bundles \u2014 Volume / Quantity Breaks styles
|
|
|
3612
3660
|
border-color: var(--lb-tier-selected-border-color);
|
|
3613
3661
|
}
|
|
3614
3662
|
|
|
3615
|
-
/* Suppress the UA default focus outline so a
|
|
3616
|
-
tier doesn't briefly show the 1px focus ring
|
|
3617
|
-
|
|
3618
|
-
|
|
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. */
|
|
3619
3668
|
.lb-volume__tier:focus {
|
|
3620
3669
|
outline: none;
|
|
3670
|
+
box-shadow: none;
|
|
3621
3671
|
}
|
|
3622
3672
|
|
|
3623
3673
|
/* Keyboard focus indicator \u2014 explicitly excludes the selected tier so
|
|
@@ -3625,7 +3675,8 @@ var BUNDLE_VOLUME_CSS = `/* Lime Bundles \u2014 Volume / Quantity Breaks styles
|
|
|
3625
3675
|
outline property when both states apply at once. */
|
|
3626
3676
|
.lb-volume__tier:focus-visible:not([aria-checked="true"]) {
|
|
3627
3677
|
outline: 2px solid var(--lb-primary-color);
|
|
3628
|
-
outline-offset: 2px;
|
|
3678
|
+
outline-offset: -2px;
|
|
3679
|
+
box-shadow: none;
|
|
3629
3680
|
}
|
|
3630
3681
|
|
|
3631
3682
|
.lb-volume__tier[aria-checked="true"] {
|
|
@@ -3773,6 +3824,7 @@ var BUNDLE_DROPDOWN_CSS = `/**
|
|
|
3773
3824
|
.lb-dropdown-trigger:focus-visible {
|
|
3774
3825
|
outline: 2px solid var(--lb-primary-color);
|
|
3775
3826
|
outline-offset: 2px;
|
|
3827
|
+
box-shadow: none;
|
|
3776
3828
|
}
|
|
3777
3829
|
|
|
3778
3830
|
.lb-dropdown-trigger[aria-expanded="true"] {
|