Lynx/Modules/Gestures/API reference
@sigx/lynx-gestures · Stable · Component library

API reference#

Every export of @sigx/lynx-gestures. Components and the Swiper dot hooks run on the main thread; usePinch / useRotation are background-thread fallbacks.

All exports work on both iOS and Android unless noted. The package is named-exports only — there is no default export.

Components#

Each component has its own page with usage, props, slots and events — see the Components catalog:

  • Pressable — a tap and long-press recognizer with built-in pressed-state visual feedback (opacity and scale).
  • Draggable — a draggable container built on Gesture.Pan() with axis lock, bounds clamping, snap-back, and ScrollView coordination.
  • Swipeable — a horizontal swipe-to-reveal container that snaps to closed / open-left / open-right on release.
  • ScrollView — a scroll-view wrapper that mirrors scroll position into SharedValues and coordinates descendant gestures.
  • Swiper — a paged horizontal carousel built on a native paging scroll-view, with a controlled index and live offset.

Their prop types and related APIs remain documented below.

Hooks — Swiper indicators#

These headless hooks each return a MainThreadRef<MainThread.Element | null> to spread onto a dot element. They drive one transform channel from the Swiper's live offset. All share the SwiperDotHookInputs (offset, pageWidth, index). Platform: both.

useSwiperDotProgress#

Drives the opacity channel — a triangular crossfade (default outputRange [0, 1, 0]).

TypeScript
export function useSwiperDotProgress(
  opts: UseSwiperDotProgressOptions,
): MainThreadRef<MainThread.Element | null>;

useSwiperDotScale#

Drives uniform scale (both axes); the active dot scales up. Defaults: inactive 1, active 1.4.

TypeScript
export function useSwiperDotScale(opts: SwiperDotHookInputs & {
  inactive?: number;
  active?: number;
  window?: number;
}): MainThreadRef<MainThread.Element | null>;

useSwiperDotGrowX#

Drives the scaleX transform channel (pill stretch, no layout pass); the active dot widens. Defaults: inactive 1, active 3.

TypeScript
export function useSwiperDotGrowX(opts: SwiperDotHookInputs & {
  inactive?: number;
  active?: number;
  window?: number;
}): MainThreadRef<MainThread.Element | null>;

useSwiperDotWidth#

Animates the layout width style in CSS pixels (reflows siblings; slower than useSwiperDotGrowX). Defaults: inactive 8px, active 24px.

TypeScript
export function useSwiperDotWidth(opts: SwiperDotHookInputs & {
  inactive?: number;
  active?: number;
  window?: number;
}): MainThreadRef<MainThread.Element | null>;

useSwiperDotTranslate#

Translates a single thumb across the track (translateX), proportional to scroll progress — for the "bar" indicator variant.

TypeScript
export function useSwiperDotTranslate(
  opts: UseSwiperDotTranslateOptions,
): MainThreadRef<MainThread.Element | null>;

Hooks — multi-touch#

usePinch#

A two-finger pinch/zoom gesture. JS-only background-thread fallback that parses bindtouch* events (proximity-based finger matching, since Lynx touch identifiers are unstable across events). Returns a reactive PinchState signal, a handler bag, and reset().

TypeScript
export function usePinch(options?: UsePinchOptions): UsePinchReturn;

Spread handlers onto the element's bindtouch* attributes. Platform: both, but requires multi-touch to the same element — may not work on Lynx Explorer / emulators; test on a device.

useRotation#

A two-finger rotation gesture. JS-only background-thread fallback parsing bindtouch* events. Returns a reactive RotationState signal (cumulative signed radians plus angular velocity), a handler bag, and reset().

TypeScript
export function useRotation(options?: UseRotationOptions): UseRotationReturn;

Same device caveat as usePinch. Platform: both.

useScrollContext#

Injectable accessor for the ScrollContext provided by ScrollView; returns null when no parent ScrollView is in scope. Public so custom gesture components can opt into the same auto-yield coordination as Draggable / Swipeable.

TypeScript
export const useScrollContext: () => ScrollContext | null;

Branch on null when there is no parent ScrollView. Platform: both.

Re-exports from @sigx/lynx#

These are re-exported for convenience and back-compat. Prefer importing them from @sigx/lynx directly.

useSharedValue#

Allocates a thread-aware value — writeable on the main thread, reactively observable on the background thread.

TypeScript
export { useSharedValue } from '@sigx/lynx';

useAnimatedStyle#

Binds an element's style to a SharedValue via a named mapper (translateX / translateY, scale, opacity, …); the mapper runs on the main thread every flush the value changes.

TypeScript
export { useAnimatedStyle } from '@sigx/lynx';
// useAnimatedStyle(elRef, sharedValue, mapperName, params?)

useAnimatedValue#

Alias for useSharedValue, kept for back-compat. Deprecated.

TypeScript
export { useAnimatedValue } from '@sigx/lynx';

resetAnimatedStyleBindingIds#

Resets the internal useAnimatedStyle binding-id counter. Test / SSR helper.

TypeScript
export { resetAnimatedStyleBindingIds } from '@sigx/lynx';

SharedValue#

