@lime-bundles/react 7.3.0 → 7.4.0

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/styles.css CHANGED
@@ -42,7 +42,7 @@
42
42
  Falls back to --lb-border-radius until the bundle config has loaded, matching
43
43
  the rest of this stylesheet. */
44
44
  .lb-bundle {
45
- --lb-radius-sm: max(0px, calc(var(--lb-radius, var(--lb-border-radius)) - 4px));
45
+ --lb-radius-sm: calc(var(--lb-radius, var(--lb-border-radius)) * 2 / 3);
46
46
  }
47
47
 
48
48
  /* Edge fade — the shared treatment for inset scroll lists (fixed products,
@@ -184,7 +184,7 @@
184
184
  aspect-ratio: var(--lb-thumbnail-aspect-ratio, 1 / 1);
185
185
  object-fit: var(--lb-thumbnail-img-fit, cover);
186
186
  /* Thumbnails carry only the derived corner radius — no border. */
187
- border-radius: var(--lb-radius-sm);
187
+ border-radius: var(--lb-radius, var(--lb-border-radius));
188
188
  box-sizing: border-box;
189
189
  flex-shrink: 0;
190
190
  }
@@ -233,7 +233,7 @@
233
233
  display: inline-flex;
234
234
  align-items: center;
235
235
  justify-content: center;
236
- border-radius: var(--lb-radius-sm);
236
+ border-radius: var(--lb-radius, var(--lb-border-radius));
237
237
  background: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 7%, transparent);
238
238
  color: color-mix(in srgb, var(--lb-text, var(--lb-primary-color)) 75%, transparent);
239
239
  font-size: 14px;
@@ -310,7 +310,7 @@
310
310
  line-height: 1.4;
311
311
  color: var(--lb-low-stock-text, var(--lb-error-color));
312
312
  background-color: var(--lb-low-stock-bg, #fef3c7);
313
- border-radius: 4px;
313
+ border-radius: var(--lb-radius-sm);
314
314
  white-space: nowrap;
315
315
  }
316
316
 
@@ -428,7 +428,7 @@
428
428
  width: 60px;
429
429
  min-width: 60px;
430
430
  /* Thumbnails carry only the derived corner radius — no border. */
431
- border-radius: var(--lb-radius-sm);
431
+ border-radius: var(--lb-radius, var(--lb-border-radius));
432
432
  box-sizing: border-box;
433
433
  flex-shrink: 0;
434
434
  }
@@ -437,7 +437,7 @@
437
437
  width: 100%;
438
438
  aspect-ratio: var(--lb-thumbnail-aspect-ratio, 1 / 1);
439
439
  object-fit: var(--lb-thumbnail-img-fit, cover);
440
- border-radius: var(--lb-radius-sm);
440
+ border-radius: var(--lb-radius, var(--lb-border-radius));
441
441
  border: none;
442
442
  display: block;
443
443
  }
@@ -603,7 +603,7 @@
603
603
  product tiles keep the full --lb-picker-radius. Falls back to 16px to match
604
604
  the rest of the picker rules until the bundle config has loaded. */
605
605
  [data-modal-overlay] {
606
- --lb-picker-radius-sm: max(0px, calc(var(--lb-picker-radius, 16px) - 4px));
606
+ --lb-picker-radius-sm: calc(var(--lb-picker-radius, 16px) * 2 / 3);
607
607
  }
608
608
 
609
609
  /* === Modal overlay ===================================================== */
@@ -700,7 +700,7 @@
700
700
  border: none;
701
701
  cursor: pointer;
702
702
  color: var(--lb-picker-text, var(--lb-text, var(--lb-primary-color)));
703
- border-radius: 8px;
703
+ border-radius: var(--lb-picker-radius-sm);
704
704
  padding: 0;
705
705
  margin: -12px -12px 0 0;
706
706
  }
