@lime-bundles/react 5.0.0 → 6.0.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.
@@ -39,78 +39,62 @@ Merchants can set these (and any other CSS) via Lime Bundles admin → Settings
39
39
  | `--lb-text` | `#1A1A1A` | Base body text colour. |
40
40
  | `--lb-border` | `#E5E5E5` | Outer card border colour. |
41
41
  | `--lb-border-width` | `1px` | Outer card border width. |
42
- | `--lb-radius` | `12px` | Outer card corner radius. |
42
+ | `--lb-radius` | `12px` | Global corner radius. The merchant picks a preset (none / subtle / rounded / round) and every element derives its rounding from this value. |
43
43
 
44
44
  ## Header
45
45
 
46
- | Variable | Default | What it styles |
47
- |---|---|---|
48
- | `--lb-header-start` | `#C62828` | Gradient start (ignored when header style is `solid`). |
49
- | `--lb-header-end` | `#AD1457` | Gradient end. |
50
- | `--lb-header-bg` | *derived* | Final header background. Emitted as a solid colour or a gradient depending on the merchant's header-style pick. |
51
- | `--lb-header-text` | `#FFFFFF` | Header text colour. |
52
- | `--lb-countdown-bg` | `#FFF0F3` | Countdown badge background inside the header. |
53
- | `--lb-countdown-text` | `#C62828` | Countdown badge text colour. |
54
-
55
- ## Save badge
46
+ The bundle title renders as a plain section heading in the host theme's own
47
+ type, using `--lb-text`. There is no colored header band and no save-badge pill.
48
+ Only the countdown timer carries its own colours.
56
49
 
57
50
  | Variable | Default | What it styles |
58
51
  |---|---|---|
59
- | `--lb-save-badge-bg` | `#FFFFFF` | Background. |
60
- | `--lb-save-badge-text` | `#AD1457` | Text colour. |
61
- | `--lb-save-badge-border-color` | `#FFFFFF` | Border colour. |
62
- | `--lb-save-badge-border-width` | `0px` | Border width. |
63
- | `--lb-save-badge-radius` | `8px` | Corner radius. |
52
+ | `--lb-countdown-bg` | `#FFF0F3` | Countdown bar background. |
53
+ | `--lb-countdown-text` | `#C62828` | Countdown bar text colour. |
64
54
 
65
55
  ## Product list
66
56
 
57
+ Product thumbnails carry no border; they round to a tighter radius derived from
58
+ `--lb-radius`. The variant selector inherits the global `--lb-border` /
59
+ `--lb-border-width` and the same derived radius, so there are no per-element
60
+ border variables here.
61
+
67
62
  | Variable | Default | What it styles |
68
63
  |---|---|---|
69
- | `--lb-image-border-color` | `#E5E5E5` | Product thumbnail border. |
70
- | `--lb-image-border-width` | `0px` | Product thumbnail border width. |
71
- | `--lb-image-border-radius` | `8px` | Product thumbnail corner radius. |
72
- | `--lb-variant-border-color` | `#E5E5E5` | Variant selector border. |
73
- | `--lb-variant-border-width` | `1px` | Variant selector border width. |
74
- | `--lb-variant-radius` | `8px` | Variant selector corner radius. |
75
- | `--lb-variant-chevron` | *derived SVG data URL* | Chevron icon shown in the variant dropdown. Auto-coloured to match `--lb-variant-border-color`. |
76
-
77
- The variant dropdown is an accessible custom combobox (not a native `<select>`). Its open panel reuses `--lb-variant-border-color`, `--lb-variant-border-width`, and `--lb-variant-radius` for the panel border, `--lb-bg` for the panel background, `--lb-text` for option text and the 4px scrollbar thumb, and `--lb-primary-color` for the focus ring. No additional variables required — adjusting the border or text/background colour automatically restyles the open panel to match.
78
-
79
- | `--lb-qty-badge-bg` | `#1A1A1A` | Quantity badge background. |
80
- | `--lb-qty-badge-color` | `#FFFFFF` | Quantity badge text. |
81
- | `--lb-qty-badge-display` | `flex` (shown) / `none` (hidden) | Toggle; merchant config controls this. |
64
+ | `--lb-variant-chevron` | *derived SVG data URL* | Chevron icon shown in the variant dropdown. Auto-coloured to match `--lb-border`. |
65
+
66
+ The variant dropdown is an accessible custom combobox (not a native `<select>`). Its open panel reuses `--lb-border` and `--lb-border-width` for the panel border, `--lb-bg` for the panel background, `--lb-text` for option text and the scrollbar thumb, and `--lb-primary-color` for the focus ring. No additional variables required: adjusting the global border or text/background colour automatically restyles the open panel to match.
67
+
82
68
  | `--lb-product-price-display` | `block` (shown) / `none` (hidden) | Toggle. |
