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.

When scroll="paper" (the default), overflow happens inside the panel. The panel uses bridge-scroll-fade-y and bridge-hide-scrollbar so a fade hints overflow instead of a thumb. See Scroll utilities.

Card, Modal, Sidebar, 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
@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.
v-model boolean — Two-way binding for overlay visibility.
Prop Type Default Description
onClose () => void — Fired when the user dismisses (Escape or click-away). Not fired when the parent sets show={false} directly.
onShowChange (show: boolean) => void — Called when visibility changes.
show boolean — Whether the overlay is visible. Use with onShowChange for controlled state.
Prop Type Default Description
ariaLabel string — Accessible name for the dialog.
ariaLabelledBy string — Id of the element that labels the dialog.
autoFocus boolean false Focus the first focusable element on open.
blur DrawerBlur "none" Backdrop blur on the overlay.
classes DrawerClasses — Class overrides for drawer parts.
closeOnEscape boolean true Whether the drawer closes on Escape.
closeOnOverlay boolean true Whether the drawer closes on overlay click.
customProps DrawerCustomProps — Props forwarded to each drawer part.
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.
hideBackdrop boolean false When true, the backdrop overlay is not rendered.
keepMounted boolean false When true, the drawer stays mounted after closing (hidden).
persistent boolean false When true, Escape and overlay clicks do not close the drawer.
placement DrawerPlacement "left" Which edge the panel docks to.
scroll DrawerScroll "paper" Where scroll happens: page (body) or panel (paper). paper uses bridge-scroll-fade-y and bridge-hide-scrollbar.
size DrawerSize "md" Panel size along the placement axis.
teleportTo string | false "body" Portal target. Pass false to render in place.
transition DrawerTransition "slide" Enter/leave animation for overlay and panel.