{"version":3,"file":"useObserveOverflow.mjs","names":[],"sources":["../../../../../../../../src/lib/hooks/dom/useObserveOverflow.ts"],"sourcesContent":["import type { RefCallback } from \"react\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { FrameResizeObserver } from \"@/lib/dom/createFrameResizeObserver\";\nimport { createFrameResizeObserver } from \"@/lib/dom/createFrameResizeObserver\";\n\ninterface UseObserveOverflowReturn {\n  ref: RefCallback<HTMLElement>;\n  isOverflowing: boolean;\n}\n\n/**\n * Tracks whether the observed element overflows its parent horizontally.\n * Re-measures when the element, its parent or any of its children resize, and\n * when children are added or removed.\n */\nexport const useObserveOverflow = (): UseObserveOverflowReturn => {\n  const elementRef = useRef<HTMLElement | null>(null);\n  const observerRef = useRef<FrameResizeObserver | null>(null);\n  const mutationObserverRef = useRef<MutationObserver | null>(null);\n  const [isOverflowing, setIsOverflowing] = useState(false);\n\n  const measureOverflow = useCallback(() => {\n    const element = elementRef.current;\n    const parent = element?.parentElement;\n\n    if (!element || !parent) {\n      setIsOverflowing(false);\n      return;\n    }\n\n    // React bails out of the re-render when the boolean is unchanged.\n    setIsOverflowing(element.scrollWidth - parent.clientWidth > 1);\n  }, []);\n\n  const observeTargets = useCallback(() => {\n    const element = elementRef.current;\n\n    if (!element) {\n      return;\n    }\n\n    const targets: Element[] = [element];\n    if (element.parentElement) {\n      targets.push(element.parentElement);\n    }\n    targets.push(...element.children);\n\n    observerRef.current?.observe(targets);\n  }, []);\n\n  const stopObservers = useCallback(() => {\n    observerRef.current?.disconnect();\n    mutationObserverRef.current?.disconnect();\n\n    observerRef.current = null;\n    mutationObserverRef.current = null;\n  }, []);\n\n  const ref: RefCallback<HTMLElement> = useCallback(\n    (element) => {\n      stopObservers();\n      elementRef.current = element;\n\n      if (!element) {\n        setIsOverflowing(false);\n        return;\n      }\n\n      const observer = createFrameResizeObserver(measureOverflow);\n      observerRef.current = observer;\n      observeTargets();\n\n      // Children may be rendered by someone else entirely (e.g. portaled in via\n      // UiComponentTunnel), so the observing component never receives a\n      // `children`/count prop to react to — childList mutations are the only\n      // signal that a child was added or removed.\n      mutationObserverRef.current = new MutationObserver(() => {\n        observeTargets();\n        observer.schedule();\n      });\n      mutationObserverRef.current.observe(element, {\n        childList: true,\n      });\n\n      observer.schedule();\n    },\n    [measureOverflow, observeTargets, stopObservers],\n  );\n\n  useEffect(() => {\n    return stopObservers;\n  }, [stopObservers]);\n\n  return {\n    ref,\n    isOverflowing,\n  };\n};\n"],"mappings":";;;;;;;;;;AAeA,IAAa,2BAAqD;CAChE,MAAM,aAAa,OAA2B,IAAI;CAClD,MAAM,cAAc,OAAmC,IAAI;CAC3D,MAAM,sBAAsB,OAAgC,IAAI;CAChE,MAAM,CAAC,eAAe,oBAAoB,SAAS,KAAK;CAExD,MAAM,kBAAkB,kBAAkB;EACxC,MAAM,UAAU,WAAW;EAC3B,MAAM,SAAS,SAAS;EAExB,IAAI,CAAC,WAAW,CAAC,QAAQ;GACvB,iBAAiB,KAAK;GACtB;EACF;EAGA,iBAAiB,QAAQ,cAAc,OAAO,cAAc,CAAC;CAC/D,GAAG,CAAC,CAAC;CAEL,MAAM,iBAAiB,kBAAkB;EACvC,MAAM,UAAU,WAAW;EAE3B,IAAI,CAAC,SACH;EAGF,MAAM,UAAqB,CAAC,OAAO;EACnC,IAAI,QAAQ,eACV,QAAQ,KAAK,QAAQ,aAAa;EAEpC,QAAQ,KAAK,GAAG,QAAQ,QAAQ;EAEhC,YAAY,SAAS,QAAQ,OAAO;CACtC,GAAG,CAAC,CAAC;CAEL,MAAM,gBAAgB,kBAAkB;EACtC,YAAY,SAAS,WAAW;EAChC,oBAAoB,SAAS,WAAW;EAExC,YAAY,UAAU;EACtB,oBAAoB,UAAU;CAChC,GAAG,CAAC,CAAC;CAEL,MAAM,MAAgC,aACnC,YAAY;EACX,cAAc;EACd,WAAW,UAAU;EAErB,IAAI,CAAC,SAAS;GACZ,iBAAiB,KAAK;GACtB;EACF;EAEA,MAAM,WAAW,0BAA0B,eAAe;EAC1D,YAAY,UAAU;EACtB,eAAe;EAMf,oBAAoB,UAAU,IAAI,uBAAuB;GACvD,eAAe;GACf,SAAS,SAAS;EACpB,CAAC;EACD,oBAAoB,QAAQ,QAAQ,SAAS,EAC3C,WAAW,KACb,CAAC;EAED,SAAS,SAAS;CACpB,GACA;EAAC;EAAiB;EAAgB;CAAa,CACjD;CAEA,gBAAgB;EACd,OAAO;CACT,GAAG,CAAC,aAAa,CAAC;CAElB,OAAO;EACL;EACA;CACF;AACF"}