# Sheet

The one drawer: floats over the region (never reflows the layout), full takeover under 700px, a lens on the armed object with crossfade swap, resizable handle with keyboard path, lens/focus postures remembered per key.

Install: `npx candlelight-ds add sheet`

Category: primitive · Grammar: G1, G7

## Use when

Editing or inspecting the thing selected from an adjacent list.

## Don't use when

Blocking decisions (Overlay) or whole workflows (a route).

## States

- closed
- open lens (340px)
- open focus (560px+)
- takeover (<700px container)
- dragging the handle
- content swapping (120ms crossfade)

## Keyboard

- `Esc` — steps focus → lens → closed
- `←/→ on the handle` — nudges width 16px

## Traps (shipped once — do not re-learn)

- Cold-mount focus: focus the title only after the panel exists (key the effect on mounted, not just open).
- Focus steal: the title-focus effect must never depend on callback props — an unstable onClose would re-fire it on every continuous save.

## Acceptance tests

- The layout behind never reflows (push mode is dead).
- Arming a different object swaps content in place — the drawer does not close/reopen.
- The handle is a citizen: role=separator, focusable, ←/→ nudges, width remembered per key per posture.
- Closing is announced with Undo when local state dies, never blocked by a dialog.

## Files

- components/ui/Sheet.tsx

npm dependencies: @candlelight-ds/tokens, lucide-react, clsx, tailwind-merge

Rendered twin: https://candlelight-docs.vercel.app/components/sheet · Full spec: https://candlelight-docs.vercel.app/spec.md
