Version v3.0.0 Size 1.6 KB gzip Dependencies Zero dependencies
Why Gesture?
Pointer-driven interfaces need reliable one-pointer movement tracking without coupling recognition to rendering, drag-and-drop semantics, or product-specific completion policy.
ts
// Before
element.addEventListener('pointermove', (event) => {
// Coordinate tracking, pointer identity, direction locking, and cleanup
});
// After
import { createPanGesture } from '@vielzeug/gesture';
const pan = createPanGesture(element, {
axis: 'x',
onMove: ({ distance }) => console.log('distance', distance),
onEnd: ({ reason }) => console.log('ended', reason),
});| Feature | Gesture | Ad-hoc pointer handling |
|---|---|---|
| Bundle size | 1.6 KB | n/a |
| Zero dependencies | n/a | |
| Two-dimensional drag tracking | Built in | Manual |
| Axis intent recognition | Built in | Manual |
| Pointer ownership | Tracked across the document | Manual |
| Lifecycle cleanup | dispose() + disposalSignal | Manual |
Use Gesture when UI surfaces need consistent free drag or axis-locked pan tracking while retaining their own rendering and 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 element = document.querySelector<HTMLElement>('[data-swipe]');
if (!element) throw new Error('Missing [data-swipe] element');
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) {
pan.dispose();
element.remove();
}
},
});
window.addEventListener('pagehide', () => pan.dispose(), { once: true });Features
createDragGesture()— unrestricted two-dimensional pointer movement trackingcreatePanGesture()— one-axis pointer movement with direction intent recognition- Direction locking — activates only when movement favors the configured axis
- Configurable pointer capture — own the pointer by default or preserve native targeting
- Configurable
activationDistance— tune slop for touch density and component needs - Consumer-owned policy — completion thresholds, snapping, and outcomes stay in application code
- Stable completion — one
onEndcallback for release and cancellation - Lifecycle ownership —
dispose(),disposed,disposalSignal, optional ownersignal, and[Symbol.dispose]()
Documentation
See Also
- Refine — components that use pan recognition for carousel, drawer, toast, and list interactions.
- Dnd — builds touch sorting on
createDragGesture()and adds files, previews, drop targets, keyboard reordering, and connected-list transactions. - Keymap — keyboard interaction primitives for complementary input paths.