Drawer 1.2.2
<velin-drawer> slides an off-canvas panel from any side with overlay, focus trap, and
scroll lock. In 1.2.0, lifecycle uses focus-manager for background inert + overflow locking. Deutsch: Schublade
Maturity: Documented as stable in VelinStyle 1.2.0. Design Intelligence (plan / review / agent meta) is separate and beta / foundation where noted.
When to use
- Navigation, filters, or secondary panels that should not cover the full viewport as a centered modal.
- When edge placement matters (
start/end/top/bottom).
When not
- Centered forms or confirmations — use Modal or Dialog.
- Mobile action sheets that should hug the bottom only — prefer Sheet.
Basic example
Drawer content goes here.
<velin-drawer title="Navigation" id="myDrawer">
<p>Drawer content goes here.</p>
</velin-drawer>
<button type="button" class="velin-btn velin-btn--primary"
onclick="document.getElementById('myDrawer').open()">
Open Drawer
</button>
Four sides
Use side: start (default), end, top, or bottom. Positioning uses logical inset properties so start/end flip in RTL.
<velin-drawer side="start" title="Menu">…</velin-drawer>
<velin-drawer side="end" title="Filters">…</velin-drawer>
<velin-drawer side="top" title="Banner">…</velin-drawer>
<velin-drawer side="bottom" title="Actions">…</velin-drawer>
Accessibility
- Panel:
role="dialog",aria-modal="true",aria-labelledbyon the title. - Close button:
aria-label="Close"(part="close"). - On open:
focus-managersaves focus, applies siblinginert, locks body scroll; focuses first focusable in the shadow tree. - Tab trap + Escape →
close(); overlay click closes. - On close / disconnect:
clearBackgroundInert(this)and focus restore. close()dispatches bubblingvelin-close.
Dark, responsive, motion, RTL
- Dark / themes:
--velin-color-surface-bright, overlay, and border tokens. - Responsive: side drawers use
min(20rem, 85vw); top/bottom usemin(50vh, 24rem). - Motion: overlay/panel transitions off under
prefers-reduced-motion: reduce. - RTL: prefer
side="start"|"end"over left/right so panels mirror correctly.
API
Attributes
| Attribute | Type | Description |
|---|---|---|
open | Boolean | Observed — presence opens the drawer |
side | String | start | end | top | bottom |
title | String | Header title (escaped) + labelling |
Methods, events, parts
| API | Description |
|---|---|
open() / close() | Toggle visibility; close() fires velin-close |
velin-close | Bubbling close event |
| Parts | overlay, drawer, header, body, close |
| Default slot | Drawer body |
CSS variables
| Variable | Description |
|---|---|
--velin-color-overlay | Backdrop |
--velin-color-surface-bright | Panel background |
--velin-shadow-xl | Panel shadow |
--velin-z-overlay | Backdrop z-index (400) |
--velin-z-modal | Panel z-index (500) |
Best practices & pitfalls
- Always set a meaningful
titleforaria-labelledby. - Use logical
sidevalues; physical left/right attributes are not supported. - Do not set
document.body.style.overflowyourself —focus-managerowns scroll lock (ADR 0013). - Removing an open drawer from the DOM clears its inert layer via
disconnectedCallback.