83
69
  | `--lb-product-compare-display` | `inline` (shown) / `none` (hidden) | Toggle. |
84
70
 
71
+ Per-product quantity renders as inline `×N` text beside the price (no floating
72
+ count badge), using the widget's own `--lb-text`.
73
+
85
74
  ## CTA button
86
75
 
87
76
  | Variable | Default | What it styles |
88
77
  |---|---|---|
89
78
  | `--lb-primary-color` | `#1A1A1A` | Button background. |
90
79
  | `--lb-btn-text` | `#FFFFFF` | Button text. |
91
- | `--lb-cta-border-color` | `#1A1A1A` | Border colour. |
80
+ | `--lb-cta-border-color` | `#1A1A1A` | Border colour. The button keeps its own border (the global border does not touch it). |
92
81
  | `--lb-cta-border-width` | `0px` | Border width. |
93
- | `--lb-cta-radius` | `12px` | Corner radius. |
94
82
 
95
- ## Savings bar
83
+ ## Savings line
96
84
 
97
- | Variable | Default | What it styles |
98
- |---|---|---|
99
- | `--lb-savings-bar-bg` | `#EDFBF1` | Bar background. |
100
- | `--lb-savings-bar-text` | `#2DB554` | Bar text colour. |
101
- | `--lb-savings-bar-border-color` | `#2DB554` | Border colour. |
102
- | `--lb-savings-bar-border-width` | `0px` | Border width. |
103
- | `--lb-savings-bar-radius` | `8px` | Corner radius. |
85
+ The "You save {amount} ({percent}%)" line sits beneath the receipt total. It is
86
+ quiet text with no colours of its own — it inherits the widget's `--lb-text`
87
+ (lime is reserved for the CTA). Toggle it via the `savingsBar.visible` config
88
+ field; there are no savings-line CSS variables.
104
89
 
105
90
  ## Volume tier cards
106
91
 
107
- | Variable | Default | What it styles |
108
- |---|---|---|
109
- | `--lb-tier-border-color` | `#E5E5E5` | Tier card border. |
110
- | `--lb-tier-border-width` | `1px` | Tier card border width. |
111
- | `--lb-tier-radius` | `12px` | Tier card corner radius. |
112
- | `--lb-tier-selected-border-color` | `#1A1A1A` | Border colour for the active tier. |
113
- | `--lb-tier-selected-border-width` | `2px` | Border width for the active tier. |
92
+ Tier cards inherit the global border (`--lb-border` / `--lb-border-width`) and the
93
+ global corner radius (`--lb-radius`), so they have no dedicated border variables.
94
+
95
+ The selected tier is highlighted with a quiet neutral tint and a stronger
96
+ border derived from `--lb-text` (matching the mix & match in-bundle card), so it
97
+ has no dedicated CSS variables.
114
98
 
115
99
  ## "Most popular" badge (volume bundle)
116
100
 
@@ -120,7 +104,9 @@ The variant dropdown is an accessible custom combobox (not a native `<select>`).
120
104
  | `--lb-popular-badge-text` | `#FFFFFF` | Badge text. |
121
105
  | `--lb-popular-badge-border-color` | `#1A1A1A` | Badge border colour. |
122
106
  | `--lb-popular-badge-border-width` | `0px` | Badge border width. |
123
- | `--lb-popular-badge-radius` | `12px` | Badge corner radius. |
107
+
108
+ The badge keeps its own border width + colour, but its corner radius follows the
109
+ global radius preset (the derived `--lb-radius-sm`).
124
110
 
125
111
  ## "Only X left" low-stock badge
126
112
 
@@ -135,34 +121,23 @@ Surfaces when a variant's `quantityAvailable` is at or below
135
121
 
136
122
  ## Mix-and-match picker modal
137
123
 
