@dropins/storefront-cart 1.5.0-beta2 → 1.5.0-beta3

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.
@@ -1 +1 @@
1
- {"version":3,"file":"CartSummaryTable2.js","sources":["../../node_modules/@adobe-commerce/elsie/src/icons/Trash.svg","/@dropins/storefront-cart/src/components/CartSummaryTable/CartSummaryTable.tsx","/@dropins/storefront-cart/src/components/CartSummaryTable/Elements/Item/Item.tsx","/@dropins/storefront-cart/src/hooks/useCartItems.ts","../../node_modules/@adobe-commerce/elsie/src/components/InLineAlert/InLineAlert.tsx","/@dropins/storefront-cart/src/containers/CartSummaryTable/CartSummaryTable.tsx"],"sourcesContent":["import * as React from \"react\";\nconst SvgTrash = (props) => /* @__PURE__ */ React.createElement(\"svg\", { xmlns: \"http://www.w3.org/2000/svg\", width: 24, height: 24, viewBox: \"0 0 24 24\", fill: \"none\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { d: \"M1 5H23\", stroke: \"currentColor\", strokeWidth: 1.5, strokeMiterlimit: 10 }), /* @__PURE__ */ React.createElement(\"path\", { d: \"M17.3674 22H6.63446C5.67952 22 4.88992 21.2688 4.8379 20.3338L4 5H20L19.1621 20.3338C19.1119 21.2688 18.3223 22 17.3655 22H17.3674Z\", stroke: \"currentColor\", strokeWidth: 1.5, strokeMiterlimit: 10 }), /* @__PURE__ */ React.createElement(\"path\", { d: \"M9.87189 2H14.1281C14.6085 2 15 2.39766 15 2.88889V5H9V2.88889C9 2.39912 9.39006 2 9.87189 2Z\", stroke: \"currentColor\", strokeWidth: 1.5, strokeMiterlimit: 10 }), /* @__PURE__ */ React.createElement(\"path\", { d: \"M8.87402 8.58057L9.39348 17.682\", stroke: \"currentColor\", strokeWidth: 1.5, strokeMiterlimit: 10 }), /* @__PURE__ */ React.createElement(\"path\", { d: \"M14.6673 8.58057L14.146 17.682\", stroke: \"currentColor\", strokeWidth: 1.5, strokeMiterlimit: 10 }));\nexport default SvgTrash;\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\n/**\n * CartSummaryTable is a responsive grid-based component that displays cart items in a table-like format.\n * It adapts to mobile views by switching to a stacked layout with labeled sections.\n * \n * @component\n */\n\nimport { FunctionComponent, VNode } from 'preact';\nimport { HTMLAttributes } from 'preact/compat';\nimport { classes, VComponent } from '@adobe-commerce/elsie/lib';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport '@/cart/components/CartSummaryTable/CartSummaryTable.css';\n\n/**\n * Represents a single row entry in the cart summary table\n * Each field accepts a VNode to allow for flexible content rendering\n */\nexport interface CartTableEntry {\n /** The item UID */\n uid: string;\n /** Whether the item is updating */\n updating: boolean;\n /** Whether the item has an update error */\n hasError: boolean;\n /** The product details section (typically includes image, name, and options) */\n item: VNode;\n /** The unit price of the product */\n price: VNode;\n /** The quantity selector/display */\n quantity: VNode;\n /** The total price for this line item */\n subtotal: VNode;\n /** Actions bar on the bottom of the row */\n actions: VNode;\n /** Optional undo banner for removed items */\n undoBanner?: VNode;\n}\n\n/**\n * Props for the CartSummaryTable component\n */\nexport interface CartSummaryTableProps extends HTMLAttributes<HTMLDivElement> {\n /** Array of cart entries to display in the table */\n entries: CartTableEntry[];\n /** Optional CSS class name for custom styling */\n className?: string;\n}\n\n/**\n * CartSummaryTable component displays cart items in a responsive grid layout\n * - Uses CSS Grid for layout with 4 columns on desktop\n * - Switches to a stacked single-column layout on mobile with labeled sections\n * - Renders each entry's content using VComponent for proper component handling\n */\nexport const CartSummaryTable: FunctionComponent<CartSummaryTableProps> = ({\n entries,\n className,\n ...props\n}) => {\n const dictionary = useText({\n itemLabel: 'Cart.CartSummaryTable.item',\n priceLabel: 'Cart.CartSummaryTable.price',\n qtyLabel: 'Cart.CartSummaryTable.qty',\n subtotalLabel: 'Cart.CartSummaryTable.subtotal',\n mobilePriceLabel: 'Cart.CartSummaryTable.mobilePrice',\n mobileQtyLabel: 'Cart.CartSummaryTable.mobileQty',\n mobileSubtotalLabel: 'Cart.CartSummaryTable.mobileSubtotal'\n });\n\n return (\n <div {...props} className={classes(['cart-cart-summary-table', className])}>\n {/* Table header - hidden on mobile */}\n <div className=\"cart-cart-summary-table__header\">\n <div className=\"cart-cart-summary-table__header-item\">{dictionary.itemLabel}</div>\n <div className=\"cart-cart-summary-table__header-price\">{dictionary.priceLabel}</div>\n <div className=\"cart-cart-summary-table__header-qty\">{dictionary.qtyLabel}</div>\n <div className=\"cart-cart-summary-table__header-subtotal\">{dictionary.subtotalLabel}</div>\n </div>\n {/* Table body - adapts to grid layout on mobile */}\n <div className=\"cart-cart-summary-table__body\">\n {entries.map((entry) => {\n // If this entry is an undo banner, render it as a full-width banner\n if (entry.undoBanner) {\n return (\n <div key={entry.uid} className=\"cart-cart-summary-table__undo-banner\">\n <VComponent node={entry.undoBanner} />\n </div>\n );\n }\n \n // Otherwise render as a regular table row\n return (\n <div key={entry.uid} className={classes([\n 'cart-cart-summary-table__row',\n [ 'cart-cart-summary-table__row--updating', entry.updating ],\n [ 'cart-cart-summary-table__row--error', entry.hasError ],\n ])}\n >\n <div className=\"cart-cart-summary-table__cell-item\">\n <VComponent node={entry.item} />\n </div>\n <div className=\"cart-cart-summary-table__cell-price\">\n <span className=\"cart-cart-summary-table__mobile-label\">{dictionary.mobilePriceLabel}</span>\n <VComponent node={entry.price} />\n </div>\n <div className=\"cart-cart-summary-table__cell-qty\">\n <span className=\"cart-cart-summary-table__mobile-label\">{dictionary.mobileQtyLabel}</span>\n <VComponent node={entry.quantity} />\n </div>\n <div className=\"cart-cart-summary-table__cell-subtotal\">\n <span className=\"cart-cart-summary-table__mobile-label\">{dictionary.mobileSubtotalLabel}</span>\n <VComponent node={entry.subtotal} />\n </div>\n <div className=\"cart-cart-summary-table__item-footer\">\n <VComponent className=\"cart-cart-summary-table__item-actions\" node={entry.actions} />\n </div>\n </div>\n );\n })}\n </div>\n </div>\n );\n};\n","/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this \n * file in accordance with the terms of the Adobe license agreement \n * accompanying it. \n *******************************************************************/\n \nimport { FunctionComponent, VNode } from 'preact';\nimport { HTMLAttributes } from 'preact/compat';\nimport { classes, VComponent } from '@adobe-commerce/elsie/lib';\nimport '@/cart/components/CartSummaryTable/Elements/Item/Item.css';\n\nexport interface ItemProps extends HTMLAttributes<HTMLDivElement> {\n productTitle: VNode;\n sku?: VNode;\n image?: VNode;\n configurations?: VNode;\n alert?: VNode;\n warning?: VNode;\n}\n\nexport const Item: FunctionComponent<ItemProps> = ({\n className,\n productTitle,\n sku,\n image,\n configurations,\n alert,\n warning,\n ...props\n}) => {\n return (\n <div {...props} className={classes(['cart-cart-summary-table__item', className])}>\n {image && <VComponent className=\"cart-cart-summary-table__item-image-wrapper\" node={image} />}\n <div className=\"cart-cart-summary-table__item-details\">\n {productTitle && <VComponent className=\"cart-cart-summary-table__item-name\" node={productTitle} />}\n {sku && <VComponent className=\"cart-cart-summary-table__sku\" node={sku} />}\n {alert && <VComponent className=\"cart-cart-summary-table__item-quantity-alert-text\" node={alert} />}\n {warning && <VComponent className=\"cart-cart-summary-table__item-quantity-warning-text\" node={warning} />}\n {configurations && <VComponent className=\"cart-cart-summary-table__item-configurations\" node={configurations} />}\n </div>\n </div>\n );\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\n/**\n * This hook provides an API for getting calculated cart items data.\n */\n\nimport { useState, useCallback, useMemo } from 'preact/compat';\nimport { CartModel } from '../data/models';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport { state } from '@/cart/lib/state';\nimport { PriceProps } from '@adobe-commerce/elsie/components/Price';\nimport { updateProductsFromCart } from '@/cart/api';\nimport { debounce } from '@adobe-commerce/elsie/lib';\n\n\n/**\n * Params for the useCartItems hook\n * \n * @param {\n * dictionary: ReturnType<typeof useText>;\n * onQuantityUpdate?: (item: CartModel['items'][number], quantity: number) => void;\n * onItemRemove?: (item: CartModel['items'][number]) => void;\n * }\n * \n * dictionary - The dictionary\n * onQuantityUpdate - The function to call when the quantity is updated\n * onItemRemove - The function to call when the item is removed\n */\nexport interface useCartItemsProps {\n dictionary: ReturnType<typeof useText>;\n onQuantityUpdate?: (item: CartModel['items'][number], quantity: number) => void;\n onItemRemove?: (item: CartModel['items'][number]) => void;\n}\n\n/**\n * Params for the getConfiguration function\n */\ninterface GetConfigurationParams {\n item: CartModel['items'][number];\n}\n\ninterface ItemUpdateState {\n isUpdating: boolean;\n updatedValue: any;\n}\n\n/**\n * Type for the API returned by useCartItems\n *\n * This interface ensures that the returned object from the hook is well-typed and clear for consumers.\n */\nexport interface UseCartItemsApi {\n showIncludedTaxPrice: boolean; // Whether to show prices including tax\n showExcludingTaxPrice: boolean; // Whether to show prices excluding tax\n itemsUpdating: Map<string, ItemUpdateState>; // Tracks which items are currently being updated\n itemUpdateErrors: Map<string, string>; // Tracks update errors for each item\n getConfiguration: (params: GetConfigurationParams) => object | undefined; // Returns configuration details for a cart item\n getPriceProps: (item: CartModel['items'][number]) => PriceProps; // Returns price display props for a cart item\n getSubtotalProps: (item: CartModel['items'][number]) => { subtotalProps: PriceProps; subtotalDiscountProps: PriceProps | null }; // Returns subtotal and discount subtotal props\n processQuantityChange: (item: CartModel['items'][number], value: number) => Promise<void>; // Handles quantity change with state and error management\n debouncedQuantityChange: (item: CartModel['items'][number], value: number) => void; // Debounced version of processQuantityChange\n setItemsUpdating: (itemsUpdating: Map<string, ItemUpdateState>) => void; // Allows external setting of updating state\n getWarningMessage: (item: CartModel['items'][number]) => string | undefined; // Returns warning message for a cart item\n setItemUpdateError: (uid: string, error: string) => void; // Sets or clears update error for an item\n handleRemoveItem: (item: CartModel['items'][number]) => Promise<CartModel | null>; // Removes an item from the cart\n setItemUpdating: (uid: string, state: boolean) => void; // Sets updating state for a specific item\n}\n\n/**\n * useCartItems hook\n *\n * Provides an API for managing and retrieving calculated cart items data, including price, subtotal, configuration, quantity updates, and error handling.\n *\n * @param {Object} params\n * @param {ReturnType<typeof useText>} params.dictionary - The i18n dictionary\n * @param {(item: CartModel['items'][number], quantity: number) => void} [params.onQuantityUpdate] - Callback when item quantity is updated\n * @param {(item: CartModel['items'][number]) => void} [params.onItemRemove] - Callback when item is removed\n *\n * @returns {Object} API for cart item management:\n * - showIncludedTaxPrice: boolean\n * - showExcludingTaxPrice: boolean\n * - itemsUpdating: Map<string, ItemUpdateState>\n * - itemUpdateErrors: Map<string, string>\n * - getConfiguration(item): object | undefined\n * - getPriceProps(item): PriceProps\n * - getSubtotalProps(item): { subtotalProps: PriceProps, subtotalDiscountProps: PriceProps | null }\n * - processQuantityChange(item, value): Promise<void>\n * - debouncedQuantityChange(item, value): void\n * - setItemsUpdating(map): void\n * - getWarningMessage(item): string | undefined\n * - setItemUpdateError(uid, error): void\n * - handleRemoveItem(item): Promise<CartModel>\n * - setItemUpdating(uid, state): void\n */\nexport const useCartItems = ({ dictionary, onQuantityUpdate, onItemRemove }: useCartItemsProps): UseCartItemsApi => {\n // State for tracking which items are being updated (e.g., quantity change in progress)\n const [itemsUpdating, setItemsUpdating] = useState<Map<string, ItemUpdateState>>(new Map());\n // State for tracking errors related to item updates\n const [itemUpdateErrors, setItemUpdateErrors] = useState<Map<string, string>>(new Map());\n\n // Get cart display settings (e.g., tax display mode) from global state\n const cartSettings = state?.config?.shoppingCartDisplaySetting;\n\n // Determine which price display modes are active\n const showIncludedTaxPrice = cartSettings?.price === 'INCLUDING_TAX';\n const showExcludingTaxPrice = cartSettings?.price === 'INCLUDING_EXCLUDING_TAX';\n\n /**\n * Returns a configuration object for the cart item, combining bundle, selected, and customizable options, as well as recipient/sender info.\n * Returns undefined if there is no configuration to show.\n */\n const getConfiguration = ({ item }: GetConfigurationParams) => {\n // Merge all possible configuration sources into a single object\n const configuration = {\n ...item.bundleOptions,\n ...item.selectedOptions,\n ...item.customizableOptions,\n // Add recipient/sender info if present\n ...(item.recipient ? { [dictionary.recipient]: item.recipient } : null),\n ...(item.recipientEmail && item.recipient\n ? {\n [dictionary.recipient]: `${item.recipient} (${item.recipientEmail})`,\n }\n : null),\n ...(item.sender ? { [dictionary.sender]: item.sender } : null),\n ...(item.senderEmail && item.sender\n ? {\n [dictionary.sender]: `${item.sender} (${item.senderEmail})`,\n }\n : {}),\n ...(item.message ? { [dictionary.message]: item.message } : null),\n // Add file/link info if present\n ...(item.links && item.links.count\n ? item.links.count > 1\n ? {\n [dictionary.files.replace(\n '{count}',\n item.links.count.toString()\n )]: item.links.result,\n }\n : {\n [dictionary.file.replace('{count}', item.links.count.toString())]:\n item.links.result,\n }\n : null),\n };\n\n // If no configuration, return undefined\n if (Object.keys(configuration).length === 0) {\n return undefined;\n }\n\n return configuration;\n };\n\n /**\n * Returns price props for the cart item, depending on tax and discount settings.\n * Used for rendering the price in the UI.\n */\n const getPriceProps = (item: CartModel['items'][number]) => {\n return showIncludedTaxPrice\n ? item.discounted\n ? {\n amount: item.regularPrice.value,\n currency: item.regularPrice.currency,\n 'data-testid': 'discounted-regular-item-price',\n }\n : {\n amount: item.taxedPrice?.value,\n currency: item.taxedPrice?.currency,\n 'data-testid': 'taxed-item-price',\n }\n : {\n amount: item.regularPrice?.value,\n currency: item.regularPrice?.currency,\n 'data-testid': 'regular-item-price',\n };\n };\n\n /**\n * Returns subtotal and discount subtotal props for the cart item.\n * Used for rendering the subtotal and any discount in the UI.\n */\n const getSubtotalProps = (item: CartModel['items'][number]) => {\n const subtotalProps: PriceProps = {\n 'aria-label': dictionary.regularPrice,\n };\n // If the item is discounted, prepare a separate object for the discount subtotal\n const subtotalDiscountProps: PriceProps | null = item.discounted ? {} : null;\n\n if (\n ['INCLUDING_TAX', 'INCLUDING_EXCLUDING_TAX'].includes(\n cartSettings?.price as string\n )\n ) {\n subtotalProps['amount'] = item.rowTotalIncludingTax?.value;\n subtotalProps['currency'] = item.rowTotalIncludingTax?.currency;\n subtotalProps['variant'] = item.discounted ? 'strikethrough' : 'default';\n // @ts-ignore: data-testid is used for testing\n subtotalProps['data-testid'] = 'including-tax-item-total';\n\n if (subtotalDiscountProps) {\n // If discounted, show the original total as the discount\n subtotalProps['amount'] = item.total?.value;\n subtotalProps['currency'] = item.total?.currency;\n\n subtotalDiscountProps['amount'] = item.rowTotalIncludingTax?.value;\n subtotalDiscountProps['currency'] = item.rowTotalIncludingTax?.currency;\n subtotalDiscountProps['sale'] = true;\n subtotalDiscountProps['aria-label'] = dictionary.discountedPrice;\n // @ts-ignore: data-testid is used for testing\n subtotalDiscountProps['data-testid'] = 'discount-total';\n }\n } else {\n subtotalProps['amount'] = item.total?.value;\n subtotalProps['currency'] = item.total?.currency;\n subtotalProps['variant'] = item.discounted ? 'strikethrough' : 'default';\n // @ts-ignore: data-testid is used for testing\n subtotalProps['data-testid'] = 'regular-item-total';\n\n if (subtotalDiscountProps) {\n subtotalDiscountProps['amount'] = item.discountedTotal?.value;\n subtotalDiscountProps['currency'] = item.discountedTotal?.currency;\n subtotalDiscountProps['sale'] = true;\n subtotalDiscountProps['aria-label'] = dictionary.regularPrice;\n // @ts-ignore: data-testid is used for testing\n subtotalDiscountProps['data-testid'] = 'discount-total';\n }\n }\n\n return {\n subtotalProps,\n subtotalDiscountProps,\n };\n };\n\n /**\n * Returns a warning message for the cart item, based on update errors, insufficient quantity, or low inventory.\n * Returns undefined if there is no warning.\n */\n const getWarningMessage = (item: CartModel['items'][number]) => {\n // Check for update error first\n const updateErrorMessage = itemUpdateErrors.get(item.uid);\n\n // Check for insufficient quantity\n const insufficientQuantityText = item.insufficientQuantity && item.stockLevel\n ? item.stockLevel === 'noNumber'\n ? dictionary.insufficientQuantityGeneral // No stock level set\n : dictionary.insufficientQuantity // Stock level set\n .replace('{inventory}', item.stockLevel?.toString())\n .replace('{count}', item.quantity.toString())\n : undefined; // Could not generate insufficient quantity text\n\n // Check for low inventory\n const lowInventoryText = item.lowInventory &&\n item.onlyXLeftInStock &&\n dictionary.lowInventory.replace(\n '{count}',\n item.onlyXLeftInStock?.toString()\n );\n\n // Return the first warning found, or undefined\n return updateErrorMessage || insufficientQuantityText || lowInventoryText || undefined;\n };\n\n /**\n * Processes a quantity change for the cart item, updating state and handling errors.\n * Handles optimistic UI updates and error state.\n */\n const processQuantityChange = useCallback(\n async (item: CartModel['items'][number], value: number) => {\n\n /**\n * Updates the quantity for the cart item in the backend.\n * This function is used internally by processQuantityChange.\n */\n const handleQuantityChange = (item: CartModel['items'][number], quantity: number) => {\n return updateProductsFromCart([\n {\n uid: item.uid,\n quantity,\n },\n ]);\n };\n\n if (isNaN(value) || item.quantity === value) {\n return;\n }\n\n // Clear all item update errors before processing\n setItemUpdateErrors(new Map());\n\n try {\n // Mark item as updating\n setItemsUpdating((prev) => {\n const next = new Map(prev);\n next.set(item.uid, { isUpdating: true, updatedValue: value });\n return next;\n });\n\n await handleQuantityChange(item, value);\n\n // Callbacks for item removal or quantity update\n if (value === 0) {\n onItemRemove?.(item);\n } else {\n onQuantityUpdate?.(item, value);\n }\n } catch (error: any) {\n // Remove updating state and set error message\n setItemsUpdating((prev) => {\n const next = new Map(prev);\n next.delete(item.uid);\n return next;\n });\n setItemUpdateErrors((prev) => {\n const next = new Map(prev);\n next.set(item.uid, error.message);\n return next;\n });\n }\n },\n [onItemRemove, onQuantityUpdate]\n );\n\n /**\n * Debounced version of processQuantityChange (500ms delay).\n * Use this to avoid rapid API calls when the user is typing or clicking quickly.\n */\n const debouncedQuantityChange = useMemo(\n () => debounce(processQuantityChange, 500),\n [processQuantityChange]\n );\n\n /**\n * Removes the item from the cart (sets quantity to 0).\n * Also updates the UI state to reflect the removal.\n */\n const handleRemoveItem = (item: CartModel['items'][number]) => {\n setItemsUpdating((prev) => {\n const next = new Map(prev);\n next.set(item.uid, { isUpdating: true, updatedValue: 0 });\n return next;\n });\n return updateProductsFromCart([\n {\n uid: item.uid,\n quantity: 0,\n },\n ]).then((data) => {\n onItemRemove?.(item);\n return Promise.resolve(data);\n });\n };\n\n /**\n * Sets the updating state for a specific cart item.\n * Used to manually mark an item as updating or not.\n */\n const setItemUpdating = (uid: string, state: boolean) => {\n setItemsUpdating((prev) => {\n const next = new Map(prev);\n next.set(uid, { isUpdating: state, updatedValue: state });\n return next;\n });\n };\n\n /**\n * Sets or clears the update error for a specific cart item.\n * Pass an error string to set, or an empty string to clear.\n */\n const setItemUpdateError = (uid: string, error: string) => {\n setItemUpdateErrors((prev) => {\n const next = new Map(prev);\n if (error) {\n next.set(uid, error);\n } else {\n next.delete(uid);\n }\n return next;\n });\n };\n\n // Construct the API object to return from the hook\n const api: UseCartItemsApi = {\n showIncludedTaxPrice,\n showExcludingTaxPrice,\n itemsUpdating,\n itemUpdateErrors,\n getConfiguration,\n getPriceProps,\n getSubtotalProps,\n processQuantityChange,\n debouncedQuantityChange,\n setItemsUpdating,\n getWarningMessage,\n setItemUpdateError,\n handleRemoveItem,\n setItemUpdating,\n };\n\n // Return the API for use in components\n return api;\n};","/********************************************************************\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this \n * file in accordance with the terms of the Adobe license agreement \n * accompanying it. \n *******************************************************************/\n\nimport { Button, Icon } from '@adobe-commerce/elsie/components';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport { Close } from '@adobe-commerce/elsie/icons';\nimport { VComponent, classes } from '@adobe-commerce/elsie/lib';\nimport { FunctionComponent, VNode } from 'preact';\nimport { HTMLAttributes } from 'preact/compat';\n\nimport '@adobe-commerce/elsie/components/InLineAlert/InLineAlert.css';\nexport interface InLineAlertProps\n extends Omit<HTMLAttributes<HTMLDivElement>, 'icon'> {\n variant?: 'primary' | 'secondary';\n heading: string;\n description?: string;\n type?: 'error' | 'warning' | 'success';\n icon?: VNode<HTMLAttributes<SVGSVGElement>>;\n additionalActions?: Array<{\n label: string;\n onClick: (event: Event) => void;\n }>;\n onDismiss?: (event: Event) => void;\n itemList?: VNode;\n actionButtonPosition?: 'top' | 'bottom';\n}\n\nexport const InLineAlert: FunctionComponent<InLineAlertProps> = ({\n variant = 'primary',\n className,\n type = 'warning',\n additionalActions,\n onDismiss,\n heading,\n description,\n icon,\n itemList,\n actionButtonPosition,\n ...props\n}) => {\n const translations = useText({\n dismiss: 'Dropin.InlineAlert.dismissLabel',\n });\n\n return (\n <div\n {...props}\n className={classes([\n 'dropin-in-line-alert',\n `dropin-in-line-alert--${type}`,\n `dropin-in-line-alert--${variant}`,\n className,\n ])}\n >\n <div className={'dropin-in-line-alert__heading'}>\n <div className={'dropin-in-line-alert__title-container'}>\n {icon && (\n <VComponent node={icon} className={'dropin-in-line-alert__icon'} />\n )}\n\n <span className={'dropin-in-line-alert__title'}>{heading}</span>\n </div>\n\n <div className={'dropin-in-line-alert__actions-container'}>\n {additionalActions &&\n (actionButtonPosition === 'top' ||\n (!actionButtonPosition && additionalActions.length <= 1)) && (\n <Button\n variant=\"tertiary\"\n className={'dropin-in-line-alert__additional-action'}\n onClick={\n additionalActions.length > 0\n ? additionalActions[0]?.onClick\n : undefined\n }\n aria-label={additionalActions[0]?.label}\n >\n {additionalActions[0]?.label}\n </Button>\n )}\n {onDismiss && (\n <Button\n icon={<Icon source={Close} size=\"24\" stroke=\"2\" />}\n className={'dropin-in-line-alert__dismiss-button'}\n variant=\"tertiary\"\n onClick={onDismiss}\n aria-label={translations.dismiss}\n />\n )}\n </div>\n </div>\n\n {description && (\n <p className={'dropin-in-line-alert__description'}>{description}</p>\n )}\n <div className={'dropin-in-line-alert__item-list-container'}>\n {itemList && (\n <VComponent\n node={itemList}\n className={classes(['dropin-in-line-alert__item-list'])}\n />\n )}\n </div>\n {additionalActions &&\n (actionButtonPosition === 'bottom' ||\n (!actionButtonPosition && additionalActions.length > 1)) && (\n <div className={'dropin-in-line-alert__additional-actions-container'}>\n {additionalActions.map((action) => (\n <Button\n key={action.label}\n variant=\"tertiary\"\n className={'dropin-in-line-alert__additional-action'}\n onClick={action.onClick}\n >\n {action.label}\n </Button>\n ))}\n </div>\n )}\n </div>\n );\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { HTMLAttributes } from 'preact/compat';\nimport { classes, Container, Slot, SlotProps } from '@adobe-commerce/elsie/lib';\nimport { CartModel } from '@/cart/data/models/cart-model';\nimport { CartSummaryTable as CartSummaryTableComponent } from '@/cart/components';\nimport {\n Price,\n Skeleton,\n SkeletonRow,\n Image,\n ImageProps,\n Icon,\n Button,\n} from '@adobe-commerce/elsie/components';\nimport { useState, useEffect, useMemo, useCallback } from 'preact/hooks';\nimport { events } from '@adobe-commerce/event-bus';\nimport {\n Cart,\n OrderError,\n Trash,\n WarningWithCircle,\n} from '@adobe-commerce/elsie/icons';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport { Item } from '@/cart/components/CartSummaryTable/Elements/Item/Item';\nimport { useCartItems } from '@/cart/hooks/useCartItems';\nimport { getPersistedCartData } from '@/cart/lib/persisted-data';\nimport { InLineAlert } from '@adobe-commerce/elsie/components/InLineAlert';\nimport { addProductsToCart } from '@/cart/api/addProductsToCart/addProductsToCart';\nimport { VNode } from 'preact';\nimport { EmptyCart } from '@/cart/containers/EmptyCart';\n\nexport interface CartSummaryTableContainerProps\n extends HTMLAttributes<HTMLDivElement> {\n /** Initial data for the cart */\n initialData?: CartModel | null;\n /** Optional CSS class name for custom styling */\n className?: string;\n /** Slots for customizing different parts of the table */\n slots?: {\n /** Slot for customizing the item cell content */\n Item?: SlotProps<{ item: CartModel['items'][number] }>;\n /** Slot for customizing the price cell content */\n Price?: SlotProps<{ item: CartModel['items'][number] }>;\n /** Slot for customizing the quantity cell content */\n Quantity?: SlotProps<{\n item: CartModel['items'][number];\n isUpdating: boolean;\n quantityInputValue: number;\n handleInputChange: (e: Event) => void;\n itemUpdateErrors: Map<string, string>;\n }>;\n /** Slot for customizing the subtotal cell content */\n Subtotal?: SlotProps<{ item: CartModel['items'][number] }>;\n /** Slot for customizing the thumbnail image on an item */\n Thumbnail?: SlotProps<{\n item: CartModel['items'][number];\n defaultImageProps: ImageProps;\n index: number;\n }>;\n /** Slot for customizing the product title on an item */\n ProductTitle?: SlotProps<{ item: CartModel['items'][number] }>;\n /** Slot for customizing the product sku on an item */\n Sku?: SlotProps<{ item: CartModel['items'][number] }>;\n /** Slot for customizing the product configurations on an item */\n Configurations?: SlotProps<{ item: CartModel['items'][number] }>;\n /** Slot for customizing the product alert on an item */\n ItemAlert?: SlotProps<{ item: CartModel['items'][number] }>;\n /** Slot for customizing the product warning on an item */\n ItemWarning?: SlotProps<{ item: CartModel['items'][number] }>;\n /** Slot for customizing the actions on an item */\n Actions?: SlotProps<{\n item: CartModel['items'][number];\n itemsUpdating: Map<string, { isUpdating: boolean; updatedValue: number }>;\n setItemUpdating: (uid: string, state: boolean) => void;\n setItemUpdateError: (uid: string, error: string) => void;\n }>;\n UndoBanner?: SlotProps<{\n item: CartModel['items'][number];\n loading: boolean;\n error?: string;\n onUndo: () => void;\n onDismiss: () => void;\n }>;\n /** Slot for customizing the empty cart */\n EmptyCart?: SlotProps;\n };\n /** Function for getting the product page route */\n routeProduct?: (item: CartModel['items'][number]) => string;\n /** Function for getting the empty cart CTA route */\n routeEmptyCartCTA?: () => string;\n /** Whether to allow quantity updates */\n allowQuantityUpdates?: boolean;\n /** Whether to allow remove items */\n allowRemoveItems?: boolean;\n /** On quantity update */\n onQuantityUpdate?: (\n item: CartModel['items'][number],\n quantity: number\n ) => void;\n /** On item remove */\n onItemRemove?: (item: CartModel['items'][number]) => void;\n /** Whether to enable undo functionality for removed items */\n undo?: boolean;\n}\n\n/**\n * Skeleton loader component for the cart summary table\n */\nconst CartSummaryTableSkeleton = () => {\n return (\n <Skeleton\n data-testid=\"cart-summary-table-skeleton\"\n className=\"cart-cart-summary-table__skeleton\"\n rowGap=\"medium\"\n >\n <SkeletonRow\n variant=\"row\"\n size=\"xlarge\"\n fullWidth={true}\n lines={4}\n multilineGap=\"small\"\n />\n </Skeleton>\n );\n};\n\n/**\n * Container component for CartSummaryTable that provides slots for customizing the table cells\n * and handles data management\n */\nexport const CartSummaryTable: Container<\n CartSummaryTableContainerProps,\n CartModel | null\n> = ({\n initialData = null,\n routeProduct,\n routeEmptyCartCTA,\n slots,\n className,\n allowQuantityUpdates = true,\n allowRemoveItems = true,\n onQuantityUpdate,\n onItemRemove,\n undo = false,\n ...props\n}) => {\n const [loading, setLoading] = useState(!initialData);\n const [cartModelData, setCartModelData] = useState<CartModel | null>(\n initialData\n );\n const [recentlyRemovedItems, setRecentlyRemovedItems] = useState<\n {\n item: CartModel['items'][number];\n index: number;\n loading: boolean;\n error?: string;\n }[]\n >([]);\n /** I18n text for the cart summary table */\n const dictionary = useText({\n file: 'Cart.CartItem.file',\n files: 'Cart.CartItem.files',\n heading: 'Cart.Cart.heading',\n message: 'Cart.CartItem.message',\n recipient: 'Cart.CartItem.recipient',\n regularPrice: 'Cart.CartItem.regularPrice',\n discountedPrice: 'Cart.CartItem.discountedPrice',\n sender: 'Cart.CartItem.sender',\n lowInventory: 'Cart.CartItem.lowInventory',\n insufficientQuantity: 'Cart.CartItem.insufficientQuantity',\n insufficientQuantityGeneral: 'Cart.CartItem.insufficientQuantityGeneral',\n outOfStockHeading: 'Cart.OutOfStockMessage.heading',\n outOfStockDescription: 'Cart.OutOfStockMessage.message',\n outOfStockAlert: 'Cart.OutOfStockMessage.alert',\n removeAction: 'Cart.OutOfStockMessage.action',\n notAvailableMessage: 'Cart.CartItem.notAvailableMessage',\n viewMore: 'Cart.Cart.viewMore',\n viewAll: 'Cart.Cart.viewAll',\n discountPercent: 'Cart.CartItem.discountPercentage',\n savingsAmount: 'Cart.CartItem.savingsAmount',\n includingTax: 'Cart.CartItem.includingTax',\n excludingTax: 'Cart.CartItem.excludingTax',\n remove: 'Dropin.CartItem.remove.label',\n removeDefault: 'Dropin.CartItem.removeDefault.label',\n quantity: 'Dropin.CartItem.quantity.label',\n itemBeingRemoved: 'Cart.CartItem.itemBeingRemoved',\n itemRemoved: 'Cart.CartItem.itemRemoved',\n itemRemovedDescription: 'Cart.CartItem.itemRemovedDescription',\n undoAction: 'Cart.CartItem.undoAction',\n dismissAction: 'Cart.CartItem.dismissAction',\n });\n\n /** Helper functions */\n const {\n showIncludedTaxPrice,\n showExcludingTaxPrice,\n itemsUpdating,\n itemUpdateErrors,\n getConfiguration,\n getPriceProps,\n getSubtotalProps,\n debouncedQuantityChange,\n setItemsUpdating,\n getWarningMessage,\n handleRemoveItem,\n setItemUpdating,\n setItemUpdateError,\n } = useCartItems({ dictionary, onQuantityUpdate, onItemRemove });\n\n // Helper to add to recently removed items for undo\n function addToRecentlyRemovedItems(uid: string) {\n const cart = getPersistedCartData();\n const item = cart?.items.find((i) => i.uid === uid);\n if (item) {\n setRecentlyRemovedItems((prev) => {\n const index = cart.items.findIndex((i) => i.uid === uid);\n if (index !== -1 && !prev.some((r) => r.item.uid === uid)) {\n // Emit the event for analytics or listeners\n events.emit('cart/product/removed', { item, index });\n return [...prev, { item, index, loading: false, error: undefined }];\n }\n return prev;\n });\n }\n }\n\n const handleUndo = createUndoHandler(\n recentlyRemovedItems,\n setRecentlyRemovedItems\n );\n\n const handleDismiss = createDismissHandler(setRecentlyRemovedItems);\n\n const handleRemoveWithUndo = useCallback(\n (item: CartModel['items'][number]) => {\n if (undo) {\n addToRecentlyRemovedItems(item.uid);\n }\n handleRemoveItem(item); // original remove logic\n },\n [undo, handleRemoveItem]\n );\n\n /**\n * Handle the cart data event\n */\n useEffect(() => {\n const cartDataEvent = events.on(\n 'cart/data',\n (payload: Cart | null) => {\n setLoading(true);\n setCartModelData(payload as CartModel);\n setItemsUpdating(new Map());\n setLoading(false);\n },\n { eager: true }\n );\n\n return () => {\n cartDataEvent?.off();\n };\n }, [setLoading, setCartModelData, setItemsUpdating]);\n\n // Transform cart items into table entries with slots for customization\n const entries = useMemo(\n () =>\n cartModelData?.items\n ?.sort((a, b) => {\n // Sort out of stock items and items with update errors last\n // to show them at the top since we are rendering the list in reverse order\n if (itemUpdateErrors.has(a.uid) && !itemUpdateErrors.has(b.uid))\n return -1;\n if (!itemUpdateErrors.has(a.uid) && itemUpdateErrors.has(b.uid))\n return 1;\n if (a.outOfStock && !b.outOfStock) return -1;\n if (!a.outOfStock && b.outOfStock) return 1;\n return 0;\n })\n .map((item, index) => {\n const isUpdating = itemsUpdating.has(item.uid);\n const warningMessage = getWarningMessage(item);\n\n const productTitle = (\n <Slot\n name=\"ProductTitle\"\n slot={slots?.ProductTitle}\n context={{ item }}\n >\n {routeProduct ? (\n <a href={routeProduct(item)}>{item.name}</a>\n ) : (\n item.name\n )}\n </Slot>\n );\n\n const defaultImageProps = {\n src: item.image.src,\n alt: item.image.alt,\n width: '300',\n height: '300',\n params: { width: 300 },\n };\n\n const defaultImage = (\n <Image\n data-testid={`cart-table-item-image-${item.sku}`}\n loading={index < 4 ? 'eager' : 'lazy'}\n {...defaultImageProps}\n />\n );\n\n const productImage = (\n <Slot\n name=\"Thumbnail\"\n slot={slots?.Thumbnail}\n className=\"cart-cart-summary-table__item-image-wrapper\"\n context={{\n item,\n defaultImageProps: {\n ...defaultImageProps,\n loading: index < 4 ? 'eager' : 'lazy',\n },\n index,\n }}\n >\n {routeProduct ? (\n <a href={routeProduct(item)}>{defaultImage}</a>\n ) : (\n defaultImage\n )}\n </Slot>\n );\n\n const productSku = (\n <Slot name=\"Sku\" slot={slots?.Sku} context={{ item }}>\n {item.sku}\n </Slot>\n );\n\n const itemAlert =\n item.outOfStock || slots?.ItemAlert ? (\n <Slot name=\"ItemAlert\" slot={slots?.ItemAlert} context={{ item }}>\n {item.outOfStock && (\n <div\n className=\"cart-cart-summary-table__item-quantity-alert-wrapper\"\n data-testid={`cart-table-item-quantity-alert-${item.uid}`}\n >\n <Icon\n className=\"cart-cart-summary-table__item-quantity-alert-icon\"\n source={OrderError}\n size={'16'}\n />\n <span className=\"cart-cart-summary-table__item-quantity-alert-text\">\n {dictionary.outOfStockAlert}\n </span>\n </div>\n )}\n </Slot>\n ) : undefined;\n\n const itemWarning =\n warningMessage || slots?.ItemWarning ? (\n <Slot\n name=\"ItemWarning\"\n slot={slots?.ItemWarning}\n context={{ item }}\n >\n {warningMessage && (\n <div\n className=\"cart-cart-summary-table__item-quantity-warning-wrapper\"\n data-testid={`cart-table-item-quantity-warning-${item.uid}`}\n >\n <Icon\n className=\"cart-cart-summary-table__item-quantity-warning-icon\"\n source={WarningWithCircle}\n size={'16'}\n />\n <span className=\"cart-cart-summary-table__item-quantity-warning-text\">\n {warningMessage}\n </span>\n </div>\n )}\n </Slot>\n ) : undefined;\n\n const itemConfigurations = getConfiguration({ item });\n const productConfigurations =\n itemConfigurations || slots?.Configurations ? (\n <Slot\n name=\"Configurations\"\n slot={slots?.Configurations}\n context={{ item }}\n >\n {itemConfigurations && (\n <ul\n className=\"cart-cart-summary-table__item-configurations\"\n data-testid={`cart-table-item-configurations-${item.sku}`}\n >\n {Object.entries(itemConfigurations).map(([key, value]) => (\n <li\n className=\"cart-cart-summary-table__item-configuration\"\n data-testid={`cart-table-item-configuration-${key}`}\n key={key}\n >\n <span className=\"cart-cart-summary-table__item-configuration-label\">\n {key}:\n </span>\n <span className=\"cart-cart-summary-table__item-configuration-value\">\n {value}\n </span>\n </li>\n ))}\n </ul>\n )}\n </Slot>\n ) : undefined;\n\n const { subtotalProps, subtotalDiscountProps } =\n getSubtotalProps(item);\n\n const updatedValue = itemsUpdating.get(item.uid)?.updatedValue;\n const quantityInputValue =\n isUpdating && !isNaN(updatedValue) ? updatedValue : item.quantity;\n\n const handleInputChange = (e: Event) => {\n const target = e.target as HTMLInputElement;\n const value = parseInt(target.value, 10);\n\n debouncedQuantityChange(item, value);\n };\n\n const isBeingRemoved =\n itemsUpdating.has(item.uid) &&\n itemsUpdating.get(item.uid)?.updatedValue === 0;\n const actions = (\n <Slot\n name=\"Actions\"\n slot={slots?.Actions}\n context={{\n item,\n itemsUpdating,\n setItemUpdating,\n setItemUpdateError,\n }}\n >\n {allowRemoveItems && !isBeingRemoved && (\n <Button\n variant=\"tertiary\"\n size=\"medium\"\n className=\"cart-cart-summary-table__item-remove-button\"\n data-testid={`cart-table-item-remove-${item.uid}`}\n icon={<Icon source={Trash} size={'32'} />}\n onClick={() => handleRemoveWithUndo(item)}\n aria-label={\n dictionary.remove?.replace('{product}', item.name) ||\n dictionary.removeDefault\n }\n />\n )}\n </Slot>\n );\n\n return {\n key: item.uid,\n uid: item.uid,\n updating: isUpdating,\n hasError: item.outOfStock || itemUpdateErrors.has(item.uid),\n item: (\n <Slot name=\"Item\" slot={slots?.Item} context={{ item }}>\n <Item\n productTitle={productTitle}\n image={productImage}\n sku={productSku}\n configurations={productConfigurations}\n alert={itemAlert}\n warning={itemWarning}\n />\n </Slot>\n ),\n price: (\n <Slot\n name=\"Price\"\n className=\"cart-cart-summary-table__item-price\"\n slot={slots?.Price}\n context={{ item }}\n >\n <Price {...getPriceProps(item)} />\n {showIncludedTaxPrice && (\n <span className=\"cart-cart-summary-table__item-price-tax-label\">\n {dictionary.includingTax}:&nbsp;\n <Price\n amount={item.taxedPrice?.value}\n currency={item.taxedPrice?.currency}\n />\n </span>\n )}\n {showExcludingTaxPrice && (\n <span className=\"cart-cart-summary-table__item-price-tax-label\">\n {dictionary.excludingTax}:&nbsp;\n <Price\n amount={item.regularPrice?.value}\n currency={item.regularPrice?.currency}\n />\n </span>\n )}\n </Slot>\n ),\n quantity: (\n <Slot\n name=\"Quantity\"\n className=\"cart-cart-summary-table__item-qty\"\n slot={slots?.Quantity}\n context={{\n item,\n isUpdating,\n quantityInputValue,\n handleInputChange,\n itemUpdateErrors,\n }}\n >\n {allowQuantityUpdates ? (\n <input\n id={`cart-table-item-quantity-${item.uid}`}\n data-testid={`cart-table-item-quantity-${item.uid}`}\n type=\"number\"\n min=\"1\"\n value={quantityInputValue}\n disabled={isUpdating}\n aria-label={dictionary.quantity}\n className={classes([\n 'cart-cart-summary-table__cell-qty-input',\n 'cart-cart-summary-table__cell-qty-updater',\n [\n 'cart-cart-summary-table__cell-qty-updater--disabled',\n isUpdating,\n ],\n [\n 'cart-cart-summary-table__cell-qty-updater--error',\n itemUpdateErrors.has(item.uid),\n ],\n ])}\n onChange={handleInputChange}\n />\n ) : (\n <span>{item.quantity}</span>\n )}\n </Slot>\n ),\n subtotal: (\n <Slot\n name=\"Subtotal\"\n className=\"cart-cart-summary-table__item-subtotal\"\n slot={slots?.Subtotal}\n context={{ item }}\n >\n <Price {...subtotalProps} />\n {subtotalDiscountProps && <Price {...subtotalDiscountProps} />}\n {showIncludedTaxPrice && (\n <span className=\"cart-cart-summary-table__item-subtotal-tax-label\">\n {dictionary.includingTax}:&nbsp;\n <Price\n amount={item.rowTotalIncludingTax?.value}\n currency={item.rowTotalIncludingTax?.currency}\n />\n </span>\n )}\n {showExcludingTaxPrice && (\n <span className=\"cart-cart-summary-table__item-subtotal-tax-label\">\n {dictionary.excludingTax}:&nbsp;\n <Price\n amount={item.rowTotal?.value}\n currency={item.rowTotal?.currency}\n />\n </span>\n )}\n </Slot>\n ),\n actions,\n };\n }) || [],\n [\n cartModelData,\n itemsUpdating,\n allowQuantityUpdates,\n routeProduct,\n slots,\n itemUpdateErrors,\n dictionary,\n getConfiguration,\n allowRemoveItems,\n debouncedQuantityChange,\n getWarningMessage,\n getPriceProps,\n getSubtotalProps,\n setItemUpdating,\n setItemUpdateError,\n showIncludedTaxPrice,\n showExcludingTaxPrice,\n handleRemoveWithUndo,\n ]\n );\n\n /**\n * Render the cart summary table skeleton if the cart is loading\n */\n if (loading) {\n return <CartSummaryTableSkeleton />;\n }\n const renderTableWithUndoBanners = () => {\n if (!cartModelData?.items) return null;\n const tableEntries: any[] = [];\n const items = cartModelData.items;\n\n // Process items up to the available entries length\n for (let i = 0; i <= entries.length; i++) {\n // Render undo banners for this index position if undo is enabled\n if (undo) {\n recentlyRemovedItems\n .filter((r) => r.index === i)\n .forEach(({ item, error }) => {\n const isUndoBeingRemoved = getIsUndoBeingRemoved(item.uid, itemsUpdating);\n const undoBanner = createUndoBanner(\n { item, index: i, error },\n item,\n isUndoBeingRemoved,\n dictionary,\n handleUndo,\n handleDismiss,\n slots\n );\n \n // Add undo banner as a special entry\n tableEntries.push({\n uid: `undo-banner-${item.uid}`,\n updating: false,\n hasError: false,\n item: <div />,\n price: <div />,\n quantity: <div />,\n subtotal: <div />,\n actions: <div />,\n undoBanner,\n });\n });\n }\n \n // Render cart item if not at the end and within the entries limit\n if (i < entries.length && i < items.length) {\n tableEntries.push(entries[i]);\n }\n }\n \n return (\n <CartSummaryTableComponent\n entries={tableEntries}\n className={className}\n {...props}\n />\n );\n };\n\n /**\n * Create empty cart component with undo banner support\n */\n const emptyCart = (\n <Slot name=\"EmptyCart\" slot={slots?.EmptyCart} context={{}}>\n <EmptyCart ctaLinkURL={routeEmptyCartCTA?.()} />\n </Slot>\n );\n\n /**\n * Choose between original table entries and undo banner version (matches CartSummaryList logic)\n */\n const tableContent = \n cartModelData?.totalQuantity ||\n (undo && recentlyRemovedItems.length > 0) ? (\n !undo ? (\n <CartSummaryTableComponent\n entries={entries}\n className={className}\n {...props}\n />\n ) : recentlyRemovedItems.length > 0 ? (\n renderTableWithUndoBanners()\n ) : (\n <CartSummaryTableComponent\n entries={entries}\n className={className}\n {...props}\n />\n )\n ) : emptyCart;\n\n /**\n * Render the cart summary table\n */\n return tableContent;\n};\n\nCartSummaryTable.getInitialData = async function () {\n return getPersistedCartData();\n};\n\nexport const createUndoHandler = (\n recentlyRemovedItems: {\n item: CartModel['items'][number];\n index: number;\n loading: boolean;\n error?: string;\n }[],\n setRecentlyRemovedItems: (\n updater: (\n prev: {\n item: CartModel['items'][number];\n index: number;\n loading: boolean;\n error?: string;\n }[]\n ) => {\n item: CartModel['items'][number];\n index: number;\n loading: boolean;\n error?: string;\n }[]\n ) => void\n) => {\n return async (uid: string) => {\n setRecentlyRemovedItems((prev) =>\n prev.map((r) => (r.item.uid === uid ? { ...r, error: undefined } : r))\n );\n\n const removed = recentlyRemovedItems.find((r) => r.item.uid === uid);\n if (!removed) return;\n\n try {\n await addProductsToCart([\n {\n sku: removed.item.sku,\n parentSku: removed.item.topLevelSku,\n quantity: removed.item.quantity,\n optionsUIDs:\n removed.item.bundleOptionsUIDs || // Use bundle option UIDs for bundle products\n (removed.item.selectedOptionsUIDs\n ? Object.values(removed.item.selectedOptionsUIDs)\n : undefined),\n enteredOptions: removed.item.customizableOptions\n ? Object.entries(removed.item.customizableOptions).map(\n ([uid, value]) => ({ uid, value })\n )\n : undefined,\n },\n ]);\n setRecentlyRemovedItems((prev) => prev.filter((r) => r.item.uid !== uid));\n } catch (error: any) {\n setRecentlyRemovedItems((prev) =>\n prev.map((r) =>\n r.item.uid === uid\n ? { ...r, error: error?.message || 'Failed to restore item.' }\n : r\n )\n );\n }\n };\n};\n\nexport const createDismissHandler = (\n setRecentlyRemovedItems: (\n updater: (\n prev: {\n item: CartModel['items'][number];\n index: number;\n loading: boolean;\n error?: string;\n }[]\n ) => {\n item: CartModel['items'][number];\n index: number;\n loading: boolean;\n error?: string;\n }[]\n ) => void\n) => {\n return (uid: string) => {\n setRecentlyRemovedItems((prev) => prev.filter((r) => r.item.uid !== uid));\n };\n};\n\n/**\n * Helper function to determine if an undo is currently being removed\n * This makes the logic more explicit and testable\n */\nexport const getIsUndoBeingRemoved = (\n itemUid: string,\n itemsUpdating: Map<string, { isUpdating: boolean; updatedValue: number }>\n): boolean => {\n return itemsUpdating.has(itemUid) && itemsUpdating.get(itemUid)?.updatedValue === 0;\n};\n\n/**\n * Helper function to create additional actions for undo banner\n * This makes the ternary operator logic more explicit and testable\n */\nexport const createUndoBannerActions = (\n isUndoBeingRemoved: boolean,\n dictionary: any,\n handleUndo: (uid: string) => void,\n handleDismiss: (uid: string) => void,\n itemUid: string,\n itemName: string\n) => {\n if (isUndoBeingRemoved) {\n return []; // Hide buttons while removing\n }\n \n return [\n {\n label: dictionary.undoAction,\n onClick: () => {\n handleUndo(itemUid);\n },\n 'aria-label': `${dictionary.undoAction} remove ${itemName}`,\n },\n {\n label: dictionary.dismissAction,\n onClick: () => {\n handleDismiss(itemUid);\n },\n 'aria-label': `${dictionary.dismissAction} undo for ${itemName}`,\n },\n ];\n};\n\n/**\n * Helper function to create undo callback\n */\nexport const createUndoCallback = (\n handleUndo: (uid: string) => void,\n itemUid: string\n) => {\n return () => handleUndo(itemUid);\n};\n\n/**\n * Helper function to create dismiss callback\n */\nexport const createDismissCallback = (\n handleDismiss: (uid: string) => void,\n itemUid: string\n) => {\n return () => handleDismiss(itemUid);\n};\n\nexport const createUndoBanner = (\n removed: { item: CartModel['items'][number]; index: number; error?: string },\n item: CartModel['items'][number],\n isUndoBeingRemoved: boolean,\n dictionary: any,\n handleUndo: (uid: string) => void,\n handleDismiss: (uid: string) => void,\n slots?: CartSummaryTableContainerProps['slots']\n): VNode => {\n const additionalActions = createUndoBannerActions(\n isUndoBeingRemoved,\n dictionary,\n handleUndo,\n handleDismiss,\n removed.item.uid,\n removed.item.name\n );\n\n const onUndoCallback = createUndoCallback(handleUndo, removed.item.uid);\n const onDismissCallback = createDismissCallback(handleDismiss, removed.item.uid);\n\n return (\n <Slot\n name=\"UndoBanner\"\n slot={slots?.UndoBanner}\n context={{\n item: removed.item,\n loading: isUndoBeingRemoved,\n error: removed.error,\n onUndo: onUndoCallback,\n onDismiss: onDismissCallback,\n }}\n key={`undo-banner-${removed.item.uid}`}\n >\n <InLineAlert\n key={`undo-banner-${removed.item.uid}`}\n type={removed.error ? 'error' : 'info'}\n heading={\n isUndoBeingRemoved\n ? dictionary.itemBeingRemoved?.replace('{product}', item.name)\n : dictionary.itemRemoved?.replace('{product}', removed.item.name)\n }\n description={removed.error || dictionary.itemRemovedDescription}\n variant=\"primary\"\n actionButtonPosition=\"bottom\"\n additionalActions={additionalActions}\n />\n </Slot>\n );\n};\n"],"names":["SvgTrash","props","React","CartSummaryTable","entries","className","dictionary","useText","jsxs","classes","jsx","entry","VComponent","Item","productTitle","sku","image","configurations","alert","warning","useCartItems","onQuantityUpdate","onItemRemove","itemsUpdating","setItemsUpdating","useState","itemUpdateErrors","setItemUpdateErrors","cartSettings","_b","_a","state","showIncludedTaxPrice","showExcludingTaxPrice","getConfiguration","item","configuration","getPriceProps","_c","_d","getSubtotalProps","subtotalProps","subtotalDiscountProps","_e","_f","_g","_h","_i","_j","getWarningMessage","updateErrorMessage","insufficientQuantityText","lowInventoryText","processQuantityChange","useCallback","value","handleQuantityChange","quantity","updateProductsFromCart","prev","next","error","debouncedQuantityChange","useMemo","debounce","uid","data","InLineAlert","variant","type","additionalActions","onDismiss","heading","description","icon","itemList","actionButtonPosition","translations","Button","Icon","Close","action","CartSummaryTableSkeleton","Skeleton","SkeletonRow","initialData","routeProduct","routeEmptyCartCTA","slots","allowQuantityUpdates","allowRemoveItems","undo","loading","setLoading","cartModelData","setCartModelData","recentlyRemovedItems","setRecentlyRemovedItems","handleRemoveItem","setItemUpdating","setItemUpdateError","addToRecentlyRemovedItems","cart","getPersistedCartData","i","index","r","events","handleUndo","createUndoHandler","handleDismiss","createDismissHandler","handleRemoveWithUndo","useEffect","cartDataEvent","payload","a","b","isUpdating","warningMessage","Slot","defaultImageProps","defaultImage","Image","productImage","productSku","itemAlert","OrderError","itemWarning","WarningWithCircle","itemConfigurations","productConfigurations","key","updatedValue","quantityInputValue","handleInputChange","e","target","isBeingRemoved","actions","Trash","Price","_k","renderTableWithUndoBanners","tableEntries","items","isUndoBeingRemoved","getIsUndoBeingRemoved","undoBanner","createUndoBanner","CartSummaryTableComponent","emptyCart","EmptyCart","removed","addProductsToCart","itemUid","createUndoBannerActions","itemName","createUndoCallback","createDismissCallback","onUndoCallback","onDismissCallback"],"mappings":"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","x_google_ignoreList":[0,4]}
1
+ {"version":3,"file":"CartSummaryTable2.js","sources":["/@dropins/storefront-cart/src/components/CartSummaryTable/CartSummaryTable.tsx","/@dropins/storefront-cart/src/components/CartSummaryTable/Elements/Item/Item.tsx","/@dropins/storefront-cart/src/hooks/useCartItems.ts","../../node_modules/@adobe-commerce/elsie/src/components/InLineAlert/InLineAlert.tsx","/@dropins/storefront-cart/src/containers/CartSummaryTable/CartSummaryTable.tsx"],"sourcesContent":["/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\n/**\n * CartSummaryTable is a responsive grid-based component that displays cart items in a table-like format.\n * It adapts to mobile views by switching to a stacked layout with labeled sections.\n * \n * @component\n */\n\nimport { FunctionComponent, VNode } from 'preact';\nimport { HTMLAttributes } from 'preact/compat';\nimport { classes, VComponent } from '@adobe-commerce/elsie/lib';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport '@/cart/components/CartSummaryTable/CartSummaryTable.css';\n\n/**\n * Represents a single row entry in the cart summary table\n * Each field accepts a VNode to allow for flexible content rendering\n */\nexport interface CartTableEntry {\n /** The item UID */\n uid: string;\n /** Whether the item is updating */\n updating: boolean;\n /** Whether the item has an update error */\n hasError: boolean;\n /** The product details section (typically includes image, name, and options) */\n item: VNode;\n /** The unit price of the product */\n price: VNode;\n /** The quantity selector/display */\n quantity: VNode;\n /** The total price for this line item */\n subtotal: VNode;\n /** Actions bar on the bottom of the row */\n actions: VNode;\n /** Optional undo banner for removed items */\n undoBanner?: VNode;\n}\n\n/**\n * Props for the CartSummaryTable component\n */\nexport interface CartSummaryTableProps extends HTMLAttributes<HTMLDivElement> {\n /** Array of cart entries to display in the table */\n entries: CartTableEntry[];\n /** Optional CSS class name for custom styling */\n className?: string;\n}\n\n/**\n * CartSummaryTable component displays cart items in a responsive grid layout\n * - Uses CSS Grid for layout with 4 columns on desktop\n * - Switches to a stacked single-column layout on mobile with labeled sections\n * - Renders each entry's content using VComponent for proper component handling\n */\nexport const CartSummaryTable: FunctionComponent<CartSummaryTableProps> = ({\n entries,\n className,\n ...props\n}) => {\n const dictionary = useText({\n itemLabel: 'Cart.CartSummaryTable.item',\n priceLabel: 'Cart.CartSummaryTable.price',\n qtyLabel: 'Cart.CartSummaryTable.qty',\n subtotalLabel: 'Cart.CartSummaryTable.subtotal',\n mobilePriceLabel: 'Cart.CartSummaryTable.mobilePrice',\n mobileQtyLabel: 'Cart.CartSummaryTable.mobileQty',\n mobileSubtotalLabel: 'Cart.CartSummaryTable.mobileSubtotal'\n });\n\n return (\n <div {...props} className={classes(['cart-cart-summary-table', className])}>\n {/* Table header - hidden on mobile */}\n <div className=\"cart-cart-summary-table__header\">\n <div className=\"cart-cart-summary-table__header-item\">{dictionary.itemLabel}</div>\n <div className=\"cart-cart-summary-table__header-price\">{dictionary.priceLabel}</div>\n <div className=\"cart-cart-summary-table__header-qty\">{dictionary.qtyLabel}</div>\n <div className=\"cart-cart-summary-table__header-subtotal\">{dictionary.subtotalLabel}</div>\n </div>\n {/* Table body - adapts to grid layout on mobile */}\n <div className=\"cart-cart-summary-table__body\">\n {entries.map((entry) => {\n // If this entry is an undo banner, render it as a full-width banner\n if (entry.undoBanner) {\n return (\n <div key={entry.uid} className=\"cart-cart-summary-table__undo-banner\">\n <VComponent node={entry.undoBanner} />\n </div>\n );\n }\n \n // Otherwise render as a regular table row\n return (\n <div key={entry.uid} className={classes([\n 'cart-cart-summary-table__row',\n [ 'cart-cart-summary-table__row--updating', entry.updating ],\n [ 'cart-cart-summary-table__row--error', entry.hasError ],\n ])}\n >\n <div className=\"cart-cart-summary-table__cell-item\">\n <VComponent node={entry.item} />\n </div>\n <div className=\"cart-cart-summary-table__cell-price\">\n <span className=\"cart-cart-summary-table__mobile-label\">{dictionary.mobilePriceLabel}</span>\n <VComponent node={entry.price} />\n </div>\n <div className=\"cart-cart-summary-table__cell-qty\">\n <span className=\"cart-cart-summary-table__mobile-label\">{dictionary.mobileQtyLabel}</span>\n <VComponent node={entry.quantity} />\n </div>\n <div className=\"cart-cart-summary-table__cell-subtotal\">\n <span className=\"cart-cart-summary-table__mobile-label\">{dictionary.mobileSubtotalLabel}</span>\n <VComponent node={entry.subtotal} />\n </div>\n <div className=\"cart-cart-summary-table__item-footer\">\n <VComponent className=\"cart-cart-summary-table__item-actions\" node={entry.actions} />\n </div>\n </div>\n );\n })}\n </div>\n </div>\n );\n};\n","/********************************************************************\n * Copyright 2025 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this \n * file in accordance with the terms of the Adobe license agreement \n * accompanying it. \n *******************************************************************/\n \nimport { FunctionComponent, VNode } from 'preact';\nimport { HTMLAttributes } from 'preact/compat';\nimport { classes, VComponent } from '@adobe-commerce/elsie/lib';\nimport '@/cart/components/CartSummaryTable/Elements/Item/Item.css';\n\nexport interface ItemProps extends HTMLAttributes<HTMLDivElement> {\n productTitle: VNode;\n sku?: VNode;\n image?: VNode;\n configurations?: VNode;\n alert?: VNode;\n warning?: VNode;\n}\n\nexport const Item: FunctionComponent<ItemProps> = ({\n className,\n productTitle,\n sku,\n image,\n configurations,\n alert,\n warning,\n ...props\n}) => {\n return (\n <div {...props} className={classes(['cart-cart-summary-table__item', className])}>\n {image && <VComponent className=\"cart-cart-summary-table__item-image-wrapper\" node={image} />}\n <div className=\"cart-cart-summary-table__item-details\">\n {productTitle && <VComponent className=\"cart-cart-summary-table__item-name\" node={productTitle} />}\n {sku && <VComponent className=\"cart-cart-summary-table__sku\" node={sku} />}\n {alert && <VComponent className=\"cart-cart-summary-table__item-quantity-alert-text\" node={alert} />}\n {warning && <VComponent className=\"cart-cart-summary-table__item-quantity-warning-text\" node={warning} />}\n {configurations && <VComponent className=\"cart-cart-summary-table__item-configurations\" node={configurations} />}\n </div>\n </div>\n );\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\n/**\n * This hook provides an API for getting calculated cart items data.\n */\n\nimport { useState, useCallback, useMemo } from 'preact/compat';\nimport { CartModel } from '../data/models';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport { state } from '@/cart/lib/state';\nimport { PriceProps } from '@adobe-commerce/elsie/components/Price';\nimport { updateProductsFromCart } from '@/cart/api';\nimport { debounce } from '@adobe-commerce/elsie/lib';\n\n\n/**\n * Params for the useCartItems hook\n * \n * @param {\n * dictionary: ReturnType<typeof useText>;\n * onQuantityUpdate?: (item: CartModel['items'][number], quantity: number) => void;\n * onItemRemove?: (item: CartModel['items'][number]) => void;\n * }\n * \n * dictionary - The dictionary\n * onQuantityUpdate - The function to call when the quantity is updated\n * onItemRemove - The function to call when the item is removed\n */\nexport interface useCartItemsProps {\n dictionary: ReturnType<typeof useText>;\n onQuantityUpdate?: (item: CartModel['items'][number], quantity: number) => void;\n onItemRemove?: (item: CartModel['items'][number]) => void;\n}\n\n/**\n * Params for the getConfiguration function\n */\ninterface GetConfigurationParams {\n item: CartModel['items'][number];\n}\n\ninterface ItemUpdateState {\n isUpdating: boolean;\n updatedValue: any;\n}\n\n/**\n * Type for the API returned by useCartItems\n *\n * This interface ensures that the returned object from the hook is well-typed and clear for consumers.\n */\nexport interface UseCartItemsApi {\n showIncludedTaxPrice: boolean; // Whether to show prices including tax\n showExcludingTaxPrice: boolean; // Whether to show prices excluding tax\n itemsUpdating: Map<string, ItemUpdateState>; // Tracks which items are currently being updated\n itemUpdateErrors: Map<string, string>; // Tracks update errors for each item\n getConfiguration: (params: GetConfigurationParams) => object | undefined; // Returns configuration details for a cart item\n getPriceProps: (item: CartModel['items'][number]) => PriceProps; // Returns price display props for a cart item\n getSubtotalProps: (item: CartModel['items'][number]) => { subtotalProps: PriceProps; subtotalDiscountProps: PriceProps | null }; // Returns subtotal and discount subtotal props\n processQuantityChange: (item: CartModel['items'][number], value: number) => Promise<void>; // Handles quantity change with state and error management\n debouncedQuantityChange: (item: CartModel['items'][number], value: number) => void; // Debounced version of processQuantityChange\n setItemsUpdating: (itemsUpdating: Map<string, ItemUpdateState>) => void; // Allows external setting of updating state\n getWarningMessage: (item: CartModel['items'][number]) => string | undefined; // Returns warning message for a cart item\n setItemUpdateError: (uid: string, error: string) => void; // Sets or clears update error for an item\n handleRemoveItem: (item: CartModel['items'][number]) => Promise<CartModel | null>; // Removes an item from the cart\n setItemUpdating: (uid: string, state: boolean) => void; // Sets updating state for a specific item\n}\n\n/**\n * useCartItems hook\n *\n * Provides an API for managing and retrieving calculated cart items data, including price, subtotal, configuration, quantity updates, and error handling.\n *\n * @param {Object} params\n * @param {ReturnType<typeof useText>} params.dictionary - The i18n dictionary\n * @param {(item: CartModel['items'][number], quantity: number) => void} [params.onQuantityUpdate] - Callback when item quantity is updated\n * @param {(item: CartModel['items'][number]) => void} [params.onItemRemove] - Callback when item is removed\n *\n * @returns {Object} API for cart item management:\n * - showIncludedTaxPrice: boolean\n * - showExcludingTaxPrice: boolean\n * - itemsUpdating: Map<string, ItemUpdateState>\n * - itemUpdateErrors: Map<string, string>\n * - getConfiguration(item): object | undefined\n * - getPriceProps(item): PriceProps\n * - getSubtotalProps(item): { subtotalProps: PriceProps, subtotalDiscountProps: PriceProps | null }\n * - processQuantityChange(item, value): Promise<void>\n * - debouncedQuantityChange(item, value): void\n * - setItemsUpdating(map): void\n * - getWarningMessage(item): string | undefined\n * - setItemUpdateError(uid, error): void\n * - handleRemoveItem(item): Promise<CartModel>\n * - setItemUpdating(uid, state): void\n */\nexport const useCartItems = ({ dictionary, onQuantityUpdate, onItemRemove }: useCartItemsProps): UseCartItemsApi => {\n // State for tracking which items are being updated (e.g., quantity change in progress)\n const [itemsUpdating, setItemsUpdating] = useState<Map<string, ItemUpdateState>>(new Map());\n // State for tracking errors related to item updates\n const [itemUpdateErrors, setItemUpdateErrors] = useState<Map<string, string>>(new Map());\n\n // Get cart display settings (e.g., tax display mode) from global state\n const cartSettings = state?.config?.shoppingCartDisplaySetting;\n\n // Determine which price display modes are active\n const showIncludedTaxPrice = cartSettings?.price === 'INCLUDING_TAX';\n const showExcludingTaxPrice = cartSettings?.price === 'INCLUDING_EXCLUDING_TAX';\n\n /**\n * Returns a configuration object for the cart item, combining bundle, selected, and customizable options, as well as recipient/sender info.\n * Returns undefined if there is no configuration to show.\n */\n const getConfiguration = ({ item }: GetConfigurationParams) => {\n // Merge all possible configuration sources into a single object\n const configuration = {\n ...item.bundleOptions,\n ...item.selectedOptions,\n ...item.customizableOptions,\n // Add recipient/sender info if present\n ...(item.recipient ? { [dictionary.recipient]: item.recipient } : null),\n ...(item.recipientEmail && item.recipient\n ? {\n [dictionary.recipient]: `${item.recipient} (${item.recipientEmail})`,\n }\n : null),\n ...(item.sender ? { [dictionary.sender]: item.sender } : null),\n ...(item.senderEmail && item.sender\n ? {\n [dictionary.sender]: `${item.sender} (${item.senderEmail})`,\n }\n : {}),\n ...(item.message ? { [dictionary.message]: item.message } : null),\n // Add file/link info if present\n ...(item.links && item.links.count\n ? item.links.count > 1\n ? {\n [dictionary.files.replace(\n '{count}',\n item.links.count.toString()\n )]: item.links.result,\n }\n : {\n [dictionary.file.replace('{count}', item.links.count.toString())]:\n item.links.result,\n }\n : null),\n };\n\n // If no configuration, return undefined\n if (Object.keys(configuration).length === 0) {\n return undefined;\n }\n\n return configuration;\n };\n\n /**\n * Returns price props for the cart item, depending on tax and discount settings.\n * Used for rendering the price in the UI.\n */\n const getPriceProps = (item: CartModel['items'][number]) => {\n return showIncludedTaxPrice\n ? item.discounted\n ? {\n amount: item.regularPrice.value,\n currency: item.regularPrice.currency,\n 'data-testid': 'discounted-regular-item-price',\n }\n : {\n amount: item.taxedPrice?.value,\n currency: item.taxedPrice?.currency,\n 'data-testid': 'taxed-item-price',\n }\n : {\n amount: item.regularPrice?.value,\n currency: item.regularPrice?.currency,\n 'data-testid': 'regular-item-price',\n };\n };\n\n /**\n * Returns subtotal and discount subtotal props for the cart item.\n * Used for rendering the subtotal and any discount in the UI.\n */\n const getSubtotalProps = (item: CartModel['items'][number]) => {\n const subtotalProps: PriceProps = {\n 'aria-label': dictionary.regularPrice,\n };\n // If the item is discounted, prepare a separate object for the discount subtotal\n const subtotalDiscountProps: PriceProps | null = item.discounted ? {} : null;\n\n if (\n ['INCLUDING_TAX', 'INCLUDING_EXCLUDING_TAX'].includes(\n cartSettings?.price as string\n )\n ) {\n subtotalProps['amount'] = item.rowTotalIncludingTax?.value;\n subtotalProps['currency'] = item.rowTotalIncludingTax?.currency;\n subtotalProps['variant'] = item.discounted ? 'strikethrough' : 'default';\n // @ts-ignore: data-testid is used for testing\n subtotalProps['data-testid'] = 'including-tax-item-total';\n\n if (subtotalDiscountProps) {\n // If discounted, show the original total as the discount\n subtotalProps['amount'] = item.total?.value;\n subtotalProps['currency'] = item.total?.currency;\n\n subtotalDiscountProps['amount'] = item.rowTotalIncludingTax?.value;\n subtotalDiscountProps['currency'] = item.rowTotalIncludingTax?.currency;\n subtotalDiscountProps['sale'] = true;\n subtotalDiscountProps['aria-label'] = dictionary.discountedPrice;\n // @ts-ignore: data-testid is used for testing\n subtotalDiscountProps['data-testid'] = 'discount-total';\n }\n } else {\n subtotalProps['amount'] = item.total?.value;\n subtotalProps['currency'] = item.total?.currency;\n subtotalProps['variant'] = item.discounted ? 'strikethrough' : 'default';\n // @ts-ignore: data-testid is used for testing\n subtotalProps['data-testid'] = 'regular-item-total';\n\n if (subtotalDiscountProps) {\n subtotalDiscountProps['amount'] = item.discountedTotal?.value;\n subtotalDiscountProps['currency'] = item.discountedTotal?.currency;\n subtotalDiscountProps['sale'] = true;\n subtotalDiscountProps['aria-label'] = dictionary.regularPrice;\n // @ts-ignore: data-testid is used for testing\n subtotalDiscountProps['data-testid'] = 'discount-total';\n }\n }\n\n return {\n subtotalProps,\n subtotalDiscountProps,\n };\n };\n\n /**\n * Returns a warning message for the cart item, based on update errors, insufficient quantity, or low inventory.\n * Returns undefined if there is no warning.\n */\n const getWarningMessage = (item: CartModel['items'][number]) => {\n // Check for update error first\n const updateErrorMessage = itemUpdateErrors.get(item.uid);\n\n // Check for insufficient quantity\n const insufficientQuantityText = item.insufficientQuantity && item.stockLevel\n ? item.stockLevel === 'noNumber'\n ? dictionary.insufficientQuantityGeneral // No stock level set\n : dictionary.insufficientQuantity // Stock level set\n .replace('{inventory}', item.stockLevel?.toString())\n .replace('{count}', item.quantity.toString())\n : undefined; // Could not generate insufficient quantity text\n\n // Check for low inventory\n const lowInventoryText = item.lowInventory &&\n item.onlyXLeftInStock &&\n dictionary.lowInventory.replace(\n '{count}',\n item.onlyXLeftInStock?.toString()\n );\n\n // Return the first warning found, or undefined\n return updateErrorMessage || insufficientQuantityText || lowInventoryText || undefined;\n };\n\n /**\n * Processes a quantity change for the cart item, updating state and handling errors.\n * Handles optimistic UI updates and error state.\n */\n const processQuantityChange = useCallback(\n async (item: CartModel['items'][number], value: number) => {\n\n /**\n * Updates the quantity for the cart item in the backend.\n * This function is used internally by processQuantityChange.\n */\n const handleQuantityChange = (item: CartModel['items'][number], quantity: number) => {\n return updateProductsFromCart([\n {\n uid: item.uid,\n quantity,\n },\n ]);\n };\n\n if (isNaN(value) || item.quantity === value) {\n return;\n }\n\n // Clear all item update errors before processing\n setItemUpdateErrors(new Map());\n\n try {\n // Mark item as updating\n setItemsUpdating((prev) => {\n const next = new Map(prev);\n next.set(item.uid, { isUpdating: true, updatedValue: value });\n return next;\n });\n\n await handleQuantityChange(item, value);\n\n // Callbacks for item removal or quantity update\n if (value === 0) {\n onItemRemove?.(item);\n } else {\n onQuantityUpdate?.(item, value);\n }\n } catch (error: any) {\n // Remove updating state and set error message\n setItemsUpdating((prev) => {\n const next = new Map(prev);\n next.delete(item.uid);\n return next;\n });\n setItemUpdateErrors((prev) => {\n const next = new Map(prev);\n next.set(item.uid, error.message);\n return next;\n });\n }\n },\n [onItemRemove, onQuantityUpdate]\n );\n\n /**\n * Debounced version of processQuantityChange (500ms delay).\n * Use this to avoid rapid API calls when the user is typing or clicking quickly.\n */\n const debouncedQuantityChange = useMemo(\n () => debounce(processQuantityChange, 500),\n [processQuantityChange]\n );\n\n /**\n * Removes the item from the cart (sets quantity to 0).\n * Also updates the UI state to reflect the removal.\n */\n const handleRemoveItem = (item: CartModel['items'][number]) => {\n setItemsUpdating((prev) => {\n const next = new Map(prev);\n next.set(item.uid, { isUpdating: true, updatedValue: 0 });\n return next;\n });\n return updateProductsFromCart([\n {\n uid: item.uid,\n quantity: 0,\n },\n ]).then((data) => {\n onItemRemove?.(item);\n return Promise.resolve(data);\n });\n };\n\n /**\n * Sets the updating state for a specific cart item.\n * Used to manually mark an item as updating or not.\n */\n const setItemUpdating = (uid: string, state: boolean) => {\n setItemsUpdating((prev) => {\n const next = new Map(prev);\n next.set(uid, { isUpdating: state, updatedValue: state });\n return next;\n });\n };\n\n /**\n * Sets or clears the update error for a specific cart item.\n * Pass an error string to set, or an empty string to clear.\n */\n const setItemUpdateError = (uid: string, error: string) => {\n setItemUpdateErrors((prev) => {\n const next = new Map(prev);\n if (error) {\n next.set(uid, error);\n } else {\n next.delete(uid);\n }\n return next;\n });\n };\n\n // Construct the API object to return from the hook\n const api: UseCartItemsApi = {\n showIncludedTaxPrice,\n showExcludingTaxPrice,\n itemsUpdating,\n itemUpdateErrors,\n getConfiguration,\n getPriceProps,\n getSubtotalProps,\n processQuantityChange,\n debouncedQuantityChange,\n setItemsUpdating,\n getWarningMessage,\n setItemUpdateError,\n handleRemoveItem,\n setItemUpdating,\n };\n\n // Return the API for use in components\n return api;\n};","/********************************************************************\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: Adobe permits you to use, modify, and distribute this \n * file in accordance with the terms of the Adobe license agreement \n * accompanying it. \n *******************************************************************/\n\nimport { Button, Icon } from '@adobe-commerce/elsie/components';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport { Close } from '@adobe-commerce/elsie/icons';\nimport { VComponent, classes } from '@adobe-commerce/elsie/lib';\nimport { FunctionComponent, VNode } from 'preact';\nimport { HTMLAttributes } from 'preact/compat';\n\nimport '@adobe-commerce/elsie/components/InLineAlert/InLineAlert.css';\nexport interface InLineAlertProps\n extends Omit<HTMLAttributes<HTMLDivElement>, 'icon'> {\n variant?: 'primary' | 'secondary';\n heading: string;\n description?: string;\n type?: 'error' | 'warning' | 'success';\n icon?: VNode<HTMLAttributes<SVGSVGElement>>;\n additionalActions?: Array<{\n label: string;\n onClick: (event: Event) => void;\n }>;\n onDismiss?: (event: Event) => void;\n itemList?: VNode;\n actionButtonPosition?: 'top' | 'bottom';\n}\n\nexport const InLineAlert: FunctionComponent<InLineAlertProps> = ({\n variant = 'primary',\n className,\n type = 'warning',\n additionalActions,\n onDismiss,\n heading,\n description,\n icon,\n itemList,\n actionButtonPosition,\n ...props\n}) => {\n const translations = useText({\n dismiss: 'Dropin.InlineAlert.dismissLabel',\n });\n\n return (\n <div\n {...props}\n className={classes([\n 'dropin-in-line-alert',\n `dropin-in-line-alert--${type}`,\n `dropin-in-line-alert--${variant}`,\n className,\n ])}\n >\n <div className={'dropin-in-line-alert__heading'}>\n <div className={'dropin-in-line-alert__title-container'}>\n {icon && (\n <VComponent node={icon} className={'dropin-in-line-alert__icon'} />\n )}\n\n <span className={'dropin-in-line-alert__title'}>{heading}</span>\n </div>\n\n <div className={'dropin-in-line-alert__actions-container'}>\n {additionalActions &&\n (actionButtonPosition === 'top' ||\n (!actionButtonPosition && additionalActions.length <= 1)) && (\n <Button\n variant=\"tertiary\"\n className={'dropin-in-line-alert__additional-action'}\n onClick={\n additionalActions.length > 0\n ? additionalActions[0]?.onClick\n : undefined\n }\n aria-label={additionalActions[0]?.label}\n >\n {additionalActions[0]?.label}\n </Button>\n )}\n {onDismiss && (\n <Button\n icon={<Icon source={Close} size=\"24\" stroke=\"2\" />}\n className={'dropin-in-line-alert__dismiss-button'}\n variant=\"tertiary\"\n onClick={onDismiss}\n aria-label={translations.dismiss}\n />\n )}\n </div>\n </div>\n\n {description && (\n <p className={'dropin-in-line-alert__description'}>{description}</p>\n )}\n <div className={'dropin-in-line-alert__item-list-container'}>\n {itemList && (\n <VComponent\n node={itemList}\n className={classes(['dropin-in-line-alert__item-list'])}\n />\n )}\n </div>\n {additionalActions &&\n (actionButtonPosition === 'bottom' ||\n (!actionButtonPosition && additionalActions.length > 1)) && (\n <div className={'dropin-in-line-alert__additional-actions-container'}>\n {additionalActions.map((action) => (\n <Button\n key={action.label}\n variant=\"tertiary\"\n className={'dropin-in-line-alert__additional-action'}\n onClick={action.onClick}\n >\n {action.label}\n </Button>\n ))}\n </div>\n )}\n </div>\n );\n};\n","/********************************************************************\n * ADOBE CONFIDENTIAL\n * __________________\n *\n * Copyright 2024 Adobe\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n *******************************************************************/\n\nimport { HTMLAttributes } from 'preact/compat';\nimport { classes, Container, Slot, SlotProps } from '@adobe-commerce/elsie/lib';\nimport { CartModel } from '@/cart/data/models/cart-model';\nimport { CartSummaryTable as CartSummaryTableComponent } from '@/cart/components';\nimport {\n Price,\n Skeleton,\n SkeletonRow,\n Image,\n ImageProps,\n Icon,\n Button,\n} from '@adobe-commerce/elsie/components';\nimport { useState, useEffect, useMemo, useCallback } from 'preact/hooks';\nimport { events } from '@adobe-commerce/event-bus';\nimport {\n Cart,\n OrderError,\n Trash,\n WarningWithCircle,\n} from '@adobe-commerce/elsie/icons';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport { Item } from '@/cart/components/CartSummaryTable/Elements/Item/Item';\nimport { useCartItems } from '@/cart/hooks/useCartItems';\nimport { getPersistedCartData } from '@/cart/lib/persisted-data';\nimport { InLineAlert } from '@adobe-commerce/elsie/components/InLineAlert';\nimport { addProductsToCart } from '@/cart/api/addProductsToCart/addProductsToCart';\nimport { VNode } from 'preact';\nimport { EmptyCart } from '@/cart/containers/EmptyCart';\n\nexport interface CartSummaryTableContainerProps\n extends HTMLAttributes<HTMLDivElement> {\n /** Initial data for the cart */\n initialData?: CartModel | null;\n /** Optional CSS class name for custom styling */\n className?: string;\n /** Slots for customizing different parts of the table */\n slots?: {\n /** Slot for customizing the item cell content */\n Item?: SlotProps<{ item: CartModel['items'][number] }>;\n /** Slot for customizing the price cell content */\n Price?: SlotProps<{ item: CartModel['items'][number] }>;\n /** Slot for customizing the quantity cell content */\n Quantity?: SlotProps<{\n item: CartModel['items'][number];\n isUpdating: boolean;\n quantityInputValue: number;\n handleInputChange: (e: Event) => void;\n itemUpdateErrors: Map<string, string>;\n }>;\n /** Slot for customizing the subtotal cell content */\n Subtotal?: SlotProps<{ item: CartModel['items'][number] }>;\n /** Slot for customizing the thumbnail image on an item */\n Thumbnail?: SlotProps<{\n item: CartModel['items'][number];\n defaultImageProps: ImageProps;\n index: number;\n }>;\n /** Slot for customizing the product title on an item */\n ProductTitle?: SlotProps<{ item: CartModel['items'][number] }>;\n /** Slot for customizing the product sku on an item */\n Sku?: SlotProps<{ item: CartModel['items'][number] }>;\n /** Slot for customizing the product configurations on an item */\n Configurations?: SlotProps<{ item: CartModel['items'][number] }>;\n /** Slot for customizing the product alert on an item */\n ItemAlert?: SlotProps<{ item: CartModel['items'][number] }>;\n /** Slot for customizing the product warning on an item */\n ItemWarning?: SlotProps<{ item: CartModel['items'][number] }>;\n /** Slot for customizing the actions on an item */\n Actions?: SlotProps<{\n item: CartModel['items'][number];\n itemsUpdating: Map<string, { isUpdating: boolean; updatedValue: number }>;\n setItemUpdating: (uid: string, state: boolean) => void;\n setItemUpdateError: (uid: string, error: string) => void;\n }>;\n UndoBanner?: SlotProps<{\n item: CartModel['items'][number];\n loading: boolean;\n error?: string;\n onUndo: () => void;\n onDismiss: () => void;\n }>;\n /** Slot for customizing the empty cart */\n EmptyCart?: SlotProps;\n };\n /** Function for getting the product page route */\n routeProduct?: (item: CartModel['items'][number]) => string;\n /** Function for getting the empty cart CTA route */\n routeEmptyCartCTA?: () => string;\n /** Whether to allow quantity updates */\n allowQuantityUpdates?: boolean;\n /** Whether to allow remove items */\n allowRemoveItems?: boolean;\n /** On quantity update */\n onQuantityUpdate?: (\n item: CartModel['items'][number],\n quantity: number\n ) => void;\n /** On item remove */\n onItemRemove?: (item: CartModel['items'][number]) => void;\n /** Whether to enable undo functionality for removed items */\n undo?: boolean;\n}\n\n/**\n * Skeleton loader component for the cart summary table\n */\nconst CartSummaryTableSkeleton = () => {\n return (\n <Skeleton\n data-testid=\"cart-summary-table-skeleton\"\n className=\"cart-cart-summary-table__skeleton\"\n rowGap=\"medium\"\n >\n <SkeletonRow\n variant=\"row\"\n size=\"xlarge\"\n fullWidth={true}\n lines={4}\n multilineGap=\"small\"\n />\n </Skeleton>\n );\n};\n\n/**\n * Container component for CartSummaryTable that provides slots for customizing the table cells\n * and handles data management\n */\nexport const CartSummaryTable: Container<\n CartSummaryTableContainerProps,\n CartModel | null\n> = ({\n initialData = null,\n routeProduct,\n routeEmptyCartCTA,\n slots,\n className,\n allowQuantityUpdates = true,\n allowRemoveItems = true,\n onQuantityUpdate,\n onItemRemove,\n undo = false,\n ...props\n}) => {\n const [loading, setLoading] = useState(!initialData);\n const [cartModelData, setCartModelData] = useState<CartModel | null>(\n initialData\n );\n const [recentlyRemovedItems, setRecentlyRemovedItems] = useState<\n {\n item: CartModel['items'][number];\n index: number;\n loading: boolean;\n error?: string;\n }[]\n >([]);\n /** I18n text for the cart summary table */\n const dictionary = useText({\n file: 'Cart.CartItem.file',\n files: 'Cart.CartItem.files',\n heading: 'Cart.Cart.heading',\n message: 'Cart.CartItem.message',\n recipient: 'Cart.CartItem.recipient',\n regularPrice: 'Cart.CartItem.regularPrice',\n discountedPrice: 'Cart.CartItem.discountedPrice',\n sender: 'Cart.CartItem.sender',\n lowInventory: 'Cart.CartItem.lowInventory',\n insufficientQuantity: 'Cart.CartItem.insufficientQuantity',\n insufficientQuantityGeneral: 'Cart.CartItem.insufficientQuantityGeneral',\n outOfStockHeading: 'Cart.OutOfStockMessage.heading',\n outOfStockDescription: 'Cart.OutOfStockMessage.message',\n outOfStockAlert: 'Cart.OutOfStockMessage.alert',\n removeAction: 'Cart.OutOfStockMessage.action',\n notAvailableMessage: 'Cart.CartItem.notAvailableMessage',\n viewMore: 'Cart.Cart.viewMore',\n viewAll: 'Cart.Cart.viewAll',\n discountPercent: 'Cart.CartItem.discountPercentage',\n savingsAmount: 'Cart.CartItem.savingsAmount',\n includingTax: 'Cart.CartItem.includingTax',\n excludingTax: 'Cart.CartItem.excludingTax',\n remove: 'Dropin.CartItem.remove.label',\n removeDefault: 'Dropin.CartItem.removeDefault.label',\n quantity: 'Dropin.CartItem.quantity.label',\n itemBeingRemoved: 'Cart.CartItem.itemBeingRemoved',\n itemRemoved: 'Cart.CartItem.itemRemoved',\n itemRemovedDescription: 'Cart.CartItem.itemRemovedDescription',\n undoAction: 'Cart.CartItem.undoAction',\n dismissAction: 'Cart.CartItem.dismissAction',\n });\n\n /** Helper functions */\n const {\n showIncludedTaxPrice,\n showExcludingTaxPrice,\n itemsUpdating,\n itemUpdateErrors,\n getConfiguration,\n getPriceProps,\n getSubtotalProps,\n debouncedQuantityChange,\n setItemsUpdating,\n getWarningMessage,\n handleRemoveItem,\n setItemUpdating,\n setItemUpdateError,\n } = useCartItems({ dictionary, onQuantityUpdate, onItemRemove });\n\n // Helper to add to recently removed items for undo\n function addToRecentlyRemovedItems(uid: string) {\n const cart = getPersistedCartData();\n const item = cart?.items.find((i) => i.uid === uid);\n if (item) {\n setRecentlyRemovedItems((prev) => {\n const index = cart.items.findIndex((i) => i.uid === uid);\n if (index !== -1 && !prev.some((r) => r.item.uid === uid)) {\n // Emit the event for analytics or listeners\n events.emit('cart/product/removed', { item, index });\n return [...prev, { item, index, loading: false, error: undefined }];\n }\n return prev;\n });\n }\n }\n\n const handleUndo = createUndoHandler(\n recentlyRemovedItems,\n setRecentlyRemovedItems\n );\n\n const handleDismiss = createDismissHandler(setRecentlyRemovedItems);\n\n const handleRemoveWithUndo = useCallback(\n (item: CartModel['items'][number]) => {\n if (undo) {\n addToRecentlyRemovedItems(item.uid);\n }\n handleRemoveItem(item); // original remove logic\n },\n [undo, handleRemoveItem]\n );\n\n /**\n * Handle the cart data event\n */\n useEffect(() => {\n const cartDataEvent = events.on(\n 'cart/data',\n (payload: Cart | null) => {\n setLoading(true);\n setCartModelData(payload as CartModel);\n setItemsUpdating(new Map());\n setLoading(false);\n },\n { eager: true }\n );\n\n return () => {\n cartDataEvent?.off();\n };\n }, [setLoading, setCartModelData, setItemsUpdating]);\n\n // Transform cart items into table entries with slots for customization\n const entries = useMemo(\n () =>\n cartModelData?.items\n ?.sort((a, b) => {\n // Sort out of stock items and items with update errors last\n // to show them at the top since we are rendering the list in reverse order\n if (itemUpdateErrors.has(a.uid) && !itemUpdateErrors.has(b.uid))\n return -1;\n if (!itemUpdateErrors.has(a.uid) && itemUpdateErrors.has(b.uid))\n return 1;\n if (a.outOfStock && !b.outOfStock) return -1;\n if (!a.outOfStock && b.outOfStock) return 1;\n return 0;\n })\n .map((item, index) => {\n const isUpdating = itemsUpdating.has(item.uid);\n const warningMessage = getWarningMessage(item);\n\n const productTitle = (\n <Slot\n name=\"ProductTitle\"\n slot={slots?.ProductTitle}\n context={{ item }}\n >\n {routeProduct ? (\n <a href={routeProduct(item)}>{item.name}</a>\n ) : (\n item.name\n )}\n </Slot>\n );\n\n const defaultImageProps = {\n src: item.image.src,\n alt: item.image.alt,\n width: '300',\n height: '300',\n params: { width: 300 },\n };\n\n const defaultImage = (\n <Image\n data-testid={`cart-table-item-image-${item.sku}`}\n loading={index < 4 ? 'eager' : 'lazy'}\n {...defaultImageProps}\n />\n );\n\n const productImage = (\n <Slot\n name=\"Thumbnail\"\n slot={slots?.Thumbnail}\n className=\"cart-cart-summary-table__item-image-wrapper\"\n context={{\n item,\n defaultImageProps: {\n ...defaultImageProps,\n loading: index < 4 ? 'eager' : 'lazy',\n },\n index,\n }}\n >\n {routeProduct ? (\n <a href={routeProduct(item)}>{defaultImage}</a>\n ) : (\n defaultImage\n )}\n </Slot>\n );\n\n const productSku = (\n <Slot name=\"Sku\" slot={slots?.Sku} context={{ item }}>\n {item.sku}\n </Slot>\n );\n\n const itemAlert =\n item.outOfStock || slots?.ItemAlert ? (\n <Slot name=\"ItemAlert\" slot={slots?.ItemAlert} context={{ item }}>\n {item.outOfStock && (\n <div\n className=\"cart-cart-summary-table__item-quantity-alert-wrapper\"\n data-testid={`cart-table-item-quantity-alert-${item.uid}`}\n >\n <Icon\n className=\"cart-cart-summary-table__item-quantity-alert-icon\"\n source={OrderError}\n size={'16'}\n />\n <span className=\"cart-cart-summary-table__item-quantity-alert-text\">\n {dictionary.outOfStockAlert}\n </span>\n </div>\n )}\n </Slot>\n ) : undefined;\n\n const itemWarning =\n warningMessage || slots?.ItemWarning ? (\n <Slot\n name=\"ItemWarning\"\n slot={slots?.ItemWarning}\n context={{ item }}\n >\n {warningMessage && (\n <div\n className=\"cart-cart-summary-table__item-quantity-warning-wrapper\"\n data-testid={`cart-table-item-quantity-warning-${item.uid}`}\n >\n <Icon\n className=\"cart-cart-summary-table__item-quantity-warning-icon\"\n source={WarningWithCircle}\n size={'16'}\n />\n <span className=\"cart-cart-summary-table__item-quantity-warning-text\">\n {warningMessage}\n </span>\n </div>\n )}\n </Slot>\n ) : undefined;\n\n const itemConfigurations = getConfiguration({ item });\n const productConfigurations =\n itemConfigurations || slots?.Configurations ? (\n <Slot\n name=\"Configurations\"\n slot={slots?.Configurations}\n context={{ item }}\n >\n {itemConfigurations && (\n <ul\n className=\"cart-cart-summary-table__item-configurations\"\n data-testid={`cart-table-item-configurations-${item.sku}`}\n >\n {Object.entries(itemConfigurations).map(([key, value]) => (\n <li\n className=\"cart-cart-summary-table__item-configuration\"\n data-testid={`cart-table-item-configuration-${key}`}\n key={key}\n >\n <span className=\"cart-cart-summary-table__item-configuration-label\">\n {key}:\n </span>\n <span className=\"cart-cart-summary-table__item-configuration-value\">\n {value}\n </span>\n </li>\n ))}\n </ul>\n )}\n </Slot>\n ) : undefined;\n\n const { subtotalProps, subtotalDiscountProps } =\n getSubtotalProps(item);\n\n const updatedValue = itemsUpdating.get(item.uid)?.updatedValue;\n const quantityInputValue =\n isUpdating && !isNaN(updatedValue) ? updatedValue : item.quantity;\n\n const handleInputChange = (e: Event) => {\n const target = e.target as HTMLInputElement;\n const value = parseInt(target.value, 10);\n\n debouncedQuantityChange(item, value);\n };\n\n const isBeingRemoved =\n itemsUpdating.has(item.uid) &&\n itemsUpdating.get(item.uid)?.updatedValue === 0;\n const actions = (\n <Slot\n name=\"Actions\"\n slot={slots?.Actions}\n context={{\n item,\n itemsUpdating,\n setItemUpdating,\n setItemUpdateError,\n }}\n >\n {allowRemoveItems && !isBeingRemoved && (\n <Button\n variant=\"tertiary\"\n size=\"medium\"\n className=\"cart-cart-summary-table__item-remove-button\"\n data-testid={`cart-table-item-remove-${item.uid}`}\n icon={<Icon source={Trash} size={'32'} />}\n onClick={() => handleRemoveWithUndo(item)}\n aria-label={\n dictionary.remove?.replace('{product}', item.name) ||\n dictionary.removeDefault\n }\n />\n )}\n </Slot>\n );\n\n return {\n key: item.uid,\n uid: item.uid,\n updating: isUpdating,\n hasError: item.outOfStock || itemUpdateErrors.has(item.uid),\n item: (\n <Slot name=\"Item\" slot={slots?.Item} context={{ item }}>\n <Item\n productTitle={productTitle}\n image={productImage}\n sku={productSku}\n configurations={productConfigurations}\n alert={itemAlert}\n warning={itemWarning}\n />\n </Slot>\n ),\n price: (\n <Slot\n name=\"Price\"\n className=\"cart-cart-summary-table__item-price\"\n slot={slots?.Price}\n context={{ item }}\n >\n <Price {...getPriceProps(item)} />\n {showIncludedTaxPrice && (\n <span className=\"cart-cart-summary-table__item-price-tax-label\">\n {dictionary.includingTax}:&nbsp;\n <Price\n amount={item.taxedPrice?.value}\n currency={item.taxedPrice?.currency}\n />\n </span>\n )}\n {showExcludingTaxPrice && (\n <span className=\"cart-cart-summary-table__item-price-tax-label\">\n {dictionary.excludingTax}:&nbsp;\n <Price\n amount={item.regularPrice?.value}\n currency={item.regularPrice?.currency}\n />\n </span>\n )}\n </Slot>\n ),\n quantity: (\n <Slot\n name=\"Quantity\"\n className=\"cart-cart-summary-table__item-qty\"\n slot={slots?.Quantity}\n context={{\n item,\n isUpdating,\n quantityInputValue,\n handleInputChange,\n itemUpdateErrors,\n }}\n >\n {allowQuantityUpdates ? (\n <input\n id={`cart-table-item-quantity-${item.uid}`}\n data-testid={`cart-table-item-quantity-${item.uid}`}\n type=\"number\"\n min=\"1\"\n value={quantityInputValue}\n disabled={isUpdating}\n aria-label={dictionary.quantity}\n className={classes([\n 'cart-cart-summary-table__cell-qty-input',\n 'cart-cart-summary-table__cell-qty-updater',\n [\n 'cart-cart-summary-table__cell-qty-updater--disabled',\n isUpdating,\n ],\n [\n 'cart-cart-summary-table__cell-qty-updater--error',\n itemUpdateErrors.has(item.uid),\n ],\n ])}\n onChange={handleInputChange}\n />\n ) : (\n <span>{item.quantity}</span>\n )}\n </Slot>\n ),\n subtotal: (\n <Slot\n name=\"Subtotal\"\n className=\"cart-cart-summary-table__item-subtotal\"\n slot={slots?.Subtotal}\n context={{ item }}\n >\n <Price {...subtotalProps} />\n {subtotalDiscountProps && <Price {...subtotalDiscountProps} />}\n {showIncludedTaxPrice && (\n <span className=\"cart-cart-summary-table__item-subtotal-tax-label\">\n {dictionary.includingTax}:&nbsp;\n <Price\n amount={item.rowTotalIncludingTax?.value}\n currency={item.rowTotalIncludingTax?.currency}\n />\n </span>\n )}\n {showExcludingTaxPrice && (\n <span className=\"cart-cart-summary-table__item-subtotal-tax-label\">\n {dictionary.excludingTax}:&nbsp;\n <Price\n amount={item.rowTotal?.value}\n currency={item.rowTotal?.currency}\n />\n </span>\n )}\n </Slot>\n ),\n actions,\n };\n }) || [],\n [\n cartModelData,\n itemsUpdating,\n allowQuantityUpdates,\n routeProduct,\n slots,\n itemUpdateErrors,\n dictionary,\n getConfiguration,\n allowRemoveItems,\n debouncedQuantityChange,\n getWarningMessage,\n getPriceProps,\n getSubtotalProps,\n setItemUpdating,\n setItemUpdateError,\n showIncludedTaxPrice,\n showExcludingTaxPrice,\n handleRemoveWithUndo,\n ]\n );\n\n /**\n * Render the cart summary table skeleton if the cart is loading\n */\n if (loading) {\n return <CartSummaryTableSkeleton />;\n }\n const renderTableWithUndoBanners = () => {\n if (!cartModelData?.items) return null;\n const tableEntries: any[] = [];\n const items = cartModelData.items;\n\n // Process items up to the available entries length\n for (let i = 0; i <= entries.length; i++) {\n // Render undo banners for this index position if undo is enabled\n if (undo) {\n recentlyRemovedItems\n .filter((r) => r.index === i)\n .forEach(({ item, error }) => {\n const isUndoBeingRemoved = getIsUndoBeingRemoved(item.uid, itemsUpdating);\n const undoBanner = createUndoBanner(\n { item, index: i, error },\n item,\n isUndoBeingRemoved,\n dictionary,\n handleUndo,\n handleDismiss,\n slots\n );\n \n // Add undo banner as a special entry\n tableEntries.push({\n uid: `undo-banner-${item.uid}`,\n updating: false,\n hasError: false,\n item: <div />,\n price: <div />,\n quantity: <div />,\n subtotal: <div />,\n actions: <div />,\n undoBanner,\n });\n });\n }\n \n // Render cart item if not at the end and within the entries limit\n if (i < entries.length && i < items.length) {\n tableEntries.push(entries[i]);\n }\n }\n \n return (\n <CartSummaryTableComponent\n entries={tableEntries}\n className={className}\n {...props}\n />\n );\n };\n\n /**\n * Create empty cart component with undo banner support\n */\n const emptyCart = (\n <Slot name=\"EmptyCart\" slot={slots?.EmptyCart} context={{}}>\n <EmptyCart ctaLinkURL={routeEmptyCartCTA?.()} />\n </Slot>\n );\n\n /**\n * Choose between original table entries and undo banner version (matches CartSummaryList logic)\n */\n const tableContent = \n cartModelData?.totalQuantity ||\n (undo && recentlyRemovedItems.length > 0) ? (\n !undo ? (\n <CartSummaryTableComponent\n entries={entries}\n className={className}\n {...props}\n />\n ) : recentlyRemovedItems.length > 0 ? (\n renderTableWithUndoBanners()\n ) : (\n <CartSummaryTableComponent\n entries={entries}\n className={className}\n {...props}\n />\n )\n ) : emptyCart;\n\n /**\n * Render the cart summary table\n */\n return tableContent;\n};\n\nCartSummaryTable.getInitialData = async function () {\n return getPersistedCartData();\n};\n\nexport const createUndoHandler = (\n recentlyRemovedItems: {\n item: CartModel['items'][number];\n index: number;\n loading: boolean;\n error?: string;\n }[],\n setRecentlyRemovedItems: (\n updater: (\n prev: {\n item: CartModel['items'][number];\n index: number;\n loading: boolean;\n error?: string;\n }[]\n ) => {\n item: CartModel['items'][number];\n index: number;\n loading: boolean;\n error?: string;\n }[]\n ) => void\n) => {\n return async (uid: string) => {\n setRecentlyRemovedItems((prev) =>\n prev.map((r) => (r.item.uid === uid ? { ...r, error: undefined } : r))\n );\n\n const removed = recentlyRemovedItems.find((r) => r.item.uid === uid);\n if (!removed) return;\n\n try {\n await addProductsToCart([\n {\n sku: removed.item.sku,\n parentSku: removed.item.topLevelSku,\n quantity: removed.item.quantity,\n optionsUIDs:\n removed.item.bundleOptionsUIDs || // Use bundle option UIDs for bundle products\n (removed.item.selectedOptionsUIDs\n ? Object.values(removed.item.selectedOptionsUIDs)\n : undefined),\n enteredOptions: removed.item.customizableOptions\n ? Object.entries(removed.item.customizableOptions).map(\n ([uid, value]) => ({ uid, value })\n )\n : undefined,\n },\n ]);\n setRecentlyRemovedItems((prev) => prev.filter((r) => r.item.uid !== uid));\n } catch (error: any) {\n setRecentlyRemovedItems((prev) =>\n prev.map((r) =>\n r.item.uid === uid\n ? { ...r, error: error?.message || 'Failed to restore item.' }\n : r\n )\n );\n }\n };\n};\n\nexport const createDismissHandler = (\n setRecentlyRemovedItems: (\n updater: (\n prev: {\n item: CartModel['items'][number];\n index: number;\n loading: boolean;\n error?: string;\n }[]\n ) => {\n item: CartModel['items'][number];\n index: number;\n loading: boolean;\n error?: string;\n }[]\n ) => void\n) => {\n return (uid: string) => {\n setRecentlyRemovedItems((prev) => prev.filter((r) => r.item.uid !== uid));\n };\n};\n\n/**\n * Helper function to determine if an undo is currently being removed\n * This makes the logic more explicit and testable\n */\nexport const getIsUndoBeingRemoved = (\n itemUid: string,\n itemsUpdating: Map<string, { isUpdating: boolean; updatedValue: number }>\n): boolean => {\n return itemsUpdating.has(itemUid) && itemsUpdating.get(itemUid)?.updatedValue === 0;\n};\n\n/**\n * Helper function to create additional actions for undo banner\n * This makes the ternary operator logic more explicit and testable\n */\nexport const createUndoBannerActions = (\n isUndoBeingRemoved: boolean,\n dictionary: any,\n handleUndo: (uid: string) => void,\n handleDismiss: (uid: string) => void,\n itemUid: string,\n itemName: string\n) => {\n if (isUndoBeingRemoved) {\n return []; // Hide buttons while removing\n }\n \n return [\n {\n label: dictionary.undoAction,\n onClick: () => {\n handleUndo(itemUid);\n },\n 'aria-label': `${dictionary.undoAction} remove ${itemName}`,\n },\n {\n label: dictionary.dismissAction,\n onClick: () => {\n handleDismiss(itemUid);\n },\n 'aria-label': `${dictionary.dismissAction} undo for ${itemName}`,\n },\n ];\n};\n\n/**\n * Helper function to create undo callback\n */\nexport const createUndoCallback = (\n handleUndo: (uid: string) => void,\n itemUid: string\n) => {\n return () => handleUndo(itemUid);\n};\n\n/**\n * Helper function to create dismiss callback\n */\nexport const createDismissCallback = (\n handleDismiss: (uid: string) => void,\n itemUid: string\n) => {\n return () => handleDismiss(itemUid);\n};\n\nexport const createUndoBanner = (\n removed: { item: CartModel['items'][number]; index: number; error?: string },\n item: CartModel['items'][number],\n isUndoBeingRemoved: boolean,\n dictionary: any,\n handleUndo: (uid: string) => void,\n handleDismiss: (uid: string) => void,\n slots?: CartSummaryTableContainerProps['slots']\n): VNode => {\n const additionalActions = createUndoBannerActions(\n isUndoBeingRemoved,\n dictionary,\n handleUndo,\n handleDismiss,\n removed.item.uid,\n removed.item.name\n );\n\n const onUndoCallback = createUndoCallback(handleUndo, removed.item.uid);\n const onDismissCallback = createDismissCallback(handleDismiss, removed.item.uid);\n\n return (\n <Slot\n name=\"UndoBanner\"\n slot={slots?.UndoBanner}\n context={{\n item: removed.item,\n loading: isUndoBeingRemoved,\n error: removed.error,\n onUndo: onUndoCallback,\n onDismiss: onDismissCallback,\n }}\n key={`undo-banner-${removed.item.uid}`}\n >\n <InLineAlert\n key={`undo-banner-${removed.item.uid}`}\n type={removed.error ? 'error' : 'info'}\n heading={\n isUndoBeingRemoved\n ? dictionary.itemBeingRemoved?.replace('{product}', item.name)\n : dictionary.itemRemoved?.replace('{product}', removed.item.name)\n }\n description={removed.error || dictionary.itemRemovedDescription}\n variant=\"primary\"\n actionButtonPosition=\"bottom\"\n additionalActions={additionalActions}\n />\n </Slot>\n );\n};\n"],"names":["CartSummaryTable","entries","className","props","dictionary","useText","jsxs","classes","jsx","entry","VComponent","Item","productTitle","sku","image","configurations","alert","warning","useCartItems","onQuantityUpdate","onItemRemove","itemsUpdating","setItemsUpdating","useState","itemUpdateErrors","setItemUpdateErrors","cartSettings","_b","_a","state","showIncludedTaxPrice","showExcludingTaxPrice","getConfiguration","item","configuration","getPriceProps","_c","_d","getSubtotalProps","subtotalProps","subtotalDiscountProps","_e","_f","_g","_h","_i","_j","getWarningMessage","updateErrorMessage","insufficientQuantityText","lowInventoryText","processQuantityChange","useCallback","value","handleQuantityChange","quantity","updateProductsFromCart","prev","next","error","debouncedQuantityChange","useMemo","debounce","uid","data","InLineAlert","variant","type","additionalActions","onDismiss","heading","description","icon","itemList","actionButtonPosition","translations","Button","Icon","Close","action","CartSummaryTableSkeleton","Skeleton","SkeletonRow","initialData","routeProduct","routeEmptyCartCTA","slots","allowQuantityUpdates","allowRemoveItems","undo","loading","setLoading","cartModelData","setCartModelData","recentlyRemovedItems","setRecentlyRemovedItems","handleRemoveItem","setItemUpdating","setItemUpdateError","addToRecentlyRemovedItems","cart","getPersistedCartData","i","index","r","events","handleUndo","createUndoHandler","handleDismiss","createDismissHandler","handleRemoveWithUndo","useEffect","cartDataEvent","payload","a","b","isUpdating","warningMessage","Slot","defaultImageProps","defaultImage","Image","productImage","productSku","itemAlert","OrderError","itemWarning","WarningWithCircle","itemConfigurations","productConfigurations","key","updatedValue","quantityInputValue","handleInputChange","e","target","isBeingRemoved","actions","Trash","Price","_k","renderTableWithUndoBanners","tableEntries","items","isUndoBeingRemoved","getIsUndoBeingRemoved","undoBanner","createUndoBanner","CartSummaryTableComponent","emptyCart","EmptyCart","removed","addProductsToCart","itemUid","createUndoBannerActions","itemName","createUndoCallback","createDismissCallback","onUndoCallback","onDismissCallback"],"mappings":"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","x_google_ignoreList":[3]}
@@ -1,4 +1,4 @@
1
1
  /*! Copyright 2025 Adobe
2
2
  All Rights Reserved. */
