Current section

Files

Jump to
mishka_chelekom usage-rules headless drawer.md
Raw

usage-rules/headless/drawer.md

# drawer (headless)
An unstyled, focus-trapped panel that slides in from an edge — same behavior as `dialog`
(WAI-ARIA Dialog-Modal pattern), with a `side`.
## Generate
`mix mishka.ui.gen.headless drawer``lib/<app>_web/components/headless/drawer.ex` (wires the
`FocusTrap` JS engine).
## Anatomy
Root `div[phx-hook="FocusTrap"][data-side]`. Parts (via `data-part`): `trigger`, `backdrop`
(auto, `aria-hidden`), `popup` (`role="dialog"` `aria-modal` `data-side`), `title`,
`description`, `close`. Put `data-close` on a button to close.
## ARIA & keyboard
Escape closes; Tab is trapped inside the popup; focus returns to the opener on close. Backdrop
click closes (unless `data-close-on-outside="false"`).
## State
Paired-presence `data-open`/`data-closed` on root + popup (toggled by `FocusTrap`); `data-side`
(left/right/top/bottom) for your slide animation.
## Example
```heex
<.drawer id="filters" side="right">
<:trigger>Filters</:trigger>
<:title>Filters</:title>
<:description>Refine the results.</:description>
<p>…filter controls…</p>
<:close><button data-close>Done</button></:close>
</.drawer>
```
Attrs: `id` (req), `open`, `side` (default `right`), `labelledby`, `describedby`, `class`, `rest`.
## Styling
Ships no colors. Pin the popup to an edge and animate off the `data-side` + `data-open`/`data-closed`
state, e.g. `.chelekom-drawer__popup[data-side=right]{ right:0; … }`.