Responsive
undefined
Responsive behavior belongs to the canonical pattern contract and source rather than a docs-only clone.
commerce-social production pattern
Shopping cart with quantity edits, removal, and checkout.
Live production pattern
The preview is the actual Pattern Gallery route and source below is the canonical screen composition.
Exact committed source used by the preview/runtime path.
import { Button, Card, EmptyState, HStack, Separator, Text, VStack } from '@beemvp/beeui-ui';
import * as React from 'react';
import type { CartItem } from '../fixtures/commerce-fixtures';
import { cartItems, formatPrice } from '../fixtures/commerce-fixtures';
import { CartRow } from '../components/cart-row';
import { PatternScreen } from '../components/screen-shell';
export type CartScreenProps = {
empty?: boolean;
items?: CartItem[];
onCheckout?: () => void;
onQuantityChange?: (itemId: string, quantity: number) => void;
onRemove?: (itemId: string) => void;
};
export function CartScreen({ empty = false, items = cartItems, onCheckout, onQuantityChange, onRemove }: CartScreenProps) {
const visibleItems = empty ? [] : items;
const subtotal = visibleItems.reduce((sum, item) => sum + item.product.price * item.quantity, 0);
const delivery = subtotal >= 100 ? 0 : 12;
const discount = subtotal >= 300 ? 24 : 0;
const total = subtotal + delivery - discount;
return (
<PatternScreen description="Review quantities, delivery, and the real total before moving to checkout." eyebrow="Bag" testID="cart-screen" title={`${visibleItems.length} ${visibleItems.length === 1 ? 'item' : 'items'} in your cart`}>
{visibleItems.length === 0 ? (
<EmptyState action={<Button variant="outline">Browse the collection</Button>} description="Saved pieces will stay here until you are ready." testID="cart-empty" title="Your cart is beautifully empty" />
) : (
<VStack gap="lg" testID="cart-populated">
<VStack gap="md">
{visibleItems.map((item) => (
<CartRow
item={item}
key={item.id}
onQuantityChange={(itemId, quantity) => onQuantityChange?.(itemId, quantity)}
onRemove={(itemId) => onRemove?.(itemId)}
/>
))}
</VStack>
<Card className="gap-3 p-4" variant="raised">
<Text variant="heading">Order summary</Text>
<HStack justify="between"><Text tone="muted">Subtotal</Text><Text>{formatPrice(subtotal)}</Text></HStack>
<HStack justify="between"><Text tone="muted">Delivery</Text><Text>{delivery ? formatPrice(delivery) : 'Free'}</Text></HStack>
{discount ? <HStack justify="between"><Text tone="success">Collection discount</Text><Text tone="success">−{formatPrice(discount)}</Text></HStack> : null}
<Separator />
<HStack justify="between"><Text variant="heading">Total</Text><Text variant="heading">{formatPrice(total)}</Text></HStack>
<Button onPress={onCheckout} testID="cart-checkout">Continue to checkout</Button>
</Card>
</VStack>
)}
</PatternScreen>
);
}
Responsive
Responsive behavior belongs to the canonical pattern contract and source rather than a docs-only clone.
Application layer
Cart persistence, pricing/tax calculation, and checkout routing.
Composition
Each linked symbol opens its component preview-and-code recipe.
Application boundary
Cart persistence, pricing/tax calculation, and checkout routing.
Caller contract: CartScreenProps · onCheckout onQuantityChange onRemove
Adapt safely
This screen source is a production composition recipe. Fetching, persistence, routing, authentication/business rules, and backend side effects stay in the consuming application.