summaryrefslogtreecommitdiff
path: root/node_modules/@floating-ui/dom
diff options
context:
space:
mode:
authorrxliuli <rxliuli@gmail.com>2025-11-04 05:03:50 +0800
committerrxliuli <rxliuli@gmail.com>2025-11-04 05:03:50 +0800
commitbce557cc2dc767628bed6aac87301a1be7c5431b (patch)
treeb51a051228d01fe3306cd7626d4a96768aadb944 /node_modules/@floating-ui/dom
init commit
Diffstat (limited to 'node_modules/@floating-ui/dom')
-rw-r--r--node_modules/@floating-ui/dom/dist/floating-ui.dom.mjs759
1 files changed, 759 insertions, 0 deletions
diff --git a/node_modules/@floating-ui/dom/dist/floating-ui.dom.mjs b/node_modules/@floating-ui/dom/dist/floating-ui.dom.mjs
new file mode 100644
index 0000000..2c1ccbb
--- /dev/null
+++ b/node_modules/@floating-ui/dom/dist/floating-ui.dom.mjs
@@ -0,0 +1,759 @@
+import { rectToClientRect, arrow as arrow$1, autoPlacement as autoPlacement$1, detectOverflow as detectOverflow$1, flip as flip$1, hide as hide$1, inline as inline$1, limitShift as limitShift$1, offset as offset$1, shift as shift$1, size as size$1, computePosition as computePosition$1 } from '@floating-ui/core';
+import { round, createCoords, max, min, floor } from '@floating-ui/utils';
+import { getComputedStyle, isHTMLElement, isElement, getWindow, isWebKit, getFrameElement, getNodeScroll, getDocumentElement, isTopLayer, getNodeName, isOverflowElement, getOverflowAncestors, getParentNode, isLastTraversableNode, isContainingBlock, isTableElement, getContainingBlock } from '@floating-ui/utils/dom';
+export { getOverflowAncestors } from '@floating-ui/utils/dom';
+
+function getCssDimensions(element) {
+ const css = getComputedStyle(element);
+ // In testing environments, the `width` and `height` properties are empty
+ // strings for SVG elements, returning NaN. Fallback to `0` in this case.
+ let width = parseFloat(css.width) || 0;
+ let height = parseFloat(css.height) || 0;
+ const hasOffset = isHTMLElement(element);
+ const offsetWidth = hasOffset ? element.offsetWidth : width;
+ const offsetHeight = hasOffset ? element.offsetHeight : height;
+ const shouldFallback = round(width) !== offsetWidth || round(height) !== offsetHeight;
+ if (shouldFallback) {
+ width = offsetWidth;
+ height = offsetHeight;
+ }
+ return {
+ width,
+ height,
+ $: shouldFallback
+ };
+}
+
+function unwrapElement(element) {
+ return !isElement(element) ? element.contextElement : element;
+}
+
+function getScale(element) {
+ const domElement = unwrapElement(element);
+ if (!isHTMLElement(domElement)) {
+ return createCoords(1);
+ }
+ const rect = domElement.getBoundingClientRect();
+ const {
+ width,
+ height,
+ $
+ } = getCssDimensions(domElement);
+ let x = ($ ? round(rect.width) : rect.width) / width;
+ let y = ($ ? round(rect.height) : rect.height) / height;
+
+ // 0, NaN, or Infinity should always fallback to 1.
+
+ if (!x || !Number.isFinite(x)) {
+ x = 1;
+ }
+ if (!y || !Number.isFinite(y)) {
+ y = 1;
+ }
+ return {
+ x,
+ y
+ };
+}
+
+const noOffsets = /*#__PURE__*/createCoords(0);
+function getVisualOffsets(element) {
+ const win = getWindow(element);
+ if (!isWebKit() || !win.visualViewport) {
+ return noOffsets;
+ }
+ return {
+ x: win.visualViewport.offsetLeft,
+ y: win.visualViewport.offsetTop
+ };
+}
+function shouldAddVisualOffsets(element, isFixed, floatingOffsetParent) {
+ if (isFixed === void 0) {
+ isFixed = false;
+ }
+ if (!floatingOffsetParent || isFixed && floatingOffsetParent !== getWindow(element)) {
+ return false;
+ }
+ return isFixed;
+}
+
+function getBoundingClientRect(element, includeScale, isFixedStrategy, offsetParent) {
+ if (includeScale === void 0) {
+ includeScale = false;
+ }
+ if (isFixedStrategy === void 0) {
+ isFixedStrategy = false;
+ }
+ const clientRect = element.getBoundingClientRect();
+ const domElement = unwrapElement(element);
+ let scale = createCoords(1);
+ if (includeScale) {
+ if (offsetParent) {
+ if (isElement(offsetParent)) {
+ scale = getScale(offsetParent);
+ }
+ } else {
+ scale = getScale(element);
+ }
+ }
+ const visualOffsets = shouldAddVisualOffsets(domElement, isFixedStrategy, offsetParent) ? getVisualOffsets(domElement) : createCoords(0);
+ let x = (clientRect.left + visualOffsets.x) / scale.x;
+ let y = (clientRect.top + visualOffsets.y) / scale.y;
+ let width = clientRect.width / scale.x;
+ let height = clientRect.height / scale.y;
+ if (domElement) {
+ const win = getWindow(domElement);
+ const offsetWin = offsetParent && isElement(offsetParent) ? getWindow(offsetParent) : offsetParent;
+ let currentWin = win;
+ let currentIFrame = getFrameElement(currentWin);
+ while (currentIFrame && offsetParent && offsetWin !== currentWin) {
+ const iframeScale = getScale(currentIFrame);
+ const iframeRect = currentIFrame.getBoundingClientRect();
+ const css = getComputedStyle(currentIFrame);
+ const left = iframeRect.left + (currentIFrame.clientLeft + parseFloat(css.paddingLeft)) * iframeScale.x;
+ const top = iframeRect.top + (currentIFrame.clientTop + parseFloat(css.paddingTop)) * iframeScale.y;
+ x *= iframeScale.x;
+ y *= iframeScale.y;
+ width *= iframeScale.x;
+ height *= iframeScale.y;
+ x += left;
+ y += top;
+ currentWin = getWindow(currentIFrame);
+ currentIFrame = getFrameElement(currentWin);
+ }
+ }
+ return rectToClientRect({
+ width,
+ height,
+ x,
+ y
+ });
+}
+
+// If <html> has a CSS width greater than the viewport, then this will be
+// incorrect for RTL.
+function getWindowScrollBarX(element, rect) {
+ const leftScroll = getNodeScroll(element).scrollLeft;
+ if (!rect) {
+ return getBoundingClientRect(getDocumentElement(element)).left + leftScroll;
+ }
+ return rect.left + leftScroll;
+}
+
+function getHTMLOffset(documentElement, scroll, ignoreScrollbarX) {
+ if (ignoreScrollbarX === void 0) {
+ ignoreScrollbarX = false;
+ }
+ const htmlRect = documentElement.getBoundingClientRect();
+ const x = htmlRect.left + scroll.scrollLeft - (ignoreScrollbarX ? 0 :
+ // RTL <body> scrollbar.
+ getWindowScrollBarX(documentElement, htmlRect));
+ const y = htmlRect.top + scroll.scrollTop;
+ return {
+ x,
+ y
+ };
+}
+
+function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) {
+ let {
+ elements,
+ rect,
+ offsetParent,
+ strategy
+ } = _ref;
+ const isFixed = strategy === 'fixed';
+ const documentElement = getDocumentElement(offsetParent);
+ const topLayer = elements ? isTopLayer(elements.floating) : false;
+ if (offsetParent === documentElement || topLayer && isFixed) {
+ return rect;
+ }
+ let scroll = {
+ scrollLeft: 0,
+ scrollTop: 0
+ };
+ let scale = createCoords(1);
+ const offsets = createCoords(0);
+ const isOffsetParentAnElement = isHTMLElement(offsetParent);
+ if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
+ if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) {
+ scroll = getNodeScroll(offsetParent);
+ }
+ if (isHTMLElement(offsetParent)) {
+ const offsetRect = getBoundingClientRect(offsetParent);
+ scale = getScale(offsetParent);
+ offsets.x = offsetRect.x + offsetParent.clientLeft;
+ offsets.y = offsetRect.y + offsetParent.clientTop;
+ }
+ }
+ const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll, true) : createCoords(0);
+ return {
+ width: rect.width * scale.x,
+ height: rect.height * scale.y,
+ x: rect.x * scale.x - scroll.scrollLeft * scale.x + offsets.x + htmlOffset.x,
+ y: rect.y * scale.y - scroll.scrollTop * scale.y + offsets.y + htmlOffset.y
+ };
+}
+
+function getClientRects(element) {
+ return Array.from(element.getClientRects());
+}
+
+// Gets the entire size of the scrollable document area, even extending outside
+// of the `<html>` and `<body>` rect bounds if horizontally scrollable.
+function getDocumentRect(element) {
+ const html = getDocumentElement(element);
+ const scroll = getNodeScroll(element);
+ const body = element.ownerDocument.body;
+ const width = max(html.scrollWidth, html.clientWidth, body.scrollWidth, body.clientWidth);
+ const height = max(html.scrollHeight, html.clientHeight, body.scrollHeight, body.clientHeight);
+ let x = -scroll.scrollLeft + getWindowScrollBarX(element);
+ const y = -scroll.scrollTop;
+ if (getComputedStyle(body).direction === 'rtl') {
+ x += max(html.clientWidth, body.clientWidth) - width;
+ }
+ return {
+ width,
+ height,
+ x,
+ y
+ };
+}
+
+function getViewportRect(element, strategy) {
+ const win = getWindow(element);
+ const html = getDocumentElement(element);
+ const visualViewport = win.visualViewport;
+ let width = html.clientWidth;
+ let height = html.clientHeight;
+ let x = 0;
+ let y = 0;
+ if (visualViewport) {
+ width = visualViewport.width;
+ height = visualViewport.height;
+ const visualViewportBased = isWebKit();
+ if (!visualViewportBased || visualViewportBased && strategy === 'fixed') {
+ x = visualViewport.offsetLeft;
+ y = visualViewport.offsetTop;
+ }
+ }
+ return {
+ width,
+ height,
+ x,
+ y
+ };
+}
+
+// Returns the inner client rect, subtracting scrollbars if present.
+function getInnerBoundingClientRect(element, strategy) {
+ const clientRect = getBoundingClientRect(element, true, strategy === 'fixed');
+ const top = clientRect.top + element.clientTop;
+ const left = clientRect.left + element.clientLeft;
+ const scale = isHTMLElement(element) ? getScale(element) : createCoords(1);
+ const width = element.clientWidth * scale.x;
+ const height = element.clientHeight * scale.y;
+ const x = left * scale.x;
+ const y = top * scale.y;
+ return {
+ width,
+ height,
+ x,
+ y
+ };
+}
+function getClientRectFromClippingAncestor(element, clippingAncestor, strategy) {
+ let rect;
+ if (clippingAncestor === 'viewport') {
+ rect = getViewportRect(element, strategy);
+ } else if (clippingAncestor === 'document') {
+ rect = getDocumentRect(getDocumentElement(element));
+ } else if (isElement(clippingAncestor)) {
+ rect = getInnerBoundingClientRect(clippingAncestor, strategy);
+ } else {
+ const visualOffsets = getVisualOffsets(element);
+ rect = {
+ x: clippingAncestor.x - visualOffsets.x,
+ y: clippingAncestor.y - visualOffsets.y,
+ width: clippingAncestor.width,
+ height: clippingAncestor.height
+ };
+ }
+ return rectToClientRect(rect);
+}
+function hasFixedPositionAncestor(element, stopNode) {
+ const parentNode = getParentNode(element);
+ if (parentNode === stopNode || !isElement(parentNode) || isLastTraversableNode(parentNode)) {
+ return false;
+ }
+ return getComputedStyle(parentNode).position === 'fixed' || hasFixedPositionAncestor(parentNode, stopNode);
+}
+
+// A "clipping ancestor" is an `overflow` element with the characteristic of
+// clipping (or hiding) child elements. This returns all clipping ancestors
+// of the given element up the tree.
+function getClippingElementAncestors(element, cache) {
+ const cachedResult = cache.get(element);
+ if (cachedResult) {
+ return cachedResult;
+ }
+ let result = getOverflowAncestors(element, [], false).filter(el => isElement(el) && getNodeName(el) !== 'body');
+ let currentContainingBlockComputedStyle = null;
+ const elementIsFixed = getComputedStyle(element).position === 'fixed';
+ let currentNode = elementIsFixed ? getParentNode(element) : element;
+
+ // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
+ while (isElement(currentNode) && !isLastTraversableNode(currentNode)) {
+ const computedStyle = getComputedStyle(currentNode);
+ const currentNodeIsContaining = isContainingBlock(currentNode);
+ if (!currentNodeIsContaining && computedStyle.position === 'fixed') {
+ currentContainingBlockComputedStyle = null;
+ }
+ const shouldDropCurrentNode = elementIsFixed ? !currentNodeIsContaining && !currentContainingBlockComputedStyle : !currentNodeIsContaining && computedStyle.position === 'static' && !!currentContainingBlockComputedStyle && ['absolute', 'fixed'].includes(currentContainingBlockComputedStyle.position) || isOverflowElement(currentNode) && !currentNodeIsContaining && hasFixedPositionAncestor(element, currentNode);
+ if (shouldDropCurrentNode) {
+ // Drop non-containing blocks.
+ result = result.filter(ancestor => ancestor !== currentNode);
+ } else {
+ // Record last containing block for next iteration.
+ currentContainingBlockComputedStyle = computedStyle;
+ }
+ currentNode = getParentNode(currentNode);
+ }
+ cache.set(element, result);
+ return result;
+}
+
+// Gets the maximum area that the element is visible in due to any number of
+// clipping ancestors.
+function getClippingRect(_ref) {
+ let {
+ element,
+ boundary,
+ rootBoundary,
+ strategy
+ } = _ref;
+ const elementClippingAncestors = boundary === 'clippingAncestors' ? isTopLayer(element) ? [] : getClippingElementAncestors(element, this._c) : [].concat(boundary);
+ const clippingAncestors = [...elementClippingAncestors, rootBoundary];
+ const firstClippingAncestor = clippingAncestors[0];
+ const clippingRect = clippingAncestors.reduce((accRect, clippingAncestor) => {
+ const rect = getClientRectFromClippingAncestor(element, clippingAncestor, strategy);
+ accRect.top = max(rect.top, accRect.top);
+ accRect.right = min(rect.right, accRect.right);
+ accRect.bottom = min(rect.bottom, accRect.bottom);
+ accRect.left = max(rect.left, accRect.left);
+ return accRect;
+ }, getClientRectFromClippingAncestor(element, firstClippingAncestor, strategy));
+ return {
+ width: clippingRect.right - clippingRect.left,
+ height: clippingRect.bottom - clippingRect.top,
+ x: clippingRect.left,
+ y: clippingRect.top
+ };
+}
+
+function getDimensions(element) {
+ const {
+ width,
+ height
+ } = getCssDimensions(element);
+ return {
+ width,
+ height
+ };
+}
+
+function getRectRelativeToOffsetParent(element, offsetParent, strategy) {
+ const isOffsetParentAnElement = isHTMLElement(offsetParent);
+ const documentElement = getDocumentElement(offsetParent);
+ const isFixed = strategy === 'fixed';
+ const rect = getBoundingClientRect(element, true, isFixed, offsetParent);
+ let scroll = {
+ scrollLeft: 0,
+ scrollTop: 0
+ };
+ const offsets = createCoords(0);
+
+ // If the <body> scrollbar appears on the left (e.g. RTL systems). Use
+ // Firefox with layout.scrollbar.side = 3 in about:config to test this.
+ function setLeftRTLScrollbarOffset() {
+ offsets.x = getWindowScrollBarX(documentElement);
+ }
+ if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
+ if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) {
+ scroll = getNodeScroll(offsetParent);
+ }
+ if (isOffsetParentAnElement) {
+ const offsetRect = getBoundingClientRect(offsetParent, true, isFixed, offsetParent);
+ offsets.x = offsetRect.x + offsetParent.clientLeft;
+ offsets.y = offsetRect.y + offsetParent.clientTop;
+ } else if (documentElement) {
+ setLeftRTLScrollbarOffset();
+ }
+ }
+ if (isFixed && !isOffsetParentAnElement && documentElement) {
+ setLeftRTLScrollbarOffset();
+ }
+ const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0);
+ const x = rect.left + scroll.scrollLeft - offsets.x - htmlOffset.x;
+ const y = rect.top + scroll.scrollTop - offsets.y - htmlOffset.y;
+ return {
+ x,
+ y,
+ width: rect.width,
+ height: rect.height
+ };
+}
+
+function isStaticPositioned(element) {
+ return getComputedStyle(element).position === 'static';
+}
+
+function getTrueOffsetParent(element, polyfill) {
+ if (!isHTMLElement(element) || getComputedStyle(element).position === 'fixed') {
+ return null;
+ }
+ if (polyfill) {
+ return polyfill(element);
+ }
+ let rawOffsetParent = element.offsetParent;
+
+ // Firefox returns the <html> element as the offsetParent if it's non-static,
+ // while Chrome and Safari return the <body> element. The <body> element must
+ // be used to perform the correct calculations even if the <html> element is
+ // non-static.
+ if (getDocumentElement(element) === rawOffsetParent) {
+ rawOffsetParent = rawOffsetParent.ownerDocument.body;
+ }
+ return rawOffsetParent;
+}
+
+// Gets the closest ancestor positioned element. Handles some edge cases,
+// such as table ancestors and cross browser bugs.
+function getOffsetParent(element, polyfill) {
+ const win = getWindow(element);
+ if (isTopLayer(element)) {
+ return win;
+ }
+ if (!isHTMLElement(element)) {
+ let svgOffsetParent = getParentNode(element);
+ while (svgOffsetParent && !isLastTraversableNode(svgOffsetParent)) {
+ if (isElement(svgOffsetParent) && !isStaticPositioned(svgOffsetParent)) {
+ return svgOffsetParent;
+ }
+ svgOffsetParent = getParentNode(svgOffsetParent);
+ }
+ return win;
+ }
+ let offsetParent = getTrueOffsetParent(element, polyfill);
+ while (offsetParent && isTableElement(offsetParent) && isStaticPositioned(offsetParent)) {
+ offsetParent = getTrueOffsetParent(offsetParent, polyfill);
+ }
+ if (offsetParent && isLastTraversableNode(offsetParent) && isStaticPositioned(offsetParent) && !isContainingBlock(offsetParent)) {
+ return win;
+ }
+ return offsetParent || getContainingBlock(element) || win;
+}
+
+const getElementRects = async function (data) {
+ const getOffsetParentFn = this.getOffsetParent || getOffsetParent;
+ const getDimensionsFn = this.getDimensions;
+ const floatingDimensions = await getDimensionsFn(data.floating);
+ return {
+ reference: getRectRelativeToOffsetParent(data.reference, await getOffsetParentFn(data.floating), data.strategy),
+ floating: {
+ x: 0,
+ y: 0,
+ width: floatingDimensions.width,
+ height: floatingDimensions.height
+ }
+ };
+};
+
+function isRTL(element) {
+ return getComputedStyle(element).direction === 'rtl';
+}
+
+const platform = {
+ convertOffsetParentRelativeRectToViewportRelativeRect,
+ getDocumentElement,
+ getClippingRect,
+ getOffsetParent,
+ getElementRects,
+ getClientRects,
+ getDimensions,
+ getScale,
+ isElement,
+ isRTL
+};
+
+function rectsAreEqual(a, b) {
+ return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;
+}
+
+// https://samthor.au/2021/observing-dom/
+function observeMove(element, onMove) {
+ let io = null;
+ let timeoutId;
+ const root = getDocumentElement(element);
+ function cleanup() {
+ var _io;
+ clearTimeout(timeoutId);
+ (_io = io) == null || _io.disconnect();
+ io = null;
+ }
+ function refresh(skip, threshold) {
+ if (skip === void 0) {
+ skip = false;
+ }
+ if (threshold === void 0) {
+ threshold = 1;
+ }
+ cleanup();
+ const elementRectForRootMargin = element.getBoundingClientRect();
+ const {
+ left,
+ top,
+ width,
+ height
+ } = elementRectForRootMargin;
+ if (!skip) {
+ onMove();
+ }
+ if (!width || !height) {
+ return;
+ }
+ const insetTop = floor(top);
+ const insetRight = floor(root.clientWidth - (left + width));
+ const insetBottom = floor(root.clientHeight - (top + height));
+ const insetLeft = floor(left);
+ const rootMargin = -insetTop + "px " + -insetRight + "px " + -insetBottom + "px " + -insetLeft + "px";
+ const options = {
+ rootMargin,
+ threshold: max(0, min(1, threshold)) || 1
+ };
+ let isFirstUpdate = true;
+ function handleObserve(entries) {
+ const ratio = entries[0].intersectionRatio;
+ if (ratio !== threshold) {
+ if (!isFirstUpdate) {
+ return refresh();
+ }
+ if (!ratio) {
+ // If the reference is clipped, the ratio is 0. Throttle the refresh
+ // to prevent an infinite loop of updates.
+ timeoutId = setTimeout(() => {
+ refresh(false, 1e-7);
+ }, 1000);
+ } else {
+ refresh(false, ratio);
+ }
+ }
+ if (ratio === 1 && !rectsAreEqual(elementRectForRootMargin, element.getBoundingClientRect())) {
+ // It's possible that even though the ratio is reported as 1, the
+ // element is not actually fully within the IntersectionObserver's root
+ // area anymore. This can happen under performance constraints. This may
+ // be a bug in the browser's IntersectionObserver implementation. To
+ // work around this, we compare the element's bounding rect now with
+ // what it was at the time we created the IntersectionObserver. If they
+ // are not equal then the element moved, so we refresh.
+ refresh();
+ }
+ isFirstUpdate = false;
+ }
+
+ // Older browsers don't support a `document` as the root and will throw an
+ // error.
+ try {
+ io = new IntersectionObserver(handleObserve, {
+ ...options,
+ // Handle <iframe>s
+ root: root.ownerDocument
+ });
+ } catch (_e) {
+ io = new IntersectionObserver(handleObserve, options);
+ }
+ io.observe(element);
+ }
+ refresh(true);
+ return cleanup;
+}
+
+/**
+ * Automatically updates the position of the floating element when necessary.
+ * Should only be called when the floating element is mounted on the DOM or
+ * visible on the screen.
+ * @returns cleanup function that should be invoked when the floating element is
+ * removed from the DOM or hidden from the screen.
+ * @see https://floating-ui.com/docs/autoUpdate
+ */
+function autoUpdate(reference, floating, update, options) {
+ if (options === void 0) {
+ options = {};
+ }
+ const {
+ ancestorScroll = true,
+ ancestorResize = true,
+ elementResize = typeof ResizeObserver === 'function',
+ layoutShift = typeof IntersectionObserver === 'function',
+ animationFrame = false
+ } = options;
+ const referenceEl = unwrapElement(reference);
+ const ancestors = ancestorScroll || ancestorResize ? [...(referenceEl ? getOverflowAncestors(referenceEl) : []), ...getOverflowAncestors(floating)] : [];
+ ancestors.forEach(ancestor => {
+ ancestorScroll && ancestor.addEventListener('scroll', update, {
+ passive: true
+ });
+ ancestorResize && ancestor.addEventListener('resize', update);
+ });
+ const cleanupIo = referenceEl && layoutShift ? observeMove(referenceEl, update) : null;
+ let reobserveFrame = -1;
+ let resizeObserver = null;
+ if (elementResize) {
+ resizeObserver = new ResizeObserver(_ref => {
+ let [firstEntry] = _ref;
+ if (firstEntry && firstEntry.target === referenceEl && resizeObserver) {
+ // Prevent update loops when using the `size` middleware.
+ // https://github.com/floating-ui/floating-ui/issues/1740
+ resizeObserver.unobserve(floating);
+ cancelAnimationFrame(reobserveFrame);
+ reobserveFrame = requestAnimationFrame(() => {
+ var _resizeObserver;
+ (_resizeObserver = resizeObserver) == null || _resizeObserver.observe(floating);
+ });
+ }
+ update();
+ });
+ if (referenceEl && !animationFrame) {
+ resizeObserver.observe(referenceEl);
+ }
+ resizeObserver.observe(floating);
+ }
+ let frameId;
+ let prevRefRect = animationFrame ? getBoundingClientRect(reference) : null;
+ if (animationFrame) {
+ frameLoop();
+ }
+ function frameLoop() {
+ const nextRefRect = getBoundingClientRect(reference);
+ if (prevRefRect && !rectsAreEqual(prevRefRect, nextRefRect)) {
+ update();
+ }
+ prevRefRect = nextRefRect;
+ frameId = requestAnimationFrame(frameLoop);
+ }
+ update();
+ return () => {
+ var _resizeObserver2;
+ ancestors.forEach(ancestor => {
+ ancestorScroll && ancestor.removeEventListener('scroll', update);
+ ancestorResize && ancestor.removeEventListener('resize', update);
+ });
+ cleanupIo == null || cleanupIo();
+ (_resizeObserver2 = resizeObserver) == null || _resizeObserver2.disconnect();
+ resizeObserver = null;
+ if (animationFrame) {
+ cancelAnimationFrame(frameId);
+ }
+ };
+}
+
+/**
+ * Resolves with an object of overflow side offsets that determine how much the
+ * element is overflowing a given clipping boundary on each side.
+ * - positive = overflowing the boundary by that number of pixels
+ * - negative = how many pixels left before it will overflow
+ * - 0 = lies flush with the boundary
+ * @see https://floating-ui.com/docs/detectOverflow
+ */
+const detectOverflow = detectOverflow$1;
+
+/**
+ * Modifies the placement by translating the floating element along the
+ * specified axes.
+ * A number (shorthand for `mainAxis` or distance), or an axes configuration
+ * object may be passed.
+ * @see https://floating-ui.com/docs/offset
+ */
+const offset = offset$1;
+
+/**
+ * Optimizes the visibility of the floating element by choosing the placement
+ * that has the most space available automatically, without needing to specify a
+ * preferred placement. Alternative to `flip`.
+ * @see https://floating-ui.com/docs/autoPlacement
+ */
+const autoPlacement = autoPlacement$1;
+
+/**
+ * Optimizes the visibility of the floating element by shifting it in order to
+ * keep it in view when it will overflow the clipping boundary.
+ * @see https://floating-ui.com/docs/shift
+ */
+const shift = shift$1;
+
+/**
+ * Optimizes the visibility of the floating element by flipping the `placement`
+ * in order to keep it in view when the preferred placement(s) will overflow the
+ * clipping boundary. Alternative to `autoPlacement`.
+ * @see https://floating-ui.com/docs/flip
+ */
+const flip = flip$1;
+
+/**
+ * Provides data that allows you to change the size of the floating element —
+ * for instance, prevent it from overflowing the clipping boundary or match the
+ * width of the reference element.
+ * @see https://floating-ui.com/docs/size
+ */
+const size = size$1;
+
+/**
+ * Provides data to hide the floating element in applicable situations, such as
+ * when it is not in the same clipping context as the reference element.
+ * @see https://floating-ui.com/docs/hide
+ */
+const hide = hide$1;
+
+/**
+ * Provides data to position an inner element of the floating element so that it
+ * appears centered to the reference element.
+ * @see https://floating-ui.com/docs/arrow
+ */
+const arrow = arrow$1;
+
+/**
+ * Provides improved positioning for inline reference elements that can span
+ * over multiple lines, such as hyperlinks or range selections.
+ * @see https://floating-ui.com/docs/inline
+ */
+const inline = inline$1;
+
+/**
+ * Built-in `limiter` that will stop `shift()` at a certain point.
+ */
+const limitShift = limitShift$1;
+
+/**
+ * Computes the `x` and `y` coordinates that will place the floating element
+ * next to a given reference element.
+ */
+const computePosition = (reference, floating, options) => {
+ // This caches the expensive `getClippingElementAncestors` function so that
+ // multiple lifecycle resets re-use the same result. It only lives for a
+ // single call. If other functions become expensive, we can add them as well.
+ const cache = new Map();
+ const mergedOptions = {
+ platform,
+ ...options
+ };
+ const platformWithCache = {
+ ...mergedOptions.platform,
+ _c: cache
+ };
+ return computePosition$1(reference, floating, {
+ ...mergedOptions,
+ platform: platformWithCache
+ });
+};
+
+export { arrow, autoPlacement, autoUpdate, computePosition, detectOverflow, flip, hide, inline, limitShift, offset, platform, shift, size };