@liquidcommerce/elements-sdk 2.7.24 → 2.7.26
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/README.md +20 -4
- package/dist/index.checkout.esm.js +8435 -7152
- package/dist/index.esm.js +13789 -11658
- package/dist/types/core/a11y/announcer.service.d.ts +16 -0
- package/dist/types/core/a11y/focus-manager.service.d.ts +21 -0
- package/dist/types/core/a11y/focusable.d.ts +5 -0
- package/dist/types/core/a11y/glyph-button.d.ts +8 -0
- package/dist/types/core/a11y/index.d.ts +5 -0
- package/dist/types/core/a11y/single-select.d.ts +16 -0
- package/dist/types/core/base-component.service.d.ts +2 -0
- package/dist/types/core/google-tag-manager.service.d.ts +1 -0
- package/dist/types/interfaces/configs/global.interface.d.ts +2 -0
- package/dist/types/modules/address/address-display.component.d.ts +3 -1
- package/dist/types/modules/address/address-input.component.d.ts +10 -1
- package/dist/types/modules/cart/components/cart-body.component.d.ts +1 -0
- package/dist/types/modules/cart/components/cart-item-quantity-price.component.d.ts +5 -0
- package/dist/types/modules/cart/components/cart-item.component.d.ts +6 -0
- package/dist/types/modules/checkout/components/checkout-completed.component.d.ts +2 -0
- package/dist/types/modules/checkout/components/checkout-item-quantity.component.d.ts +1 -0
- package/dist/types/modules/checkout/components/checkout-payment.component.d.ts +1 -0
- package/dist/types/modules/checkout/components/checkout-place-order-button.component.d.ts +2 -0
- package/dist/types/modules/product/components/components.d.ts +6 -1
- package/dist/types/modules/product/components/product-add-to-cart-section.component.d.ts +6 -1
- package/dist/types/modules/product/components/product-drawer.component.d.ts +6 -0
- package/dist/types/modules/product/components/product-image-carousel.component.d.ts +1 -0
- package/dist/types/modules/product/components/product-retailers-carousel.component.d.ts +1 -0
- package/dist/types/modules/product/components/product-retailers-popup-list.component.d.ts +5 -0
- package/dist/types/modules/product/product.commands.d.ts +2 -2
- package/dist/types/modules/product-list/components/card-components/product-price-and-personalization.d.ts +2 -1
- package/dist/types/modules/product-list/components/card-components/product-quantity-selector.d.ts +2 -1
- package/dist/types/modules/product-list/components/card-components/product-sizes-list.d.ts +1 -0
- package/dist/types/modules/product-list/components/filter-components/product-list-fulfillment-filter.d.ts +1 -0
- package/dist/types/modules/product-list/components/product-list-filters.component.d.ts +1 -0
- package/dist/types/modules/product-list/components/product-list-product-pre-cart.component.d.ts +2 -0
- package/dist/types/modules/product-list/product-list.commands.d.ts +1 -1
- package/dist/types/modules/product-list/product-list.component.d.ts +3 -0
- package/dist/types/modules/theme-provider/services/contrast-guard.service.d.ts +19 -0
- package/dist/types/modules/ui-components/alert/alert.component.d.ts +1 -1
- package/dist/types/modules/ui-components/buttons/buttons-open-cart.component.d.ts +5 -0
- package/dist/types/modules/ui-components/drawer/drawer.component.d.ts +14 -0
- package/dist/types/modules/ui-components/engraving/engraving-form.component.d.ts +2 -0
- package/dist/types/modules/ui-components/engraving/engraving-view.component.d.ts +1 -0
- package/dist/types/modules/ui-components/input/input.component.d.ts +5 -0
- package/dist/types/modules/ui-components/lce-element/lce-element.component.d.ts +9 -1
- package/dist/types/modules/ui-components/ui.commands.d.ts +3 -1
- package/dist/types/static/icon/arrow-right.icon.d.ts +1 -1
- package/dist/types/static/icon/bag.icon.d.ts +1 -1
- package/dist/types/static/icon/check.icon.d.ts +1 -1
- package/dist/types/static/icon/checkbox.icon.d.ts +1 -1
- package/dist/types/static/icon/chevron-down.icon.d.ts +1 -1
- package/dist/types/static/icon/chevron-left.icon.d.ts +1 -1
- package/dist/types/static/icon/chevron-up.icon.d.ts +1 -1
- package/dist/types/static/icon/close.icon.d.ts +1 -1
- package/dist/types/static/icon/error-info.icon.d.ts +1 -1
- package/dist/types/static/icon/filter.icon.d.ts +1 -1
- package/dist/types/static/icon/icon.a11y.d.ts +1 -0
- package/dist/types/static/icon/icon.types.d.ts +1 -0
- package/dist/types/static/icon/index.d.ts +1 -0
- package/dist/types/static/icon/info.icon.d.ts +1 -1
- package/dist/types/static/icon/loading-spinner.icon.d.ts +1 -1
- package/dist/types/static/icon/search.icon.d.ts +1 -1
- package/dist/types/static/icon/success.icon.d.ts +1 -1
- package/dist/types/static/icon/trash.icon.d.ts +1 -1
- package/dist/types/static/icon/warning.icon.d.ts +1 -1
- package/dist/types/utils/color-contrast.d.ts +16 -0
- package/docs/v1/README.md +3 -0
- package/docs/v1/api/actions/address-actions.md +1 -1
- package/docs/v1/api/actions/cart-actions.md +9 -2
- package/docs/v1/api/actions/checkout-actions.md +2 -0
- package/docs/v1/api/client.md +88 -9
- package/docs/v1/api/configuration.md +23 -0
- package/docs/v1/api/typescript-types.md +5 -1
- package/docs/v1/api/ui-helpers.md +2 -2
- package/docs/v1/getting-started/concepts.md +29 -10
- package/docs/v1/getting-started/installation.md +23 -2
- package/docs/v1/getting-started/quick-start.md +8 -3
- package/docs/v1/guides/accessibility.md +190 -0
- package/docs/v1/guides/address-component.md +3 -3
- package/docs/v1/guides/best-practices.md +1 -1
- package/docs/v1/guides/cart-component.md +35 -3
- package/docs/v1/guides/events.md +18 -5
- package/docs/v1/guides/product-component.md +6 -2
- package/docs/v1/guides/product-list-component.md +4 -5
- package/docs/v1/guides/theming.md +16 -1
- package/docs/v1/integration/vanilla-js.md +1 -1
- package/docs/v1/reference/analytics.md +108 -0
- package/docs/v1/reference/browser-support.md +3 -1
- package/docs/v1/reference/error-handling.md +9 -1
- package/docs/v1/reference/telemetry.md +85 -0
- package/docs/v1/reference/troubleshooting.md +1 -2
- package/package.json +44 -15
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { IconProps } from './icon.types';
|
|
2
|
-
export declare const CloseIcon: ({ width, height, className, color }: IconProps) => string;
|
|
2
|
+
export declare const CloseIcon: ({ width, height, className, color, label }: IconProps) => string;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { IconProps } from './icon.types';
|
|
2
|
-
export declare const ErrorInfoIcon: ({ width, height, className, color }: IconProps) => string;
|
|
2
|
+
export declare const ErrorInfoIcon: ({ width, height, className, color, label }: IconProps) => string;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { IconProps } from './icon.types';
|
|
2
|
-
export declare const FilterIcon: ({ width, height, className, color }: IconProps) => string;
|
|
2
|
+
export declare const FilterIcon: ({ width, height, className, color, label }: IconProps) => string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function iconA11yAttributes(label?: string): string;
|
|
@@ -7,6 +7,7 @@ export * from './chevron-left.icon';
|
|
|
7
7
|
export * from './chevron-up.icon';
|
|
8
8
|
export * from './close.icon';
|
|
9
9
|
export * from './error-info.icon';
|
|
10
|
+
export * from './icon.a11y';
|
|
10
11
|
export * from './icon.types';
|
|
11
12
|
export * from './info.icon';
|
|
12
13
|
export * from './loading-spinner.icon';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { IconProps } from './icon.types';
|
|
2
|
-
export declare const InfoIcon: ({ width, height, className, color }: IconProps) => string;
|
|
2
|
+
export declare const InfoIcon: ({ width, height, className, color, label }: IconProps) => string;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { IconProps } from './icon.types';
|
|
2
|
-
export declare const LoadingSpinnerIcon: ({ width, height, className, color }: IconProps) => string;
|
|
2
|
+
export declare const LoadingSpinnerIcon: ({ width, height, className, color, label }: IconProps) => string;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { IconProps } from './icon.types';
|
|
2
|
-
export declare const SearchIcon: ({ width, height, className, color }: IconProps) => string;
|
|
2
|
+
export declare const SearchIcon: ({ width, height, className, color, label }: IconProps) => string;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { IconProps } from './icon.types';
|
|
2
|
-
export declare const SuccessIcon: ({ width, height, className, color }: IconProps) => string;
|
|
2
|
+
export declare const SuccessIcon: ({ width, height, className, color, label }: IconProps) => string;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { IconProps } from './icon.types';
|
|
2
|
-
export declare const TrashIcon: ({ width, height, className, color }: IconProps) => string;
|
|
2
|
+
export declare const TrashIcon: ({ width, height, className, color, label }: IconProps) => string;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { IconProps } from './icon.types';
|
|
2
|
-
export declare const WarningIcon: ({ width, height, className, color }: IconProps) => string;
|
|
2
|
+
export declare const WarningIcon: ({ width, height, className, color, label }: IconProps) => string;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface IRgbColor {
|
|
2
|
+
r: number;
|
|
3
|
+
g: number;
|
|
4
|
+
b: number;
|
|
5
|
+
a: number;
|
|
6
|
+
}
|
|
7
|
+
export declare const TEXT_CONTRAST_MIN = 4.5;
|
|
8
|
+
export declare const NON_TEXT_CONTRAST_MIN = 3;
|
|
9
|
+
export declare function parseColor(value: string | null | undefined): IRgbColor | null;
|
|
10
|
+
export declare function toHexColor({ r, g, b }: IRgbColor): string;
|
|
11
|
+
export declare function compositeOver(foreground: IRgbColor, background: IRgbColor): IRgbColor;
|
|
12
|
+
export declare function relativeLuminance({ r, g, b }: IRgbColor): number;
|
|
13
|
+
export declare function contrastRatio(foreground: IRgbColor, background: IRgbColor): number;
|
|
14
|
+
export declare function meetsContrast(foreground: IRgbColor, background: IRgbColor, minRatio: number): boolean;
|
|
15
|
+
export declare function ensureContrast(foreground: IRgbColor, background: IRgbColor, minRatio: number): IRgbColor;
|
|
16
|
+
export declare function ensureContrastAgainstAll(foreground: IRgbColor, backgrounds: IRgbColor[], minRatio: number): IRgbColor;
|
package/docs/v1/README.md
CHANGED
|
@@ -32,6 +32,7 @@ In-depth guides for each major component:
|
|
|
32
32
|
- **[Address Component](./guides/address-component.md)** - Delivery location management
|
|
33
33
|
- **[Product List Component](./guides/product-list-component.md)** - Filterable product catalogs
|
|
34
34
|
- **[Theming](./guides/theming.md)** - Customize appearance and branding
|
|
35
|
+
- **[Accessibility](./guides/accessibility.md)** - Keyboard, screen reader, contrast and focus behaviour
|
|
35
36
|
- **[Events](./guides/events.md)** - Event system and subscriptions
|
|
36
37
|
- **[Best Practices](./guides/best-practices.md)** - Patterns, tips, and recommendations
|
|
37
38
|
|
|
@@ -83,6 +84,8 @@ Technical reference and troubleshooting:
|
|
|
83
84
|
- **[Troubleshooting](./reference/troubleshooting.md)** - Common issues and solutions
|
|
84
85
|
- **[Error Handling](./reference/error-handling.md)** - Error types and debugging
|
|
85
86
|
- **[Performance](./reference/performance.md)** - Optimization tips and best practices
|
|
87
|
+
- **[Analytics](./reference/analytics.md)** - Google Tag Manager / GA4 integration
|
|
88
|
+
- **[Telemetry](./reference/telemetry.md)** - What the SDK reports and how to control it
|
|
86
89
|
|
|
87
90
|
### Examples
|
|
88
91
|
|
|
@@ -169,11 +169,16 @@ applyPromoCode(promoCode: string): Promise<void>
|
|
|
169
169
|
### Example
|
|
170
170
|
|
|
171
171
|
```javascript
|
|
172
|
+
// Listen for the outcome — an invalid code surfaces here, not as a rejection
|
|
173
|
+
window.addEventListener('lce:actions.cart_promo_code_failed', (event) => {
|
|
174
|
+
console.error('Invalid promo code:', event.detail.data);
|
|
175
|
+
});
|
|
176
|
+
|
|
172
177
|
try {
|
|
173
178
|
await window.LiquidCommerce.elements.actions.cart.applyPromoCode('SUMMER20');
|
|
174
|
-
console.log('Promo code applied successfully');
|
|
175
179
|
} catch (error) {
|
|
176
|
-
|
|
180
|
+
// Only reached on unexpected errors, not for an invalid code
|
|
181
|
+
console.error('Failed to apply promo code:', error);
|
|
177
182
|
}
|
|
178
183
|
```
|
|
179
184
|
|
|
@@ -183,6 +188,8 @@ try {
|
|
|
183
188
|
- Promo codes must be enabled in configuration
|
|
184
189
|
- Only one promo code can be active at a time
|
|
185
190
|
- Applying a new code replaces the existing one
|
|
191
|
+
- An invalid/rejected code does **not** reject the promise — the failure is surfaced via the `lce:actions.cart_promo_code_failed` event. Listen for that event to handle invalid codes.
|
|
192
|
+
- An empty or whitespace-only code is a silent no-op: it sets a `cart.error` on the store and returns without throwing.
|
|
186
193
|
|
|
187
194
|
---
|
|
188
195
|
|
|
@@ -4,6 +4,8 @@ Checkout actions allow you to programmatically control the checkout flow.
|
|
|
4
4
|
|
|
5
5
|
## Navigation Actions
|
|
6
6
|
|
|
7
|
+
> **Note:** `openCheckout()`, `closeCheckout()`, and `toggleCheckout()` are only available on the full `Elements()` client's `actions.checkout`. They are **not** present on the checkout-only client (`ElementsCheckout()`), whose `actions.checkout` is typed `IElementsCheckoutActions = Omit<ICheckoutActions, 'openCheckout' | 'closeCheckout' | 'toggleCheckout'>`. The remaining checkout actions are available on both clients.
|
|
8
|
+
|
|
7
9
|
### actions.checkout.openCheckout()
|
|
8
10
|
|
|
9
11
|
```typescript
|
package/docs/v1/api/client.md
CHANGED
|
@@ -11,7 +11,7 @@ Initialize the full SDK client.
|
|
|
11
11
|
```typescript
|
|
12
12
|
function Elements(
|
|
13
13
|
apiKey: string,
|
|
14
|
-
config
|
|
14
|
+
config?: ILiquidCommerceElementsConfig
|
|
15
15
|
): Promise<ILiquidCommerceElementsClient | null>
|
|
16
16
|
```
|
|
17
17
|
|
|
@@ -20,7 +20,7 @@ function Elements(
|
|
|
20
20
|
| Parameter | Type | Required | Description |
|
|
21
21
|
|-----------|-------------------------------|----------|-----------------------------|
|
|
22
22
|
| `apiKey` | string | Yes | Your LiquidCommerce API key |
|
|
23
|
-
| `config` | ILiquidCommerceElementsConfig |
|
|
23
|
+
| `config` | ILiquidCommerceElementsConfig | No | Configuration object |
|
|
24
24
|
|
|
25
25
|
**Returns:** Promise that resolves to the client instance, or `null` if initialization fails.
|
|
26
26
|
|
|
@@ -43,7 +43,7 @@ Initialize the checkout-only client (tree-shaken build).
|
|
|
43
43
|
```typescript
|
|
44
44
|
function ElementsCheckout(
|
|
45
45
|
apiKey: string,
|
|
46
|
-
config
|
|
46
|
+
config?: ILiquidCommerceElementsCheckoutClientConfig
|
|
47
47
|
): Promise<IElementsCheckoutClient | null>
|
|
48
48
|
```
|
|
49
49
|
|
|
@@ -52,7 +52,7 @@ function ElementsCheckout(
|
|
|
52
52
|
| Parameter | Type | Required | Description |
|
|
53
53
|
|-----------|---------------------------------------------|----------|-----------------------------|
|
|
54
54
|
| `apiKey` | string | Yes | Your LiquidCommerce API key |
|
|
55
|
-
| `config` | ILiquidCommerceElementsCheckoutClientConfig |
|
|
55
|
+
| `config` | ILiquidCommerceElementsCheckoutClientConfig | No | Checkout configuration |
|
|
56
56
|
|
|
57
57
|
**Example:**
|
|
58
58
|
|
|
@@ -71,7 +71,7 @@ Initialize the builder client, which exposes manual `inject*` / `update*` method
|
|
|
71
71
|
```typescript
|
|
72
72
|
function ElementsBuilder(
|
|
73
73
|
apiKey: string,
|
|
74
|
-
config
|
|
74
|
+
config?: ILiquidCommerceElementsBuilderConfig
|
|
75
75
|
): Promise<ILiquidCommerceElementsBuilderClient | null>
|
|
76
76
|
```
|
|
77
77
|
|
|
@@ -80,7 +80,7 @@ function ElementsBuilder(
|
|
|
80
80
|
| Parameter | Type | Required | Description |
|
|
81
81
|
|-----------|--------------------------------------|----------|-----------------------------|
|
|
82
82
|
| `apiKey` | string | Yes | Your LiquidCommerce API key |
|
|
83
|
-
| `config` | ILiquidCommerceElementsBuilderConfig |
|
|
83
|
+
| `config` | ILiquidCommerceElementsBuilderConfig | No | Builder configuration object (same shape as `ILiquidCommerceElementsConfig`) |
|
|
84
84
|
|
|
85
85
|
**Returns:** Promise that resolves to the builder client instance (`ILiquidCommerceElementsBuilderClient`), or `null` if initialization fails or it is called outside the browser.
|
|
86
86
|
|
|
@@ -256,7 +256,7 @@ window.addEventListener('lce:actions.client_ready', ( event ) => {
|
|
|
256
256
|
|
|
257
257
|
// Safe to use client
|
|
258
258
|
window.LiquidCommerce.elements.injectProductElement([...]);
|
|
259
|
-
});
|
|
259
|
+
}, { once: true });
|
|
260
260
|
```
|
|
261
261
|
|
|
262
262
|
## Client Interface
|
|
@@ -296,6 +296,84 @@ interface ILiquidCommerceElementsClient {
|
|
|
296
296
|
}
|
|
297
297
|
```
|
|
298
298
|
|
|
299
|
+
### ILiquidCommerceElementsBuilderClient
|
|
300
|
+
|
|
301
|
+
The builder client (returned by `ElementsBuilder()`) exposes the same `inject*` methods plus a set of `update*Component` methods for applying theme/layout changes at runtime:
|
|
302
|
+
|
|
303
|
+
```typescript
|
|
304
|
+
interface ILiquidCommerceElementsBuilderClient {
|
|
305
|
+
// Runtime theme/layout updates (builder-only)
|
|
306
|
+
updateComponentGlobalConfigs(configs: UpdateComponentGlobalConfigs): Promise<void>;
|
|
307
|
+
updateProductComponent(configs: UpdateProductComponent): Promise<void>;
|
|
308
|
+
updateAddressComponent(configs: UpdateAddressComponent): void;
|
|
309
|
+
updateCartComponent(configs: UpdateCartComponent): void;
|
|
310
|
+
updateCheckoutComponent(configs: UpdateCheckoutComponent): void;
|
|
311
|
+
updateProductListComponent(configs: UpdateProductListComponent): void;
|
|
312
|
+
|
|
313
|
+
// Injection methods
|
|
314
|
+
injectElement(params: IBuilderInjectElementParams): Promise<IInjectedComponent | null>;
|
|
315
|
+
injectProductElement(params: IInjectProductElement[]): Promise<IInjectedComponent[]>;
|
|
316
|
+
injectAddressElement(containerId: string, options?: IAddressOptions): Promise<IInjectedComponent | null>;
|
|
317
|
+
injectCartElement(containerId: string): Promise<IInjectedComponent | null>;
|
|
318
|
+
injectCheckoutElement(params: IInjectCheckoutBuilderParams): Promise<IInjectedComponent | null>;
|
|
319
|
+
injectProductList(params: IInjectProductListParams): Promise<void>;
|
|
320
|
+
|
|
321
|
+
// Actions
|
|
322
|
+
actions: ILiquidCommerceElementsActions;
|
|
323
|
+
|
|
324
|
+
// Cleanup
|
|
325
|
+
destroy(): void;
|
|
326
|
+
}
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
#### Runtime theme updates (`update*Component`)
|
|
330
|
+
|
|
331
|
+
These methods are **builder-only** — they exist on the client returned by `ElementsBuilder()` and are **not** available on the full `Elements()` client. Each method applies theme changes to its scope and, when the passed `configs` include a non-empty `layout`, triggers targeted rerenders of only the components affected by those layout fields.
|
|
332
|
+
|
|
333
|
+
Return types are not uniform:
|
|
334
|
+
|
|
335
|
+
- `updateComponentGlobalConfigs()` and `updateProductComponent()` return `Promise<void>` (they may await product rerenders) — `await` them.
|
|
336
|
+
- `updateCartComponent()`, `updateCheckoutComponent()`, `updateAddressComponent()`, and `updateProductListComponent()` return `void` (synchronous).
|
|
337
|
+
|
|
338
|
+
```javascript
|
|
339
|
+
const builder = await ElementsBuilder('YOUR_API_KEY', { env: 'production' });
|
|
340
|
+
|
|
341
|
+
// Asynchronous — await these
|
|
342
|
+
await builder.updateComponentGlobalConfigs({
|
|
343
|
+
theme: { primaryColor: '#0a7d33', buttonCornerRadius: '8px' },
|
|
344
|
+
layout: { allowPromoCodes: true }
|
|
345
|
+
});
|
|
346
|
+
await builder.updateProductComponent({
|
|
347
|
+
theme: { backgroundColor: '#ffffff' },
|
|
348
|
+
layout: { addToCartButtonText: 'Add to bag' }
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
// Synchronous — no await needed
|
|
352
|
+
builder.updateCartComponent({ layout: { drawerHeaderText: 'Your bag' } });
|
|
353
|
+
builder.updateCheckoutComponent({ layout: { placeOrderButtonText: 'Pay now' } });
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
#### injectCheckoutElement (builder)
|
|
357
|
+
|
|
358
|
+
The builder's `injectCheckoutElement()` accepts `IInjectCheckoutBuilderParams`, which extends `IInjectCheckoutParams` with two **preview-only** fields:
|
|
359
|
+
|
|
360
|
+
```typescript
|
|
361
|
+
interface IInjectCheckoutBuilderParams extends IInjectCheckoutParams {
|
|
362
|
+
simulatePresale?: boolean; // simulate a presale lock in builder mode
|
|
363
|
+
presaleExpiresInMinutes?: number; // minutes until the simulated lock expires (defaults to 15)
|
|
364
|
+
}
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
`simulatePresale` and `presaleExpiresInMinutes` only take effect in the builder preview and have no counterpart on the full `Elements()` client's `injectCheckoutElement()`.
|
|
368
|
+
|
|
369
|
+
```javascript
|
|
370
|
+
await builder.injectCheckoutElement({
|
|
371
|
+
containerId: 'checkout',
|
|
372
|
+
simulatePresale: true,
|
|
373
|
+
presaleExpiresInMinutes: 30
|
|
374
|
+
});
|
|
375
|
+
```
|
|
376
|
+
|
|
299
377
|
## Methods Overview
|
|
300
378
|
|
|
301
379
|
### Injection Methods
|
|
@@ -410,7 +488,8 @@ const config: ILiquidCommerceElementsConfig = {
|
|
|
410
488
|
env: 'production'
|
|
411
489
|
};
|
|
412
490
|
|
|
413
|
-
|
|
491
|
+
// Elements() resolves to `null` on failure, so the type is nullable.
|
|
492
|
+
const client: ILiquidCommerceElementsClient | null = await Elements('KEY', config);
|
|
414
493
|
```
|
|
415
494
|
|
|
416
495
|
### Type Exports
|
|
@@ -488,7 +567,7 @@ if (window.LiquidCommerce?.elements) {
|
|
|
488
567
|
// Wait for client ready
|
|
489
568
|
window.addEventListener('lce:actions.client_ready', () => {
|
|
490
569
|
window.LiquidCommerce.elements.actions.cart.openCart();
|
|
491
|
-
});
|
|
570
|
+
}, { once: true });
|
|
492
571
|
}
|
|
493
572
|
```
|
|
494
573
|
|
|
@@ -30,6 +30,8 @@ interface ILiquidCommerceElementsConfig {
|
|
|
30
30
|
| `proxy` | `IElementsProxyConfig` | No | Proxy configuration for API requests |
|
|
31
31
|
| `development` | `ILiquidCommerceElementsDevelopmentConfig` | No | Development/testing options |
|
|
32
32
|
|
|
33
|
+
> **Note:** `debugMode` (`'console'` or `'panel'`) is **ignored in production** -- it is forced off when `env` is `'production'`. It only takes effect in non-production environments (`'development'` / `'staging'`).
|
|
34
|
+
|
|
33
35
|
---
|
|
34
36
|
|
|
35
37
|
## Theme Configuration
|
|
@@ -72,9 +74,22 @@ interface IGlobalTheme {
|
|
|
72
74
|
warningColor: string;
|
|
73
75
|
successColor: string;
|
|
74
76
|
drawerBackgroundColor: string;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Boundary color for form fields. Optional; defaults to a neutral that clears the 3:1
|
|
80
|
+
* contrast required by WCAG 1.4.11.
|
|
81
|
+
*/
|
|
82
|
+
inputBorderColor?: string;
|
|
83
|
+
|
|
84
|
+
/** Keyboard focus ring color. Must reach 3:1 against the surface behind the control. */
|
|
85
|
+
focusRingColor?: string;
|
|
75
86
|
}
|
|
76
87
|
```
|
|
77
88
|
|
|
89
|
+
> `inputBorderColor` and `focusRingColor` are optional. If you omit them — or supply a value that
|
|
90
|
+
> fails contrast — the runtime contrast guard substitutes a compliant color. Set them explicitly to
|
|
91
|
+
> keep those two details on-brand. See [Accessibility](../guides/accessibility.md).
|
|
92
|
+
|
|
78
93
|
| Property | Type | Description |
|
|
79
94
|
|----------|------|-------------|
|
|
80
95
|
| `buttonCornerRadius` | `string` | CSS border-radius for buttons (e.g., `'8px'`) |
|
|
@@ -100,6 +115,8 @@ interface IFontFamily {
|
|
|
100
115
|
}
|
|
101
116
|
```
|
|
102
117
|
|
|
118
|
+
> **Note:** Only Google Fonts are supported -- `name` must be a valid Google Fonts family. `Poppins` is always injected as the default font family in addition to any fonts you specify. Font loading requires network access to `fonts.googleapis.com` and `fonts.gstatic.com`; if you run behind a CSP or proxy, allow these hosts.
|
|
119
|
+
|
|
103
120
|
#### IGlobalLayout
|
|
104
121
|
|
|
105
122
|
```typescript
|
|
@@ -109,6 +126,8 @@ interface IGlobalLayout {
|
|
|
109
126
|
personalizationCardStyle: 'outlined' | 'filled';
|
|
110
127
|
allowPromoCodes: boolean;
|
|
111
128
|
inputFieldStyle: 'outlined' | 'filled';
|
|
129
|
+
enableOrderedProductSizes: boolean;
|
|
130
|
+
orderedProductSizes: string[];
|
|
112
131
|
showPoweredBy: boolean;
|
|
113
132
|
poweredByMode: 'light' | 'dark';
|
|
114
133
|
}
|
|
@@ -121,9 +140,13 @@ interface IGlobalLayout {
|
|
|
121
140
|
| `personalizationCardStyle` | `'outlined' \| 'filled'` | Visual style for personalization cards |
|
|
122
141
|
| `allowPromoCodes` | `boolean` | Show promo code inputs in cart/checkout |
|
|
123
142
|
| `inputFieldStyle` | `'outlined' \| 'filled'` | Visual style for input fields |
|
|
143
|
+
| `enableOrderedProductSizes` | `boolean` | Enable a fixed display order for product/PLC size selectors (defined by `orderedProductSizes`) instead of the default ordering |
|
|
144
|
+
| `orderedProductSizes` | `string[]` | Ordered list of size values controlling the sequence in which size selectors are rendered; changes trigger targeted rerenders of the affected size selectors |
|
|
124
145
|
| `showPoweredBy` | `boolean` | Show "Powered by LiquidCommerce" badge |
|
|
125
146
|
| `poweredByMode` | `'light' \| 'dark'` | Color mode for the powered-by badge |
|
|
126
147
|
|
|
148
|
+
> **Note:** `showPoweredBy` is a server/plan-controlled setting and **cannot** be overridden by hosts. Any value supplied via `customTheme` (or a later config update) is stripped and the server value is restored. Only `poweredByMode` (`'light' \| 'dark'`) is host-overridable.
|
|
149
|
+
|
|
127
150
|
**Example:**
|
|
128
151
|
|
|
129
152
|
```javascript
|
|
@@ -178,6 +178,8 @@ interface IInjectCheckoutParams {
|
|
|
178
178
|
|
|
179
179
|
### IInjectCheckoutBuilderParams
|
|
180
180
|
|
|
181
|
+
`simulatePresale` and `presaleExpiresInMinutes` are builder-only preview controls (presale lock defaults to 15 minutes) and only take effect via `ElementsBuilder().injectCheckoutElement()`.
|
|
182
|
+
|
|
181
183
|
```typescript
|
|
182
184
|
interface IInjectCheckoutBuilderParams extends IInjectCheckoutParams {
|
|
183
185
|
simulatePresale?: boolean;
|
|
@@ -293,7 +295,7 @@ interface ILiquidCommerceElementsActions {
|
|
|
293
295
|
|
|
294
296
|
### IElementsCheckoutActions
|
|
295
297
|
|
|
296
|
-
Checkout actions available in the checkout-only client.
|
|
298
|
+
Checkout actions available in the checkout-only client. This is `ICheckoutActions` with `openCheckout`, `closeCheckout`, and `toggleCheckout` omitted -- the checkout-only client renders checkout independently and has no drawer navigation to open, close, or toggle.
|
|
297
299
|
|
|
298
300
|
```typescript
|
|
299
301
|
interface IElementsCheckoutActions extends Omit<ICheckoutActions, 'openCheckout' | 'closeCheckout' | 'toggleCheckout'> {}
|
|
@@ -378,6 +380,8 @@ interface UpdateProductListComponent {
|
|
|
378
380
|
}
|
|
379
381
|
```
|
|
380
382
|
|
|
383
|
+
These `Update*Component` types are the arguments to the `ElementsBuilder()` client's `update*Component` methods; see [Client API](./client.md) for their behavior and usage.
|
|
384
|
+
|
|
381
385
|
See [Configuration Reference](./configuration.md) for detailed theme property descriptions.
|
|
382
386
|
|
|
383
387
|
---
|
|
@@ -136,7 +136,7 @@ window.LiquidCommerce.elements.ui.cartItemsCount('items-count', { hideZero: fals
|
|
|
136
136
|
<script>
|
|
137
137
|
window.addEventListener('lce:actions.client_ready', () => {
|
|
138
138
|
window.LiquidCommerce.elements.ui.cartButton('cart-btn', true);
|
|
139
|
-
});
|
|
139
|
+
}, { once: true });
|
|
140
140
|
</script>
|
|
141
141
|
```
|
|
142
142
|
|
|
@@ -153,7 +153,7 @@ window.addEventListener('lce:actions.client_ready', () => {
|
|
|
153
153
|
window.addEventListener('lce:actions.client_ready', () => {
|
|
154
154
|
window.LiquidCommerce.elements.ui.cartItemsCount('item-count');
|
|
155
155
|
window.LiquidCommerce.elements.ui.cartSubtotal('cart-total');
|
|
156
|
-
});
|
|
156
|
+
}, { once: true });
|
|
157
157
|
</script>
|
|
158
158
|
```
|
|
159
159
|
|
|
@@ -96,11 +96,11 @@ The SDK uses a two-phase initialization strategy for optimal performance:
|
|
|
96
96
|
- Store initialization
|
|
97
97
|
- Theme setup
|
|
98
98
|
- Core component registration
|
|
99
|
-
- Telemetry / logger wiring
|
|
99
|
+
- Telemetry / logger wiring (see [Telemetry & Privacy](../reference/telemetry.md))
|
|
100
100
|
- Debug panel (if enabled)
|
|
101
101
|
|
|
102
102
|
**Phase 2: Deferred Services (next macrotask, via `setTimeout(…, 0)`)**
|
|
103
|
-
- Analytics (Google Tag Manager)
|
|
103
|
+
- Analytics (Google Tag Manager — see [Analytics (GTM/GA4)](../reference/analytics.md))
|
|
104
104
|
- Cart pre-loading
|
|
105
105
|
- Heavy component registration
|
|
106
106
|
|
|
@@ -117,7 +117,7 @@ window.addEventListener('lce:actions.client_ready', (event) => {
|
|
|
117
117
|
|
|
118
118
|
// Safe to use client
|
|
119
119
|
window.LiquidCommerce.elements.actions.cart.openCart();
|
|
120
|
-
});
|
|
120
|
+
}, { once: true });
|
|
121
121
|
```
|
|
122
122
|
|
|
123
123
|
## Declarative vs Programmatic
|
|
@@ -197,7 +197,7 @@ window.addEventListener('lce:actions.client_ready', async () => {
|
|
|
197
197
|
await window.LiquidCommerce.elements.injectProductElement([
|
|
198
198
|
{ containerId: 'dynamic-product', identifier: selectedProductId }
|
|
199
199
|
]);
|
|
200
|
-
});
|
|
200
|
+
}, { once: true });
|
|
201
201
|
</script>
|
|
202
202
|
```
|
|
203
203
|
|
|
@@ -327,20 +327,37 @@ The SDK is designed to fail gracefully and not crash your site.
|
|
|
327
327
|
|
|
328
328
|
### Error Isolation
|
|
329
329
|
|
|
330
|
-
|
|
330
|
+
Most action failures are **not** thrown. Action methods take one of three paths, so `try/catch`
|
|
331
|
+
alone is not enough to detect failure:
|
|
332
|
+
|
|
333
|
+
| Situation | Behaviour |
|
|
334
|
+
|---|---|
|
|
335
|
+
| Malformed argument (missing `identifier`, invalid `fulfillmentType`, `quantity < 1`) | Throws `SDKError` — `try/catch` catches it |
|
|
336
|
+
| Empty array or no arguments | Logs a warning and **resolves**. No event, no throw. |
|
|
337
|
+
| Valid input that fails at runtime (product not found, unavailable variant, API error) | Publishes `lce:actions.cart_product_add_failed` and **resolves** |
|
|
338
|
+
|
|
339
|
+
So listen for the `*_failed` event **and** wrap the call in `try/catch`:
|
|
331
340
|
|
|
332
341
|
```javascript
|
|
333
|
-
|
|
342
|
+
window.addEventListener('lce:actions.cart_product_add_failed', (event) => {
|
|
343
|
+
console.log('Add to cart failed:', event.detail.data);
|
|
344
|
+
});
|
|
345
|
+
|
|
334
346
|
try {
|
|
335
|
-
|
|
347
|
+
// Throws only if the argument itself is malformed.
|
|
348
|
+
await window.LiquidCommerce.elements.actions.cart.addProduct([
|
|
349
|
+
{ identifier: '00619947000020', fulfillmentType: 'shipping', quantity: 1 }
|
|
350
|
+
]);
|
|
336
351
|
} catch (error) {
|
|
337
|
-
console.log('
|
|
352
|
+
console.log('Malformed input rejected by the SDK');
|
|
338
353
|
}
|
|
339
354
|
|
|
340
|
-
//
|
|
355
|
+
// Either way, your page keeps working
|
|
341
356
|
console.log('Page still functional');
|
|
342
357
|
```
|
|
343
358
|
|
|
359
|
+
See [Error Handling](../reference/error-handling.md) for the full matrix.
|
|
360
|
+
|
|
344
361
|
### Error Types
|
|
345
362
|
|
|
346
363
|
The SDK uses a custom `SDKError` class for all errors:
|
|
@@ -368,10 +385,12 @@ const client = await Elements('YOUR_API_KEY', {
|
|
|
368
385
|
```
|
|
369
386
|
|
|
370
387
|
**Debug Modes:**
|
|
371
|
-
- `'none'` - No debug output (
|
|
388
|
+
- `'none'` - No debug output (default)
|
|
372
389
|
- `'console'` - Log to browser console
|
|
373
390
|
- `'panel'` - Show debug panel on page
|
|
374
391
|
|
|
392
|
+
> **Production note:** `debugMode` has no effect when `env` is `'production'`. All debug output — console logging and the debug panel — is disabled in production regardless of the `debugMode` you pass. `'console'` and `'panel'` only take effect in non-production environments.
|
|
393
|
+
|
|
375
394
|
## Security & API Keys
|
|
376
395
|
|
|
377
396
|
### API Key Protection
|
|
@@ -30,6 +30,16 @@ Add the following script tag to your page's `<head>` section:
|
|
|
30
30
|
></script>
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
+
> **Note:** The host `elements.reservebar-worker.workers.dev` shown above is an example, partner-specific endpoint. Use the CDN URL provided by your LiquidCommerce representative in place of this host.
|
|
34
|
+
|
|
35
|
+
The path segment selects which bundle is served:
|
|
36
|
+
|
|
37
|
+
| Path | Bundle |
|
|
38
|
+
|------|--------|
|
|
39
|
+
| `/all/elements.js` | Full SDK bundle (product, cart, checkout, and all other elements) |
|
|
40
|
+
| `/checkout/checkout.js` | Checkout-only bundle (tree-shaken, smaller) |
|
|
41
|
+
| `/all/beta/elements.js` | Beta channel of the full SDK bundle |
|
|
42
|
+
|
|
33
43
|
### Script Attributes
|
|
34
44
|
|
|
35
45
|
| Attribute | Required | Description |
|
|
@@ -77,7 +87,7 @@ If you only need checkout functionality (without product displays or cart), use
|
|
|
77
87
|
data-token="YOUR_API_KEY"
|
|
78
88
|
data-env="production"
|
|
79
89
|
type="text/javascript"
|
|
80
|
-
src="https://elements.reservebar-worker.workers.dev/checkout/
|
|
90
|
+
src="https://elements.reservebar-worker.workers.dev/checkout/checkout.js"
|
|
81
91
|
></script>
|
|
82
92
|
```
|
|
83
93
|
|
|
@@ -140,7 +150,16 @@ const config: ILiquidCommerceElementsConfig = {
|
|
|
140
150
|
}
|
|
141
151
|
};
|
|
142
152
|
|
|
143
|
-
|
|
153
|
+
// Elements() returns `null` in SSR / non-browser environments, so the
|
|
154
|
+
// client is typed as `ILiquidCommerceElementsClient | null`.
|
|
155
|
+
const client: ILiquidCommerceElementsClient | null = await Elements('YOUR_API_KEY', config);
|
|
156
|
+
|
|
157
|
+
if (client) {
|
|
158
|
+
// Safe to use the client here
|
|
159
|
+
client.injectProductElement([
|
|
160
|
+
{ containerId: 'product-1', identifier: '00619947000020' }
|
|
161
|
+
]);
|
|
162
|
+
}
|
|
144
163
|
```
|
|
145
164
|
|
|
146
165
|
## Framework Integration
|
|
@@ -255,6 +274,8 @@ const client = await Elements('YOUR_API_KEY', {
|
|
|
255
274
|
});
|
|
256
275
|
```
|
|
257
276
|
|
|
277
|
+
> **Note:** `debugMode` is ignored when `env` is `'production'`. Debug logging and the debug panel are only activated in non-production environments (`development` or `staging`).
|
|
278
|
+
|
|
258
279
|
See [Configuration Reference](../api/configuration.md) for complete configuration options.
|
|
259
280
|
|
|
260
281
|
## Verification
|
|
@@ -165,7 +165,7 @@ If you prefer JavaScript over HTML attributes:
|
|
|
165
165
|
identifier: '00619947000020'
|
|
166
166
|
}
|
|
167
167
|
]);
|
|
168
|
-
});
|
|
168
|
+
}, { once: true });
|
|
169
169
|
</script>
|
|
170
170
|
</head>
|
|
171
171
|
<body>
|
|
@@ -181,10 +181,15 @@ Or with NPM:
|
|
|
181
181
|
import { Elements } from '@liquidcommerce/elements-sdk';
|
|
182
182
|
|
|
183
183
|
async function initProduct() {
|
|
184
|
+
// Elements() resolves to `null` if initialization fails — it never throws.
|
|
184
185
|
const client = await Elements('YOUR_API_KEY', {
|
|
185
186
|
env: 'production'
|
|
186
187
|
});
|
|
187
|
-
|
|
188
|
+
|
|
189
|
+
if (!client) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
|
|
188
193
|
await client.injectProductElement([
|
|
189
194
|
{
|
|
190
195
|
containerId: 'product-display',
|
|
@@ -256,7 +261,7 @@ window.addEventListener('lce:actions.client_ready', async () => {
|
|
|
256
261
|
|
|
257
262
|
// You can customize after initialization
|
|
258
263
|
// See Theming Guide for more options
|
|
259
|
-
});
|
|
264
|
+
}, { once: true });
|
|
260
265
|
</script>
|
|
261
266
|
```
|
|
262
267
|
|