# Cart Drawer

> A slide-over shopping cart on Base UI's Drawer. The quantity minus turns into a bin at one, stock caps show "Only 2 left", and a removed line leaves an undo strip that drains away. A meter counts toward free shipping, suggestions add in one tap, and prices roll as they change. Swipe it away on touch. Also exports CartButton, a bag icon whose count pops.

- Slug: `cart-drawer`
- Category: [Commerce](https://www.assembli.design/category/commerce.md)
- Type: component
- Tags: cart, shopping-cart, drawer, ecommerce, checkout, quantity, undo, free-shipping
- npm dependencies: @base-ui/react, lucide-react, motion
- shadcn/ui dependencies: none
- Live preview: https://www.assembli.design/preview/cart-drawer
- Page: https://www.assembli.design/components/cart-drawer

![Cart Drawer preview](https://www.assembli.design/thumbnails/cart-drawer-light.png)

## Props

Other props pass through to the root element.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `lines` | `CartLine[]` |  |  |
| `defaultLines` | `CartLine[]` | `[]` |  |
| `onLinesChange` | `(lines: CartLine[]) => void` |  |  |
| `trigger` | `React.ReactElement<Record<string, unknown>>` |  | An element that opens the cart, such as `<CartButton />`. |
| `open` | `boolean` |  |  |
| `defaultOpen` | `boolean` |  |  |
| `onOpenChange` | `(open: boolean) => void` |  |  |
| `title` | `React.ReactNode` | `"Your cart"` |  |
| `currency` | `string` | `"USD"` |  |
| `locale` | `string` | `"en-US"` |  |
| `freeShippingAt` | `number` |  | Subtotal that unlocks free shipping. Shows a progress meter on top; leave out to hide it. |
| `upsells` | `CartUpsell[]` | `[]` | Products suggested under the lines and in the empty state. |
| `upsellTitle` | `React.ReactNode` | `"Pairs well with"` |  |
| `onCheckout` | `(lines: CartLine[], subtotal: number) => void \| Promise<unknown>` |  | Called with the lines and subtotal. Return a promise to show a spinner on the button until it settles. |
| `undoSeconds` | `number` | `5` | Seconds a removed line can be restored for. |
| `container` | `HTMLElement \| React.RefObject<HTMLElement \| null> \| null` |  | Mount inside this element instead of `<body>` (a preview frame, a pane). |

## Install

One-time setup (needs a subscription):

1. Add the registry to the project's `components.json`: `{"@assembli":{"url":"https://www.assembli.design/r/{name}.json","headers":{"Authorization":"Bearer ${ASSEMBLI_API_KEY}"}}}` (merge into `"registries"`).
2. Put an API key from https://www.assembli.design/account in `.env.local` as `ASSEMBLI_API_KEY=asm_…`.

Then install with the shadcn CLI (writes `components/cart-drawer/cart-drawer.tsx` and installs dependencies):

```bash
npx shadcn@latest add @assembli/cart-drawer
```

Registry item JSON: https://www.assembli.design/r/cart-drawer.json (send `Authorization: Bearer <api key>`)

## Code

> Component source needs an Assembli subscription ($12/month or $96/year) and an API key sent as `Authorization: Bearer <key>`. To get one without copying anything, POST https://www.assembli.design/api/agent/login (or call the MCP tool connect_account), show the user the link it returns, and poll https://www.assembli.design/api/agent/token for the key. Or subscribe at https://www.assembli.design/pricing and create a key at https://www.assembli.design/account.
