Skip to content

Components

A React Bottom Sheet With Real Snap Points — Mobile Data Entry Without the Modal Jail

Peek, Half and Full — Three Snap Points, Drag Physics, Zero Dependencies
Written by Aiden Wood Founder and Lead Design Engineer
📱 🧲 👆

Full-screen modals are where mobile data entry goes to die. The user loses the page behind them, the context they were acting on, and — on a bad day — their half-typed form when the backdrop eats a stray tap.

The pattern that actually works on mobile is the bottom sheet with snap points: a peek state that doesn't cover the content, a half state for quick entry, and a full state when the job gets serious. Velocity X's standard-bottom-sheet-snap-points ships exactly that, as one React file installed into your codebase.

The Setup

velocityx add standard-bottom-sheet-snap-points

(The velocityx CLI is in preview — not on npm yet; the free tier's source is public on GitHub meanwhile.) No portal library, no gesture dependency, no 40KB of spring physics. Pointer events and a CSS transform do the dragging; the sheet is positioned with plain fixed positioning and translated to whichever snap point is active.

The Money Pattern

Snapping is the whole trick, and it's a release-velocity decision, not a position one. On pointer-up you don't ask "which snap point is closest" — you ask "which snap point is closest in the direction they flicked":

const onRelease = (y: number, velocity: number) => {
  const points = [PEEK, HALF, FULL].map(toPixels);
  const biased = y + velocity * 120; // project the flick forward
  const target = points.reduce((a, b) =>
    Math.abs(b - biased) < Math.abs(a - biased) ? b : a
  );
  setSnap(target);
};

That one projection term is the difference between a sheet that feels native and one that feels like a div with a transition. Flick down from full and you land at half, not peek — the same behaviour Apple Maps trained everyone to expect.

The Catch

Scroll containment is on you. A scrollable list inside the sheet needs the drag handler to yield when the list isn't at its top, or dragging the list drags the sheet. The component handles the handle-drag case out of the box; wire the content-drag case to your own scroll container if you add one.

And this is an application-surface component — it assumes it owns the viewport bottom and the keyboard-safe area. For a desktop equivalent, pair it with a right-docked drawer rather than stretching a sheet across a 27-inch monitor.

The Verdict

Three snap points cover roughly every mobile data-entry flow we've shipped — and the whole component is short enough to read with your coffee. It's part of the Velocity X library: 400+ Astro and React components installed as source you own, versioned so you can hot-swap or pin any release.

Let us make some quick suggestions?

Please provide your full name.
Please provide your phone number.
Please provide a valid phone number.
Please provide your email address.
Please provide a valid email address.
Please provide your brand name or website.
Please provide your brand name or website.