@liquidcommerce/elements-sdk 2.6.0-beta.12 → 2.6.0-beta.121
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 +100 -2518
- package/dist/index.checkout.esm.js +20445 -0
- package/dist/index.esm.js +28574 -20597
- package/dist/ssr-stub.checkout.esm.js +17 -0
- package/dist/ssr-stub.esm.js +277 -0
- package/dist/types/auto-initialize/checkout.d.ts +2 -0
- package/dist/types/auto-initialize/shared-utils.d.ts +51 -0
- package/dist/types/{elements-base-client.d.ts → clients/base.d.ts} +16 -2
- package/dist/types/clients/builder.d.ts +3 -0
- package/dist/types/clients/checkout.d.ts +6 -0
- package/dist/types/clients/helpers.d.ts +8 -0
- package/dist/types/clients/main.d.ts +3 -0
- package/dist/types/constants/core.constant.d.ts +13 -18
- package/dist/types/constants/index.d.ts +1 -0
- package/dist/types/constants/prop65.constant.d.ts +8 -0
- 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 +6 -0
- package/dist/types/core/a11y/required.d.ts +1 -0
- package/dist/types/core/a11y/single-select.d.ts +20 -0
- package/dist/types/core/api/api-client.service.d.ts +23 -18
- package/dist/types/core/api/api-result.d.ts +19 -0
- package/dist/types/core/api/auth-client.service.d.ts +37 -13
- package/dist/types/core/api/http-client.service.d.ts +0 -8
- package/dist/types/core/base-component.service.d.ts +4 -1
- package/dist/types/core/client/actions/base-action.service.d.ts +22 -0
- package/dist/types/core/client/actions/client-address-action.service.d.ts +18 -0
- package/dist/types/core/client/actions/client-cart-action.service.d.ts +38 -0
- package/dist/types/core/client/actions/client-checkout-action.service.d.ts +75 -0
- package/dist/types/core/client/actions/client-product-action.service.d.ts +15 -0
- package/dist/types/core/client/client-action.service.d.ts +6 -74
- package/dist/types/core/client/client-config.service.d.ts +10 -5
- package/dist/types/core/debug-panel/debug-panel.styles.d.ts +1 -1
- package/dist/types/core/google-tag-manager.service.d.ts +10 -1
- package/dist/types/core/logger/logger.service.d.ts +1 -1
- package/dist/types/core/pubsub/interfaces/address.interface.d.ts +3 -0
- package/dist/types/core/pubsub/interfaces/cart.interface.d.ts +6 -1
- package/dist/types/core/pubsub/interfaces/checkout.interface.d.ts +45 -49
- package/dist/types/core/pubsub/interfaces/core.interface.d.ts +15 -7
- package/dist/types/core/pubsub/pubsub.service.d.ts +1 -2
- package/dist/types/core/singleton-manager.service.d.ts +12 -8
- package/dist/types/core/store/interfaces/cart.interface.d.ts +2 -3
- package/dist/types/core/store/interfaces/checkout.interface.d.ts +36 -107
- package/dist/types/core/store/interfaces/core.interface.d.ts +12 -2
- package/dist/types/core/store/interfaces/metadata.interface.d.ts +11 -0
- package/dist/types/core/store/interfaces/product-list.interface.d.ts +30 -0
- package/dist/types/core/store/interfaces/product.interface.d.ts +1 -0
- package/dist/types/core/store/store.constant.d.ts +5 -0
- package/dist/types/core/store/store.service.d.ts +1 -0
- package/dist/types/core/telemetry/telemetry.service.d.ts +1 -0
- package/dist/types/enums/core.enum.d.ts +47 -2
- package/dist/types/enums/index.d.ts +0 -1
- package/dist/types/index.checkout.d.ts +9 -0
- package/dist/types/index.checkout.umd.d.ts +4 -0
- package/dist/types/index.d.ts +8 -3
- package/dist/types/interfaces/api/cart.interface.d.ts +12 -7
- package/dist/types/interfaces/api/checkout.interface.d.ts +271 -0
- package/dist/types/interfaces/api/index.d.ts +5 -0
- package/dist/types/interfaces/api/product-list.interface.d.ts +15 -6
- package/dist/types/interfaces/api/product.interface.d.ts +10 -4
- package/dist/types/interfaces/client.interface.d.ts +74 -0
- package/dist/types/interfaces/component.interface.d.ts +7 -0
- package/dist/types/interfaces/config.interface.d.ts +44 -0
- package/dist/types/interfaces/configs/address.interface.d.ts +1 -1
- package/dist/types/interfaces/configs/cart.interface.d.ts +2 -1
- package/dist/types/interfaces/configs/checkout.interface.d.ts +3 -1
- package/dist/types/interfaces/configs/global.interface.d.ts +9 -3
- package/dist/types/interfaces/configs/index.d.ts +1 -0
- package/dist/types/interfaces/configs/product-list.interface.d.ts +49 -0
- package/dist/types/interfaces/configs/product.interface.d.ts +7 -1
- package/dist/types/interfaces/injection.interface.d.ts +56 -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/address/address.command.d.ts +2 -1
- package/dist/types/modules/address/styles/register-styles.d.ts +1 -0
- package/dist/types/modules/cart/cart.commands.d.ts +9 -5
- package/dist/types/modules/cart/components/cart-body.component.d.ts +1 -0
- package/dist/types/modules/cart/components/cart-fulfillment.component.d.ts +1 -1
- 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/cart/styles/register-styles.d.ts +1 -0
- package/dist/types/modules/checkout/checkout.commands.d.ts +95 -12
- package/dist/types/modules/checkout/checkout.component.d.ts +7 -1
- package/dist/types/modules/checkout/components/checkout-billing.component.d.ts +5 -2
- package/dist/types/modules/checkout/components/checkout-buyer.component.d.ts +1 -0
- package/dist/types/modules/checkout/components/checkout-completed.component.d.ts +5 -0
- package/dist/types/modules/checkout/components/checkout-deliver-to.component.d.ts +1 -0
- package/dist/types/modules/checkout/components/checkout-delivery-method.component.d.ts +22 -0
- package/dist/types/modules/checkout/components/checkout-express-checkout.component.d.ts +61 -0
- package/dist/types/modules/checkout/components/checkout-express-completion.component.d.ts +21 -0
- package/dist/types/modules/checkout/components/checkout-header.component.d.ts +1 -0
- package/dist/types/modules/checkout/components/checkout-item-quantity.component.d.ts +4 -0
- package/dist/types/modules/checkout/components/checkout-items.component.d.ts +4 -3
- package/dist/types/modules/checkout/components/checkout-order-summary.component.d.ts +3 -0
- package/dist/types/modules/checkout/components/checkout-payment.component.d.ts +6 -1
- package/dist/types/modules/checkout/components/checkout-place-order-button.component.d.ts +1 -5
- package/dist/types/modules/checkout/components/checkout-presale-countdown.component.d.ts +15 -1
- package/dist/types/modules/checkout/components/checkout-presale-expired.component.d.ts +7 -1
- package/dist/types/modules/checkout/components/checkout-prop65-warning.component.d.ts +8 -0
- package/dist/types/modules/checkout/components/checkout-send-as-gift.component.d.ts +3 -0
- package/dist/types/modules/checkout/components/checkout-stripe-form.component.d.ts +7 -2
- package/dist/types/modules/checkout/components/checkout-tips.component.d.ts +4 -2
- package/dist/types/modules/checkout/components/index.d.ts +4 -0
- package/dist/types/modules/checkout/components/promo-pc-gc.component.d.ts +0 -2
- package/dist/types/modules/checkout/components/required-fields-legend.d.ts +1 -0
- package/dist/types/modules/checkout/constant.d.ts +15 -0
- package/dist/types/modules/checkout/customer-prefill.d.ts +5 -0
- package/dist/types/modules/checkout/express-wallet.d.ts +12 -0
- package/dist/types/modules/checkout/payment-session-error.d.ts +4 -0
- package/dist/types/modules/checkout/styles/delivery-method.style.d.ts +1 -0
- package/dist/types/modules/checkout/styles/express-checkout.style.d.ts +1 -0
- package/dist/types/modules/checkout/styles/express-completion.style.d.ts +1 -0
- package/dist/types/modules/checkout/styles/register-styles.d.ts +1 -0
- package/dist/types/modules/product/components/components.d.ts +26 -2
- package/dist/types/modules/product/components/index.d.ts +1 -0
- package/dist/types/modules/product/components/product-add-to-cart-section.component.d.ts +8 -1
- package/dist/types/modules/product/components/product-delivery-estimate.component.d.ts +11 -0
- package/dist/types/modules/product/components/product-description.component.d.ts +1 -0
- 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 +5 -0
- package/dist/types/modules/product/components/product-options.component.d.ts +2 -1
- package/dist/types/modules/product/components/product-prop65-warning.d.ts +1 -0
- package/dist/types/modules/product/components/product-retailers-carousel.component.d.ts +6 -0
- package/dist/types/modules/product/components/product-retailers-popup-list.component.d.ts +12 -2
- package/dist/types/modules/product/components/product-retailers-popup.component.d.ts +1 -0
- package/dist/types/modules/product/components/product-retailers.component.d.ts +1 -0
- package/dist/types/modules/product/product.commands.d.ts +5 -5
- package/dist/types/modules/product/product.component.d.ts +3 -0
- package/dist/types/modules/product/styles/prop65-warning.style.d.ts +1 -0
- package/dist/types/modules/product/styles/register-styles.d.ts +1 -0
- package/dist/types/modules/product-list/components/card-components/index.d.ts +6 -0
- package/dist/types/modules/product-list/components/card-components/product-badge.d.ts +9 -0
- package/dist/types/modules/product-list/components/card-components/product-button.d.ts +11 -0
- package/dist/types/modules/product-list/components/card-components/product-fulfillment-text.d.ts +2 -0
- package/dist/types/modules/product-list/components/card-components/product-price-and-personalization.d.ts +14 -0
- package/dist/types/modules/product-list/components/card-components/product-quantity-selector.d.ts +11 -0
- package/dist/types/modules/product-list/components/card-components/product-sizes-list.d.ts +14 -0
- package/dist/types/modules/product-list/components/filter-components/index.d.ts +7 -0
- package/dist/types/modules/product-list/components/filter-components/product-list-apply-filter-button.d.ts +1 -0
- package/dist/types/modules/product-list/components/{product-list-filters-subcomponents/product-list-checkbox-filter.components.d.ts → filter-components/product-list-checkbox-filter.d.ts} +1 -0
- package/dist/types/modules/product-list/components/filter-components/product-list-chip.d.ts +5 -0
- package/dist/types/modules/product-list/components/filter-components/product-list-filters-chips.d.ts +13 -0
- package/dist/types/modules/product-list/components/filter-components/product-list-fulfillment-filter.d.ts +15 -0
- package/dist/types/modules/product-list/components/{product-list-filters-subcomponents/product-list-price-filter.components.d.ts → filter-components/product-list-price-filter.d.ts} +2 -1
- package/dist/types/modules/product-list/components/filter-components/product-list-toggle-filters.d.ts +7 -0
- package/dist/types/modules/product-list/components/index.d.ts +6 -2
- package/dist/types/modules/product-list/components/product-list-card-loading.component.d.ts +3 -1
- package/dist/types/modules/product-list/components/product-list-card.component.d.ts +39 -31
- package/dist/types/modules/product-list/components/product-list-engraving.component.d.ts +12 -0
- package/dist/types/modules/product-list/components/product-list-filters.component.d.ts +58 -36
- package/dist/types/modules/product-list/components/product-list-product-engraving-lines.component.d.ts +22 -0
- package/dist/types/modules/product-list/components/product-list-product-pre-cart.component.d.ts +54 -0
- package/dist/types/modules/product-list/components/product-list-search.component.d.ts +25 -0
- package/dist/types/modules/product-list/product-list-filter.registry.d.ts +42 -0
- package/dist/types/modules/product-list/product-list-filter.utils.d.ts +7 -0
- package/dist/types/modules/product-list/product-list-order.utils.d.ts +3 -0
- package/dist/types/modules/product-list/product-list-query-params.utils.d.ts +3 -0
- package/dist/types/modules/product-list/product-list.commands.d.ts +22 -7
- package/dist/types/modules/product-list/product-list.component.d.ts +23 -47
- package/dist/types/modules/product-list/product-list.constants.d.ts +38 -0
- package/dist/types/modules/product-list/product-list.interface.d.ts +17 -28
- package/dist/types/modules/product-list/styles/product-list-card.style.d.ts +1 -0
- package/dist/types/modules/product-list/styles/product-list-filters.style.d.ts +1 -0
- package/dist/types/modules/product-list/styles/register-styles.d.ts +1 -0
- package/dist/types/modules/theme-provider/constants/component-groupings.d.ts +1 -0
- package/dist/types/modules/theme-provider/constants/css-variable-mappings.d.ts +1 -1
- package/dist/types/modules/theme-provider/services/style-registry.service.d.ts +16 -0
- package/dist/types/modules/theme-provider/services/stylesheet-generator.service.d.ts +0 -1
- package/dist/types/modules/theme-provider/styles/register-styles.d.ts +1 -0
- package/dist/types/modules/theme-provider/theme-provider.service.d.ts +2 -2
- package/dist/types/modules/ui-components/alert/alert.component.d.ts +10 -10
- 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 +15 -0
- package/dist/types/modules/ui-components/engraving/engraving-form.component.d.ts +9 -1
- package/dist/types/modules/ui-components/engraving/engraving-view.component.d.ts +7 -1
- package/dist/types/modules/ui-components/input/index.d.ts +0 -1
- package/dist/types/modules/ui-components/input/input.component.d.ts +15 -2
- package/dist/types/modules/ui-components/lce-element/lce-element.component.d.ts +2 -1
- package/dist/types/modules/ui-components/promo-code-ticker/promo-code-ticker.component.d.ts +1 -1
- package/dist/types/modules/ui-components/ui.commands.d.ts +7 -1
- package/dist/types/ssr/stub.checkout.d.ts +6 -0
- package/dist/types/ssr/stub.d.ts +10 -0
- 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 +2 -0
- 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 +2 -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/dom-compat.d.ts +2 -0
- package/dist/types/utils/format.d.ts +9 -14
- package/dist/types/utils/image-bg-removal.d.ts +3 -0
- package/dist/types/utils/product-selection.d.ts +16 -0
- package/dist/types/utils/product.d.ts +21 -0
- package/dist/types/utils/timezone.d.ts +6 -0
- package/docs/v1/README.md +213 -0
- package/docs/v1/api/actions/address-actions.md +286 -0
- package/docs/v1/api/actions/cart-actions.md +364 -0
- package/docs/v1/api/actions/checkout-actions.md +586 -0
- package/docs/v1/api/actions/product-actions.md +204 -0
- package/docs/v1/api/client.md +664 -0
- package/docs/v1/api/configuration.md +583 -0
- package/docs/v1/api/injection-methods.md +331 -0
- package/docs/v1/api/typescript-types.md +501 -0
- package/docs/v1/api/ui-helpers.md +200 -0
- package/docs/v1/examples/advanced-patterns.md +199 -0
- package/docs/v1/examples/checkout-flow.md +90 -0
- package/docs/v1/examples/custom-theming.md +76 -0
- package/docs/v1/examples/multi-product-page.md +90 -0
- package/docs/v1/examples/simple-product-page.md +89 -0
- package/docs/v1/getting-started/concepts.md +521 -0
- package/docs/v1/getting-started/installation.md +351 -0
- package/docs/v1/getting-started/quick-start.md +410 -0
- package/docs/v1/guides/accessibility.md +288 -0
- package/docs/v1/guides/address-component.md +435 -0
- package/docs/v1/guides/best-practices.md +365 -0
- package/docs/v1/guides/cart-component.md +800 -0
- package/docs/v1/guides/checkout-component.md +817 -0
- package/docs/v1/guides/events.md +1004 -0
- package/docs/v1/guides/product-component.md +761 -0
- package/docs/v1/guides/product-list-component.md +730 -0
- package/docs/v1/guides/theming.md +243 -0
- package/docs/v1/integration/angular.md +39 -0
- package/docs/v1/integration/laravel.md +41 -0
- package/docs/v1/integration/nextjs.md +69 -0
- package/docs/v1/integration/proxy-setup.md +106 -0
- package/docs/v1/integration/react.md +64 -0
- package/docs/v1/integration/vanilla-js.md +84 -0
- package/docs/v1/integration/vue.md +58 -0
- package/docs/v1/reference/analytics.md +133 -0
- package/docs/v1/reference/browser-support.md +47 -0
- package/docs/v1/reference/error-handling.md +83 -0
- package/docs/v1/reference/performance.md +52 -0
- package/docs/v1/reference/telemetry.md +85 -0
- package/docs/v1/reference/troubleshooting.md +135 -0
- package/package.json +75 -45
- package/dist/types/elements-builder-client.d.ts +0 -2
- package/dist/types/elements-client-helper.d.ts +0 -4
- package/dist/types/elements-client.d.ts +0 -2
- package/dist/types/enums/cloud.enum.d.ts +0 -97
- package/dist/types/interfaces/cloud/checkout.interface.d.ts +0 -218
- package/dist/types/interfaces/cloud/core.interface.d.ts +0 -22
- package/dist/types/interfaces/cloud/index.d.ts +0 -3
- package/dist/types/interfaces/cloud/retailer.interface.d.ts +0 -67
- package/dist/types/interfaces/cloud/user.interface.d.ts +0 -100
- package/dist/types/interfaces/core.interface.d.ts +0 -111
- package/dist/types/modules/checkout/components/checkout.type.d.ts +0 -4
- package/dist/types/modules/product-list/components/product-list-filters-subcomponents/index.d.ts +0 -6
- package/dist/types/modules/product-list/components/product-list-filters-subcomponents/product-list-apply-filter-button.component.d.ts +0 -1
- package/dist/types/modules/product-list/components/product-list-filters-subcomponents/product-list-delivery-options-filter.components.d.ts +0 -16
- package/dist/types/modules/product-list/components/product-list-filters-subcomponents/product-list-search.component.d.ts +0 -16
- package/dist/types/modules/product-list/components/product-list-filters-subcomponents/product-list-toggle-filters.components.d.ts +0 -18
- package/dist/types/modules/theme-provider/styles/address/index.d.ts +0 -1
- package/dist/types/modules/theme-provider/styles/cart/index.d.ts +0 -1
- package/dist/types/modules/theme-provider/styles/checkout/index.d.ts +0 -1
- package/dist/types/modules/theme-provider/styles/product/index.d.ts +0 -3
- package/dist/types/modules/theme-provider/styles/product-list/index.d.ts +0 -1
- package/dist/types/modules/theme-provider/styles/ui/index.d.ts +0 -3
- package/dist/types/modules/ui-components/input/birthdate-input.component.d.ts +0 -53
- package/dist/types/utils/helper.d.ts +0 -28
- package/docs/ACTIONS.md +0 -1300
- package/docs/BROWSER_SUPPORT.md +0 -279
- package/docs/CONFIGURATION.md +0 -853
- package/docs/DOCUMENTATION_INDEX.md +0 -311
- package/docs/EVENTS.md +0 -798
- package/docs/PROXY.md +0 -228
- package/docs/THEMING.md +0 -592
- package/docs/TROUBLESHOOTING.md +0 -793
- package/umd/elements.js +0 -1
- /package/dist/types/{auto-initialize.d.ts → auto-initialize/main.d.ts} +0 -0
- /package/dist/types/modules/{theme-provider/styles/address → address/styles}/address.style.d.ts +0 -0
- /package/dist/types/modules/{theme-provider/styles/cart → cart/styles}/cart.style.d.ts +0 -0
- /package/dist/types/modules/{theme-provider/styles/checkout → checkout/styles}/checkout.style.d.ts +0 -0
- /package/dist/types/modules/{theme-provider/styles/product → product/styles}/image-carousel.style.d.ts +0 -0
- /package/dist/types/modules/{theme-provider/styles/product → product/styles}/product.style.d.ts +0 -0
- /package/dist/types/modules/{theme-provider/styles/product → product/styles}/retailers.style.d.ts +0 -0
- /package/dist/types/modules/{theme-provider/styles/product-list → product-list/styles}/product-list.style.d.ts +0 -0
- /package/dist/types/modules/{theme-provider/styles/ui → ui-components/styles}/drawer.style.d.ts +0 -0
- /package/dist/types/modules/{theme-provider/styles/ui → ui-components/styles}/loading.style.d.ts +0 -0
- /package/dist/types/modules/{theme-provider/styles/ui → ui-components/styles}/promo-code-ticker.style.d.ts +0 -0
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
# Quick Start
|
|
2
|
+
|
|
3
|
+
Get a product display with add-to-cart functionality working on your page in under 5 minutes.
|
|
4
|
+
|
|
5
|
+
## What You'll Build
|
|
6
|
+
|
|
7
|
+
A fully functional product page with:
|
|
8
|
+
- Product images and details
|
|
9
|
+
- Size selection
|
|
10
|
+
- Fulfillment options (shipping/on-demand delivery)
|
|
11
|
+
- Add to cart button
|
|
12
|
+
- Shopping cart drawer
|
|
13
|
+
- Complete checkout flow
|
|
14
|
+
|
|
15
|
+
## Prerequisites
|
|
16
|
+
|
|
17
|
+
- A LiquidCommerce API key (contact your LiquidCommerce representative)
|
|
18
|
+
- A product identifier
|
|
19
|
+
- A web page or HTML file
|
|
20
|
+
|
|
21
|
+
## Step 1: Add the SDK Script
|
|
22
|
+
|
|
23
|
+
Add the Elements SDK script tag to your HTML `<head>`:
|
|
24
|
+
|
|
25
|
+
```html
|
|
26
|
+
<!DOCTYPE html>
|
|
27
|
+
<html>
|
|
28
|
+
<head>
|
|
29
|
+
<title>My Product Page</title>
|
|
30
|
+
<script
|
|
31
|
+
defer
|
|
32
|
+
data-liquid-commerce-elements
|
|
33
|
+
data-token="YOUR_API_KEY"
|
|
34
|
+
data-env="production"
|
|
35
|
+
type="text/javascript"
|
|
36
|
+
src="https://elements.reservebar-worker.workers.dev/all/elements.js"
|
|
37
|
+
></script>
|
|
38
|
+
</head>
|
|
39
|
+
<body>
|
|
40
|
+
<!-- We'll add the product here -->
|
|
41
|
+
</body>
|
|
42
|
+
</html>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Replace `YOUR_API_KEY`** with your actual API key.
|
|
46
|
+
|
|
47
|
+
## Step 2: Add a Product Container
|
|
48
|
+
|
|
49
|
+
Create a container where the product will be displayed:
|
|
50
|
+
|
|
51
|
+
```html
|
|
52
|
+
<body>
|
|
53
|
+
<h1>Our Premium Whiskey</h1>
|
|
54
|
+
|
|
55
|
+
<!-- Product will be injected here -->
|
|
56
|
+
<div id="product-display"></div>
|
|
57
|
+
</body>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Step 3: Configure the Product (Declarative)
|
|
61
|
+
|
|
62
|
+
Add product configuration using HTML data attributes on the script tag:
|
|
63
|
+
|
|
64
|
+
```html
|
|
65
|
+
<script
|
|
66
|
+
defer
|
|
67
|
+
data-liquid-commerce-elements
|
|
68
|
+
data-token="YOUR_API_KEY"
|
|
69
|
+
data-env="production"
|
|
70
|
+
data-container-1="product-display"
|
|
71
|
+
data-product-1="00619947000020"
|
|
72
|
+
type="text/javascript"
|
|
73
|
+
src="https://elements.reservebar-worker.workers.dev/all/elements.js"
|
|
74
|
+
></script>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**New attributes:**
|
|
78
|
+
- `data-container-1="product-display"` - Points to the container ID
|
|
79
|
+
- `data-product-1="00619947000020"` - The product identifier
|
|
80
|
+
|
|
81
|
+
The numbers (1) connect the container to its product. For multiple products, increment the number:
|
|
82
|
+
- `data-container-2` with `data-product-2`
|
|
83
|
+
- `data-container-3` with `data-product-3`
|
|
84
|
+
- etc.
|
|
85
|
+
|
|
86
|
+
## Complete Example
|
|
87
|
+
|
|
88
|
+
Here's the complete HTML for a working product page:
|
|
89
|
+
|
|
90
|
+
```html
|
|
91
|
+
<!DOCTYPE html>
|
|
92
|
+
<html lang="en">
|
|
93
|
+
<head>
|
|
94
|
+
<meta charset="UTF-8">
|
|
95
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
96
|
+
<title>Premium Whiskey - Buy Online</title>
|
|
97
|
+
|
|
98
|
+
<script
|
|
99
|
+
defer
|
|
100
|
+
data-liquid-commerce-elements
|
|
101
|
+
data-token="YOUR_API_KEY"
|
|
102
|
+
data-env="production"
|
|
103
|
+
data-container-1="product-display"
|
|
104
|
+
data-product-1="00619947000020"
|
|
105
|
+
type="text/javascript"
|
|
106
|
+
src="https://elements.reservebar-worker.workers.dev/all/elements.js"
|
|
107
|
+
></script>
|
|
108
|
+
|
|
109
|
+
<style>
|
|
110
|
+
body {
|
|
111
|
+
font-family: Arial, sans-serif;
|
|
112
|
+
max-width: 1200px;
|
|
113
|
+
margin: 0 auto;
|
|
114
|
+
padding: 20px;
|
|
115
|
+
}
|
|
116
|
+
h1 {
|
|
117
|
+
text-align: center;
|
|
118
|
+
}
|
|
119
|
+
</style>
|
|
120
|
+
</head>
|
|
121
|
+
<body>
|
|
122
|
+
<h1>Our Premium Whiskey</h1>
|
|
123
|
+
<div id="product-display"></div>
|
|
124
|
+
</body>
|
|
125
|
+
</html>
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
That's it! Save the file and open it in a browser. You should see:
|
|
129
|
+
1. Product images in a carousel
|
|
130
|
+
2. Product name and description
|
|
131
|
+
3. Size selector
|
|
132
|
+
4. Fulfillment type selector (shipping/delivery)
|
|
133
|
+
5. Retailer selection
|
|
134
|
+
6. Add to cart button
|
|
135
|
+
|
|
136
|
+
When you click "Add to Cart," a cart drawer slides in from the right with checkout functionality.
|
|
137
|
+
|
|
138
|
+
## Alternative: Programmatic Setup
|
|
139
|
+
|
|
140
|
+
If you prefer JavaScript over HTML attributes:
|
|
141
|
+
|
|
142
|
+
```html
|
|
143
|
+
<!DOCTYPE html>
|
|
144
|
+
<html>
|
|
145
|
+
<head>
|
|
146
|
+
<title>My Product Page</title>
|
|
147
|
+
<script
|
|
148
|
+
defer
|
|
149
|
+
data-liquid-commerce-elements
|
|
150
|
+
data-token="YOUR_API_KEY"
|
|
151
|
+
data-env="production"
|
|
152
|
+
type="text/javascript"
|
|
153
|
+
src="https://elements.reservebar-worker.workers.dev/all/elements.js"
|
|
154
|
+
></script>
|
|
155
|
+
|
|
156
|
+
<script defer>
|
|
157
|
+
// Wait for SDK to be ready
|
|
158
|
+
window.addEventListener('lce:actions.client_ready', async (event) => {
|
|
159
|
+
const client = window.LiquidCommerce.elements;
|
|
160
|
+
|
|
161
|
+
// Inject the product
|
|
162
|
+
await client.injectProductElement([
|
|
163
|
+
{
|
|
164
|
+
containerId: 'product-display',
|
|
165
|
+
identifier: '00619947000020'
|
|
166
|
+
}
|
|
167
|
+
]);
|
|
168
|
+
}, { once: true });
|
|
169
|
+
</script>
|
|
170
|
+
</head>
|
|
171
|
+
<body>
|
|
172
|
+
<h1>Our Premium Whiskey</h1>
|
|
173
|
+
<div id="product-display"></div>
|
|
174
|
+
</body>
|
|
175
|
+
</html>
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Or with NPM:
|
|
179
|
+
|
|
180
|
+
```javascript
|
|
181
|
+
import { Elements } from '@liquidcommerce/elements-sdk';
|
|
182
|
+
|
|
183
|
+
async function initProduct() {
|
|
184
|
+
// Elements() resolves to `null` if initialization fails — it never throws.
|
|
185
|
+
const client = await Elements('YOUR_API_KEY', {
|
|
186
|
+
env: 'production'
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
if (!client) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
await client.injectProductElement([
|
|
194
|
+
{
|
|
195
|
+
containerId: 'product-display',
|
|
196
|
+
identifier: '00619947000020'
|
|
197
|
+
}
|
|
198
|
+
]);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
initProduct();
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Multiple Products
|
|
205
|
+
|
|
206
|
+
To display multiple products on one page:
|
|
207
|
+
|
|
208
|
+
```html
|
|
209
|
+
<script
|
|
210
|
+
defer
|
|
211
|
+
data-liquid-commerce-elements
|
|
212
|
+
|
|
213
|
+
data-token="YOUR_API_KEY"
|
|
214
|
+
data-env="production"
|
|
215
|
+
|
|
216
|
+
data-container-1="product-1"
|
|
217
|
+
data-product-1="00619947000020"
|
|
218
|
+
data-container-2="product-2"
|
|
219
|
+
data-product-2="08504405135"
|
|
220
|
+
data-container-3="product-3"
|
|
221
|
+
data-product-3="08068660001"
|
|
222
|
+
|
|
223
|
+
type="text/javascript"
|
|
224
|
+
src="https://elements.reservebar-worker.workers.dev/all/elements.js"
|
|
225
|
+
></script>
|
|
226
|
+
|
|
227
|
+
<div id="product-1"></div>
|
|
228
|
+
<div id="product-2"></div>
|
|
229
|
+
<div id="product-3"></div>
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Or programmatically:
|
|
233
|
+
|
|
234
|
+
```javascript
|
|
235
|
+
await client.injectProductElement([
|
|
236
|
+
{ containerId: 'product-1', identifier: '00619947000020' },
|
|
237
|
+
{ containerId: 'product-2', identifier: '08504405135' },
|
|
238
|
+
{ containerId: 'product-3', identifier: '08068660001' }
|
|
239
|
+
]);
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
## What Happens Automatically
|
|
243
|
+
|
|
244
|
+
The SDK handles everything for you:
|
|
245
|
+
|
|
246
|
+
1. **Address Collection** - If needed, prompts for delivery location
|
|
247
|
+
2. **Availability Check** - Shows only available fulfillment options
|
|
248
|
+
3. **Cart Management** - Maintains cart across page refreshes and tabs
|
|
249
|
+
4. **Checkout Flow** - Complete payment and order processing
|
|
250
|
+
5. **Error Handling** - Graceful error messages and recovery
|
|
251
|
+
6. **Mobile Responsiveness** - Works on all screen sizes
|
|
252
|
+
|
|
253
|
+
## Customization
|
|
254
|
+
|
|
255
|
+
Want to customize the look, visit the Elements Builder in our [Partner Portal](https://app.liquidcommerce.co/)? Want to manually override your theme, you can pass a `customTheme: IClientCustomThemeConfig` configuration:
|
|
256
|
+
|
|
257
|
+
```html
|
|
258
|
+
<script>
|
|
259
|
+
window.addEventListener('lce:actions.client_ready', async () => {
|
|
260
|
+
const client = window.LiquidCommerce.elements;
|
|
261
|
+
|
|
262
|
+
// You can customize after initialization
|
|
263
|
+
// See Theming Guide for more options
|
|
264
|
+
}, { once: true });
|
|
265
|
+
</script>
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Or with NPM:
|
|
269
|
+
|
|
270
|
+
```javascript
|
|
271
|
+
const client = await Elements('YOUR_API_KEY', {
|
|
272
|
+
env: 'production',
|
|
273
|
+
customTheme: {
|
|
274
|
+
global: {
|
|
275
|
+
theme: {
|
|
276
|
+
primaryColor: '#007bff',
|
|
277
|
+
buttonCornerRadius: '8px',
|
|
278
|
+
headingFont: {
|
|
279
|
+
name: 'Poppins',
|
|
280
|
+
weights: [400, 600]
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## Testing Different Products
|
|
289
|
+
|
|
290
|
+
To test with different products, simply change the product identifier:
|
|
291
|
+
|
|
292
|
+
```html
|
|
293
|
+
<!-- Replace with your product UPC -->
|
|
294
|
+
data-product-1="YOUR_PRODUCT_IDENTIFIER"
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
Contact your LiquidCommerce representative for available product identifiers.
|
|
298
|
+
|
|
299
|
+
## Troubleshooting
|
|
300
|
+
|
|
301
|
+
### Product Not Showing
|
|
302
|
+
|
|
303
|
+
1. **Check the browser console** for errors
|
|
304
|
+
2. **Verify your API key** is correct
|
|
305
|
+
3. **Confirm the product identifier** exists in your catalog
|
|
306
|
+
4. **Check the container ID** matches your HTML
|
|
307
|
+
|
|
308
|
+
### Styling Issues
|
|
309
|
+
|
|
310
|
+
The product uses Shadow DOM for style encapsulation. To customize:
|
|
311
|
+
|
|
312
|
+
- Use the `customTheme` configuration option
|
|
313
|
+
- See [Theming Guide](../guides/theming.md) for detailed customization
|
|
314
|
+
|
|
315
|
+
### Cart Not Opening
|
|
316
|
+
|
|
317
|
+
The cart should open automatically after adding a product. If it doesn't:
|
|
318
|
+
|
|
319
|
+
1. Check browser console for JavaScript errors
|
|
320
|
+
2. Verify no other scripts are conflicting
|
|
321
|
+
3. Try manually opening: `window.LiquidCommerce.elements.actions.cart.openCart()`
|
|
322
|
+
|
|
323
|
+
## Next Steps
|
|
324
|
+
|
|
325
|
+
Now that you have a basic product working:
|
|
326
|
+
|
|
327
|
+
- **[Core Concepts](./concepts.md)** - Understand how the SDK works
|
|
328
|
+
- **[Product Component Guide](../guides/product-component.md)** - Deep dive into product features
|
|
329
|
+
- **[Cart Component Guide](../guides/cart-component.md)** - Learn about cart functionality
|
|
330
|
+
- **[Checkout Component Guide](../guides/checkout-component.md)** - Customize the checkout experience
|
|
331
|
+
- **[Theming Guide](../guides/theming.md)** - Make it match your brand
|
|
332
|
+
- **[Events](../guides/events.md)** - React to user actions
|
|
333
|
+
- **[API Reference](../api/client.md)** - Explore all available methods
|
|
334
|
+
|
|
335
|
+
## Complete Working Example
|
|
336
|
+
|
|
337
|
+
Try this complete example with your API key:
|
|
338
|
+
|
|
339
|
+
```html
|
|
340
|
+
<!DOCTYPE html>
|
|
341
|
+
<html lang="en">
|
|
342
|
+
<head>
|
|
343
|
+
<meta charset="UTF-8">
|
|
344
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
345
|
+
<title>Whiskey Shop</title>
|
|
346
|
+
|
|
347
|
+
<script
|
|
348
|
+
defer
|
|
349
|
+
data-liquid-commerce-elements
|
|
350
|
+
data-token="YOUR_API_KEY"
|
|
351
|
+
data-env="production"
|
|
352
|
+
data-container-1="product"
|
|
353
|
+
data-product-1="00619947000020"
|
|
354
|
+
type="text/javascript"
|
|
355
|
+
src="https://elements.reservebar-worker.workers.dev/all/elements.js"
|
|
356
|
+
></script>
|
|
357
|
+
|
|
358
|
+
<style>
|
|
359
|
+
* {
|
|
360
|
+
margin: 0;
|
|
361
|
+
padding: 0;
|
|
362
|
+
box-sizing: border-box;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
body {
|
|
366
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
|
|
367
|
+
background: #f5f5f5;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
header {
|
|
371
|
+
background: white;
|
|
372
|
+
padding: 20px;
|
|
373
|
+
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
374
|
+
margin-bottom: 40px;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
.container {
|
|
378
|
+
max-width: 1200px;
|
|
379
|
+
margin: 0 auto;
|
|
380
|
+
padding: 0 20px;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
h1 {
|
|
384
|
+
text-align: center;
|
|
385
|
+
color: #333;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
#product {
|
|
389
|
+
background: white;
|
|
390
|
+
border-radius: 8px;
|
|
391
|
+
padding: 20px;
|
|
392
|
+
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
|
393
|
+
}
|
|
394
|
+
</style>
|
|
395
|
+
</head>
|
|
396
|
+
<body>
|
|
397
|
+
<header>
|
|
398
|
+
<div class="container">
|
|
399
|
+
<h1>🥃 Premium Spirits Collection</h1>
|
|
400
|
+
</div>
|
|
401
|
+
</header>
|
|
402
|
+
|
|
403
|
+
<div class="container">
|
|
404
|
+
<div id="product"></div>
|
|
405
|
+
</div>
|
|
406
|
+
</body>
|
|
407
|
+
</html>
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
Replace `YOUR_API_KEY` with your actual key and you're ready to go!
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
# Accessibility Guide
|
|
2
|
+
|
|
3
|
+
What the Elements SDK does for accessibility, what it needs from your page, and how to verify it.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Elements target **WCAG 2.1 Level AA**. Every element ships with keyboard support, screen-reader
|
|
8
|
+
announcements and managed focus — there is nothing to switch on. Colour contrast is the exception:
|
|
9
|
+
the SDK renders your theme's colours exactly as given, so that part is yours — see
|
|
10
|
+
[Colour and contrast](#colour-and-contrast).
|
|
11
|
+
|
|
12
|
+
Accessibility is shared between the SDK and the host page:
|
|
13
|
+
|
|
14
|
+
| The SDK owns | Your page owns |
|
|
15
|
+
|---|---|
|
|
16
|
+
| Roles, names and states of everything inside an element | Page structure: landmarks, `<html lang>` |
|
|
17
|
+
| Keyboard operation of every control it renders | Contrast of your own content, and the surface you place elements on |
|
|
18
|
+
| Focus movement into and out of its overlays | A theme whose colours meet the WCAG contrast minimums (the SDK renders your colours as given) |
|
|
19
|
+
| Announcing its own content changes | Not hiding or `inert`-ing the element container |
|
|
20
|
+
| Reflow down to a 320px viewport | Layout around the element at 400% zoom |
|
|
21
|
+
|
|
22
|
+
## Keyboard navigation
|
|
23
|
+
|
|
24
|
+
Every control is reachable and operable with a keyboard alone. Related controls are grouped into
|
|
25
|
+
a **single tab stop** with arrow keys inside it, so a long list of retailers or sizes is not a
|
|
26
|
+
tab-through slog.
|
|
27
|
+
|
|
28
|
+
| Widget | Keys |
|
|
29
|
+
|---|---|
|
|
30
|
+
| Size selector (product) | `Tab` to the group, `←` `→` to move, `Enter` / `Space` to choose, `Home` / `End` for the ends |
|
|
31
|
+
| Size dropdown (product list) | `Enter` / `Space` / `↓` opens, `↑` `↓` moves, `Enter` chooses, `Esc` closes |
|
|
32
|
+
| Delivery method tabs (Shipping / Same-Day) | `←` `→` switches method immediately; unavailable methods are skipped, `Home` / `End` for the ends |
|
|
33
|
+
| Retailer / delivery-option lists | `↑` `↓` moves, `Enter` / `Space` chooses, `Home` / `End` for the ends |
|
|
34
|
+
| Retailer carousel | `←` `→` moves, `Enter` / `Space` chooses |
|
|
35
|
+
| Product image thumbnails | `←` `→` moves, `Enter` / `Space` shows the image |
|
|
36
|
+
| Tip amount | `Tab` to the group, `←` `→` to move, `Enter` / `Space` to choose, `Home` / `End` for the ends |
|
|
37
|
+
| Quantity steppers | `Tab` to each button, `Enter` / `Space` to step |
|
|
38
|
+
| Address field | Type to search, `↑` `↓` through suggestions, `Enter` selects, `Esc` dismisses |
|
|
39
|
+
| Cart / checkout drawer, modals | `Tab` cycles inside the panel only, `Esc` closes |
|
|
40
|
+
|
|
41
|
+
Arrow keys change the selection immediately only where that is cheap and reversible (the delivery
|
|
42
|
+
method tabs). Where choosing has a side effect the user cannot navigate back out of — picking a
|
|
43
|
+
retailer closes the panel — arrow keys move focus and `Enter` commits.
|
|
44
|
+
|
|
45
|
+
### Focus management
|
|
46
|
+
|
|
47
|
+
- **Opening an overlay** moves focus onto the first control inside it — the panel's close
|
|
48
|
+
button, the address field — and remembers the control that opened it. Focus lands on a
|
|
49
|
+
control rather than on the panel itself so the focus ring shows a sighted keyboard user
|
|
50
|
+
where they now are; the dialog's role and name are announced either way as focus crosses
|
|
51
|
+
into it. Views whose point is the text at the top of them (the order confirmation) focus
|
|
52
|
+
that heading instead.
|
|
53
|
+
- **Closing** returns focus to that control, even when a re-render has replaced it.
|
|
54
|
+
- **While an overlay is open** focus is trapped inside it and the rest of the page is `inert` and
|
|
55
|
+
`aria-hidden`, so a screen reader cannot wander behind the dialog.
|
|
56
|
+
- **In-place content swaps** (Buy Now → address form, Add to Cart → personalize) re-seat focus on
|
|
57
|
+
the new view's heading; nothing is left focused on a destroyed node.
|
|
58
|
+
- **After a re-render** focus returns to the control that caused it — the quantity stepper you
|
|
59
|
+
pressed, the delivery-method tab you switched to.
|
|
60
|
+
- **Nothing hidden is focusable.** Collapsed panels are removed from the tab order and the
|
|
61
|
+
accessibility tree, and closed overlays have their content torn down.
|
|
62
|
+
|
|
63
|
+
### Retailer shopping from the cart
|
|
64
|
+
|
|
65
|
+
The opt-in `cart.layout.showShopRetailerButton` uses a native **Shop {retailer}** button with
|
|
66
|
+
normal Tab, Enter and Space behavior, a 44px minimum target height and a visible focus ring.
|
|
67
|
+
It appears beside the unmet-minimum warning on desktop and below it on mobile. Warning updates
|
|
68
|
+
retain the button node and its focus; if it disappears because the minimum is met or eligibility
|
|
69
|
+
changes, focus moves to the containing fulfillment before its item controls. The host handles
|
|
70
|
+
focus after closing the drawer and navigating in response to `cart_shop_retailer`.
|
|
71
|
+
|
|
72
|
+
The button text, border and focus ring use `global.theme.primaryColor`; check that color against
|
|
73
|
+
the cart background as part of your theme contrast review.
|
|
74
|
+
|
|
75
|
+
### Focus indicator
|
|
76
|
+
|
|
77
|
+
A 2px ring in `--focus-ring-color`, offset 2px from the control. Controls that span their
|
|
78
|
+
container's full width use an inset ring instead, because an outward ring on those is clipped by
|
|
79
|
+
the scrolling panel around them. On primary-coloured fills the ring switches to
|
|
80
|
+
`--selected-text-color`, the token already used for text on that fill — so setting the pair
|
|
81
|
+
`primaryColor` / `selectedTextColor` to a combination that clears 3:1 covers the ring too.
|
|
82
|
+
|
|
83
|
+
The ring targets `:focus` as well as `:focus-visible`, so browsers without `:focus-visible`
|
|
84
|
+
support still show it.
|
|
85
|
+
|
|
86
|
+
## Screen reader support
|
|
87
|
+
|
|
88
|
+
Elements are Web Components inside a shadow root, which is fully visible to assistive technology.
|
|
89
|
+
|
|
90
|
+
### Announcements
|
|
91
|
+
|
|
92
|
+
Content that appears or changes without navigation is announced through a shared live region
|
|
93
|
+
(`role="status"`, `aria-live="polite"`; `role="alert"` for errors) that lives at the end of
|
|
94
|
+
`document.body` and survives re-renders.
|
|
95
|
+
|
|
96
|
+
| What happened | What is announced |
|
|
97
|
+
|---|---|
|
|
98
|
+
| Buy Now pressed | "Enter delivery address" |
|
|
99
|
+
| Address saved | "Delivery address updated. Now delivering to …" |
|
|
100
|
+
| Delivery option chosen | "Delivery option updated. Shipping from …, $…, Ships in 2-3 days, delivery $…" |
|
|
101
|
+
| Delivery method switched | "Shipping selected. 5 options available. Shipping from …, $…, Ships in 2-3 days, delivery $…" |
|
|
102
|
+
| Size chosen | "Size 750 ML selected" |
|
|
103
|
+
| Quantity stepped | "Tito's Handmade Vodka, quantity 4" |
|
|
104
|
+
| Personalization saved / removed | "Personalization saved" / "Personalization removed" |
|
|
105
|
+
| Cart or checkout opened / closed | "Shopping cart opened" / "Shopping cart closed" |
|
|
106
|
+
| Panel closed (product) | "Closed. Back to product options." |
|
|
107
|
+
| Item added / removed, promo applied, totals changed | The new state, e.g. "Promo code SPRING applied, $5.00 off" |
|
|
108
|
+
| Express checkout payment failed | "Express checkout failed. …" |
|
|
109
|
+
| Product list filtered or searched | "12 products found, showing 12" |
|
|
110
|
+
| Validation failed | The field name and the error, interrupting (assertive) |
|
|
111
|
+
| Carousel image changed | "Image 2 of 4" |
|
|
112
|
+
|
|
113
|
+
Live regions are never written into a component template: components replace their whole subtree
|
|
114
|
+
on render, and a live region recreated with its text already in place is not announced. Use
|
|
115
|
+
`this.announcer.announce(message)` from a component instead.
|
|
116
|
+
|
|
117
|
+
### Names, roles and states
|
|
118
|
+
|
|
119
|
+
- Dialogs carry `role="dialog"`, an accessible name, and `aria-modal` when they cover the page.
|
|
120
|
+
- Single-select groups are `listbox` / `radiogroup` with `option` / `radio` children carrying
|
|
121
|
+
`aria-selected` / `aria-checked` — not toggle buttons with `aria-pressed`, which would describe
|
|
122
|
+
each choice as an independent on/off switch. Product sizes are a `listbox`; the delivery options
|
|
123
|
+
under each method are a `radiogroup`.
|
|
124
|
+
- Checkout's **Delivery Method** section is an accordion whose header is a real `button` carrying
|
|
125
|
+
`aria-expanded`, and whose two methods are a `radiogroup` of `radio` cards. Choosing one re-prices
|
|
126
|
+
the order, so selection does not follow focus here either: arrow keys move between the methods and
|
|
127
|
+
`Enter` / `Space` commits, rather than committing a switch the shopper was only passing through.
|
|
128
|
+
A method that cannot fulfil is `aria-disabled` and not activatable, but the **Change Location**
|
|
129
|
+
button inside it stays reachable — it is the way out of that state, so it must not be sealed in
|
|
130
|
+
with the option it sits under. Each card names the method, its fee and its timing, or, when it
|
|
131
|
+
cannot fulfil, the reason why.
|
|
132
|
+
- The delivery-method controls are a `tablist` of `tab`s. Only one method's options are rendered at
|
|
133
|
+
a time, so the selected tab carries `aria-controls` and the region it swaps in is the matching
|
|
134
|
+
`tabpanel`, labelled by that tab; the inactive tab points at nothing, because there is nothing
|
|
135
|
+
there to point at. A method switched off by configuration renders no tab at all, and the region
|
|
136
|
+
then falls back to its own label rather than naming a tab that does not exist. Choosing an option
|
|
137
|
+
closes the panel, so arrow keys move without choosing and `Enter` / `Space` commits — a
|
|
138
|
+
deliberate departure from the radio-group model, which would otherwise select a neighbour and
|
|
139
|
+
end the interaction before the shopper reached the option they wanted.
|
|
140
|
+
- Unavailable controls are `aria-disabled` **and** genuinely inert: they cannot be activated.
|
|
141
|
+
- Icon-only buttons take their name from the button's `aria-label`.
|
|
142
|
+
- Visible label text is always contained in the accessible name (2.5.3 Label in Name), so speech
|
|
143
|
+
input works: saying "click See Delivery Options" activates the button that reads that way.
|
|
144
|
+
- Fields whose design has no room for a visible label (promo code, gift card) get an
|
|
145
|
+
`aria-label` instead — no rendered label, no layout change. A field that has a visible `<label>`
|
|
146
|
+
is never *also* given an `aria-label`, which would replace the label's text rather than add to
|
|
147
|
+
it.
|
|
148
|
+
- **Required fields** carry `aria-required="true"`, so they announce as required. The visible `*`
|
|
149
|
+
is reinforcement and is `aria-hidden`, since the state is already spoken; each form section
|
|
150
|
+
explains the glyph with a "Fields marked * are required." line above its fields (3.3.2).
|
|
151
|
+
- An option in a single-select group carries its **whole** visible content in its accessible name.
|
|
152
|
+
`option` and `radio` have presentational children, so the name is the only channel: a delivery
|
|
153
|
+
option names the retailer, the price, the timing, the delivery fee and — for same-day — the
|
|
154
|
+
store address and whether it is currently closed.
|
|
155
|
+
- The California Proposition 65 warning on the product is a native `<details>` / `<summary>`
|
|
156
|
+
disclosure: the summary is a button that exposes its expanded state, and `Enter` / `Space` toggle
|
|
157
|
+
it with no scripting involved. Its `+` / `−` indicator is decorative and hidden. In checkout it is
|
|
158
|
+
a plain link whose accessible name ends "(opens in a new tab)", since following it leaves the
|
|
159
|
+
purchase mid-flow; the `·` separator is hidden.
|
|
160
|
+
|
|
161
|
+
### Headings
|
|
162
|
+
|
|
163
|
+
The product element emits a level-1 title, and every section caption below it sits at level 2 —
|
|
164
|
+
`Size`, `Delivers to:`, `Shipping From:` and `About this product:` — so the whole element is
|
|
165
|
+
reachable by heading navigation with no level skipped. An overlay supplies its own heading at the
|
|
166
|
+
top of its content, because the page behind it is out of the accessibility tree while it is open.
|
|
167
|
+
|
|
168
|
+
A caption can do both jobs at once: `Shipping From:` is a heading *and* names the retailer card
|
|
169
|
+
beneath it through `aria-labelledby`. Heading ids are scoped to the product, so each product
|
|
170
|
+
element on a page labels its own sections.
|
|
171
|
+
|
|
172
|
+
The checkout element has its own outline and is not covered by the above. Where any element's
|
|
173
|
+
top-level heading sits in **your** page's outline is yours to place.
|
|
174
|
+
|
|
175
|
+
### Express checkout
|
|
176
|
+
|
|
177
|
+
The Apple Pay and Google Pay buttons are rendered by Stripe inside an iframe, so their own labels
|
|
178
|
+
and keyboard behaviour are Stripe's. What the SDK owns around them:
|
|
179
|
+
|
|
180
|
+
- The **"Express Checkout" heading** is an `h3`, matching the other checkout section headings. It is
|
|
181
|
+
rendered only by the `section` variant; injected on their own the buttons carry no heading, and the
|
|
182
|
+
host page's own outline supplies it.
|
|
183
|
+
- The **`OR` divider** is decorative and carries `aria-hidden="true"`, so "OR" is not announced as
|
|
184
|
+
content between the buttons and the section below.
|
|
185
|
+
- When the shopper's device offers **no wallet**, the heading and the divider are removed from the
|
|
186
|
+
accessibility tree along with the buttons, so no orphan rule or empty heading is left behind. The block is also removed on a gift order, which express cannot place, and where a
|
|
187
|
+
payment method is already bound to the checkout. It is offered to every shopper otherwise.
|
|
188
|
+
- The **wallet sheet is browser UI**, not an SDK overlay: the browser owns focus while it is open and
|
|
189
|
+
returns it to the button that opened it. Dismissing the sheet changes nothing in the page, so
|
|
190
|
+
nothing is announced.
|
|
191
|
+
- Failures are announced assertively, because the shopper has just authorised a payment and the sheet
|
|
192
|
+
that showed the error has already closed. Confirming the sheet places the order outright, so there
|
|
193
|
+
is nothing to announce on the success path beyond the order confirmation itself.
|
|
194
|
+
|
|
195
|
+
### Images and icons
|
|
196
|
+
|
|
197
|
+
- Product photos use the product name as their alt text; a photo painted as a CSS background is
|
|
198
|
+
exposed with `role="img"` and the same name.
|
|
199
|
+
- Decorative images inside a named control use `alt=""` so the control is not announced twice.
|
|
200
|
+
- Every inline SVG icon renders `aria-hidden="true" focusable="false"`. Icons that carry meaning
|
|
201
|
+
on their own opt in to a name: `CloseIcon({ label: 'Close' })`.
|
|
202
|
+
|
|
203
|
+
## Colour and contrast
|
|
204
|
+
|
|
205
|
+
Element colours come from your theme, and a brand palette chosen to look right often does not
|
|
206
|
+
clear WCAG: white on a mid-tone brand fill is around 3:1, well under the 4.5:1 body text needs.
|
|
207
|
+
|
|
208
|
+
**The SDK renders the colours you supply exactly as given — it does not adjust them.** Contrast is
|
|
209
|
+
therefore yours to get right: check each foreground token against the surface the Element sits on
|
|
210
|
+
and make sure it reaches 4.5:1 for text (WCAG 1.4.3) and 3:1 for borders, icons and the focus ring
|
|
211
|
+
(WCAG 1.4.11).
|
|
212
|
+
|
|
213
|
+
The tokens worth checking are `defaultTextColor`, `linkTextColor`, `warningColor`, `errorColor` and
|
|
214
|
+
`successColor` against `drawerBackgroundColor` (or whatever your page puts behind the Element), plus
|
|
215
|
+
`selectedTextColor` against `primaryColor` for text on brand-filled buttons and badges.
|
|
216
|
+
|
|
217
|
+
`defaultTextColor` also colours the product's California Proposition 65 warning, which is legally
|
|
218
|
+
required copy, so it always uses the full-strength token, never a lighter variant — make sure it
|
|
219
|
+
reaches 4.5:1 on your product background. The checkout's warning panel does not use it: it is a
|
|
220
|
+
fixed colour pair chosen by `global.layout.poweredByMode` (over 13:1 in both `light` and `dark`), so
|
|
221
|
+
set that to `dark` if your checkout is dark.
|
|
222
|
+
|
|
223
|
+
Every token ships with a default that already passes on a light surface. Two are easy to forget
|
|
224
|
+
because they are optional — leave them out to keep the compliant defaults, or set them explicitly to
|
|
225
|
+
keep those details on-brand:
|
|
226
|
+
|
|
227
|
+
```javascript
|
|
228
|
+
customTheme: {
|
|
229
|
+
global: {
|
|
230
|
+
theme: {
|
|
231
|
+
inputBorderColor: '#767C85', // form field boundaries, needs 3:1 on your surface
|
|
232
|
+
focusRingColor: '#1D4ED8' // keyboard focus ring, needs 3:1 on your surface
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Zoom, reflow and text spacing
|
|
239
|
+
|
|
240
|
+
Elements reflow down to a 320px CSS viewport (400% zoom on a 1280px screen) without horizontal
|
|
241
|
+
scrolling. Labels wrap instead of truncating, so they survive user text-spacing overrides.
|
|
242
|
+
|
|
243
|
+
## Verifying it
|
|
244
|
+
|
|
245
|
+
**Keyboard:** unplug the mouse and complete a purchase. Every control must be reachable, every
|
|
246
|
+
focus ring visible, and focus must never land on `<body>`.
|
|
247
|
+
|
|
248
|
+
**Announcements** without a screen reader — the live regions are plain DOM:
|
|
249
|
+
|
|
250
|
+
```javascript
|
|
251
|
+
for (const region of document.querySelectorAll('[data-lce-live-region]')) {
|
|
252
|
+
new MutationObserver(() => console.log('[SR]', region.textContent)).observe(region, {
|
|
253
|
+
childList: true, subtree: true, characterData: true,
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
**Screen readers:** verify with VoiceOver (Safari/macOS), NVDA (Firefox/Windows) or TalkBack
|
|
259
|
+
(Chrome/Android) — the pairings that matter most for a storefront.
|
|
260
|
+
|
|
261
|
+
## See Also
|
|
262
|
+
|
|
263
|
+
- [Theming Guide](./theming.md) — the colour tokens to check for contrast
|
|
264
|
+
- [Best Practices](./best-practices.md)
|
|
265
|
+
- [Browser Support](../reference/browser-support.md)
|
|
266
|
+
|
|
267
|
+
## Checkout initialization and payment recovery
|
|
268
|
+
|
|
269
|
+
Checkout announces loading or initialization failure in a status region. If initialization fails, payment fields are withheld and a keyboard-operable **Retry checkout** button retries the same checkout. The button is disabled while loading.
|
|
270
|
+
|
|
271
|
+
Save Payment Information remains disabled until checkout initializes. During payment save it stays busy until the server responds. Recoverable billing/prepare errors are announced while the mounted card fields and billing input remain available for correction and retry.
|
|
272
|
+
|
|
273
|
+
### Wallet payment actions
|
|
274
|
+
|
|
275
|
+
The payment action's accessible name matches its visible label, including the
|
|
276
|
+
selected Apple Pay or Google Pay wallet and retry/processing states. Adjacent
|
|
277
|
+
instructions explain whether the action opens the wallet or retries saving already
|
|
278
|
+
authorized details. These actions save the payment method; order placement is a
|
|
279
|
+
separate step.
|
|
280
|
+
|
|
281
|
+
### Recorded marketing choices
|
|
282
|
+
|
|
283
|
+
Checkout suppresses each email/SMS consent checkbox only after the corresponding
|
|
284
|
+
recorded account choice is confirmed. Suppressed controls are hidden visually and
|
|
285
|
+
from the accessibility tree; unknown choices retain their named, keyboard-operable
|
|
286
|
+
checkboxes. Clearing account preferences reveals the controls and synchronizes
|
|
287
|
+
`aria-checked` with the current guest defaults. A shopper's explicit checkbox edit
|
|
288
|
+
keeps that channel visible when account data arrives later.
|