Cross-thread value primitive (extends MainThreadRef). Deprecated since 0.3.0 — import from @sigx/lynx directly.

TypeScript
export { SharedValue } from '@sigx/lynx';

AnimatedValue#

Alias for SharedValue. Deprecated.

TypeScript
export { AnimatedValue } from '@sigx/lynx';

SharedValueState / AnimatedValueState#

Re-exported types. AnimatedValueState is deprecated — use SharedValueState.

TypeScript
export type { SharedValueState } from '@sigx/lynx';
export type { AnimatedValueState } from '@sigx/lynx';

BuiltinMapperName#

Union of built-in useAnimatedStyle mapper names.

TypeScript
export type { BuiltinMapperName } from '@sigx/lynx';

MapperParams#

Per-channel parameter shapes for useAnimatedStyle mappers — linear { factor, offset } or range { inputRange, outputRange, extrapolate }.

TypeScript
export type { MapperParams } from '@sigx/lynx';

Types — component props#

PressableProps#

TypeScript
export type PressableProps =
  & Define.Prop<'pressedOpacity', number, false>
  & Define.Prop<'pressedScale', number, false>
  & Define.Prop<'longPressDuration', number, false>
  & Define.Prop<'maxDistance', number, false>
  & Define.Prop<'disabled', boolean, false>
  & Define.Prop<'class', string, false>
  & Define.Prop<'style', Record<string, string | number>, false>
  & Define.Prop<'accessibility-element', boolean, false>
  & Define.Prop<'accessibility-label', string, false>
  & Define.Prop<'accessibility-role', string, false>
  & Define.Prop<'accessibility-trait', string, false>
  & Define.Prop<'accessibility-status', string, false>
  & Define.Slot<'default'>
  & Define.Event<'press', void>
  & Define.Event<'longPress', void>;

DraggableProps#

TypeScript
export type DraggableProps =
  & Define.Prop<'axis', 'x' | 'y' | 'both', false>
  & Define.Prop<'threshold', number, false>
  & Define.Prop<'snapBack', boolean, false>
  & Define.Prop<'minX', number, false>
  & Define.Prop<'maxX', number, false>
  & Define.Prop<'minY', number, false>
  & Define.Prop<'maxY', number, false>
  & Define.Prop<'translateX', SharedValue<number>, false>
  & Define.Prop<'translateY', SharedValue<number>, false>
  & Define.Prop<'edgeScroll', EdgeScrollConfig, false>
  & Define.Prop<'class', string, false>
  & Define.Prop<'style', Record<string, string | number>, false>
  & Define.Slot<'default'>
  & Define.Event<'dragStart', { x: number; y: number }>
  & Define.Event<'dragEnd', DragEndDetail>;

translateX / translateY are optional external SharedValues the worklet writes each frame. edgeScroll auto-scrolls a parent ScrollView near its edge.

SwipeableProps#

TypeScript
export type SwipeableProps =
  & Define.Prop<'leftActionsWidth', number, false>
  & Define.Prop<'rightActionsWidth', number, false>
  & Define.Prop<'snapThreshold', number, false>
  & Define.Prop<'snapDuration', number, false>
  & Define.Prop<'leftActions', () => unknown, false>
  & Define.Prop<'rightActions', () => unknown, false>
  & Define.Prop<'class', string, false>
  & Define.Prop<'style', Record<string, string | number>, false>
  & Define.Prop<'foregroundStyle', Record<string, string | number>, false>
  & Define.Slot<'default'>
  & Define.Event<'swipeOpen', { side: SwipeSide }>
  & Define.Event<'swipeClose', void>;

ScrollViewProps#

TypeScript
export type ScrollViewProps =
  & Define.Prop<'offsetX', SharedValue<number>, false>
  & Define.Prop<'offsetY', SharedValue<number>, false>
  & Define.Prop<'scroll-orientation', 'vertical' | 'horizontal', false>
  & Define.Prop<'enable-scroll', boolean, false>
  & Define.Prop<'class', string, false>
  & Define.Prop<'style', Record<string, string | number>, false>
  & Define.Slot<'default'>;

SwiperProps#

TypeScript
export type SwiperProps<T = unknown> =
  & Define.Prop<'items', readonly T[], true>
  & Define.Prop<'renderItem', (item: T, index: number) => unknown, true>
  & Define.Prop<'keyExtractor', (item: T, index: number) => string | number, false>
  & Define.Prop<'width', number, false>
  & Define.Prop<'height', number | string, false>
  & Define.Prop<'index', PrimitiveSignal<number>, false>
  & Define.Prop<'initialIndex', number, false>
  & Define.Prop<'offset', SharedValue<number>, false>
  & Define.Prop<'class', string, false>
  & Define.Prop<'style', Record<string, string | number>, false>
  & Define.Event<'pageChange', { index: number }>;

items and renderItem are required. index is a controlled PrimitiveSignal; offset is the live main-thread pixel offset.

Types — payloads and config#

DragEndDetail#

Payload of the Draggable dragEnd event: terminal position and terminal velocity (page px per ms).

TypeScript
export interface DragEndDetail {
  x: number;
  y: number;
  vx: number;
  vy: number;
}

