{"version":3,"sources":["../../src/use-element-bounding/index.ts"],"sourcesContent":["import { useEffect } from 'react'\nimport { useEventListener } from '../use-event-listener'\nimport { useLatest } from '../use-latest'\nimport { useMutationObserver } from '../use-mutation-observer'\nimport { useResizeObserver } from '../use-resize-observer'\nimport { useSafeState } from '../use-safe-state'\nimport { useStableFn } from '../use-stable-fn'\nimport { normalizeElement, useTargetElement } from '../use-target-element'\n\nimport type { ElementTarget } from '../use-target-element'\n\nexport interface UseElementBoundingOptions {\n  /**\n   * Reset the bounding box when the element is not found\n   *\n   * @defaultValue true\n   */\n  reset?: boolean\n  /**\n   * Update the bounding box when the window is resized\n   *\n   * @defaultValue true\n   */\n  windowResize?: boolean\n  /**\n   * Update the bounding box when the window is scrolled\n   *\n   * @defaultValue true\n   */\n  windowScroll?: boolean\n}\n\nexport type UseElementBoundingReturns = readonly [\n  {\n    /**\n     * The height of the element\n     */\n    height: number\n    /**\n     * The bottom position of the element\n     */\n    bottom: number\n    /**\n     * The left position of the element\n     */\n    left: number\n    /**\n     * The right position of the element\n     */\n    right: number\n    /**\n     * The top position of the element\n     */\n    top: number\n    /**\n     * The width of the element\n     */\n    width: number\n    /**\n     * The x position of the element\n     */\n    x: number\n    /**\n     * The y position of the element\n     */\n    y: number\n  },\n  /**\n   * Update the bounding box of the element\n   */\n  update: () => void,\n]\n\nconst defaultElBounding = { x: 0, y: 0, height: 0, width: 0, top: 0, right: 0, bottom: 0, left: 0 }\n\n/**\n * A React Hook that returns the [bounding client rect](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect) of an element.\n */\nexport function useElementBounding<T extends HTMLElement = HTMLElement>(\n  target: ElementTarget<T>,\n  options: UseElementBoundingOptions = {},\n): UseElementBoundingReturns {\n  const { reset = true, windowResize = true, windowScroll = true } = options\n  const el = useTargetElement<T>(target)\n\n  const [bounding, setBounding] = useSafeState({ ...defaultElBounding }, { deep: true })\n  const latest = useLatest({ reset })\n\n  const update = useStableFn(() => {\n    if (!el.current) {\n      latest.current.reset && setBounding({ ...defaultElBounding })\n      return\n    }\n\n    const rect = getElBounding(el.current)\n    const { height, bottom, left, right, top, width, x, y } = rect\n\n    setBounding({ x, y, height, width, top, right, bottom, left })\n  })\n\n  // biome-ignore lint/correctness/useExhaustiveDependencies: effect need to re-run when reset, windowResize or windowScroll changes\n  useEffect(() => void update(), [el.current, reset, windowScroll, windowResize])\n\n  useResizeObserver(el, update)\n  useMutationObserver(el, update, { attributeFilter: ['style', 'class'] })\n\n  useEventListener(() => window, windowScroll ? 'scroll' : [], update, { capture: true, passive: true })\n  useEventListener(() => window, windowResize ? 'resize' : [], update, { passive: true })\n\n  return [bounding, update] as const\n}\n\nfunction getElBounding<T extends HTMLElement>(target: ElementTarget<T>): UseElementBoundingReturns[0] {\n  const el = normalizeElement(target)\n\n  if (!el) return defaultElBounding\n\n  return el.getBoundingClientRect()\n}\n"],"names":["useElementBounding","defaultElBounding","x","y","height","width","top","right","bottom","left","target","options","reset","windowResize","windowScroll","el","useTargetElement","useSafeState","deep","bounding","setBounding","latest","useLatest","update","useStableFn","current","rect","getElBounding","useEffect","useResizeObserver","useMutationObserver","attributeFilter","useEventListener","window","capture","passive","normalizeElement","getBoundingClientRect"],"mappings":";;;;+BA8EgBA;;;eAAAA;;;qBA9EU;gCACO;yBACP;mCACU;iCACF;4BACL;2BACD;gCACuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkEnD,IAAMC,oBAAoB;IAAEC,GAAG;IAAGC,GAAG;IAAGC,QAAQ;IAAGC,OAAO;IAAGC,KAAK;IAAGC,OAAO;IAAGC,QAAQ;IAAGC,MAAM;AAAE;AAK3F,SAAST,mBACdU,MAAwB;QACxBC,UAAAA,iEAAqC,CAAC;IAEtC,qBAAmEA,QAA3DC,OAAAA,oCAAQ,+CAAmDD,QAA7CE,cAAAA,kDAAe,sDAA8BF,QAAxBG,cAAAA,kDAAe;IAC1D,IAAMC,KAAKC,IAAAA,kCAAgB,EAAIN;IAE/B,IAAgCO,iCAAAA,IAAAA,0BAAY,EAAC,mBAAKhB,oBAAqB;QAAEiB,MAAM;IAAK,QAA7EC,WAAyBF,kBAAfG,cAAeH;IAChC,IAAMI,SAASC,IAAAA,oBAAS,EAAC;QAAEV,OAAAA;IAAM;IAEjC,IAAMW,SAASC,IAAAA,wBAAW,EAAC;QACzB,IAAI,CAACT,GAAGU,OAAO,EAAE;YACfJ,OAAOI,OAAO,CAACb,KAAK,IAAIQ,YAAY,mBAAKnB;YACzC;QACF;QAEA,IAAMyB,OAAOC,cAAcZ,GAAGU,OAAO;QACrC,IAAQrB,SAAkDsB,KAAlDtB,QAAQI,SAA0CkB,KAA1ClB,QAAQC,OAAkCiB,KAAlCjB,MAAMF,QAA4BmB,KAA5BnB,OAAOD,MAAqBoB,KAArBpB,KAAKD,QAAgBqB,KAAhBrB,OAAOH,IAASwB,KAATxB,GAAGC,IAAMuB,KAANvB;QAEpDiB,YAAY;YAAElB,GAAAA;YAAGC,GAAAA;YAAGC,QAAAA;YAAQC,OAAAA;YAAOC,KAAAA;YAAKC,OAAAA;YAAOC,QAAAA;YAAQC,MAAAA;QAAK;IAC9D;IAEA,kIAAkI;IAClImB,IAAAA,gBAAS,EAAC;eAAM,KAAKL;OAAU;QAACR,GAAGU,OAAO;QAAEb;QAAOE;QAAcD;KAAa;IAE9EgB,IAAAA,oCAAiB,EAACd,IAAIQ;IACtBO,IAAAA,wCAAmB,EAACf,IAAIQ,QAAQ;QAAEQ,iBAAiB;YAAC;YAAS;SAAQ;IAAC;IAEtEC,IAAAA,kCAAgB,EAAC;eAAMC;OAAQnB,eAAe,WAAW,EAAE,EAAES,QAAQ;QAAEW,SAAS;QAAMC,SAAS;IAAK;IACpGH,IAAAA,kCAAgB,EAAC;eAAMC;OAAQpB,eAAe,WAAW,EAAE,EAAEU,QAAQ;QAAEY,SAAS;IAAK;IAErF,OAAO;QAAChB;QAAUI;KAAO;AAC3B;AAEA,SAASI,cAAqCjB,MAAwB;IACpE,IAAMK,KAAKqB,IAAAA,kCAAgB,EAAC1B;IAE5B,IAAI,CAACK,IAAI,OAAOd;IAEhB,OAAOc,GAAGsB,qBAAqB;AACjC"}