Bridge UI

Drawer

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.

Drawer vs Modal

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.

Card, Modal, useDrawerAction

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.