{
  "version": 3,
  "sources": ["../../src/utils/element-rect.ts"],
  "sourcesContent": ["/* eslint-disable jsdoc/require-param */\n/**\n * WordPress dependencies\n */\nimport { useLayoutEffect, useRef, useState } from '@wordpress/element';\nimport { useEvent, useResizeObserver } from '@wordpress/compose';\n\n/**\n * The position and dimensions of an element, relative to its offset parent.\n */\n\n/**\n * An `ElementOffsetRect` object with all values set to zero.\n */\nexport const NULL_ELEMENT_OFFSET_RECT = {\n  element: undefined,\n  top: 0,\n  right: 0,\n  bottom: 0,\n  left: 0,\n  width: 0,\n  height: 0\n};\n\n/**\n * Returns the position and dimensions of an element, relative to its offset\n * parent, with subpixel precision. Values reflect the real measures before any\n * potential scaling distortions along the X and Y axes.\n *\n * Useful in contexts where plain `getBoundingClientRect` calls or `ResizeObserver`\n * entries are not suitable, such as when the element is transformed, and when\n * `element.offset<Top|Left|Width|Height>` methods are not precise enough.\n *\n * **Note:** in some contexts, like when the scale is 0, this method will fail\n * because it's impossible to calculate a scaling ratio. When that happens, it\n * will return `undefined`.\n */\nexport function getElementOffsetRect(element) {\n  // Position and dimension values computed with `getBoundingClientRect` have\n  // subpixel precision, but are affected by distortions since they represent\n  // the \"real\" measures, or in other words, the actual final values as rendered\n  // by the browser.\n  const rect = element.getBoundingClientRect();\n  if (rect.width === 0 || rect.height === 0) {\n    return;\n  }\n  const offsetParent = element.offsetParent;\n  const offsetParentRect = offsetParent?.getBoundingClientRect() ?? NULL_ELEMENT_OFFSET_RECT;\n  const offsetParentScrollX = offsetParent?.scrollLeft ?? 0;\n  const offsetParentScrollY = offsetParent?.scrollTop ?? 0;\n\n  // Computed widths and heights have subpixel precision, and are not affected\n  // by distortions.\n  const computedWidth = parseFloat(getComputedStyle(element).width);\n  const computedHeight = parseFloat(getComputedStyle(element).height);\n\n  // We can obtain the current scale factor for the element by comparing \"computed\"\n  // dimensions with the \"real\" ones.\n  const scaleX = computedWidth / rect.width;\n  const scaleY = computedHeight / rect.height;\n  return {\n    element,\n    // To obtain the adjusted values for the position:\n    // 1. Compute the element's position relative to the offset parent.\n    // 2. Correct for the scale factor.\n    // 3. Adjust for the scroll position of the offset parent.\n    top: (rect.top - offsetParentRect?.top) * scaleY + offsetParentScrollY,\n    right: (offsetParentRect?.right - rect.right) * scaleX - offsetParentScrollX,\n    bottom: (offsetParentRect?.bottom - rect.bottom) * scaleY - offsetParentScrollY,\n    left: (rect.left - offsetParentRect?.left) * scaleX + offsetParentScrollX,\n    // Computed dimensions don't need any adjustments.\n    width: computedWidth,\n    height: computedHeight\n  };\n}\nconst POLL_RATE = 100;\n\n/**\n * Tracks the position and dimensions of an element, relative to its offset\n * parent. The element can be changed dynamically.\n *\n * When no element is provided (`null` or `undefined`), the hook will return\n * a \"null\" rect, in which all values are `0` and `element` is `undefined`.\n *\n * **Note:** sometimes, the measurement will fail (see `getElementOffsetRect`'s\n * documentation for more details). When that happens, this hook will attempt\n * to measure again after a frame, and if that fails, it will poll every 100\n * milliseconds until it succeeds.\n */\nexport function useTrackElementOffsetRect(targetElement, deps = []) {\n  const [indicatorPosition, setIndicatorPosition] = useState(NULL_ELEMENT_OFFSET_RECT);\n  const intervalRef = useRef(undefined);\n  const measure = useEvent(() => {\n    // Check that the targetElement is still attached to the DOM, in case\n    // it was removed since the last `measure` call.\n    if (targetElement && targetElement.isConnected) {\n      const elementOffsetRect = getElementOffsetRect(targetElement);\n      if (elementOffsetRect) {\n        setIndicatorPosition(elementOffsetRect);\n        clearInterval(intervalRef.current);\n        return true;\n      }\n    } else {\n      clearInterval(intervalRef.current);\n    }\n    return false;\n  });\n  const setElement = useResizeObserver(() => {\n    if (!measure()) {\n      requestAnimationFrame(() => {\n        if (!measure()) {\n          intervalRef.current = setInterval(measure, POLL_RATE);\n        }\n      });\n    }\n  });\n  useLayoutEffect(() => {\n    setElement(targetElement);\n    if (!targetElement) {\n      setIndicatorPosition(NULL_ELEMENT_OFFSET_RECT);\n    }\n  }, [setElement, targetElement]);\n\n  // Escape hatch to force a remeasurement when something else changes rather\n  // than the target elements' ref or size (for example, the target element\n  // can change its position within the tablist).\n  useLayoutEffect(() => {\n    measure();\n    // `measure` is a stable function, so it's safe to omit it from the deps array.\n    // deps can't be statically analyzed by ESLint\n  }, deps);\n  return indicatorPosition;\n}\n\n/* eslint-enable jsdoc/require-param */"],
  "mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,qBAAkD;AAClD,qBAA4C;AASrC,IAAM,2BAA2B;AAAA,EACtC,SAAS;AAAA,EACT,KAAK;AAAA,EACL,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AACV;AAeO,SAAS,qBAAqB,SAAS;AAK5C,QAAM,OAAO,QAAQ,sBAAsB;AAC3C,MAAI,KAAK,UAAU,KAAK,KAAK,WAAW,GAAG;AACzC;AAAA,EACF;AACA,QAAM,eAAe,QAAQ;AAC7B,QAAM,mBAAmB,cAAc,sBAAsB,KAAK;AAClE,QAAM,sBAAsB,cAAc,cAAc;AACxD,QAAM,sBAAsB,cAAc,aAAa;AAIvD,QAAM,gBAAgB,WAAW,iBAAiB,OAAO,EAAE,KAAK;AAChE,QAAM,iBAAiB,WAAW,iBAAiB,OAAO,EAAE,MAAM;AAIlE,QAAM,SAAS,gBAAgB,KAAK;AACpC,QAAM,SAAS,iBAAiB,KAAK;AACrC,SAAO;AAAA,IACL;AAAA;AAAA;AAAA;AAAA;AAAA,IAKA,MAAM,KAAK,MAAM,kBAAkB,OAAO,SAAS;AAAA,IACnD,QAAQ,kBAAkB,QAAQ,KAAK,SAAS,SAAS;AAAA,IACzD,SAAS,kBAAkB,SAAS,KAAK,UAAU,SAAS;AAAA,IAC5D,OAAO,KAAK,OAAO,kBAAkB,QAAQ,SAAS;AAAA;AAAA,IAEtD,OAAO;AAAA,IACP,QAAQ;AAAA,EACV;AACF;AACA,IAAM,YAAY;AAcX,SAAS,0BAA0B,eAAe,OAAO,CAAC,GAAG;AAClE,QAAM,CAAC,mBAAmB,oBAAoB,QAAI,yBAAS,wBAAwB;AACnF,QAAM,kBAAc,uBAAO,MAAS;AACpC,QAAM,cAAU,yBAAS,MAAM;AAG7B,QAAI,iBAAiB,cAAc,aAAa;AAC9C,YAAM,oBAAoB,qBAAqB,aAAa;AAC5D,UAAI,mBAAmB;AACrB,6BAAqB,iBAAiB;AACtC,sBAAc,YAAY,OAAO;AACjC,eAAO;AAAA,MACT;AAAA,IACF,OAAO;AACL,oBAAc,YAAY,OAAO;AAAA,IACnC;AACA,WAAO;AAAA,EACT,CAAC;AACD,QAAM,iBAAa,kCAAkB,MAAM;AACzC,QAAI,CAAC,QAAQ,GAAG;AACd,4BAAsB,MAAM;AAC1B,YAAI,CAAC,QAAQ,GAAG;AACd,sBAAY,UAAU,YAAY,SAAS,SAAS;AAAA,QACtD;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AACD,sCAAgB,MAAM;AACpB,eAAW,aAAa;AACxB,QAAI,CAAC,eAAe;AAClB,2BAAqB,wBAAwB;AAAA,IAC/C;AAAA,EACF,GAAG,CAAC,YAAY,aAAa,CAAC;AAK9B,sCAAgB,MAAM;AACpB,YAAQ;AAAA,EAGV,GAAG,IAAI;AACP,SAAO;AACT;",
  "names": []
}
