Drawer

A drawer component for displaying content in a slide-out panel from any side of the screen.

Drawers open from the right by default, for settings and forms. Most product drawers set width between 460 and 560px. The footer's customRenderer gets a closeDrawer callback.

Left

Set placement="left" for lists that relate to the page's own navigation. contentClassName adjusts the content padding.

Wide

Use 800px or more for multi-column forms and detail views. Without width the drawer grows up to 1100px. On small screens it fills the viewport.

Setup

Mount <DrawerProvider /> once near the root of your app (inside the relevant context providers). Nested mounts will render duplicate drawers because all drawers share the same global Zustand store.

Usage

Open drawers through the store. DrawerProvider renders the drawer parts for you. Opening a drawer with an id that is already open replaces it; opening a new id stacks it on top.

The store also has updateDrawer(id, updates) to change an open drawer and closeAllDrawers().

openDrawer Options

idRequired
string

Unique identifier for the drawer. Pass it to closeDrawer and updateDrawer.

content
ReactNode

Content rendered inside the drawer's padded scroll area

placement
'left''right''top''bottom'

Side of the screen where the drawer appears

Default: right

width
number

Maximum width of the drawer in pixels

Default: 1100

header
object

Header configuration. See header Options below.

hideHeader
boolean

Removes the header bar, close button included, for content that renders its own header

Default: false

footer
{ customRenderer?: ({ closeDrawer, id }) => ReactNode }

Footer rendered below the scroll area. Nothing renders without customRenderer.

withOverlay
boolean

Renders the backdrop and makes the drawer modal

Default: true

closeOnEsc
boolean

Whether to close drawer when escape key is pressed

Default: true

closeOnOutsideClick
boolean

Whether to close drawer when clicking outside

Default: true

beforeClose
() => boolean

Called before closing. Return false to keep the drawer open.

onClose
() => void

Called when the drawer closes. May return a promise, which closeDrawer passes back.

onCloseAutoFocus
(event: Event) => void

Called when focus moves back after the drawer closes

className
string

Additional CSS classes for the drawer panel

contentClassName
string

Additional CSS classes for the padded content box

scrollAreaClassName
string

Additional CSS classes for the scroll area around the content

header Options

title
ReactNode

Title shown on the left of the header

showCloseButton
boolean

Shows the close button on the right of the header

Default: true

headerEnd
ReactNode

Content placed after the title

isBackButton
boolean

Renders the title as a back button with a left chevron

Default: false

onBack
() => void

Called by the back button. Closes the drawer when omitted.

showNavigation
boolean

Shows the previous/next pager. Needs currentIndex and totalItems.

Default: false

currentIndex
number

0-based index of the item shown in the pager

totalItems
number

Number of items in the pager

labelPrefix
string

Text shown before the pager count

onPrevious
() => void

Called by the pager's previous button

onNext
() => void

Called by the pager's next button

customRenderer
({ closeDrawer, id }) => ReactNode

Replaces the whole header, including its container