{"version":3,"file":"auto-scroll.mjs","sources":["../../../../../src/components/Reorder/utils/auto-scroll.ts"],"sourcesContent":["const threshold = 50\nconst maxSpeed = 25\n\nconst overflowStyles = new Set([\"auto\", \"scroll\"])\n\n// Track initial scroll limits per scrollable element (Bug 1 fix)\nconst initialScrollLimits = new WeakMap<HTMLElement, number>()\n\n// Track auto-scroll active state per edge: \"start\" (top/left) or \"end\" (bottom/right)\ntype ActiveEdge = \"start\" | \"end\" | null\nconst activeScrollEdge = new WeakMap<HTMLElement, ActiveEdge>()\n\n// Track which group element is currently dragging to clear state on end\nlet currentGroupElement: Element | null = null\n\nexport function resetAutoScrollState(): void {\n    if (currentGroupElement) {\n        const scrollableAncestor = findScrollableAncestor(\n            currentGroupElement,\n            \"y\"\n        )\n        if (scrollableAncestor) {\n            activeScrollEdge.delete(scrollableAncestor)\n            initialScrollLimits.delete(scrollableAncestor)\n        }\n        // Also try x axis\n        const scrollableAncestorX = findScrollableAncestor(\n            currentGroupElement,\n            \"x\"\n        )\n        if (scrollableAncestorX && scrollableAncestorX !== scrollableAncestor) {\n            activeScrollEdge.delete(scrollableAncestorX)\n            initialScrollLimits.delete(scrollableAncestorX)\n        }\n        currentGroupElement = null\n    }\n}\n\nfunction isScrollableElement(element: Element, axis: \"x\" | \"y\"): boolean {\n    const style = getComputedStyle(element)\n    const overflow = axis === \"x\" ? style.overflowX : style.overflowY\n\n    const isDocumentScroll =\n        element === document.body ||\n        element === document.documentElement\n\n    return overflowStyles.has(overflow) || isDocumentScroll\n}\n\nfunction findScrollableAncestor(\n    element: Element | null,\n    axis: \"x\" | \"y\"\n): HTMLElement | null {\n    let current = element?.parentElement\n    while (current) {\n        if (isScrollableElement(current, axis)) {\n            return current\n        }\n        current = current.parentElement\n    }\n    return null\n}\n\nfunction getScrollAmount(\n    pointerPosition: number,\n    scrollElement: HTMLElement,\n    axis: \"x\" | \"y\"\n): { amount: number; edge: ActiveEdge } {\n    const rect = scrollElement.getBoundingClientRect()\n\n    const start = axis === \"x\" ? Math.max(0, rect.left) : Math.max(0, rect.top)\n    const end = axis === \"x\" ? Math.min(window.innerWidth, rect.right) : Math.min(window.innerHeight, rect.bottom)\n\n    const distanceFromStart = pointerPosition - start\n    const distanceFromEnd = end - pointerPosition\n\n    if (distanceFromStart < threshold) {\n        const intensity = 1 - distanceFromStart / threshold\n        return { amount: -maxSpeed * intensity * intensity, edge: \"start\" }\n    } else if (distanceFromEnd < threshold) {\n        const intensity = 1 - distanceFromEnd / threshold\n        return { amount: maxSpeed * intensity * intensity, edge: \"end\" }\n    }\n\n    return { amount: 0, edge: null }\n}\n\nexport function autoScrollIfNeeded(\n    groupElement: Element | null,\n    pointerPosition: number,\n    axis: \"x\" | \"y\",\n    velocity: number\n): void {\n    if (!groupElement) return\n\n    // Track the group element for cleanup\n    currentGroupElement = groupElement\n\n    const scrollableAncestor = findScrollableAncestor(groupElement, axis)\n    if (!scrollableAncestor) return\n\n    // Convert pointer position from page coordinates to viewport coordinates.\n    // The gesture system uses pageX/pageY but getBoundingClientRect() returns\n    // viewport-relative coordinates, so we need to account for page scroll.\n    const viewportPointerPosition =\n        pointerPosition - (axis === \"x\" ? window.scrollX : window.scrollY)\n\n    const { amount: scrollAmount, edge } = getScrollAmount(\n        viewportPointerPosition,\n        scrollableAncestor,\n        axis\n    )\n\n    // If not in any threshold zone, clear all state\n    if (edge === null) {\n        activeScrollEdge.delete(scrollableAncestor)\n        initialScrollLimits.delete(scrollableAncestor)\n        return\n    }\n\n    const currentActiveEdge = activeScrollEdge.get(scrollableAncestor)\n\n    const isDocumentScroll =\n        scrollableAncestor === document.body ||\n        scrollableAncestor === document.documentElement\n\n    // If not currently scrolling this edge, check velocity to see if we should start\n    if (currentActiveEdge !== edge) {\n        // Only start scrolling if velocity is towards the edge\n        const shouldStart =\n            (edge === \"start\" && velocity < 0) ||\n            (edge === \"end\" && velocity > 0)\n        if (!shouldStart) return\n\n        // Activate this edge\n        activeScrollEdge.set(scrollableAncestor, edge)\n\n        // Record initial scroll limit (prevents infinite scroll)\n        const maxScroll =\n            axis === \"x\"\n                ? scrollableAncestor.scrollWidth - (isDocumentScroll ? window.innerWidth : scrollableAncestor.clientWidth)\n                : scrollableAncestor.scrollHeight - (isDocumentScroll ? window.innerHeight : scrollableAncestor.clientHeight)\n\n        initialScrollLimits.set(scrollableAncestor, maxScroll)\n    }\n\n    // Cap scrolling at initial limit (prevents infinite scroll)\n    if (scrollAmount > 0) {\n        const initialLimit = initialScrollLimits.get(scrollableAncestor)!\n        const currentScroll =\n            axis === \"x\"\n                ? (isDocumentScroll ? window.scrollX : scrollableAncestor.scrollLeft)\n                : (isDocumentScroll ? window.scrollY : scrollableAncestor.scrollTop)\n        if (currentScroll >= initialLimit) return\n    }\n\n    // Apply scroll\n    if (axis === \"x\") {\n        if (isDocumentScroll) {\n            window.scrollBy({ left: scrollAmount })\n        } else {\n            scrollableAncestor.scrollLeft += scrollAmount\n        }\n    } else {\n        if (isDocumentScroll) {\n            window.scrollBy({ top: scrollAmount })\n        } else {\n            scrollableAncestor.scrollTop += scrollAmount\n        }\n    }\n}\n"],"names":[],"mappings":"AAAA,MAAM,SAAS,GAAG,EAAE;AACpB,MAAM,QAAQ,GAAG,EAAE;AAEnB,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AAElD;AACA,MAAM,mBAAmB,GAAG,IAAI,OAAO,EAAuB;AAI9D,MAAM,gBAAgB,GAAG,IAAI,OAAO,EAA2B;AAE/D;AACA,IAAI,mBAAmB,GAAmB,IAAI;SAE9B,oBAAoB,GAAA;IAChC,IAAI,mBAAmB,EAAE;QACrB,MAAM,kBAAkB,GAAG,sBAAsB,CAC7C,mBAAmB,EACnB,GAAG,CACN;QACD,IAAI,kBAAkB,EAAE;AACpB,YAAA,gBAAgB,CAAC,MAAM,CAAC,kBAAkB,CAAC;AAC3C,YAAA,mBAAmB,CAAC,MAAM,CAAC,kBAAkB,CAAC;QAClD;;QAEA,MAAM,mBAAmB,GAAG,sBAAsB,CAC9C,mBAAmB,EACnB,GAAG,CACN;AACD,QAAA,IAAI,mBAAmB,IAAI,mBAAmB,KAAK,kBAAkB,EAAE;AACnE,YAAA,gBAAgB,CAAC,MAAM,CAAC,mBAAmB,CAAC;AAC5C,YAAA,mBAAmB,CAAC,MAAM,CAAC,mBAAmB,CAAC;QACnD;QACA,mBAAmB,GAAG,IAAI;IAC9B;AACJ;AAEA,SAAS,mBAAmB,CAAC,OAAgB,EAAE,IAAe,EAAA;AAC1D,IAAA,MAAM,KAAK,GAAG,gBAAgB,CAAC,OAAO,CAAC;AACvC,IAAA,MAAM,QAAQ,GAAG,IAAI,KAAK,GAAG,GAAG,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS;AAEjE,IAAA,MAAM,gBAAgB,GAClB,OAAO,KAAK,QAAQ,CAAC,IAAI;AACzB,QAAA,OAAO,KAAK,QAAQ,CAAC,eAAe;IAExC,OAAO,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,gBAAgB;AAC3D;AAEA,SAAS,sBAAsB,CAC3B,OAAuB,EACvB,IAAe,EAAA;AAEf,IAAA,IAAI,OAAO,GAAG,OAAO,EAAE,aAAa;IACpC,OAAO,OAAO,EAAE;AACZ,QAAA,IAAI,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE;AACpC,YAAA,OAAO,OAAO;QAClB;AACA,QAAA,OAAO,GAAG,OAAO,CAAC,aAAa;IACnC;AACA,IAAA,OAAO,IAAI;AACf;AAEA,SAAS,eAAe,CACpB,eAAuB,EACvB,aAA0B,EAC1B,IAAe,EAAA;AAEf,IAAA,MAAM,IAAI,GAAG,aAAa,CAAC,qBAAqB,EAAE;AAElD,IAAA,MAAM,KAAK,GAAG,IAAI,KAAK,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC;AAC3E,IAAA,MAAM,GAAG,GAAG,IAAI,KAAK,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC;AAE9G,IAAA,MAAM,iBAAiB,GAAG,eAAe,GAAG,KAAK;AACjD,IAAA,MAAM,eAAe,GAAG,GAAG,GAAG,eAAe;AAE7C,IAAA,IAAI,iBAAiB,GAAG,SAAS,EAAE;AAC/B,QAAA,MAAM,SAAS,GAAG,CAAC,GAAG,iBAAiB,GAAG,SAAS;AACnD,QAAA,OAAO,EAAE,MAAM,EAAE,CAAC,QAAQ,GAAG,SAAS,GAAG,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE;IACvE;AAAO,SAAA,IAAI,eAAe,GAAG,SAAS,EAAE;AACpC,QAAA,MAAM,SAAS,GAAG,CAAC,GAAG,eAAe,GAAG,SAAS;AACjD,QAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE;IACpE;IAEA,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE;AACpC;AAEM,SAAU,kBAAkB,CAC9B,YAA4B,EAC5B,eAAuB,EACvB,IAAe,EACf,QAAgB,EAAA;AAEhB,IAAA,IAAI,CAAC,YAAY;QAAE;;IAGnB,mBAAmB,GAAG,YAAY;IAElC,MAAM,kBAAkB,GAAG,sBAAsB,CAAC,YAAY,EAAE,IAAI,CAAC;AACrE,IAAA,IAAI,CAAC,kBAAkB;QAAE;;;;IAKzB,MAAM,uBAAuB,GACzB,eAAe,IAAI,IAAI,KAAK,GAAG,GAAG,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;AAEtE,IAAA,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,GAAG,eAAe,CAClD,uBAAuB,EACvB,kBAAkB,EAClB,IAAI,CACP;;AAGD,IAAA,IAAI,IAAI,KAAK,IAAI,EAAE;AACf,QAAA,gBAAgB,CAAC,MAAM,CAAC,kBAAkB,CAAC;AAC3C,QAAA,mBAAmB,CAAC,MAAM,CAAC,kBAAkB,CAAC;QAC9C;IACJ;IAEA,MAAM,iBAAiB,GAAG,gBAAgB,CAAC,GAAG,CAAC,kBAAkB,CAAC;AAElE,IAAA,MAAM,gBAAgB,GAClB,kBAAkB,KAAK,QAAQ,CAAC,IAAI;AACpC,QAAA,kBAAkB,KAAK,QAAQ,CAAC,eAAe;;AAGnD,IAAA,IAAI,iBAAiB,KAAK,IAAI,EAAE;;QAE5B,MAAM,WAAW,GACb,CAAC,IAAI,KAAK,OAAO,IAAI,QAAQ,GAAG,CAAC;aAChC,IAAI,KAAK,KAAK,IAAI,QAAQ,GAAG,CAAC,CAAC;AACpC,QAAA,IAAI,CAAC,WAAW;YAAE;;AAGlB,QAAA,gBAAgB,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAI,CAAC;;AAG9C,QAAA,MAAM,SAAS,GACX,IAAI,KAAK;AACL,cAAE,kBAAkB,CAAC,WAAW,IAAI,gBAAgB,GAAG,MAAM,CAAC,UAAU,GAAG,kBAAkB,CAAC,WAAW;cACvG,kBAAkB,CAAC,YAAY,IAAI,gBAAgB,GAAG,MAAM,CAAC,WAAW,GAAG,kBAAkB,CAAC,YAAY,CAAC;AAErH,QAAA,mBAAmB,CAAC,GAAG,CAAC,kBAAkB,EAAE,SAAS,CAAC;IAC1D;;AAGA,IAAA,IAAI,YAAY,GAAG,CAAC,EAAE;QAClB,MAAM,YAAY,GAAG,mBAAmB,CAAC,GAAG,CAAC,kBAAkB,CAAE;AACjE,QAAA,MAAM,aAAa,GACf,IAAI,KAAK;AACL,eAAG,gBAAgB,GAAG,MAAM,CAAC,OAAO,GAAG,kBAAkB,CAAC,UAAU;AACpE,eAAG,gBAAgB,GAAG,MAAM,CAAC,OAAO,GAAG,kBAAkB,CAAC,SAAS,CAAC;QAC5E,IAAI,aAAa,IAAI,YAAY;YAAE;IACvC;;AAGA,IAAA,IAAI,IAAI,KAAK,GAAG,EAAE;QACd,IAAI,gBAAgB,EAAE;YAClB,MAAM,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;QAC3C;aAAO;AACH,YAAA,kBAAkB,CAAC,UAAU,IAAI,YAAY;QACjD;IACJ;SAAO;QACH,IAAI,gBAAgB,EAAE;YAClB,MAAM,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,YAAY,EAAE,CAAC;QAC1C;aAAO;AACH,YAAA,kBAAkB,CAAC,SAAS,IAAI,YAAY;QAChD;IACJ;AACJ;;;;"}