@lime-bundles/react 5.0.0 → 6.1.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/LICENSE +21 -0
- package/README.md +1 -1
- package/dist/index.cjs +3292 -634
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +54 -11
- package/dist/index.d.ts +54 -11
- package/dist/index.js +3305 -611
- package/dist/index.js.map +1 -1
- package/docs/css-variables.md +50 -70
- package/docs/hydrogen.md +1 -1
- package/docs/react-nextjs.md +4 -2
- package/docs/web-component.md +1 -1
- package/package.json +3 -3
package/docs/css-variables.md
CHANGED
|
@@ -39,48 +39,43 @@ 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` |
|
|
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
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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-
|
|
60
|
-
| `--lb-
|
|
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-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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. |
|
|
70
|
+
| `--lb-product-unit-price-display` | `block` (shown) / `none` (hidden) | Toggle for the per-unit line (`$4.99/kg`) under a product's price. Separate from the bundle summary's per-item figure. |
|
|
71
|
+
| `--lb-product-qty-chip-display` | `inline-flex` (shown) / `none` (hidden) | Toggle for the fixed bundle's right-slot quantity chip. |
|
|
72
|
+
| `--lb-product-qty-inline-display` | `inline` (shown) / `none` (hidden) | Toggle for the inline `×N` count used by every other bundle type. |
|
|
73
|
+
|
|
74
|
+
Per-product quantity renders as inline `×N` text beside the price (no floating
|
|
75
|
+
count badge), using the widget's own `--lb-text`. The fixed bundle instead puts
|
|
76
|
+
its count in a chip in the row's right slot, which is why one merchant setting
|
|
77
|
+
drives two variables: the chip is a flex box and the inline count is text, so a
|
|
78
|
+
single "shown" value cannot serve both.
|
|
84
79
|
|
|
85
80
|
## CTA button
|
|
86
81
|
|
|
@@ -88,29 +83,24 @@ The variant dropdown is an accessible custom combobox (not a native `<select>`).
|
|
|
88
83
|
|---|---|---|
|
|
89
84
|
| `--lb-primary-color` | `#1A1A1A` | Button background. |
|
|
90
85
|
| `--lb-btn-text` | `#FFFFFF` | Button text. |
|
|
91
|
-
| `--lb-cta-border-color` | `#1A1A1A` | Border colour. |
|
|
86
|
+
| `--lb-cta-border-color` | `#1A1A1A` | Border colour. The button keeps its own border (the global border does not touch it). |
|
|
92
87
|
| `--lb-cta-border-width` | `0px` | Border width. |
|
|
93
|
-
| `--lb-cta-radius` | `12px` | Corner radius. |
|
|
94
88
|
|
|
95
|
-
## Savings
|
|
89
|
+
## Savings line
|
|
96
90
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
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. |
|
|
91
|
+
The "You save {amount} ({percent}%)" line sits beneath the receipt total. It is
|
|
92
|
+
quiet text with no colours of its own — it inherits the widget's `--lb-text`
|
|
93
|
+
(lime is reserved for the CTA). Toggle it via the `savingsBar.visible` config
|
|
94
|
+
field; there are no savings-line CSS variables.
|
|
104
95
|
|
|
105
96
|
## Volume tier cards
|
|
106
97
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
| `--lb-tier-selected-border-width` | `2px` | Border width for the active tier. |
|
|
98
|
+
Tier cards inherit the global border (`--lb-border` / `--lb-border-width`) and the
|
|
99
|
+
global corner radius (`--lb-radius`), so they have no dedicated border variables.
|
|
100
|
+
|
|
101
|
+
The selected tier is highlighted with a quiet neutral tint and a stronger
|
|
102
|
+
border derived from `--lb-text` (matching the mix & match in-bundle card), so it
|
|
103
|
+
has no dedicated CSS variables.
|
|
114
104
|
|
|
115
105
|
## "Most popular" badge (volume bundle)
|
|
116
106
|
|
|
@@ -120,7 +110,9 @@ The variant dropdown is an accessible custom combobox (not a native `<select>`).
|
|
|
120
110
|
| `--lb-popular-badge-text` | `#FFFFFF` | Badge text. |
|
|
121
111
|
| `--lb-popular-badge-border-color` | `#1A1A1A` | Badge border colour. |
|
|
122
112
|
| `--lb-popular-badge-border-width` | `0px` | Badge border width. |
|
|
123
|
-
|
|
113
|
+
|
|
114
|
+
The badge keeps its own border width + colour, but its corner radius follows the
|
|
115
|
+
global radius preset (the derived `--lb-radius-sm`).
|
|
124
116
|
|
|
125
117
|
## "Only X left" low-stock badge
|
|
126
118
|
|
|
@@ -135,34 +127,23 @@ Surfaces when a variant's `quantityAvailable` is at or below
|
|
|
135
127
|
|
|
136
128
|
## Mix-and-match picker modal
|
|
137
129
|
|
|
130
|
+
One "Borders" group drives every border inside the modal (the modal itself, the
|
|
131
|
+
search input, product tiles, the variant select, and the quantity stepper).
|
|
132
|
+
Thumbnails take the radius only (no border). The Add button keeps its own border
|
|
133
|
+
width + colour but shares the radius.
|
|
134
|
+
|
|
138
135
|
| Variable | Default | What it styles |
|
|
139
136
|
|---|---|---|
|
|
140
137
|
| `--lb-picker-bg` | `#FFFFFF` | Modal background. |
|
|
141
138
|
| `--lb-picker-text` | `#1A1A1A` | Modal text colour. |
|
|
142
|
-
| `--lb-picker-border-color` | `#E5E5E5` |
|
|
143
|
-
| `--lb-picker-border-width` | `
|
|
144
|
-
| `--lb-picker-radius` | `16px` |
|
|
145
|
-
| `--lb-picker-
|
|
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. |
|
|
139
|
+
| `--lb-picker-border-color` | `#E5E5E5` | Border colour for every element in the modal. |
|
|
140
|
+
| `--lb-picker-border-width` | `1px` | Border width for every element in the modal. |
|
|
141
|
+
| `--lb-picker-radius` | `16px` | Corner radius every element in the modal rounds to. |
|
|
142
|
+
| `--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
143
|
| `--lb-picker-add-bg` | `#1A1A1A` | Add-to-bundle button background. |
|
|
162
144
|
| `--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. |
|
|
145
|
+
| `--lb-picker-add-border-color` | `#1A1A1A` | Add-to-bundle button border colour (its own, not the modal Borders). |
|
|
146
|
+
| `--lb-picker-add-border-width` | `0px` | Add-to-bundle button border width (its own). |
|
|
166
147
|
|
|
167
148
|
## Internal variables (don't override)
|
|
168
149
|
|
|
@@ -170,7 +151,6 @@ These exist for internal composition and are not merchant-configurable. The CSS
|
|
|
170
151
|
|
|
171
152
|
- `--lb-thumbnail-bg`: placeholder background behind images.
|
|
172
153
|
- `--lb-widget-pad`: internal padding token.
|
|
173
|
-
- `--lb-progress-color`: volume progress bar accent.
|
|
174
154
|
- `--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
155
|
- `--lb-thumbnail-img-fit`: derived from `thumbnailRatio`. `cover` for the cropping presets, `contain` for `original`.
|
|
176
156
|
- `--lb-thumbnail-img-height`: derived from `thumbnailRatio`. `100%` for the cropping presets, `auto` for `original` so the image renders at its intrinsic ratio.
|
package/docs/hydrogen.md
CHANGED
|
@@ -27,7 +27,7 @@ PUBLIC_LIME_BUNDLES_TOKEN=<paste the generated token>
|
|
|
27
27
|
|
|
28
28
|
The variable is intentionally namespaced so it doesn't collide with the `PUBLIC_STOREFRONT_API_TOKEN` that Shopify's Headless app issues for your primary storefront. Lime Bundles uses its own Storefront Access Token, scoped to bundle metaobjects and product listings only.
|
|
29
29
|
|
|
30
|
-
Lime Bundles creates the token for you via Shopify's Admin API. No custom-app configuration needed (Shopify deprecated that flow on 2026-01-01). The token carries the read-only scopes `unauthenticated_read_metaobjects` and `
|
|
30
|
+
Lime Bundles creates the token for you via Shopify's Admin API. No custom-app configuration needed (Shopify deprecated that flow on 2026-01-01). The token carries the read-only scopes `unauthenticated_read_metaobjects`, `unauthenticated_read_product_listings` and `unauthenticated_read_product_inventory` and nothing else. To rotate, click **Regenerate** on the same page. It revokes the current token and issues a new one atomically.
|
|
31
31
|
|
|
32
32
|
## Getting a bundle GID
|
|
33
33
|
|
package/docs/react-nextjs.md
CHANGED
|
@@ -27,7 +27,7 @@ NEXT_PUBLIC_LIME_BUNDLES_TOKEN=<paste the generated token>
|
|
|
27
27
|
|
|
28
28
|
The variable is intentionally namespaced to `LIME_BUNDLES_` so it doesn't collide with the Storefront API token Shopify's own Headless app issues for your primary storefront. Lime Bundles uses its own Storefront Access Token, scoped to bundle metaobjects and product listings only.
|
|
29
29
|
|
|
30
|
-
The `NEXT_PUBLIC_` prefix (or `VITE_` for Vite) exposes the value to client bundles. Lime Bundles creates the token for you via Shopify's Admin API. No custom-app setup needed (Shopify deprecated that flow on 2026-01-01). The token is a read-only public Storefront Access Token with `unauthenticated_read_metaobjects` and `
|
|
30
|
+
The `NEXT_PUBLIC_` prefix (or `VITE_` for Vite) exposes the value to client bundles. Lime Bundles creates the token for you via Shopify's Admin API. No custom-app setup needed (Shopify deprecated that flow on 2026-01-01). The token is a read-only public Storefront Access Token with `unauthenticated_read_metaobjects`, `unauthenticated_read_product_listings` and `unauthenticated_read_product_inventory` scopes, safe to ship in client code. To rotate, click **Regenerate** in the admin. It atomically revokes the old token and issues a new one.
|
|
31
31
|
|
|
32
32
|
## Pick a rendering mode
|
|
33
33
|
|
|
@@ -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
|
-
|
|
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.
|
package/docs/web-component.md
CHANGED
|
@@ -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
|
|
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": "
|
|
3
|
+
"version": "6.1.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": "
|
|
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": "^
|
|
55
|
+
"@lime-bundles/core": "^6.2.0"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@shopify/hydrogen-react": "^2026.4.1",
|