Drawer
A panel that slides in from an edge of the screen and that users swipe to close.
A drawer slides a panel in from an edge of the screen, where users read details or complete a short task without leaving the page. By default, it rises from the bottom edge, and while it is open, focus stays in the drawer and the page behind it doesn't scroll. Users close it with a swipe toward its edge, a close button, the Escape key or a press outside the drawer. On a touch screen, the swipe starts anywhere on the drawer. With a mouse, it starts on the swipe handle only, because a drag in the content selects text.
Usage
Examples
Swipe Up
Some content belongs near the upper edge of a screen, such as filters that apply to the list beneath them. With swipeDirection set to "up", the drawer slides in from the top edge, and users close it with a swipe upward.
Swipe Down
On a phone, the lower edge lies within reach of the thumb, which makes it the natural place for a short task. This edge is the default, and swipeDirection set to "down" states it explicitly.
Swipe Left
Navigation between the areas of a product commonly opens from the left side of the screen. Set to "left", swipeDirection brings the drawer in from that edge, and a swipe to the left closes it again.
Swipe Right
Details that accompany the current page, such as the history of an order, usually open at the right edge. Through the value "right" of swipeDirection, the drawer enters from there, and users swipe it back to the right to close it.
With Swipe Handle
A drag with the mouse in the content of a drawer selects text instead of moving the drawer. Once showSwipeHandle is set, the drawer offers a handle that users drag with a mouse or a finger, to close the drawer or to move it to another snap point.
With Snap Points
Long content often deserves a first glance before users decide to read all of it. Through snapPoints, the drawer comes to rest at several heights, opens at the first of them, and moves between them as users swipe.
Default Snap Point
Where users need the full content from the start, defaultSnapPoint opens the drawer at another of its snap points instead of the first. Users still swipe it down to a smaller height or close it.
Controlled Snap Point
An application can move the drawer between its heights on its own, for example to expand it when a step inside it needs more room. For this, snapPoint and onSnapPointChange hold the current snap point in the application, while users keep swiping between the heights.
Sequential Snap Points
With three or more heights, a quick swipe can carry the drawer past the ones in between. Once snapToSequentialPoints is set, the distance of the drag alone decides the next snap point, and the speed of a swipe no longer skips one.
Nested
A task in a drawer can raise a related question that deserves room of its own. Opened from within the first, a second drawer stacks above it, and once users close it, they return to the first drawer as they left it.
Controlled
The application sometimes decides when the drawer opens or closes, for example to close it as soon as a change has been saved. Through open and onOpenChange it holds that state, and users keep every way to open and close the drawer.
Disabled Trigger
Details can depend on data that is still on its way, such as a report that has not been generated yet. Marked as disabled, the trigger no longer opens the drawer, while users still see that the details exist.
Disabled Close
A single close button can lose its purpose for a moment, for example while an entry is being saved. With disabled, that button ignores presses, yet a swipe, the Escape key and a press outside the drawer still close it.
API Reference
Drawer
| Prop | open |
|---|---|
| Type | boolean |
| Default | – |
| Description | Sets whether the drawer is open and makes it controlled. Update it in onOpenChange. |
| Prop | defaultOpen |
|---|---|
| Type | boolean |
| Default | false |
| Description | Opens the drawer at first render. The drawer then tracks its open state itself. |
| Prop | onOpenChange |
|---|---|
| Type | (open: boolean, eventDetails: DrawerRootChangeEventDetails) => void |
| Default | – |
| Description | Runs when users open or close the drawer. It receives the open state that follows. |
| Prop | onOpenChangeComplete |
|---|---|
| Type | (open: boolean) => void |
| Default | – |
| Description | Runs after the drawer has opened or closed and its animations have finished. |
| Prop | swipeDirection |
|---|---|
| Type | "up" | "down" | "left" | "right" |
| Default | "down" |
| Description | Sets the direction of the swipe that closes the drawer, and with it the edge of the screen that the drawer slides in from. "down" places the drawer at the bottom edge, "up" at the top edge, "left" at the left edge and "right" at the right edge. |
| Prop | showSwipeHandle |
|---|---|
| Type | boolean |
| Default | false |
| Description | Shows a handle on the side of the drawer that faces the page. Users drag it to close the drawer or to move it to another snap point. With a mouse, the handle is the only part of the drawer that starts a swipe. |
| Prop | snapPoints |
|---|---|
| Type | (number | string)[] |
| Default | – |
| Description | Sets the heights at which the drawer comes to rest. A number from 0 to 1 is a fraction of the viewport height, a number above 1 is a height in pixels, and a string is a height in px or rem, such as "16rem". Snap points only apply to the swipe directions "down" and "up". |
| Prop | snapPoint |
|---|---|
| Type | number | string | null |
| Default | – |
| Description | Sets the snap point at which the drawer rests and makes it controlled. Update it in onSnapPointChange. |
| Prop | defaultSnapPoint |
|---|---|
| Type | number | string | null |
| Default | – |
| Description | Sets the snap point at which the drawer opens. Without it, the drawer opens at the first entry of snapPoints. The drawer then tracks its snap point itself. |
| Prop | onSnapPointChange |
|---|---|
| Type | (snapPoint: number | string | null, eventDetails: DrawerRootSnapPointChangeEventDetails) => void |
| Default | – |
| Description | Runs when the snap point changes. It receives the snap point that follows, or null when users swipe the drawer closed. When the drawer closes, it receives the snap point at which the drawer opens next. |
| Prop | snapToSequentialPoints |
|---|---|
| Type | boolean |
| Default | false |
| Description | Makes the distance of the drag alone decide the next snap point. Without it, the speed of the swipe counts as well, so a fast swipe can skip snap points. |
| Prop | modal |
|---|---|
| Type | boolean | "trap-focus" |
| Default | true |
| Description | Sets how the drawer limits the rest of the page while it is open. With true, focus stays in the drawer, the page doesn't scroll, and an overlay covers the page. With "trap-focus", focus stays in the drawer, but the page scrolls and has no overlay. With false, focus can move to the rest of the page, and the page scrolls and has no overlay. |
| Prop | disablePointerDismissal |
|---|---|
| Type | boolean |
| Default | false |
| Description | Keeps the drawer open when users press outside of it. A drawer with modal set to false then also stays open when focus moves outside of it. |
| Prop | triggerId |
|---|---|
| Type | string | null |
| Default | – |
| Description | Sets the ID of the trigger that a controlled drawer is associated with. A drawer without open doesn't need it. |
| Prop | defaultTriggerId |
|---|---|
| Type | string | null |
| Default | – |
| Description | Sets the ID of the trigger that the drawer is associated with when defaultOpen opens it at first render. |
| Prop | handle |
|---|---|
| Type | DrawerHandle<Payload> |
| Default | – |
| Description | Connects the drawer with triggers that are rendered outside of it. Create the handle with Drawer.createHandle() from @base-ui/react/drawer. |
| Prop | actionsRef |
|---|---|
| Type | RefObject<DrawerRootActions | null> |
| Default | – |
| Description | Receives the functions close and unmount. close closes the drawer from code, and unmount removes it from the DOM after a closing animation that the code controls itself. |
| Prop | children |
|---|---|
| Type | ReactNode | ((arg: { payload: Payload | undefined }) => ReactNode) |
| Default | – |
| Description | Holds the parts of the drawer. A function receives the payload of the trigger that opened the drawer. |
DrawerTrigger
| Prop | handle |
|---|---|
| Type | DrawerHandle<Payload> |
| Default | – |
| Description | Connects the trigger with a drawer that it is rendered outside of. Pass the same handle to Drawer. |
| Prop | payload |
|---|---|
| Type | Payload |
| Default | – |
| Description | Passes a value to the drawer when this trigger opens it. A function as children of Drawer receives it. |
| Prop | id |
|---|---|
| Type | string |
| Default | – |
| Description | Sets the ID of the trigger element. triggerId and defaultTriggerId of Drawer refer to it. |
| Prop | render |
|---|---|
| Type | ReactElement | render function |
| Default | – |
| Description | Replaces the native element or composes the trigger with another component. |
| Prop | nativeButton |
|---|---|
| Type | boolean |
| Default | true |
| Description | Declares whether the rendered element is a native button. Set it to false when render returns a different element. |
| Prop | disabled |
|---|---|
| Type | boolean |
| Default | false |
| Description | Prevents users from opening the drawer with this trigger. |
DrawerPortal
| Prop | keepMounted |
|---|---|
| Type | boolean |
| Default | false |
| Description | Keeps the portal in the DOM while the drawer is closed. |
| Prop | container |
|---|---|
| Type | HTMLElement | ShadowRoot | RefObject<HTMLElement | ShadowRoot | null> | null |
| Default | – |
| Description | Sets the element that the portal is rendered into. Without it, the portal is appended to the body. |
| Prop | render |
|---|---|
| Type | ReactElement | render function |
| Default | – |
| Description | Replaces the native element or composes the portal with another component. |
DrawerOverlay
| Prop | forceRender |
|---|---|
| Type | boolean |
| Default | false |
| Description | Renders the overlay even when the drawer is nested in another drawer. |
| Prop | render |
|---|---|
| Type | ReactElement | render function |
| Default | – |
| Description | Replaces the native element or composes the overlay with another component. |
DrawerContent
| Prop | initialFocus |
|---|---|
| Type | boolean | RefObject<HTMLElement | null> | ((openType: InteractionType) => boolean | HTMLElement | null | void) |
| Default | – |
| Description | Determines the element that receives focus when the drawer opens. Without it, focus moves to the drawer itself and not to an element inside it. |
| Prop | finalFocus |
|---|---|
| Type | boolean | RefObject<HTMLElement | null> | ((closeType: InteractionType) => boolean | HTMLElement | null | void) |
| Default | – |
| Description | Determines the element that receives focus when the drawer closes. Without it, focus returns to the trigger or to the element that had focus before. |
| Prop | render |
|---|---|
| Type | ReactElement | render function |
| Default | – |
| Description | Replaces the native element or composes the content with another component. |
DrawerSwipeHandle
DrawerSwipeHandle shows the bar that users drag to close the drawer or to move it to another snap point. DrawerContent renders it when showSwipeHandle is set on Drawer. It renders a div and has no props of its own.
DrawerHeader
DrawerHeader groups the title and the description. It renders a div and has no props of its own.
DrawerTitle
| Prop | render |
|---|---|
| Type | ReactElement | render function |
| Default | – |
| Description | Replaces the native element or composes the title with another component. |
DrawerDescription
| Prop | render |
|---|---|
| Type | ReactElement | render function |
| Default | – |
| Description | Replaces the native element or composes the description with another component. |
DrawerFooter
DrawerFooter stacks the actions at the end of the drawer. It renders a div and has no props of its own.
DrawerClose
| Prop | render |
|---|---|
| Type | ReactElement | render function |
| Default | – |
| Description | Replaces the native element or composes the close button with another component. |
| Prop | nativeButton |
|---|---|
| Type | boolean |
| Default | true |
| Description | Declares whether the rendered element is a native button. Set it to false when render returns a different element. |
| Prop | disabled |
|---|---|
| Type | boolean |
| Default | false |
| Description | Prevents users from closing the drawer with this button. |