@liquidcommerce/elements-sdk 2.6.0-beta.93 → 2.6.0-beta.95

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.
Files changed (50) hide show
  1. package/dist/index.checkout.esm.js +7862 -7146
  2. package/dist/index.esm.js +12759 -11541
  3. package/dist/types/core/a11y/announcer.service.d.ts +16 -0
  4. package/dist/types/core/a11y/focus-manager.service.d.ts +21 -0
  5. package/dist/types/core/a11y/focusable.d.ts +5 -0
  6. package/dist/types/core/a11y/index.d.ts +3 -0
  7. package/dist/types/core/base-component.service.d.ts +2 -0
  8. package/dist/types/core/google-tag-manager.service.d.ts +1 -0
  9. package/dist/types/interfaces/configs/global.interface.d.ts +2 -0
  10. package/dist/types/modules/address/address-input.component.d.ts +10 -1
  11. package/dist/types/modules/cart/components/cart-body.component.d.ts +1 -0
  12. package/dist/types/modules/cart/components/cart-item-quantity-price.component.d.ts +5 -0
  13. package/dist/types/modules/cart/components/cart-item.component.d.ts +6 -0
  14. package/dist/types/modules/checkout/components/checkout-completed.component.d.ts +2 -0
  15. package/dist/types/modules/checkout/components/checkout-item-quantity.component.d.ts +1 -0
  16. package/dist/types/modules/checkout/components/checkout-payment.component.d.ts +1 -0
  17. package/dist/types/modules/checkout/components/checkout-place-order-button.component.d.ts +2 -0
  18. package/dist/types/modules/product/components/product-drawer.component.d.ts +6 -0
  19. package/dist/types/modules/product/product.commands.d.ts +2 -2
  20. package/dist/types/modules/product-list/components/card-components/product-price-and-personalization.d.ts +2 -1
  21. package/dist/types/modules/product-list/components/card-components/product-sizes-list.d.ts +1 -0
  22. package/dist/types/modules/product-list/components/filter-components/product-list-fulfillment-filter.d.ts +1 -0
  23. package/dist/types/modules/product-list/components/product-list-filters.component.d.ts +1 -0
  24. package/dist/types/modules/product-list/components/product-list-product-pre-cart.component.d.ts +2 -0
  25. package/dist/types/modules/product-list/product-list.commands.d.ts +1 -1
  26. package/dist/types/modules/product-list/product-list.component.d.ts +3 -0
  27. package/dist/types/modules/ui-components/alert/alert.component.d.ts +1 -1
  28. package/dist/types/modules/ui-components/buttons/buttons-open-cart.component.d.ts +5 -0
  29. package/dist/types/modules/ui-components/drawer/drawer.component.d.ts +14 -0
  30. package/dist/types/modules/ui-components/engraving/engraving-form.component.d.ts +2 -0
  31. package/dist/types/modules/ui-components/engraving/engraving-view.component.d.ts +1 -0
  32. package/dist/types/modules/ui-components/input/input.component.d.ts +4 -0
  33. package/dist/types/modules/ui-components/ui.commands.d.ts +3 -1
  34. package/docs/v1/api/actions/cart-actions.md +9 -2
  35. package/docs/v1/api/actions/checkout-actions.md +2 -0
  36. package/docs/v1/api/client.md +84 -6
  37. package/docs/v1/api/configuration.md +10 -0
  38. package/docs/v1/api/typescript-types.md +5 -1
  39. package/docs/v1/getting-started/concepts.md +5 -3
  40. package/docs/v1/getting-started/installation.md +22 -1
  41. package/docs/v1/guides/cart-component.md +32 -0
  42. package/docs/v1/guides/product-component.md +6 -2
  43. package/docs/v1/guides/product-list-component.md +4 -5
  44. package/docs/v1/guides/theming.md +10 -0
  45. package/docs/v1/reference/analytics.md +108 -0
  46. package/docs/v1/reference/browser-support.md +3 -1
  47. package/docs/v1/reference/error-handling.md +8 -0
  48. package/docs/v1/reference/telemetry.md +85 -0
  49. package/docs/v1/reference/troubleshooting.md +1 -2
  50. package/package.json +44 -15
