Skip to content
gesture logoGestureInput
Framework-neutral two-dimensional pointer drag and one-axis pan recognition with lifecycle-owned handles.
Version
v3.0.0
Size
1.6 KB gzip
Dependencies
Zero dependencies
Browser
createDragGesturecreatePanGesture

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),
});
FeatureGestureAd-hoc pointer handling
Bundle size1.6 KBn/a
Zero dependenciesn/a
Two-dimensional drag trackingBuilt inManual
Axis intent recognitionBuilt inManual
Pointer ownershipTracked across the documentManual
Lifecycle cleanupdispose() + disposalSignalManual

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/gesture
sh
npm install @vielzeug/gesture
sh
yarn add @vielzeug/gesture

Quick 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 tracking
  • createPanGesture() — 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 onEnd callback for release and cancellation
  • Lifecycle ownership — dispose(), disposed, disposalSignal, optional owner signal, 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.