@@ -723,7 +723,9 @@
723
723
  .lb-mix-match__filter {
724
724
  padding: 6px 14px;
725
725
  border: var(--lb-picker-border-width, 0px) solid var(--lb-picker-border-color, var(--lb-border-color));
726
- border-radius: 999px;
726
+ /* Pills follow the merchant's picker radius (parity with the theme widget) —
727
+ a fixed 999px read as a stray rounded shape at None or Subtle. */
728
+ border-radius: var(--lb-picker-radius-sm);
727
729
  background: transparent;
728
730
  color: var(--lb-picker-text, var(--lb-text, var(--lb-primary-color)));
729
731
  font-family: inherit;
@@ -770,7 +772,7 @@
770
772
  width: 100%;
771
773
  padding: 12px 40px 12px 44px;
772
774
  border: var(--lb-picker-border-width, 0px) solid var(--lb-picker-border-color, var(--lb-border-color));
773
- border-radius: var(--lb-picker-radius-sm);
775
+ border-radius: var(--lb-picker-radius, 16px);
774
776
  font-size: 16px;
775
777
  line-height: 20px;
776
778
  color: var(--lb-picker-text, var(--lb-text, var(--lb-primary-color)));
@@ -848,7 +850,7 @@
848
850
  width: 100%;
849
851
  aspect-ratio: var(--lb-picker-thumbnail-aspect-ratio, 1 / 1);
850
852
  /* Thumbnails carry only the picker corner radius — no border. */
851
- border-radius: var(--lb-picker-radius-sm);
853
+ border-radius: var(--lb-picker-radius, 16px);
852
854
  box-sizing: border-box;
853
855
  overflow: hidden;
854
856
  background: var(--lb-thumbnail-bg, transparent);
@@ -859,7 +861,7 @@
859
861
  width: 100%;
860
862
  height: var(--lb-picker-thumbnail-img-height, 100%);
861
863
  object-fit: var(--lb-picker-thumbnail-img-fit, cover);
862
- border-radius: var(--lb-picker-radius-sm);
864
+ border-radius: var(--lb-picker-radius, 16px);
863
865
  display: block;
864
866
  }
865
867
 
@@ -918,7 +920,7 @@
918
920
  width: 100%;
919
921
  flex-shrink: 0;
920
922
  border: var(--lb-picker-border-width, 0px) solid var(--lb-picker-border-color, var(--lb-border-color));
921
- border-radius: var(--lb-picker-radius-sm);
923
+ border-radius: var(--lb-picker-radius, 16px);
922
924
  background-color: var(--lb-picker-bg, var(--lb-bg, var(--lb-background)));
923
925
  overflow: hidden;
924
926
  box-sizing: border-box;
@@ -987,7 +989,7 @@
987
989
  background: var(--lb-picker-add-bg, var(--lb-primary-color));