@@ -0,0 +1,16 @@
1
+ export type AnnouncementPoliteness = 'polite' | 'assertive';
2
+ export declare class AnnouncerService {
3
+ private politeRegion;
4
+ private assertiveRegion;
5
+ private pendingTimeouts;
6
+ private readonly queues;
7
+ private readonly draining;
8
+ private lastMessage;
9
+ private lastMessageAt;
10
+ static getInstance(): AnnouncerService;
11
+ announce(message: string, politeness?: AnnouncementPoliteness): void;
12
+ private drain;
13
+ clear(): void;
14
+ destroy(): void;
15
+ private ensureRegion;
16
+ }
@@ -0,0 +1,21 @@
1
+ export declare const A11Y_PERSIST_ATTRIBUTE = "data-lce-a11y-persist";
2
+ export type FocusScope = 'drawer' | 'product-drawer';
3
+ export declare class FocusManagerService {
4
+ private readonly triggerStacks;
5
+ private hiddenBackground;
6
+ static getInstance(): FocusManagerService;
7
+ captureTrigger(scope: FocusScope, trigger?: Element | null, fallback?: () => HTMLElement | null): void;
8
+ restoreFocus(scope: FocusScope): boolean;
9
+ releaseTrigger(scope: FocusScope): void;
10
+ hasTrigger(scope: FocusScope): boolean;
11
+ hasRestorableTrigger(scope: FocusScope): boolean;
12
+ private resolveTrigger;
13
+ focusInitial(container: HTMLElement, preferredSelector?: string): boolean;
14
+ restoreFocusWhenReady(root: ParentNode, selector: string, maxFrames?: number): () => void;
15
+ containsFocus(container: HTMLElement): boolean;
16
+ trapFocus(container: HTMLElement): () => void;
17
+ private getDeepActiveElement;
18
+ hideBackground(overlayRoot: Element | null): void;
19
+ showBackground(): void;
20
+ destroy(): void;
21
+ }
@@ -0,0 +1,5 @@
1
+ export declare function isVisible(element: HTMLElement): boolean;
2
+ export declare function isFocusable(element: HTMLElement, root?: ParentNode): boolean;
3
+ export declare function getFocusableElements(root: ParentNode): HTMLElement[];
4
+ export declare function isFocusTarget(element: HTMLElement): boolean;
5
+ export declare function safeFocus(element: HTMLElement | null | undefined): boolean;
@@ -0,0 +1,3 @@
1
+ export { type AnnouncementPoliteness, AnnouncerService } from '@/core/a11y/announcer.service';
2
+ export { A11Y_PERSIST_ATTRIBUTE, FocusManagerService } from '@/core/a11y/focus-manager.service';
3
+ export { getFocusableElements, isFocusable, isVisible, safeFocus } from '@/core/a11y/focusable';
@@ -1,3 +1,4 @@
1
+ import { AnnouncerService } from '@/core/a11y';
1
2
  import { ClientConfigService } from '@/core/client/client-config.service';
2
3
  import { LoggerFactory } from '@/core/logger/logger-factory';
3
4
  import { PubSubService } from '@/core/pubsub/pubsub.service';
@@ -34,6 +35,7 @@ export declare abstract class BaseComponent<TParams = Record<string, any>, TConf
34
35
  protected readonly logger: ReturnType<typeof LoggerFactory.get>;
35
36
  protected readonly clientConfig: ClientConfigService;
36
37
  protected readonly telemetry: TelemetryService;
38
+ protected readonly announcer: AnnouncerService;
37
39
  private initialized;
38
40
  private isDestroyed;
39
41
  private renderScheduled;
