@liquidcommerce/elements-sdk 2.6.0-beta.96 → 2.6.0-beta.97
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 +7883 -7316
- package/dist/index.esm.js +12992 -12079
- package/dist/types/core/a11y/glyph-button.d.ts +8 -0
- package/dist/types/core/a11y/index.d.ts +2 -0
- package/dist/types/core/a11y/single-select.d.ts +16 -0
- package/dist/types/modules/address/address-display.component.d.ts +3 -1
- 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-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-list/components/card-components/product-quantity-selector.d.ts +2 -1
- package/dist/types/modules/theme-provider/services/contrast-guard.service.d.ts +19 -0
- package/dist/types/modules/ui-components/input/input.component.d.ts +1 -0
- package/dist/types/modules/ui-components/lce-element/lce-element.component.d.ts +9 -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/client.md +4 -3
- package/docs/v1/api/configuration.md +13 -0
- package/docs/v1/api/ui-helpers.md +2 -2
- package/docs/v1/getting-started/concepts.md +24 -7
- package/docs/v1/getting-started/installation.md +2 -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 +3 -3
- package/docs/v1/guides/events.md +18 -5
- package/docs/v1/guides/theming.md +6 -1
- package/docs/v1/integration/vanilla-js.md +1 -1
- package/docs/v1/reference/error-handling.md +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface IGlyphButtonParams {
|
|
2
|
+
glyph: string;
|
|
3
|
+
label: string;
|
|
4
|
+
className?: string;
|
|
5
|
+
focusKey?: string;
|
|
6
|
+
enabled?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare function createGlyphButton({ glyph, label, className, focusKey, enabled }: IGlyphButtonParams): HTMLButtonElement;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export { type AnnouncementPoliteness, AnnouncerService } from '@/core/a11y/announcer.service';
|
|
2
2
|
export { A11Y_PERSIST_ATTRIBUTE, FocusManagerService } from '@/core/a11y/focus-manager.service';
|
|
3
3
|
export { getFocusableElements, isFocusable, isVisible, safeFocus } from '@/core/a11y/focusable';
|
|
4
|
+
export { type IGlyphButtonParams, createGlyphButton } from '@/core/a11y/glyph-button';
|
|
5
|
+
export { type IRovingFocusOptions, type RovingOrientation, applyOptionSemantics, focusSelectedItem, updateSelection, wireRovingFocus, } from '@/core/a11y/single-select';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type RovingOrientation = 'horizontal' | 'vertical' | 'both';
|
|
2
|
+
type SelectionAttribute = 'aria-selected' | 'aria-checked';
|
|
3
|
+
export interface IRovingFocusOptions {
|
|
4
|
+
items: HTMLElement[];
|
|
5
|
+
orientation?: RovingOrientation;
|
|
6
|
+
selectionFollowsFocus?: boolean;
|
|
7
|
+
onActivate?: (item: HTMLElement, index: number) => void;
|
|
8
|
+
}
|
|
9
|
+
export declare function updateSelection(items: HTMLElement[], selected: HTMLElement | null, attribute?: SelectionAttribute): void;
|
|
10
|
+
export declare function applyOptionSemantics(element: HTMLElement, { label, selected }: {
|
|
11
|
+
label: string;
|
|
12
|
+
selected: boolean;
|
|
13
|
+
}): void;
|
|
14
|
+
export declare function focusSelectedItem(root: ParentNode, itemSelector: string): boolean;
|
|
15
|
+
export declare function wireRovingFocus({ items, orientation, selectionFollowsFocus, onActivate }: IRovingFocusOptions): void;
|
|
16
|
+
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BaseComponent } from '@/core/base-component.service';
|
|
1
|
+
import { BaseComponent, type IOnStoreChanged } from '@/core/base-component.service';
|
|
2
2
|
import type { IAddressComponent } from '@/interfaces/configs';
|
|
3
3
|
import type { IAddressOptions } from './address.interface';
|
|
4
4
|
export interface IAddressDisplayComponentParams {
|
|
@@ -8,6 +8,8 @@ export interface IAddressDisplayComponentParams {
|
|
|
8
8
|
}
|
|
9
9
|
export declare class AddressDisplayComponent extends BaseComponent<IAddressDisplayComponentParams, IAddressComponent> {
|
|
10
10
|
get hostClasses(): string[];
|
|
11
|
+
private lastAnnouncedAddress;
|
|
11
12
|
constructor();
|
|
13
|
+
onStoreChanged(changes: IOnStoreChanged[]): boolean | undefined;
|
|
12
14
|
protected template(): HTMLElement[];
|
|
13
15
|
}
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import type { IProductFulfillmentStore } from '@/core/store/interfaces/product.interface';
|
|
2
2
|
import { type FulfillmentType } from '@/enums';
|
|
3
3
|
import type { IProductSizeAttributes } from '@/interfaces/api/product.interface';
|
|
4
|
-
export declare
|
|
4
|
+
export declare const FULFILLMENT_TAB_SELECTOR = ".fulfillment-tab";
|
|
5
|
+
export declare function fulfillmentSelectedMessage(fulfillment: IProductFulfillmentStore, type: FulfillmentType): string;
|
|
6
|
+
export declare function fulfillmentTypeMessage(type: FulfillmentType, optionCount: number): string;
|
|
7
|
+
export declare function focusSelectedFulfillmentTab(root: ParentNode): boolean;
|
|
8
|
+
export declare function renderPopupRetailerCard({ fulfillment, selectedFulfillmentType, isSelected, selectedSizeAttributes, interactive, }: {
|
|
5
9
|
fulfillment: IProductFulfillmentStore;
|
|
6
10
|
selectedFulfillmentType: FulfillmentType;
|
|
7
11
|
isSelected: boolean;
|
|
8
12
|
selectedSizeAttributes: IProductSizeAttributes | null;
|
|
13
|
+
interactive?: boolean;
|
|
9
14
|
}): HTMLElement;
|
|
10
15
|
export declare function renderFulfillmentTabsContainer({ shippingFulfillments, onDemandFulfillments, shippingSelected, onDemandSelected, onTabClick, enableShippingFulfillment, enableOnDemandFulfillment, }: {
|
|
11
16
|
shippingFulfillments: IProductFulfillmentStore[];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BaseComponent } from '@/core/base-component.service';
|
|
1
|
+
import { BaseComponent, type IOnStoreChanged } from '@/core/base-component.service';
|
|
2
2
|
import type { IProductComponent } from '@/interfaces/configs';
|
|
3
3
|
export interface IAddToCartSectionComponentParams {
|
|
4
4
|
productId: string;
|
|
@@ -8,10 +8,13 @@ export declare class ProductAddToCartSectionComponent extends BaseComponent<IAdd
|
|
|
8
8
|
private qtyIncreaseButton;
|
|
9
9
|
private qtyDecreaseButton;
|
|
10
10
|
private quantityText;
|
|
11
|
+
private pendingFocusKey;
|
|
11
12
|
get hostClasses(): string[];
|
|
12
13
|
get hostAttributes(): Record<string, string>;
|
|
13
14
|
constructor();
|
|
14
15
|
private getProductId;
|
|
16
|
+
onStoreChanged(changes: IOnStoreChanged[]): boolean | undefined;
|
|
17
|
+
afterRender(): void;
|
|
15
18
|
private getAvailableQuantity;
|
|
16
19
|
private isFulfillmentClosed;
|
|
17
20
|
private isButtonLoading;
|
|
@@ -19,6 +22,8 @@ export declare class ProductAddToCartSectionComponent extends BaseComponent<IAdd
|
|
|
19
22
|
private handleAddToCart;
|
|
20
23
|
private handleQuantityChange;
|
|
21
24
|
private calculateTotalPrice;
|
|
25
|
+
private stepperFocusKey;
|
|
26
|
+
private createStepper;
|
|
22
27
|
private createQuantityContainer;
|
|
23
28
|
private getSizeAttributes;
|
|
24
29
|
private openEngravingForm;
|
|
@@ -9,8 +9,13 @@ export interface IProductRetailersPopupListComponentParams {
|
|
|
9
9
|
export declare class ProductRetailersPopupListComponent extends BaseComponent<IProductRetailersPopupListComponentParams, IProductComponent> {
|
|
10
10
|
get hostClasses(): string[];
|
|
11
11
|
private get isProductContext();
|
|
12
|
+
private productPath;
|
|
12
13
|
beforeSetupStoreWatchers(): void;
|
|
14
|
+
private pendingTabFocus;
|
|
15
|
+
protected afterRender(): void;
|
|
13
16
|
private onFulfillmentTabClick;
|
|
17
|
+
private announceSelectedFulfillment;
|
|
18
|
+
private announceFulfillmentTypeChange;
|
|
14
19
|
private onRetailerCardClick;
|
|
15
20
|
protected template(): HTMLElement[];
|
|
16
21
|
}
|
package/dist/types/modules/product-list/components/card-components/product-quantity-selector.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export interface IQuantitySelectorParams {
|
|
|
5
5
|
maxQuantity: number;
|
|
6
6
|
cardStyle: PLCCardStyle;
|
|
7
7
|
disabled?: boolean;
|
|
8
|
+
productName?: string;
|
|
8
9
|
onChange: (quantity: number) => void;
|
|
9
10
|
}
|
|
10
|
-
export declare const createQuantitySelector: ({ initialQuantity, minQuantity, maxQuantity, cardStyle, disabled, onChange, }: IQuantitySelectorParams) => HTMLElement;
|
|
11
|
+
export declare const createQuantitySelector: ({ initialQuantity, minQuantity, maxQuantity, cardStyle, disabled, productName, onChange, }: IQuantitySelectorParams) => HTMLElement;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { IGlobalTheme } from '@/interfaces/configs';
|
|
2
|
+
import { type IRgbColor } from '@/utils/color-contrast';
|
|
3
|
+
interface IGuardedHost {
|
|
4
|
+
apply: () => void;
|
|
5
|
+
}
|
|
6
|
+
export declare class ContrastGuardService {
|
|
7
|
+
private readonly logger;
|
|
8
|
+
private readonly hosts;
|
|
9
|
+
private readonly reported;
|
|
10
|
+
static getInstance(): ContrastGuardService;
|
|
11
|
+
register(host: IGuardedHost): () => void;
|
|
12
|
+
refreshAll(): void;
|
|
13
|
+
computeOverrides(theme: Partial<IGlobalTheme> | undefined, surface: IRgbColor | null): Record<string, string>;
|
|
14
|
+
private token;
|
|
15
|
+
private correctAgainstAll;
|
|
16
|
+
private correct;
|
|
17
|
+
private report;
|
|
18
|
+
}
|
|
19
|
+
export {};
|
|
@@ -1,12 +1,20 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ComponentType } from '@/enums';
|
|
2
2
|
import { SafeHTMLElement } from '@/utils/dom-compat';
|
|
3
3
|
export declare class LceElementComponent extends SafeHTMLElement {
|
|
4
4
|
private _initialized;
|
|
5
5
|
protected _container: ShadowRoot | null;
|
|
6
6
|
private _wrappedComponentRerender;
|
|
7
|
+
private _contentType;
|
|
8
|
+
private _appliedContrastVariables;
|
|
9
|
+
private _unregisterContrastGuard;
|
|
7
10
|
constructor();
|
|
8
11
|
initialize(contentType: ComponentType, contentElement: HTMLElement): void;
|
|
9
12
|
rerender(context?: string): void;
|
|
13
|
+
connectedCallback(): void;
|
|
14
|
+
disconnectedCallback(): void;
|
|
15
|
+
private applyContrastCorrections;
|
|
16
|
+
private resolveSurfaceColor;
|
|
17
|
+
private measureHostSurfaceColor;
|
|
10
18
|
private applyBasicStyles;
|
|
11
19
|
private isCSSStyleSheetSupported;
|
|
12
20
|
private applyThemeStyles;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { IconProps } from './icon.types';
|
|
2
|
-
export declare const ArrowRightIcon: ({ width, height, className, color }: IconProps) => string;
|
|
2
|
+
export declare const ArrowRightIcon: ({ width, height, className, color, label }: IconProps) => string;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { IconProps } from './icon.types';
|
|
2
|
-
export declare const BagIcon: ({ width, height, className, color }: IconProps) => string;
|
|
2
|
+
export declare const BagIcon: ({ width, height, className, color, label }: IconProps) => string;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { IconProps } from './icon.types';
|
|
2
|
-
export declare const CheckIcon: ({ width, height, className, color }: IconProps) => string;
|
|
2
|
+
export declare const CheckIcon: ({ width, height, className, color, label }: IconProps) => string;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { IconProps } from './icon.types';
|
|
2
|
-
export declare const CheckboxIcon: ({ width, height, className, color }: IconProps) => string;
|
|
2
|
+
export declare const CheckboxIcon: ({ width, height, className, color, label }: IconProps) => string;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { IconProps } from './icon.types';
|
|
2
|
-
export declare const ChevronDownIcon: ({ width, height, className, color }: IconProps) => string;
|
|
2
|
+
export declare const ChevronDownIcon: ({ width, height, className, color, label }: IconProps) => string;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { IconProps } from './icon.types';
|
|
2
|
-
export declare const ChevronLeftIcon: ({ width, height, className, color }: IconProps) => string;
|
|
2
|
+
export declare const ChevronLeftIcon: ({ width, height, className, color, label }: IconProps) => string;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { IconProps } from './icon.types';
|
|
2
|
-
export declare const ChevronUpIcon: ({ width, height, className, color }: IconProps) => string;
|
|
2
|
+
export declare const ChevronUpIcon: ({ width, height, className, color, label }: IconProps) => string;
|
|
@@ -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
|
|
package/docs/v1/api/client.md
CHANGED
|
@@ -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
|
|
@@ -488,7 +488,8 @@ const config: ILiquidCommerceElementsConfig = {
|
|
|
488
488
|
env: 'production'
|
|
489
489
|
};
|
|
490
490
|
|
|
491
|
-
|
|
491
|
+
// Elements() resolves to `null` on failure, so the type is nullable.
|
|
492
|
+
const client: ILiquidCommerceElementsClient | null = await Elements('KEY', config);
|
|
492
493
|
```
|
|
493
494
|
|
|
494
495
|
### Type Exports
|
|
@@ -566,7 +567,7 @@ if (window.LiquidCommerce?.elements) {
|
|
|
566
567
|
// Wait for client ready
|
|
567
568
|
window.addEventListener('lce:actions.client_ready', () => {
|
|
568
569
|
window.LiquidCommerce.elements.actions.cart.openCart();
|
|
569
|
-
});
|
|
570
|
+
}, { once: true });
|
|
570
571
|
}
|
|
571
572
|
```
|
|
572
573
|
|
|
@@ -74,9 +74,22 @@ interface IGlobalTheme {
|
|
|
74
74
|
warningColor: string;
|
|
75
75
|
successColor: string;
|
|
76
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;
|
|
77
86
|
}
|
|
78
87
|
```
|
|
79
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
|
+
|
|
80
93
|
| Property | Type | Description |
|
|
81
94
|
|----------|------|-------------|
|
|
82
95
|
| `buttonCornerRadius` | `string` | CSS border-radius for buttons (e.g., `'8px'`) |
|
|
@@ -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
|
|
|
@@ -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:
|
|
@@ -37,7 +37,7 @@ The path segment selects which bundle is served:
|
|
|
37
37
|
| Path | Bundle |
|
|
38
38
|
|------|--------|
|
|
39
39
|
| `/all/elements.js` | Full SDK bundle (product, cart, checkout, and all other elements) |
|
|
40
|
-
| `/checkout/
|
|
40
|
+
| `/checkout/checkout.js` | Checkout-only bundle (tree-shaken, smaller) |
|
|
41
41
|
| `/all/beta/elements.js` | Beta channel of the full SDK bundle |
|
|
42
42
|
|
|
43
43
|
### Script Attributes
|
|
@@ -87,7 +87,7 @@ If you only need checkout functionality (without product displays or cart), use
|
|
|
87
87
|
data-token="YOUR_API_KEY"
|
|
88
88
|
data-env="production"
|
|
89
89
|
type="text/javascript"
|
|
90
|
-
src="https://elements.reservebar-worker.workers.dev/checkout/
|
|
90
|
+
src="https://elements.reservebar-worker.workers.dev/checkout/checkout.js"
|
|
91
91
|
></script>
|
|
92
92
|
```
|
|
93
93
|
|
|
@@ -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
|
|