Bottom Sheet

Opens a panel from the bottom of the page.

@paneui/theme@base-ui/reactmotion

Installation

pnpm dlx shadcn@latest add @paneui/bottom-sheet

Usage

Composition

Examples

Single Snap

Use one snap point for short content; the handle then only drags to close.

Controlled Snap

Non-dismissible

Without Handle

Hide the handle when the sheet shouldn't be resized by dragging.

Motion

A flick moves a whole snap. With reduced motion the sheet fades in and out and jumps between snaps.

Keyboard

The handle is a button, so Enter or Space cycles to the next snap point (or collapses from the top one). Esc closes when dismissible.

API Reference

Built on the Dialog primitive. Only the props this library adds or changes are listed; everything else passes through.

BottomSheet

Root. Holds the open state and the snap index. Also accepts every prop of Dialog.Root.

snapPoints= [0.5, 0.92]
number[]
Visible heights as fractions of the viewport, smallest first.
defaultSnap= 0
number
Index into snapPoints each open starts at.
snap
number
Controlled snap index.
onSnapChange
(index: number) => void
Called when the sheet settles on a new snap.
dismissible= true
boolean
Allow drag-down, Esc and backdrop press to close.
open
boolean
Controlled open state.
defaultOpen= false
boolean
Open on first render.
onOpenChange
(open: boolean, details: Dialog.Root.ChangeEventDetails) => void
Called when the sheet opens or closes, with the dialog's event details (reason, event, cancel()), like Drawer. A drag-down dismissal reports reason: "imperative-action".
PropTypeDefaultDescription
snapPointsnumber[][0.5, 0.92]Visible heights as fractions of the viewport, smallest first.
defaultSnapnumber0Index into snapPoints each open starts at.
snapnumber—Controlled snap index.
onSnapChange(index: number) => void—Called when the sheet settles on a new snap.
dismissiblebooleantrueAllow drag-down, Esc and backdrop press to close.
openboolean—Controlled open state.
defaultOpenbooleanfalseOpen on first render.
onOpenChange(open: boolean, details: Dialog.Root.ChangeEventDetails) => void—Called when the sheet opens or closes, with the dialog's event details (reason, event, cancel()), like Drawer. A drag-down dismissal reports reason: "imperative-action".

BottomSheetTrigger

Also accepts every prop of Dialog.Trigger.

BottomSheetContent

The sheet (up to 576px wide) with its backdrop and portal. Always as tall as the highest snap. Also accepts every prop of Dialog.Popup.

showHandle= true
boolean
Render the grip at the top.
PropTypeDefaultDescription
showHandlebooleantrueRender the grip at the top.

BottomSheetHandle

The grip. Drag it to resize or dismiss, press it to cycle snap points. Rendered by BottomSheetContent. Also accepts every prop of button.

BottomSheetHeader

Doubles as a drag zone, ignoring presses on buttons, links and fields inside it. Also accepts every prop of div.

BottomSheetBody

The scrolling area (overscroll-contain). Also accepts every prop of div.

BottomSheetFooter

Bottom action row with a top border and safe-area padding. Also accepts every prop of div.

BottomSheetTitle

Also accepts every prop of Dialog.Title.

BottomSheetDescription

Also accepts every prop of Dialog.Description.

BottomSheetClose

Also accepts every prop of Dialog.Close.