@@ -63,6 +63,7 @@ export declare class GoogleTagManagerService {
63
63
  private readonly clientConfigService;
64
64
  constructor();
65
65
  static getInstance(): GoogleTagManagerService;
66
+ private isGTMEnabledEnvironment;
66
67
  private waitForDOMReady;
67
68
  private isGTMAlreadyLoaded;
68
69
  private isContainerLoaded;
@@ -23,6 +23,8 @@ export interface IGlobalTheme {
23
23
  warningColor: string;
24
24
  successColor: string;
25
25
  drawerBackgroundColor: string;
26
+ inputBorderColor?: string;
27
+ focusRingColor?: string;
26
28
  }
27
29
  export interface IPromoTicker {
28
30
  promoCode: string;
@@ -25,10 +25,19 @@ export declare class AddressInputComponent extends BaseComponent<IAddressInputCo
25
25
  private handleCancel;
26
26
  private handleCheckAvailability;
27
27
  private handleSuggestionClick;
28
- private handleDocumentClick;
28
+ private suggestionsStatus;
29
+ private activeSuggestionIndex;
30
+ private handleRootClick;
31
+ private handleFocusOut;
29
32
  private searchAddresses;
30
33
  private updateErrorDisplay;
31
34
  private updateSuggestionsDisplay;
35
+ private updateSuggestionsStatus;
36
+ private getSuggestionOptions;
37
+ private moveActiveSuggestion;
38
+ private setActiveSuggestion;
39
+ private isSuggestionListOpen;
40
+ private handleComboboxKeydown;
32
41
  private showSuggestions;
33
42
  private hideSuggestions;
34
43
  private createElement;
@@ -10,6 +10,7 @@ export declare class CartBodyComponent extends BaseComponent<null, ICartComponen
10
10
  private getRetailerElementById;
11
11
  private getLoadingElement;
12
12
  private showEmptyCartState;
13
+ private preserveDialogFocus;
13
14
  private addLoadingOverlay;
14
15
  private removeLoadingOverlay;
15
16
  private setupEmptyCartListeners;
@@ -7,14 +7,19 @@ export declare class CartItemQuantityPriceComponent extends BaseComponent<ICartI
7
7
  private qtyIncreaseButton;
8
8
  private qtyDecreaseButton;
9
9
  private quantitySpan;
10
+ private priceElement;
11
+ private unitPriceElement;
10
12
  get hostClasses(): string[];
11
13
  constructor();
14
+ onStoreChanged(changes: IOnStoreChanged[]): boolean;
12
15
  onStoreWatch(changes: IOnStoreChanged[]): void;
13
16
  private getItemStore;
14
17
  private calculateQuantityLimits;
15
18
  private getAvailableQuantity;
16
19
  private updateButtonStates;
17
20
  private handleQuantityChange;
21
+ private updatePriceText;
22
+ private applyUnitPrice;
18
23
  private createQuantityContainer;
19
24
  private createPriceContainer;
20
25
  protected template(): HTMLElement[];
@@ -6,6 +6,12 @@ export declare class CartItemComponent extends BaseComponent<ICartItemComponentP
6
6
  get hostClasses(): string[];
7
7
  get hostAttributes(): Record<string, string>;
8
8
  constructor();
9
+ private lastFocusedKey;
10
+ private cancelFocusRestore;
11
+ protected connected(): void;
12
+ protected disconnected(): void;
13
+ private readonly handleFocusIn;
14
+ protected afterRender(): void;
9
15
  private handleOpenEngravingForm;
10
16
  protected template(): HTMLElement[];
11
17
  }
@@ -12,5 +12,7 @@ export interface ICheckoutCompletedComponentParams {
12
12
  }
13
13
  export declare class CheckoutCompletedComponent extends BaseComponent<ICheckoutCompletedComponentParams, ICheckoutComponent> {
14
14
  get hostClasses(): string[];
15
+ private hasAnnouncedCompletion;
16
+ protected afterRender(): void;
15
17
  protected template(): HTMLElement[];
16
18
  }
@@ -14,6 +14,7 @@ export declare class CheckoutItemQuantityComponent extends BaseComponent<IChecko
14
14
  private getProductStoreByLiquidId;
15
15
  private getAvailableQuantity;
16
16
  private calculateQuantityLimits;
17
+ private get itemName();
17
18
  private updateButtonStates;
18
19
  private handleQuantityChange;
19
20
  protected template(): HTMLElement[];
@@ -21,6 +21,7 @@ export declare class CheckoutPaymentComponent extends BaseComponent<ICheckoutSen
21
21
  private handleBillingSameAsShippingChange;
22
22
  afterRender(): Promise<void>;
23
23
  private updateSaveButtonState;
24
+ private lastAnnouncedPaymentError;
24
25
  private updateErrorMessage;
25
26
  private showError;
26
27
  protected template(): HTMLElement[];
@@ -4,6 +4,8 @@ export declare class CheckoutPlaceOrderButtonComponent extends BaseComponent<nul
4
4
  private placeOrderButton;
5
5
  private errorContainer;
6
6
  private errorTimeoutId;
7
+ private lastButtonState;
8
+ private lastAnnouncedError;
7
9
  get hostClasses(): string[];
8
10
  constructor();
9
11
  afterRender(): void;
@@ -8,12 +8,18 @@ export declare class ProductDrawerComponent extends BaseComponent<IProductDrawer
8
8
  private isOpen;
9
9
  private contentContainer;
10
10
  private currentContentType;
11
+ private focusEntryFrame;
12
+ private readonly focusManager;
13
+ private readonly boundHandleKeydown;
11
14
  constructor();
15
+ private handleKeydown;
16
+ disconnected(): void;
12
17
  private getProductId;
13
18
  onStoreChanged(changes: IOnStoreChanged[]): boolean;
14
19
  private openWithContent;
15
20
  private open;
16
21
  private close;
22
+ private moveFocusIntoPanel;
17
23
  private updateDrawerState;
18
24
  protected template(): HTMLElement;
19
25
  }
