Edge-docked overlay with portal, backdrop, and focus management.
Introduction
Drawer docks a panel to a viewport edge. It portals content over a backdrop, locks page scroll by default, and manages focus while open.
Prefer Drawer for side panels, filters, and settings that stay attached to an edge. Prefer Modal for centered dialogs.
Use the framework selector in the site header to switch between React and Vue.
Import
import { Drawer } from "@bridge-ui/vue/Components/Drawer";import { Drawer } from "@bridge-ui/react/Components/Drawer";Basic usage
Pair a trigger with a controlled Drawer. Place content such as a Card inside the panel.
Sizes
Use the size prop to control panel width for left/right placement and height for top/bottom. Available sizes: xs, sm, md (default), lg, xl, and full.
Persistent
When persistent is true, Escape and backdrop clicks do not close the drawer. Provide an explicit close action inside the content.
Placements
Use placement to dock the panel to left (default), right, top, or bottom. size controls width for left/right and height for top/bottom.
Transitions and blur
Set transition to slide (default), fade, or none. slide animates from the placement edge; fade fades both layers; none opens instantly. Combine with blur on the backdrop for depth.
Nested drawers
Place a second Drawer inside the first. Each layer gets its own overlay and a higher z-index. Escape closes only the topmost drawer.
Card composition
Combine Drawer with Card for structured panels. Use Card slots for title, body, and footer actions. Additional Drawer props such as blur, size, and transition customize the overlay experience.
Scroll lock
While open, Drawer locks body scroll and adds padding-right on document.body so page content does not shift when the scrollbar disappears. Fixed or sticky UI outside the document flow is not covered by that padding. Bridge UI sets --bridge-scrollbar-compensation on :root with the scrollbar width for the duration of the lock (and clears it when the last locking layer closes):
.my-fixed-header {
padding-inline-end: var(--bridge-scrollbar-compensation, 0px);
}Set disableScrollLock if the page should keep scrolling behind the overlay.
Related components
Accessibility
- Content under an active drawer is inert—users cannot interact with the page behind the overlay.
- Focus is trapped inside the drawer by default (disableEnforceFocus disables this).
- Focus returns to the trigger on close unless disableRestoreFocus is set.
- Escape closes the drawer when closeOnEscape is true and persistent is false.
- Pass ariaLabel or ariaLabelledBy for an accessible dialog name.
Anatomy
<div> <!-- Drawer root (portaled) -->
<div> <!-- overlay / backdrop -->
<div> <!-- panel -->
<!-- children: Card, form, or custom content -->
</div>
</div>API
| Prop | Type | Default | Description |
|---|---|---|---|
| v-model | boolean | — | Two-way binding for overlay visibility. |
| @close | — | — | Fired when the user dismisses (Escape or click-away). Not fired when the parent sets v-model={false} directly. |
| @show-change | (show: boolean) => void | — | Equivalent to onShowChange when you prefer events over a callback prop. |
| Prop | Type | Default | Description |
|---|---|---|---|
| show | boolean | — | Whether the overlay is visible. Use with onShowChange for controlled state. |
| onShowChange | (show: boolean) => void | — | Called when visibility changes. |
| onClose | () => void | — | Fired when the user dismisses (Escape or click-away). Not fired when the parent sets show={false} directly. |
| Prop | Type | Default | Description |
|---|---|---|---|
| placement | DrawerPlacement | "left" | Which edge the panel docks to. |
| size | DrawerSize | "md" | Panel size along the placement axis. |
| transition | DrawerTransition | "slide" | Enter/leave animation for overlay and panel. |
| blur | DrawerBlur | "none" | Backdrop blur on the overlay. |
| persistent | boolean | false | When true, Escape and overlay clicks do not close the drawer. |
| closeOnEscape | boolean | true | Whether the drawer closes on Escape. |
| closeOnOverlay | boolean | true | Whether the drawer closes on overlay click. |
| hideBackdrop | boolean | false | When true, the backdrop overlay is not rendered. |
| scroll | DrawerScroll | "paper" | Where scroll happens: page (body) or panel (paper). |
| autoFocus | boolean | false | Focus the first focusable element on open. |
| disableEnforceFocus | boolean | false | When true, focus is not trapped inside the drawer. |
| disableRestoreFocus | boolean | false | When true, focus is not restored on close. |
| disableScrollLock | boolean | false | When true, body scroll is not locked while open. |
| keepMounted | boolean | false | When true, the drawer stays mounted after closing (hidden). |
| teleportTo | string | false | "body" | Portal target. Pass false to render in place. |
| ariaLabel | string | — | Accessible name for the dialog. |
| ariaLabelledBy | string | — | Id of the element that labels the dialog. |
| classes | DrawerClasses | — | Class overrides for drawer parts. |
| customProps | DrawerCustomProps | — | Props forwarded to each drawer part. |