@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.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 : "";
|
|
@@ -1044,20 +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);
|
|
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));
|
|
1053
|
+
});
|
|
1047
1054
|
const modal = renderModal(bundle, eligible, currency, {
|
|
1048
1055
|
showSearch: wc.showSearch,
|
|
1049
1056
|
showQtySelector,
|
|
1050
1057
|
selections,
|
|
1051
1058
|
onAdd: (product, variant, quantity) => addSelection(product, variant, quantity),
|
|
1052
|
-
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
|
+
}
|
|
1053
1066
|
});
|
|
1054
1067
|
root.appendChild(modal.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
|
-
});
|
|
1061
1068
|
root.appendChild(cta);
|
|
1062
1069
|
root.appendChild(
|
|
1063
1070
|
el("p", "lb-bundle-error", { "data-error": "", "aria-live": "polite" })
|
|
@@ -1189,12 +1196,14 @@ function renderProgress(requiredQty) {
|
|
|
1189
1196
|
const wrap = el("div", "lb-mix-match__progress");
|
|
1190
1197
|
const labels = el("div", "lb-mix-match__progress-labels");
|
|
1191
1198
|
const count = el("span", "lb-mix-match__progress-count", {
|
|
1192
|
-
"data-progress-count": ""
|
|
1199
|
+
"data-progress-count": "",
|
|
1200
|
+
"aria-live": "polite"
|
|
1193
1201
|
});
|
|
1194
1202
|
count.textContent = `0 of ${requiredQty} selected`;
|
|
1195
1203
|
labels.appendChild(count);
|
|
1196
1204
|
const remaining = el("span", "lb-mix-match__progress-remaining", {
|
|
1197
|
-
"data-progress-remaining": ""
|
|
1205
|
+
"data-progress-remaining": "",
|
|
1206
|
+
"aria-live": "polite"
|
|
1198
1207
|
});
|
|
1199
1208
|
remaining.textContent = `${requiredQty} more to go`;
|
|
1200
1209
|
labels.appendChild(remaining);
|
|
@@ -1569,12 +1578,12 @@ function renderModal(bundle, eligible, currency, handlers) {
|
|
|
1569
1578
|
refreshFromSelections: () => {
|
|
1570
1579
|
}
|
|
1571
1580
|
};
|
|
1581
|
+
const optionSelects = [];
|
|
1572
1582
|
if (availableVariants.length > 1) {
|
|
1573
1583
|
const optionNames = availableVariants[0].selectedOptions.map(
|
|
1574
1584
|
(o) => o.name
|
|
1575
1585
|
);
|
|
1576
1586
|
const productIdTail = ep.product.id.replace(/^.*\//, "");
|
|
1577
|
-
const optionSelects = [];
|
|
1578
1587
|
const resolveVariant = (values) => availableVariants.find(
|
|
1579
1588
|
(v) => v.selectedOptions.length === values.length && v.selectedOptions.every((o, i) => o.value === values[i])
|
|
1580
1589
|
) ?? null;
|
|
@@ -1683,7 +1692,13 @@ function renderModal(bundle, eligible, currency, handlers) {
|
|
|
1683
1692
|
productEl.appendChild(info);
|
|
1684
1693
|
let addBtn = null;
|
|
1685
1694
|
const refreshAddState = () => {
|
|
1686
|
-
if (!addBtn)
|
|
1695
|
+
if (!addBtn) {
|
|
1696
|
+
optionSelects.forEach((sel) => {
|
|
1697
|
+
sel.disabled = true;
|
|
1698
|
+
});
|
|
1699
|
+
if (stepper) stepper.setExternallyDisabled(true);
|
|
1700
|
+
return;
|
|
1701
|
+
}
|
|
1687
1702
|
const { cap } = computeStepperBounds();
|
|
1688
1703
|
const already = alreadyInBundleFor(
|
|
1689
1704
|
handlers.selections,
|
|
@@ -1702,12 +1717,19 @@ function renderModal(bundle, eligible, currency, handlers) {
|
|
|
1702
1717
|
if (productInBundle) {
|
|
1703
1718
|
addBtn.disabled = true;
|
|
1704
1719
|
addBtn.textContent = "Added";
|
|
1720
|
+
addBtn.setAttribute("aria-label", `Added ${ep.product.title}`);
|
|
1705
1721
|
productEl.classList.add("lb-mix-match__modal-product--in-bundle");
|
|
1706
1722
|
} else {
|
|
1707
1723
|
addBtn.textContent = "Add";
|
|
1724
|
+
addBtn.setAttribute("aria-label", `Add ${ep.product.title}`);
|
|
1708
1725
|
productEl.classList.remove("lb-mix-match__modal-product--in-bundle");
|
|
1709
1726
|
addBtn.disabled = handlers.isComplete() || cap < rule.min;
|
|
1710
1727
|
}
|
|
1728
|
+
const rowDisabled = addBtn.disabled;
|
|
1729
|
+
optionSelects.forEach((sel) => {
|
|
1730
|
+
sel.disabled = rowDisabled;
|
|
1731
|
+
});
|
|
1732
|
+
if (stepper) stepper.setExternallyDisabled(rowDisabled);
|
|
1711
1733
|
};
|
|
1712
1734
|
if (!ep.isOos) {
|
|
1713
1735
|
const actions = el("div", "lb-mix-match__modal-product-actions");
|
|
@@ -1716,12 +1738,15 @@ function renderModal(bundle, eligible, currency, handlers) {
|
|
|
1716
1738
|
addBtn.type = "button";
|
|
1717
1739
|
addBtn.className = "lb-mix-match__modal-add";
|
|
1718
1740
|
addBtn.textContent = "Add";
|
|
1741
|
+
addBtn.setAttribute("aria-label", `Add ${ep.product.title}`);
|
|
1719
1742
|
addBtn.addEventListener("click", () => {
|
|
1720
1743
|
if (!addBtn || addBtn.disabled) return;
|
|
1721
1744
|
if (handlers.isComplete()) return;
|
|
1722
1745
|
const qty = stepper ? stepper.value() : rule.min;
|
|
1723
1746
|
handlers.onAdd(ep.product, currentVariant, qty);
|
|
1724
1747
|
if (stepper) stepper.reset(rule.min);
|
|
1748
|
+
const nextFocus = handlers.getFocusAfterAdd();
|
|
1749
|
+
if (nextFocus) lastFocused = nextFocus;
|
|
1725
1750
|
close();
|
|
1726
1751
|
});
|
|
1727
1752
|
actions.appendChild(addBtn);
|
|
@@ -1817,6 +1842,7 @@ function renderQtyStepper(opts) {
|
|
|
1817
1842
|
plus.innerHTML = STEPPER_PLUS_SVG;
|
|
1818
1843
|
wrap.appendChild(plus);
|
|
1819
1844
|
let current = clamp2(opts.initial, opts.getBounds());
|
|
1845
|
+
let externallyDisabled = false;
|
|
1820
1846
|
function clamp2(n, b) {
|
|
1821
1847
|
return Math.max(b.min, Math.min(b.max, n));
|
|
1822
1848
|
}
|
|
@@ -1824,8 +1850,8 @@ function renderQtyStepper(opts) {
|
|
|
1824
1850
|
const b = opts.getBounds();
|
|
1825
1851
|
current = clamp2(current, b);
|
|
1826
1852
|
valueEl.textContent = String(current);
|
|
1827
|
-
minus.disabled = current <= b.min;
|
|
1828
|
-
plus.disabled = current >= b.max;
|
|
1853
|
+
minus.disabled = externallyDisabled || current <= b.min;
|
|
1854
|
+
plus.disabled = externallyDisabled || current >= b.max;
|
|
1829
1855
|
}
|
|
1830
1856
|
minus.addEventListener("click", () => {
|
|
1831
1857
|
const b = opts.getBounds();
|
|
@@ -1845,7 +1871,11 @@ function renderQtyStepper(opts) {
|
|
|
1845
1871
|
current = clamp2(qty, opts.getBounds());
|
|
1846
1872
|
paint();
|
|
1847
1873
|
},
|
|
1848
|
-
refresh: paint
|
|
1874
|
+
refresh: paint,
|
|
1875
|
+
setExternallyDisabled(disabled) {
|
|
1876
|
+
externallyDisabled = disabled;
|
|
1877
|
+
paint();
|
|
1878
|
+
}
|
|
1849
1879
|
};
|
|
1850
1880
|
}
|
|
1851
1881
|
function buildEligibleProducts(bundle, oosBehavior) {
|
|
@@ -2492,6 +2522,13 @@ var BUNDLE_BASE_CSS = `/* Lime Bundles \u2014 shared base styles for all bundle
|
|
|
2492
2522
|
text-decoration: underline;
|
|
2493
2523
|
}
|
|
2494
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
|
+
|
|
2495
2532
|
.lb-bundle-product-price {
|
|
2496
2533
|
/* --lb-product-price-display fallback is the "on" branch; Liquid sets 'none' when merchant disables. */
|
|
2497
2534
|
display: var(--lb-product-price-display, block);
|
|
@@ -2940,6 +2977,7 @@ var BUNDLE_FIXED_CSS = `/* Lime Bundles \u2014 Fixed bundle styles */
|
|
|
2940
2977
|
.lb-bundle-variant-select:focus-visible {
|
|
2941
2978
|
outline: 2px solid var(--lb-primary-color);
|
|
2942
2979
|
outline-offset: 2px;
|
|
2980
|
+
box-shadow: none;
|
|
2943
2981
|
}
|
|
2944
2982
|
`;
|
|
2945
2983
|
var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
@@ -3017,7 +3055,8 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3017
3055
|
|
|
3018
3056
|
.lb-mix-match__slot--empty:focus-visible {
|
|
3019
3057
|
outline: 2px solid var(--lb-primary-color);
|
|
3020
|
-
outline-offset: 2px;
|
|
3058
|
+
outline-offset: -2px;
|
|
3059
|
+
box-shadow: none;
|
|
3021
3060
|
border-radius: 8px;
|
|
3022
3061
|
}
|
|
3023
3062
|
|
|
@@ -3084,6 +3123,13 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3084
3123
|
text-decoration: underline;
|
|
3085
3124
|
}
|
|
3086
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
|
+
|
|
3087
3133
|
/* .lb-mix-match__filled-variant \u2014 styled jointly with
|
|
3088
3134
|
.lb-bundle-variant-badge above to keep the variant text consistent
|
|
3089
3135
|
across mix-match and fixed bundle widgets. */
|
|
@@ -3129,7 +3175,8 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3129
3175
|
|
|
3130
3176
|
.lb-mix-match__slot-remove:focus-visible {
|
|
3131
3177
|
outline: 2px solid var(--lb-primary-color);
|
|
3132
|
-
outline-offset: 2px;
|
|
3178
|
+
outline-offset: -2px;
|
|
3179
|
+
box-shadow: none;
|
|
3133
3180
|
}
|
|
3134
3181
|
|
|
3135
3182
|
/* === Modal Overlay === */
|
|
@@ -3209,7 +3256,8 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3209
3256
|
|
|
3210
3257
|
.lb-mix-match__modal-close:focus-visible {
|
|
3211
3258
|
outline: 2px solid var(--lb-primary-color);
|
|
3212
|
-
outline-offset:
|
|
3259
|
+
outline-offset: 0;
|
|
3260
|
+
box-shadow: none;
|
|
3213
3261
|
}
|
|
3214
3262
|
|
|
3215
3263
|
/* === Modal Search === */
|
|
@@ -3237,9 +3285,10 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3237
3285
|
color: color-mix(in srgb, var(--lb-picker-text) 50%, transparent);
|
|
3238
3286
|
}
|
|
3239
3287
|
|
|
3240
|
-
.lb-mix-match__modal-search-input:focus {
|
|
3241
|
-
outline:
|
|
3242
|
-
|
|
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;
|
|
3243
3292
|
}
|
|
3244
3293
|
|
|
3245
3294
|
.lb-mix-match__modal-search-clear {
|
|
@@ -3372,6 +3421,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3372
3421
|
.lb-mix-match__variant-select:focus-visible {
|
|
3373
3422
|
outline: 2px solid var(--lb-primary-color);
|
|
3374
3423
|
outline-offset: 2px;
|
|
3424
|
+
box-shadow: none;
|
|
3375
3425
|
}
|
|
3376
3426
|
|
|
3377
3427
|
/* Per-pick quantity stepper inside the picker modal product row.
|
|
@@ -3426,13 +3476,10 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3426
3476
|
justify-content: center;
|
|
3427
3477
|
}
|
|
3428
3478
|
|
|
3429
|
-
.lb-mix-match__qty-stepper-button:hover:not(:disabled) {
|
|
3430
|
-
background: color-mix(in srgb, var(--lb-picker-text) 6%, transparent);
|
|
3431
|
-
}
|
|
3432
|
-
|
|
3433
3479
|
.lb-mix-match__qty-stepper-button:focus-visible {
|
|
3434
3480
|
outline: 2px solid var(--lb-primary-color);
|
|
3435
3481
|
outline-offset: -2px;
|
|
3482
|
+
box-shadow: none;
|
|
3436
3483
|
}
|
|
3437
3484
|
|
|
3438
3485
|
.lb-mix-match__qty-stepper-button:disabled {
|
|
@@ -3488,6 +3535,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
3488
3535
|
.lb-mix-match__modal-add:focus-visible {
|
|
3489
3536
|
outline: 2px solid var(--lb-primary-color);
|
|
3490
3537
|
outline-offset: 2px;
|
|
3538
|
+
box-shadow: none;
|
|
3491
3539
|
}
|
|
3492
3540
|
|
|
3493
3541
|
.lb-mix-match__modal-add:disabled {
|
|
@@ -3605,12 +3653,14 @@ var BUNDLE_VOLUME_CSS = `/* Lime Bundles \u2014 Volume / Quantity Breaks styles
|
|
|
3605
3653
|
border-color: var(--lb-tier-selected-border-color);
|
|
3606
3654
|
}
|
|
3607
3655
|
|
|
3608
|
-
/* Suppress the UA default focus outline so a
|
|
3609
|
-
tier doesn't briefly show the 1px focus ring
|
|
3610
|
-
|
|
3611
|
-
|
|
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. */
|
|
3612
3661
|
.lb-volume__tier:focus {
|
|
3613
3662
|
outline: none;
|
|
3663
|
+
box-shadow: none;
|
|
3614
3664
|
}
|
|
3615
3665
|
|
|
3616
3666
|
/* Keyboard focus indicator \u2014 explicitly excludes the selected tier so
|
|
@@ -3618,7 +3668,8 @@ var BUNDLE_VOLUME_CSS = `/* Lime Bundles \u2014 Volume / Quantity Breaks styles
|
|
|
3618
3668
|
outline property when both states apply at once. */
|
|
3619
3669
|
.lb-volume__tier:focus-visible:not([aria-checked="true"]) {
|
|
3620
3670
|
outline: 2px solid var(--lb-primary-color);
|
|
3621
|
-
outline-offset: 2px;
|
|
3671
|
+
outline-offset: -2px;
|
|
3672
|
+
box-shadow: none;
|
|
3622
3673
|
}
|
|
3623
3674
|
|
|
3624
3675
|
.lb-volume__tier[aria-checked="true"] {
|
|
@@ -3766,6 +3817,7 @@ var BUNDLE_DROPDOWN_CSS = `/**
|
|
|
3766
3817
|
.lb-dropdown-trigger:focus-visible {
|
|
3767
3818
|
outline: 2px solid var(--lb-primary-color);
|
|
3768
3819
|
outline-offset: 2px;
|
|
3820
|
+
box-shadow: none;
|
|
3769
3821
|
}
|
|
3770
3822
|
|
|
3771
3823
|
.lb-dropdown-trigger[aria-expanded="true"] {
|