import { Gesture } from "react-native-gesture-handler"; import { type SharedValue } from "react-native-reanimated"; import type { ChartPadding } from "../draw/line"; /** Minimum height (px) of the bottom "grab the time ruler" band in axis-drag mode. */ export declare const AXIS_GRAB_MIN_PX = 44; /** Which gesture activates a time-scroll. */ export type PanScrollGestureMode = "holdToScrub" | "axisDrag"; /** Engine SharedValues the pan-scroll gesture reads/writes (subset of the engine state). */ export interface PanScrollEngineRefs { /** Absolute right-edge time to freeze at, or `null` to follow the live edge. */ viewEnd: SharedValue; /** Right-edge time the engine would use if following live (advances each frame). */ liveEdge: SharedValue; /** Animating visible window width in seconds. */ displayWindow: SharedValue; /** Canvas width in px. */ canvasWidth: SharedValue; /** Canvas height in px (for the axis-drag band hit-test). */ canvasHeight: SharedValue; } export interface UsePanScrollOptions { engine: PanScrollEngineRefs; padding: ChartPadding; /** * Earliest selectable time (unix seconds) — typically the first data point / * candle. Clamps how far back the window can pan. When there's no scrollable * history this should equal (or exceed) the live edge so panning is a no-op. */ minTime: SharedValue; /** Master switch. When false the gesture is disabled and the chart follows live. */ enabled: boolean; /** * Activation model: * - `"holdToScrub"` (default): a one-finger drag anywhere scrolls; scrub moves * to press-and-hold (Rainbow-style). The caller must give the scrub gesture * a long-press delay so a quick drag falls through to this one. * - `"axisDrag"`: a one-finger drag starting in the bottom X-axis band ("grab * the time ruler"); one-finger plot scrub untouched. */ mode?: PanScrollGestureMode; /** * Worklet fired when a scroll drag activates — e.g. to clear the crosshair so * a stray scrub doesn't linger behind the pan. */ onScrollStart?: () => void; /** * Set true for as long as this gesture owns the touch, cleared on finalize. * The hold-to-scrub pan reads it and refuses to activate mid-scroll — RNGH's * `Gesture.Race` declares no relation between the two pans, so this latch is * the only thing stopping the scrub's long-press timer from firing while the * chart is already being dragged. See `delayedPanGuard.shouldStartDelayedPan`. */ scrollActive?: SharedValue; /** * True while the scrub crosshair owns the touch. Scrolling is inert while set, * so an engaged scrub locks the chart in place and the finger only moves the * price indicator. Cleared when the finger lifts (the scrub pan's finalize). */ scrubActive?: SharedValue; /** * Fraction of the visible window (0–1) the pan may travel past the data * bounds — into blank future space beyond the live edge and blank history * before the oldest point (TradingView-style free dragging). `0` (default) * keeps the classic hard stops at the data. Resolved from * `timeScroll.overscroll` (see `resolveOverscroll`). */ overscroll?: number; /** * Fling inertia on release: a fast drag keeps scrolling and decays to a stop. * `false` stops the window dead where the finger lifts (a release near the * live edge still re-attaches to live). Resolved from `timeScroll.fling` * (see `resolveFling`). Default `true`. */ fling?: boolean; } /** * Snap-to-follow zone around the live edge, as a fraction of the window. With * overscroll a released drag/fling that settles within this zone re-attaches to * live; anything further out stays parked where it stopped. */ export declare const FOLLOW_SNAP = 0.02; /** * Smallest valid right-edge time: keeps the window's left edge * (`rightEdge - window`) from passing `minTime`, and never exceeds the live edge * so the `[lo, liveEdge]` clamp range stays valid when history is short. With * `overscroll` the left edge may pass `minTime` by that fraction of the window, * exposing blank space before the oldest data. */ export declare function panLowerBound(minTime: number, windowSecs: number, liveEdge: number, overscroll?: number): number; /** * Largest valid right-edge time: the live edge, pushed past it by `overscroll` * (a fraction of the window) so the latest data can be dragged toward the middle * of the plot, leaving blank future space on the right. `0` = the live edge. */ export declare function panUpperBound(windowSecs: number, liveEdge: number, overscroll: number): number; /** * Re-clamp a parked right edge after the overscroll setting changes. Reducing * the allowance must not leave a stale future/history position outside the new * bounds; at the classic live-edge hard stop, `null` resumes following live. */ export declare function clampViewEndForOverscroll(viewEnd: number, minTime: number, windowSecs: number, liveEdge: number, overscroll: number): number | null; /** * Next right-edge time after dragging `changeX` px (drag right ⇒ reveal earlier * time ⇒ smaller right edge), clamped to `[lo, panUpperBound]`. Without * overscroll, returns `null` once the drag reaches the live edge — the signal to * resume following. * * With overscroll it must NOT return `null` mid-drag: the pan's `onChange` * re-derives `cur` from `viewEnd ?? liveEdge` each frame, so snapping to follow * re-anchors every per-frame delta at the live edge and the drag can't escape it * in either direction. Re-attaching to live happens only in the release decay * callback (see `usePanScroll`), inside the {@link FOLLOW_SNAP} zone. */ export declare function nextViewEnd(cur: number, changeX: number, chartW: number, windowSecs: number, liveEdge: number, lo: number, overscroll?: number): number | null; /** Pan velocity (px/s) → time-seconds/s for `withDecay` (drag right ⇒ earlier). */ export declare function flingVelocity(velocityX: number, chartW: number, windowSecs: number): number; /** * Top y (px) of the axis-drag grab band — a touch at or below this row starts a * scroll. The band is the bottom padding (where the time labels sit), widened to * a comfortable touch target. */ export declare function axisBandTop(canvasHeight: number, padBottom: number): number; /** * Horizontal pan that scrolls the chart back through time. Pick the activation * with `mode`: * - `"holdToScrub"` — a one-finger drag anywhere (activates on horizontal * travel; vertical falls through). Scrub must be press-and-hold so a quick * drag races past it (compose with `Gesture.Race`). * - `"axisDrag"` — a one-finger drag starting in the bottom X-axis band, gated * via `manualActivation` (compose with `Gesture.Exclusive`, this gesture * first: outside the band it fails instantly so scrub runs). * * Writes `engine.viewEnd`: a number freezes the window at that absolute right * edge; `null` means "follow live". Dragging (or flinging) back to the live edge * resumes following. */ export declare function usePanScroll({ engine, padding, minTime, enabled, mode, onScrollStart, scrollActive, scrubActive, overscroll, fling, }: UsePanScrollOptions): ReturnType; //# sourceMappingURL=usePanScroll.d.ts.map