usePanGesture@astryxdesign/core v0.7.5 · usePanGesture

Usage

Reports a drag on an element as values, for a surface the product moves itself: a card that follows the finger, a drawer pulled by its handle. The drag claims its touch at UIKit’s 10 pt, as UIPanGestureRecognizer does, so a tap or a scroll that starts on the element stays a tap or a scroll, and a press or a long press is never reported as a pan. The hook is a thin layer over createPanGesture, the same API for code without React. A drag has no keyboard or assistive-technology path of its own: whatever the drag does needs another way to do it, such as buttons or arrow keys (WCAG 2.5.7), and useDragToSnapPoints provides settleTo for that. The pan moves nothing itself, so Reduce Motion applies to the motion you drive from it: animate with useAnimator, which plans every animation for Reduce Motion. Where a component already offers the behavior, use its prop instead: BottomSheet’s snapPoints, Carousel’s hasSnap.

ts
import {usePanGesture} from '@astryxdesign/core/hooks'

Best practices

GuidancePractices
Do

Move the element from translation added to where it was when the drag began, so it moves with the finger from the moment the drag claims it.

Do

At ended, hand velocity to the animation that settles the element (useAnimator’s animate or decay), so a flick carries on at the speed it was released.

Do

Give every drag another way to do the same thing from a keyboard and from assistive technology, such as buttons, arrow keys or a menu.

Do

Use a component's own prop when it covers the job: BottomSheet's snapPoints for a sheet, Carousel's hasSnap for paging.

Don't

Set a new React state on every changed event; write the element’s style in onPan instead, so a drag costs no render.

Don't

Recognize taps or long presses with it; useLongPress and the components’ own press handling own those.

Parameters

ParamTypeDescription
refrequired
RefObject<Element | null>

The element to drag. The hook creates one pan for the element behind the ref, creates a new one when the ref moves to another node, and destroys it at unmount.

optionsrequired

Configuration object.

options.axis
'x' | 'y'

Limits the drag to one axis. A drag along the other axis is not reported, and that component of every value reads 0. Omit it to report both axes.

options.onPanrequired
(event:
) => void

Called with {state, translation, velocity} as the drag begins, changes, ends at the release, or is cancelled. state is 'began', 'changed', 'ended' or 'cancelled'. translation is the movement since the drag began, in pixels: the travel the drag needed to begin is not part of it, so an element that follows it does not jump. velocity is in pixels per second; at 'ended' it is the release velocity (0 when the finger rested before lifting), and at 'cancelled' it is 0. Read through a ref: a new function each render re-creates nothing.

Returns

FieldTypeDescription
voidvoid

Nothing: the hook hands out no recognizer. Without React, createPanGesture(element, options) takes the same options and returns {destroy}, which removes every listener it added and cancels a drag in progress.

Use with shadcn

Already using the shadcn registry workflow? Install the real Astryx package and a local public re-export. Component implementation source stays in Astryx.

This install URL expires with the draft preview.
bash
npx shadcn@4.19.0 add https://astryx-pujkjvd84-fbopensource.vercel.app/shadcn/hooks/use-pan-gesture.json