1// @floating-ui/[email protected] downloaded from https://cdn.jsdelivr.net/npm/@floating-ui/[email protected]/dist/floating-ui.dom.mjs 2 3import { 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'; 4import { round, createCoords, max, min, floor } from '@floating-ui/utils'; 5import { getComputedStyle as getComputedStyle$1, isHTMLElement, isElement, getWindow, isWebKit, getFrameElement, getNodeScroll, getDocumentElement, isTopLayer, getNodeName, isOverflowElement, getOverflowAncestors, getParentNode, isLastTraversableNode, isContainingBlock, isTableElement, getContainingBlock } from '@floating-ui/utils/dom'; 6export { getOverflowAncestors } from '@floating-ui/utils/dom';
vendor: 23,381 bytes, lines 6-680
6 7 8function getCssDimensions(element) { 9 const css = getComputedStyle$1(element); 10 // In testing environments, the `width` and `height` properties are empty 11 // strings for SVG elements, returning NaN. Fallback to `0` in this case. 12 let width = parseFloat(css.width) || 0; 13 let height = parseFloat(css.height) || 0; 14 const hasOffset = isHTMLElement(element); 15 const offsetWidth = hasOffset ? element.offsetWidth : width; 16 const offsetHeight = hasOffset ? element.offsetHeight : height; 17 const shouldFallback = round(width) !== offsetWidth || round(height) !== offsetHeight; 18 if (shouldFallback) { 19 width = offsetWidth; 20 height = offsetHeight; 21 } 22 return { 23 width, 24 height, 25 $: shouldFallback 26 }; 27} 28 29function unwrapElement(element) { 30 return !isElement(element) ? element.contextElement : element; 31} 32 33function getScale(element) { 34 const domElement = unwrapElement(element); 35 if (!isHTMLElement(domElement)) { 36 return createCoords(1); 37 } 38 const rect = domElement.getBoundingClientRect(); 39 const { 40 width, 41 height, 42 $ 43 } = getCssDimensions(domElement); 44 let x = ($ ? round(rect.width) : rect.width) / width; 45 let y = ($ ? round(rect.height) : rect.height) / height; 46 47 // 0, NaN, or Infinity should always fallback to 1. 48 49 if (!x || !Number.isFinite(x)) { 50 x = 1; 51 } 52 if (!y || !Number.isFinite(y)) { 53 y = 1; 54 } 55 return { 56 x, 57 y 58 }; 59} 60 61const noOffsets = /*#__PURE__*/createCoords(0); 62function getVisualOffsets(element) { 63 const win = getWindow(element); 64 if (!isWebKit() || !win.visualViewport) { 65 return noOffsets; 66 } 67 return { 68 x: win.visualViewport.offsetLeft, 69 y: win.visualViewport.offsetTop 70 }; 71} 72function shouldAddVisualOffsets(element, isFixed, floatingOffsetParent) { 73 if (isFixed === void 0) { 74 isFixed = false; 75 } 76 return !!floatingOffsetParent && isFixed && floatingOffsetParent === getWindow(element); 77} 78 79function getBoundingClientRect(element, includeScale, isFixedStrategy, offsetParent) { 80 if (includeScale === void 0) { 81 includeScale = false; 82 } 83 if (isFixedStrategy === void 0) { 84 isFixedStrategy = false; 85 } 86 const clientRect = element.getBoundingClientRect(); 87 const domElement = unwrapElement(element); 88 let scale = createCoords(1); 89 if (includeScale) { 90 if (offsetParent) { 91 if (isElement(offsetParent)) { 92 scale = getScale(offsetParent); 93 } 94 } else { 95 scale = getScale(element); 96 } 97 } 98 const visualOffsets = shouldAddVisualOffsets(domElement, isFixedStrategy, offsetParent) ? getVisualOffsets(domElement) : createCoords(0); 99 let x = (clientRect.left + visualOffsets.x) / scale.x; 100 let y = (clientRect.top + visualOffsets.y) / scale.y; 101 let width = clientRect.width / scale.x; 102 let height = clientRect.height / scale.y; 103 if (domElement && offsetParent) { 104 const win = getWindow(domElement); 105 const offsetWin = isElement(offsetParent) ? getWindow(offsetParent) : offsetParent; 106 let currentWin = win; 107 let currentIFrame = getFrameElement(currentWin); 108 while (currentIFrame && offsetWin !== currentWin) { 109 const iframeScale = getScale(currentIFrame); 110 const iframeRect = currentIFrame.getBoundingClientRect(); 111 const css = getComputedStyle$1(currentIFrame); 112 const left = iframeRect.left + (currentIFrame.clientLeft + parseFloat(css.paddingLeft)) * iframeScale.x; 113 const top = iframeRect.top + (currentIFrame.clientTop + parseFloat(css.paddingTop)) * iframeScale.y; 114 x *= iframeScale.x; 115 y *= iframeScale.y; 116 width *= iframeScale.x; 117 height *= iframeScale.y; 118 x += left; 119 y += top; 120 currentWin = getWindow(currentIFrame); 121 currentIFrame = getFrameElement(currentWin); 122 } 123 } 124 return rectToClientRect({ 125 width, 126 height, 127 x, 128 y 129 }); 130} 131 132// If <html> has a CSS width greater than the viewport, then this will be 133// incorrect for RTL. 134function getWindowScrollBarX(element, rect) { 135 const leftScroll = getNodeScroll(element).scrollLeft; 136 if (!rect) { 137 return getBoundingClientRect(getDocumentElement(element)).left + leftScroll; 138 } 139 return rect.left + leftScroll; 140} 141 142function getHTMLOffset(documentElement, scroll) { 143 const htmlRect = documentElement.getBoundingClientRect(); 144 const x = htmlRect.left + scroll.scrollLeft - getWindowScrollBarX(documentElement, htmlRect); 145 const y = htmlRect.top + scroll.scrollTop; 146 return { 147 x, 148 y 149 }; 150} 151 152function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) { 153 let { 154 elements, 155 rect, 156 offsetParent, 157 strategy 158 } = _ref; 159 const isFixed = strategy === 'fixed'; 160 const documentElement = getDocumentElement(offsetParent); 161 const topLayer = elements ? isTopLayer(elements.floating) : false; 162 if (offsetParent === documentElement || topLayer && isFixed) { 163 return rect; 164 } 165 let scroll = { 166 scrollLeft: 0, 167 scrollTop: 0 168 }; 169 let scale = createCoords(1); 170 const offsets = createCoords(0); 171 const isOffsetParentAnElement = isHTMLElement(offsetParent); 172 if (isOffsetParentAnElement || !isFixed) { 173 if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) { 174 scroll = getNodeScroll(offsetParent); 175 } 176 if (isOffsetParentAnElement) { 177 const offsetRect = getBoundingClientRect(offsetParent); 178 scale = getScale(offsetParent); 179 offsets.x = offsetRect.x + offsetParent.clientLeft; 180 offsets.y = offsetRect.y + offsetParent.clientTop; 181 } 182 } 183 const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0); 184 return { 185 width: rect.width * scale.x, 186 height: rect.height * scale.y, 187 x: rect.x * scale.x - scroll.scrollLeft * scale.x + offsets.x + htmlOffset.x, 188 y: rect.y * scale.y - scroll.scrollTop * scale.y + offsets.y + htmlOffset.y 189 }; 190} 191 192function getClientRects(element) { 193 return element.getClientRects ? Array.from(element.getClientRects()) : []; 194} 195 196// Gets the entire size of the scrollable document area, even extending outside 197// of the `<html>` and `<body>` rect bounds if horizontally scrollable. 198function getDocumentRect(html) { 199 const scroll = getNodeScroll(html); 200 const body = html.ownerDocument.body; 201 const width = max(html.scrollWidth, html.clientWidth, body.scrollWidth, body.clientWidth); 202 const height = max(html.scrollHeight, html.clientHeight, body.scrollHeight, body.clientHeight); 203 let x = -scroll.scrollLeft + getWindowScrollBarX(html); 204 const y = -scroll.scrollTop; 205 if (getComputedStyle$1(body).direction === 'rtl') { 206 x += max(html.clientWidth, body.clientWidth) - width; 207 } 208 return { 209 width, 210 height, 211 x, 212 y 213 }; 214} 215 216// Safety check: ensure the scrollbar space is reasonable in case this 217// calculation is affected by unusual styles. 218// Most scrollbars leave 15-18px of space. 219const SCROLLBAR_MAX = 25; 220function getViewportRect(element, strategy, rootBoundary) { 221 if (rootBoundary === void 0) { 222 rootBoundary = 'viewport'; 223 } 224 const isLayoutViewport = rootBoundary === 'layoutViewport'; 225 const win = getWindow(element); 226 const html = getDocumentElement(element); 227 const visualViewport = win.visualViewport; 228 let width = html.clientWidth; 229 let height = html.clientHeight; 230 let x = 0; 231 let y = 0; 232 if (visualViewport) { 233 // Client coordinates are relative to the layout viewport, except in 234 // WebKit with an `absolute` strategy, where they are relative to the 235 // visual viewport. 236 const layoutRelativeClientCoords = !isWebKit() || strategy === 'fixed'; 237 if (isLayoutViewport) { 238 if (!layoutRelativeClientCoords) { 239 x = -visualViewport.offsetLeft; 240 y = -visualViewport.offsetTop; 241 } 242 } else { 243 width = visualViewport.width; 244 height = visualViewport.height; 245 if (layoutRelativeClientCoords) { 246 x = visualViewport.offsetLeft; 247 y = visualViewport.offsetTop; 248 } 249 } 250 } 251 const windowScrollbarX = getWindowScrollBarX(html); 252 // `scrollbar-gutter: stable` on the <html> reserves gutter space that shrinks 253 // the visual width but isn't reflected in `html.clientWidth`, so subtract it. 254 // Only the inline-end (right) gutter can hold the scrollbar; `both-edges` also 255 // reserves an empty inline-start gutter that clips nothing, so exclude just 256 // the one scrollbar-side gutter â halve the measured (two-gutter) total. A 257 // left-side scrollbar (`windowScrollbarX > 0`) is already handled by 258 // `getHTMLOffset`/`visualViewport.width`; skip it here. 259 if (windowScrollbarX <= 0) { 260 const doc = html.ownerDocument; 261 const body = doc.body; 262 const bodyStyles = getComputedStyle(body); 263 const bodyMarginInline = doc.compatMode === 'CSS1Compat' ? parseFloat(bodyStyles.marginLeft) + parseFloat(bodyStyles.marginRight) || 0 : 0; 264 const reservedWidth = Math.abs(html.clientWidth - body.clientWidth - bodyMarginInline); 265 const gutter = getComputedStyle(html).scrollbarGutter === 'stable both-edges' ? reservedWidth / 2 : reservedWidth; 266 if (gutter <= SCROLLBAR_MAX) { 267 width -= gutter; 268 } 269 } 270 return { 271 width, 272 height, 273 x, 274 y 275 }; 276} 277 278// Returns the inner client rect, subtracting scrollbars if present. 279function getInnerBoundingClientRect(element, strategy) { 280 const clientRect = getBoundingClientRect(element, true, strategy === 'fixed'); 281 const top = clientRect.top + element.clientTop; 282 const left = clientRect.left + element.clientLeft; 283 const scale = getScale(element); 284 const width = element.clientWidth * scale.x; 285 const height = element.clientHeight * scale.y; 286 const x = left * scale.x; 287 const y = top * scale.y; 288 return { 289 width, 290 height, 291 x, 292 y 293 }; 294} 295function getClientRectFromClippingAncestor(element, clippingAncestor, strategy) { 296 let rect; 297 if (clippingAncestor === 'viewport' || clippingAncestor === 'layoutViewport') { 298 rect = getViewportRect(element, strategy, clippingAncestor); 299 } else if (clippingAncestor === 'document') { 300 rect = getDocumentRect(getDocumentElement(element)); 301 } else if (isElement(clippingAncestor)) { 302 rect = getInnerBoundingClientRect(clippingAncestor, strategy); 303 } else { 304 const visualOffsets = getVisualOffsets(element); 305 rect = { 306 x: clippingAncestor.x - visualOffsets.x, 307 y: clippingAncestor.y - visualOffsets.y, 308 width: clippingAncestor.width, 309 height: clippingAncestor.height 310 }; 311 } 312 return rectToClientRect(rect); 313} 314 315// A "clipping ancestor" is an `overflow` element with the characteristic of 316// clipping (or hiding) child elements. This returns all clipping ancestors 317// of the given element up the tree. 318function getClippingElementAncestors(element, cache) { 319 const cachedResult = cache.get(element); 320 if (cachedResult) { 321 return cachedResult; 322 } 323 let result = getOverflowAncestors(element, [], false).filter(el => isElement(el) && getNodeName(el) !== 'body'); 324 let lastKeptComputedStyle = null; 325 const elementIsFixed = getComputedStyle$1(element).position === 'fixed'; 326 let currentNode = elementIsFixed ? getParentNode(element) : element; 327 328 // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block 329 while (isElement(currentNode) && !isLastTraversableNode(currentNode)) { 330 const computedStyle = getComputedStyle$1(currentNode); 331 const currentNodeIsContaining = isContainingBlock(currentNode); 332 // Position of the containing block chain below the current node. A fixed 333 // element whose containing block hasn't been found yet is a fixed chain. 334 const lastPosition = lastKeptComputedStyle ? lastKeptComputedStyle.position : elementIsFixed ? 'fixed' : ''; 335 336 // A non-containing ancestor does not clip the element when the chain 337 // below it escapes it: a fixed chain escapes all ancestors up to the 338 // next containing block, an absolute chain escapes static ancestors. 339 const shouldDropCurrentNode = !currentNodeIsContaining && (lastPosition === 'fixed' || lastPosition === 'absolute' && computedStyle.position === 'static'); 340 if (shouldDropCurrentNode) { 341 // Drop non-containing blocks. 342 result = result.filter(ancestor => ancestor !== currentNode); 343 } else { 344 // The kept node carries the chain position for the next iteration. 345 lastKeptComputedStyle = computedStyle; 346 } 347 currentNode = getParentNode(currentNode); 348 } 349 cache.set(element, result); 350 return result; 351} 352 353// Gets the maximum area that the element is visible in due to any number of 354// clipping ancestors. 355function getClippingRect(_ref) { 356 let { 357 element, 358 boundary, 359 rootBoundary, 360 strategy 361 } = _ref; 362 const elementClippingAncestors = boundary === 'clippingAncestors' ? isTopLayer(element) ? [] : getClippingElementAncestors(element, this._c) : [].concat(boundary); 363 const clippingAncestors = [...elementClippingAncestors, rootBoundary]; 364 const firstRect = getClientRectFromClippingAncestor(element, clippingAncestors[0], strategy); 365 let top = firstRect.top; 366 let right = firstRect.right; 367 let bottom = firstRect.bottom; 368 let left = firstRect.left; 369 for (let i = 1; i < clippingAncestors.length; i++) { 370 const rect = getClientRectFromClippingAncestor(element, clippingAncestors[i], strategy); 371 top = max(rect.top, top); 372 right = min(rect.right, right); 373 bottom = min(rect.bottom, bottom); 374 left = max(rect.left, left); 375 } 376 return { 377 width: right - left, 378 height: bottom - top, 379 x: left, 380 y: top 381 }; 382} 383 384function getDimensions(element) { 385 const { 386 width, 387 height 388 } = getCssDimensions(element); 389 return { 390 width, 391 height 392 }; 393} 394 395function getRectRelativeToOffsetParent(element, offsetParent, strategy) { 396 const isOffsetParentAnElement = isHTMLElement(offsetParent); 397 const documentElement = getDocumentElement(offsetParent); 398 const isFixed = strategy === 'fixed'; 399 const rect = getBoundingClientRect(element, true, isFixed, offsetParent); 400 let scroll = { 401 scrollLeft: 0, 402 scrollTop: 0 403 }; 404 const offsets = createCoords(0); 405 if (isOffsetParentAnElement || !isFixed) { 406 if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) { 407 scroll = getNodeScroll(offsetParent); 408 } 409 if (isOffsetParentAnElement) { 410 const offsetRect = getBoundingClientRect(offsetParent, true, isFixed, offsetParent); 411 offsets.x = offsetRect.x + offsetParent.clientLeft; 412 offsets.y = offsetRect.y + offsetParent.clientTop; 413 } 414 } 415 416 // If the <body> scrollbar appears on the left (e.g. RTL systems). Use 417 // Firefox with layout.scrollbar.side = 3 in about:config to test this. 418 if (!isOffsetParentAnElement && documentElement) { 419 offsets.x = getWindowScrollBarX(documentElement); 420 } 421 const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0); 422 const x = rect.left + scroll.scrollLeft - offsets.x - htmlOffset.x; 423 const y = rect.top + scroll.scrollTop - offsets.y - htmlOffset.y; 424 return { 425 x, 426 y, 427 width: rect.width, 428 height: rect.height 429 }; 430} 431 432function isStaticPositioned(element) { 433 return getComputedStyle$1(element).position === 'static'; 434} 435 436function getTrueOffsetParent(element, polyfill) { 437 if (!isHTMLElement(element) || getComputedStyle$1(element).position === 'fixed') { 438 return null; 439 } 440 if (polyfill) { 441 return polyfill(element); 442 } 443 let rawOffsetParent = element.offsetParent; 444 445 // Firefox returns the <html> element as the offsetParent if it's non-static, 446 // while Chrome and Safari return the <body> element. The <body> element must 447 // be used to perform the correct calculations even if the <html> element is 448 // non-static. 449 if (getDocumentElement(element) === rawOffsetParent) { 450 rawOffsetParent = rawOffsetParent.ownerDocument.body; 451 } 452 return rawOffsetParent; 453} 454 455// Gets the closest ancestor positioned element. Handles some edge cases, 456// such as table ancestors and cross browser bugs. 457function getOffsetParent(element, polyfill) { 458 const win = getWindow(element); 459 if (isTopLayer(element)) { 460 return win; 461 } 462 if (!isHTMLElement(element)) { 463 let svgOffsetParent = getParentNode(element); 464 while (svgOffsetParent && !isLastTraversableNode(svgOffsetParent)) { 465 if (isElement(svgOffsetParent) && !isStaticPositioned(svgOffsetParent)) { 466 return svgOffsetParent; 467 } 468 svgOffsetParent = getParentNode(svgOffsetParent); 469 } 470 return win; 471 } 472 let offsetParent = getTrueOffsetParent(element, polyfill); 473 while (offsetParent && isTableElement(offsetParent) && isStaticPositioned(offsetParent)) { 474 offsetParent = getTrueOffsetParent(offsetParent, polyfill); 475 } 476 if (offsetParent && isLastTraversableNode(offsetParent) && isStaticPositioned(offsetParent) && !isContainingBlock(offsetParent)) { 477 return win; 478 } 479 return offsetParent || getContainingBlock(element) || win; 480} 481 482const getElementRects = async function (data) { 483 const getOffsetParentFn = this.getOffsetParent || getOffsetParent; 484 const getDimensionsFn = this.getDimensions; 485 const floatingDimensions = await getDimensionsFn(data.floating); 486 return { 487 reference: getRectRelativeToOffsetParent(data.reference, await getOffsetParentFn(data.floating), data.strategy), 488 floating: { 489 x: 0, 490 y: 0, 491 width: floatingDimensions.width, 492 height: floatingDimensions.height 493 } 494 }; 495}; 496 497function isRTL(element) { 498 return getComputedStyle$1(element).direction === 'rtl'; 499} 500 501const platform = { 502 convertOffsetParentRelativeRectToViewportRelativeRect, 503 getDocumentElement, 504 getClippingRect, 505 getOffsetParent, 506 getElementRects, 507 getClientRects, 508 getDimensions, 509 getScale, 510 isElement, 511 isRTL 512}; 513 514function rectsAreEqual(a, b) { 515 return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height; 516} 517 518// https://samthor.au/2021/observing-dom/ 519function observeMove(element, onMove, ancestorResize) { 520 let io = null; 521 let timeoutId; 522 const root = getDocumentElement(element); 523 function cleanup() { 524 var _io; 525 clearTimeout(timeoutId); 526 (_io = io) == null || _io.disconnect(); 527 io = null; 528 } 529 function refresh(skip, threshold) { 530 if (skip === void 0) { 531 skip = false; 532 } 533 if (threshold === void 0) { 534 threshold = 1; 535 } 536 cleanup(); 537 const elementRectForRootMargin = element.getBoundingClientRect(); 538 const { 539 left, 540 top, 541 width, 542 height 543 } = elementRectForRootMargin; 544 if (!skip) { 545 onMove(); 546 } 547 if (!width || !height) { 548 return; 549 } 550 const insetTop = floor(top); 551 const insetRight = floor(root.clientWidth - (left + width)); 552 const insetBottom = floor(root.clientHeight - (top + height)); 553 const insetLeft = floor(left); 554 const rootMargin = -insetTop + "px " + -insetRight + "px " + -insetBottom + "px " + -insetLeft + "px"; 555 const options = { 556 rootMargin, 557 threshold: max(0, min(1, threshold)) || 1 558 }; 559 let isFirstUpdate = true; 560 function handleObserve(entries) { 561 const ratio = entries[0].intersectionRatio; 562 563 // The entry is a snapshot, so the reference may have moved since the 564 // intersection was computed (under performance constraints, or between 565 // consecutive frames of a multi-frame layout shift). The reported ratio 566 // and the observed area are stale in that case and cannot be trusted to 567 // detect subsequent movement, so refresh regardless of the ratio. 568 if (!rectsAreEqual(elementRectForRootMargin, element.getBoundingClientRect())) { 569 return refresh(); 570 } 571 if (ratio !== threshold) { 572 if (!isFirstUpdate) { 573 return refresh(); 574 } 575 if (!ratio) { 576 // If the reference is clipped in place, the ratio is 0. Throttle 577 // the refresh to prevent an infinite loop of updates. 578 timeoutId = setTimeout(() => { 579 refresh(false, 1e-7); 580 }, 1000); 581 } else { 582 refresh(false, ratio); 583 } 584 } 585 isFirstUpdate = false; 586 } 587 588 // Older browsers don't support a `document` as the root and will throw an 589 // error. 590 try { 591 io = new IntersectionObserver(handleObserve, { 592 ...options, 593 // Handle <iframe>s 594 root: root.ownerDocument 595 }); 596 } catch (_e) { 597 io = new IntersectionObserver(handleObserve, options); 598 } 599 io.observe(element); 600 } 601 const win = getWindow(element); 602 // The window is a resize ancestor, so when `ancestorResize` is enabled its 603 // listener already runs the update on resize. Here we only need to rebuild 604 // the `IntersectionObserver` for the new root size, skipping a redundant 605 // update. When `ancestorResize` is disabled, this becomes the sole update. 606 const handleResize = () => refresh(ancestorResize); 607 win.addEventListener('resize', handleResize); 608 refresh(true); 609 return () => { 610 win.removeEventListener('resize', handleResize); 611 cleanup(); 612 }; 613} 614 615/** 616 * Automatically updates the position of the floating element when necessary. 617 * Should only be called when the floating element is mounted on the DOM or 618 * visible on the screen. 619 * @returns cleanup function that should be invoked when the floating element is 620 * removed from the DOM or hidden from the screen. 621 * @see https://floating-ui.com/docs/autoUpdate 622 */ 623function autoUpdate(reference, floating, update, options) { 624 if (options === void 0) { 625 options = {}; 626 } 627 const { 628 ancestorScroll = true, 629 ancestorResize = true, 630 elementResize = typeof ResizeObserver === 'function', 631 layoutShift = typeof IntersectionObserver === 'function', 632 animationFrame = false 633 } = options; 634 const referenceEl = unwrapElement(reference); 635 const ancestors = ancestorScroll || ancestorResize ? [...(referenceEl ? getOverflowAncestors(referenceEl) : []), ...(floating ? getOverflowAncestors(floating) : [])] : []; 636 ancestors.forEach(ancestor => { 637 ancestorScroll && ancestor.addEventListener('scroll', update); 638 ancestorResize && ancestor.addEventListener('resize', update); 639 }); 640 const cleanupIo = referenceEl && layoutShift ? observeMove(referenceEl, update, ancestorResize) : null; 641 let reobserveFrame = -1; 642 let resizeObserver = null; 643 if (elementResize) { 644 resizeObserver = new ResizeObserver(_ref => { 645 let [firstEntry] = _ref; 646 if (firstEntry && firstEntry.target === referenceEl && resizeObserver && floating) { 647 // Prevent update loops when using the `size` middleware. 648 // https://github.com/floating-ui/floating-ui/issues/1740 649 resizeObserver.unobserve(floating); 650 cancelAnimationFrame(reobserveFrame); 651 reobserveFrame = requestAnimationFrame(() => { 652 var _resizeObserver; 653 (_resizeObserver = resizeObserver) == null || _resizeObserver.observe(floating); 654 }); 655 } 656 update(); 657 }); 658 if (referenceEl && !animationFrame) { 659 resizeObserver.observe(referenceEl); 660 } 661 if (floating) { 662 resizeObserver.observe(floating); 663 } 664 } 665 let frameId; 666 let prevRefRect = animationFrame ? getBoundingClientRect(reference) : null; 667 if (animationFrame) { 668 frameLoop(); 669 } 670 function frameLoop() { 671 const nextRefRect = getBoundingClientRect(reference); 672 if (prevRefRect && !rectsAreEqual(prevRefRect, nextRefRect)) { 673 update(); 674 } 675 prevRefRect = nextRefRect; 676 frameId = requestAnimationFrame(frameLoop); 677 } 678 update(); 679 return () => { 680 var _resizeObserver2;
vendor: 3,779 bytes, lines 681-791
681 ancestors.forEach(ancestor => { 682 ancestorScroll && ancestor.removeEventListener('scroll', update); 683 ancestorResize && ancestor.removeEventListener('resize', update); 684 }); 685 cleanupIo == null || cleanupIo(); 686 (_resizeObserver2 = resizeObserver) == null || _resizeObserver2.disconnect(); 687 resizeObserver = null; 688 if (animationFrame) { 689 cancelAnimationFrame(frameId); 690 } 691 }; 692} 693 694/** 695 * Resolves with an object of overflow side offsets that determine how much the 696 * element is overflowing a given clipping boundary on each side. 697 * - positive = overflowing the boundary by that number of pixels 698 * - negative = how many pixels left before it will overflow 699 * - 0 = lies flush with the boundary 700 * @see https://floating-ui.com/docs/detectOverflow 701 */ 702const detectOverflow = detectOverflow$1; 703 704/** 705 * Modifies the placement by translating the floating element along the 706 * specified axes. 707 * A number (shorthand for `mainAxis` or distance), or an axes configuration 708 * object may be passed. 709 * @see https://floating-ui.com/docs/offset 710 */ 711const offset = offset$1; 712 713/** 714 * Optimizes the visibility of the floating element by choosing the placement 715 * that has the most space available automatically, without needing to specify a 716 * preferred placement. Alternative to `flip`. 717 * @see https://floating-ui.com/docs/autoPlacement 718 */ 719const autoPlacement = autoPlacement$1; 720 721/** 722 * Optimizes the visibility of the floating element by shifting it in order to 723 * keep it in view when it will overflow the clipping boundary. 724 * @see https://floating-ui.com/docs/shift 725 */ 726const shift = shift$1; 727 728/** 729 * Optimizes the visibility of the floating element by flipping the `placement` 730 * in order to keep it in view when the preferred placement(s) will overflow the 731 * clipping boundary. Alternative to `autoPlacement`. 732 * @see https://floating-ui.com/docs/flip 733 */ 734const flip = flip$1; 735 736/** 737 * Provides data that allows you to change the size of the floating element â 738 * for instance, prevent it from overflowing the clipping boundary or match the 739 * width of the reference element. 740 * @see https://floating-ui.com/docs/size 741 */ 742const size = size$1; 743 744/** 745 * Provides data to hide the floating element in applicable situations, such as 746 * when it is not in the same clipping context as the reference element. 747 * @see https://floating-ui.com/docs/hide 748 */ 749const hide = hide$1; 750 751/** 752 * Provides data to position an inner element of the floating element so that it 753 * appears centered to the reference element. 754 * @see https://floating-ui.com/docs/arrow 755 */ 756const arrow = arrow$1; 757 758/** 759 * Provides improved positioning for inline reference elements that can span 760 * over multiple lines, such as hyperlinks or range selections. 761 * @see https://floating-ui.com/docs/inline 762 */ 763const inline = inline$1; 764 765/** 766 * Built-in `limiter` that will stop `shift()` at a certain point. 767 */ 768const limitShift = limitShift$1; 769 770/** 771 * Computes the `x` and `y` coordinates that will place the floating element 772 * next to a given reference element. 773 */ 774const computePosition = (reference, floating, options) => { 775 // This caches the expensive `getClippingElementAncestors` function so that 776 // multiple lifecycle resets re-use the same result. It only lives for a 777 // single call. If other functions become expensive, we can add them as well. 778 const cache = new Map(); 779 const mergedOptions = options != null ? options : {}; 780 const platformWithCache = { 781 ...platform, 782 ...mergedOptions.platform, 783 _c: cache 784 }; 785 return computePosition$1(reference, floating, { 786 ...mergedOptions, 787 platform: platformWithCache 788 }); 789}; 790 791export { arrow, autoPlacement, autoUpdate, computePosition, detectOverflow, flip, hide, inline, limitShift, offset, platform, shift, size };
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.