3
- import*as e from"@dropins/tools/preact-compat.js";const r=t=>e.createElement("svg",{width:24,height:24,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",...t},e.createElement("g",{clipPath:"url(#clip0_4797_15331)"},e.createElement("path",{vectorEffect:"non-scaling-stroke",d:"M10.25 20.91L1.5 17.55V6.51996L10.25 9.92996V20.91Z",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round"}),e.createElement("path",{vectorEffect:"non-scaling-stroke",d:"M6.24023 4.64001L14.9902 8.06001V11.42",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round"}),e.createElement("path",{className:"error-icon",vectorEffect:"non-scaling-stroke",d:"M19 13.31L15.5 19.37H22.5L19 13.31Z",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round"}),e.createElement("path",{className:"error-icon",vectorEffect:"non-scaling-stroke",d:"M19.0202 17.11H18.9802L18.9502 15.56H19.0502L19.0202 17.11ZM18.9602 18.29V18.06H19.0502V18.29H18.9602Z",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round"}),e.createElement("path",{vectorEffect:"non-scaling-stroke",d:"M19 12.16V6.51996L10.25 9.92996V20.91L14.27 19.37L14.4 19.32",stroke:"currentColor",strokeLinejoin:"round"}),e.createElement("path",{vectorEffect:"non-scaling-stroke",d:"M1.5 6.51999L10.25 3.04999L19 6.51999L10.25 9.92999L1.5 6.51999Z",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round"})),e.createElement("defs",null,e.createElement("clipPath",{id:"clip0_4797_15331"},e.createElement("rect",{width:22,height:18.86,fill:"white",transform:"translate(1 2.54999)"})))),o=t=>e.createElement("svg",{width:24,height:24,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",...t},e.createElement("path",{vectorEffect:"non-scaling-stroke",d:"M0.75 12C0.75 5.78421 5.78421 0.75 12 0.75C18.2158 0.75 23.25 5.78421 23.25 12C23.25 18.2158 18.2158 23.25 12 23.25C5.78421 23.25 0.75 18.2158 0.75 12Z",stroke:"currentColor"}),e.createElement("path",{vectorEffect:"non-scaling-stroke",d:"M11.75 5.88423V4.75H12.25V5.88423L12.0485 13.0713H11.9515L11.75 5.88423ZM11.7994 18.25V16.9868H12.2253V18.25H11.7994Z",stroke:"currentColor"}));export{r as S,o as a};
4
- //# sourceMappingURL=WarningWithCircle.js.map
3
+ import*as e from"@dropins/tools/preact-compat.js";const r=t=>e.createElement("svg",{width:24,height:24,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",...t},e.createElement("g",{clipPath:"url(#clip0_4797_15331)"},e.createElement("path",{vectorEffect:"non-scaling-stroke",d:"M10.25 20.91L1.5 17.55V6.51996L10.25 9.92996V20.91Z",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round"}),e.createElement("path",{vectorEffect:"non-scaling-stroke",d:"M6.24023 4.64001L14.9902 8.06001V11.42",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round"}),e.createElement("path",{className:"error-icon",vectorEffect:"non-scaling-stroke",d:"M19 13.31L15.5 19.37H22.5L19 13.31Z",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round"}),e.createElement("path",{className:"error-icon",vectorEffect:"non-scaling-stroke",d:"M19.0202 17.11H18.9802L18.9502 15.56H19.0502L19.0202 17.11ZM18.9602 18.29V18.06H19.0502V18.29H18.9602Z",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round"}),e.createElement("path",{vectorEffect:"non-scaling-stroke",d:"M19 12.16V6.51996L10.25 9.92996V20.91L14.27 19.37L14.4 19.32",stroke:"currentColor",strokeLinejoin:"round"}),e.createElement("path",{vectorEffect:"non-scaling-stroke",d:"M1.5 6.51999L10.25 3.04999L19 6.51999L10.25 9.92999L1.5 6.51999Z",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round"})),e.createElement("defs",null,e.createElement("clipPath",{id:"clip0_4797_15331"},e.createElement("rect",{width:22,height:18.86,fill:"white",transform:"translate(1 2.54999)"})))),o=t=>e.createElement("svg",{width:24,height:24,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",...t},e.createElement("path",{vectorEffect:"non-scaling-stroke",d:"M0.75 12C0.75 5.78421 5.78421 0.75 12 0.75C18.2158 0.75 23.25 5.78421 23.25 12C23.25 18.2158 18.2158 23.25 12 23.25C5.78421 23.25 0.75 18.2158 0.75 12Z",stroke:"currentColor"}),e.createElement("path",{vectorEffect:"non-scaling-stroke",d:"M11.75 5.88423V4.75H12.25V5.88423L12.0485 13.0713H11.9515L11.75 5.88423ZM11.7994 18.25V16.9868H12.2253V18.25H11.7994Z",stroke:"currentColor"})),n=t=>e.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",...t},e.createElement("path",{d:"M1 5H23",stroke:"currentColor",strokeWidth:1.5,strokeMiterlimit:10}),e.createElement("path",{d:"M17.3674 22H6.63446C5.67952 22 4.88992 21.2688 4.8379 20.3338L4 5H20L19.1621 20.3338C19.1119 21.2688 18.3223 22 17.3655 22H17.3674Z",stroke:"currentColor",strokeWidth:1.5,strokeMiterlimit:10}),e.createElement("path",{d:"M9.87189 2H14.1281C14.6085 2 15 2.39766 15 2.88889V5H9V2.88889C9 2.39912 9.39006 2 9.87189 2Z",stroke:"currentColor",strokeWidth:1.5,strokeMiterlimit:10}),e.createElement("path",{d:"M8.87402 8.58057L9.39348 17.682",stroke:"currentColor",strokeWidth:1.5,strokeMiterlimit:10}),e.createElement("path",{d:"M14.6673 8.58057L14.146 17.682",stroke:"currentColor",strokeWidth:1.5,strokeMiterlimit:10}));export{r as S,o as a,n as b};
4
+ //# sourceMappingURL=Trash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Trash.js","sources":["../../node_modules/@adobe-commerce/elsie/src/icons/OrderError.svg","../../node_modules/@adobe-commerce/elsie/src/icons/WarningWithCircle.svg","../../node_modules/@adobe-commerce/elsie/src/icons/Trash.svg"],"sourcesContent":["import * as React from \"react\";\nconst SvgOrderError = (props) => /* @__PURE__ */ React.createElement(\"svg\", { width: 24, height: 24, viewBox: \"0 0 24 24\", fill: \"none\", xmlns: \"http://www.w3.org/2000/svg\", ...props }, /* @__PURE__ */ React.createElement(\"g\", { clipPath: \"url(#clip0_4797_15331)\" }, /* @__PURE__ */ React.createElement(\"path\", { vectorEffect: \"non-scaling-stroke\", d: \"M10.25 20.91L1.5 17.55V6.51996L10.25 9.92996V20.91Z\", stroke: \"currentColor\", strokeLinecap: \"round\", strokeLinejoin: \"round\" }), /* @__PURE__ */ React.createElement(\"path\", { vectorEffect: \"non-scaling-stroke\", d: \"M6.24023 4.64001L14.9902 8.06001V11.42\", stroke: \"currentColor\", strokeLinecap: \"round\", strokeLinejoin: \"round\" }), /* @__PURE__ */ React.createElement(\"path\", { className: \"error-icon\", vectorEffect: \"non-scaling-stroke\", d: \"M19 13.31L15.5 19.37H22.5L19 13.31Z\", stroke: \"currentColor\", strokeLinecap: \"round\", strokeLinejoin: \"round\" }), /* @__PURE__ */ React.createElement(\"path\", { className: \"error-icon\", vectorEffect: \"non-scaling-stroke\", d: \"M19.0202 17.11H18.9802L18.9502 15.56H19.0502L19.0202 17.11ZM18.9602 18.29V18.06H19.0502V18.29H18.9602Z\", stroke: \"currentColor\", strokeLinecap: \"round\", strokeLinejoin: \"round\" }), /* @__PURE__ */ React.createElement(\"path\", { vectorEffect: \"non-scaling-stroke\", d: \"M19 12.16V6.51996L10.25 9.92996V20.91L14.27 19.37L14.4 19.32\", stroke: \"currentColor\", strokeLinejoin: \"round\" }), /* @__PURE__ */ React.createElement(\"path\", { vectorEffect: \"non-scaling-stroke\", d: \"M1.5 6.51999L10.25 3.04999L19 6.51999L10.25 9.92999L1.5 6.51999Z\", stroke: \"currentColor\", strokeLinecap: \"round\", strokeLinejoin: \"round\" })), /* @__PURE__ */ React.createElement(\"defs\", null, /* @__PURE__ */ React.createElement(\"clipPath\", { id: \"clip0_4797_15331\" }, /* @__PURE__ */ React.createElement(\"rect\", { width: 22, height: 18.86, fill: \"white\", transform: \"translate(1 2.54999)\" }))));\nexport default SvgOrderError;\n","import * as React from \"react\";\nconst SvgWarningWithCircle = (props) => /* @__PURE__ */ React.createElement(\"svg\", { width: 24, height: 24, viewBox: \"0 0 24 24\", fill: \"none\", xmlns: \"http://www.w3.org/2000/svg\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { vectorEffect: \"non-scaling-stroke\", d: \"M0.75 12C0.75 5.78421 5.78421 0.75 12 0.75C18.2158 0.75 23.25 5.78421 23.25 12C23.25 18.2158 18.2158 23.25 12 23.25C5.78421 23.25 0.75 18.2158 0.75 12Z\", stroke: \"currentColor\" }), /* @__PURE__ */ React.createElement(\"path\", { vectorEffect: \"non-scaling-stroke\", d: \"M11.75 5.88423V4.75H12.25V5.88423L12.0485 13.0713H11.9515L11.75 5.88423ZM11.7994 18.25V16.9868H12.2253V18.25H11.7994Z\", stroke: \"currentColor\" }));\nexport default SvgWarningWithCircle;\n","import * as React from \"react\";\nconst SvgTrash = (props) => /* @__PURE__ */ React.createElement(\"svg\", { xmlns: \"http://www.w3.org/2000/svg\", width: 24, height: 24, viewBox: \"0 0 24 24\", fill: \"none\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { d: \"M1 5H23\", stroke: \"currentColor\", strokeWidth: 1.5, strokeMiterlimit: 10 }), /* @__PURE__ */ React.createElement(\"path\", { d: \"M17.3674 22H6.63446C5.67952 22 4.88992 21.2688 4.8379 20.3338L4 5H20L19.1621 20.3338C19.1119 21.2688 18.3223 22 17.3655 22H17.3674Z\", stroke: \"currentColor\", strokeWidth: 1.5, strokeMiterlimit: 10 }), /* @__PURE__ */ React.createElement(\"path\", { d: \"M9.87189 2H14.1281C14.6085 2 15 2.39766 15 2.88889V5H9V2.88889C9 2.39912 9.39006 2 9.87189 2Z\", stroke: \"currentColor\", strokeWidth: 1.5, strokeMiterlimit: 10 }), /* @__PURE__ */ React.createElement(\"path\", { d: \"M8.87402 8.58057L9.39348 17.682\", stroke: \"currentColor\", strokeWidth: 1.5, strokeMiterlimit: 10 }), /* @__PURE__ */ React.createElement(\"path\", { d: \"M14.6673 8.58057L14.146 17.682\", stroke: \"currentColor\", strokeWidth: 1.5, strokeMiterlimit: 10 }));\nexport default SvgTrash;\n"],"names":["SvgOrderError","props","React","SvgWarningWithCircle","SvgTrash"],"mappings":"kDACK,MAACA,EAAiBC,GAA0BC,EAAM,cAAc,MAAO,CAAE,MAAO,GAAI,OAAQ,GAAI,QAAS,YAAa,KAAM,OAAQ,MAAO,6BAA8B,GAAGD,CAAO,EAAkBC,EAAM,cAAc,IAAK,CAAE,SAAU,0BAA4CA,EAAM,cAAc,OAAQ,CAAE,aAAc,qBAAsB,EAAG,sDAAuD,OAAQ,eAAgB,cAAe,QAAS,eAAgB,OAAO,CAAE,EAAmBA,EAAM,cAAc,OAAQ,CAAE,aAAc,qBAAsB,EAAG,yCAA0C,OAAQ,eAAgB,cAAe,QAAS,eAAgB,OAAS,CAAA,EAAmBA,EAAM,cAAc,OAAQ,CAAE,UAAW,aAAc,aAAc,qBAAsB,EAAG,sCAAuC,OAAQ,eAAgB,cAAe,QAAS,eAAgB,OAAS,CAAA,EAAmBA,EAAM,cAAc,OAAQ,CAAE,UAAW,aAAc,aAAc,qBAAsB,EAAG,yGAA0G,OAAQ,eAAgB,cAAe,QAAS,eAAgB,OAAO,CAAE,EAAmBA,EAAM,cAAc,OAAQ,CAAE,aAAc,qBAAsB,EAAG,+DAAgE,OAAQ,eAAgB,eAAgB,OAAS,CAAA,EAAmBA,EAAM,cAAc,OAAQ,CAAE,aAAc,qBAAsB,EAAG,mEAAoE,OAAQ,eAAgB,cAAe,QAAS,eAAgB,OAAO,CAAE,CAAC,EAAmBA,EAAM,cAAc,OAAQ,KAAsBA,EAAM,cAAc,WAAY,CAAE,GAAI,kBAAoB,EAAkBA,EAAM,cAAc,OAAQ,CAAE,MAAO,GAAI,OAAQ,MAAO,KAAM,QAAS,UAAW,sBAAwB,CAAA,CAAC,CAAC,CAAC,ECAv1DC,EAAwBF,GAA0BC,EAAM,cAAc,MAAO,CAAE,MAAO,GAAI,OAAQ,GAAI,QAAS,YAAa,KAAM,OAAQ,MAAO,6BAA8B,GAAGD,CAAK,EAAoBC,EAAM,cAAc,OAAQ,CAAE,aAAc,qBAAsB,EAAG,0JAA2J,OAAQ,cAAc,CAAE,EAAmBA,EAAM,cAAc,OAAQ,CAAE,aAAc,qBAAsB,EAAG,wHAAyH,OAAQ,eAAgB,CAAC,ECA7qBE,EAAYH,GAA0BC,EAAM,cAAc,MAAO,CAAE,MAAO,6BAA8B,MAAO,GAAI,OAAQ,GAAI,QAAS,YAAa,KAAM,OAAQ,GAAGD,CAAK,EAAoBC,EAAM,cAAc,OAAQ,CAAE,EAAG,UAAW,OAAQ,eAAgB,YAAa,IAAK,iBAAkB,EAAI,CAAA,EAAmBA,EAAM,cAAc,OAAQ,CAAE,EAAG,sIAAuI,OAAQ,eAAgB,YAAa,IAAK,iBAAkB,EAAE,CAAE,EAAmBA,EAAM,cAAc,OAAQ,CAAE,EAAG,gGAAiG,OAAQ,eAAgB,YAAa,IAAK,iBAAkB,EAAE,CAAE,EAAmBA,EAAM,cAAc,OAAQ,CAAE,EAAG,kCAAmC,OAAQ,eAAgB,YAAa,IAAK,iBAAkB,EAAI,CAAA,EAAmBA,EAAM,cAAc,OAAQ,CAAE,EAAG,iCAAkC,OAAQ,eAAgB,YAAa,IAAK,iBAAkB,GAAI,CAAC","x_google_ignoreList":[0,1,2]}
@@ -36,6 +36,40 @@ export interface CartSummaryListProps extends HTMLAttributes<HTMLDivElement> {
36
36
  onUndo: () => void;
37
37
  onDismiss: () => void;
38
38
  }>;
39
+ ItemTitle?: SlotProps<{
40
+ item: CartModel['items'][number];
41
+ }>;
42
+ ItemPrice?: SlotProps<{
43
+ item: CartModel['items'][number];
44
+ }>;
45
+ ItemQuantity?: SlotProps<{
46
+ item: CartModel['items'][number];
47
+ enableUpdateItemQuantity: boolean;
48
+ handleItemQuantityUpdate: (item: CartModel['items'][number], quantity: number) => void;
49
+ itemsLoading: Set<string>;
50
+ handleItemsError: (uid: string, message?: string) => void;
51
+ handleItemsLoading: (uid: string, state: boolean) => void;
52
+ onItemUpdate?: ({ item }: {
53
+ item: CartModel['items'][number];
54
+ }) => void;
55
+ }>;
56
+ ItemTotal?: SlotProps<{
57
+ item: CartModel['items'][number];
58
+ }>;
59
+ ItemSku?: SlotProps<{
60
+ item: CartModel['items'][number];
61
+ }>;
62
+ ItemRemoveAction?: SlotProps<{
63
+ item: CartModel['items'][number];
64
+ enableRemoveItem: boolean;
65
+ handleItemQuantityUpdate: (item: CartModel['items'][number], quantity: number) => void;
66
+ handleItemsError: (uid: string, message?: string) => void;
67
+ handleItemsLoading: (uid: string, state: boolean) => void;
68
+ onItemUpdate?: ({ item }: {
69
+ item: CartModel['items'][number];
70
+ }) => void;
71
+ itemsLoading: Set<string>;
72
+ }>;
39
73
  };
40
74
  enableRemoveItem?: boolean;
41
75
  enableUpdateItemQuantity?: boolean;
@@ -1,4 +1,4 @@
1
1
  /*! Copyright 2025 Adobe
2
2
  All Rights Reserved. */
3
- import{C as h,C as j}from"../chunks/CartSummaryList.js";import"@dropins/tools/preact-jsx-runtime.js";import"@dropins/tools/preact-compat.js";import"@dropins/tools/lib.js";import"../chunks/EmptyCart2.js";import"@dropins/tools/components.js";/* empty css */import"@dropins/tools/i18n.js";import"@dropins/tools/preact-hooks.js";import"../chunks/persisted-data.js";import"@dropins/tools/event-bus.js";import"../chunks/resetCart.js";import"@dropins/tools/fetch-graphql.js";import"../chunks/createGuestCart.js";import"../chunks/refreshCart.js";import"../fragments.js";import"../chunks/updateProductsFromCart.js";import"../chunks/acdl.js";import"../chunks/WarningWithCircle.js";import"../chunks/ChevronDown.js";export{h as CartSummaryList,j as default};
3
+ import{C as h,C as j}from"../chunks/CartSummaryList.js";import"@dropins/tools/preact-jsx-runtime.js";import"@dropins/tools/preact-compat.js";import"@dropins/tools/lib.js";import"../chunks/EmptyCart2.js";import"@dropins/tools/components.js";/* empty css */import"@dropins/tools/i18n.js";import"@dropins/tools/preact-hooks.js";import"../chunks/persisted-data.js";import"@dropins/tools/event-bus.js";import"../chunks/resetCart.js";import"@dropins/tools/fetch-graphql.js";import"../chunks/createGuestCart.js";import"../chunks/refreshCart.js";import"../fragments.js";import"../chunks/updateProductsFromCart.js";import"../chunks/acdl.js";import"../chunks/Trash.js";import"../chunks/ChevronDown.js";export{h as CartSummaryList,j as default};
4
4
  //# sourceMappingURL=CartSummaryList.js.map
@@ -1,4 +1,4 @@
1
1
  /*! Copyright 2025 Adobe
2
2
  All Rights Reserved. */
3
- import{C as H,e as v,a as x,f as y,b as A,d as I,c as R,C as S,g as T}from"../chunks/CartSummaryTable2.js";import"@dropins/tools/preact-jsx-runtime.js";import"@dropins/tools/lib.js";import"@dropins/tools/components.js";/* empty css */import"@dropins/tools/preact-compat.js";import"@dropins/tools/preact-hooks.js";import"@dropins/tools/i18n.js";import"@dropins/tools/event-bus.js";import"../chunks/resetCart.js";import"@dropins/tools/fetch-graphql.js";import"../chunks/persisted-data.js";import"../chunks/updateProductsFromCart.js";import"../chunks/refreshCart.js";import"../fragments.js";import"../chunks/acdl.js";import"../chunks/createGuestCart.js";import"../chunks/EmptyCart.js";import"../chunks/EmptyCart2.js";import"../chunks/WarningWithCircle.js";import"../chunks/Close.js";export{H as CartSummaryTable,v as createDismissCallback,x as createDismissHandler,y as createUndoBanner,A as createUndoBannerActions,I as createUndoCallback,R as createUndoHandler,S as default,T as getIsUndoBeingRemoved};
3
+ import{C as H,e as v,a as x,f as y,b as A,d as I,c as R,C as S,g as T}from"../chunks/CartSummaryTable2.js";import"@dropins/tools/preact-jsx-runtime.js";import"@dropins/tools/lib.js";import"@dropins/tools/components.js";/* empty css */import"@dropins/tools/preact-compat.js";import"@dropins/tools/preact-hooks.js";import"@dropins/tools/i18n.js";import"@dropins/tools/event-bus.js";import"../chunks/resetCart.js";import"@dropins/tools/fetch-graphql.js";import"../chunks/persisted-data.js";import"../chunks/updateProductsFromCart.js";import"../chunks/refreshCart.js";import"../fragments.js";import"../chunks/acdl.js";import"../chunks/createGuestCart.js";import"../chunks/EmptyCart.js";import"../chunks/EmptyCart2.js";import"../chunks/Trash.js";import"../chunks/Close.js";export{H as CartSummaryTable,v as createDismissCallback,x as createDismissHandler,y as createUndoBanner,A as createUndoBannerActions,I as createUndoCallback,R as createUndoHandler,S as default,T as getIsUndoBeingRemoved};
4
4
  //# sourceMappingURL=CartSummaryTable.js.map
@@ -16,6 +16,53 @@ export interface MiniCartProps extends HTMLAttributes<HTMLDivElement> {
16
16
  item: CartModel['items'][number];
17
17
  defaultImageProps: ImageProps;
18
18
  }>;
19
+ Heading?: SlotProps;
20
+ EmptyCart?: SlotProps;
21
+ Footer?: SlotProps;
22
+ ProductAttributes?: SlotProps;
23
+ CartSummaryFooter?: SlotProps;
24
+ CartItem?: SlotProps;
25
+ UndoBanner?: SlotProps<{
26
+ item: CartModel['items'][0];
27
+ loading: boolean;
28
+ error?: string;
29
+ onUndo: () => void;
30
+ onDismiss: () => void;
31
+ }>;
32
+ ItemTitle?: SlotProps<{
33
+ item: CartModel['items'][number];
34
+ }>;
35
+ ItemPrice?: SlotProps<{
36
+ item: CartModel['items'][number];
37
+ }>;
38
+ ItemQuantity?: SlotProps<{
39
+ item: CartModel['items'][number];
40
+ enableUpdateItemQuantity: boolean;
41
+ handleItemQuantityUpdate: (item: CartModel['items'][number], quantity: number) => void;
42
+ itemsLoading: Set<string>;
43
+ handleItemsError: (uid: string, message?: string) => void;
44
+ handleItemsLoading: (uid: string, state: boolean) => void;
45
+ onItemUpdate?: ({ item }: {
46
+ item: CartModel['items'][number];
47
+ }) => void;
48
+ }>;
49
+ ItemTotal?: SlotProps<{
50
+ item: CartModel['items'][number];
51
+ }>;
52
+ ItemSku?: SlotProps<{
53
+ item: CartModel['items'][number];
54
+ }>;
55
+ ItemRemoveAction?: SlotProps<{
56
+ item: CartModel['items'][number];
57
+ enableRemoveItem: boolean;
58
+ handleItemQuantityUpdate: (item: CartModel['items'][number], quantity: number) => void;
59
+ handleItemsError: (uid: string, message?: string) => void;
60
+ handleItemsLoading: (uid: string, state: boolean) => void;
61
+ onItemUpdate?: ({ item }: {
62
+ item: CartModel['items'][number];
63
+ }) => void;
64
+ itemsLoading: Set<string>;
65
+ }>;
19
66
  };
20
67
  hideFooter?: boolean;
21
68
  displayAllItems?: boolean;