/**
* @fileoverview Cart Primitive Components
*
* This module provides unstyled, composable components for building cart functionality.
* These components follow the Radix UI primitive pattern, offering:
*
* - **Unstyled**: No default styling, only functional behavior
* - **Composable**: Support for the `asChild` pattern for flexible DOM structure
* - **Accessible**: Built-in ARIA attributes and proper semantics
* - **Flexible**: Render props pattern for maximum customization
*
* ## Architecture
*
* These components are the **primitive layer** that sits between:
* 1. **Core components** (pure logic, no DOM)
* 2. **Styled components** (project-specific styling)
*
* ## Usage
*
* ```tsx
* import { Cart } from '@wix/ecom/react';
*
* function CartProvider() {
* return (
*
*
* {({ totalItems, open }) => (
*
* )}
*
*
* {({ cart, isLoading }) => (
*
* {isLoading ? 'Loading...' : 'Cart content'}
*
* )}
*
*
* );
* }
* ```
*
* @module Cart
*/
import React from 'react';
import type { LineItem } from '../services/common-types.js';
import { AsChildChildren } from '@wix/headless-utils/react';
import * as CouponComponents from './CartCoupon.js';
/**
* Props for the Root component
*/
export interface RootProps {
/** Child components that will have access to the cart context */
children: React.ReactNode;
}
/**
* Root component that provides cart service context to its children.
* This is a primitive wrapper around the core Root component that maintains
* the same API while providing a foundation for composition patterns.
*
* @component
* @example
* ```tsx
* import { Cart } from '@wix/ecom/react';
*
* function CartProvider() {
* return (
*
*
* {({ totalItems, open }) => (
*
* )}
*
*
* );
* }
* ```
*/
export declare const Root: {
({ children }: RootProps): import("react/jsx-runtime").JSX.Element;
displayName: string;
};
/**
* Props for EmptyState component with asChild support
*/
export interface EmptyStateProps {
/** When true, the component will not render its own element but forward its props to its child */
asChild?: boolean;
/** Content to display when cart is empty (can be a render function or ReactNode) */
children?: AsChildChildren<{}>;
/** Text label to display when cart is empty */
label?: string;
/** CSS class name */
className?: string;
/** Additional HTML attributes */
[key: string]: any;
}
/**
* Component that renders content when the cart is empty.
* Only displays its children when there are no items in cart, no loading state, and no errors.
* Supports the asChild pattern for flexible composition.
*
* @component
* @example
* ```tsx
* // Default rendering with default label
*
*
* // Custom label
*
*
* // Custom content with render function
*
* {() => (
*
*
No items in cart
*
Items will appear here once they are added
*
* )}
*
*
* // Using asChild for custom wrapper
*
*
* Content will be rendered here
*
*
* ```
*/
export declare const EmptyState: React.ForwardRefExoticComponent & React.RefAttributes>;
/**
* Props for button-like components that support the asChild pattern
*/
export interface ButtonProps extends React.ButtonHTMLAttributes {
/** When true, the component will not render its own element but forward its props to its child */
asChild?: boolean;
}
/**
* Props for OpenTrigger component
*/
export interface OpenTriggerProps {
/** Whether to render as a child component */
asChild?: boolean;
/** Custom render function when using asChild */
children?: React.ReactNode | React.ForwardRefRenderFunction void;
isLoading: boolean;
}>;
/** CSS classes to apply to the default element */
className?: string;
}
/**
* Props for LineItemsList component
*/
export interface LineItemsListProps {
/** Whether to render as a child component */
asChild?: boolean;
/** Custom render function when using asChild */
children?: AsChildChildren<{
items: LineItem[];
totalItems: number;
}>;
/** CSS classes to apply to the default element */
className?: string;
/** Empty state to display when cart is empty */
emptyState?: React.ReactNode;
}
/**
* Headless component for cart items collection.
* Supports the asChild pattern for flexible composition.
*
* @component
* @example
* ```tsx
* // Default div wrapper
*
* {({ items, totalItems }) => (
*
*
Cart ({totalItems} items)
* {items.map(item =>
{item.productName?.original}
)}
*
* )}
*
*
* // Using asChild for custom wrapper
*
*
* Items content will be rendered here
*
*
* ```
*/
export declare const LineItemsList: React.ForwardRefExoticComponent>;
/**
* Props for LineItems component (alternative to LineItemsList)
*/
export interface LineItemsProps {
/** Whether to render as a child component */
asChild?: boolean;
/** Custom render function when using asChild */
children?: AsChildChildren<{}>;
/** CSS classes to apply to the default element */
className?: string;
/** Empty state to display when cart is empty */
emptyState?: React.ReactNode;
/** Additional HTML attributes */
[key: string]: any;
}
/**
* Headless component for cart items collection (alternative to LineItemsList)
*
* @example
* ```tsx
* Your cart is empty}
* >
*
*
*
*
*
*
* ```
*/
export declare const LineItems: React.ForwardRefExoticComponent & React.RefAttributes>;
export interface LineItemRepeaterProps {
/** Whether to render as a child component */
asChild?: boolean;
/** Custom render function when using asChild */
children?: AsChildChildren<{}>;
/** CSS classes to apply to the default element */
className?: string;
/** Additional HTML attributes */
[key: string]: any;
}
/**
* Component that repeats its children for each line item in the cart.
* Provides context for each line item.
*
* @component
* @example
* ```tsx
* import { Cart } from '@wix/ecom/components';
*
* function CartItemsList() {
* return (
*
*
*
*
*
*
*
* );
* }
* ```
*/
export declare const LineItemRepeater: React.ForwardRefExoticComponent & React.RefAttributes>;
/**
* Props for Content headless component
*/
export interface ContentProps {
/** Render prop function that receives content data */
children: (props: ContentRenderProps) => React.ReactNode;
}
/**
* Render props for Content component
*/
export interface ContentRenderProps {
/** Whether cart is loading */
isLoading: boolean;
/** Error message if any */
error: string | null;
}
export declare const Content: (props: ContentProps) => import("react/jsx-runtime").JSX.Element;
/**
* Props for Summary component
*/
export interface SummaryProps {
/** When true, the component will not render its own element but forward its props to its child */
asChild?: boolean;
/** Render prop function that receives summary data */
children: AsChildChildren<{
/** Cart subtotal */
subtotal: string;
/** Discount amount if coupon applied */
discount: string | null;
/** Applied coupon code if any */
appliedCoupon: string | null;
/** Shipping cost */
shipping: string;
/** Tax amount */
tax: string;
/** Cart total */
total: string;
/** Currency code */
currency: string;
/** Total number of items */
totalItems: number;
/** Whether totals are being calculated */
isTotalsLoading: boolean;
}>;
/** CSS classes to apply to the default element */
className?: string;
/** Labels for the summary display. Supports {totalItems} placeholder replacement */
labels?: {
/** Label for subtotal line. Use {totalItems} to include item count */
subtotal?: string;
/** Label for total line */
total?: string;
/** Label shown when totals are being calculated */
calculating?: string;
};
}
/**
* Headless component for cart summary/totals.
* Supports the asChild pattern for flexible composition.
*
* @component
* @example
* ```tsx
* // Default div wrapper
*
* {({ subtotal, total, totalItems, isTotalsLoading }) => (
*
* )}
*
*
* // With custom labels
*
*
* // Using asChild for custom wrapper
*
*
* Summary content will be rendered here
*
*
* ```
*/
export declare const Summary: React.ForwardRefExoticComponent>;
/**
* Props for Clear component
*/
export interface ClearProps {
/** Whether to render as a child component */
asChild?: boolean;
/** Custom render function when using asChild */
children?: AsChildChildren<{
clear: () => Promise;
totalItems: number;
isLoading: boolean;
}>;
/** CSS classes to apply to the default element */
className?: string;
/** Labels for the clear button. Supports {totalItems} placeholder replacement */
labels?: {
/** Label shown when clearing is in progress */
clearing?: string;
/** Label shown when cart is ready to be cleared. Use {totalItems} to include item count */
clear?: string;
};
}
/**
* Headless component for clearing the cart.
* Supports the asChild pattern for flexible composition.
*
* @component
* @example
* ```tsx
* // Default button
*
* {({ clear, totalItems, isLoading }) => (
*
* )}
*
*
* // With custom labels
*
*
* // Using asChild for custom button
*
*
*
* ```
*/
export declare const Clear: React.ForwardRefExoticComponent>;
/**
* Props for Checkout component
*/
export interface CheckoutProps {
/** When true, the component will not render its own element but forward its props to its child */
asChild?: boolean;
/** Render prop function that receives checkout data */
children: AsChildChildren<{
/** Function to proceed to checkout */
proceedToCheckout: () => Promise;
/** Whether checkout is available */
canCheckout: boolean;
/** Whether checkout action is loading */
isLoading: boolean;
/** Error message if checkout fails */
error: string | null;
}>;
/** CSS class name */
className?: string;
/** Additional HTML attributes */
[key: string]: any;
}
/**
* Headless component for checkout action.
* Supports the asChild pattern for flexible composition.
*
* @component
* @example
* ```tsx
* // Default button
*
* {({ proceedToCheckout, canCheckout, isLoading, error }) => (
*
* {error &&
Error: {error}
}
*
*
* )}
*
*
* // Using asChild for custom button
*
*
*
* ```
*/
export declare const Checkout: React.ForwardRefExoticComponent & React.RefAttributes>;
/**
* Props for Notes component
*/
export interface NotesProps {
/** When true, the component will not render its own element but forward its props to its child */
asChild?: boolean;
/** Render prop function that receives notes data */
children?: AsChildChildren<{
/** Current notes value */
notes: string;
/** Function to update notes */
updateNotes: (notes: string) => Promise;
}>;
/** CSS class name */
className?: string;
/** Additional HTML attributes */
[key: string]: any;
}
/**
* Headless component for notes.
* Supports the asChild pattern for flexible composition.
*
* @component
* @example
* ```tsx
* // Default div wrapper
*
* {({ notes, updateNotes }) => (
*
*
* // Using asChild for custom wrapper
*
*
* Notes content will be rendered here
*
*
* ```
*/
export declare const Notes: React.ForwardRefExoticComponent & React.RefAttributes>;
/**
* Props for LineItemAdded component
*/
export interface LineItemAddedProps {
/** Render prop function that receives line item added subscription data */
children: (props: {
/**
* Subscribe to line item added events
* @param callback - Function called when items are added to cart
* @returns Unsubscribe function to clean up the subscription
*/
onAddedToCart: (callback: (lineItems: LineItem[] | undefined) => void) => void;
}) => React.ReactNode;
}
/**
* Headless component for line item added event subscription.
* This component does not render any DOM elements - it only provides event subscription functionality.
*
* @component
* @example
* ```tsx
*
* {({ onAddedToCart }) => {
* useEffect(() => {
* return onAddedToCart((lineItems) => {
* console.log('Items added:', lineItems);
* setShowNotification(true);
* });
* }, [onAddedToCart]);
* return null;
* }}
*
* ```
*/
export declare const LineItemAdded: (props: LineItemAddedProps) => import("react/jsx-runtime").JSX.Element;
export type CouponRootProps = CouponComponents.CouponRootProps;
export type CouponInputProps = CouponComponents.CouponInputProps;
export type CouponTriggerProps = CouponComponents.CouponTriggerProps;
export type CouponClearProps = CouponComponents.CouponClearProps;
export type CouponRawProps = CouponComponents.CouponRawProps;
/**
* Props for Note.Input component
*/
export interface NoteInputProps {
/** Whether to render as a child component */
asChild?: boolean;
/** Custom render function when using asChild */
children?: AsChildChildren<{
value: string;
onChange: (value: string) => void;
}>;
/** Placeholder text for the textarea */
placeholder?: string;
/** Maximum character limit */
maxLength?: number;
/** CSS classes to apply to the default element */
className?: string;
/** Additional HTML attributes */
[key: string]: any;
}
/**
* Coupon-related components namespace
*
* @example
* ```tsx
* // Complete coupon management with new Root structure
*
*
*
*
* Apply
*
*
*
* Remove coupon
*
*
*
* // Raw access to all coupon functionality
*
* {({ appliedCoupon, apply, remove, isLoading, error }) => (
*
* )}
*
* ```
*/
export declare const Coupon: {
readonly Root: React.ForwardRefExoticComponent>;
readonly Input: React.ForwardRefExoticComponent>;
readonly Trigger: React.ForwardRefExoticComponent>;
readonly Clear: React.ForwardRefExoticComponent>;
readonly Raw: React.FC;
};
/**
* Note-related components namespace
*/
export declare const Note: {
readonly Input: React.ForwardRefExoticComponent & React.RefAttributes>;
};
/**
* Represents a monetary value with amount and currency
*/
export interface Money {
/** The amount in the smallest currency unit (e.g., cents for USD) */
amount: number;
/** The currency code (e.g., 'USD', 'EUR') */
currency: string;
}
/**
* Props for cart price components that display various cart pricing information.
* Supports the asChild pattern for flexible composition.
*/
export interface CartPriceProps extends Omit, 'children'> {
/** When true, the component will not render its own element but forward its props to its child */
asChild?: boolean;
/** Render function that receives price data and formatting information */
children?: AsChildChildren<{
/** The price object containing amount and currency */
price: Money;
/** Human-readable formatted price string (e.g., "$24.99") */
formattedPrice: string;
/** Whether the price calculation is currently loading */
isLoading: boolean;
/** Optional label for the price component */
label?: string;
}>;
/** Optional text label to display with the price */
label?: string;
}
/**
* Namespace containing all cart pricing/totals components.
* These components provide a consistent way to display different aspects of cart pricing
* including subtotal, discounts, shipping, tax, and final total.
*
* All components support the asChild pattern for flexible styling and composition.
* They automatically handle loading states and conditional rendering based on cart state.
*
* @namespace
* @example
* ```tsx
* // Basic cart totals display
* function CartSummary() {
* return (
*
*
*
*
*
*
*
*
* );
* }
*
* // Custom styled totals with asChild
* function StyledCartTotals() {
* return (
*
* );
* }
* ```
*/
export declare const Totals: {
/** Cart subtotal before taxes, shipping, and discounts */
readonly Price: React.ForwardRefExoticComponent>;
/** Discount amount from applied coupons (only shows when coupon applied) */
readonly Discount: React.ForwardRefExoticComponent>;
/** Shipping cost for the order */
readonly Shipping: React.ForwardRefExoticComponent>;
/** Tax amount for the order */
readonly Tax: React.ForwardRefExoticComponent>;
/** Final total including all charges and discounts */
readonly Total: React.ForwardRefExoticComponent>;
};
interface ErrorProps extends Omit, 'children'> {
/** When true, the component will not render its own element but forward its props to its child */
asChild?: boolean;
/** Render prop function that receives error data */
children?: AsChildChildren<{
/** Error message to display */
error: string;
}>;
}
export declare const Errors: React.ForwardRefExoticComponent>;
export {};