124
+ One "Borders" group drives every border inside the modal (the modal itself, the
125
+ search input, product tiles, the variant select, and the quantity stepper).
126
+ Thumbnails take the radius only (no border). The Add button keeps its own border
127
+ width + colour but shares the radius.
128
+
138
129
  | Variable | Default | What it styles |
139
130
  |---|---|---|
140
131
  | `--lb-picker-bg` | `#FFFFFF` | Modal background. |
141
132
  | `--lb-picker-text` | `#1A1A1A` | Modal text colour. |
142
- | `--lb-picker-border-color` | `#E5E5E5` | Modal outer border. |
143
- | `--lb-picker-border-width` | `0px` | Modal outer border width. |
144
- | `--lb-picker-radius` | `16px` | Modal corner radius. |
145
- | `--lb-picker-search-border-color` | `#E5E5E5` | Search input border. |
146
- | `--lb-picker-search-border-width` | `1px` | Search input border width. |
147
- | `--lb-picker-search-radius` | `8px` | Search input corner radius. |
148
- | `--lb-picker-product-border-color` | `#E5E5E5` | Product thumbnail border. |
149
- | `--lb-picker-product-border-width` | `0px` | Product thumbnail border width. |
150
- | `--lb-picker-product-radius` | `8px` | Product thumbnail corner radius. |
151
- | `--lb-picker-qty-badge-bg` | `#1A1A1A` | Picker quantity-badge background. |
152
- | `--lb-picker-qty-badge-color` | `#FFFFFF` | Picker quantity-badge text. |
153
- | `--lb-picker-qty-badge-display` | `flex` (shown) / `none` (hidden) | Toggle; picker quantity badge visibility. |
154
- | `--lb-picker-variant-border-color` | `#1A1A1A` | Variant select border. |
155
- | `--lb-picker-variant-border-width` | `1px` | Variant select border width. |
156
- | `--lb-picker-variant-radius` | `8px` | Variant select corner radius. |
157
- | `--lb-picker-variant-chevron` | *derived SVG data URL* | Chevron icon on the picker's variant dropdown. Auto-coloured to match `--lb-picker-variant-border-color`. |
158
- | `--lb-picker-qty-stepper-border-color` | `#1A1A1A` | Per-pick quantity stepper border. |
159
- | `--lb-picker-qty-stepper-border-width` | `1px` | Per-pick quantity stepper border width. |
160
- | `--lb-picker-qty-stepper-radius` | `8px` | Per-pick quantity stepper corner radius. |
133
+ | `--lb-picker-border-color` | `#E5E5E5` | Border colour for every element in the modal. |
134
+ | `--lb-picker-border-width` | `1px` | Border width for every element in the modal. |
135
+ | `--lb-picker-radius` | `16px` | Corner radius every element in the modal rounds to. |
136
+ | `--lb-picker-variant-chevron` | *derived SVG data URL* | Chevron icon on the picker's variant dropdown. Auto-coloured to match `--lb-picker-border-color`. |
161
137
  | `--lb-picker-add-bg` | `#1A1A1A` | Add-to-bundle button background. |
162
138
  | `--lb-picker-add-label` | `#FFFFFF` | Add-to-bundle button text. |
163
- | `--lb-picker-add-border-color` | `#1A1A1A` | Add-to-bundle button border colour. |
164
- | `--lb-picker-add-border-width` | `0px` | Add-to-bundle button border width. |
165
- | `--lb-picker-add-radius` | `8px` | Add-to-bundle button corner radius. |
139
+ | `--lb-picker-add-border-color` | `#1A1A1A` | Add-to-bundle button border colour (its own, not the modal Borders). |
140
+ | `--lb-picker-add-border-width` | `0px` | Add-to-bundle button border width (its own). |
166
141
 
167
142
  ## Internal variables (don't override)
168
143
 
@@ -170,7 +145,6 @@ These exist for internal composition and are not merchant-configurable. The CSS
170
145
 
171
146
  - `--lb-thumbnail-bg`: placeholder background behind images.
172
147
  - `--lb-widget-pad`: internal padding token.
173
- - `--lb-progress-color`: volume progress bar accent.
174
148
  - `--lb-thumbnail-aspect-ratio`: derived from the merchant's `thumbnailRatio` setting (`square`/`tall`/`wide`/`original`). `1 / 1`, `3 / 4`, `4 / 3`, or `auto`. Override only if you need a custom thumb shape that isn't one of the four presets.
