{"version":3,"file":"useViewportShift.hook.cjs","sources":["../../../src/hooks/use-viewport-shift/useViewportShift.hook.ts"],"sourcesContent":["import { useCallback, useRef } from 'react'\r\nimport { guardAccidentalSelection } from '@hooks/use-viewport-shift/helpers/guardAccidentalSelection.helper.ts'\r\nimport { normalizePadding } from '@hooks/use-viewport-shift/helpers/normalizePadding.helper.ts'\r\nimport { createCorrector } from '@hooks/use-viewport-shift/helpers/createCorrector.helper.ts'\r\nimport { watchRepositions } from '@hooks/use-viewport-shift/helpers/watchRepositions.helper.ts'\r\nimport type { Padding } from '@hooks/use-viewport-shift/types'\r\n\r\n/**\r\n * Returns a React 19 **callback ref** that keeps a Radix floating panel fully\r\n * visible within the viewport by applying a CSS `translate` correction.\r\n *\r\n * A callback ref is required because Radix `Portal` mounts content in a second\r\n * render pass, so a parent `useLayoutEffect` would fire while the node is still\r\n * `null`; the callback fires exactly when the DOM node attaches.\r\n *\r\n * @param collisionPadding - Minimum gap in px between the panel and each\r\n *   viewport edge. Accepts a uniform number or a per-side object. @default 8\r\n */\r\nexport const useViewportShift = (collisionPadding: Padding = 8) => {\r\n    // Stable ref so the callback always reads the latest padding without being\r\n    // recreated on every render.\r\n    const padRef = useRef(normalizePadding(collisionPadding))\r\n    padRef.current = normalizePadding(collisionPadding)\r\n\r\n    return useCallback((content: HTMLDivElement | null): (() => void) | void => {\r\n        // `parentElement` is the Radix popper wrapper carrying floating-ui's\r\n        // positioning transform — the element we measure and observe.\r\n        const wrapper = content?.parentElement\r\n        if (!content || !wrapper) { return }\r\n\r\n        const correct = createCorrector(content, wrapper, padRef)\r\n        const stopWatching = watchRepositions(content, wrapper, correct)\r\n        const stopGuarding = guardAccidentalSelection(content)\r\n\r\n        // React 19 callback ref cleanup — called automatically on unmount.\r\n        return () => {\r\n            stopWatching()\r\n            stopGuarding()\r\n        }\r\n    }, []) // stable: only padRef (a ref) is captured — never changes identity\r\n}\r\n"],"names":["useViewportShift","collisionPadding","padRef","useRef","normalizePadding","useCallback","content","wrapper","correct","createCorrector","stopWatching","watchRepositions","stopGuarding","guardAccidentalSelection"],"mappings":"4TAkBaA,EAAmB,CAACC,EAA4B,IAAM,CAG/D,MAAMC,EAASC,EAAAA,OAAOC,EAAAA,iBAAiBH,CAAgB,CAAC,EACxD,OAAAC,EAAO,QAAUE,EAAAA,iBAAiBH,CAAgB,EAE3CI,EAAAA,YAAaC,GAAwD,CAGxE,MAAMC,EAAUD,GAAS,cACzB,GAAI,CAACA,GAAW,CAACC,EAAW,OAE5B,MAAMC,EAAUC,EAAAA,gBAAgBH,EAASC,EAASL,CAAM,EAClDQ,EAAeC,EAAAA,iBAAiBL,EAASC,EAASC,CAAO,EACzDI,EAAeC,EAAAA,yBAAyBP,CAAO,EAGrD,MAAO,IAAM,CACTI,EAAA,EACAE,EAAA,CACJ,CACJ,EAAG,CAAA,CAAE,CACT"}