@@ -19,10 +19,10 @@ export declare class ProductCommands extends BaseCommand {
19
19
  updateQuantity(productId: string, delta: number): Promise<void>;
20
20
  changeFulfillmentType(productId: string, newFulfillmentType: FulfillmentType): Promise<void>;
21
21
  removeProduct(productId: string): Promise<void>;
22
- openProductDrawer(productId: string, contentType: IProductDrawerContentConfig['type'], data?: Record<string, any>): Promise<void>;
22
+ openProductDrawer(productId: string, contentType: IProductDrawerContentConfig['type'], data?: Record<string, any>, trigger?: HTMLElement | null): Promise<void>;
23
23
  closeProductDrawer(productId: string): Promise<void>;
24
24
  rerenderAllProducts(): Promise<void>;
25
- addToCart(productId: string, params: AddItemParams): Promise<void>;
25
+ addToCart(productId: string, params: AddItemParams, trigger?: HTMLElement | null): Promise<void>;
26
26
  addPresaleToCart(productId: string, params: AddItemParams): Promise<void>;
27
27
  productDataForEventFromStore(identifier: string): IBaseProductEventData;
28
28
  }
@@ -8,6 +8,7 @@ export interface IPricePersonalizationSectionParams {
8
8
  priceClassName?: string;
9
9
  personalizeClassName?: string;
10
10
  personalizeText?: string;
11
+ productName?: string;
11
12
  onPersonalizeClick?: () => void;
12
13
  }
13
- export declare const createPricePersonalizationSection: ({ price, showPrice, hasPersonalization, showPersonalization, hasAddress, wrapperClassName, priceClassName, personalizeClassName, personalizeText, onPersonalizeClick, }: IPricePersonalizationSectionParams) => HTMLElement | null;
14
+ export declare const createPricePersonalizationSection: ({ price, showPrice, hasPersonalization, showPersonalization, hasAddress, wrapperClassName, priceClassName, personalizeClassName, personalizeText, productName, onPersonalizeClick, }: IPricePersonalizationSectionParams) => HTMLElement | null;
@@ -7,6 +7,7 @@ export interface IProductListSizeSelectorParams {
7
7
  }
