/**
 * @file useSheetGestures.ts
 * @input Uses React (useCallback, useEffect, useMemo, useRef, useState)
 * @output Exports useSheetGestures hook and its option/result types
 * @position Internal to BottomSheet; not exported from the lab entry point
 *
 * Drag + snap machinery for the bottom sheet. Tracks a pointer drag down the
 * block axis, translates the sliding surface live, and on release either
 * settles to the nearest snap detent (a slow drag) or dismisses (a fast flick
 * down). A fast flick up expands to the tallest detent. This is the core
 * behavior split the sheet needs: DRAG places, SWIPE closes.
 *
 * Kept private to BottomSheet: a dismiss edge + detents on a bottom-anchored
 * surface are inherently sheet concepts. It is not a general primitive and is
 * intentionally not exported.
 *
 * SSR-safe: no window/document access at module scope; all measurement
 * happens inside handlers. Respects prefers-reduced-motion by skipping the
 * settle transition.
 *
 * SYNC: When modified, update these files to stay in sync:
 * - /packages/lab/src/BottomSheet/useSheetGestures.doc.mjs
 * - /packages/lab/src/BottomSheet/useSheetGestures.test.ts
 */
import { type CSSProperties, type PointerEvent as ReactPointerEvent } from 'react';
export interface UseSheetGesturesOptions {
    /** Whether the owning sheet is open. Drag state resets when it closes. */
    isOpen: boolean;
    /** Called on a swipe-to-close (fast downward flick, or drag past the floor). */
    onDismiss: () => void;
    /**
     * Resolver for candidate detent heights in px BELOW the full sheet height.
     * Called lazily at the start of each drag so the values stay current (e.g.
     * after a rotation or the virtual keyboard opening) without a persistent
     * resize listener. The measured full height is always the tallest detent,
     * so the effective detent set is `[...snapHeights(), fullHeight]`. Omit for
     * a single-height sheet (a drag then only dismisses or springs back).
     */
    snapHeights?: () => number[];
    /** Notified when the settled detent height (px) changes. */
    onSnap?: (heightPx: number) => void;
    /**
     * Called with the scrim opacity the sheet should show (1 = fully visible,
     * 0 = hidden) as the drag moves and on settle. Full while the sheet is at
     * or above its mid detent, fading to 0 as it collapses onto the shortest
     * "peek" detent — thinning to a faint glance state without fully clearing — and
     * on the dismiss overshoot. Lets the owner mirror it onto the scrim.
     */
    onScrimOpacity?: (opacity: number) => void;
}
export interface SheetContentProps {
    style: CSSProperties;
}
export interface SheetHandleProps {
    style: CSSProperties;
    onPointerDown: (event: ReactPointerEvent) => void;
    onPointerMove: (event: ReactPointerEvent) => void;
    onPointerUp: (event: ReactPointerEvent) => void;
    onPointerCancel: (event: ReactPointerEvent) => void;
}
export interface SheetBodyProps {
    ref: (node: HTMLElement | null) => void;
    onPointerDown: (event: ReactPointerEvent) => void;
    onPointerMove: (event: ReactPointerEvent) => void;
    onPointerUp: (event: ReactPointerEvent) => void;
    onPointerCancel: (event: ReactPointerEvent) => void;
}
export interface UseSheetGesturesResult {
    /**
     * Callback ref for the sheet surface. The hook observes it (ResizeObserver)
     * to keep the fully-open height current, so detents stay correct across
     * rotation / viewport changes without re-measuring mid-drag.
     */
    sheetRef: (node: HTMLElement | null) => void;
    /** Spread on the sliding surface: live translate + touch-action guard. */
    contentProps: SheetContentProps;
    /** Spread on the grab-handle element: pointer drag handlers. */
    handleProps: SheetHandleProps;
    /**
     * Spread on the scrollable body. An overscroll-at-top pull-down starts a
     * sheet drag (a larger, more forgiving target when the content isn't itself
     * scrolling); normal scrolling passes through untouched.
     */
    bodyProps: SheetBodyProps;
    /** Current live drag translate in px (0 = fully expanded, larger = collapsed). */
    dragOffset: number;
    /** Translate of the resting detent in px (0 = tallest detent). */
    settledOffset: number;
    /** Whether a drag is currently in progress. */
    isDragging: boolean;
}
/**
 * Drag + snap machinery for the bottom sheet. Returns props to spread on the
 * grab handle and the sliding surface, plus live drag state. A slow drag
 * settles to the nearest detent; a fast downward flick dismisses; a fast
 * upward flick expands to the tallest detent.
 *
 * @example
 * ```
 * const {contentProps, handleProps} = useSheetGestures({
 *   isOpen,
 *   onDismiss: () => onOpenChange(false),
 *   snapHeights: () => [240, 0.5 * (window.visualViewport?.height ?? 0)],
 * });
 * <div {...contentProps}>
 *   <div {...handleProps} />
 *   {children}
 * </div>
 * ```
 */
export declare function useSheetGestures({ isOpen, onDismiss, snapHeights, onSnap, onScrimOpacity, }: UseSheetGesturesOptions): UseSheetGesturesResult;
//# sourceMappingURL=useSheetGestures.d.ts.map