Skip to content

Foundations

Gestures

The three actions every touch surface here is built from: ripple, press and swipe.

ripple press swipe haptic
import { ripple, press, swipe, haptic } from '@anomalia/ui';

Notes

  • Ripple queues its fade until the grow animation lands, so a 40ms tap still plays the full gesture.
  • Press and swipe both cancel on pointercancel — the event the browser fires when it claims the gesture for scrolling.
  • Haptics are a no-op where the Vibration API is missing (notably iOS Safari) and under reduced motion.

Examples

Ripple press

The two actions every interactive surface here is built from. Press and hold: the ink stays at full opacity and only fades once the grow animation has landed.

ripple + press

centered, tinted

Haptics are a no-op where the Vibration API is missing (notably iOS Safari) and under reduced motion, so callers never need to feature-detect.

Swipe

`use:swipe` decides direction in the first few pixels: move mostly across the tracked axis and it hands the gesture back to the browser, so page scrolling never fights it.

Swipe me sideways

delta 0px · velocity 0.00 px/ms

API

use:ripple

PropTypeDefaultDescription
disabledbooleanSkip the effect.
centeredbooleanfalseAlways start from the centre.
unboundedbooleanfalseLet the ink grow past the host.
color / opacitystring / numberInk appearance.

use:swipe

PropTypeDefaultDescription
axis'x' | 'y''y'Tracked axis.
thresholdnumber6px before the gesture is claimed.
onstart / onmove / onend(state) => void`{ delta, velocity, event }`.

Every component also forwards the native attributes of its root element, plus class, so anything not listed here still works.