A draggable, snap-point bottom sheet built on Radix Dialog for accessibility, with Motion driving the drag gesture and glide.
Made by AxylInstallation
File Structure
Usage
For a fully custom row (not the label — value layout), pass children to BottomSheetRow instead of label/value, or skip BottomSheetPanel/BottomSheetList/BottomSheetRow entirely and render your own content inside BottomSheetContent.
Props
BottomSheet
| Prop | Type | Default |
|---|---|---|
open? | boolean | - |
defaultOpen? | boolean | false |
onOpenChange? | (open: boolean) => void | - |
BottomSheetContent
| Prop | Type | Default |
|---|---|---|
snapPoints? | (number | "auto")[] | [0.5, 0.92] |
defaultSnap? | number | 0 |
dismissThreshold? | number | 120 |
showHandle? | boolean | true |
handleClassName? | string | - |
overlay? | boolean | true |
overlayClassName? | string | - |
BottomSheetRow
| Prop | Type | Default |
|---|---|---|
label? | React.ReactNode | - |
value? | React.ReactNode | - |
children? | React.ReactNode | - |
labelClassName? | string | - |
valueClassName? | string | - |
lineClassName? | string | - |
When to Use
Use the Bottom Sheet for mobile-first actions that need more room than a dropdown but shouldn't take over the whole screen — settings panels, filters, or action lists reachable with a thumb. snapPoints lets it act as a half-height quick-glance panel that expands to near-fullscreen on a second drag.
Avoid it for content that must stay reachable on desktop without a pointer-drag affordance, or for anything that must block navigation entirely — use a centered dialog instead.
Accessibility
Built on Radix Dialog, so focus is trapped inside the sheet while open, Esc and an outside click close it, and focus returns to the trigger on close. Radix requires both BottomSheetTitle and BottomSheetDescription on every sheet — both default to sr-only, so include them even when the sheet doesn't need a visible heading (Radix logs a console warning if BottomSheetDescription is missing). When prefers-reduced-motion: reduce is set, the sheet fades in/out instead of sliding.
Credits
Inspired by Vaul.
Built by Axyl. A motion-first component registry for React.
Last updated: 7/4/2026