EdgeScrollConfig#

Edge-scroll config for Draggable's edgeScroll prop. Defaults: threshold 50pt, maxSpeed 800pt/sec. Note: this type is not re-exported from the package entry — it is reachable only structurally through the edgeScroll prop, not as a named import.

TypeScript
export type EdgeScrollConfig = boolean | {
  /** Distance from viewport edge in pt where auto-scroll engages. Default 50. */
  threshold?: number;
  /** Maximum scroll velocity in pt/sec at the edge. Default 800. */
  maxSpeed?: number;
};

SwipeSide#

Which side a Swipeable opened toward; the payload field of the swipeOpen event.

TypeScript
export type SwipeSide = 'left' | 'right';

GesturePhase#

Lifecycle phase reported in PinchState / RotationState.

TypeScript
export type GesturePhase = 'idle' | 'began' | 'active' | 'ended' | 'cancelled';

Types — touch and multi-touch state#

TouchPoint#

A single touch point (Lynx-shaped); used by usePinch / useRotation touch parsing.

TypeScript
export interface TouchPoint {
  identifier: number;
  x: number;
  y: number;
  pageX: number;
  pageY: number;
  clientX: number;
  clientY: number;
}

TouchEvent#

Touch event shape consumed by the GestureHandlers bind* callbacks.

TypeScript
export interface TouchEvent {
  touches: TouchPoint[];
  changedTouches: TouchPoint[];
}

GestureHandlers#

The handler bag returned by usePinch / useRotation; spread onto an element's bindtouch* attributes.

TypeScript
export interface GestureHandlers {
  bindtouchstart?: (e: TouchEvent) => void;
  bindtouchmove?: (e: TouchEvent) => void;
  bindtouchend?: (e: TouchEvent) => void;
  bindtouchcancel?: (e: TouchEvent) => void;
}

PinchState#

Reactive state of usePinch: phase, scale (relative to gesture start, 1 = unchanged), and focal point.

TypeScript
export interface PinchState {
  phase: GesturePhase;
  scale: number;
  focalX: number;
  focalY: number;
}

UsePinchOptions#

TypeScript
export interface UsePinchOptions {
  onPinch?: (state: PinchState) => void;
}

The onPinch callback fires on the active / ended / cancelled phases.

UsePinchReturn#

TypeScript
export interface UsePinchReturn {
  state: Signal<PinchState>;
  handlers: GestureHandlers;
  reset: () => void;
}

RotationState#

Reactive state of useRotation: phase, cumulative signed rotation (radians), angular velocity (radians/ms), and focal point.

TypeScript
export interface RotationState {
  phase: GesturePhase;
  /** Cumulative rotation in radians since gesture start (signed). */
  rotation: number;
  /** Angular velocity in radians/ms. */
  velocity: number;
  focalX: number;
  focalY: number;
}

UseRotationOptions#

TypeScript
export interface UseRotationOptions {
  onRotation?: (state: RotationState) => void;
}

UseRotationReturn#

TypeScript
export interface UseRotationReturn {
  state: Signal<RotationState>;
  handlers: GestureHandlers;
  reset: () => void;
}

Types — Swiper dot hooks#

SwiperDotHookInputs#

Common per-dot inputs shared by every useSwiperDot* hook.

TypeScript
export interface SwiperDotHookInputs {
  /** Live MT-thread pixel offset from the Swiper's `offset` prop. */
  offset: SharedValue<number>;
  /** Page width in CSS pixels. Must match the Swiper's effective page width. */
  pageWidth: number;
  /** Zero-based page index this dot represents. */
  index: number;
}

UseSwiperDotProgressOptions#

TypeScript
export interface UseSwiperDotProgressOptions extends SwiperDotHookInputs {
  /** Half-width of the input window in `pageWidth` units. Default `1`. */
  window?: number;
  /** Output values at [centre−window·pageWidth, centre, centre+window·pageWidth]. Default `[0, 1, 0]`. */
  outputRange?: readonly [number, number, number];
}

UseSwiperDotTranslateOptions#

TypeScript
export interface UseSwiperDotTranslateOptions {
  offset: SharedValue<number>;
  /** Page width in CSS pixels. */
  pageWidth: number;
  /** Distance in CSS pixels one full page of scroll moves the thumb — typically dotWidth + spacing. */
  step: number;
}

Types — scroll coordination#

ScrollContext#

Scroll-arena coordination context provided by ScrollView and consumed by descendant gesture components via useScrollContext().

TypeScript
export interface ScrollContext {
  /** BG-side flag the parent `<ScrollView>` reads as `enable-scroll={!dragging.value}`. */
  dragging: PrimitiveSignal<boolean>;
  /** MT element ref to the underlying `<scroll-view>`. Null until mounted. */
  scrollViewRef: MainThreadRef<MainThread.Element | null>;
  /** Live horizontal scroll position SharedValue. */
  offsetX: SharedValue<number>;
  /** Live vertical scroll position SharedValue. */
  offsetY: SharedValue<number>;
  /** Scroll axis as configured on the <scroll-view>. */
  scrollOrientation: 'vertical' | 'horizontal';
}