import type { ReactiveController, ReactiveControllerHost } from 'lit'; export interface PointerClaimOptions { readonly kind?: 'drag' | 'pan'; readonly pinchCandidate?: boolean; } export interface PinchStartDecision { readonly context: TContext; } /** Coordinates and deltas use CSS pixels; movement is sample-relative and total displacement is start-relative. */ export interface PointerMovementGesture { readonly event: PointerEvent; readonly clientX: number; readonly clientY: number; readonly movementX: number; readonly movementY: number; readonly startClientX: number; readonly startClientY: number; readonly totalDisplacementX: number; readonly totalDisplacementY: number; } export interface PinchStart { readonly firstPointerId: number; readonly firstPointerType: string; readonly firstStartClientX: number; readonly firstStartClientY: number; readonly secondPointerId: number; readonly secondPointerType: string; readonly secondStartClientX: number; readonly secondStartClientY: number; readonly startCenterClientX: number; readonly startCenterClientY: number; } export interface PinchGesture extends PinchStart { readonly kind: 'pinch'; readonly event: PointerEvent; readonly context: TContext; /** Current pointer distance divided by the starting pointer distance. */ readonly scale: number; readonly centerClientX: number; readonly centerClientY: number; } /** * Per-event wheel input normalized to CSS pixels. * * Modifier-assisted trackpad pinch remains wheel input: consumers can classify it using the native event's * `ctrlKey` or `metaKey` without conflating it with the start-relative lifecycle of a two-pointer pinch. */ export interface WheelGesture { readonly kind: 'wheel'; readonly event: WheelEvent; readonly clientX: number; readonly clientY: number; readonly deltaX: number; readonly deltaY: number; } export type PointerEndReason = 'up' | 'cancel' | 'lost-capture' | 'buttons-released'; export interface PointerEndGesture extends PointerMovementGesture { readonly kind: 'pointerend'; /** Whether the pointer session ended without an observed physical release. */ readonly interrupted: boolean; readonly reason: PointerEndReason; } export type Gesture = (PointerMovementGesture & { readonly kind: 'drag'; }) | (PointerMovementGesture & { readonly kind: 'pan'; }) | PinchGesture; export interface PointerDownInput { readonly event: PointerEvent; readonly kind: 'pointerdown'; /** * Claims this pointer sequence once during the synchronous input dispatch and suppresses native text selection for * its lifetime; returns `false` after that window. */ readonly claim: (options?: PointerClaimOptions) => boolean; } export interface WheelGestureInput extends WheelGesture { /** Claims and prevents this wheel event during the synchronous input dispatch; returns `false` afterward. */ readonly claim: () => boolean; } /** Claimable starts, claimed pointer terminals, and normalized claimable wheel input. */ export type GestureInput = PointerDownInput | PointerEndGesture | WheelGestureInput; /** Precedence policy for claims among nested GestureController targets. */ export type GestureClaimPriority = 'self-first' | 'descendant-first'; export interface GestureControllerOptions { /** * Skips admission of a new pointer sequence or a stateless native event. * The controller does not consult it again after a pointerdown claim. */ readonly shouldIgnoreEvent?: (event: Event) => boolean; /** * Consulted once when the controller first observes two claimed pinch candidates. * Returning `undefined` declines that pair; otherwise the controller retains the context for its pinch lifetime. * The pair remains locked until fewer than two pinch candidates remain. */ readonly beginPinch?: (start: PinchStart) => PinchStartDecision | undefined; /** Consulted independently for each context-menu event. */ readonly shouldPreventContextMenu?: (event: MouseEvent) => boolean; /** * Determines precedence among nested GestureController targets. * * `self-first` is appropriate for a dedicated interaction surface. * `descendant-first` lets nested controllers claim input before this controller. * * Defaults to `self-first`. */ readonly claimPriority?: GestureClaimPriority; /** * Consulted during native pointerdown capture before descendant handlers. * * Returning true calls preventDefault() on the pointerdown, but does not * claim the pointer, capture it, stop propagation, create pointer state, * suppress selection, or start a gesture. * * This is meaningful with `claimPriority: 'descendant-first'`. It lets an * activated higher-level interaction mode reserve a sequence for ordinary * target-phase application code while preserving nested GestureController * claim priority. */ readonly shouldReservePointerDown?: (event: PointerEvent) => boolean; /** Prevents native HTML drag competition on a dedicated interaction surface. */ readonly suppressNativeDrag?: boolean; /** * Inline `touch-action` for a dedicated interaction surface. The controller reevaluates a callback after host updates. * Restores the target's prior inline value afterward. * Avoid applying it to a general root that contains native interactive content. */ readonly touchAction?: string | (() => string | undefined); } type GestureHost = EventTarget & ReactiveControllerHost; /** * Normalizes claimable platform pointer and wheel input on a dynamically assigned target. * A pointer claim owns native input competition for its lifetime: the controller prevents claimed movement and text * selection, and can suppress native drag when configured. */ export declare class GestureController implements ReactiveController { #private; constructor(host: GestureHost, options: GestureControllerOptions); getWheelZoomFactor(input: Pick): number; set target(target: HTMLElement | undefined); hostConnected(): void; hostDisconnected(): void; hostUpdated(): void; } export {};