988
990
  color: var(--lb-picker-add-label, #fff);
989
991
  border: var(--lb-picker-add-border-width, 0px) solid var(--lb-picker-add-border-color, var(--lb-primary-color));
990
- border-radius: var(--lb-picker-radius-sm);
992
+ border-radius: var(--lb-picker-radius, 16px);
991
993
  box-sizing: border-box;
992
994
  font-family: inherit;
993
995
  font-size: 12px;
@@ -1111,7 +1113,7 @@
1111
1113
  background: var(--lb-picker-add-bg, var(--lb-primary-color));
1112
1114
  color: var(--lb-picker-add-label, #fff);
1113
1115
  border: var(--lb-picker-add-border-width, 0px) solid var(--lb-picker-add-border-color, var(--lb-primary-color));
1114
- border-radius: var(--lb-picker-radius-sm);
1116
+ border-radius: var(--lb-picker-radius, 16px);
1115
1117
  box-sizing: border-box;
1116
1118
  font-family: inherit;
1117
1119
  font-size: 14px;
@@ -1158,7 +1160,10 @@
1158
1160
  .lb-mix-match__modal {
1159
1161
  max-width: 100%;
1160
1162
  max-height: 90vh;
1161
- border-radius: 16px 16px 0 0;
1163
+ /* Bottom sheet: only the top corners round, but to whatever the merchant
1164
+ picked rather than a fixed 16px (parity with the theme widget). */
1165
+ border-radius: var(--lb-picker-radius, 16px) var(--lb-picker-radius, 16px) 0
1166
+ 0;
1162
1167
  transform: translateY(100%);
1163
1168
  }
1164
1169
 
@@ -1589,7 +1594,7 @@
1589
1594
  gap: 8px;
1590
1595
  width: 100%;
1591
1596
  border: var(--lb-border-width, 1px) solid var(--lb-border, var(--lb-border-color));
1592
- border-radius: var(--lb-radius-sm);
1597
+ border-radius: var(--lb-radius, var(--lb-border-radius));
1593
1598
  padding: 8px 12px;
1594
1599
  font-size: 12px;
1595
1600
  line-height: 16px;
@@ -1647,7 +1652,7 @@
1647
1652
  background: var(--lb-bg, var(--lb-background));
1648
1653
  color: var(--lb-text, var(--lb-primary-color));
1649
1654
  border: var(--lb-border-width, 1px) solid var(--lb-border, var(--lb-border-color));
1650
- border-radius: var(--lb-radius-sm);
1655
+ border-radius: var(--lb-radius, var(--lb-border-radius));
1651
1656
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
1652
1657
  overflow-y: auto;
1653
1658
  overflow-x: hidden;
@@ -1696,6 +1701,15 @@
1696
1701
  overflow: hidden;
1697
1702
  text-overflow: ellipsis;
1698
1703
  color: var(--lb-text, var(--lb-primary-color));
1704
+ /* The active/hover tint below fills the option, so it rounds with the rest
1705
+ of the widget rather than squaring off against the listbox corner. */
1706
+ border-radius: var(--lb-radius-sm);
1707
+ }
1708
+
1709
+ /* Inside the picker modal the option follows the picker preset, like the
1710
+ trigger and listbox around it. */
1711
+ .lb-mix-match__modal-overlay .lb-dropdown-option {
1712
+ border-radius: var(--lb-picker-radius-sm);
1699
1713
  }
1700
1714
 
1701
1715
  .lb-dropdown-option[aria-selected="true"] {
@@ -1880,6 +1894,8 @@
1880
1894
  cursor: pointer;
1881
1895
  box-sizing: border-box;
1882
1896
  transition: background-color 0.25s ease;
1897
+ /* The hover tint below is a filled shape, so it needs the widget's radius
1898
+ the same way the focus ring does. */
1883
1899
  }
1884
1900
 
1885
1901
  .lb-multi-step__step-row:hover {
@@ -2019,7 +2035,7 @@
2019
2035
  padding: 10px 24px;
2020
2036
  background: none;
2021
2037
  border: var(--lb-picker-border-width) solid var(--lb-picker-border-color);
2022
- border-radius: var(--lb-picker-radius-sm);
2038
+ border-radius: var(--lb-picker-radius);
2023
2039
  box-sizing: border-box;
2024
2040
  color: var(--lb-picker-text);
2025
2041
  font-family: inherit;
@@ -2037,3 +2053,105 @@
2037
2053
  outline: 2px solid var(--lb-primary-color);
2038
2054
  outline-offset: 2px;
2039
2055
  }
2056
+
2057
+ /* ── Step-change transition ────────────────────────────────────
2058
+ Moving between steps swaps the whole step-scoped region in a single
2059
+ paint, which reads as nothing happening (or as a glitch) rather than
2060
+ as arriving somewhere new — and worst of all under auto-advance,
2061
+ where the shopper never clicked anything. So the step assembles
2062
+ instead of arriving whole: the step label leads, the filter pills
2063
+ follow, then the product cards one after another. Staging is what
2064
+ makes the change legible; a uniform slide of everything at once only
2065
+ wobbles the card.
2066
+
2067
+ The wizard stamps data-step-transition="forward" | "back" on the
2068
+ dialog on every step change (manual Next/Back and auto-advance
2069
+ alike, never on open, where the modal entrance already carries the
2070
+ motion), and clears it again once the cascade has played — see
2071
+ STEP_CASCADE_MS in multi-step/wizard.ts. That clear is load-bearing,
2072
+ not tidiness: search and filter hide cards with .lb-hidden
2073
+ (display: none), and restoring display restarts a card's animation,
2074
+ so a live attribute would replay the whole cascade on every
2075
+ keystroke that reveals a card.
2076
+
2077
+ Two elements deliberately hold still. The footer, because Back/Next
2078
+ are the shopper's anchor while everything above them moves. And the
2079
+ progress rail, because it is the one thing that answers "where am I
2080
+ now" — animating the shopper's only orientation cue is what made the
2081
+ previous version hard to read. Its segment fill carries its own
2082
+ state change already. */
2083
+ @keyframes lb-multi-step-cascade-fwd {
2084
+ from {
2085
+ opacity: 0;
2086
+ transform: translateY(10px);
2087
+ }
2088
+ }
2089
+
2090
+ @keyframes lb-multi-step-cascade-back {
2091
+ from {
2092
+ opacity: 0;
2093
+ transform: translateY(-10px);
2094
+ }
2095
+ }
2096
+
2097
+ .lb-mix-match__modal[data-step-transition] .lb-mix-match__modal-subtitle {
2098
+ animation: lb-multi-step-cascade-fwd 0.2s ease-out both;
2099
+ }
2100
+
2101
+ .lb-mix-match__modal[data-step-transition] .lb-mix-match__filters {
2102
+ animation: lb-multi-step-cascade-fwd 0.2s ease-out 0.05s both;
2103
+ }
2104
+
2105
+ /* Cards stagger 30ms apart, but only the first four: a step can hold
2106
+ dozens of products and the two-column grid shows about four at a
2107
+ time, so past that the stagger is below the fold and would only add
2108
+ lag. Everything from the fifth on shares the fourth's landing. */
2109
+ .lb-mix-match__modal[data-step-transition] .lb-mix-match__modal-list > * {
2110
+ animation: lb-multi-step-cascade-fwd 0.22s ease-out 0.2s both;
2111
+ }
2112
+
2113
+ .lb-mix-match__modal[data-step-transition] .lb-mix-match__modal-list > :nth-child(1) {
2114
+ animation-delay: 0.09s;
2115
+ }
2116
+
2117
+ .lb-mix-match__modal[data-step-transition] .lb-mix-match__modal-list > :nth-child(2) {
2118
+ animation-delay: 0.12s;
2119
+ }
2120
+
2121
+ .lb-mix-match__modal[data-step-transition] .lb-mix-match__modal-list > :nth-child(3) {
2122
+ animation-delay: 0.15s;
2123
+ }
2124
+
2125
+ .lb-mix-match__modal[data-step-transition] .lb-mix-match__modal-list > :nth-child(4) {
2126
+ animation-delay: 0.18s;
2127
+ }
2128
+
2129
+ /* Going back runs the same cascade in the same order — only the offset
2130
+ flips, so the shopper still reads which way they moved. Overrides
2131
+ the name alone; the staggered delays above must survive. */
2132
+ .lb-mix-match__modal[data-step-transition="back"] .lb-mix-match__modal-subtitle,
2133
+ .lb-mix-match__modal[data-step-transition="back"] .lb-mix-match__filters,
2134
+ .lb-mix-match__modal[data-step-transition="back"] .lb-mix-match__modal-list > * {
2135
+ animation-name: lb-multi-step-cascade-back;
2136
+ }
2137
+
2138
+ @keyframes lb-multi-step-cascade-fade {
2139
+ from {
2140
+ opacity: 0;
2141
+ }
2142
+ }
2143
+
2144
+ /* Reduced motion keeps the fade and drops the travel and the stagger:
2145
+ the step change still has to be perceptible, which is the whole
2146
+ point of this block. The card selector is :nth-child(n) rather than
2147
+ * on purpose — a plain * loses to the :nth-child(1..4) delays above
2148
+ on specificity, which would leave the stagger running with nothing
2149
+ moving. :nth-child(n) matches every child at equal specificity and
2150
+ wins on order. */
2151
+ @media (prefers-reduced-motion: reduce) {
2152
+ .lb-mix-match__modal[data-step-transition] .lb-mix-match__modal-subtitle,
2153
+ .lb-mix-match__modal[data-step-transition] .lb-mix-match__filters,
2154
+ .lb-mix-match__modal[data-step-transition] .lb-mix-match__modal-list > :nth-child(n) {
2155
+ animation: lb-multi-step-cascade-fade 0.15s ease-out both;
2156
+ }
2157
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lime-bundles/react",
3
- "version": "7.3.0",
3
+ "version": "7.4.0",
4
4
  "description": "React components and hooks for the Lime Bundles Shopify app. Use on Hydrogen, Next.js, Vite, or any React-based headless storefront.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -52,7 +52,7 @@
52
52
  "react-dom": ">=18.0.0"
53
53
  },
54
54
  "dependencies": {
55
- "@lime-bundles/core": "^7.3.0"
55
+ "@lime-bundles/core": "^7.4.0"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@shopify/hydrogen-react": "^2026.4.1",