Follows drags, resists past its largest detent and settles with your release speed; a flick moves one detent or closes it.
Touch drags hand over to scrollable content: pulling down scrolls the content back to its top before the sheet moves.
Detents as fractions of the screen, pixels, or 'content' for the content's natural size.
A modal sheet keeps focus inside, makes the page inert and closes with Escape or the backdrop.
Use it for
A filter panel.
A share menu.
A navigation drawer with side="start".
Props
Prop
Type
Default
Description
open
boolean
false
Whether the sheet is shown.
onOpenChange
(open) => void
Runs with false when the sheet is dragged, tapped or escaped closed.
detents
(number | 'content')[]
['content']
Resting sizes: a fraction of the screen, pixels, or 'content'.
detent
number
Controlled detent index.
defaultDetent
number
0
Detent index used when opening without detent.
onDetentChange
(index) => void
Runs with the index of the detent the sheet settles on.
side
'bottom' | 'top' | 'start' | 'end'
'bottom'
The edge the sheet comes from.
modal
boolean
true
Adds a backdrop, keeps focus inside and makes the page inert.
dismissible
boolean
true
Dragging past the smallest detent, the backdrop and Escape close it.
backdropClassName
string
Class for the backdrop; backdropStyle sets its inline style.
transition
Transition
spring
A timing curve { duration, easing } or a spring { tempo: 'spring', spring }. Springs keep their momentum when interrupted.
Other props go to the rendered element, so className, style and event handlers work as usual.
Web and React Native
On the web a modal sheet is a native dialog; the panel is a flex column that you style with className.
On React Native it renders in a transparent Modal and the back button closes it. Inner ScrollViews keep their own gestures, so the sheet is dragged from its handle, header and other static areas.