Download node_modules/@floating-ui/core/dist/floating-ui.core.browser.mjs from metarm/QMetaRam: direct link, hf CLI and curl.
- Browser
- Download file 39.9 kB
-
https://huggingface.co/metarm/QMetaRam/resolve/main/node_modules/%40floating-ui/core/dist/floating-ui.core.browser.mjs
- Command line
-
hf download hf://metarm/QMetaRam/node_modules/@floating-ui/core/dist/floating-ui.core.browser.mjs
-
curl -L -o floating-ui.core.browser.mjs https://huggingface.co/metarm/QMetaRam/resolve/main/node_modules/%40floating-ui/core/dist/floating-ui.core.browser.mjs
39.9 kB
| /** | |
| * Custom positioning reference element. | |
| * @see https://floating-ui.com/docs/virtual-elements | |
| */ | |
| const sides = ['top', 'right', 'bottom', 'left']; | |
| const alignments = ['start', 'end']; | |
| const placements = /*#__PURE__*/sides.reduce((acc, side) => acc.concat(side, side + "-" + alignments[0], side + "-" + alignments[1]), []); | |
| const min = Math.min; | |
| const max = Math.max; | |
| const oppositeSideMap = { | |
| left: 'right', | |
| right: 'left', | |
| bottom: 'top', | |
| top: 'bottom' | |
| }; | |
| function clamp(start, value, end) { | |
| return max(start, min(value, end)); | |
| } | |
| function evaluate(value, param) { | |
| return typeof value === 'function' ? value(param) : value; | |
| } | |
| function getSide(placement) { | |
| return placement.split('-')[0]; | |
| } | |
| function getAlignment(placement) { | |
| return placement.split('-')[1]; | |
| } | |
| function getOppositeAxis(axis) { | |
| return axis === 'x' ? 'y' : 'x'; | |
| } | |
| function getAxisLength(axis) { | |
| return axis === 'y' ? 'height' : 'width'; | |
| } | |
| function getSideAxis(placement) { | |
| const firstChar = placement[0]; | |
| return firstChar === 't' || firstChar === 'b' ? 'y' : 'x'; | |
| } | |
| function getAlignmentAxis(placement) { | |
| return getOppositeAxis(getSideAxis(placement)); | |
| } | |
| function getAlignmentSides(placement, rects, rtl) { | |
| if (rtl === void 0) { | |
| rtl = false; | |
| } | |
| const alignment = getAlignment(placement); | |
| const alignmentAxis = getAlignmentAxis(placement); | |
| const length = getAxisLength(alignmentAxis); | |
| let mainAlignmentSide = alignmentAxis === 'x' ? alignment === (rtl ? 'end' : 'start') ? 'right' : 'left' : alignment === 'start' ? 'bottom' : 'top'; | |
| if (rects.reference[length] > rects.floating[length]) { | |
| mainAlignmentSide = getOppositePlacement(mainAlignmentSide); | |
| } | |
| return [mainAlignmentSide, getOppositePlacement(mainAlignmentSide)]; | |
| } | |
| function getExpandedPlacements(placement) { | |
| const oppositePlacement = getOppositePlacement(placement); | |
| return [getOppositeAlignmentPlacement(placement), oppositePlacement, getOppositeAlignmentPlacement(oppositePlacement)]; | |
| } | |
| function getOppositeAlignmentPlacement(placement) { | |
| return placement.includes('start') ? placement.replace('start', 'end') : placement.replace('end', 'start'); | |
| } | |
| const lrPlacement = ['left', 'right']; | |
| const rlPlacement = ['right', 'left']; | |
| const tbPlacement = ['top', 'bottom']; | |
| const btPlacement = ['bottom', 'top']; | |
| function getSideList(side, isStart, rtl) { | |
| switch (side) { | |
| case 'top': | |
| case 'bottom': | |
| if (rtl) return isStart ? rlPlacement : lrPlacement; | |
| return isStart ? lrPlacement : rlPlacement; | |
| case 'left': | |
| case 'right': | |
| return isStart ? tbPlacement : btPlacement; | |
| default: | |
| return []; | |
| } | |
| } | |
| function getOppositeAxisPlacements(placement, flipAlignment, direction, rtl) { | |
| const alignment = getAlignment(placement); | |
| let list = getSideList(getSide(placement), direction === 'start', rtl); | |
| if (alignment) { | |
| list = list.map(side => side + "-" + alignment); | |
| if (flipAlignment) { | |
| list = list.concat(list.map(getOppositeAlignmentPlacement)); | |
| } | |
| } | |
| return list; | |
| } | |
| function getOppositePlacement(placement) { | |
| const side = getSide(placement); | |
| return oppositeSideMap[side] + placement.slice(side.length); | |
| } | |
| function expandPaddingObject(padding) { | |
| var _padding$top, _padding$right, _padding$bottom, _padding$left; | |
| return { | |
| top: (_padding$top = padding.top) != null ? _padding$top : 0, | |
| right: (_padding$right = padding.right) != null ? _padding$right : 0, | |
| bottom: (_padding$bottom = padding.bottom) != null ? _padding$bottom : 0, | |
| left: (_padding$left = padding.left) != null ? _padding$left : 0 | |
| }; | |
| } | |
| function getPaddingObject(padding) { | |
| return typeof padding !== 'number' ? expandPaddingObject(padding) : { | |
| top: padding, | |
| right: padding, | |
| bottom: padding, | |
| left: padding | |
| }; | |
| } | |
| function rectToClientRect(rect) { | |
| const { | |
| x, | |
| y, | |
| width, | |
| height | |
| } = rect; | |
| return { | |
| width, | |
| height, | |
| top: y, | |
| left: x, | |
| right: x + width, | |
| bottom: y + height, | |
| x, | |
| y | |
| }; | |
| } | |
| function computeCoordsFromPlacement(_ref, placement, rtl) { | |
| let { | |
| reference, | |
| floating | |
| } = _ref; | |
| const sideAxis = getSideAxis(placement); | |
| const alignmentAxis = getAlignmentAxis(placement); | |
| const alignLength = getAxisLength(alignmentAxis); | |
| const side = getSide(placement); | |
| const isVertical = sideAxis === 'y'; | |
| const commonX = reference.x + reference.width / 2 - floating.width / 2; | |
| const commonY = reference.y + reference.height / 2 - floating.height / 2; | |
| const commonAlign = reference[alignLength] / 2 - floating[alignLength] / 2; | |
| let coords; | |
| switch (side) { | |
| case 'top': | |
| coords = { | |
| x: commonX, | |
| y: reference.y - floating.height | |
| }; | |
| break; | |
| case 'bottom': | |
| coords = { | |
| x: commonX, | |
| y: reference.y + reference.height | |
| }; | |
| break; | |
| case 'right': | |
| coords = { | |
| x: reference.x + reference.width, | |
| y: commonY | |
| }; | |
| break; | |
| case 'left': | |
| coords = { | |
| x: reference.x - floating.width, | |
| y: commonY | |
| }; | |
| break; | |
| default: | |
| coords = { | |
| x: reference.x, | |
| y: reference.y | |
| }; | |
| } | |
| const alignment = getAlignment(placement); | |
| if (alignment) { | |
| coords[alignmentAxis] += commonAlign * (alignment === 'end' ? 1 : -1) * (rtl && isVertical ? -1 : 1); | |
| } | |
| return coords; | |
| } | |
| /** | |
| * Resolves with an object of overflow side offsets that determine how much the | |
| * element is overflowing a given clipping boundary on each side. | |
| * - positive = overflowing the boundary by that number of pixels | |
| * - negative = how many pixels left before it will overflow | |
| * - 0 = lies flush with the boundary | |
| * @see https://floating-ui.com/docs/detectOverflow | |
| */ | |
| async function detectOverflow(state, options) { | |
| var _await$platform$isEle; | |
| if (options === void 0) { | |
| options = {}; | |
| } | |
| const { | |
| x, | |
| y, | |
| platform, | |
| rects, | |
| elements, | |
| strategy | |
| } = state; | |
| const { | |
| boundary = 'clippingAncestors', | |
| rootBoundary = 'viewport', | |
| elementContext = 'floating', | |
| altBoundary = false, | |
| padding = 0 | |
| } = evaluate(options, state); | |
| const paddingObject = getPaddingObject(padding); | |
| const altContext = elementContext === 'floating' ? 'reference' : 'floating'; | |
| const element = elements[altBoundary ? altContext : elementContext]; | |
| const clippingClientRect = rectToClientRect(await platform.getClippingRect({ | |
| 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))), | |
| boundary, | |
| rootBoundary, | |
| strategy | |
| })); | |
| const rect = elementContext === 'floating' ? { | |
| x, | |
| y, | |
| width: rects.floating.width, | |
| height: rects.floating.height | |
| } : rects.reference; | |
| const offsetParent = await (platform.getOffsetParent == null ? void 0 : platform.getOffsetParent(elements.floating)); | |
| const offsetScale = (await (platform.isElement == null ? void 0 : platform.isElement(offsetParent))) && (await (platform.getScale == null ? void 0 : platform.getScale(offsetParent))) || { | |
| x: 1, | |
| y: 1 | |
| }; | |
| const elementClientRect = rectToClientRect(platform.convertOffsetParentRelativeRectToViewportRelativeRect ? await platform.convertOffsetParentRelativeRectToViewportRelativeRect({ | |
| elements, | |
| rect, | |
| offsetParent, | |
| strategy | |
| }) : rect); | |
| return { | |
| top: (clippingClientRect.top - elementClientRect.top + paddingObject.top) / offsetScale.y, | |
| bottom: (elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom) / offsetScale.y, | |
| left: (clippingClientRect.left - elementClientRect.left + paddingObject.left) / offsetScale.x, | |
| right: (elementClientRect.right - clippingClientRect.right + paddingObject.right) / offsetScale.x | |
| }; | |
| } | |
| // Maximum number of resets that can occur before bailing to avoid infinite reset loops. | |
| const MAX_RESET_COUNT = 50; | |
| /** | |
| * Computes the `x` and `y` coordinates that will place the floating element | |
| * next to a given reference element. | |
| * | |
| * This export does not have any `platform` interface logic. You will need to | |
| * write one for the platform you are using Floating UI with. | |
| */ | |
| const computePosition = async (reference, floating, config) => { | |
| const { | |
| placement = 'bottom', | |
| strategy = 'absolute', | |
| middleware = [], | |
| platform | |
| } = config; | |
| const platformWithDetectOverflow = platform.detectOverflow ? platform : { | |
| ...platform, | |
| detectOverflow | |
| }; | |
| const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(floating)); | |
| let rects = await platform.getElementRects({ | |
| reference, | |
| floating, | |
| strategy | |
| }); | |
| let { | |
| x, | |
| y | |
| } = computeCoordsFromPlacement(rects, placement, rtl); | |
| let statefulPlacement = placement; | |
| let resetCount = 0; | |
| const middlewareData = {}; | |
| for (let i = 0; i < middleware.length; i++) { | |
| const currentMiddleware = middleware[i]; | |
| if (!currentMiddleware) { | |
| continue; | |
| } | |
| const { | |
| name, | |
| fn | |
| } = currentMiddleware; | |
| const { | |
| x: nextX, | |
| y: nextY, | |
| data, | |
| reset | |
| } = await fn({ | |
| x, | |
| y, | |
| initialPlacement: placement, | |
| placement: statefulPlacement, | |
| strategy, | |
| middlewareData, | |
| rects, | |
| platform: platformWithDetectOverflow, | |
| elements: { | |
| reference, | |
| floating | |
| } | |
| }); | |
| x = nextX != null ? nextX : x; | |
| y = nextY != null ? nextY : y; | |
| middlewareData[name] = { | |
| ...middlewareData[name], | |
| ...data | |
| }; | |
| if (reset && resetCount < MAX_RESET_COUNT) { | |
| resetCount++; | |
| if (typeof reset === 'object') { | |
| if (reset.placement) { | |
| statefulPlacement = reset.placement; | |
| } | |
| if (reset.rects) { | |
| rects = reset.rects === true ? await platform.getElementRects({ | |
| reference, | |
| floating, | |
| strategy | |
| }) : reset.rects; | |
| } | |
| ({ | |
| x, | |
| y | |
| } = computeCoordsFromPlacement(rects, statefulPlacement, rtl)); | |
| } | |
| i = -1; | |
| } | |
| } | |
| return { | |
| x, | |
| y, | |
| placement: statefulPlacement, | |
| strategy, | |
| middlewareData | |
| }; | |
| }; | |
| /** | |
| * Provides data to position an inner element of the floating element so that it | |
| * appears centered to the reference element. | |
| * @see https://floating-ui.com/docs/arrow | |
| */ | |
| const arrow = options => ({ | |
| name: 'arrow', | |
| options, | |
| async fn(state) { | |
| const { | |
| x, | |
| y, | |
| placement, | |
| rects, | |
| platform, | |
| elements, | |
| middlewareData | |
| } = state; | |
| // Since `element` is required, we don't Partial<> the type. | |
| const { | |
| element, | |
| padding = 0 | |
| } = evaluate(options, state) || {}; | |
| if (element == null) { | |
| return {}; | |
| } | |
| const paddingObject = getPaddingObject(padding); | |
| const coords = { | |
| x, | |
| y | |
| }; | |
| const axis = getAlignmentAxis(placement); | |
| const length = getAxisLength(axis); | |
| const arrowDimensions = await platform.getDimensions(element); | |
| const isYAxis = axis === 'y'; | |
| const minProp = isYAxis ? 'top' : 'left'; | |
| const maxProp = isYAxis ? 'bottom' : 'right'; | |
| const clientProp = isYAxis ? 'clientHeight' : 'clientWidth'; | |
| const endDiff = rects.reference[length] + rects.reference[axis] - coords[axis] - rects.floating[length]; | |
| const startDiff = coords[axis] - rects.reference[axis]; | |
| const arrowOffsetParent = await (platform.getOffsetParent == null ? void 0 : platform.getOffsetParent(element)); | |
| let clientSize = arrowOffsetParent ? arrowOffsetParent[clientProp] : 0; | |
| // DOM platform can return `window` as the `offsetParent`. | |
| if (!clientSize || !(await (platform.isElement == null ? void 0 : platform.isElement(arrowOffsetParent)))) { | |
| clientSize = elements.floating[clientProp] || rects.floating[length]; | |
| } | |
| const centerToReference = endDiff / 2 - startDiff / 2; | |
| // If the padding is large enough that it causes the arrow to no longer be | |
| // centered, modify the padding so that it is centered. | |
| const largestPossiblePadding = clientSize / 2 - arrowDimensions[length] / 2 - 1; | |
| const minPadding = min(paddingObject[minProp], largestPossiblePadding); | |
| const maxPadding = min(paddingObject[maxProp], largestPossiblePadding); | |
| // Make sure the arrow doesn't overflow the floating element if the center | |
| // point is outside the floating element's bounds. | |
| const max = clientSize - arrowDimensions[length] - maxPadding; | |
| const center = clientSize / 2 - arrowDimensions[length] / 2 + centerToReference; | |
| const offset = clamp(minPadding, center, max); | |
| // If the reference is small enough that the arrow's padding causes it to | |
| // to point to nothing for an aligned placement, adjust the offset of the | |
| // floating element itself. To ensure `shift()` continues to take action, | |
| // a single reset is performed when this is true. | |
| const shouldAddOffset = !middlewareData.arrow && getAlignment(placement) != null && center !== offset && rects.reference[length] / 2 - (center < minPadding ? minPadding : maxPadding) - arrowDimensions[length] / 2 < 0; | |
| const alignmentOffset = shouldAddOffset ? center < minPadding ? center - minPadding : center - max : 0; | |
| return { | |
| [axis]: coords[axis] + alignmentOffset, | |
| data: { | |
| [axis]: offset, | |
| centerOffset: center - offset - alignmentOffset, | |
| ...(shouldAddOffset && { | |
| alignmentOffset | |
| }) | |
| }, | |
| reset: shouldAddOffset | |
| }; | |
| } | |
| }); | |
| function getPlacementList(alignment, autoAlignment, allowedPlacements) { | |
| const allowedPlacementsSortedByAlignment = alignment ? [...allowedPlacements.filter(placement => getAlignment(placement) === alignment), ...allowedPlacements.filter(placement => getAlignment(placement) !== alignment)] : allowedPlacements.filter(placement => getSide(placement) === placement); | |
| return allowedPlacementsSortedByAlignment.filter(placement => { | |
| if (alignment) { | |
| return getAlignment(placement) === alignment || (autoAlignment ? getOppositeAlignmentPlacement(placement) !== placement : false); | |
| } | |
| return true; | |
| }); | |
| } | |
| /** | |
| * Optimizes the visibility of the floating element by choosing the placement | |
| * that has the most space available automatically, without needing to specify a | |
| * preferred placement. Alternative to `flip`. | |
| * @see https://floating-ui.com/docs/autoPlacement | |
| */ | |
| const autoPlacement = function (options) { | |
| if (options === void 0) { | |
| options = {}; | |
| } | |
| return { | |
| name: 'autoPlacement', | |
| options, | |
| async fn(state) { | |
| var _middlewareData$autoP, _middlewareData$autoP2, _placementsThatFitOnE; | |
| const { | |
| rects, | |
| middlewareData, | |
| placement, | |
| platform, | |
| elements | |
| } = state; | |
| const { | |
| crossAxis = false, | |
| alignment, | |
| allowedPlacements = placements, | |
| autoAlignment = true, | |
| ...detectOverflowOptions | |
| } = evaluate(options, state); | |
| const placements$1 = alignment !== undefined || allowedPlacements === placements ? getPlacementList(alignment || null, autoAlignment, allowedPlacements) : allowedPlacements; | |
| const currentIndex = ((_middlewareData$autoP = middlewareData.autoPlacement) == null ? void 0 : _middlewareData$autoP.index) || 0; | |
| const currentPlacement = placements$1[currentIndex]; | |
| if (currentPlacement == null) { | |
| return {}; | |
| } | |
| // Make `computeCoords` start from the right place. | |
| if (placement !== currentPlacement) { | |
| return { | |
| reset: { | |
| placement: placements$1[0] | |
| } | |
| }; | |
| } | |
| const overflow = await platform.detectOverflow(state, detectOverflowOptions); | |
| const alignmentSides = getAlignmentSides(currentPlacement, rects, await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating))); | |
| const currentOverflows = [overflow[getSide(currentPlacement)], overflow[alignmentSides[0]], overflow[alignmentSides[1]]]; | |
| const allOverflows = [...(((_middlewareData$autoP2 = middlewareData.autoPlacement) == null ? void 0 : _middlewareData$autoP2.overflows) || []), { | |
| placement: currentPlacement, | |
| overflows: currentOverflows | |
| }]; | |
| const nextPlacement = placements$1[currentIndex + 1]; | |
| // There are more placements to check. | |
| if (nextPlacement) { | |
| return { | |
| data: { | |
| index: currentIndex + 1, | |
| overflows: allOverflows | |
| }, | |
| reset: { | |
| placement: nextPlacement | |
| } | |
| }; | |
| } | |
| const placementsSortedByMostSpace = allOverflows.map(d => { | |
| const alignment = getAlignment(d.placement); | |
| return [d.placement, alignment && crossAxis ? | |
| // Check along the mainAxis and main crossAxis side. | |
| d.overflows.slice(0, 2).reduce((acc, v) => acc + v, 0) : | |
| // Check only the mainAxis. | |
| d.overflows[0], d.overflows]; | |
| }).sort((a, b) => a[1] - b[1]); | |
| const placementsThatFitOnEachSide = placementsSortedByMostSpace.filter(d => d[2].slice(0, | |
| // Aligned placements should not check their opposite crossAxis | |
| // side. | |
| getAlignment(d[0]) ? 2 : 3).every(v => v <= 0)); | |
| const resetPlacement = ((_placementsThatFitOnE = placementsThatFitOnEachSide[0]) == null ? void 0 : _placementsThatFitOnE[0]) || placementsSortedByMostSpace[0][0]; | |
| if (resetPlacement !== placement) { | |
| return { | |
| data: { | |
| index: currentIndex + 1, | |
| overflows: allOverflows | |
| }, | |
| reset: { | |
| placement: resetPlacement | |
| } | |
| }; | |
| } | |
| return {}; | |
| } | |
| }; | |
| }; | |
| /** | |
| * Optimizes the visibility of the floating element by flipping the `placement` | |
| * in order to keep it in view when the preferred placement(s) will overflow the | |
| * clipping boundary. Alternative to `autoPlacement`. | |
| * @see https://floating-ui.com/docs/flip | |
| */ | |
| const flip = function (options) { | |
| if (options === void 0) { | |
| options = {}; | |
| } | |
| return { | |
| name: 'flip', | |
| options, | |
| async fn(state) { | |
| var _middlewareData$arrow, _middlewareData$flip; | |
| const { | |
| placement, | |
| middlewareData, | |
| rects, | |
| initialPlacement, | |
| platform, | |
| elements | |
| } = state; | |
| const { | |
| mainAxis: checkMainAxis = true, | |
| crossAxis: checkCrossAxis = true, | |
| fallbackPlacements: specifiedFallbackPlacements, | |
| fallbackStrategy = 'bestFit', | |
| fallbackAxisSideDirection = 'none', | |
| flipAlignment = true, | |
| ...detectOverflowOptions | |
| } = evaluate(options, state); | |
| // If a reset by the arrow was caused due to an alignment offset being | |
| // added, we should skip any logic now since `flip()` has already done its | |
| // work. | |
| // https://github.com/floating-ui/floating-ui/issues/2549#issuecomment-1719601643 | |
| if ((_middlewareData$arrow = middlewareData.arrow) != null && _middlewareData$arrow.alignmentOffset) { | |
| return {}; | |
| } | |
| const side = getSide(placement); | |
| const initialSideAxis = getSideAxis(initialPlacement); | |
| const isBasePlacement = getSide(initialPlacement) === initialPlacement; | |
| const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating)); | |
| const fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipAlignment ? [getOppositePlacement(initialPlacement)] : getExpandedPlacements(initialPlacement)); | |
| const hasFallbackAxisSideDirection = fallbackAxisSideDirection !== 'none'; | |
| if (!specifiedFallbackPlacements && hasFallbackAxisSideDirection) { | |
| fallbackPlacements.push(...getOppositeAxisPlacements(initialPlacement, flipAlignment, fallbackAxisSideDirection, rtl)); | |
| } | |
| const placements = [initialPlacement, ...fallbackPlacements]; | |
| const overflow = await platform.detectOverflow(state, detectOverflowOptions); | |
| const overflows = []; | |
| let overflowsData = ((_middlewareData$flip = middlewareData.flip) == null ? void 0 : _middlewareData$flip.overflows) || []; | |
| if (checkMainAxis) { | |
| overflows.push(overflow[side]); | |
| } | |
| if (checkCrossAxis) { | |
| const sides = getAlignmentSides(placement, rects, rtl); | |
| overflows.push(overflow[sides[0]], overflow[sides[1]]); | |
| } | |
| overflowsData = [...overflowsData, { | |
| placement, | |
| overflows | |
| }]; | |
| // One or more sides is overflowing. | |
| if (!overflows.every(side => side <= 0)) { | |
| var _middlewareData$flip2, _overflowsData$filter; | |
| const nextIndex = (((_middlewareData$flip2 = middlewareData.flip) == null ? void 0 : _middlewareData$flip2.index) || 0) + 1; | |
| const nextPlacement = placements[nextIndex]; | |
| if (nextPlacement) { | |
| const ignoreCrossAxisOverflow = checkCrossAxis === 'alignment' ? initialSideAxis !== getSideAxis(nextPlacement) : false; | |
| if (!ignoreCrossAxisOverflow || | |
| // We leave the current main axis only if every placement on that axis | |
| // overflows the main axis. | |
| overflowsData.every(d => getSideAxis(d.placement) === initialSideAxis ? d.overflows[0] > 0 : true)) { | |
| // Try next placement and re-run the lifecycle. | |
| return { | |
| data: { | |
| index: nextIndex, | |
| overflows: overflowsData | |
| }, | |
| reset: { | |
| placement: nextPlacement | |
| } | |
| }; | |
| } | |
| } | |
| // First, find the candidates that fit on the mainAxis side of overflow, | |
| // then find the placement that fits the best on the main crossAxis side. | |
| 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; | |
| // Otherwise fallback. | |
| if (!resetPlacement) { | |
| switch (fallbackStrategy) { | |
| case 'bestFit': | |
| { | |
| var _overflowsData$filter2; | |
| const placement = (_overflowsData$filter2 = overflowsData.filter(d => { | |
| if (hasFallbackAxisSideDirection) { | |
| const currentSideAxis = getSideAxis(d.placement); | |
| return currentSideAxis === initialSideAxis || | |
| // Create a bias to the `y` side axis due to horizontal | |
| // reading directions favoring greater width. | |
| currentSideAxis === 'y'; | |
| } | |
| return true; | |
| }).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]; | |
| if (placement) { | |
| resetPlacement = placement; | |
| } | |
| break; | |
| } | |
| case 'initialPlacement': | |
| resetPlacement = initialPlacement; | |
| break; | |
| } | |
| } | |
| if (placement !== resetPlacement) { | |
| return { | |
| reset: { | |
| placement: resetPlacement | |
| } | |
| }; | |
| } | |
| } | |
| return {}; | |
| } | |
| }; | |
| }; | |
| function getSideOffsets(overflow, rect) { | |
| return { | |
| top: overflow.top - rect.height, | |
| right: overflow.right - rect.width, | |
| bottom: overflow.bottom - rect.height, | |
| left: overflow.left - rect.width | |
| }; | |
| } | |
| function isAnySideFullyClipped(overflow) { | |
| return sides.some(side => overflow[side] >= 0); | |
| } | |
| /** | |
| * Provides data to hide the floating element in applicable situations, such as | |
| * when it is not in the same clipping context as the reference element. | |
| * @see https://floating-ui.com/docs/hide | |
| */ | |
| const hide = function (options) { | |
| if (options === void 0) { | |
| options = {}; | |
| } | |
| return { | |
| name: 'hide', | |
| options, | |
| async fn(state) { | |
| const { | |
| rects, | |
| platform | |
| } = state; | |
| const { | |
| strategy = 'referenceHidden', | |
| ...detectOverflowOptions | |
| } = evaluate(options, state); | |
| switch (strategy) { | |
| case 'referenceHidden': | |
| { | |
| const overflow = await platform.detectOverflow(state, { | |
| ...detectOverflowOptions, | |
| elementContext: 'reference' | |
| }); | |
| const offsets = getSideOffsets(overflow, rects.reference); | |
| return { | |
| data: { | |
| referenceHiddenOffsets: offsets, | |
| referenceHidden: isAnySideFullyClipped(offsets) | |
| } | |
| }; | |
| } | |
| case 'escaped': | |
| { | |
| const overflow = await platform.detectOverflow(state, { | |
| ...detectOverflowOptions, | |
| altBoundary: true | |
| }); | |
| const offsets = getSideOffsets(overflow, rects.floating); | |
| return { | |
| data: { | |
| escapedOffsets: offsets, | |
| escaped: isAnySideFullyClipped(offsets) | |
| } | |
| }; | |
| } | |
| default: | |
| { | |
| return {}; | |
| } | |
| } | |
| } | |
| }; | |
| }; | |
| function getBoundingRect(rects) { | |
| const minX = min(...rects.map(rect => rect.left)); | |
| const minY = min(...rects.map(rect => rect.top)); | |
| const maxX = max(...rects.map(rect => rect.right)); | |
| const maxY = max(...rects.map(rect => rect.bottom)); | |
| return { | |
| x: minX, | |
| y: minY, | |
| width: maxX - minX, | |
| height: maxY - minY | |
| }; | |
| } | |
| function getRectsByLine(rects) { | |
| const sortedRects = rects.slice().sort((a, b) => a.y - b.y); | |
| const groups = []; | |
| let prevRect = null; | |
| for (let i = 0; i < sortedRects.length; i++) { | |
| const rect = sortedRects[i]; | |
| if (!prevRect || rect.y - prevRect.y > prevRect.height / 2) { | |
| groups.push([rect]); | |
| } else { | |
| groups[groups.length - 1].push(rect); | |
| } | |
| prevRect = rect; | |
| } | |
| return groups.map(rect => rectToClientRect(getBoundingRect(rect))); | |
| } | |
| /** | |
| * Provides improved positioning for inline reference elements that can span | |
| * over multiple lines, such as hyperlinks or range selections. | |
| * @see https://floating-ui.com/docs/inline | |
| */ | |
| const inline = function (options) { | |
| if (options === void 0) { | |
| options = {}; | |
| } | |
| return { | |
| name: 'inline', | |
| options, | |
| async fn(state) { | |
| const { | |
| placement, | |
| elements, | |
| rects, | |
| platform, | |
| strategy | |
| } = state; | |
| // A MouseEvent's client{X,Y} coords can be up to 2 pixels off a | |
| // ClientRect's bounds, despite the event listener being triggered. A | |
| // padding of 2 seems to handle this issue. | |
| const { | |
| padding = 2, | |
| x, | |
| y | |
| } = evaluate(options, state); | |
| const nativeClientRects = Array.from((await (platform.getClientRects == null ? void 0 : platform.getClientRects(elements.reference))) || []); | |
| // No rects (e.g. a hidden or detached reference, or a collapsed range) — | |
| // keep the existing reference rect rather than resetting to an invalid | |
| // one with non-finite values. | |
| if (!nativeClientRects.length) { | |
| return {}; | |
| } | |
| const clientRects = getRectsByLine(nativeClientRects); | |
| const fallback = rectToClientRect(getBoundingRect(nativeClientRects)); | |
| const paddingObject = getPaddingObject(padding); | |
| function getBoundingClientRect() { | |
| // There are two rects and they are disjoined. | |
| if (clientRects.length === 2 && (clientRects[0].left > clientRects[1].right || clientRects[1].left > clientRects[0].right) && x != null && y != null) { | |
| // Find the first rect in which the point is fully inside. | |
| 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; | |
| } | |
| // There are 2 or more connected rects. | |
| if (clientRects.length >= 2) { | |
| if (getSideAxis(placement) === 'y') { | |
| const firstRect = clientRects[0]; | |
| const lastRect = clientRects[clientRects.length - 1]; | |
| const isTop = getSide(placement) === 'top'; | |
| const top = firstRect.top; | |
| const bottom = lastRect.bottom; | |
| const left = isTop ? firstRect.left : lastRect.left; | |
| const right = isTop ? firstRect.right : lastRect.right; | |
| return rectToClientRect({ | |
| x: left, | |
| y: top, | |
| width: right - left, | |
| height: bottom - top | |
| }); | |
| } | |
| const isLeftSide = getSide(placement) === 'left'; | |
| const maxRight = max(...clientRects.map(rect => rect.right)); | |
| const minLeft = min(...clientRects.map(rect => rect.left)); | |
| const measureRects = clientRects.filter(rect => isLeftSide ? rect.left === minLeft : rect.right === maxRight); | |
| const top = measureRects[0].top; | |
| const bottom = measureRects[measureRects.length - 1].bottom; | |
| return rectToClientRect({ | |
| x: minLeft, | |
| y: top, | |
| width: maxRight - minLeft, | |
| height: bottom - top | |
| }); | |
| } | |
| return fallback; | |
| } | |
| const resetRects = await platform.getElementRects({ | |
| reference: { | |
| getBoundingClientRect | |
| }, | |
| floating: elements.floating, | |
| strategy | |
| }); | |
| 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) { | |
| return { | |
| reset: { | |
| rects: resetRects | |
| } | |
| }; | |
| } | |
| return {}; | |
| } | |
| }; | |
| }; | |
| const originSides = /*#__PURE__*/new Set(['left', 'top']); | |
| // For type backwards-compatibility, the `OffsetOptions` type was also | |
| // Derivable. | |
| async function convertValueToCoords(state, options) { | |
| const { | |
| placement, | |
| platform, | |
| elements | |
| } = state; | |
| const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating)); | |
| const side = getSide(placement); | |
| const alignment = getAlignment(placement); | |
| const isVertical = getSideAxis(placement) === 'y'; | |
| const mainAxisMulti = originSides.has(side) ? -1 : 1; | |
| const crossAxisMulti = rtl && isVertical ? -1 : 1; | |
| const rawValue = evaluate(options, state); | |
| // eslint-disable-next-line prefer-const | |
| let { | |
| mainAxis, | |
| crossAxis, | |
| alignmentAxis | |
| } = typeof rawValue === 'number' ? { | |
| mainAxis: rawValue, | |
| crossAxis: 0, | |
| alignmentAxis: null | |
| } : { | |
| mainAxis: rawValue.mainAxis || 0, | |
| crossAxis: rawValue.crossAxis || 0, | |
| alignmentAxis: rawValue.alignmentAxis | |
| }; | |
| if (alignment && typeof alignmentAxis === 'number') { | |
| crossAxis = alignment === 'end' ? alignmentAxis * -1 : alignmentAxis; | |
| } | |
| return isVertical ? { | |
| x: crossAxis * crossAxisMulti, | |
| y: mainAxis * mainAxisMulti | |
| } : { | |
| x: mainAxis * mainAxisMulti, | |
| y: crossAxis * crossAxisMulti | |
| }; | |
| } | |
| /** | |
| * Modifies the placement by translating the floating element along the | |
| * specified axes. | |
| * A number (shorthand for `mainAxis` or distance), or an axes configuration | |
| * object may be passed. | |
| * @see https://floating-ui.com/docs/offset | |
| */ | |
| const offset = function (options) { | |
| if (options === void 0) { | |
| options = 0; | |
| } | |
| return { | |
| name: 'offset', | |
| options, | |
| async fn(state) { | |
| var _middlewareData$offse, _middlewareData$arrow; | |
| const { | |
| x, | |
| y, | |
| placement, | |
| middlewareData | |
| } = state; | |
| const diffCoords = await convertValueToCoords(state, options); | |
| // If the placement is the same and the arrow caused an alignment offset | |
| // then we don't need to change the positioning coordinates. | |
| if (placement === ((_middlewareData$offse = middlewareData.offset) == null ? void 0 : _middlewareData$offse.placement) && (_middlewareData$arrow = middlewareData.arrow) != null && _middlewareData$arrow.alignmentOffset) { | |
| return {}; | |
| } | |
| return { | |
| x: x + diffCoords.x, | |
| y: y + diffCoords.y, | |
| data: { | |
| ...diffCoords, | |
| placement | |
| } | |
| }; | |
| } | |
| }; | |
| }; | |
| /** | |
| * Optimizes the visibility of the floating element by shifting it in order to | |
| * keep it in view when it will overflow the clipping boundary. | |
| * @see https://floating-ui.com/docs/shift | |
| */ | |
| const shift = function (options) { | |
| if (options === void 0) { | |
| options = {}; | |
| } | |
| return { | |
| name: 'shift', | |
| options, | |
| async fn(state) { | |
| const { | |
| x, | |
| y, | |
| placement, | |
| platform | |
| } = state; | |
| const { | |
| mainAxis: checkMainAxis = true, | |
| crossAxis: checkCrossAxis = false, | |
| limiter = { | |
| fn: _ref => { | |
| let { | |
| x, | |
| y | |
| } = _ref; | |
| return { | |
| x, | |
| y | |
| }; | |
| } | |
| }, | |
| ...detectOverflowOptions | |
| } = evaluate(options, state); | |
| const coords = { | |
| x, | |
| y | |
| }; | |
| const overflow = await platform.detectOverflow(state, detectOverflowOptions); | |
| const crossAxis = getSideAxis(placement); | |
| const mainAxis = getOppositeAxis(crossAxis); | |
| let mainAxisCoord = coords[mainAxis]; | |
| let crossAxisCoord = coords[crossAxis]; | |
| const clampCoord = (axis, coord) => clamp(coord + overflow[axis === 'y' ? 'top' : 'left'], coord, coord - overflow[axis === 'y' ? 'bottom' : 'right']); | |
| if (checkMainAxis) { | |
| mainAxisCoord = clampCoord(mainAxis, mainAxisCoord); | |
| } | |
| if (checkCrossAxis) { | |
| crossAxisCoord = clampCoord(crossAxis, crossAxisCoord); | |
| } | |
| const limitedCoords = limiter.fn({ | |
| ...state, | |
| [mainAxis]: mainAxisCoord, | |
| [crossAxis]: crossAxisCoord | |
| }); | |
| return { | |
| ...limitedCoords, | |
| data: { | |
| x: limitedCoords.x - x, | |
| y: limitedCoords.y - y, | |
| enabled: { | |
| [mainAxis]: checkMainAxis, | |
| [crossAxis]: checkCrossAxis | |
| } | |
| } | |
| }; | |
| } | |
| }; | |
| }; | |
| /** | |
| * Built-in `limiter` that will stop `shift()` at a certain point. | |
| */ | |
| const limitShift = function (options) { | |
| if (options === void 0) { | |
| options = {}; | |
| } | |
| return { | |
| options, | |
| fn(state) { | |
| var _rawOffset$mainAxis, _rawOffset$crossAxis; | |
| const { | |
| x, | |
| y, | |
| placement, | |
| rects, | |
| middlewareData | |
| } = state; | |
| const { | |
| offset = 0, | |
| mainAxis: checkMainAxis = true, | |
| crossAxis: checkCrossAxis = true | |
| } = evaluate(options, state); | |
| const coords = { | |
| x, | |
| y | |
| }; | |
| const crossAxis = getSideAxis(placement); | |
| const mainAxis = getOppositeAxis(crossAxis); | |
| let mainAxisCoord = coords[mainAxis]; | |
| let crossAxisCoord = coords[crossAxis]; | |
| const rawOffset = evaluate(offset, state); | |
| const computedOffset = typeof rawOffset === 'number' ? { | |
| mainAxis: rawOffset, | |
| crossAxis: 0 | |
| } : { | |
| mainAxis: (_rawOffset$mainAxis = rawOffset.mainAxis) != null ? _rawOffset$mainAxis : 0, | |
| crossAxis: (_rawOffset$crossAxis = rawOffset.crossAxis) != null ? _rawOffset$crossAxis : 0 | |
| }; | |
| if (checkMainAxis) { | |
| const len = mainAxis === 'y' ? 'height' : 'width'; | |
| const limitMin = rects.reference[mainAxis] - rects.floating[len] + computedOffset.mainAxis; | |
| const limitMax = rects.reference[mainAxis] + rects.reference[len] - computedOffset.mainAxis; | |
| if (mainAxisCoord < limitMin) { | |
| mainAxisCoord = limitMin; | |
| } else if (mainAxisCoord > limitMax) { | |
| mainAxisCoord = limitMax; | |
| } | |
| } | |
| if (checkCrossAxis) { | |
| var _middlewareData$offse, _middlewareData$offse2; | |
| const len = mainAxis === 'y' ? 'width' : 'height'; | |
| const isOriginSide = originSides.has(getSide(placement)); | |
| 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); | |
| 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); | |
| if (crossAxisCoord < limitMin) { | |
| crossAxisCoord = limitMin; | |
| } else if (crossAxisCoord > limitMax) { | |
| crossAxisCoord = limitMax; | |
| } | |
| } | |
| return { | |
| [mainAxis]: mainAxisCoord, | |
| [crossAxis]: crossAxisCoord | |
| }; | |
| } | |
| }; | |
| }; | |
| // Method syntax keeps callback parameters bivariant, but expressing the | |
| // explicit `| undefined` required by `exactOptionalPropertyTypes` needs | |
| // property syntax, which is contravariant under `strictFunctionTypes`. | |
| // Extracting the function from a method position restores that bivariance so | |
| // consumers can still assign callbacks with narrower parameter types. | |
| /** | |
| * Provides data that allows you to change the size of the floating element — | |
| * for instance, prevent it from overflowing the clipping boundary or match the | |
| * width of the reference element. | |
| * @see https://floating-ui.com/docs/size | |
| */ | |
| const size = function (options) { | |
| if (options === void 0) { | |
| options = {}; | |
| } | |
| return { | |
| name: 'size', | |
| options, | |
| async fn(state) { | |
| const { | |
| placement, | |
| rects, | |
| platform, | |
| elements | |
| } = state; | |
| const { | |
| apply = () => {}, | |
| ...detectOverflowOptions | |
| } = evaluate(options, state); | |
| const overflow = await platform.detectOverflow(state, detectOverflowOptions); | |
| const side = getSide(placement); | |
| const alignment = getAlignment(placement); | |
| const isYAxis = getSideAxis(placement) === 'y'; | |
| const { | |
| width, | |
| height | |
| } = rects.floating; | |
| let heightSide; | |
| let widthSide; | |
| if (side === 'top' || side === 'bottom') { | |
| heightSide = side; | |
| widthSide = alignment === ((await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating))) ? 'start' : 'end') ? 'left' : 'right'; | |
| } else { | |
| widthSide = side; | |
| heightSide = alignment === 'end' ? 'top' : 'bottom'; | |
| } | |
| const maximumClippingHeight = height - overflow.top - overflow.bottom; | |
| const maximumClippingWidth = width - overflow.left - overflow.right; | |
| const overflowAvailableHeight = min(height - overflow[heightSide], maximumClippingHeight); | |
| const overflowAvailableWidth = min(width - overflow[widthSide], maximumClippingWidth); | |
| const shiftData = state.middlewareData.shift; | |
| const noShift = !shiftData; | |
| let availableHeight = overflowAvailableHeight; | |
| let availableWidth = overflowAvailableWidth; | |
| if (shiftData != null && shiftData.enabled.x) { | |
| availableWidth = maximumClippingWidth; | |
| } | |
| if (shiftData != null && shiftData.enabled.y) { | |
| availableHeight = maximumClippingHeight; | |
| } | |
| if (noShift && !alignment) { | |
| if (isYAxis) { | |
| availableWidth = width - 2 * max(overflow.left, overflow.right); | |
| } else { | |
| availableHeight = height - 2 * max(overflow.top, overflow.bottom); | |
| } | |
| } | |
| await apply({ | |
| ...state, | |
| availableWidth, | |
| availableHeight | |
| }); | |
| const nextDimensions = await platform.getDimensions(elements.floating); | |
| if (width !== nextDimensions.width || height !== nextDimensions.height) { | |
| return { | |
| reset: { | |
| rects: true | |
| } | |
| }; | |
| } | |
| return {}; | |
| } | |
| }; | |
| }; | |
| export { arrow, autoPlacement, computePosition, detectOverflow, flip, hide, inline, limitShift, offset, rectToClientRect, shift, size }; | |