Version v1.0.0 Size 1.0 KB gzip Dependencies Zero dependencies
Why Gesture?
Pointer-driven interfaces need reliable movement tracking without coupling input recognition to rendering or product-specific thresholds.
ts
// Before
element.addEventListener('pointermove', (event) => {
// Coordinate tracking, pointer identity, direction locking, and cleanup
});
// After
const pan = createPanGesture(element, {
axis: 'x',
onMove: ({ distance }) => render(distance),
onEnd: ({ distance, reason }) => finish(distance, reason),
});| Feature | Ad-hoc pointer handling | Gesture |
|---|---|---|
| Bundle size | n/a | 1.0 KB |
| Zero dependencies | n/a | |
| Axis intent recognition | Manual | Built in |
| Pointer ownership | Manual | Tracked across the document |
| Lifecycle cleanup | Manual | dispose() + disposalSignal |
Use Gesture when several UI surfaces need consistent one-axis pointer tracking while retaining their own completion rules.
Consider direct pointer handling when the interaction is isolated and does not need reusable lifecycle or direction-lock behavior.
Installation
sh
pnpm add @vielzeug/gesturesh
npm install @vielzeug/gesturesh
yarn add @vielzeug/gestureQuick Start
ts
import { createPanGesture } from '@vielzeug/gesture';
const pan = createPanGesture(element, {
axis: 'x',
onMove: ({ distance }) => {
element.style.transform = `translateX(${distance}px)`;
},
onEnd: ({ distance, reason }) => {
element.style.transform = '';
if (reason === 'release' && Math.abs(distance) >= 48) {
dismiss();
}
},
});Features
createPanGesture()— one-axis pointer movement tracking- Direction locking — activates only when movement favors the configured axis
- Configurable pointer capture — own the pointer by default or preserve native targeting
- Consumer-owned policy — thresholds, snapping, and outcomes stay in application code
- Stable completion — one
onEndcallback for release and cancellation - Lifecycle ownership —
dispose(),disposed, anddisposalSignal