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).


Live Demo: Snap Points

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>