vendor: 9,993 bytes, lines 1-323
1(function (global, factory) { 2 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : 3 typeof define === 'function' && define.amd ? define(['exports'], factory) : 4 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.FloatingUICore = {})); 5})(this, (function (exports) { 'use strict'; 6 7 function getAlignment(placement) { 8 return placement.split('-')[1]; 9 } 10 11 function getLengthFromAxis(axis) { 12 return axis === 'y' ? 'height' : 'width'; 13 } 14 15 function getSide(placement) { 16 return placement.split('-')[0]; 17 } 18 19 function getMainAxisFromPlacement(placement) { 20 return ['top', 'bottom'].includes(getSide(placement)) ? 'x' : 'y'; 21 } 22 23 function computeCoordsFromPlacement(_ref, placement, rtl) { 24 let { 25 reference, 26 floating 27 } = _ref; 28 const commonX = reference.x + reference.width / 2 - floating.width / 2; 29 const commonY = reference.y + reference.height / 2 - floating.height / 2; 30 const mainAxis = getMainAxisFromPlacement(placement); 31 const length = getLengthFromAxis(mainAxis); 32 const commonAlign = reference[length] / 2 - floating[length] / 2; 33 const side = getSide(placement); 34 const isVertical = mainAxis === 'x'; 35 let coords; 36 switch (side) { 37 case 'top': 38 coords = { 39 x: commonX, 40 y: reference.y - floating.height 41 }; 42 break; 43 case 'bottom': 44 coords = { 45 x: commonX, 46 y: reference.y + reference.height 47 }; 48 break; 49 case 'right': 50 coords = { 51 x: reference.x + reference.width, 52 y: commonY 53 }; 54 break; 55 case 'left': 56 coords = { 57 x: reference.x - floating.width, 58 y: commonY 59 }; 60 break; 61 default: 62 coords = { 63 x: reference.x, 64 y: reference.y 65 }; 66 } 67 switch (getAlignment(placement)) { 68 case 'start': 69 coords[mainAxis] -= commonAlign * (rtl && isVertical ? -1 : 1); 70 break; 71 case 'end': 72 coords[mainAxis] += commonAlign * (rtl && isVertical ? -1 : 1); 73 break; 74 } 75 return coords; 76 } 77 78 /** 79 * Computes the `x` and `y` coordinates that will place the floating element 80 * next to a reference element when it is given a certain positioning strategy. 81 * 82 * This export does not have any `platform` interface logic. You will need to 83 * write one for the platform you are using Floating UI with. 84 */ 85 const computePosition = async (reference, floating, config) => { 86 const { 87 placement = 'bottom', 88 strategy = 'absolute', 89 middleware = [], 90 platform 91 } = config; 92 const validMiddleware = middleware.filter(Boolean); 93 const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(floating)); 94 let rects = await platform.getElementRects({ 95 reference, 96 floating, 97 strategy 98 }); 99 let { 100 x, 101 y 102 } = computeCoordsFromPlacement(rects, placement, rtl); 103 let statefulPlacement = placement; 104 let middlewareData = {}; 105 let resetCount = 0; 106 for (let i = 0; i < validMiddleware.length; i++) { 107 const { 108 name, 109 fn 110 } = validMiddleware[i]; 111 const { 112 x: nextX, 113 y: nextY, 114 data, 115 reset 116 } = await fn({ 117 x, 118 y, 119 initialPlacement: placement, 120 placement: statefulPlacement, 121 strategy, 122 middlewareData, 123 rects, 124 platform, 125 elements: { 126 reference, 127 floating 128 } 129 }); 130 x = nextX != null ? nextX : x; 131 y = nextY != null ? nextY : y; 132 middlewareData = { 133 ...middlewareData, 134 [name]: { 135 ...middlewareData[name], 136 ...data 137 } 138 }; 139 if (reset && resetCount <= 50) { 140 resetCount++; 141 if (typeof reset === 'object') { 142 if (reset.placement) { 143 statefulPlacement = reset.placement; 144 } 145 if (reset.rects) { 146 rects = reset.rects === true ? await platform.getElementRects({ 147 reference, 148 floating, 149 strategy 150 }) : reset.rects; 151 } 152 ({ 153 x, 154 y 155 } = computeCoordsFromPlacement(rects, statefulPlacement, rtl)); 156 } 157 i = -1; 158 continue; 159 } 160 } 161 return { 162 x, 163 y, 164 placement: statefulPlacement, 165 strategy, 166 middlewareData 167 }; 168 }; 169 170 function evaluate(value, param) { 171 return typeof value === 'function' ? value(param) : value; 172 } 173 174 function expandPaddingObject(padding) { 175 return { 176 top: 0, 177 right: 0, 178 bottom: 0, 179 left: 0, 180 ...padding 181 }; 182 } 183 184 function getSideObjectFromPadding(padding) { 185 return typeof padding !== 'number' ? expandPaddingObject(padding) : { 186 top: padding, 187 right: padding, 188 bottom: padding, 189 left: padding 190 }; 191 } 192 193 function rectToClientRect(rect) { 194 return { 195 ...rect, 196 top: rect.y, 197 left: rect.x, 198 right: rect.x + rect.width, 199 bottom: rect.y + rect.height 200 }; 201 } 202 203 /** 204 * Resolves with an object of overflow side offsets that determine how much the 205 * element is overflowing a given clipping boundary on each side. 206 * - positive = overflowing the boundary by that number of pixels 207 * - negative = how many pixels left before it will overflow 208 * - 0 = lies flush with the boundary 209 * @see https://floating-ui.com/docs/detectOverflow 210 */ 211 async function detectOverflow(state, options) { 212 var _await$platform$isEle; 213 if (options === void 0) { 214 options = {}; 215 } 216 const { 217 x, 218 y, 219 platform, 220 rects, 221 elements, 222 strategy 223 } = state; 224 const { 225 boundary = 'clippingAncestors', 226 rootBoundary = 'viewport', 227 elementContext = 'floating', 228 altBoundary = false, 229 padding = 0 230 } = evaluate(options, state); 231 const paddingObject = getSideObjectFromPadding(padding); 232 const altContext = elementContext === 'floating' ? 'reference' : 'floating'; 233 const element = elements[altBoundary ? altContext : elementContext]; 234 const clippingClientRect = rectToClientRect(await platform.getClippingRect({ 235 element: ((_await$platform$isEle = await (platform.isElement == null ? void 0 : platform.isElement(element))) != null ? _await$platform$isEle : true) ? element : element.contextElement || (await (platform.getDocumentElement == null ? void 0 : platform.getDocumentElement(elements.floating))), 236 boundary, 237 rootBoundary, 238 strategy 239 })); 240 const rect = elementContext === 'floating' ? { 241 ...rects.floating, 242 x, 243 y 244 } : rects.reference; 245 const offsetParent = await (platform.getOffsetParent == null ? void 0 : platform.getOffsetParent(elements.floating)); 246 const offsetScale = (await (platform.isElement == null ? void 0 : platform.isElement(offsetParent))) ? (await (platform.getScale == null ? void 0 : platform.getScale(offsetParent))) || { 247 x: 1, 248 y: 1 249 } : { 250 x: 1, 251 y: 1 252 }; 253 const elementClientRect = rectToClientRect(platform.convertOffsetParentRelativeRectToViewportRelativeRect ? await platform.convertOffsetParentRelativeRectToViewportRelativeRect({ 254 rect, 255 offsetParent, 256 strategy 257 }) : rect); 258 return { 259 top: (clippingClientRect.top - elementClientRect.top + paddingObject.top) / offsetScale.y, 260 bottom: (elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom) / offsetScale.y, 261 left: (clippingClientRect.left - elementClientRect.left + paddingObject.left) / offsetScale.x, 262 right: (elementClientRect.right - clippingClientRect.right + paddingObject.right) / offsetScale.x 263 }; 264 } 265 266 const min = Math.min; 267 const max = Math.max; 268 269 function within(min$1, value, max$1) { 270 return max(min$1, min(value, max$1)); 271 } 272 273 /** 274 * Provides data to position an inner element of the floating element so that it 275 * appears centered to the reference element. 276 * @see https://floating-ui.com/docs/arrow 277 */ 278 const arrow = options => ({ 279 name: 'arrow', 280 options, 281 async fn(state) { 282 const { 283 x, 284 y, 285 placement, 286 rects, 287 platform, 288 elements 289 } = state; 290 // Since `element` is required, we don't Partial<> the type. 291 const { 292 element, 293 padding = 0 294 } = evaluate(options, state) || {}; 295 if (element == null) { 296 return {}; 297 } 298 const paddingObject = getSideObjectFromPadding(padding); 299 const coords = { 300 x, 301 y 302 }; 303 const axis = getMainAxisFromPlacement(placement); 304 const length = getLengthFromAxis(axis); 305 const arrowDimensions = await platform.getDimensions(element); 306 const isYAxis = axis === 'y'; 307 const minProp = isYAxis ? 'top' : 'left'; 308 const maxProp = isYAxis ? 'bottom' : 'right'; 309 const clientProp = isYAxis ? 'clientHeight' : 'clientWidth'; 310 const endDiff = rects.reference[length] + rects.reference[axis] - coords[axis] - rects.floating[length]; 311 const startDiff = coords[axis] - rects.reference[axis]; 312 const arrowOffsetParent = await (platform.getOffsetParent == null ? void 0 : platform.getOffsetParent(element)); 313 let clientSize = arrowOffsetParent ? arrowOffsetParent[clientProp] : 0; 314 315 // DOM platform can return `window` as the `offsetParent`. 316 if (!clientSize || !(await (platform.isElement == null ? void 0 : platform.isElement(arrowOffsetParent)))) { 317 clientSize = elements.floating[clientProp] || rects.floating[length]; 318 } 319 const centerToReference = endDiff / 2 - startDiff / 2; 320 321 // If the padding is large enough that it causes the arrow to no longer be 322 // centered, modify the padding so that it is centered. 323 const largestPossiblePadding = clientSize / 2 - arrowDimensions[length] / 2 - 1;
vendor: 29,499 bytes, lines 324-1152
324 const minPadding = min(paddingObject[minProp], largestPossiblePadding); 325 const maxPadding = min(paddingObject[maxProp], largestPossiblePadding); 326 327 // Make sure the arrow doesn't overflow the floating element if the center 328 // point is outside the floating element's bounds. 329 const min$1 = minPadding; 330 const max = clientSize - arrowDimensions[length] - maxPadding; 331 const center = clientSize / 2 - arrowDimensions[length] / 2 + centerToReference; 332 const offset = within(min$1, center, max); 333 334 // If the reference is small enough that the arrow's padding causes it to 335 // to point to nothing for an aligned placement, adjust the offset of the 336 // floating element itself. This stops `shift()` from taking action, but can 337 // be worked around by calling it again after the `arrow()` if desired. 338 const shouldAddOffset = getAlignment(placement) != null && center != offset && rects.reference[length] / 2 - (center < min$1 ? minPadding : maxPadding) - arrowDimensions[length] / 2 < 0; 339 const alignmentOffset = shouldAddOffset ? center < min$1 ? min$1 - center : max - center : 0; 340 return { 341 [axis]: coords[axis] - alignmentOffset, 342 data: { 343 [axis]: offset, 344 centerOffset: center - offset + alignmentOffset 345 } 346 }; 347 } 348 }); 349 350 const sides = ['top', 'right', 'bottom', 'left']; 351 const allPlacements = /*#__PURE__*/sides.reduce((acc, side) => acc.concat(side, side + "-start", side + "-end"), []); 352 353 const oppositeSideMap = { 354 left: 'right', 355 right: 'left', 356 bottom: 'top', 357 top: 'bottom' 358 }; 359 function getOppositePlacement(placement) { 360 return placement.replace(/left|right|bottom|top/g, side => oppositeSideMap[side]); 361 } 362 363 function getAlignmentSides(placement, rects, rtl) { 364 if (rtl === void 0) { 365 rtl = false; 366 } 367 const alignment = getAlignment(placement); 368 const mainAxis = getMainAxisFromPlacement(placement); 369 const length = getLengthFromAxis(mainAxis); 370 let mainAlignmentSide = mainAxis === 'x' ? alignment === (rtl ? 'end' : 'start') ? 'right' : 'left' : alignment === 'start' ? 'bottom' : 'top'; 371 if (rects.reference[length] > rects.floating[length]) { 372 mainAlignmentSide = getOppositePlacement(mainAlignmentSide); 373 } 374 return { 375 main: mainAlignmentSide, 376 cross: getOppositePlacement(mainAlignmentSide) 377 }; 378 } 379 380 const oppositeAlignmentMap = { 381 start: 'end', 382 end: 'start' 383 }; 384 function getOppositeAlignmentPlacement(placement) { 385 return placement.replace(/start|end/g, alignment => oppositeAlignmentMap[alignment]); 386 } 387 388 function getPlacementList(alignment, autoAlignment, allowedPlacements) { 389 const allowedPlacementsSortedByAlignment = alignment ? [...allowedPlacements.filter(placement => getAlignment(placement) === alignment), ...allowedPlacements.filter(placement => getAlignment(placement) !== alignment)] : allowedPlacements.filter(placement => getSide(placement) === placement); 390 return allowedPlacementsSortedByAlignment.filter(placement => { 391 if (alignment) { 392 return getAlignment(placement) === alignment || (autoAlignment ? getOppositeAlignmentPlacement(placement) !== placement : false); 393 } 394 return true; 395 }); 396 } 397 /** 398 * Optimizes the visibility of the floating element by choosing the placement 399 * that has the most space available automatically, without needing to specify a 400 * preferred placement. Alternative to `flip`. 401 * @see https://floating-ui.com/docs/autoPlacement 402 */ 403 const autoPlacement = function (options) { 404 if (options === void 0) { 405 options = {}; 406 } 407 return { 408 name: 'autoPlacement', 409 options, 410 async fn(state) { 411 var _middlewareData$autoP, _middlewareData$autoP2, _placementsThatFitOnE; 412 const { 413 rects, 414 middlewareData, 415 placement, 416 platform, 417 elements 418 } = state; 419 const { 420 crossAxis = false, 421 alignment, 422 allowedPlacements = allPlacements, 423 autoAlignment = true, 424 ...detectOverflowOptions 425 } = evaluate(options, state); 426 const placements = alignment !== undefined || allowedPlacements === allPlacements ? getPlacementList(alignment || null, autoAlignment, allowedPlacements) : allowedPlacements; 427 const overflow = await detectOverflow(state, detectOverflowOptions); 428 const currentIndex = ((_middlewareData$autoP = middlewareData.autoPlacement) == null ? void 0 : _middlewareData$autoP.index) || 0; 429 const currentPlacement = placements[currentIndex]; 430 if (currentPlacement == null) { 431 return {}; 432 } 433 const { 434 main, 435 cross 436 } = getAlignmentSides(currentPlacement, rects, await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating))); 437 438 // Make `computeCoords` start from the right place. 439 if (placement !== currentPlacement) { 440 return { 441 reset: { 442 placement: placements[0] 443 } 444 }; 445 } 446 const currentOverflows = [overflow[getSide(currentPlacement)], overflow[main], overflow[cross]]; 447 const allOverflows = [...(((_middlewareData$autoP2 = middlewareData.autoPlacement) == null ? void 0 : _middlewareData$autoP2.overflows) || []), { 448 placement: currentPlacement, 449 overflows: currentOverflows 450 }]; 451 const nextPlacement = placements[currentIndex + 1]; 452 453 // There are more placements to check. 454 if (nextPlacement) { 455 return { 456 data: { 457 index: currentIndex + 1, 458 overflows: allOverflows 459 }, 460 reset: { 461 placement: nextPlacement 462 } 463 }; 464 } 465 const placementsSortedByMostSpace = allOverflows.map(d => { 466 const alignment = getAlignment(d.placement); 467 return [d.placement, alignment && crossAxis ? 468 // Check along the mainAxis and main crossAxis side. 469 d.overflows.slice(0, 2).reduce((acc, v) => acc + v, 0) : 470 // Check only the mainAxis. 471 d.overflows[0], d.overflows]; 472 }).sort((a, b) => a[1] - b[1]); 473 const placementsThatFitOnEachSide = placementsSortedByMostSpace.filter(d => d[2].slice(0, 474 // Aligned placements should not check their opposite crossAxis 475 // side. 476 getAlignment(d[0]) ? 2 : 3).every(v => v <= 0)); 477 const resetPlacement = ((_placementsThatFitOnE = placementsThatFitOnEachSide[0]) == null ? void 0 : _placementsThatFitOnE[0]) || placementsSortedByMostSpace[0][0]; 478 if (resetPlacement !== placement) { 479 return { 480 data: { 481 index: currentIndex + 1, 482 overflows: allOverflows 483 }, 484 reset: { 485 placement: resetPlacement 486 } 487 }; 488 } 489 return {}; 490 } 491 }; 492 }; 493 494 function getExpandedPlacements(placement) { 495 const oppositePlacement = getOppositePlacement(placement); 496 return [getOppositeAlignmentPlacement(placement), oppositePlacement, getOppositeAlignmentPlacement(oppositePlacement)]; 497 } 498 499 function getSideList(side, isStart, rtl) { 500 const lr = ['left', 'right']; 501 const rl = ['right', 'left']; 502 const tb = ['top', 'bottom']; 503 const bt = ['bottom', 'top']; 504 switch (side) { 505 case 'top': 506 case 'bottom': 507 if (rtl) return isStart ? rl : lr; 508 return isStart ? lr : rl; 509 case 'left': 510 case 'right': 511 return isStart ? tb : bt; 512 default: 513 return []; 514 } 515 } 516 function getOppositeAxisPlacements(placement, flipAlignment, direction, rtl) { 517 const alignment = getAlignment(placement); 518 let list = getSideList(getSide(placement), direction === 'start', rtl); 519 if (alignment) { 520 list = list.map(side => side + "-" + alignment); 521 if (flipAlignment) { 522 list = list.concat(list.map(getOppositeAlignmentPlacement)); 523 } 524 } 525 return list; 526 } 527 528 /** 529 * Optimizes the visibility of the floating element by flipping the `placement` 530 * in order to keep it in view when the preferred placement(s) will overflow the 531 * clipping boundary. Alternative to `autoPlacement`. 532 * @see https://floating-ui.com/docs/flip 533 */ 534 const flip = function (options) { 535 if (options === void 0) { 536 options = {}; 537 } 538 return { 539 name: 'flip', 540 options, 541 async fn(state) { 542 var _middlewareData$flip; 543 const { 544 placement, 545 middlewareData, 546 rects, 547 initialPlacement, 548 platform, 549 elements 550 } = state; 551 const { 552 mainAxis: checkMainAxis = true, 553 crossAxis: checkCrossAxis = true, 554 fallbackPlacements: specifiedFallbackPlacements, 555 fallbackStrategy = 'bestFit', 556 fallbackAxisSideDirection = 'none', 557 flipAlignment = true, 558 ...detectOverflowOptions 559 } = evaluate(options, state); 560 const side = getSide(placement); 561 const isBasePlacement = getSide(initialPlacement) === initialPlacement; 562 const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating)); 563 const fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipAlignment ? [getOppositePlacement(initialPlacement)] : getExpandedPlacements(initialPlacement)); 564 if (!specifiedFallbackPlacements && fallbackAxisSideDirection !== 'none') { 565 fallbackPlacements.push(...getOppositeAxisPlacements(initialPlacement, flipAlignment, fallbackAxisSideDirection, rtl)); 566 } 567 const placements = [initialPlacement, ...fallbackPlacements]; 568 const overflow = await detectOverflow(state, detectOverflowOptions); 569 const overflows = []; 570 let overflowsData = ((_middlewareData$flip = middlewareData.flip) == null ? void 0 : _middlewareData$flip.overflows) || []; 571 if (checkMainAxis) { 572 overflows.push(overflow[side]); 573 } 574 if (checkCrossAxis) { 575 const { 576 main, 577 cross 578 } = getAlignmentSides(placement, rects, rtl); 579 overflows.push(overflow[main], overflow[cross]); 580 } 581 overflowsData = [...overflowsData, { 582 placement, 583 overflows 584 }]; 585 586 // One or more sides is overflowing. 587 if (!overflows.every(side => side <= 0)) { 588 var _middlewareData$flip2, _overflowsData$filter; 589 const nextIndex = (((_middlewareData$flip2 = middlewareData.flip) == null ? void 0 : _middlewareData$flip2.index) || 0) + 1; 590 const nextPlacement = placements[nextIndex]; 591 if (nextPlacement) { 592 // Try next placement and re-run the lifecycle. 593 return { 594 data: { 595 index: nextIndex, 596 overflows: overflowsData 597 }, 598 reset: { 599 placement: nextPlacement 600 } 601 }; 602 } 603 604 // First, find the candidates that fit on the mainAxis side of overflow, 605 // then find the placement that fits the best on the main crossAxis side. 606 let resetPlacement = (_overflowsData$filter = overflowsData.filter(d => d.overflows[0] <= 0).sort((a, b) => a.overflows[1] - b.overflows[1])[0]) == null ? void 0 : _overflowsData$filter.placement; 607 608 // Otherwise fallback. 609 if (!resetPlacement) { 610 switch (fallbackStrategy) { 611 case 'bestFit': 612 { 613 var _overflowsData$map$so; 614 const placement = (_overflowsData$map$so = overflowsData.map(d => [d.placement, d.overflows.filter(overflow => overflow > 0).reduce((acc, overflow) => acc + overflow, 0)]).sort((a, b) => a[1] - b[1])[0]) == null ? void 0 : _overflowsData$map$so[0]; 615 if (placement) { 616 resetPlacement = placement; 617 } 618 break; 619 } 620 case 'initialPlacement': 621 resetPlacement = initialPlacement; 622 break; 623 } 624 } 625 if (placement !== resetPlacement) { 626 return { 627 reset: { 628 placement: resetPlacement 629 } 630 }; 631 } 632 } 633 return {}; 634 } 635 }; 636 }; 637 638 function getSideOffsets(overflow, rect) { 639 return { 640 top: overflow.top - rect.height, 641 right: overflow.right - rect.width, 642 bottom: overflow.bottom - rect.height, 643 left: overflow.left - rect.width 644 }; 645 } 646 function isAnySideFullyClipped(overflow) { 647 return sides.some(side => overflow[side] >= 0); 648 } 649 /** 650 * Provides data to hide the floating element in applicable situations, such as 651 * when it is not in the same clipping context as the reference element. 652 * @see https://floating-ui.com/docs/hide 653 */ 654 const hide = function (options) { 655 if (options === void 0) { 656 options = {}; 657 } 658 return { 659 name: 'hide', 660 options, 661 async fn(state) { 662 const { 663 rects 664 } = state; 665 const { 666 strategy = 'referenceHidden', 667 ...detectOverflowOptions 668 } = evaluate(options, state); 669 switch (strategy) { 670 case 'referenceHidden': 671 { 672 const overflow = await detectOverflow(state, { 673 ...detectOverflowOptions, 674 elementContext: 'reference' 675 }); 676 const offsets = getSideOffsets(overflow, rects.reference); 677 return { 678 data: { 679 referenceHiddenOffsets: offsets, 680 referenceHidden: isAnySideFullyClipped(offsets) 681 } 682 }; 683 } 684 case 'escaped': 685 { 686 const overflow = await detectOverflow(state, { 687 ...detectOverflowOptions, 688 altBoundary: true 689 }); 690 const offsets = getSideOffsets(overflow, rects.floating); 691 return { 692 data: { 693 escapedOffsets: offsets, 694 escaped: isAnySideFullyClipped(offsets) 695 } 696 }; 697 } 698 default: 699 { 700 return {}; 701 } 702 } 703 } 704 }; 705 }; 706 707 function getBoundingRect(rects) { 708 const minX = min(...rects.map(rect => rect.left)); 709 const minY = min(...rects.map(rect => rect.top)); 710 const maxX = max(...rects.map(rect => rect.right)); 711 const maxY = max(...rects.map(rect => rect.bottom)); 712 return { 713 x: minX, 714 y: minY, 715 width: maxX - minX, 716 height: maxY - minY 717 }; 718 } 719 function getRectsByLine(rects) { 720 const sortedRects = rects.slice().sort((a, b) => a.y - b.y); 721 const groups = []; 722 let prevRect = null; 723 for (let i = 0; i < sortedRects.length; i++) { 724 const rect = sortedRects[i]; 725 if (!prevRect || rect.y - prevRect.y > prevRect.height / 2) { 726 groups.push([rect]); 727 } else { 728 groups[groups.length - 1].push(rect); 729 } 730 prevRect = rect; 731 } 732 return groups.map(rect => rectToClientRect(getBoundingRect(rect))); 733 } 734 /** 735 * Provides improved positioning for inline reference elements that can span 736 * over multiple lines, such as hyperlinks or range selections. 737 * @see https://floating-ui.com/docs/inline 738 */ 739 const inline = function (options) { 740 if (options === void 0) { 741 options = {}; 742 } 743 return { 744 name: 'inline', 745 options, 746 async fn(state) { 747 const { 748 placement, 749 elements, 750 rects, 751 platform, 752 strategy 753 } = state; 754 // A MouseEvent's client{X,Y} coords can be up to 2 pixels off a 755 // ClientRect's bounds, despite the event listener being triggered. A 756 // padding of 2 seems to handle this issue. 757 const { 758 padding = 2, 759 x, 760 y 761 } = evaluate(options, state); 762 const nativeClientRects = Array.from((await (platform.getClientRects == null ? void 0 : platform.getClientRects(elements.reference))) || []); 763 const clientRects = getRectsByLine(nativeClientRects); 764 const fallback = rectToClientRect(getBoundingRect(nativeClientRects)); 765 const paddingObject = getSideObjectFromPadding(padding); 766 function getBoundingClientRect() { 767 // There are two rects and they are disjoined. 768 if (clientRects.length === 2 && clientRects[0].left > clientRects[1].right && x != null && y != null) { 769 // Find the first rect in which the point is fully inside. 770 return clientRects.find(rect => x > rect.left - paddingObject.left && x < rect.right + paddingObject.right && y > rect.top - paddingObject.top && y < rect.bottom + paddingObject.bottom) || fallback; 771 } 772 773 // There are 2 or more connected rects. 774 if (clientRects.length >= 2) { 775 if (getMainAxisFromPlacement(placement) === 'x') { 776 const firstRect = clientRects[0]; 777 const lastRect = clientRects[clientRects.length - 1]; 778 const isTop = getSide(placement) === 'top'; 779 const top = firstRect.top; 780 const bottom = lastRect.bottom; 781 const left = isTop ? firstRect.left : lastRect.left; 782 const right = isTop ? firstRect.right : lastRect.right; 783 const width = right - left; 784 const height = bottom - top; 785 return { 786 top, 787 bottom, 788 left, 789 right, 790 width, 791 height, 792 x: left, 793 y: top 794 }; 795 } 796 const isLeftSide = getSide(placement) === 'left'; 797 const maxRight = max(...clientRects.map(rect => rect.right)); 798 const minLeft = min(...clientRects.map(rect => rect.left)); 799 const measureRects = clientRects.filter(rect => isLeftSide ? rect.left === minLeft : rect.right === maxRight); 800 const top = measureRects[0].top; 801 const bottom = measureRects[measureRects.length - 1].bottom; 802 const left = minLeft; 803 const right = maxRight; 804 const width = right - left; 805 const height = bottom - top; 806 return { 807 top, 808 bottom, 809 left, 810 right, 811 width, 812 height, 813 x: left, 814 y: top 815 }; 816 } 817 return fallback; 818 } 819 const resetRects = await platform.getElementRects({ 820 reference: { 821 getBoundingClientRect 822 }, 823 floating: elements.floating, 824 strategy 825 }); 826 if (rects.reference.x !== resetRects.reference.x || rects.reference.y !== resetRects.reference.y || rects.reference.width !== resetRects.reference.width || rects.reference.height !== resetRects.reference.height) { 827 return { 828 reset: { 829 rects: resetRects 830 } 831 }; 832 } 833 return {}; 834 } 835 }; 836 }; 837 838 async function convertValueToCoords(state, options) { 839 const { 840 placement, 841 platform, 842 elements 843 } = state; 844 const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating)); 845 const side = getSide(placement); 846 const alignment = getAlignment(placement); 847 const isVertical = getMainAxisFromPlacement(placement) === 'x'; 848 const mainAxisMulti = ['left', 'top'].includes(side) ? -1 : 1; 849 const crossAxisMulti = rtl && isVertical ? -1 : 1; 850 const rawValue = evaluate(options, state); 851 852 // eslint-disable-next-line prefer-const 853 let { 854 mainAxis, 855 crossAxis, 856 alignmentAxis 857 } = typeof rawValue === 'number' ? { 858 mainAxis: rawValue, 859 crossAxis: 0, 860 alignmentAxis: null 861 } : { 862 mainAxis: 0, 863 crossAxis: 0, 864 alignmentAxis: null, 865 ...rawValue 866 }; 867 if (alignment && typeof alignmentAxis === 'number') { 868 crossAxis = alignment === 'end' ? alignmentAxis * -1 : alignmentAxis; 869 } 870 return isVertical ? { 871 x: crossAxis * crossAxisMulti, 872 y: mainAxis * mainAxisMulti 873 } : { 874 x: mainAxis * mainAxisMulti, 875 y: crossAxis * crossAxisMulti 876 }; 877 } 878 879 /** 880 * Modifies the placement by translating the floating element along the 881 * specified axes. 882 * A number (shorthand for `mainAxis` or distance), or an axes configuration 883 * object may be passed. 884 * @see https://floating-ui.com/docs/offset 885 */ 886 const offset = function (options) { 887 if (options === void 0) { 888 options = 0; 889 } 890 return { 891 name: 'offset', 892 options, 893 async fn(state) { 894 const { 895 x, 896 y 897 } = state; 898 const diffCoords = await convertValueToCoords(state, options); 899 return { 900 x: x + diffCoords.x, 901 y: y + diffCoords.y, 902 data: diffCoords 903 }; 904 } 905 }; 906 }; 907 908 function getCrossAxis(axis) { 909 return axis === 'x' ? 'y' : 'x'; 910 } 911 912 /** 913 * Optimizes the visibility of the floating element by shifting it in order to 914 * keep it in view when it will overflow the clipping boundary. 915 * @see https://floating-ui.com/docs/shift 916 */ 917 const shift = function (options) { 918 if (options === void 0) { 919 options = {}; 920 } 921 return { 922 name: 'shift', 923 options, 924 async fn(state) { 925 const { 926 x, 927 y, 928 placement 929 } = state; 930 const { 931 mainAxis: checkMainAxis = true, 932 crossAxis: checkCrossAxis = false, 933 limiter = { 934 fn: _ref => { 935 let { 936 x, 937 y 938 } = _ref; 939 return { 940 x, 941 y 942 }; 943 } 944 }, 945 ...detectOverflowOptions 946 } = evaluate(options, state); 947 const coords = { 948 x, 949 y 950 }; 951 const overflow = await detectOverflow(state, detectOverflowOptions); 952 const mainAxis = getMainAxisFromPlacement(getSide(placement)); 953 const crossAxis = getCrossAxis(mainAxis); 954 let mainAxisCoord = coords[mainAxis]; 955 let crossAxisCoord = coords[crossAxis]; 956 if (checkMainAxis) { 957 const minSide = mainAxis === 'y' ? 'top' : 'left'; 958 const maxSide = mainAxis === 'y' ? 'bottom' : 'right'; 959 const min = mainAxisCoord + overflow[minSide]; 960 const max = mainAxisCoord - overflow[maxSide]; 961 mainAxisCoord = within(min, mainAxisCoord, max); 962 } 963 if (checkCrossAxis) { 964 const minSide = crossAxis === 'y' ? 'top' : 'left'; 965 const maxSide = crossAxis === 'y' ? 'bottom' : 'right'; 966 const min = crossAxisCoord + overflow[minSide]; 967 const max = crossAxisCoord - overflow[maxSide]; 968 crossAxisCoord = within(min, crossAxisCoord, max); 969 } 970 const limitedCoords = limiter.fn({ 971 ...state, 972 [mainAxis]: mainAxisCoord, 973 [crossAxis]: crossAxisCoord 974 }); 975 return { 976 ...limitedCoords, 977 data: { 978 x: limitedCoords.x - x, 979 y: limitedCoords.y - y 980 } 981 }; 982 } 983 }; 984 }; 985 /** 986 * Built-in `limiter` that will stop `shift()` at a certain point. 987 */ 988 const limitShift = function (options) { 989 if (options === void 0) { 990 options = {}; 991 } 992 return { 993 options, 994 fn(state) { 995 const { 996 x, 997 y, 998 placement, 999 rects, 1000 middlewareData 1001 } = state; 1002 const { 1003 offset = 0, 1004 mainAxis: checkMainAxis = true, 1005 crossAxis: checkCrossAxis = true 1006 } = evaluate(options, state); 1007 const coords = { 1008 x, 1009 y 1010 }; 1011 const mainAxis = getMainAxisFromPlacement(placement); 1012 const crossAxis = getCrossAxis(mainAxis); 1013 let mainAxisCoord = coords[mainAxis]; 1014 let crossAxisCoord = coords[crossAxis]; 1015 const rawOffset = evaluate(offset, state); 1016 const computedOffset = typeof rawOffset === 'number' ? { 1017 mainAxis: rawOffset, 1018 crossAxis: 0 1019 } : { 1020 mainAxis: 0, 1021 crossAxis: 0, 1022 ...rawOffset 1023 }; 1024 if (checkMainAxis) { 1025 const len = mainAxis === 'y' ? 'height' : 'width'; 1026 const limitMin = rects.reference[mainAxis] - rects.floating[len] + computedOffset.mainAxis; 1027 const limitMax = rects.reference[mainAxis] + rects.reference[len] - computedOffset.mainAxis; 1028 if (mainAxisCoord < limitMin) { 1029 mainAxisCoord = limitMin; 1030 } else if (mainAxisCoord > limitMax) { 1031 mainAxisCoord = limitMax; 1032 } 1033 } 1034 if (checkCrossAxis) { 1035 var _middlewareData$offse, _middlewareData$offse2; 1036 const len = mainAxis === 'y' ? 'width' : 'height'; 1037 const isOriginSide = ['top', 'left'].includes(getSide(placement)); 1038 const limitMin = rects.reference[crossAxis] - rects.floating[len] + (isOriginSide ? ((_middlewareData$offse = middlewareData.offset) == null ? void 0 : _middlewareData$offse[crossAxis]) || 0 : 0) + (isOriginSide ? 0 : computedOffset.crossAxis); 1039 const limitMax = rects.reference[crossAxis] + rects.reference[len] + (isOriginSide ? 0 : ((_middlewareData$offse2 = middlewareData.offset) == null ? void 0 : _middlewareData$offse2[crossAxis]) || 0) - (isOriginSide ? computedOffset.crossAxis : 0); 1040 if (crossAxisCoord < limitMin) { 1041 crossAxisCoord = limitMin; 1042 } else if (crossAxisCoord > limitMax) { 1043 crossAxisCoord = limitMax; 1044 } 1045 } 1046 return { 1047 [mainAxis]: mainAxisCoord, 1048 [crossAxis]: crossAxisCoord 1049 }; 1050 } 1051 }; 1052 }; 1053 1054 /** 1055 * Provides data that allows you to change the size of the floating element â 1056 * for instance, prevent it from overflowing the clipping boundary or match the 1057 * width of the reference element. 1058 * @see https://floating-ui.com/docs/size 1059 */ 1060 const size = function (options) { 1061 if (options === void 0) { 1062 options = {}; 1063 } 1064 return { 1065 name: 'size', 1066 options, 1067 async fn(state) { 1068 const { 1069 placement, 1070 rects, 1071 platform, 1072 elements 1073 } = state; 1074 const { 1075 apply = () => {}, 1076 ...detectOverflowOptions 1077 } = evaluate(options, state); 1078 const overflow = await detectOverflow(state, detectOverflowOptions); 1079 const side = getSide(placement); 1080 const alignment = getAlignment(placement); 1081 const axis = getMainAxisFromPlacement(placement); 1082 const isXAxis = axis === 'x'; 1083 const { 1084 width, 1085 height 1086 } = rects.floating; 1087 let heightSide; 1088 let widthSide; 1089 if (side === 'top' || side === 'bottom') { 1090 heightSide = side; 1091 widthSide = alignment === ((await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating))) ? 'start' : 'end') ? 'left' : 'right'; 1092 } else { 1093 widthSide = side; 1094 heightSide = alignment === 'end' ? 'top' : 'bottom'; 1095 } 1096 const overflowAvailableHeight = height - overflow[heightSide]; 1097 const overflowAvailableWidth = width - overflow[widthSide]; 1098 const noShift = !state.middlewareData.shift; 1099 let availableHeight = overflowAvailableHeight; 1100 let availableWidth = overflowAvailableWidth; 1101 if (isXAxis) { 1102 const maximumClippingWidth = width - overflow.left - overflow.right; 1103 availableWidth = alignment || noShift ? min(overflowAvailableWidth, maximumClippingWidth) : maximumClippingWidth; 1104 } else { 1105 const maximumClippingHeight = height - overflow.top - overflow.bottom; 1106 availableHeight = alignment || noShift ? min(overflowAvailableHeight, maximumClippingHeight) : maximumClippingHeight; 1107 } 1108 if (noShift && !alignment) { 1109 const xMin = max(overflow.left, 0); 1110 const xMax = max(overflow.right, 0); 1111 const yMin = max(overflow.top, 0); 1112 const yMax = max(overflow.bottom, 0); 1113 if (isXAxis) { 1114 availableWidth = width - 2 * (xMin !== 0 || xMax !== 0 ? xMin + xMax : max(overflow.left, overflow.right)); 1115 } else { 1116 availableHeight = height - 2 * (yMin !== 0 || yMax !== 0 ? yMin + yMax : max(overflow.top, overflow.bottom)); 1117 } 1118 } 1119 await apply({ 1120 ...state, 1121 availableWidth, 1122 availableHeight 1123 }); 1124 const nextDimensions = await platform.getDimensions(elements.floating); 1125 if (width !== nextDimensions.width || height !== nextDimensions.height) { 1126 return { 1127 reset: { 1128 rects: true 1129 } 1130 }; 1131 } 1132 return {}; 1133 } 1134 }; 1135 }; 1136 1137 exports.arrow = arrow; 1138 exports.autoPlacement = autoPlacement; 1139 exports.computePosition = computePosition; 1140 exports.detectOverflow = detectOverflow; 1141 exports.flip = flip; 1142 exports.hide = hide; 1143 exports.inline = inline; 1144 exports.limitShift = limitShift; 1145 exports.offset = offset; 1146 exports.rectToClientRect = rectToClientRect; 1147 exports.shift = shift; 1148 exports.size = size; 1149 1150 Object.defineProperty(exports, '__esModule', { value: true }); 1151 1152}));
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.