@lime-bundles/widget 4.4.0 → 4.5.1
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 +231 -38
- package/dist/index.js +231 -38
- package/dist/lime-bundle.global.js +196 -56
- package/dist/lime-bundle.global.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -3582,6 +3582,8 @@ function mergeCartLines(selections) {
|
|
|
3582
3582
|
var ALL_TYPES2 = "__all__";
|
|
3583
3583
|
var CLOSE_TRANSITION_MS2 = 300;
|
|
3584
3584
|
var SEARCH_DEBOUNCE_MS2 = 200;
|
|
3585
|
+
var STEP_CASCADE_MS = 500;
|
|
3586
|
+
var AUTO_ADVANCE_HOLD_MS = 160;
|
|
3585
3587
|
function createWizard(deps) {
|
|
3586
3588
|
const { container, steps, selections, t } = deps;
|
|
3587
3589
|
const overlay = container.querySelector("[data-modal-overlay]");
|
|
@@ -3606,6 +3608,8 @@ function createWizard(deps) {
|
|
|
3606
3608
|
let modalOpen = false;
|
|
3607
3609
|
let stepIndex = 0;
|
|
3608
3610
|
let rows = [];
|
|
3611
|
+
let cascadeTimer = null;
|
|
3612
|
+
let autoAdvanceTimer = null;
|
|
3609
3613
|
const productsFor = (i) => steps[i].eligibleProducts || [];
|
|
3610
3614
|
const rowCapacity = {
|
|
3611
3615
|
remainingSpots: () => stepHeadroom(selections, steps, stepIndex),
|
|
@@ -3702,6 +3706,18 @@ function createWizard(deps) {
|
|
|
3702
3706
|
for (const r of rows) r.refresh();
|
|
3703
3707
|
updateModalMeta();
|
|
3704
3708
|
}
|
|
3709
|
+
function maybeAutoAdvance() {
|
|
3710
|
+
if (!deps.autoAdvance) return;
|
|
3711
|
+
if (stepIndex >= steps.length - 1) return;
|
|
3712
|
+
if (stepHeadroom(selections, steps, stepIndex) !== 0) return;
|
|
3713
|
+
const from = stepIndex;
|
|
3714
|
+
if (autoAdvanceTimer !== null) clearTimeout(autoAdvanceTimer);
|
|
3715
|
+
autoAdvanceTimer = setTimeout(() => {
|
|
3716
|
+
autoAdvanceTimer = null;
|
|
3717
|
+
if (!modalOpen) return;
|
|
3718
|
+
goToStep(from + 1);
|
|
3719
|
+
}, AUTO_ADVANCE_HOLD_MS);
|
|
3720
|
+
}
|
|
3705
3721
|
function buildProductList(forStep) {
|
|
3706
3722
|
if (!modalList) return;
|
|
3707
3723
|
deps.dropdown?.unbindAll(modalList);
|
|
@@ -3718,6 +3734,7 @@ function createWizard(deps) {
|
|
|
3718
3734
|
onCommittedQtyChanged: () => {
|
|
3719
3735
|
deps.onSelectionChanged();
|
|
3720
3736
|
refresh();
|
|
3737
|
+
maybeAutoAdvance();
|
|
3721
3738
|
}
|
|
3722
3739
|
});
|
|
3723
3740
|
rows.push(row);
|
|
@@ -3797,6 +3814,7 @@ function createWizard(deps) {
|
|
|
3797
3814
|
selections[stepIndex].push(newItem);
|
|
3798
3815
|
deps.onSelectionChanged();
|
|
3799
3816
|
refresh();
|
|
3817
|
+
maybeAutoAdvance();
|
|
3800
3818
|
}
|
|
3801
3819
|
if (modalList) modalList.addEventListener("click", onListClick);
|
|
3802
3820
|
function buildFilters(forStep) {
|
|
@@ -3886,7 +3904,29 @@ function createWizard(deps) {
|
|
|
3886
3904
|
});
|
|
3887
3905
|
}
|
|
3888
3906
|
function goToStep(i, opts = {}) {
|
|
3889
|
-
|
|
3907
|
+
const target = Math.max(0, Math.min(steps.length - 1, i));
|
|
3908
|
+
if (autoAdvanceTimer !== null) {
|
|
3909
|
+
clearTimeout(autoAdvanceTimer);
|
|
3910
|
+
autoAdvanceTimer = null;
|
|
3911
|
+
}
|
|
3912
|
+
if (modalDialog) {
|
|
3913
|
+
if (cascadeTimer !== null) clearTimeout(cascadeTimer);
|
|
3914
|
+
cascadeTimer = null;
|
|
3915
|
+
modalDialog.removeAttribute("data-step-transition");
|
|
3916
|
+
if (opts.animate !== false && target !== stepIndex) {
|
|
3917
|
+
void modalDialog.offsetHeight;
|
|
3918
|
+
modalDialog.setAttribute(
|
|
3919
|
+
"data-step-transition",
|
|
3920
|
+
target > stepIndex ? "forward" : "back"
|
|
3921
|
+
);
|
|
3922
|
+
const dialog = modalDialog;
|
|
3923
|
+
cascadeTimer = setTimeout(() => {
|
|
3924
|
+
cascadeTimer = null;
|
|
3925
|
+
dialog.removeAttribute("data-step-transition");
|
|
3926
|
+
}, STEP_CASCADE_MS);
|
|
3927
|
+
}
|
|
3928
|
+
}
|
|
3929
|
+
stepIndex = target;
|
|
3890
3930
|
buildProductList(stepIndex);
|
|
3891
3931
|
buildFilters(stepIndex);
|
|
3892
3932
|
activeType = ALL_TYPES2;
|
|
@@ -3911,7 +3951,10 @@ function createWizard(deps) {
|
|
|
3911
3951
|
function open(atStep) {
|
|
3912
3952
|
if (!overlay || modalOpen) return;
|
|
3913
3953
|
modalOpen = true;
|
|
3914
|
-
goToStep(typeof atStep === "number" ? atStep : 0, {
|
|
3954
|
+
goToStep(typeof atStep === "number" ? atStep : 0, {
|
|
3955
|
+
skipFocus: true,
|
|
3956
|
+
animate: false
|
|
3957
|
+
});
|
|
3915
3958
|
overlay.style.display = "";
|
|
3916
3959
|
void overlay.offsetHeight;
|
|
3917
3960
|
overlay.classList.add("lb-mix-match__modal-overlay--open");
|
|
@@ -3924,6 +3967,14 @@ function createWizard(deps) {
|
|
|
3924
3967
|
function close() {
|
|
3925
3968
|
if (!overlay || !modalOpen) return;
|
|
3926
3969
|
modalOpen = false;
|
|
3970
|
+
if (autoAdvanceTimer !== null) {
|
|
3971
|
+
clearTimeout(autoAdvanceTimer);
|
|
3972
|
+
autoAdvanceTimer = null;
|
|
3973
|
+
}
|
|
3974
|
+
if (cascadeTimer !== null) {
|
|
3975
|
+
clearTimeout(cascadeTimer);
|
|
3976
|
+
cascadeTimer = null;
|
|
3977
|
+
}
|
|
3927
3978
|
overlay.classList.remove("lb-mix-match__modal-overlay--open");
|
|
3928
3979
|
unlock();
|
|
3929
3980
|
setTimeout(() => {
|
|
@@ -4180,6 +4231,8 @@ function renderMultiStepBundle(container, bundle, onAddToCart, onCleanup) {
|
|
|
4180
4231
|
rulesMap,
|
|
4181
4232
|
showQtySelector: wc.mixMatchShowQuantitySelector !== false,
|
|
4182
4233
|
showTypeFilters: wc.mixMatchShowTypeFilters !== false,
|
|
4234
|
+
// Off by default: a stored config predating the key must not advance.
|
|
4235
|
+
autoAdvance: wc.multiStepAutoAdvance === true,
|
|
4183
4236
|
formatMoney,
|
|
4184
4237
|
dropdown: void 0,
|
|
4185
4238
|
portalTarget: null,
|
|
@@ -4309,11 +4362,18 @@ var BUNDLE_BASE_CSS = `/* Lime Bundles \u2014 shared base styles for all bundle
|
|
|
4309
4362
|
--lb-list-max-height: 360px;
|
|
4310
4363
|
/* Depth of the soft fade at a scroll list's clipped edge. */
|
|
4311
4364
|
--lb-edge-fade-size: 20px;
|
|
4312
|
-
/* Derived "small" corner radius for
|
|
4313
|
-
|
|
4314
|
-
|
|
4315
|
-
|
|
4316
|
-
|
|
4365
|
+
/* Derived "small" corner radius for chips and badges \u2014 the low-stock badge,
|
|
4366
|
+
the volume tier badge, the multi-step count chip. Controls and media
|
|
4367
|
+
(thumbnails, selects, steppers, buttons) take the full --lb-radius: they
|
|
4368
|
+
are the elements the merchant is looking at when they pick a preset, and
|
|
4369
|
+
the picker's own help text already promises they follow it.
|
|
4370
|
+
|
|
4371
|
+
Proportional rather than a fixed subtraction. At "subtle" (6px) minus-4px
|
|
4372
|
+
left 2px, which reads as square \u2014 the merchant saw a picker set to Subtle
|
|
4373
|
+
render with sharp corners (issue #363). Two thirds holds the proportion at
|
|
4374
|
+
every preset: none 0, subtle 4px, rounded 8px, round 12px. No max() needed,
|
|
4375
|
+
since 0 \xD7 \u2154 is 0. */
|
|
4376
|
+
--lb-radius-sm: calc(var(--lb-radius) * 2 / 3);
|
|
4317
4377
|
|
|
4318
4378
|
font-family: inherit;
|
|
4319
4379
|
font-size: 16px;
|
|
@@ -4477,7 +4537,7 @@ var BUNDLE_BASE_CSS = `/* Lime Bundles \u2014 shared base styles for all bundle
|
|
|
4477
4537
|
ratio. Default keeps the historical 1:1 behaviour. */
|
|
4478
4538
|
aspect-ratio: var(--lb-thumbnail-aspect-ratio, 1 / 1);
|
|
4479
4539
|
background: var(--lb-thumbnail-bg);
|
|
4480
|
-
border-radius: var(--lb-radius
|
|
4540
|
+
border-radius: var(--lb-radius);
|
|
4481
4541
|
overflow: hidden;
|
|
4482
4542
|
display: flex;
|
|
4483
4543
|
align-items: center;
|
|
@@ -5027,12 +5087,12 @@ var BUNDLE_FIXED_CSS = `/* Lime Bundles \u2014 Fixed bundle styles */
|
|
|
5027
5087
|
.lb-fixed .lb-bundle-thumbnail {
|
|
5028
5088
|
width: 60px;
|
|
5029
5089
|
min-width: 60px;
|
|
5030
|
-
border-radius: var(--lb-radius
|
|
5090
|
+
border-radius: var(--lb-radius);
|
|
5031
5091
|
box-sizing: border-box;
|
|
5032
5092
|
}
|
|
5033
5093
|
|
|
5034
5094
|
.lb-fixed .lb-bundle-thumbnail img {
|
|
5035
|
-
border-radius: var(--lb-radius
|
|
5095
|
+
border-radius: var(--lb-radius);
|
|
5036
5096
|
border: none;
|
|
5037
5097
|
}
|
|
5038
5098
|
|
|
@@ -5049,7 +5109,7 @@ var BUNDLE_FIXED_CSS = `/* Lime Bundles \u2014 Fixed bundle styles */
|
|
|
5049
5109
|
display: var(--lb-product-qty-chip-display, inline-flex);
|
|
5050
5110
|
align-items: center;
|
|
5051
5111
|
justify-content: center;
|
|
5052
|
-
border-radius: var(--lb-radius
|
|
5112
|
+
border-radius: var(--lb-radius);
|
|
5053
5113
|
background: color-mix(in srgb, var(--lb-text) 7%, transparent);
|
|
5054
5114
|
color: color-mix(in srgb, var(--lb-text) 75%, transparent);
|
|
5055
5115
|
font-size: 13px;
|
|
@@ -5065,7 +5125,7 @@ var BUNDLE_FIXED_CSS = `/* Lime Bundles \u2014 Fixed bundle styles */
|
|
|
5065
5125
|
.lb-bundle-variant-select {
|
|
5066
5126
|
display: inline-block;
|
|
5067
5127
|
border: var(--lb-border-width) solid var(--lb-border);
|
|
5068
|
-
border-radius: var(--lb-radius
|
|
5128
|
+
border-radius: var(--lb-radius);
|
|
5069
5129
|
padding: 8px 32px 8px 12px;
|
|
5070
5130
|
font-size: 12px;
|
|
5071
5131
|
line-height: 16px;
|
|
@@ -5213,12 +5273,12 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
5213
5273
|
position: relative;
|
|
5214
5274
|
width: 60px;
|
|
5215
5275
|
min-width: 60px;
|
|
5216
|
-
border-radius: var(--lb-radius
|
|
5276
|
+
border-radius: var(--lb-radius);
|
|
5217
5277
|
box-sizing: border-box;
|
|
5218
5278
|
}
|
|
5219
5279
|
|
|
5220
5280
|
.lb-mix-match .lb-bundle-thumbnail img {
|
|
5221
|
-
border-radius: var(--lb-radius
|
|
5281
|
+
border-radius: var(--lb-radius);
|
|
5222
5282
|
border: none;
|
|
5223
5283
|
}
|
|
5224
5284
|
|
|
@@ -5384,14 +5444,26 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
5384
5444
|
color: inherit;
|
|
5385
5445
|
}
|
|
5386
5446
|
|
|
5387
|
-
/* Derived "small" radius for the picker's
|
|
5388
|
-
|
|
5389
|
-
|
|
5390
|
-
|
|
5391
|
-
|
|
5392
|
-
|
|
5447
|
+
/* Derived "small" radius for the picker's chips and badges \u2014 the progress
|
|
5448
|
+
segments, the "Added" badge, the close button, the filter pills. The
|
|
5449
|
+
picker-scoped mirror of --lb-radius-sm, and proportional for the same reason
|
|
5450
|
+
(see bundle-base.css).
|
|
5451
|
+
|
|
5452
|
+
Everything the merchant would call a control or an image \u2014 the modal, search,
|
|
5453
|
+
product tiles, thumbnails, variant dropdown, quantity stepper and the
|
|
5454
|
+
buttons \u2014 takes the full --lb-picker-radius instead. That is what the
|
|
5455
|
+
editor's own Borders copy promises them, and the reduced tier had it
|
|
5456
|
+
rendering square at the Subtle preset (issue #363).
|
|
5457
|
+
|
|
5458
|
+
Declared on BOTH hosts the modal can live under. On the storefront it portals
|
|
5459
|
+
to [data-modal-overlay], which the variant listbox portals up to as well. In
|
|
5460
|
+
the admin widget editor there is no overlay at all \u2014 the preview renders the
|
|
5461
|
+
modal directly under .lb-bundle-widget \u2014 so scoping this to the overlay alone
|
|
5462
|
+
left the variable undefined there and every control using it fell back to
|
|
5463
|
+
square corners while the modal and tiles rounded correctly (issue #363). */
|
|
5464
|
+
.lb-bundle-widget,
|
|
5393
5465
|
[data-modal-overlay] {
|
|
5394
|
-
--lb-picker-radius-sm:
|
|
5466
|
+
--lb-picker-radius-sm: calc(var(--lb-picker-radius) * 2 / 3);
|
|
5395
5467
|
}
|
|
5396
5468
|
|
|
5397
5469
|
/* === Modal Overlay === */
|
|
@@ -5488,7 +5560,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
5488
5560
|
border: none;
|
|
5489
5561
|
cursor: pointer;
|
|
5490
5562
|
color: var(--lb-picker-text);
|
|
5491
|
-
border-radius:
|
|
5563
|
+
border-radius: var(--lb-picker-radius-sm);
|
|
5492
5564
|
padding: 0;
|
|
5493
5565
|
margin: -12px -12px 0 0;
|
|
5494
5566
|
transition: background 0.25s ease;
|
|
@@ -5518,7 +5590,9 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
5518
5590
|
.lb-mix-match__filter {
|
|
5519
5591
|
padding: 6px 14px;
|
|
5520
5592
|
border: var(--lb-picker-border-width) solid var(--lb-picker-border-color);
|
|
5521
|
-
|
|
5593
|
+
/* Pills followed the merchant's picker radius as of #363 \u2014 a fixed 999px
|
|
5594
|
+
read as a stray rounded shape in a picker set to None or Subtle. */
|
|
5595
|
+
border-radius: var(--lb-picker-radius-sm);
|
|
5522
5596
|
background: transparent;
|
|
5523
5597
|
color: var(--lb-picker-text);
|
|
5524
5598
|
font-family: inherit;
|
|
@@ -5572,7 +5646,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
5572
5646
|
width: 100%;
|
|
5573
5647
|
padding: 12px 40px 12px 44px;
|
|
5574
5648
|
border: var(--lb-picker-border-width) solid var(--lb-picker-border-color);
|
|
5575
|
-
border-radius: var(--lb-picker-radius
|
|
5649
|
+
border-radius: var(--lb-picker-radius);
|
|
5576
5650
|
font-size: 16px;
|
|
5577
5651
|
line-height: 20px;
|
|
5578
5652
|
color: var(--lb-picker-text);
|
|
@@ -5672,7 +5746,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
5672
5746
|
independent from the main widget's thumbnailRatio so a merchant can
|
|
5673
5747
|
e.g. show tall picker thumbs with square main thumbs. */
|
|
5674
5748
|
aspect-ratio: var(--lb-picker-thumbnail-aspect-ratio, 1 / 1);
|
|
5675
|
-
border-radius: var(--lb-picker-radius
|
|
5749
|
+
border-radius: var(--lb-picker-radius);
|
|
5676
5750
|
box-sizing: border-box;
|
|
5677
5751
|
overflow: hidden;
|
|
5678
5752
|
background: var(--lb-thumbnail-bg);
|
|
@@ -5685,7 +5759,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
5685
5759
|
to auto/contain so the image renders uncropped at intrinsic ratio. */
|
|
5686
5760
|
height: var(--lb-picker-thumbnail-img-height, 100%);
|
|
5687
5761
|
object-fit: var(--lb-picker-thumbnail-img-fit, cover);
|
|
5688
|
-
border-radius: var(--lb-picker-radius
|
|
5762
|
+
border-radius: var(--lb-picker-radius);
|
|
5689
5763
|
}
|
|
5690
5764
|
|
|
5691
5765
|
.lb-mix-match__modal-product-info {
|
|
@@ -5760,7 +5834,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
5760
5834
|
font-size: 12px;
|
|
5761
5835
|
padding: 4px 24px 4px 8px;
|
|
5762
5836
|
border: var(--lb-picker-border-width) solid var(--lb-picker-border-color);
|
|
5763
|
-
border-radius: var(--lb-picker-radius
|
|
5837
|
+
border-radius: var(--lb-picker-radius);
|
|
5764
5838
|
background-color: var(--lb-picker-bg);
|
|
5765
5839
|
background-image: var(--lb-picker-variant-chevron);
|
|
5766
5840
|
background-repeat: no-repeat;
|
|
@@ -5811,7 +5885,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
5811
5885
|
width: 100%;
|
|
5812
5886
|
flex-shrink: 0;
|
|
5813
5887
|
border: var(--lb-picker-border-width) solid var(--lb-picker-border-color);
|
|
5814
|
-
border-radius: var(--lb-picker-radius
|
|
5888
|
+
border-radius: var(--lb-picker-radius);
|
|
5815
5889
|
background-color: var(--lb-picker-bg);
|
|
5816
5890
|
overflow: hidden;
|
|
5817
5891
|
box-sizing: border-box;
|
|
@@ -5888,7 +5962,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
5888
5962
|
background: var(--lb-picker-add-bg);
|
|
5889
5963
|
color: var(--lb-picker-add-label);
|
|
5890
5964
|
border: var(--lb-picker-add-border-width) solid var(--lb-picker-add-border-color);
|
|
5891
|
-
border-radius: var(--lb-picker-radius
|
|
5965
|
+
border-radius: var(--lb-picker-radius);
|
|
5892
5966
|
box-sizing: border-box;
|
|
5893
5967
|
font-size: 12px;
|
|
5894
5968
|
font-weight: 600;
|
|
@@ -6029,7 +6103,7 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
6029
6103
|
background: var(--lb-picker-add-bg);
|
|
6030
6104
|
color: var(--lb-picker-add-label);
|
|
6031
6105
|
border: var(--lb-picker-add-border-width) solid var(--lb-picker-add-border-color);
|
|
6032
|
-
border-radius: var(--lb-picker-radius
|
|
6106
|
+
border-radius: var(--lb-picker-radius);
|
|
6033
6107
|
box-sizing: border-box;
|
|
6034
6108
|
font-family: inherit;
|
|
6035
6109
|
font-size: 14px;
|
|
@@ -6078,7 +6152,9 @@ var BUNDLE_MIX_MATCH_CSS = `/* Lime Bundles \u2014 Mix & Match styles */
|
|
|
6078
6152
|
.lb-mix-match__modal {
|
|
6079
6153
|
max-width: 100%;
|
|
6080
6154
|
max-height: 90vh;
|
|
6081
|
-
|
|
6155
|
+
/* Bottom sheet: only the top corners round, but they round to whatever the
|
|
6156
|
+
merchant picked rather than a fixed 16px (issue #363). */
|
|
6157
|
+
border-radius: var(--lb-picker-radius) var(--lb-picker-radius) 0 0;
|
|
6082
6158
|
transform: translateY(100%);
|
|
6083
6159
|
}
|
|
6084
6160
|
|
|
@@ -6345,12 +6421,12 @@ var BUNDLE_BOGO_CSS = `/* Lime Bundles \u2014 BOGO (Buy X Get Y) bundle styles *
|
|
|
6345
6421
|
.lb-bogo .lb-bundle-thumbnail {
|
|
6346
6422
|
width: 60px;
|
|
6347
6423
|
min-width: 60px;
|
|
6348
|
-
border-radius: var(--lb-radius
|
|
6424
|
+
border-radius: var(--lb-radius);
|
|
6349
6425
|
box-sizing: border-box;
|
|
6350
6426
|
}
|
|
6351
6427
|
|
|
6352
6428
|
.lb-bogo .lb-bundle-thumbnail img {
|
|
6353
|
-
border-radius: var(--lb-radius
|
|
6429
|
+
border-radius: var(--lb-radius);
|
|
6354
6430
|
border: none;
|
|
6355
6431
|
}
|
|
6356
6432
|
|
|
@@ -6471,6 +6547,13 @@ var BUNDLE_MULTI_STEP_CSS = `/**
|
|
|
6471
6547
|
cursor: pointer;
|
|
6472
6548
|
box-sizing: border-box;
|
|
6473
6549
|
transition: background-color 0.25s ease;
|
|
6550
|
+
/* Deliberately no border-radius. This row paints the checklist hairline as
|
|
6551
|
+
its own border-top (see the run rule above), and a radius tapers that
|
|
6552
|
+
border into the corner arcs \u2014 the dividers came out visibly curved at the
|
|
6553
|
+
"round" preset (issue #363). A full-bleed list row is meant to be square
|
|
6554
|
+
anyway; the hover tint below spans the card width, so it has no corner to
|
|
6555
|
+
round against. The :focus-visible radius is fine: an outline is a
|
|
6556
|
+
separate paint and never touches the border. */
|
|
6474
6557
|
}
|
|
6475
6558
|
|
|
6476
6559
|
.lb-multi-step__step-row:hover {
|
|
@@ -6618,7 +6701,7 @@ var BUNDLE_MULTI_STEP_CSS = `/**
|
|
|
6618
6701
|
padding: 10px 24px;
|
|
6619
6702
|
background: none;
|
|
6620
6703
|
border: var(--lb-picker-border-width) solid var(--lb-picker-border-color);
|
|
6621
|
-
border-radius: var(--lb-picker-radius
|
|
6704
|
+
border-radius: var(--lb-picker-radius);
|
|
6622
6705
|
box-sizing: border-box;
|
|
6623
6706
|
color: var(--lb-picker-text);
|
|
6624
6707
|
font-family: inherit;
|
|
@@ -6636,6 +6719,108 @@ var BUNDLE_MULTI_STEP_CSS = `/**
|
|
|
6636
6719
|
outline: 2px solid var(--lb-primary-color);
|
|
6637
6720
|
outline-offset: 2px;
|
|
6638
6721
|
}
|
|
6722
|
+
|
|
6723
|
+
/* \u2500\u2500 Step-change transition \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
6724
|
+
Moving between steps swaps the whole step-scoped region in a single
|
|
6725
|
+
paint, which reads as nothing happening (or as a glitch) rather than
|
|
6726
|
+
as arriving somewhere new \u2014 and worst of all under auto-advance,
|
|
6727
|
+
where the shopper never clicked anything. So the step assembles
|
|
6728
|
+
instead of arriving whole: the step label leads, the filter pills
|
|
6729
|
+
follow, then the product cards one after another. Staging is what
|
|
6730
|
+
makes the change legible; a uniform slide of everything at once only
|
|
6731
|
+
wobbles the card.
|
|
6732
|
+
|
|
6733
|
+
The wizard stamps data-step-transition="forward" | "back" on the
|
|
6734
|
+
dialog on every step change (manual Next/Back and auto-advance
|
|
6735
|
+
alike, never on open, where the modal entrance already carries the
|
|
6736
|
+
motion), and clears it again once the cascade has played \u2014 see
|
|
6737
|
+
STEP_CASCADE_MS in multi-step/wizard.ts. That clear is load-bearing,
|
|
6738
|
+
not tidiness: search and filter hide cards with .lb-hidden
|
|
6739
|
+
(display: none), and restoring display restarts a card's animation,
|
|
6740
|
+
so a live attribute would replay the whole cascade on every
|
|
6741
|
+
keystroke that reveals a card.
|
|
6742
|
+
|
|
6743
|
+
Two elements deliberately hold still. The footer, because Back/Next
|
|
6744
|
+
are the shopper's anchor while everything above them moves. And the
|
|
6745
|
+
progress rail, because it is the one thing that answers "where am I
|
|
6746
|
+
now" \u2014 animating the shopper's only orientation cue is what made the
|
|
6747
|
+
previous version hard to read. Its segment fill carries its own
|
|
6748
|
+
state change already. */
|
|
6749
|
+
@keyframes lb-multi-step-cascade-fwd {
|
|
6750
|
+
from {
|
|
6751
|
+
opacity: 0;
|
|
6752
|
+
transform: translateY(10px);
|
|
6753
|
+
}
|
|
6754
|
+
}
|
|
6755
|
+
|
|
6756
|
+
@keyframes lb-multi-step-cascade-back {
|
|
6757
|
+
from {
|
|
6758
|
+
opacity: 0;
|
|
6759
|
+
transform: translateY(-10px);
|
|
6760
|
+
}
|
|
6761
|
+
}
|
|
6762
|
+
|
|
6763
|
+
.lb-mix-match__modal[data-step-transition] .lb-mix-match__modal-subtitle {
|
|
6764
|
+
animation: lb-multi-step-cascade-fwd 0.2s ease-out both;
|
|
6765
|
+
}
|
|
6766
|
+
|
|
6767
|
+
.lb-mix-match__modal[data-step-transition] .lb-mix-match__filters {
|
|
6768
|
+
animation: lb-multi-step-cascade-fwd 0.2s ease-out 0.05s both;
|
|
6769
|
+
}
|
|
6770
|
+
|
|
6771
|
+
/* Cards stagger 30ms apart, but only the first four: a step can hold
|
|
6772
|
+
dozens of products and the two-column grid shows about four at a
|
|
6773
|
+
time, so past that the stagger is below the fold and would only add
|
|
6774
|
+
lag. Everything from the fifth on shares the fourth's landing. */
|
|
6775
|
+
.lb-mix-match__modal[data-step-transition] .lb-mix-match__modal-list > * {
|
|
6776
|
+
animation: lb-multi-step-cascade-fwd 0.22s ease-out 0.2s both;
|
|
6777
|
+
}
|
|
6778
|
+
|
|
6779
|
+
.lb-mix-match__modal[data-step-transition] .lb-mix-match__modal-list > :nth-child(1) {
|
|
6780
|
+
animation-delay: 0.09s;
|
|
6781
|
+
}
|
|
6782
|
+
|
|
6783
|
+
.lb-mix-match__modal[data-step-transition] .lb-mix-match__modal-list > :nth-child(2) {
|
|
6784
|
+
animation-delay: 0.12s;
|
|
6785
|
+
}
|
|
6786
|
+
|
|
6787
|
+
.lb-mix-match__modal[data-step-transition] .lb-mix-match__modal-list > :nth-child(3) {
|
|
6788
|
+
animation-delay: 0.15s;
|
|
6789
|
+
}
|
|
6790
|
+
|
|
6791
|
+
.lb-mix-match__modal[data-step-transition] .lb-mix-match__modal-list > :nth-child(4) {
|
|
6792
|
+
animation-delay: 0.18s;
|
|
6793
|
+
}
|
|
6794
|
+
|
|
6795
|
+
/* Going back runs the same cascade in the same order \u2014 only the offset
|
|
6796
|
+
flips, so the shopper still reads which way they moved. Overrides
|
|
6797
|
+
the name alone; the staggered delays above must survive. */
|
|
6798
|
+
.lb-mix-match__modal[data-step-transition="back"] .lb-mix-match__modal-subtitle,
|
|
6799
|
+
.lb-mix-match__modal[data-step-transition="back"] .lb-mix-match__filters,
|
|
6800
|
+
.lb-mix-match__modal[data-step-transition="back"] .lb-mix-match__modal-list > * {
|
|
6801
|
+
animation-name: lb-multi-step-cascade-back;
|
|
6802
|
+
}
|
|
6803
|
+
|
|
6804
|
+
@keyframes lb-multi-step-cascade-fade {
|
|
6805
|
+
from {
|
|
6806
|
+
opacity: 0;
|
|
6807
|
+
}
|
|
6808
|
+
}
|
|
6809
|
+
|
|
6810
|
+
/* Reduced motion keeps the fade and drops the travel and the stagger:
|
|
6811
|
+
the step change still has to be perceptible, which is the whole
|
|
6812
|
+
point of this block. The card selector is :nth-child(n) rather than
|
|
6813
|
+
* on purpose \u2014 a plain * loses to the :nth-child(1..4) delays above
|
|
6814
|
+
on specificity, which would leave the stagger running with nothing
|
|
6815
|
+
moving. :nth-child(n) matches every child at equal specificity and
|
|
6816
|
+
wins on order. */
|
|
6817
|
+
@media (prefers-reduced-motion: reduce) {
|
|
6818
|
+
.lb-mix-match__modal[data-step-transition] .lb-mix-match__modal-subtitle,
|
|
6819
|
+
.lb-mix-match__modal[data-step-transition] .lb-mix-match__filters,
|
|
6820
|
+
.lb-mix-match__modal[data-step-transition] .lb-mix-match__modal-list > :nth-child(n) {
|
|
6821
|
+
animation: lb-multi-step-cascade-fade 0.15s ease-out both;
|
|
6822
|
+
}
|
|
6823
|
+
}
|
|
6639
6824
|
`;
|
|
6640
6825
|
var BUNDLE_DROPDOWN_CSS = `/**
|
|
6641
6826
|
* Lime Bundles \u2014 Custom variant-picker dropdown styling.
|
|
@@ -6683,7 +6868,7 @@ var BUNDLE_DROPDOWN_CSS = `/**
|
|
|
6683
6868
|
gap: 8px;
|
|
6684
6869
|
width: 100%;
|
|
6685
6870
|
border: var(--lb-border-width) solid var(--lb-border);
|
|
6686
|
-
border-radius: var(--lb-radius
|
|
6871
|
+
border-radius: var(--lb-radius);
|
|
6687
6872
|
padding: 8px 12px;
|
|
6688
6873
|
font-size: 12px;
|
|
6689
6874
|
line-height: 16px;
|
|
@@ -6746,7 +6931,7 @@ var BUNDLE_DROPDOWN_CSS = `/**
|
|
|
6746
6931
|
background: var(--lb-bg);
|
|
6747
6932
|
color: var(--lb-text);
|
|
6748
6933
|
border: var(--lb-border-width) solid var(--lb-border);
|
|
6749
|
-
border-radius: var(--lb-radius
|
|
6934
|
+
border-radius: var(--lb-radius);
|
|
6750
6935
|
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
|
|
6751
6936
|
overflow-y: auto;
|
|
6752
6937
|
overflow-x: hidden;
|
|
@@ -6807,6 +6992,10 @@ var BUNDLE_DROPDOWN_CSS = `/**
|
|
|
6807
6992
|
overflow: hidden;
|
|
6808
6993
|
text-overflow: ellipsis;
|
|
6809
6994
|
color: var(--lb-text);
|
|
6995
|
+
/* The active/hover tint below fills the option, so it rounds with the rest
|
|
6996
|
+
of the widget rather than squaring off against the listbox corner it sits
|
|
6997
|
+
in (issue #363). */
|
|
6998
|
+
border-radius: var(--lb-radius-sm);
|
|
6810
6999
|
}
|
|
6811
7000
|
|
|
6812
7001
|
.lb-dropdown-option[aria-selected="true"] {
|
|
@@ -6865,7 +7054,7 @@ var BUNDLE_DROPDOWN_CSS = `/**
|
|
|
6865
7054
|
.lb-mix-match__modal .lb-dropdown-trigger {
|
|
6866
7055
|
border-color: var(--lb-picker-border-color);
|
|
6867
7056
|
border-width: var(--lb-picker-border-width);
|
|
6868
|
-
border-radius: var(--lb-picker-radius
|
|
7057
|
+
border-radius: var(--lb-picker-radius);
|
|
6869
7058
|
background: var(--lb-picker-bg);
|
|
6870
7059
|
color: var(--lb-picker-text);
|
|
6871
7060
|
/* Match the picker qty stepper + Add button height (border-box so 32px is
|
|
@@ -6886,13 +7075,17 @@ var BUNDLE_DROPDOWN_CSS = `/**
|
|
|
6886
7075
|
[data-modal-overlay] > .lb-dropdown-listbox {
|
|
6887
7076
|
border-color: var(--lb-picker-border-color);
|
|
6888
7077
|
border-width: var(--lb-picker-border-width);
|
|
6889
|
-
border-radius: var(--lb-picker-radius
|
|
7078
|
+
border-radius: var(--lb-picker-radius);
|
|
6890
7079
|
background: var(--lb-picker-bg);
|
|
6891
7080
|
color: var(--lb-picker-text);
|
|
6892
7081
|
scrollbar-color: color-mix(in srgb, var(--lb-picker-text) 15%, transparent)
|
|
6893
7082
|
color-mix(in srgb, var(--lb-picker-text) 2%, transparent);
|
|
6894
7083
|
}
|
|
6895
7084
|
|
|
7085
|
+
[data-modal-overlay] > .lb-dropdown-listbox .lb-dropdown-option {
|
|
7086
|
+
border-radius: var(--lb-picker-radius-sm);
|
|
7087
|
+
}
|
|
7088
|
+
|
|
6896
7089
|
[data-modal-overlay] > .lb-dropdown-listbox::-webkit-scrollbar-track {
|
|
6897
7090
|
background: color-mix(in srgb, var(--lb-picker-text) 2%, transparent);
|
|
6898
7091
|
border-radius: 2px;
|