Drawer
StableSide panel overlay that slides in from any edge. Uses the same compound API as Dialog. Animation direction follows the side prop. Focus trap and restoration built in.
OverlayCompoundFocus trapVhyxSeal
Interactive example
Click a side button to open that drawer
Import
tsx
import { Drawer } from '@vhyxui/react'
// Same sub-components as Dialog
// Drawer.Trigger, Drawer.Portal, Drawer.Overlay
// Drawer.Content, Drawer.Header, Drawer.Footer
// Drawer.Title, Drawer.Description, Drawer.CloseSides
All four sides
Sizes
sm, md, lg, full — width for side drawers, height for top/bottom
Props
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | — | Controlled open state. |
onOpenChange | (open: boolean) => void | — | Called when the open state changes. |
side | 'left' | 'right' | 'top' | 'bottom' | 'right' | Which edge the drawer slides in from. |
size | 'sm' | 'md' | 'lg' | 'full' | 'md' | Width (left/right) or height (top/bottom) of the panel. |
contract | Partial<ComponentContract> | — | VhyxSeal contract override. |
Accessibility
-
role="dialog",aria-modal="true",aria-labelledbypointing to Drawer.Title. - Drawer.Title is required — a development warning is logged if absent.
- Focus trap and Escape-to-close — identical behavior to Dialog.
- Focus returns to the exact trigger element on close.
Keyboard navigation
| Key | Action |
|---|---|
| Escape | Close the drawer and return focus to the trigger. |
| Tab | Cycle through focusable elements inside the drawer. |
| Shift + Tab | Reverse focus cycle within the drawer. |
Agent contract
Default VhyxSeal contract shipped with every Drawer.
Default contract
{
"type": "navigation",
"intent": "open-drawer",
"description": "Opens a slide-in panel from a screen edge for navigation or contextual content",
"requires": [],
"requiredPermissions": [],
"consequence": "Renders a side panel overlay — underlying page remains accessible",
"affects": [
"view"
],
"reversible": true,
"safetyLevel": "low",
"requiresConfirmation": false,
"destructive": false,
"contractVersion": "0.0.1",
"fingerprint": "vhyxs_777f4680"
}Theming
Override these CSS tokens to theme Drawer.
--vhyx-z-modalZ-index (400)
--vhyx-color-surfacePanel background
--vhyx-shadow-2xlPanel shadow
--vhyx-duration-slowSlide animation duration
--vhyx-easing-decelerateEntry easing
Examples
Navigation drawer (left)
Slide-in nav menu
Mobile filter panel (bottom)
tsx
<Drawer side="bottom" size="lg">
<Drawer.Trigger asChild>
<Button>Filters</Button>
</Drawer.Trigger>
<Drawer.Portal>
<Drawer.Overlay />
<Drawer.Content>
<Drawer.Header>
<Drawer.Title>Filter results</Drawer.Title>
</Drawer.Header>
{/* filter controls */}
<Drawer.Footer>
<Button style={{ width: '100%' }}>Apply filters</Button>
</Drawer.Footer>
</Drawer.Content>
</Drawer.Portal>
</Drawer>