> ## Documentation Index
> Fetch the complete documentation index at: https://docs-loja.usecorvex.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Cart Drawer

> Cookbook — drawer lateral com useCorvexCart, quantidade, subtotal e checkout.

> Quero um carrinho lateral (drawer) com atualizar quantidade e checkout. Como implementar?

Referência: `seu tema (adaptado do cookbook)` + `sections/cart-drawer-demo/`

Índice: [Cookbooks](https://docs-loja.usecorvex.com.br/cookbook/overview.md)

***

## Objetivo

```text theme={"theme":{"light":"github-light","dark":"github-dark"}}
useCorvexCart() no parent
↓
items, subtotal, mutating, loading
↓
CartDrawer snippet (UI)
↓
updateQuantity / removeItem / goToCheckout
```

O snippet **não** busca carrinho — só renderiza props do hook.

***

## Contratos utilizados

* [Cart Contract](https://docs-loja.usecorvex.com.br/reference/contracts/cart.md)
* [Cart resource](https://docs-loja.usecorvex.com.br/data/resources/cart.md) — `StorefrontCartItem`
* `@corvex/theme-sdk` — `formatPrice`
* `@corvex/runtime` — `SectionChrome`, `useCorvexCart` (demo section)

## Shape público (`useCorvexCart`)

| Campo / método | Uso |
| - | - |
| `items` | Linhas do carrinho |
| `subtotal` | Subtotal numérico no footer |
| `loading` | Estado inicial |
| `mutating` | Desabilita ações |
| `error` | Falha em mutação |
| `updateQuantity(itemId, quantity, variantId?)` | +/- qty |
| `removeItem(itemId, variantId?)` | Remover linha |
| `goToCheckout()` | Redireciona checkout |

**StorefrontCartItem:** `id`, `title`, `name`, `quantity`, `linePrice`, `price`, `image`, `productVariantId`.

**Não usar:** `cart.lines`, `productTitle`, `variantTitle` (não públicos).

***

## Arquivos

```text theme={"theme":{"light":"github-light","dark":"github-dark"}}
snippets/cart-drawer/
├── snippet.jsx    # UI pura (props)
└── styles.css

sections/cart-drawer-demo/
├── section.jsx    # useCorvexCart + estado open local
├── schema.json
└── styles.css
```

***

## Snippet (UI)

```jsx theme={"theme":{"light":"github-light","dark":"github-dark"}}
import CartDrawer from '@corvex/snippets/cart-drawer';

<CartDrawer
  open={open}
  onClose={() => setOpen(false)}
  items={items}
  subtotal={subtotal}
  loading={loading}
  mutating={mutating}
  error={error}
  onUpdateQuantity={(item, qty) =>
    updateQuantity(item.id, qty, item.productVariantId ?? null)
  }
  onRemove={(item) =>
    removeItem(item.id, item.productVariantId ?? null)
  }
  onCheckout={() => goToCheckout()}
/>
```

***

## Estado open/close (local)

```jsx theme={"theme":{"light":"github-light","dark":"github-dark"}}
const [open, setOpen] = useState(false);

<button type="button" onClick={() => setOpen(true)}>Carrinho</button>
```

### Abrir o drawer a partir do header

O SDK não expõe uma função para abrir o drawer de outra seção. Não existe evento global de carrinho.

Opções no tema:

1. **Link `/cart`** — página dedicada ([cart template](https://docs-loja.usecorvex.com.br/reference/contracts/page.md))
2. **Estado React elevado** — layout `theme.jsx` ou provider local do tema compartilha `open` entre header e drawer
3. **Aguardar contrato futuro** — não inventar `window.openCart()` ou similar

O cookbook header usa link `/cart` por design.

***

## Subtotal e preços

* Hook expõe `subtotal` (número) — use `formatPrice(subtotal)` do SDK
* Linha: `item.linePrice` ou `item.price` (contrato público)

***

## Checkout

```jsx theme={"theme":{"light":"github-light","dark":"github-dark"}}
await goToCheckout();
```

Redireciona via `checkoutUrl` persistido pelo SDK. Botão desabilitado quando `items` vazio ou `mutating`.

***

## Acessibilidade

* `role="dialog"` + `aria-modal="true"`
* Botão fechar com `aria-label`
* `Escape` fecha (handler no overlay)
* Overlay click fecha

***

## Edge cases

| Caso | UI |
| - | - |
| `loading` | "Carregando…" |
| `items` vazio | `emptyText` |
| `error` após mutação | alerta genérico |
| `mutating` | botões disabled |
| qty mínima 1 no − | não remove via − (usar Remover) |

***

## Checklist

* [ ] `useCorvexCart` no parent, não no snippet de dados
* [ ] `updateQuantity` / `removeItem` com `item.id`
* [ ] Somente campos públicos de `StorefrontCartItem`
* [ ] Estado `open` local ou elevado no tema — sem API global inventada
* [ ] `corvex validate .`

***

## Veja também

* [Header Cookbook](https://docs-loja.usecorvex.com.br/cookbook/header.md) — `itemCount` + link `/cart`
* [Variant Selector](https://docs-loja.usecorvex.com.br/cookbook/variant-selector.md) — `addItem` antes do drawer
* [Featured Product](https://docs-loja.usecorvex.com.br/cookbook/featured-product.md) — `addItem(product, 1)`


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.