Skip to Content
MavKitOne is in beta. @mav-labs-inc/mavkit-react is not public packages yet.
ComponentsBottom Sheet

Bottom Sheet

A native <dialog>-backed panel anchored to the bottom edge, draggable via its grabber, with optional Apple Maps-style snap points. Compose BottomSheetHeader / BottomSheetBody / BottomSheetFooter as children, the same lookup-by-class approach Modal uses.

Usage

import { BottomSheet, BottomSheetHeader, BottomSheetBody } from '@mav-labs-inc/mavkit-react' // Single, content-sized sheet <BottomSheet open={isOpen} onClose={() => setIsOpen(false)}> <BottomSheetHeader>Share</BottomSheetHeader> <BottomSheetBody><p>…</p></BottomSheetBody> </BottomSheet> // Starts content-sized, expandable via drag/tap/Enter <BottomSheet open={isOpen} onClose={() => setIsOpen(false)} snapPoints={['auto', 0.92]}> … </BottomSheet> // Apple Maps-style detents <BottomSheet open={isOpen} onClose={() => setIsOpen(false)} snapPoints={[0.3, 0.6, 0.92]} snapIndex={snapIndex} onSnapIndexChange={setSnapIndex} > … </BottomSheet>

Examples

Basic

Share

Drag the grabber, tap it, or press Enter to expand — or drag down to dismiss.

Snap points

Nearby places

Drag between three detents (30%, 60%, 92% of viewport height).

Props

BottomSheet

PropTypeDefaultDescription
open*boolean—Controlled open state. The sheet animates closed when this flips to false.
onClose() => void—Called on backdrop click, ESC, grabber, or drag-to-dismiss. Set open to false here to actually close.
snapPoints(number | 'auto')[][]Ascending detents — a fraction of viewport height (0, 1] or 'auto' for content's natural height. Omit for a single, content-sized sheet only draggable to dismiss.
snapIndexnumber—Controlled index into snapPoints. Ignored when snapPoints has fewer than 2 entries.
defaultSnapIndexnumberthe middle detentUncontrolled initial index into snapPoints.
onSnapIndexChange(index: number) => void—
snapLabel(index: number, count: number) => string—aria-valuetext for the resize handle at a given index (multi-snap only). Defaults to "Position n of total".
dismissiblebooleantrueWhether backdrop click / Escape / drag-past-threshold / grabber Enter can dismiss the sheet.
barebooleanfalseNo backdrop, no body scroll lock, page stays interactive behind it. Uses dialog.show() so native ESC-to-close doesn't fire.
ariaLabelstring—aria-label for the dialog when no BottomSheetHeader title is rendered.
classNamestring—
childrenReactNode—

BottomSheetHeader

PropTypeDefaultDescription
closeLabelstring'Close'aria-label for the generated .bottom-sheet-close (×) button.
hideClosebooleanfalse
childrenReactNode—Rendered as the .bottom-sheet-title.

BottomSheetBody / BottomSheetFooter

Thin wrappers rendering a <div> with .bottom-sheet-body / .bottom-sheet-footer — accept every native <div> attribute, no extra props of their own.

Last updated on