Sora UI

Bottom Sheet

A draggable, snap-point bottom sheet built on Radix Dialog for accessibility, with Motion driving the drag gesture and glide.

Made by Axyl

A mobile-style settings panel: drag to dismiss, snap points, and a customizable row list.

Installation

File Structure

bottom-sheet.tsx
use-controlled-state.tsx
use-prefers-reduced-motion.tsx
get-strict-context.tsx
ease.tsx

Usage

import {
  BottomSheet,
  BottomSheetContent,
  BottomSheetDescription,
  BottomSheetList,
  BottomSheetPanel,
  BottomSheetRow,
  BottomSheetTitle,
  BottomSheetTrigger,
} from "@/components/sora-ui/radix/bottom-sheet";

export default function Page() {
  return (
    <BottomSheet>
      <BottomSheetTrigger>Open settings</BottomSheetTrigger>
      <BottomSheetContent>
        <BottomSheetTitle>Settings</BottomSheetTitle>
        <BottomSheetDescription>Adjust sound and theme.</BottomSheetDescription>
        <BottomSheetPanel>
          <BottomSheetList>
            <BottomSheetRow label="Sound" value="On" />
            <BottomSheetRow label="Theme" value="Dark" />
          </BottomSheetList>
        </BottomSheetPanel>
      </BottomSheetContent>
    </BottomSheet>
  );
}

Props

BottomSheet

PropTypeDefault
open?
boolean
-
defaultOpen?
boolean
false
onOpenChange?
(open: boolean) => void
-

BottomSheetContent

PropTypeDefault
snapPoints?
(number | "auto")[]
[0.5, 0.92]
defaultSnap?
number
0
dismissThreshold?
number
120
showHandle?
boolean
true
handleClassName?
string
-
overlay?
boolean
true
overlayClassName?
string
-

BottomSheetRow

PropTypeDefault
label?
React.ReactNode
-
value?
React.ReactNode
-
children?
React.ReactNode
-
labelClassName?
string
-
valueClassName?
string
-
lineClassName?
string
-

Credits

Inspired by Vaul.

Built by Axyl. A motion-first component registry for React.

Last updated: 8/20/2026