175
149
  - `--lb-thumbnail-img-fit`: derived from `thumbnailRatio`. `cover` for the cropping presets, `contain` for `original`.
176
150
  - `--lb-thumbnail-img-height`: derived from `thumbnailRatio`. `100%` for the cropping presets, `auto` for `original` so the image renders at its intrinsic ratio.
@@ -357,7 +357,9 @@ import { injectCustomCss, sanitizeCustomCss } from "@lime-bundles/react";
357
357
  ```tsx
358
358
  import { validateQuantity } from "@lime-bundles/react";
359
359
 
360
- const { valid, message } = validateQuantity(selectedCount, bundle.minQuantity, bundle.maxQuantity);
360
+ // Pass the total units selected (sum of per-product quantities) — completion
361
+ // counts units, so one product at quantity 3 satisfies minQuantity: 3.
362
+ const { valid, message } = validateQuantity(totalUnits, bundle.minQuantity, bundle.maxQuantity);
361
363
  ```
362
364
 
363
365
  Anything the web component does, a developer importing from `@lime-bundles/react` can do too. The built-in components are one way to arrange these primitives; ship your own the moment you need a different one.
@@ -295,7 +295,7 @@ Every part of the widget a merchant configures in the admin is wired up for you:
295
295
  - **Countdown timer.** When a bundle has `endsAt`, the widget ticks a live countdown every second and hides the bar once the offer expires.
296
296
  - **Variant dropdowns on fixed bundles.** Products with multiple eligible variants (filtered by the merchant's `selectedVariantIds`) render a `<select>`; switching variants live-updates the row price and the bundle total.
297
297
  - **Mix-match picker modal.** Click any empty slot to open the modal; search, quantity stepper, progress bar, and pricing update as selections change. Keyboard: Escape closes, Tab traps inside the modal.
298
- - **Out-of-stock behaviour.** Honours `widgetConfig.outOfStockBehavior` (`"hide"` removes OOS products from the list; `"show_greyed_out"` renders them disabled). Fixed bundles hide the whole widget when required products are OOS; mix-match hides when the available count can't satisfy `minQuantity`.
298
+ - **Out-of-stock behaviour.** Honours `widgetConfig.outOfStockBehavior` (`"hide"` removes OOS products from the list; `"show_greyed_out"` renders them disabled). Fixed bundles hide the whole widget when required products are OOS; mix-match hides when the count of in-stock products falls below `minQuantity` (completion itself counts total units selected, not distinct products).
299
299
  - **A/B test assignment (link-group model).** When a bundle is the primary of an A/B test, the widget reads the link group's variant weights from `data-link-group-variants`, walks the cumulative FNV-1a weight distribution via `getLinkGroupAssignment`, and renders the assigned variant (which is a real Bundle with its own products, discount, and widget config — not an overlay). Cookie-persisted, consent-gated; honours Shopify's `customerPrivacy` framework or the SDK's `setConsent(true)` helper. Without consent the primary renders and no cookie is written.
300
300
  - **Impression + add-to-cart analytics.** Fire on visibility + CTA click regardless of whether the merchant takes over the cart via `preventDefault`. Disable by setting `analytics="false"` or omitting `app-url`.
301
301
  - **Purchase attribution.** The `orders/create` webhook ingests `bundle_purchased` events server-side from the `_lime_bundle_gid` cart attribute the widget adds automatically. No `checkout_completed` handler needed.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lime-bundles/react",
3
- "version": "5.0.0",
3
+ "version": "6.0.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",
@@ -32,7 +32,7 @@
32
32
  "url": "https://github.com/lime-app-dev/lime-bundles-app/issues"
33
33
  },
34
34
  "license": "MIT",
35
- "author": "lime-app-dev",
35
+ "author": "Lime App Dev (Pty) Ltd",
36
36
  "keywords": [
37
37
  "shopify",
38
38
  "bundles",
@@ -52,7 +52,7 @@
52
52
  "react-dom": ">=18.0.0"
53
53
  },
54
54
  "dependencies": {
55
- "@lime-bundles/core": "^5.0.0"
55
+ "@lime-bundles/core": "^6.0.0"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@shopify/hydrogen-react": "^2026.4.1",