8
8
  export declare class ProductListSizeSelectorComponent extends BaseComponent<IProductListSizeSelectorParams> {
9
9
  private onOutsideClick;
10
+ private readonly uid;
10
11
  get hostClasses(): string[];
11
12
  protected disconnected?(): void;
12
13
  protected template(): HTMLElement[];
@@ -11,4 +11,5 @@ export declare function createFulfillmentFilter(params: ICreateFulfillmentFilter
11
11
  elements: HTMLElement[];
12
12
  chevronContainer: HTMLElement;
13
13
  fulfillmentList: HTMLElement;
14
+ headerButton: HTMLButtonElement;
14
15
  };
@@ -50,6 +50,7 @@ export declare class ProductListFiltersComponent extends BaseComponent<IProductL
50
50
  private isEngravingCurrentlyDisabled;
51
51
  private buildEngravingFilterElements;
52
52
  private isSameDayDeliveryCurrentlyDisabled;
53
+ private fulfillmentFilterHeaderButton;
53
54
  private toggleFulfillmentFilterCollapse;
54
55
  private buildFulfillmentFilterElements;
55
56
  private togglePriceFilterCollapse;
@@ -19,9 +19,11 @@ export declare class ProductListProductPreCartComponent extends BaseComponent<IP
19
19
  constructor();
20
20
  private getListConfig;
21
21
  protected connected?(): void;
22
+ private pendingViewFocus;
22
23
  private handleRetailersBack;
23
24
  private handleEngravingBack;
24
25
  private handleEngravingEdit;
26
+ protected afterRender(): void;
25
27
  protected disconnected?(): void;
26
28
  private getSelectedSize;
27
29
  onStoreWatch(changes: IOnStoreChanged[]): void;
@@ -22,7 +22,7 @@ export declare class ProductListCommands extends BaseCommand {
22
22
  getItemsPerPage(slug: string): number;
23
23
  updatePagination(navigation: INavigationResponse | undefined): IPagination;
24
24
  createInitialPagination(): IPagination;
25
- addToCart(slug: string, productId: string, params: AddItemParams): Promise<void>;
25
+ addToCart(slug: string, productId: string, params: AddItemParams, trigger?: HTMLElement | null): Promise<void>;
26
26
  selectSize(slug: string, productId: string, sizeId: string): Promise<void>;
27
27
  changeFulfillmentType: (slug: string, productId: string, newFulfillmentType: FulfillmentType) => Promise<void>;
28
28
  selectFulfillment: (slug: string, productId: string, selectedFulfillmentId: string) => Promise<void>;
@@ -31,7 +31,10 @@ export declare class ProductListComponent extends BaseComponent<IProductListComp
31
31
  private loadMoreProducts;
32
32
  private createCardsContainer;
33
33
  private renderLoadingState;
34
+ private hasRenderedProductsOnce;
35
+ private lastAnnouncedSentinelState;
34
36
  private renderProducts;
37
+ private announceResultCount;
35
38
  private appendNewProducts;
36
39
  private setupInfiniteScroll;
37
40
  private createScrollSentinel;
@@ -9,8 +9,8 @@ export interface IAlertComponentParams {
9
9
  export declare class AlertComponent extends BaseComponent<IAlertComponentParams, null> {
10
10
  private hideTimeout;
11
11
  private elements;
12
+ private lastAnnouncedKey;
12
13
  get hostClasses(): string[];
13
- get hostAttributes(): Record<string, string>;
14
14
  beforeSetupStoreWatchers(): void;
15
15
  afterRender(): void;
16
16
  onStoreWatch(changes: IOnStoreChanged[]): void;
@@ -5,7 +5,12 @@ export interface IButtonsOpenCartComponentParams {
5
5
  }
6
6
  export declare class ButtonsOpenCartComponent extends BaseComponent<IButtonsOpenCartComponentParams, null> {
7
7
  get hostClasses(): string[];
8
+ private buttonElement;
9
+ private badgeElement;
10
+ private unwatchQuantity;
8
11
  protected template(): HTMLElement[];
9
12
  protected afterRender(): void;
13
+ protected disconnected(): void;
10
14
  private setupCartBadge;
15
+ private applyCartQuantity;
11
16
  }
@@ -8,7 +8,14 @@ export declare class DrawerComponent extends BaseComponent {
8
8
  private currentContentType;
9
9
  private mode;
10
10
  private isTransitioning;
11
+ private readonly focusManager;
12
+ private releaseFocusTrap;
13
+ private focusEntryFrame;
14
+ private contentTeardownTimeout;
15
+ private previousBodyOverflow;
16
+ private pendingFocusKey;
11
17
  private readonly boundHandleKeydown;
18
+ private readonly boundHandleBackdropClick;
12
19
  constructor();
13
20
  disconnected(): void;
14
21
  onStoreChanged(changes: IOnStoreChanged[]): boolean;
@@ -16,6 +23,13 @@ export declare class DrawerComponent extends BaseComponent {
16
23
  private animateContentSwap;
17
24
  private open;
18
25
  private close;
26
+ private applyDialogSemantics;
27
+ private setupOverlaySemantics;
28
+ private teardownOverlaySemantics;
29
+ private moveFocusIntoDrawer;
30
+ private getTopLevelHost;
31
+ private scheduleContentTeardown;
32
+ private cancelPendingContentTeardown;
19
33
  private cleanupCurrentContent;
20
34
  private handleBackdropClick;
21
35
  private handleKeydown;
@@ -10,6 +10,7 @@ export interface IEngravingFormComponentParams {
10
10
  fee: number;
11
11
  location?: string;
12
12
  displayMode?: DisplayModeType;
13
+ returnFocusKey?: string;
13
14
  }
14
15
  export declare class EngravingFormComponent extends BaseComponent<IEngravingFormComponentParams, null> {
15
16
  get hostClasses(): string[];
@@ -26,6 +27,7 @@ export declare class EngravingFormComponent extends BaseComponent<IEngravingForm
26
27
  private getFulfillmentData;
27
28
  private retailersSection;
28
29
  private engravingLinesSection;
30
+ private returnToCart;
29
31
  private actionButtonsSection;
30
32
  protected template(): HTMLElement[];
31
33
  }
@@ -13,6 +13,7 @@ export declare class EngravingViewComponent extends BaseComponent<IEngravingView
13
13
  private engravingQuantityFee;
14
14
  private engravingLines;
15
15
  private isEngravingRequired;
16
+ private get editFocusKey();
16
17
  private handleEdit;
17
18
  private handleRemove;
18
19
  protected template(): HTMLElement | HTMLElement[] | string;
@@ -25,10 +25,14 @@ export interface IInputComponentParams {
25
25
  disabled?: boolean;
26
26
  }
27
27
  export declare class InputComponent extends BaseComponent<IInputComponentParams, null> {
28
+ private readonly uid;
28
29
  get hostClasses(): string[];
30
+ private get controlId();
31
+ private get errorContainerId();
29
32
  private inputElement;
30
33
  private errorContainer;
31
34
  private validationTimeout;
35
+ private announceNextErrors;
32
36
  private handlePhoneKeydown;
33
37
  private formatPhoneNumber;
34
38
  private formatDate;
@@ -2,10 +2,12 @@ import { BaseCommand } from '@/core/command/base-command.service';
2
2
  import type { IDrawerContentConfig } from '@/core/store/interfaces/core.interface';
3
3
  export declare class UICommands extends BaseCommand {
4
4
  static getInstance(): UICommands;
5
- openDrawer({ mode, contentType, data, }: {
5
+ openDrawer({ mode, contentType, data, trigger, triggerFallback, }: {
6
6
  mode?: 'drawer' | 'modal';
7
7
  contentType: IDrawerContentConfig['type'];
8
8
  data?: Record<string, any>;
9
+ trigger?: HTMLElement | null;
10
+ triggerFallback?: () => HTMLElement | null;
9
11
  }): void;
10
12
  closeDrawer(): void;
11
13
  }
@@ -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
- console.error('Invalid promo code:', error);
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
@@ -11,7 +11,7 @@ Initialize the full SDK client.
11
11
  ```typescript
12
12
  function Elements(
13
13
  apiKey: string,
14
- config: ILiquidCommerceElementsConfig
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 | Yes | Configuration object |
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: ILiquidCommerceElementsCheckoutClientConfig
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 | Yes | Checkout configuration |
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: ILiquidCommerceElementsBuilderConfig
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 | Yes | Builder configuration object (same shape as `ILiquidCommerceElementsConfig`) |
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
 
@@ -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
@@ -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
@@ -100,6 +102,8 @@ interface IFontFamily {
100
102
  }
101
103
  ```
102
104
 
105
+ > **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.
106
+
103
107
  #### IGlobalLayout
104
108
 
105
109
  ```typescript
@@ -109,6 +113,8 @@ interface IGlobalLayout {
109
113
  personalizationCardStyle: 'outlined' | 'filled';
110
114
  allowPromoCodes: boolean;
111
115
  inputFieldStyle: 'outlined' | 'filled';
116
+ enableOrderedProductSizes: boolean;
117
+ orderedProductSizes: string[];
112
118
  showPoweredBy: boolean;
113
119
  poweredByMode: 'light' | 'dark';
114
120
  }
@@ -121,9 +127,13 @@ interface IGlobalLayout {
121
127
  | `personalizationCardStyle` | `'outlined' \| 'filled'` | Visual style for personalization cards |
122
128
  | `allowPromoCodes` | `boolean` | Show promo code inputs in cart/checkout |
123
129
  | `inputFieldStyle` | `'outlined' \| 'filled'` | Visual style for input fields |
130
+ | `enableOrderedProductSizes` | `boolean` | Enable a fixed display order for product/PLC size selectors (defined by `orderedProductSizes`) instead of the default ordering |
131
+ | `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
132
  | `showPoweredBy` | `boolean` | Show "Powered by LiquidCommerce" badge |
125
133
  | `poweredByMode` | `'light' \| 'dark'` | Color mode for the powered-by badge |
126
134
 
135
+ > **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.
136
+
127
137
  **Example:**
128
138
 
129
139
  ```javascript