// Shared, framework-agnostic primitives for pointer-based drag interactions.
// Extracted from the task-board Kanban drag so the page-editor pointer drag can
// reuse the same proven threshold, edge auto-scroll, and scroll-container logic.
/** Movement (in px) a pointer must travel before a press becomes a drag. */
export const DRAG_START_THRESHOLD_PX = 6;
/** Distance from a scroll-container edge (px) at which auto-scroll engages. */
export const AUTO_SCROLL_EDGE_PX = 56;
/** Maximum auto-scroll step (px per frame) at the very edge. */
export const AUTO_SCROLL_MAX_STEP_PX = 18;
export function clamp(value, min, max) {
    return Math.min(Math.max(value, min), max);
}
/**
 * Auto-scroll step for a pointer near the [start, end] edges of a scroll
 * container along one axis. Negative scrolls toward `start`, positive toward
 * `end`, 0 when the pointer is comfortably inside. The step ramps from 0 at the
 * edge band boundary to `maxStepPx` at the edge.
 */
export function getAutoScrollStep(pointerPosition, start, end, edgePx = AUTO_SCROLL_EDGE_PX, maxStepPx = AUTO_SCROLL_MAX_STEP_PX) {
    const distanceToStart = pointerPosition - start;
    const distanceToEnd = end - pointerPosition;
    if (distanceToStart >= 0 && distanceToStart < edgePx) {
        const ratio = 1 - distanceToStart / edgePx;
        return -Math.ceil(ratio * maxStepPx);
    }
    if (distanceToEnd >= 0 && distanceToEnd < edgePx) {
        const ratio = 1 - distanceToEnd / edgePx;
        return Math.ceil(ratio * maxStepPx);
    }
    return 0;
}
/**
 * Walk up from the element under (clientX, clientY) to the nearest vertically
 * scrollable ancestor, optionally constrained to within `boundary`. Returns null
 * when there is none (so callers can fall back to a different scroller).
 */
export function getScrollableAncestorFromPoint(clientX, clientY, boundary) {
    let element = document.elementFromPoint(clientX, clientY);
    if (boundary &&
        element instanceof HTMLElement &&
        !boundary.contains(element)) {
        return null;
    }
    while (element instanceof HTMLElement) {
        const style = window.getComputedStyle(element);
        const canScrollY = element.scrollHeight > element.clientHeight &&
            style.overflowY !== "hidden" &&
            style.overflowY !== "clip" &&
            style.overflowY !== "visible";
        if (canScrollY) {
            return element;
        }
        element = element.parentElement;
    }
    return null;
}
//# sourceMappingURL=pointerDrag.js.map