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