Skip to main content

Snap Points

Snap points allow a drawer to stop at predetermined height thresholds on screen (e.g. 20% visible height, 50% height, or 90% height).


Defining Snap Points

Pass an array of values to snapPoints:

  • Percentage values: numbers between 0 and 1 (or strings like '200px', '50%').
  • Values should be listed from least visible to most visible.
export function SnappedDrawer() {
const snapPoints = [0.25, 0.5, 0.9];
const [activeSnapPoint, setActiveSnapPoint] = React.useState<number | string | null>(snapPoints[0]);

return (
<Drawer.Root
snapPoints={snapPoints}
activeSnapPoint={activeSnapPoint}
setActiveSnapPoint={setActiveSnapPoint}
>
<Drawer.Trigger className="btn">Open Snap Drawer</Drawer.Trigger>
<Drawer.Portal>
<Drawer.Overlay className="fixed inset-0 bg-black/40" />
<Drawer.Content className="fixed bottom-0 left-0 right-0 bg-white p-6 rounded-t-2xl flex flex-col">
<Drawer.Handle />
<Drawer.Title>Active Point: {activeSnapPoint}</Drawer.Title>
<div className="flex gap-2 my-4">
<button onClick={() => setActiveSnapPoint(0.25)}>25%</button>
<button onClick={() => setActiveSnapPoint(0.5)}>50%</button>
<button onClick={() => setActiveSnapPoint(0.9)}>90%</button>
</div>
</Drawer.Content>
</Drawer.Portal>
</Drawer.Root>
);
}

Fade Overlay Control (fadeFromIndex)

By default, the overlay background fades out when swiping past the first snap point. Use fadeFromIndex to specify which snap point index initiates the overlay fade out:

<Drawer.Root
snapPoints={[0.3, 0.6, 1]}
fadeFromIndex={1} // Overlay fades out when dragged below index 1 (0.6 height)
>
{/* Drawer content */}
</Drawer.Root>

Sequential Snap Point Traversal (snapToSequentialPoint)

When snapToSequentialPoint is true, high-velocity flings won't skip intermediate snap points. Each swipe moves to the next adjacent point sequentially:

<Drawer.Root
snapPoints={[0.2, 0.5, 0.8]}
snapToSequentialPoint={true}
>
{/* Drawer content */}
</Drawer.Root>