3464 lines
122 KiB
JavaScript
3464 lines
122 KiB
JavaScript
"use client";
|
|
import {
|
|
Combination_default,
|
|
DismissableLayer,
|
|
FocusScope,
|
|
Portal,
|
|
hideOthers,
|
|
useFocusGuards
|
|
} from "./chunk-ZI3ABUEZ.js";
|
|
import {
|
|
useCallbackRef,
|
|
useId
|
|
} from "./chunk-F2GLZ5N4.js";
|
|
import {
|
|
clamp
|
|
} from "./chunk-QSHREGVI.js";
|
|
import {
|
|
createCollection,
|
|
useDirection
|
|
} from "./chunk-3YHVK7S6.js";
|
|
import {
|
|
usePrevious,
|
|
useSize
|
|
} from "./chunk-LRHVP6W3.js";
|
|
import {
|
|
Primitive,
|
|
composeEventHandlers,
|
|
createContextScope,
|
|
createSlot,
|
|
useControllableState,
|
|
useLayoutEffect2
|
|
} from "./chunk-DRHL3CIY.js";
|
|
import {
|
|
useComposedRefs
|
|
} from "./chunk-XYHIF63Q.js";
|
|
import {
|
|
require_jsx_runtime
|
|
} from "./chunk-NNZQKBPS.js";
|
|
import {
|
|
require_react_dom
|
|
} from "./chunk-BH4GTE34.js";
|
|
import {
|
|
require_react
|
|
} from "./chunk-2OBKLRK6.js";
|
|
import {
|
|
__toESM
|
|
} from "./chunk-G3PMV62Z.js";
|
|
|
|
// node_modules/.pnpm/@radix-ui+react-select@2.2._f9b05e8db7247fc075715ae52301583d/node_modules/@radix-ui/react-select/dist/index.mjs
|
|
var React5 = __toESM(require_react(), 1);
|
|
var ReactDOM2 = __toESM(require_react_dom(), 1);
|
|
|
|
// node_modules/.pnpm/@radix-ui+react-popper@1.2._670e32d9a64ee24e3a22b3ad7ddf00ff/node_modules/@radix-ui/react-popper/dist/index.mjs
|
|
var React3 = __toESM(require_react(), 1);
|
|
|
|
// node_modules/.pnpm/@floating-ui+utils@0.2.10/node_modules/@floating-ui/utils/dist/floating-ui.utils.mjs
|
|
var sides = ["top", "right", "bottom", "left"];
|
|
var alignments = ["start", "end"];
|
|
var placements = sides.reduce((acc, side) => acc.concat(side, side + "-" + alignments[0], side + "-" + alignments[1]), []);
|
|
var min = Math.min;
|
|
var max = Math.max;
|
|
var round = Math.round;
|
|
var floor = Math.floor;
|
|
var createCoords = (v) => ({
|
|
x: v,
|
|
y: v
|
|
});
|
|
var oppositeSideMap = {
|
|
left: "right",
|
|
right: "left",
|
|
bottom: "top",
|
|
top: "bottom"
|
|
};
|
|
var oppositeAlignmentMap = {
|
|
start: "end",
|
|
end: "start"
|
|
};
|
|
function clamp2(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";
|
|
}
|
|
var yAxisSides = /* @__PURE__ */ new Set(["top", "bottom"]);
|
|
function getSideAxis(placement) {
|
|
return yAxisSides.has(getSide(placement)) ? "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.replace(/start|end/g, (alignment) => oppositeAlignmentMap[alignment]);
|
|
}
|
|
var lrPlacement = ["left", "right"];
|
|
var rlPlacement = ["right", "left"];
|
|
var tbPlacement = ["top", "bottom"];
|
|
var 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) {
|
|
return placement.replace(/left|right|bottom|top/g, (side) => oppositeSideMap[side]);
|
|
}
|
|
function expandPaddingObject(padding) {
|
|
return {
|
|
top: 0,
|
|
right: 0,
|
|
bottom: 0,
|
|
left: 0,
|
|
...padding
|
|
};
|
|
}
|
|
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
|
|
};
|
|
}
|
|
|
|
// node_modules/.pnpm/@floating-ui+core@1.7.4/node_modules/@floating-ui/core/dist/floating-ui.core.mjs
|
|
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
|
|
};
|
|
}
|
|
switch (getAlignment(placement)) {
|
|
case "start":
|
|
coords[alignmentAxis] -= commonAlign * (rtl && isVertical ? -1 : 1);
|
|
break;
|
|
case "end":
|
|
coords[alignmentAxis] += commonAlign * (rtl && isVertical ? -1 : 1);
|
|
break;
|
|
}
|
|
return coords;
|
|
}
|
|
async function detectOverflow(state, options) {
|
|
var _await$platform$isEle;
|
|
if (options === void 0) {
|
|
options = {};
|
|
}
|
|
const {
|
|
x,
|
|
y,
|
|
platform: platform2,
|
|
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 platform2.getClippingRect({
|
|
element: ((_await$platform$isEle = await (platform2.isElement == null ? void 0 : platform2.isElement(element))) != null ? _await$platform$isEle : true) ? element : element.contextElement || await (platform2.getDocumentElement == null ? void 0 : platform2.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 (platform2.getOffsetParent == null ? void 0 : platform2.getOffsetParent(elements.floating));
|
|
const offsetScale = await (platform2.isElement == null ? void 0 : platform2.isElement(offsetParent)) ? await (platform2.getScale == null ? void 0 : platform2.getScale(offsetParent)) || {
|
|
x: 1,
|
|
y: 1
|
|
} : {
|
|
x: 1,
|
|
y: 1
|
|
};
|
|
const elementClientRect = rectToClientRect(platform2.convertOffsetParentRelativeRectToViewportRelativeRect ? await platform2.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
|
|
};
|
|
}
|
|
var computePosition = async (reference, floating, config) => {
|
|
const {
|
|
placement = "bottom",
|
|
strategy = "absolute",
|
|
middleware = [],
|
|
platform: platform2
|
|
} = config;
|
|
const validMiddleware = middleware.filter(Boolean);
|
|
const rtl = await (platform2.isRTL == null ? void 0 : platform2.isRTL(floating));
|
|
let rects = await platform2.getElementRects({
|
|
reference,
|
|
floating,
|
|
strategy
|
|
});
|
|
let {
|
|
x,
|
|
y
|
|
} = computeCoordsFromPlacement(rects, placement, rtl);
|
|
let statefulPlacement = placement;
|
|
let middlewareData = {};
|
|
let resetCount = 0;
|
|
for (let i = 0; i < validMiddleware.length; i++) {
|
|
var _platform$detectOverf;
|
|
const {
|
|
name,
|
|
fn
|
|
} = validMiddleware[i];
|
|
const {
|
|
x: nextX,
|
|
y: nextY,
|
|
data,
|
|
reset
|
|
} = await fn({
|
|
x,
|
|
y,
|
|
initialPlacement: placement,
|
|
placement: statefulPlacement,
|
|
strategy,
|
|
middlewareData,
|
|
rects,
|
|
platform: {
|
|
...platform2,
|
|
detectOverflow: (_platform$detectOverf = platform2.detectOverflow) != null ? _platform$detectOverf : detectOverflow
|
|
},
|
|
elements: {
|
|
reference,
|
|
floating
|
|
}
|
|
});
|
|
x = nextX != null ? nextX : x;
|
|
y = nextY != null ? nextY : y;
|
|
middlewareData = {
|
|
...middlewareData,
|
|
[name]: {
|
|
...middlewareData[name],
|
|
...data
|
|
}
|
|
};
|
|
if (reset && resetCount <= 50) {
|
|
resetCount++;
|
|
if (typeof reset === "object") {
|
|
if (reset.placement) {
|
|
statefulPlacement = reset.placement;
|
|
}
|
|
if (reset.rects) {
|
|
rects = reset.rects === true ? await platform2.getElementRects({
|
|
reference,
|
|
floating,
|
|
strategy
|
|
}) : reset.rects;
|
|
}
|
|
({
|
|
x,
|
|
y
|
|
} = computeCoordsFromPlacement(rects, statefulPlacement, rtl));
|
|
}
|
|
i = -1;
|
|
}
|
|
}
|
|
return {
|
|
x,
|
|
y,
|
|
placement: statefulPlacement,
|
|
strategy,
|
|
middlewareData
|
|
};
|
|
};
|
|
var arrow = (options) => ({
|
|
name: "arrow",
|
|
options,
|
|
async fn(state) {
|
|
const {
|
|
x,
|
|
y,
|
|
placement,
|
|
rects,
|
|
platform: platform2,
|
|
elements,
|
|
middlewareData
|
|
} = state;
|
|
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 platform2.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 (platform2.getOffsetParent == null ? void 0 : platform2.getOffsetParent(element));
|
|
let clientSize = arrowOffsetParent ? arrowOffsetParent[clientProp] : 0;
|
|
if (!clientSize || !await (platform2.isElement == null ? void 0 : platform2.isElement(arrowOffsetParent))) {
|
|
clientSize = elements.floating[clientProp] || rects.floating[length];
|
|
}
|
|
const centerToReference = endDiff / 2 - startDiff / 2;
|
|
const largestPossiblePadding = clientSize / 2 - arrowDimensions[length] / 2 - 1;
|
|
const minPadding = min(paddingObject[minProp], largestPossiblePadding);
|
|
const maxPadding = min(paddingObject[maxProp], largestPossiblePadding);
|
|
const min$1 = minPadding;
|
|
const max2 = clientSize - arrowDimensions[length] - maxPadding;
|
|
const center = clientSize / 2 - arrowDimensions[length] / 2 + centerToReference;
|
|
const offset4 = clamp2(min$1, center, max2);
|
|
const shouldAddOffset = !middlewareData.arrow && getAlignment(placement) != null && center !== offset4 && rects.reference[length] / 2 - (center < min$1 ? minPadding : maxPadding) - arrowDimensions[length] / 2 < 0;
|
|
const alignmentOffset = shouldAddOffset ? center < min$1 ? center - min$1 : center - max2 : 0;
|
|
return {
|
|
[axis]: coords[axis] + alignmentOffset,
|
|
data: {
|
|
[axis]: offset4,
|
|
centerOffset: center - offset4 - alignmentOffset,
|
|
...shouldAddOffset && {
|
|
alignmentOffset
|
|
}
|
|
},
|
|
reset: shouldAddOffset
|
|
};
|
|
}
|
|
});
|
|
var 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: platform2,
|
|
elements
|
|
} = state;
|
|
const {
|
|
mainAxis: checkMainAxis = true,
|
|
crossAxis: checkCrossAxis = true,
|
|
fallbackPlacements: specifiedFallbackPlacements,
|
|
fallbackStrategy = "bestFit",
|
|
fallbackAxisSideDirection = "none",
|
|
flipAlignment = true,
|
|
...detectOverflowOptions
|
|
} = evaluate(options, state);
|
|
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 (platform2.isRTL == null ? void 0 : platform2.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 placements2 = [initialPlacement, ...fallbackPlacements];
|
|
const overflow = await platform2.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 sides2 = getAlignmentSides(placement, rects, rtl);
|
|
overflows.push(overflow[sides2[0]], overflow[sides2[1]]);
|
|
}
|
|
overflowsData = [...overflowsData, {
|
|
placement,
|
|
overflows
|
|
}];
|
|
if (!overflows.every((side2) => side2 <= 0)) {
|
|
var _middlewareData$flip2, _overflowsData$filter;
|
|
const nextIndex = (((_middlewareData$flip2 = middlewareData.flip) == null ? void 0 : _middlewareData$flip2.index) || 0) + 1;
|
|
const nextPlacement = placements2[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)) {
|
|
return {
|
|
data: {
|
|
index: nextIndex,
|
|
overflows: overflowsData
|
|
},
|
|
reset: {
|
|
placement: nextPlacement
|
|
}
|
|
};
|
|
}
|
|
}
|
|
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;
|
|
if (!resetPlacement) {
|
|
switch (fallbackStrategy) {
|
|
case "bestFit": {
|
|
var _overflowsData$filter2;
|
|
const placement2 = (_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((overflow2) => overflow2 > 0).reduce((acc, overflow2) => acc + overflow2, 0)]).sort((a, b) => a[1] - b[1])[0]) == null ? void 0 : _overflowsData$filter2[0];
|
|
if (placement2) {
|
|
resetPlacement = placement2;
|
|
}
|
|
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);
|
|
}
|
|
var hide = function(options) {
|
|
if (options === void 0) {
|
|
options = {};
|
|
}
|
|
return {
|
|
name: "hide",
|
|
options,
|
|
async fn(state) {
|
|
const {
|
|
rects,
|
|
platform: platform2
|
|
} = state;
|
|
const {
|
|
strategy = "referenceHidden",
|
|
...detectOverflowOptions
|
|
} = evaluate(options, state);
|
|
switch (strategy) {
|
|
case "referenceHidden": {
|
|
const overflow = await platform2.detectOverflow(state, {
|
|
...detectOverflowOptions,
|
|
elementContext: "reference"
|
|
});
|
|
const offsets = getSideOffsets(overflow, rects.reference);
|
|
return {
|
|
data: {
|
|
referenceHiddenOffsets: offsets,
|
|
referenceHidden: isAnySideFullyClipped(offsets)
|
|
}
|
|
};
|
|
}
|
|
case "escaped": {
|
|
const overflow = await platform2.detectOverflow(state, {
|
|
...detectOverflowOptions,
|
|
altBoundary: true
|
|
});
|
|
const offsets = getSideOffsets(overflow, rects.floating);
|
|
return {
|
|
data: {
|
|
escapedOffsets: offsets,
|
|
escaped: isAnySideFullyClipped(offsets)
|
|
}
|
|
};
|
|
}
|
|
default: {
|
|
return {};
|
|
}
|
|
}
|
|
}
|
|
};
|
|
};
|
|
var originSides = /* @__PURE__ */ new Set(["left", "top"]);
|
|
async function convertValueToCoords(state, options) {
|
|
const {
|
|
placement,
|
|
platform: platform2,
|
|
elements
|
|
} = state;
|
|
const rtl = await (platform2.isRTL == null ? void 0 : platform2.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);
|
|
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
|
|
};
|
|
}
|
|
var 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 (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
|
|
}
|
|
};
|
|
}
|
|
};
|
|
};
|
|
var shift = function(options) {
|
|
if (options === void 0) {
|
|
options = {};
|
|
}
|
|
return {
|
|
name: "shift",
|
|
options,
|
|
async fn(state) {
|
|
const {
|
|
x,
|
|
y,
|
|
placement,
|
|
platform: platform2
|
|
} = state;
|
|
const {
|
|
mainAxis: checkMainAxis = true,
|
|
crossAxis: checkCrossAxis = false,
|
|
limiter = {
|
|
fn: (_ref) => {
|
|
let {
|
|
x: x2,
|
|
y: y2
|
|
} = _ref;
|
|
return {
|
|
x: x2,
|
|
y: y2
|
|
};
|
|
}
|
|
},
|
|
...detectOverflowOptions
|
|
} = evaluate(options, state);
|
|
const coords = {
|
|
x,
|
|
y
|
|
};
|
|
const overflow = await platform2.detectOverflow(state, detectOverflowOptions);
|
|
const crossAxis = getSideAxis(getSide(placement));
|
|
const mainAxis = getOppositeAxis(crossAxis);
|
|
let mainAxisCoord = coords[mainAxis];
|
|
let crossAxisCoord = coords[crossAxis];
|
|
if (checkMainAxis) {
|
|
const minSide = mainAxis === "y" ? "top" : "left";
|
|
const maxSide = mainAxis === "y" ? "bottom" : "right";
|
|
const min2 = mainAxisCoord + overflow[minSide];
|
|
const max2 = mainAxisCoord - overflow[maxSide];
|
|
mainAxisCoord = clamp2(min2, mainAxisCoord, max2);
|
|
}
|
|
if (checkCrossAxis) {
|
|
const minSide = crossAxis === "y" ? "top" : "left";
|
|
const maxSide = crossAxis === "y" ? "bottom" : "right";
|
|
const min2 = crossAxisCoord + overflow[minSide];
|
|
const max2 = crossAxisCoord - overflow[maxSide];
|
|
crossAxisCoord = clamp2(min2, crossAxisCoord, max2);
|
|
}
|
|
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
|
|
}
|
|
}
|
|
};
|
|
}
|
|
};
|
|
};
|
|
var limitShift = function(options) {
|
|
if (options === void 0) {
|
|
options = {};
|
|
}
|
|
return {
|
|
options,
|
|
fn(state) {
|
|
const {
|
|
x,
|
|
y,
|
|
placement,
|
|
rects,
|
|
middlewareData
|
|
} = state;
|
|
const {
|
|
offset: offset4 = 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(offset4, state);
|
|
const computedOffset = typeof rawOffset === "number" ? {
|
|
mainAxis: rawOffset,
|
|
crossAxis: 0
|
|
} : {
|
|
mainAxis: 0,
|
|
crossAxis: 0,
|
|
...rawOffset
|
|
};
|
|
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
|
|
};
|
|
}
|
|
};
|
|
};
|
|
var size = function(options) {
|
|
if (options === void 0) {
|
|
options = {};
|
|
}
|
|
return {
|
|
name: "size",
|
|
options,
|
|
async fn(state) {
|
|
var _state$middlewareData, _state$middlewareData2;
|
|
const {
|
|
placement,
|
|
rects,
|
|
platform: platform2,
|
|
elements
|
|
} = state;
|
|
const {
|
|
apply = () => {
|
|
},
|
|
...detectOverflowOptions
|
|
} = evaluate(options, state);
|
|
const overflow = await platform2.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 (platform2.isRTL == null ? void 0 : platform2.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 noShift = !state.middlewareData.shift;
|
|
let availableHeight = overflowAvailableHeight;
|
|
let availableWidth = overflowAvailableWidth;
|
|
if ((_state$middlewareData = state.middlewareData.shift) != null && _state$middlewareData.enabled.x) {
|
|
availableWidth = maximumClippingWidth;
|
|
}
|
|
if ((_state$middlewareData2 = state.middlewareData.shift) != null && _state$middlewareData2.enabled.y) {
|
|
availableHeight = maximumClippingHeight;
|
|
}
|
|
if (noShift && !alignment) {
|
|
const xMin = max(overflow.left, 0);
|
|
const xMax = max(overflow.right, 0);
|
|
const yMin = max(overflow.top, 0);
|
|
const yMax = max(overflow.bottom, 0);
|
|
if (isYAxis) {
|
|
availableWidth = width - 2 * (xMin !== 0 || xMax !== 0 ? xMin + xMax : max(overflow.left, overflow.right));
|
|
} else {
|
|
availableHeight = height - 2 * (yMin !== 0 || yMax !== 0 ? yMin + yMax : max(overflow.top, overflow.bottom));
|
|
}
|
|
}
|
|
await apply({
|
|
...state,
|
|
availableWidth,
|
|
availableHeight
|
|
});
|
|
const nextDimensions = await platform2.getDimensions(elements.floating);
|
|
if (width !== nextDimensions.width || height !== nextDimensions.height) {
|
|
return {
|
|
reset: {
|
|
rects: true
|
|
}
|
|
};
|
|
}
|
|
return {};
|
|
}
|
|
};
|
|
};
|
|
|
|
// node_modules/.pnpm/@floating-ui+utils@0.2.10/node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.mjs
|
|
function hasWindow() {
|
|
return typeof window !== "undefined";
|
|
}
|
|
function getNodeName(node) {
|
|
if (isNode(node)) {
|
|
return (node.nodeName || "").toLowerCase();
|
|
}
|
|
return "#document";
|
|
}
|
|
function getWindow(node) {
|
|
var _node$ownerDocument;
|
|
return (node == null || (_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;
|
|
}
|
|
function getDocumentElement(node) {
|
|
var _ref;
|
|
return (_ref = (isNode(node) ? node.ownerDocument : node.document) || window.document) == null ? void 0 : _ref.documentElement;
|
|
}
|
|
function isNode(value) {
|
|
if (!hasWindow()) {
|
|
return false;
|
|
}
|
|
return value instanceof Node || value instanceof getWindow(value).Node;
|
|
}
|
|
function isElement(value) {
|
|
if (!hasWindow()) {
|
|
return false;
|
|
}
|
|
return value instanceof Element || value instanceof getWindow(value).Element;
|
|
}
|
|
function isHTMLElement(value) {
|
|
if (!hasWindow()) {
|
|
return false;
|
|
}
|
|
return value instanceof HTMLElement || value instanceof getWindow(value).HTMLElement;
|
|
}
|
|
function isShadowRoot(value) {
|
|
if (!hasWindow() || typeof ShadowRoot === "undefined") {
|
|
return false;
|
|
}
|
|
return value instanceof ShadowRoot || value instanceof getWindow(value).ShadowRoot;
|
|
}
|
|
var invalidOverflowDisplayValues = /* @__PURE__ */ new Set(["inline", "contents"]);
|
|
function isOverflowElement(element) {
|
|
const {
|
|
overflow,
|
|
overflowX,
|
|
overflowY,
|
|
display
|
|
} = getComputedStyle2(element);
|
|
return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && !invalidOverflowDisplayValues.has(display);
|
|
}
|
|
var tableElements = /* @__PURE__ */ new Set(["table", "td", "th"]);
|
|
function isTableElement(element) {
|
|
return tableElements.has(getNodeName(element));
|
|
}
|
|
var topLayerSelectors = [":popover-open", ":modal"];
|
|
function isTopLayer(element) {
|
|
return topLayerSelectors.some((selector) => {
|
|
try {
|
|
return element.matches(selector);
|
|
} catch (_e) {
|
|
return false;
|
|
}
|
|
});
|
|
}
|
|
var transformProperties = ["transform", "translate", "scale", "rotate", "perspective"];
|
|
var willChangeValues = ["transform", "translate", "scale", "rotate", "perspective", "filter"];
|
|
var containValues = ["paint", "layout", "strict", "content"];
|
|
function isContainingBlock(elementOrCss) {
|
|
const webkit = isWebKit();
|
|
const css = isElement(elementOrCss) ? getComputedStyle2(elementOrCss) : elementOrCss;
|
|
return transformProperties.some((value) => css[value] ? css[value] !== "none" : false) || (css.containerType ? css.containerType !== "normal" : false) || !webkit && (css.backdropFilter ? css.backdropFilter !== "none" : false) || !webkit && (css.filter ? css.filter !== "none" : false) || willChangeValues.some((value) => (css.willChange || "").includes(value)) || containValues.some((value) => (css.contain || "").includes(value));
|
|
}
|
|
function getContainingBlock(element) {
|
|
let currentNode = getParentNode(element);
|
|
while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {
|
|
if (isContainingBlock(currentNode)) {
|
|
return currentNode;
|
|
} else if (isTopLayer(currentNode)) {
|
|
return null;
|
|
}
|
|
currentNode = getParentNode(currentNode);
|
|
}
|
|
return null;
|
|
}
|
|
function isWebKit() {
|
|
if (typeof CSS === "undefined" || !CSS.supports) return false;
|
|
return CSS.supports("-webkit-backdrop-filter", "none");
|
|
}
|
|
var lastTraversableNodeNames = /* @__PURE__ */ new Set(["html", "body", "#document"]);
|
|
function isLastTraversableNode(node) {
|
|
return lastTraversableNodeNames.has(getNodeName(node));
|
|
}
|
|
function getComputedStyle2(element) {
|
|
return getWindow(element).getComputedStyle(element);
|
|
}
|
|
function getNodeScroll(element) {
|
|
if (isElement(element)) {
|
|
return {
|
|
scrollLeft: element.scrollLeft,
|
|
scrollTop: element.scrollTop
|
|
};
|
|
}
|
|
return {
|
|
scrollLeft: element.scrollX,
|
|
scrollTop: element.scrollY
|
|
};
|
|
}
|
|
function getParentNode(node) {
|
|
if (getNodeName(node) === "html") {
|
|
return node;
|
|
}
|
|
const result = (
|
|
// Step into the shadow DOM of the parent of a slotted node.
|
|
node.assignedSlot || // DOM Element detected.
|
|
node.parentNode || // ShadowRoot detected.
|
|
isShadowRoot(node) && node.host || // Fallback.
|
|
getDocumentElement(node)
|
|
);
|
|
return isShadowRoot(result) ? result.host : result;
|
|
}
|
|
function getNearestOverflowAncestor(node) {
|
|
const parentNode = getParentNode(node);
|
|
if (isLastTraversableNode(parentNode)) {
|
|
return node.ownerDocument ? node.ownerDocument.body : node.body;
|
|
}
|
|
if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) {
|
|
return parentNode;
|
|
}
|
|
return getNearestOverflowAncestor(parentNode);
|
|
}
|
|
function getOverflowAncestors(node, list, traverseIframes) {
|
|
var _node$ownerDocument2;
|
|
if (list === void 0) {
|
|
list = [];
|
|
}
|
|
if (traverseIframes === void 0) {
|
|
traverseIframes = true;
|
|
}
|
|
const scrollableAncestor = getNearestOverflowAncestor(node);
|
|
const isBody = scrollableAncestor === ((_node$ownerDocument2 = node.ownerDocument) == null ? void 0 : _node$ownerDocument2.body);
|
|
const win = getWindow(scrollableAncestor);
|
|
if (isBody) {
|
|
const frameElement = getFrameElement(win);
|
|
return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : [], frameElement && traverseIframes ? getOverflowAncestors(frameElement) : []);
|
|
}
|
|
return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, [], traverseIframes));
|
|
}
|
|
function getFrameElement(win) {
|
|
return win.parent && Object.getPrototypeOf(win.parent) ? win.frameElement : null;
|
|
}
|
|
|
|
// node_modules/.pnpm/@floating-ui+dom@1.7.5/node_modules/@floating-ui/dom/dist/floating-ui.dom.mjs
|
|
function getCssDimensions(element) {
|
|
const css = getComputedStyle2(element);
|
|
let width = parseFloat(css.width) || 0;
|
|
let height = parseFloat(css.height) || 0;
|
|
const hasOffset = isHTMLElement(element);
|
|
const offsetWidth = hasOffset ? element.offsetWidth : width;
|
|
const offsetHeight = hasOffset ? element.offsetHeight : height;
|
|
const shouldFallback = round(width) !== offsetWidth || round(height) !== offsetHeight;
|
|
if (shouldFallback) {
|
|
width = offsetWidth;
|
|
height = offsetHeight;
|
|
}
|
|
return {
|
|
width,
|
|
height,
|
|
$: shouldFallback
|
|
};
|
|
}
|
|
function unwrapElement(element) {
|
|
return !isElement(element) ? element.contextElement : element;
|
|
}
|
|
function getScale(element) {
|
|
const domElement = unwrapElement(element);
|
|
if (!isHTMLElement(domElement)) {
|
|
return createCoords(1);
|
|
}
|
|
const rect = domElement.getBoundingClientRect();
|
|
const {
|
|
width,
|
|
height,
|
|
$
|
|
} = getCssDimensions(domElement);
|
|
let x = ($ ? round(rect.width) : rect.width) / width;
|
|
let y = ($ ? round(rect.height) : rect.height) / height;
|
|
if (!x || !Number.isFinite(x)) {
|
|
x = 1;
|
|
}
|
|
if (!y || !Number.isFinite(y)) {
|
|
y = 1;
|
|
}
|
|
return {
|
|
x,
|
|
y
|
|
};
|
|
}
|
|
var noOffsets = createCoords(0);
|
|
function getVisualOffsets(element) {
|
|
const win = getWindow(element);
|
|
if (!isWebKit() || !win.visualViewport) {
|
|
return noOffsets;
|
|
}
|
|
return {
|
|
x: win.visualViewport.offsetLeft,
|
|
y: win.visualViewport.offsetTop
|
|
};
|
|
}
|
|
function shouldAddVisualOffsets(element, isFixed, floatingOffsetParent) {
|
|
if (isFixed === void 0) {
|
|
isFixed = false;
|
|
}
|
|
if (!floatingOffsetParent || isFixed && floatingOffsetParent !== getWindow(element)) {
|
|
return false;
|
|
}
|
|
return isFixed;
|
|
}
|
|
function getBoundingClientRect(element, includeScale, isFixedStrategy, offsetParent) {
|
|
if (includeScale === void 0) {
|
|
includeScale = false;
|
|
}
|
|
if (isFixedStrategy === void 0) {
|
|
isFixedStrategy = false;
|
|
}
|
|
const clientRect = element.getBoundingClientRect();
|
|
const domElement = unwrapElement(element);
|
|
let scale = createCoords(1);
|
|
if (includeScale) {
|
|
if (offsetParent) {
|
|
if (isElement(offsetParent)) {
|
|
scale = getScale(offsetParent);
|
|
}
|
|
} else {
|
|
scale = getScale(element);
|
|
}
|
|
}
|
|
const visualOffsets = shouldAddVisualOffsets(domElement, isFixedStrategy, offsetParent) ? getVisualOffsets(domElement) : createCoords(0);
|
|
let x = (clientRect.left + visualOffsets.x) / scale.x;
|
|
let y = (clientRect.top + visualOffsets.y) / scale.y;
|
|
let width = clientRect.width / scale.x;
|
|
let height = clientRect.height / scale.y;
|
|
if (domElement) {
|
|
const win = getWindow(domElement);
|
|
const offsetWin = offsetParent && isElement(offsetParent) ? getWindow(offsetParent) : offsetParent;
|
|
let currentWin = win;
|
|
let currentIFrame = getFrameElement(currentWin);
|
|
while (currentIFrame && offsetParent && offsetWin !== currentWin) {
|
|
const iframeScale = getScale(currentIFrame);
|
|
const iframeRect = currentIFrame.getBoundingClientRect();
|
|
const css = getComputedStyle2(currentIFrame);
|
|
const left = iframeRect.left + (currentIFrame.clientLeft + parseFloat(css.paddingLeft)) * iframeScale.x;
|
|
const top = iframeRect.top + (currentIFrame.clientTop + parseFloat(css.paddingTop)) * iframeScale.y;
|
|
x *= iframeScale.x;
|
|
y *= iframeScale.y;
|
|
width *= iframeScale.x;
|
|
height *= iframeScale.y;
|
|
x += left;
|
|
y += top;
|
|
currentWin = getWindow(currentIFrame);
|
|
currentIFrame = getFrameElement(currentWin);
|
|
}
|
|
}
|
|
return rectToClientRect({
|
|
width,
|
|
height,
|
|
x,
|
|
y
|
|
});
|
|
}
|
|
function getWindowScrollBarX(element, rect) {
|
|
const leftScroll = getNodeScroll(element).scrollLeft;
|
|
if (!rect) {
|
|
return getBoundingClientRect(getDocumentElement(element)).left + leftScroll;
|
|
}
|
|
return rect.left + leftScroll;
|
|
}
|
|
function getHTMLOffset(documentElement, scroll) {
|
|
const htmlRect = documentElement.getBoundingClientRect();
|
|
const x = htmlRect.left + scroll.scrollLeft - getWindowScrollBarX(documentElement, htmlRect);
|
|
const y = htmlRect.top + scroll.scrollTop;
|
|
return {
|
|
x,
|
|
y
|
|
};
|
|
}
|
|
function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) {
|
|
let {
|
|
elements,
|
|
rect,
|
|
offsetParent,
|
|
strategy
|
|
} = _ref;
|
|
const isFixed = strategy === "fixed";
|
|
const documentElement = getDocumentElement(offsetParent);
|
|
const topLayer = elements ? isTopLayer(elements.floating) : false;
|
|
if (offsetParent === documentElement || topLayer && isFixed) {
|
|
return rect;
|
|
}
|
|
let scroll = {
|
|
scrollLeft: 0,
|
|
scrollTop: 0
|
|
};
|
|
let scale = createCoords(1);
|
|
const offsets = createCoords(0);
|
|
const isOffsetParentAnElement = isHTMLElement(offsetParent);
|
|
if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
|
|
if (getNodeName(offsetParent) !== "body" || isOverflowElement(documentElement)) {
|
|
scroll = getNodeScroll(offsetParent);
|
|
}
|
|
if (isHTMLElement(offsetParent)) {
|
|
const offsetRect = getBoundingClientRect(offsetParent);
|
|
scale = getScale(offsetParent);
|
|
offsets.x = offsetRect.x + offsetParent.clientLeft;
|
|
offsets.y = offsetRect.y + offsetParent.clientTop;
|
|
}
|
|
}
|
|
const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0);
|
|
return {
|
|
width: rect.width * scale.x,
|
|
height: rect.height * scale.y,
|
|
x: rect.x * scale.x - scroll.scrollLeft * scale.x + offsets.x + htmlOffset.x,
|
|
y: rect.y * scale.y - scroll.scrollTop * scale.y + offsets.y + htmlOffset.y
|
|
};
|
|
}
|
|
function getClientRects(element) {
|
|
return Array.from(element.getClientRects());
|
|
}
|
|
function getDocumentRect(element) {
|
|
const html = getDocumentElement(element);
|
|
const scroll = getNodeScroll(element);
|
|
const body = element.ownerDocument.body;
|
|
const width = max(html.scrollWidth, html.clientWidth, body.scrollWidth, body.clientWidth);
|
|
const height = max(html.scrollHeight, html.clientHeight, body.scrollHeight, body.clientHeight);
|
|
let x = -scroll.scrollLeft + getWindowScrollBarX(element);
|
|
const y = -scroll.scrollTop;
|
|
if (getComputedStyle2(body).direction === "rtl") {
|
|
x += max(html.clientWidth, body.clientWidth) - width;
|
|
}
|
|
return {
|
|
width,
|
|
height,
|
|
x,
|
|
y
|
|
};
|
|
}
|
|
var SCROLLBAR_MAX = 25;
|
|
function getViewportRect(element, strategy) {
|
|
const win = getWindow(element);
|
|
const html = getDocumentElement(element);
|
|
const visualViewport = win.visualViewport;
|
|
let width = html.clientWidth;
|
|
let height = html.clientHeight;
|
|
let x = 0;
|
|
let y = 0;
|
|
if (visualViewport) {
|
|
width = visualViewport.width;
|
|
height = visualViewport.height;
|
|
const visualViewportBased = isWebKit();
|
|
if (!visualViewportBased || visualViewportBased && strategy === "fixed") {
|
|
x = visualViewport.offsetLeft;
|
|
y = visualViewport.offsetTop;
|
|
}
|
|
}
|
|
const windowScrollbarX = getWindowScrollBarX(html);
|
|
if (windowScrollbarX <= 0) {
|
|
const doc = html.ownerDocument;
|
|
const body = doc.body;
|
|
const bodyStyles = getComputedStyle(body);
|
|
const bodyMarginInline = doc.compatMode === "CSS1Compat" ? parseFloat(bodyStyles.marginLeft) + parseFloat(bodyStyles.marginRight) || 0 : 0;
|
|
const clippingStableScrollbarWidth = Math.abs(html.clientWidth - body.clientWidth - bodyMarginInline);
|
|
if (clippingStableScrollbarWidth <= SCROLLBAR_MAX) {
|
|
width -= clippingStableScrollbarWidth;
|
|
}
|
|
} else if (windowScrollbarX <= SCROLLBAR_MAX) {
|
|
width += windowScrollbarX;
|
|
}
|
|
return {
|
|
width,
|
|
height,
|
|
x,
|
|
y
|
|
};
|
|
}
|
|
var absoluteOrFixed = /* @__PURE__ */ new Set(["absolute", "fixed"]);
|
|
function getInnerBoundingClientRect(element, strategy) {
|
|
const clientRect = getBoundingClientRect(element, true, strategy === "fixed");
|
|
const top = clientRect.top + element.clientTop;
|
|
const left = clientRect.left + element.clientLeft;
|
|
const scale = isHTMLElement(element) ? getScale(element) : createCoords(1);
|
|
const width = element.clientWidth * scale.x;
|
|
const height = element.clientHeight * scale.y;
|
|
const x = left * scale.x;
|
|
const y = top * scale.y;
|
|
return {
|
|
width,
|
|
height,
|
|
x,
|
|
y
|
|
};
|
|
}
|
|
function getClientRectFromClippingAncestor(element, clippingAncestor, strategy) {
|
|
let rect;
|
|
if (clippingAncestor === "viewport") {
|
|
rect = getViewportRect(element, strategy);
|
|
} else if (clippingAncestor === "document") {
|
|
rect = getDocumentRect(getDocumentElement(element));
|
|
} else if (isElement(clippingAncestor)) {
|
|
rect = getInnerBoundingClientRect(clippingAncestor, strategy);
|
|
} else {
|
|
const visualOffsets = getVisualOffsets(element);
|
|
rect = {
|
|
x: clippingAncestor.x - visualOffsets.x,
|
|
y: clippingAncestor.y - visualOffsets.y,
|
|
width: clippingAncestor.width,
|
|
height: clippingAncestor.height
|
|
};
|
|
}
|
|
return rectToClientRect(rect);
|
|
}
|
|
function hasFixedPositionAncestor(element, stopNode) {
|
|
const parentNode = getParentNode(element);
|
|
if (parentNode === stopNode || !isElement(parentNode) || isLastTraversableNode(parentNode)) {
|
|
return false;
|
|
}
|
|
return getComputedStyle2(parentNode).position === "fixed" || hasFixedPositionAncestor(parentNode, stopNode);
|
|
}
|
|
function getClippingElementAncestors(element, cache) {
|
|
const cachedResult = cache.get(element);
|
|
if (cachedResult) {
|
|
return cachedResult;
|
|
}
|
|
let result = getOverflowAncestors(element, [], false).filter((el) => isElement(el) && getNodeName(el) !== "body");
|
|
let currentContainingBlockComputedStyle = null;
|
|
const elementIsFixed = getComputedStyle2(element).position === "fixed";
|
|
let currentNode = elementIsFixed ? getParentNode(element) : element;
|
|
while (isElement(currentNode) && !isLastTraversableNode(currentNode)) {
|
|
const computedStyle = getComputedStyle2(currentNode);
|
|
const currentNodeIsContaining = isContainingBlock(currentNode);
|
|
if (!currentNodeIsContaining && computedStyle.position === "fixed") {
|
|
currentContainingBlockComputedStyle = null;
|
|
}
|
|
const shouldDropCurrentNode = elementIsFixed ? !currentNodeIsContaining && !currentContainingBlockComputedStyle : !currentNodeIsContaining && computedStyle.position === "static" && !!currentContainingBlockComputedStyle && absoluteOrFixed.has(currentContainingBlockComputedStyle.position) || isOverflowElement(currentNode) && !currentNodeIsContaining && hasFixedPositionAncestor(element, currentNode);
|
|
if (shouldDropCurrentNode) {
|
|
result = result.filter((ancestor) => ancestor !== currentNode);
|
|
} else {
|
|
currentContainingBlockComputedStyle = computedStyle;
|
|
}
|
|
currentNode = getParentNode(currentNode);
|
|
}
|
|
cache.set(element, result);
|
|
return result;
|
|
}
|
|
function getClippingRect(_ref) {
|
|
let {
|
|
element,
|
|
boundary,
|
|
rootBoundary,
|
|
strategy
|
|
} = _ref;
|
|
const elementClippingAncestors = boundary === "clippingAncestors" ? isTopLayer(element) ? [] : getClippingElementAncestors(element, this._c) : [].concat(boundary);
|
|
const clippingAncestors = [...elementClippingAncestors, rootBoundary];
|
|
const firstClippingAncestor = clippingAncestors[0];
|
|
const clippingRect = clippingAncestors.reduce((accRect, clippingAncestor) => {
|
|
const rect = getClientRectFromClippingAncestor(element, clippingAncestor, strategy);
|
|
accRect.top = max(rect.top, accRect.top);
|
|
accRect.right = min(rect.right, accRect.right);
|
|
accRect.bottom = min(rect.bottom, accRect.bottom);
|
|
accRect.left = max(rect.left, accRect.left);
|
|
return accRect;
|
|
}, getClientRectFromClippingAncestor(element, firstClippingAncestor, strategy));
|
|
return {
|
|
width: clippingRect.right - clippingRect.left,
|
|
height: clippingRect.bottom - clippingRect.top,
|
|
x: clippingRect.left,
|
|
y: clippingRect.top
|
|
};
|
|
}
|
|
function getDimensions(element) {
|
|
const {
|
|
width,
|
|
height
|
|
} = getCssDimensions(element);
|
|
return {
|
|
width,
|
|
height
|
|
};
|
|
}
|
|
function getRectRelativeToOffsetParent(element, offsetParent, strategy) {
|
|
const isOffsetParentAnElement = isHTMLElement(offsetParent);
|
|
const documentElement = getDocumentElement(offsetParent);
|
|
const isFixed = strategy === "fixed";
|
|
const rect = getBoundingClientRect(element, true, isFixed, offsetParent);
|
|
let scroll = {
|
|
scrollLeft: 0,
|
|
scrollTop: 0
|
|
};
|
|
const offsets = createCoords(0);
|
|
function setLeftRTLScrollbarOffset() {
|
|
offsets.x = getWindowScrollBarX(documentElement);
|
|
}
|
|
if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
|
|
if (getNodeName(offsetParent) !== "body" || isOverflowElement(documentElement)) {
|
|
scroll = getNodeScroll(offsetParent);
|
|
}
|
|
if (isOffsetParentAnElement) {
|
|
const offsetRect = getBoundingClientRect(offsetParent, true, isFixed, offsetParent);
|
|
offsets.x = offsetRect.x + offsetParent.clientLeft;
|
|
offsets.y = offsetRect.y + offsetParent.clientTop;
|
|
} else if (documentElement) {
|
|
setLeftRTLScrollbarOffset();
|
|
}
|
|
}
|
|
if (isFixed && !isOffsetParentAnElement && documentElement) {
|
|
setLeftRTLScrollbarOffset();
|
|
}
|
|
const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0);
|
|
const x = rect.left + scroll.scrollLeft - offsets.x - htmlOffset.x;
|
|
const y = rect.top + scroll.scrollTop - offsets.y - htmlOffset.y;
|
|
return {
|
|
x,
|
|
y,
|
|
width: rect.width,
|
|
height: rect.height
|
|
};
|
|
}
|
|
function isStaticPositioned(element) {
|
|
return getComputedStyle2(element).position === "static";
|
|
}
|
|
function getTrueOffsetParent(element, polyfill) {
|
|
if (!isHTMLElement(element) || getComputedStyle2(element).position === "fixed") {
|
|
return null;
|
|
}
|
|
if (polyfill) {
|
|
return polyfill(element);
|
|
}
|
|
let rawOffsetParent = element.offsetParent;
|
|
if (getDocumentElement(element) === rawOffsetParent) {
|
|
rawOffsetParent = rawOffsetParent.ownerDocument.body;
|
|
}
|
|
return rawOffsetParent;
|
|
}
|
|
function getOffsetParent(element, polyfill) {
|
|
const win = getWindow(element);
|
|
if (isTopLayer(element)) {
|
|
return win;
|
|
}
|
|
if (!isHTMLElement(element)) {
|
|
let svgOffsetParent = getParentNode(element);
|
|
while (svgOffsetParent && !isLastTraversableNode(svgOffsetParent)) {
|
|
if (isElement(svgOffsetParent) && !isStaticPositioned(svgOffsetParent)) {
|
|
return svgOffsetParent;
|
|
}
|
|
svgOffsetParent = getParentNode(svgOffsetParent);
|
|
}
|
|
return win;
|
|
}
|
|
let offsetParent = getTrueOffsetParent(element, polyfill);
|
|
while (offsetParent && isTableElement(offsetParent) && isStaticPositioned(offsetParent)) {
|
|
offsetParent = getTrueOffsetParent(offsetParent, polyfill);
|
|
}
|
|
if (offsetParent && isLastTraversableNode(offsetParent) && isStaticPositioned(offsetParent) && !isContainingBlock(offsetParent)) {
|
|
return win;
|
|
}
|
|
return offsetParent || getContainingBlock(element) || win;
|
|
}
|
|
var getElementRects = async function(data) {
|
|
const getOffsetParentFn = this.getOffsetParent || getOffsetParent;
|
|
const getDimensionsFn = this.getDimensions;
|
|
const floatingDimensions = await getDimensionsFn(data.floating);
|
|
return {
|
|
reference: getRectRelativeToOffsetParent(data.reference, await getOffsetParentFn(data.floating), data.strategy),
|
|
floating: {
|
|
x: 0,
|
|
y: 0,
|
|
width: floatingDimensions.width,
|
|
height: floatingDimensions.height
|
|
}
|
|
};
|
|
};
|
|
function isRTL(element) {
|
|
return getComputedStyle2(element).direction === "rtl";
|
|
}
|
|
var platform = {
|
|
convertOffsetParentRelativeRectToViewportRelativeRect,
|
|
getDocumentElement,
|
|
getClippingRect,
|
|
getOffsetParent,
|
|
getElementRects,
|
|
getClientRects,
|
|
getDimensions,
|
|
getScale,
|
|
isElement,
|
|
isRTL
|
|
};
|
|
function rectsAreEqual(a, b) {
|
|
return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;
|
|
}
|
|
function observeMove(element, onMove) {
|
|
let io = null;
|
|
let timeoutId;
|
|
const root = getDocumentElement(element);
|
|
function cleanup() {
|
|
var _io;
|
|
clearTimeout(timeoutId);
|
|
(_io = io) == null || _io.disconnect();
|
|
io = null;
|
|
}
|
|
function refresh(skip, threshold) {
|
|
if (skip === void 0) {
|
|
skip = false;
|
|
}
|
|
if (threshold === void 0) {
|
|
threshold = 1;
|
|
}
|
|
cleanup();
|
|
const elementRectForRootMargin = element.getBoundingClientRect();
|
|
const {
|
|
left,
|
|
top,
|
|
width,
|
|
height
|
|
} = elementRectForRootMargin;
|
|
if (!skip) {
|
|
onMove();
|
|
}
|
|
if (!width || !height) {
|
|
return;
|
|
}
|
|
const insetTop = floor(top);
|
|
const insetRight = floor(root.clientWidth - (left + width));
|
|
const insetBottom = floor(root.clientHeight - (top + height));
|
|
const insetLeft = floor(left);
|
|
const rootMargin = -insetTop + "px " + -insetRight + "px " + -insetBottom + "px " + -insetLeft + "px";
|
|
const options = {
|
|
rootMargin,
|
|
threshold: max(0, min(1, threshold)) || 1
|
|
};
|
|
let isFirstUpdate = true;
|
|
function handleObserve(entries) {
|
|
const ratio = entries[0].intersectionRatio;
|
|
if (ratio !== threshold) {
|
|
if (!isFirstUpdate) {
|
|
return refresh();
|
|
}
|
|
if (!ratio) {
|
|
timeoutId = setTimeout(() => {
|
|
refresh(false, 1e-7);
|
|
}, 1e3);
|
|
} else {
|
|
refresh(false, ratio);
|
|
}
|
|
}
|
|
if (ratio === 1 && !rectsAreEqual(elementRectForRootMargin, element.getBoundingClientRect())) {
|
|
refresh();
|
|
}
|
|
isFirstUpdate = false;
|
|
}
|
|
try {
|
|
io = new IntersectionObserver(handleObserve, {
|
|
...options,
|
|
// Handle <iframe>s
|
|
root: root.ownerDocument
|
|
});
|
|
} catch (_e) {
|
|
io = new IntersectionObserver(handleObserve, options);
|
|
}
|
|
io.observe(element);
|
|
}
|
|
refresh(true);
|
|
return cleanup;
|
|
}
|
|
function autoUpdate(reference, floating, update, options) {
|
|
if (options === void 0) {
|
|
options = {};
|
|
}
|
|
const {
|
|
ancestorScroll = true,
|
|
ancestorResize = true,
|
|
elementResize = typeof ResizeObserver === "function",
|
|
layoutShift = typeof IntersectionObserver === "function",
|
|
animationFrame = false
|
|
} = options;
|
|
const referenceEl = unwrapElement(reference);
|
|
const ancestors = ancestorScroll || ancestorResize ? [...referenceEl ? getOverflowAncestors(referenceEl) : [], ...getOverflowAncestors(floating)] : [];
|
|
ancestors.forEach((ancestor) => {
|
|
ancestorScroll && ancestor.addEventListener("scroll", update, {
|
|
passive: true
|
|
});
|
|
ancestorResize && ancestor.addEventListener("resize", update);
|
|
});
|
|
const cleanupIo = referenceEl && layoutShift ? observeMove(referenceEl, update) : null;
|
|
let reobserveFrame = -1;
|
|
let resizeObserver = null;
|
|
if (elementResize) {
|
|
resizeObserver = new ResizeObserver((_ref) => {
|
|
let [firstEntry] = _ref;
|
|
if (firstEntry && firstEntry.target === referenceEl && resizeObserver) {
|
|
resizeObserver.unobserve(floating);
|
|
cancelAnimationFrame(reobserveFrame);
|
|
reobserveFrame = requestAnimationFrame(() => {
|
|
var _resizeObserver;
|
|
(_resizeObserver = resizeObserver) == null || _resizeObserver.observe(floating);
|
|
});
|
|
}
|
|
update();
|
|
});
|
|
if (referenceEl && !animationFrame) {
|
|
resizeObserver.observe(referenceEl);
|
|
}
|
|
resizeObserver.observe(floating);
|
|
}
|
|
let frameId;
|
|
let prevRefRect = animationFrame ? getBoundingClientRect(reference) : null;
|
|
if (animationFrame) {
|
|
frameLoop();
|
|
}
|
|
function frameLoop() {
|
|
const nextRefRect = getBoundingClientRect(reference);
|
|
if (prevRefRect && !rectsAreEqual(prevRefRect, nextRefRect)) {
|
|
update();
|
|
}
|
|
prevRefRect = nextRefRect;
|
|
frameId = requestAnimationFrame(frameLoop);
|
|
}
|
|
update();
|
|
return () => {
|
|
var _resizeObserver2;
|
|
ancestors.forEach((ancestor) => {
|
|
ancestorScroll && ancestor.removeEventListener("scroll", update);
|
|
ancestorResize && ancestor.removeEventListener("resize", update);
|
|
});
|
|
cleanupIo == null || cleanupIo();
|
|
(_resizeObserver2 = resizeObserver) == null || _resizeObserver2.disconnect();
|
|
resizeObserver = null;
|
|
if (animationFrame) {
|
|
cancelAnimationFrame(frameId);
|
|
}
|
|
};
|
|
}
|
|
var offset2 = offset;
|
|
var shift2 = shift;
|
|
var flip2 = flip;
|
|
var size2 = size;
|
|
var hide2 = hide;
|
|
var arrow2 = arrow;
|
|
var limitShift2 = limitShift;
|
|
var computePosition2 = (reference, floating, options) => {
|
|
const cache = /* @__PURE__ */ new Map();
|
|
const mergedOptions = {
|
|
platform,
|
|
...options
|
|
};
|
|
const platformWithCache = {
|
|
...mergedOptions.platform,
|
|
_c: cache
|
|
};
|
|
return computePosition(reference, floating, {
|
|
...mergedOptions,
|
|
platform: platformWithCache
|
|
});
|
|
};
|
|
|
|
// node_modules/.pnpm/@floating-ui+react-dom@2.1._c27c523691b7b5617e36eea923299747/node_modules/@floating-ui/react-dom/dist/floating-ui.react-dom.mjs
|
|
var React = __toESM(require_react(), 1);
|
|
var import_react = __toESM(require_react(), 1);
|
|
var ReactDOM = __toESM(require_react_dom(), 1);
|
|
var isClient = typeof document !== "undefined";
|
|
var noop = function noop2() {
|
|
};
|
|
var index = isClient ? import_react.useLayoutEffect : noop;
|
|
function deepEqual(a, b) {
|
|
if (a === b) {
|
|
return true;
|
|
}
|
|
if (typeof a !== typeof b) {
|
|
return false;
|
|
}
|
|
if (typeof a === "function" && a.toString() === b.toString()) {
|
|
return true;
|
|
}
|
|
let length;
|
|
let i;
|
|
let keys;
|
|
if (a && b && typeof a === "object") {
|
|
if (Array.isArray(a)) {
|
|
length = a.length;
|
|
if (length !== b.length) return false;
|
|
for (i = length; i-- !== 0; ) {
|
|
if (!deepEqual(a[i], b[i])) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
keys = Object.keys(a);
|
|
length = keys.length;
|
|
if (length !== Object.keys(b).length) {
|
|
return false;
|
|
}
|
|
for (i = length; i-- !== 0; ) {
|
|
if (!{}.hasOwnProperty.call(b, keys[i])) {
|
|
return false;
|
|
}
|
|
}
|
|
for (i = length; i-- !== 0; ) {
|
|
const key = keys[i];
|
|
if (key === "_owner" && a.$$typeof) {
|
|
continue;
|
|
}
|
|
if (!deepEqual(a[key], b[key])) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
return a !== a && b !== b;
|
|
}
|
|
function getDPR(element) {
|
|
if (typeof window === "undefined") {
|
|
return 1;
|
|
}
|
|
const win = element.ownerDocument.defaultView || window;
|
|
return win.devicePixelRatio || 1;
|
|
}
|
|
function roundByDPR(element, value) {
|
|
const dpr = getDPR(element);
|
|
return Math.round(value * dpr) / dpr;
|
|
}
|
|
function useLatestRef(value) {
|
|
const ref = React.useRef(value);
|
|
index(() => {
|
|
ref.current = value;
|
|
});
|
|
return ref;
|
|
}
|
|
function useFloating(options) {
|
|
if (options === void 0) {
|
|
options = {};
|
|
}
|
|
const {
|
|
placement = "bottom",
|
|
strategy = "absolute",
|
|
middleware = [],
|
|
platform: platform2,
|
|
elements: {
|
|
reference: externalReference,
|
|
floating: externalFloating
|
|
} = {},
|
|
transform = true,
|
|
whileElementsMounted,
|
|
open
|
|
} = options;
|
|
const [data, setData] = React.useState({
|
|
x: 0,
|
|
y: 0,
|
|
strategy,
|
|
placement,
|
|
middlewareData: {},
|
|
isPositioned: false
|
|
});
|
|
const [latestMiddleware, setLatestMiddleware] = React.useState(middleware);
|
|
if (!deepEqual(latestMiddleware, middleware)) {
|
|
setLatestMiddleware(middleware);
|
|
}
|
|
const [_reference, _setReference] = React.useState(null);
|
|
const [_floating, _setFloating] = React.useState(null);
|
|
const setReference = React.useCallback((node) => {
|
|
if (node !== referenceRef.current) {
|
|
referenceRef.current = node;
|
|
_setReference(node);
|
|
}
|
|
}, []);
|
|
const setFloating = React.useCallback((node) => {
|
|
if (node !== floatingRef.current) {
|
|
floatingRef.current = node;
|
|
_setFloating(node);
|
|
}
|
|
}, []);
|
|
const referenceEl = externalReference || _reference;
|
|
const floatingEl = externalFloating || _floating;
|
|
const referenceRef = React.useRef(null);
|
|
const floatingRef = React.useRef(null);
|
|
const dataRef = React.useRef(data);
|
|
const hasWhileElementsMounted = whileElementsMounted != null;
|
|
const whileElementsMountedRef = useLatestRef(whileElementsMounted);
|
|
const platformRef = useLatestRef(platform2);
|
|
const openRef = useLatestRef(open);
|
|
const update = React.useCallback(() => {
|
|
if (!referenceRef.current || !floatingRef.current) {
|
|
return;
|
|
}
|
|
const config = {
|
|
placement,
|
|
strategy,
|
|
middleware: latestMiddleware
|
|
};
|
|
if (platformRef.current) {
|
|
config.platform = platformRef.current;
|
|
}
|
|
computePosition2(referenceRef.current, floatingRef.current, config).then((data2) => {
|
|
const fullData = {
|
|
...data2,
|
|
// The floating element's position may be recomputed while it's closed
|
|
// but still mounted (such as when transitioning out). To ensure
|
|
// `isPositioned` will be `false` initially on the next open, avoid
|
|
// setting it to `true` when `open === false` (must be specified).
|
|
isPositioned: openRef.current !== false
|
|
};
|
|
if (isMountedRef.current && !deepEqual(dataRef.current, fullData)) {
|
|
dataRef.current = fullData;
|
|
ReactDOM.flushSync(() => {
|
|
setData(fullData);
|
|
});
|
|
}
|
|
});
|
|
}, [latestMiddleware, placement, strategy, platformRef, openRef]);
|
|
index(() => {
|
|
if (open === false && dataRef.current.isPositioned) {
|
|
dataRef.current.isPositioned = false;
|
|
setData((data2) => ({
|
|
...data2,
|
|
isPositioned: false
|
|
}));
|
|
}
|
|
}, [open]);
|
|
const isMountedRef = React.useRef(false);
|
|
index(() => {
|
|
isMountedRef.current = true;
|
|
return () => {
|
|
isMountedRef.current = false;
|
|
};
|
|
}, []);
|
|
index(() => {
|
|
if (referenceEl) referenceRef.current = referenceEl;
|
|
if (floatingEl) floatingRef.current = floatingEl;
|
|
if (referenceEl && floatingEl) {
|
|
if (whileElementsMountedRef.current) {
|
|
return whileElementsMountedRef.current(referenceEl, floatingEl, update);
|
|
}
|
|
update();
|
|
}
|
|
}, [referenceEl, floatingEl, update, whileElementsMountedRef, hasWhileElementsMounted]);
|
|
const refs = React.useMemo(() => ({
|
|
reference: referenceRef,
|
|
floating: floatingRef,
|
|
setReference,
|
|
setFloating
|
|
}), [setReference, setFloating]);
|
|
const elements = React.useMemo(() => ({
|
|
reference: referenceEl,
|
|
floating: floatingEl
|
|
}), [referenceEl, floatingEl]);
|
|
const floatingStyles = React.useMemo(() => {
|
|
const initialStyles = {
|
|
position: strategy,
|
|
left: 0,
|
|
top: 0
|
|
};
|
|
if (!elements.floating) {
|
|
return initialStyles;
|
|
}
|
|
const x = roundByDPR(elements.floating, data.x);
|
|
const y = roundByDPR(elements.floating, data.y);
|
|
if (transform) {
|
|
return {
|
|
...initialStyles,
|
|
transform: "translate(" + x + "px, " + y + "px)",
|
|
...getDPR(elements.floating) >= 1.5 && {
|
|
willChange: "transform"
|
|
}
|
|
};
|
|
}
|
|
return {
|
|
position: strategy,
|
|
left: x,
|
|
top: y
|
|
};
|
|
}, [strategy, transform, elements.floating, data.x, data.y]);
|
|
return React.useMemo(() => ({
|
|
...data,
|
|
update,
|
|
refs,
|
|
elements,
|
|
floatingStyles
|
|
}), [data, update, refs, elements, floatingStyles]);
|
|
}
|
|
var arrow$1 = (options) => {
|
|
function isRef(value) {
|
|
return {}.hasOwnProperty.call(value, "current");
|
|
}
|
|
return {
|
|
name: "arrow",
|
|
options,
|
|
fn(state) {
|
|
const {
|
|
element,
|
|
padding
|
|
} = typeof options === "function" ? options(state) : options;
|
|
if (element && isRef(element)) {
|
|
if (element.current != null) {
|
|
return arrow2({
|
|
element: element.current,
|
|
padding
|
|
}).fn(state);
|
|
}
|
|
return {};
|
|
}
|
|
if (element) {
|
|
return arrow2({
|
|
element,
|
|
padding
|
|
}).fn(state);
|
|
}
|
|
return {};
|
|
}
|
|
};
|
|
};
|
|
var offset3 = (options, deps) => ({
|
|
...offset2(options),
|
|
options: [options, deps]
|
|
});
|
|
var shift3 = (options, deps) => ({
|
|
...shift2(options),
|
|
options: [options, deps]
|
|
});
|
|
var limitShift3 = (options, deps) => ({
|
|
...limitShift2(options),
|
|
options: [options, deps]
|
|
});
|
|
var flip3 = (options, deps) => ({
|
|
...flip2(options),
|
|
options: [options, deps]
|
|
});
|
|
var size3 = (options, deps) => ({
|
|
...size2(options),
|
|
options: [options, deps]
|
|
});
|
|
var hide3 = (options, deps) => ({
|
|
...hide2(options),
|
|
options: [options, deps]
|
|
});
|
|
var arrow3 = (options, deps) => ({
|
|
...arrow$1(options),
|
|
options: [options, deps]
|
|
});
|
|
|
|
// node_modules/.pnpm/@radix-ui+react-arrow@1.1.7_ca49517bc17aeb848c1fd64fd7d6a751/node_modules/@radix-ui/react-arrow/dist/index.mjs
|
|
var React2 = __toESM(require_react(), 1);
|
|
var import_jsx_runtime = __toESM(require_jsx_runtime(), 1);
|
|
var NAME = "Arrow";
|
|
var Arrow = React2.forwardRef((props, forwardedRef) => {
|
|
const { children, width = 10, height = 5, ...arrowProps } = props;
|
|
return (0, import_jsx_runtime.jsx)(
|
|
Primitive.svg,
|
|
{
|
|
...arrowProps,
|
|
ref: forwardedRef,
|
|
width,
|
|
height,
|
|
viewBox: "0 0 30 10",
|
|
preserveAspectRatio: "none",
|
|
children: props.asChild ? children : (0, import_jsx_runtime.jsx)("polygon", { points: "0,0 30,0 15,10" })
|
|
}
|
|
);
|
|
});
|
|
Arrow.displayName = NAME;
|
|
var Root = Arrow;
|
|
|
|
// node_modules/.pnpm/@radix-ui+react-popper@1.2._670e32d9a64ee24e3a22b3ad7ddf00ff/node_modules/@radix-ui/react-popper/dist/index.mjs
|
|
var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
|
|
var POPPER_NAME = "Popper";
|
|
var [createPopperContext, createPopperScope] = createContextScope(POPPER_NAME);
|
|
var [PopperProvider, usePopperContext] = createPopperContext(POPPER_NAME);
|
|
var Popper = (props) => {
|
|
const { __scopePopper, children } = props;
|
|
const [anchor, setAnchor] = React3.useState(null);
|
|
return (0, import_jsx_runtime2.jsx)(PopperProvider, { scope: __scopePopper, anchor, onAnchorChange: setAnchor, children });
|
|
};
|
|
Popper.displayName = POPPER_NAME;
|
|
var ANCHOR_NAME = "PopperAnchor";
|
|
var PopperAnchor = React3.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopePopper, virtualRef, ...anchorProps } = props;
|
|
const context = usePopperContext(ANCHOR_NAME, __scopePopper);
|
|
const ref = React3.useRef(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, ref);
|
|
const anchorRef = React3.useRef(null);
|
|
React3.useEffect(() => {
|
|
const previousAnchor = anchorRef.current;
|
|
anchorRef.current = (virtualRef == null ? void 0 : virtualRef.current) || ref.current;
|
|
if (previousAnchor !== anchorRef.current) {
|
|
context.onAnchorChange(anchorRef.current);
|
|
}
|
|
});
|
|
return virtualRef ? null : (0, import_jsx_runtime2.jsx)(Primitive.div, { ...anchorProps, ref: composedRefs });
|
|
}
|
|
);
|
|
PopperAnchor.displayName = ANCHOR_NAME;
|
|
var CONTENT_NAME = "PopperContent";
|
|
var [PopperContentProvider, useContentContext] = createPopperContext(CONTENT_NAME);
|
|
var PopperContent = React3.forwardRef(
|
|
(props, forwardedRef) => {
|
|
var _a, _b, _c, _d, _e, _f;
|
|
const {
|
|
__scopePopper,
|
|
side = "bottom",
|
|
sideOffset = 0,
|
|
align = "center",
|
|
alignOffset = 0,
|
|
arrowPadding = 0,
|
|
avoidCollisions = true,
|
|
collisionBoundary = [],
|
|
collisionPadding: collisionPaddingProp = 0,
|
|
sticky = "partial",
|
|
hideWhenDetached = false,
|
|
updatePositionStrategy = "optimized",
|
|
onPlaced,
|
|
...contentProps
|
|
} = props;
|
|
const context = usePopperContext(CONTENT_NAME, __scopePopper);
|
|
const [content, setContent] = React3.useState(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, (node) => setContent(node));
|
|
const [arrow4, setArrow] = React3.useState(null);
|
|
const arrowSize = useSize(arrow4);
|
|
const arrowWidth = (arrowSize == null ? void 0 : arrowSize.width) ?? 0;
|
|
const arrowHeight = (arrowSize == null ? void 0 : arrowSize.height) ?? 0;
|
|
const desiredPlacement = side + (align !== "center" ? "-" + align : "");
|
|
const collisionPadding = typeof collisionPaddingProp === "number" ? collisionPaddingProp : { top: 0, right: 0, bottom: 0, left: 0, ...collisionPaddingProp };
|
|
const boundary = Array.isArray(collisionBoundary) ? collisionBoundary : [collisionBoundary];
|
|
const hasExplicitBoundaries = boundary.length > 0;
|
|
const detectOverflowOptions = {
|
|
padding: collisionPadding,
|
|
boundary: boundary.filter(isNotNull),
|
|
// with `strategy: 'fixed'`, this is the only way to get it to respect boundaries
|
|
altBoundary: hasExplicitBoundaries
|
|
};
|
|
const { refs, floatingStyles, placement, isPositioned, middlewareData } = useFloating({
|
|
// default to `fixed` strategy so users don't have to pick and we also avoid focus scroll issues
|
|
strategy: "fixed",
|
|
placement: desiredPlacement,
|
|
whileElementsMounted: (...args) => {
|
|
const cleanup = autoUpdate(...args, {
|
|
animationFrame: updatePositionStrategy === "always"
|
|
});
|
|
return cleanup;
|
|
},
|
|
elements: {
|
|
reference: context.anchor
|
|
},
|
|
middleware: [
|
|
offset3({ mainAxis: sideOffset + arrowHeight, alignmentAxis: alignOffset }),
|
|
avoidCollisions && shift3({
|
|
mainAxis: true,
|
|
crossAxis: false,
|
|
limiter: sticky === "partial" ? limitShift3() : void 0,
|
|
...detectOverflowOptions
|
|
}),
|
|
avoidCollisions && flip3({ ...detectOverflowOptions }),
|
|
size3({
|
|
...detectOverflowOptions,
|
|
apply: ({ elements, rects, availableWidth, availableHeight }) => {
|
|
const { width: anchorWidth, height: anchorHeight } = rects.reference;
|
|
const contentStyle = elements.floating.style;
|
|
contentStyle.setProperty("--radix-popper-available-width", `${availableWidth}px`);
|
|
contentStyle.setProperty("--radix-popper-available-height", `${availableHeight}px`);
|
|
contentStyle.setProperty("--radix-popper-anchor-width", `${anchorWidth}px`);
|
|
contentStyle.setProperty("--radix-popper-anchor-height", `${anchorHeight}px`);
|
|
}
|
|
}),
|
|
arrow4 && arrow3({ element: arrow4, padding: arrowPadding }),
|
|
transformOrigin({ arrowWidth, arrowHeight }),
|
|
hideWhenDetached && hide3({ strategy: "referenceHidden", ...detectOverflowOptions })
|
|
]
|
|
});
|
|
const [placedSide, placedAlign] = getSideAndAlignFromPlacement(placement);
|
|
const handlePlaced = useCallbackRef(onPlaced);
|
|
useLayoutEffect2(() => {
|
|
if (isPositioned) {
|
|
handlePlaced == null ? void 0 : handlePlaced();
|
|
}
|
|
}, [isPositioned, handlePlaced]);
|
|
const arrowX = (_a = middlewareData.arrow) == null ? void 0 : _a.x;
|
|
const arrowY = (_b = middlewareData.arrow) == null ? void 0 : _b.y;
|
|
const cannotCenterArrow = ((_c = middlewareData.arrow) == null ? void 0 : _c.centerOffset) !== 0;
|
|
const [contentZIndex, setContentZIndex] = React3.useState();
|
|
useLayoutEffect2(() => {
|
|
if (content) setContentZIndex(window.getComputedStyle(content).zIndex);
|
|
}, [content]);
|
|
return (0, import_jsx_runtime2.jsx)(
|
|
"div",
|
|
{
|
|
ref: refs.setFloating,
|
|
"data-radix-popper-content-wrapper": "",
|
|
style: {
|
|
...floatingStyles,
|
|
transform: isPositioned ? floatingStyles.transform : "translate(0, -200%)",
|
|
// keep off the page when measuring
|
|
minWidth: "max-content",
|
|
zIndex: contentZIndex,
|
|
["--radix-popper-transform-origin"]: [
|
|
(_d = middlewareData.transformOrigin) == null ? void 0 : _d.x,
|
|
(_e = middlewareData.transformOrigin) == null ? void 0 : _e.y
|
|
].join(" "),
|
|
// hide the content if using the hide middleware and should be hidden
|
|
// set visibility to hidden and disable pointer events so the UI behaves
|
|
// as if the PopperContent isn't there at all
|
|
...((_f = middlewareData.hide) == null ? void 0 : _f.referenceHidden) && {
|
|
visibility: "hidden",
|
|
pointerEvents: "none"
|
|
}
|
|
},
|
|
dir: props.dir,
|
|
children: (0, import_jsx_runtime2.jsx)(
|
|
PopperContentProvider,
|
|
{
|
|
scope: __scopePopper,
|
|
placedSide,
|
|
onArrowChange: setArrow,
|
|
arrowX,
|
|
arrowY,
|
|
shouldHideArrow: cannotCenterArrow,
|
|
children: (0, import_jsx_runtime2.jsx)(
|
|
Primitive.div,
|
|
{
|
|
"data-side": placedSide,
|
|
"data-align": placedAlign,
|
|
...contentProps,
|
|
ref: composedRefs,
|
|
style: {
|
|
...contentProps.style,
|
|
// if the PopperContent hasn't been placed yet (not all measurements done)
|
|
// we prevent animations so that users's animation don't kick in too early referring wrong sides
|
|
animation: !isPositioned ? "none" : void 0
|
|
}
|
|
}
|
|
)
|
|
}
|
|
)
|
|
}
|
|
);
|
|
}
|
|
);
|
|
PopperContent.displayName = CONTENT_NAME;
|
|
var ARROW_NAME = "PopperArrow";
|
|
var OPPOSITE_SIDE = {
|
|
top: "bottom",
|
|
right: "left",
|
|
bottom: "top",
|
|
left: "right"
|
|
};
|
|
var PopperArrow = React3.forwardRef(function PopperArrow2(props, forwardedRef) {
|
|
const { __scopePopper, ...arrowProps } = props;
|
|
const contentContext = useContentContext(ARROW_NAME, __scopePopper);
|
|
const baseSide = OPPOSITE_SIDE[contentContext.placedSide];
|
|
return (
|
|
// we have to use an extra wrapper because `ResizeObserver` (used by `useSize`)
|
|
// doesn't report size as we'd expect on SVG elements.
|
|
// it reports their bounding box which is effectively the largest path inside the SVG.
|
|
(0, import_jsx_runtime2.jsx)(
|
|
"span",
|
|
{
|
|
ref: contentContext.onArrowChange,
|
|
style: {
|
|
position: "absolute",
|
|
left: contentContext.arrowX,
|
|
top: contentContext.arrowY,
|
|
[baseSide]: 0,
|
|
transformOrigin: {
|
|
top: "",
|
|
right: "0 0",
|
|
bottom: "center 0",
|
|
left: "100% 0"
|
|
}[contentContext.placedSide],
|
|
transform: {
|
|
top: "translateY(100%)",
|
|
right: "translateY(50%) rotate(90deg) translateX(-50%)",
|
|
bottom: `rotate(180deg)`,
|
|
left: "translateY(50%) rotate(-90deg) translateX(50%)"
|
|
}[contentContext.placedSide],
|
|
visibility: contentContext.shouldHideArrow ? "hidden" : void 0
|
|
},
|
|
children: (0, import_jsx_runtime2.jsx)(
|
|
Root,
|
|
{
|
|
...arrowProps,
|
|
ref: forwardedRef,
|
|
style: {
|
|
...arrowProps.style,
|
|
// ensures the element can be measured correctly (mostly for if SVG)
|
|
display: "block"
|
|
}
|
|
}
|
|
)
|
|
}
|
|
)
|
|
);
|
|
});
|
|
PopperArrow.displayName = ARROW_NAME;
|
|
function isNotNull(value) {
|
|
return value !== null;
|
|
}
|
|
var transformOrigin = (options) => ({
|
|
name: "transformOrigin",
|
|
options,
|
|
fn(data) {
|
|
var _a, _b, _c;
|
|
const { placement, rects, middlewareData } = data;
|
|
const cannotCenterArrow = ((_a = middlewareData.arrow) == null ? void 0 : _a.centerOffset) !== 0;
|
|
const isArrowHidden = cannotCenterArrow;
|
|
const arrowWidth = isArrowHidden ? 0 : options.arrowWidth;
|
|
const arrowHeight = isArrowHidden ? 0 : options.arrowHeight;
|
|
const [placedSide, placedAlign] = getSideAndAlignFromPlacement(placement);
|
|
const noArrowAlign = { start: "0%", center: "50%", end: "100%" }[placedAlign];
|
|
const arrowXCenter = (((_b = middlewareData.arrow) == null ? void 0 : _b.x) ?? 0) + arrowWidth / 2;
|
|
const arrowYCenter = (((_c = middlewareData.arrow) == null ? void 0 : _c.y) ?? 0) + arrowHeight / 2;
|
|
let x = "";
|
|
let y = "";
|
|
if (placedSide === "bottom") {
|
|
x = isArrowHidden ? noArrowAlign : `${arrowXCenter}px`;
|
|
y = `${-arrowHeight}px`;
|
|
} else if (placedSide === "top") {
|
|
x = isArrowHidden ? noArrowAlign : `${arrowXCenter}px`;
|
|
y = `${rects.floating.height + arrowHeight}px`;
|
|
} else if (placedSide === "right") {
|
|
x = `${-arrowHeight}px`;
|
|
y = isArrowHidden ? noArrowAlign : `${arrowYCenter}px`;
|
|
} else if (placedSide === "left") {
|
|
x = `${rects.floating.width + arrowHeight}px`;
|
|
y = isArrowHidden ? noArrowAlign : `${arrowYCenter}px`;
|
|
}
|
|
return { data: { x, y } };
|
|
}
|
|
});
|
|
function getSideAndAlignFromPlacement(placement) {
|
|
const [side, align = "center"] = placement.split("-");
|
|
return [side, align];
|
|
}
|
|
var Root2 = Popper;
|
|
var Anchor = PopperAnchor;
|
|
var Content = PopperContent;
|
|
var Arrow2 = PopperArrow;
|
|
|
|
// node_modules/.pnpm/@radix-ui+react-visually-hi_20e51f345ec6c8aedb80070ad020dacb/node_modules/@radix-ui/react-visually-hidden/dist/index.mjs
|
|
var React4 = __toESM(require_react(), 1);
|
|
var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1);
|
|
var VISUALLY_HIDDEN_STYLES = Object.freeze({
|
|
// See: https://github.com/twbs/bootstrap/blob/main/scss/mixins/_visually-hidden.scss
|
|
position: "absolute",
|
|
border: 0,
|
|
width: 1,
|
|
height: 1,
|
|
padding: 0,
|
|
margin: -1,
|
|
overflow: "hidden",
|
|
clip: "rect(0, 0, 0, 0)",
|
|
whiteSpace: "nowrap",
|
|
wordWrap: "normal"
|
|
});
|
|
var NAME2 = "VisuallyHidden";
|
|
var VisuallyHidden = React4.forwardRef(
|
|
(props, forwardedRef) => {
|
|
return (0, import_jsx_runtime3.jsx)(
|
|
Primitive.span,
|
|
{
|
|
...props,
|
|
ref: forwardedRef,
|
|
style: { ...VISUALLY_HIDDEN_STYLES, ...props.style }
|
|
}
|
|
);
|
|
}
|
|
);
|
|
VisuallyHidden.displayName = NAME2;
|
|
|
|
// node_modules/.pnpm/@radix-ui+react-select@2.2._f9b05e8db7247fc075715ae52301583d/node_modules/@radix-ui/react-select/dist/index.mjs
|
|
var import_jsx_runtime4 = __toESM(require_jsx_runtime(), 1);
|
|
var OPEN_KEYS = [" ", "Enter", "ArrowUp", "ArrowDown"];
|
|
var SELECTION_KEYS = [" ", "Enter"];
|
|
var SELECT_NAME = "Select";
|
|
var [Collection, useCollection, createCollectionScope] = createCollection(SELECT_NAME);
|
|
var [createSelectContext, createSelectScope] = createContextScope(SELECT_NAME, [
|
|
createCollectionScope,
|
|
createPopperScope
|
|
]);
|
|
var usePopperScope = createPopperScope();
|
|
var [SelectProvider, useSelectContext] = createSelectContext(SELECT_NAME);
|
|
var [SelectNativeOptionsProvider, useSelectNativeOptionsContext] = createSelectContext(SELECT_NAME);
|
|
var Select = (props) => {
|
|
const {
|
|
__scopeSelect,
|
|
children,
|
|
open: openProp,
|
|
defaultOpen,
|
|
onOpenChange,
|
|
value: valueProp,
|
|
defaultValue,
|
|
onValueChange,
|
|
dir,
|
|
name,
|
|
autoComplete,
|
|
disabled,
|
|
required,
|
|
form
|
|
} = props;
|
|
const popperScope = usePopperScope(__scopeSelect);
|
|
const [trigger, setTrigger] = React5.useState(null);
|
|
const [valueNode, setValueNode] = React5.useState(null);
|
|
const [valueNodeHasChildren, setValueNodeHasChildren] = React5.useState(false);
|
|
const direction = useDirection(dir);
|
|
const [open, setOpen] = useControllableState({
|
|
prop: openProp,
|
|
defaultProp: defaultOpen ?? false,
|
|
onChange: onOpenChange,
|
|
caller: SELECT_NAME
|
|
});
|
|
const [value, setValue] = useControllableState({
|
|
prop: valueProp,
|
|
defaultProp: defaultValue,
|
|
onChange: onValueChange,
|
|
caller: SELECT_NAME
|
|
});
|
|
const triggerPointerDownPosRef = React5.useRef(null);
|
|
const isFormControl = trigger ? form || !!trigger.closest("form") : true;
|
|
const [nativeOptionsSet, setNativeOptionsSet] = React5.useState(/* @__PURE__ */ new Set());
|
|
const nativeSelectKey = Array.from(nativeOptionsSet).map((option) => option.props.value).join(";");
|
|
return (0, import_jsx_runtime4.jsx)(Root2, { ...popperScope, children: (0, import_jsx_runtime4.jsxs)(
|
|
SelectProvider,
|
|
{
|
|
required,
|
|
scope: __scopeSelect,
|
|
trigger,
|
|
onTriggerChange: setTrigger,
|
|
valueNode,
|
|
onValueNodeChange: setValueNode,
|
|
valueNodeHasChildren,
|
|
onValueNodeHasChildrenChange: setValueNodeHasChildren,
|
|
contentId: useId(),
|
|
value,
|
|
onValueChange: setValue,
|
|
open,
|
|
onOpenChange: setOpen,
|
|
dir: direction,
|
|
triggerPointerDownPosRef,
|
|
disabled,
|
|
children: [
|
|
(0, import_jsx_runtime4.jsx)(Collection.Provider, { scope: __scopeSelect, children: (0, import_jsx_runtime4.jsx)(
|
|
SelectNativeOptionsProvider,
|
|
{
|
|
scope: props.__scopeSelect,
|
|
onNativeOptionAdd: React5.useCallback((option) => {
|
|
setNativeOptionsSet((prev) => new Set(prev).add(option));
|
|
}, []),
|
|
onNativeOptionRemove: React5.useCallback((option) => {
|
|
setNativeOptionsSet((prev) => {
|
|
const optionsSet = new Set(prev);
|
|
optionsSet.delete(option);
|
|
return optionsSet;
|
|
});
|
|
}, []),
|
|
children
|
|
}
|
|
) }),
|
|
isFormControl ? (0, import_jsx_runtime4.jsxs)(
|
|
SelectBubbleInput,
|
|
{
|
|
"aria-hidden": true,
|
|
required,
|
|
tabIndex: -1,
|
|
name,
|
|
autoComplete,
|
|
value,
|
|
onChange: (event) => setValue(event.target.value),
|
|
disabled,
|
|
form,
|
|
children: [
|
|
value === void 0 ? (0, import_jsx_runtime4.jsx)("option", { value: "" }) : null,
|
|
Array.from(nativeOptionsSet)
|
|
]
|
|
},
|
|
nativeSelectKey
|
|
) : null
|
|
]
|
|
}
|
|
) });
|
|
};
|
|
Select.displayName = SELECT_NAME;
|
|
var TRIGGER_NAME = "SelectTrigger";
|
|
var SelectTrigger = React5.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeSelect, disabled = false, ...triggerProps } = props;
|
|
const popperScope = usePopperScope(__scopeSelect);
|
|
const context = useSelectContext(TRIGGER_NAME, __scopeSelect);
|
|
const isDisabled = context.disabled || disabled;
|
|
const composedRefs = useComposedRefs(forwardedRef, context.onTriggerChange);
|
|
const getItems = useCollection(__scopeSelect);
|
|
const pointerTypeRef = React5.useRef("touch");
|
|
const [searchRef, handleTypeaheadSearch, resetTypeahead] = useTypeaheadSearch((search) => {
|
|
const enabledItems = getItems().filter((item) => !item.disabled);
|
|
const currentItem = enabledItems.find((item) => item.value === context.value);
|
|
const nextItem = findNextItem(enabledItems, search, currentItem);
|
|
if (nextItem !== void 0) {
|
|
context.onValueChange(nextItem.value);
|
|
}
|
|
});
|
|
const handleOpen = (pointerEvent) => {
|
|
if (!isDisabled) {
|
|
context.onOpenChange(true);
|
|
resetTypeahead();
|
|
}
|
|
if (pointerEvent) {
|
|
context.triggerPointerDownPosRef.current = {
|
|
x: Math.round(pointerEvent.pageX),
|
|
y: Math.round(pointerEvent.pageY)
|
|
};
|
|
}
|
|
};
|
|
return (0, import_jsx_runtime4.jsx)(Anchor, { asChild: true, ...popperScope, children: (0, import_jsx_runtime4.jsx)(
|
|
Primitive.button,
|
|
{
|
|
type: "button",
|
|
role: "combobox",
|
|
"aria-controls": context.contentId,
|
|
"aria-expanded": context.open,
|
|
"aria-required": context.required,
|
|
"aria-autocomplete": "none",
|
|
dir: context.dir,
|
|
"data-state": context.open ? "open" : "closed",
|
|
disabled: isDisabled,
|
|
"data-disabled": isDisabled ? "" : void 0,
|
|
"data-placeholder": shouldShowPlaceholder(context.value) ? "" : void 0,
|
|
...triggerProps,
|
|
ref: composedRefs,
|
|
onClick: composeEventHandlers(triggerProps.onClick, (event) => {
|
|
event.currentTarget.focus();
|
|
if (pointerTypeRef.current !== "mouse") {
|
|
handleOpen(event);
|
|
}
|
|
}),
|
|
onPointerDown: composeEventHandlers(triggerProps.onPointerDown, (event) => {
|
|
pointerTypeRef.current = event.pointerType;
|
|
const target = event.target;
|
|
if (target.hasPointerCapture(event.pointerId)) {
|
|
target.releasePointerCapture(event.pointerId);
|
|
}
|
|
if (event.button === 0 && event.ctrlKey === false && event.pointerType === "mouse") {
|
|
handleOpen(event);
|
|
event.preventDefault();
|
|
}
|
|
}),
|
|
onKeyDown: composeEventHandlers(triggerProps.onKeyDown, (event) => {
|
|
const isTypingAhead = searchRef.current !== "";
|
|
const isModifierKey = event.ctrlKey || event.altKey || event.metaKey;
|
|
if (!isModifierKey && event.key.length === 1) handleTypeaheadSearch(event.key);
|
|
if (isTypingAhead && event.key === " ") return;
|
|
if (OPEN_KEYS.includes(event.key)) {
|
|
handleOpen();
|
|
event.preventDefault();
|
|
}
|
|
})
|
|
}
|
|
) });
|
|
}
|
|
);
|
|
SelectTrigger.displayName = TRIGGER_NAME;
|
|
var VALUE_NAME = "SelectValue";
|
|
var SelectValue = React5.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeSelect, className, style, children, placeholder = "", ...valueProps } = props;
|
|
const context = useSelectContext(VALUE_NAME, __scopeSelect);
|
|
const { onValueNodeHasChildrenChange } = context;
|
|
const hasChildren = children !== void 0;
|
|
const composedRefs = useComposedRefs(forwardedRef, context.onValueNodeChange);
|
|
useLayoutEffect2(() => {
|
|
onValueNodeHasChildrenChange(hasChildren);
|
|
}, [onValueNodeHasChildrenChange, hasChildren]);
|
|
return (0, import_jsx_runtime4.jsx)(
|
|
Primitive.span,
|
|
{
|
|
...valueProps,
|
|
ref: composedRefs,
|
|
style: { pointerEvents: "none" },
|
|
children: shouldShowPlaceholder(context.value) ? (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children: placeholder }) : children
|
|
}
|
|
);
|
|
}
|
|
);
|
|
SelectValue.displayName = VALUE_NAME;
|
|
var ICON_NAME = "SelectIcon";
|
|
var SelectIcon = React5.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeSelect, children, ...iconProps } = props;
|
|
return (0, import_jsx_runtime4.jsx)(Primitive.span, { "aria-hidden": true, ...iconProps, ref: forwardedRef, children: children || "▼" });
|
|
}
|
|
);
|
|
SelectIcon.displayName = ICON_NAME;
|
|
var PORTAL_NAME = "SelectPortal";
|
|
var SelectPortal = (props) => {
|
|
return (0, import_jsx_runtime4.jsx)(Portal, { asChild: true, ...props });
|
|
};
|
|
SelectPortal.displayName = PORTAL_NAME;
|
|
var CONTENT_NAME2 = "SelectContent";
|
|
var SelectContent = React5.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const context = useSelectContext(CONTENT_NAME2, props.__scopeSelect);
|
|
const [fragment, setFragment] = React5.useState();
|
|
useLayoutEffect2(() => {
|
|
setFragment(new DocumentFragment());
|
|
}, []);
|
|
if (!context.open) {
|
|
const frag = fragment;
|
|
return frag ? ReactDOM2.createPortal(
|
|
(0, import_jsx_runtime4.jsx)(SelectContentProvider, { scope: props.__scopeSelect, children: (0, import_jsx_runtime4.jsx)(Collection.Slot, { scope: props.__scopeSelect, children: (0, import_jsx_runtime4.jsx)("div", { children: props.children }) }) }),
|
|
frag
|
|
) : null;
|
|
}
|
|
return (0, import_jsx_runtime4.jsx)(SelectContentImpl, { ...props, ref: forwardedRef });
|
|
}
|
|
);
|
|
SelectContent.displayName = CONTENT_NAME2;
|
|
var CONTENT_MARGIN = 10;
|
|
var [SelectContentProvider, useSelectContentContext] = createSelectContext(CONTENT_NAME2);
|
|
var CONTENT_IMPL_NAME = "SelectContentImpl";
|
|
var Slot = createSlot("SelectContent.RemoveScroll");
|
|
var SelectContentImpl = React5.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const {
|
|
__scopeSelect,
|
|
position = "item-aligned",
|
|
onCloseAutoFocus,
|
|
onEscapeKeyDown,
|
|
onPointerDownOutside,
|
|
//
|
|
// PopperContent props
|
|
side,
|
|
sideOffset,
|
|
align,
|
|
alignOffset,
|
|
arrowPadding,
|
|
collisionBoundary,
|
|
collisionPadding,
|
|
sticky,
|
|
hideWhenDetached,
|
|
avoidCollisions,
|
|
//
|
|
...contentProps
|
|
} = props;
|
|
const context = useSelectContext(CONTENT_NAME2, __scopeSelect);
|
|
const [content, setContent] = React5.useState(null);
|
|
const [viewport, setViewport] = React5.useState(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, (node) => setContent(node));
|
|
const [selectedItem, setSelectedItem] = React5.useState(null);
|
|
const [selectedItemText, setSelectedItemText] = React5.useState(
|
|
null
|
|
);
|
|
const getItems = useCollection(__scopeSelect);
|
|
const [isPositioned, setIsPositioned] = React5.useState(false);
|
|
const firstValidItemFoundRef = React5.useRef(false);
|
|
React5.useEffect(() => {
|
|
if (content) return hideOthers(content);
|
|
}, [content]);
|
|
useFocusGuards();
|
|
const focusFirst = React5.useCallback(
|
|
(candidates) => {
|
|
const [firstItem, ...restItems] = getItems().map((item) => item.ref.current);
|
|
const [lastItem] = restItems.slice(-1);
|
|
const PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement;
|
|
for (const candidate of candidates) {
|
|
if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return;
|
|
candidate == null ? void 0 : candidate.scrollIntoView({ block: "nearest" });
|
|
if (candidate === firstItem && viewport) viewport.scrollTop = 0;
|
|
if (candidate === lastItem && viewport) viewport.scrollTop = viewport.scrollHeight;
|
|
candidate == null ? void 0 : candidate.focus();
|
|
if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT) return;
|
|
}
|
|
},
|
|
[getItems, viewport]
|
|
);
|
|
const focusSelectedItem = React5.useCallback(
|
|
() => focusFirst([selectedItem, content]),
|
|
[focusFirst, selectedItem, content]
|
|
);
|
|
React5.useEffect(() => {
|
|
if (isPositioned) {
|
|
focusSelectedItem();
|
|
}
|
|
}, [isPositioned, focusSelectedItem]);
|
|
const { onOpenChange, triggerPointerDownPosRef } = context;
|
|
React5.useEffect(() => {
|
|
if (content) {
|
|
let pointerMoveDelta = { x: 0, y: 0 };
|
|
const handlePointerMove = (event) => {
|
|
var _a, _b;
|
|
pointerMoveDelta = {
|
|
x: Math.abs(Math.round(event.pageX) - (((_a = triggerPointerDownPosRef.current) == null ? void 0 : _a.x) ?? 0)),
|
|
y: Math.abs(Math.round(event.pageY) - (((_b = triggerPointerDownPosRef.current) == null ? void 0 : _b.y) ?? 0))
|
|
};
|
|
};
|
|
const handlePointerUp = (event) => {
|
|
if (pointerMoveDelta.x <= 10 && pointerMoveDelta.y <= 10) {
|
|
event.preventDefault();
|
|
} else {
|
|
if (!content.contains(event.target)) {
|
|
onOpenChange(false);
|
|
}
|
|
}
|
|
document.removeEventListener("pointermove", handlePointerMove);
|
|
triggerPointerDownPosRef.current = null;
|
|
};
|
|
if (triggerPointerDownPosRef.current !== null) {
|
|
document.addEventListener("pointermove", handlePointerMove);
|
|
document.addEventListener("pointerup", handlePointerUp, { capture: true, once: true });
|
|
}
|
|
return () => {
|
|
document.removeEventListener("pointermove", handlePointerMove);
|
|
document.removeEventListener("pointerup", handlePointerUp, { capture: true });
|
|
};
|
|
}
|
|
}, [content, onOpenChange, triggerPointerDownPosRef]);
|
|
React5.useEffect(() => {
|
|
const close = () => onOpenChange(false);
|
|
window.addEventListener("blur", close);
|
|
window.addEventListener("resize", close);
|
|
return () => {
|
|
window.removeEventListener("blur", close);
|
|
window.removeEventListener("resize", close);
|
|
};
|
|
}, [onOpenChange]);
|
|
const [searchRef, handleTypeaheadSearch] = useTypeaheadSearch((search) => {
|
|
const enabledItems = getItems().filter((item) => !item.disabled);
|
|
const currentItem = enabledItems.find((item) => item.ref.current === document.activeElement);
|
|
const nextItem = findNextItem(enabledItems, search, currentItem);
|
|
if (nextItem) {
|
|
setTimeout(() => nextItem.ref.current.focus());
|
|
}
|
|
});
|
|
const itemRefCallback = React5.useCallback(
|
|
(node, value, disabled) => {
|
|
const isFirstValidItem = !firstValidItemFoundRef.current && !disabled;
|
|
const isSelectedItem = context.value !== void 0 && context.value === value;
|
|
if (isSelectedItem || isFirstValidItem) {
|
|
setSelectedItem(node);
|
|
if (isFirstValidItem) firstValidItemFoundRef.current = true;
|
|
}
|
|
},
|
|
[context.value]
|
|
);
|
|
const handleItemLeave = React5.useCallback(() => content == null ? void 0 : content.focus(), [content]);
|
|
const itemTextRefCallback = React5.useCallback(
|
|
(node, value, disabled) => {
|
|
const isFirstValidItem = !firstValidItemFoundRef.current && !disabled;
|
|
const isSelectedItem = context.value !== void 0 && context.value === value;
|
|
if (isSelectedItem || isFirstValidItem) {
|
|
setSelectedItemText(node);
|
|
}
|
|
},
|
|
[context.value]
|
|
);
|
|
const SelectPosition = position === "popper" ? SelectPopperPosition : SelectItemAlignedPosition;
|
|
const popperContentProps = SelectPosition === SelectPopperPosition ? {
|
|
side,
|
|
sideOffset,
|
|
align,
|
|
alignOffset,
|
|
arrowPadding,
|
|
collisionBoundary,
|
|
collisionPadding,
|
|
sticky,
|
|
hideWhenDetached,
|
|
avoidCollisions
|
|
} : {};
|
|
return (0, import_jsx_runtime4.jsx)(
|
|
SelectContentProvider,
|
|
{
|
|
scope: __scopeSelect,
|
|
content,
|
|
viewport,
|
|
onViewportChange: setViewport,
|
|
itemRefCallback,
|
|
selectedItem,
|
|
onItemLeave: handleItemLeave,
|
|
itemTextRefCallback,
|
|
focusSelectedItem,
|
|
selectedItemText,
|
|
position,
|
|
isPositioned,
|
|
searchRef,
|
|
children: (0, import_jsx_runtime4.jsx)(Combination_default, { as: Slot, allowPinchZoom: true, children: (0, import_jsx_runtime4.jsx)(
|
|
FocusScope,
|
|
{
|
|
asChild: true,
|
|
trapped: context.open,
|
|
onMountAutoFocus: (event) => {
|
|
event.preventDefault();
|
|
},
|
|
onUnmountAutoFocus: composeEventHandlers(onCloseAutoFocus, (event) => {
|
|
var _a;
|
|
(_a = context.trigger) == null ? void 0 : _a.focus({ preventScroll: true });
|
|
event.preventDefault();
|
|
}),
|
|
children: (0, import_jsx_runtime4.jsx)(
|
|
DismissableLayer,
|
|
{
|
|
asChild: true,
|
|
disableOutsidePointerEvents: true,
|
|
onEscapeKeyDown,
|
|
onPointerDownOutside,
|
|
onFocusOutside: (event) => event.preventDefault(),
|
|
onDismiss: () => context.onOpenChange(false),
|
|
children: (0, import_jsx_runtime4.jsx)(
|
|
SelectPosition,
|
|
{
|
|
role: "listbox",
|
|
id: context.contentId,
|
|
"data-state": context.open ? "open" : "closed",
|
|
dir: context.dir,
|
|
onContextMenu: (event) => event.preventDefault(),
|
|
...contentProps,
|
|
...popperContentProps,
|
|
onPlaced: () => setIsPositioned(true),
|
|
ref: composedRefs,
|
|
style: {
|
|
// flex layout so we can place the scroll buttons properly
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
// reset the outline by default as the content MAY get focused
|
|
outline: "none",
|
|
...contentProps.style
|
|
},
|
|
onKeyDown: composeEventHandlers(contentProps.onKeyDown, (event) => {
|
|
const isModifierKey = event.ctrlKey || event.altKey || event.metaKey;
|
|
if (event.key === "Tab") event.preventDefault();
|
|
if (!isModifierKey && event.key.length === 1) handleTypeaheadSearch(event.key);
|
|
if (["ArrowUp", "ArrowDown", "Home", "End"].includes(event.key)) {
|
|
const items = getItems().filter((item) => !item.disabled);
|
|
let candidateNodes = items.map((item) => item.ref.current);
|
|
if (["ArrowUp", "End"].includes(event.key)) {
|
|
candidateNodes = candidateNodes.slice().reverse();
|
|
}
|
|
if (["ArrowUp", "ArrowDown"].includes(event.key)) {
|
|
const currentElement = event.target;
|
|
const currentIndex = candidateNodes.indexOf(currentElement);
|
|
candidateNodes = candidateNodes.slice(currentIndex + 1);
|
|
}
|
|
setTimeout(() => focusFirst(candidateNodes));
|
|
event.preventDefault();
|
|
}
|
|
})
|
|
}
|
|
)
|
|
}
|
|
)
|
|
}
|
|
) })
|
|
}
|
|
);
|
|
}
|
|
);
|
|
SelectContentImpl.displayName = CONTENT_IMPL_NAME;
|
|
var ITEM_ALIGNED_POSITION_NAME = "SelectItemAlignedPosition";
|
|
var SelectItemAlignedPosition = React5.forwardRef((props, forwardedRef) => {
|
|
const { __scopeSelect, onPlaced, ...popperProps } = props;
|
|
const context = useSelectContext(CONTENT_NAME2, __scopeSelect);
|
|
const contentContext = useSelectContentContext(CONTENT_NAME2, __scopeSelect);
|
|
const [contentWrapper, setContentWrapper] = React5.useState(null);
|
|
const [content, setContent] = React5.useState(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, (node) => setContent(node));
|
|
const getItems = useCollection(__scopeSelect);
|
|
const shouldExpandOnScrollRef = React5.useRef(false);
|
|
const shouldRepositionRef = React5.useRef(true);
|
|
const { viewport, selectedItem, selectedItemText, focusSelectedItem } = contentContext;
|
|
const position = React5.useCallback(() => {
|
|
if (context.trigger && context.valueNode && contentWrapper && content && viewport && selectedItem && selectedItemText) {
|
|
const triggerRect = context.trigger.getBoundingClientRect();
|
|
const contentRect = content.getBoundingClientRect();
|
|
const valueNodeRect = context.valueNode.getBoundingClientRect();
|
|
const itemTextRect = selectedItemText.getBoundingClientRect();
|
|
if (context.dir !== "rtl") {
|
|
const itemTextOffset = itemTextRect.left - contentRect.left;
|
|
const left = valueNodeRect.left - itemTextOffset;
|
|
const leftDelta = triggerRect.left - left;
|
|
const minContentWidth = triggerRect.width + leftDelta;
|
|
const contentWidth = Math.max(minContentWidth, contentRect.width);
|
|
const rightEdge = window.innerWidth - CONTENT_MARGIN;
|
|
const clampedLeft = clamp(left, [
|
|
CONTENT_MARGIN,
|
|
// Prevents the content from going off the starting edge of the
|
|
// viewport. It may still go off the ending edge, but this can be
|
|
// controlled by the user since they may want to manage overflow in a
|
|
// specific way.
|
|
// https://github.com/radix-ui/primitives/issues/2049
|
|
Math.max(CONTENT_MARGIN, rightEdge - contentWidth)
|
|
]);
|
|
contentWrapper.style.minWidth = minContentWidth + "px";
|
|
contentWrapper.style.left = clampedLeft + "px";
|
|
} else {
|
|
const itemTextOffset = contentRect.right - itemTextRect.right;
|
|
const right = window.innerWidth - valueNodeRect.right - itemTextOffset;
|
|
const rightDelta = window.innerWidth - triggerRect.right - right;
|
|
const minContentWidth = triggerRect.width + rightDelta;
|
|
const contentWidth = Math.max(minContentWidth, contentRect.width);
|
|
const leftEdge = window.innerWidth - CONTENT_MARGIN;
|
|
const clampedRight = clamp(right, [
|
|
CONTENT_MARGIN,
|
|
Math.max(CONTENT_MARGIN, leftEdge - contentWidth)
|
|
]);
|
|
contentWrapper.style.minWidth = minContentWidth + "px";
|
|
contentWrapper.style.right = clampedRight + "px";
|
|
}
|
|
const items = getItems();
|
|
const availableHeight = window.innerHeight - CONTENT_MARGIN * 2;
|
|
const itemsHeight = viewport.scrollHeight;
|
|
const contentStyles = window.getComputedStyle(content);
|
|
const contentBorderTopWidth = parseInt(contentStyles.borderTopWidth, 10);
|
|
const contentPaddingTop = parseInt(contentStyles.paddingTop, 10);
|
|
const contentBorderBottomWidth = parseInt(contentStyles.borderBottomWidth, 10);
|
|
const contentPaddingBottom = parseInt(contentStyles.paddingBottom, 10);
|
|
const fullContentHeight = contentBorderTopWidth + contentPaddingTop + itemsHeight + contentPaddingBottom + contentBorderBottomWidth;
|
|
const minContentHeight = Math.min(selectedItem.offsetHeight * 5, fullContentHeight);
|
|
const viewportStyles = window.getComputedStyle(viewport);
|
|
const viewportPaddingTop = parseInt(viewportStyles.paddingTop, 10);
|
|
const viewportPaddingBottom = parseInt(viewportStyles.paddingBottom, 10);
|
|
const topEdgeToTriggerMiddle = triggerRect.top + triggerRect.height / 2 - CONTENT_MARGIN;
|
|
const triggerMiddleToBottomEdge = availableHeight - topEdgeToTriggerMiddle;
|
|
const selectedItemHalfHeight = selectedItem.offsetHeight / 2;
|
|
const itemOffsetMiddle = selectedItem.offsetTop + selectedItemHalfHeight;
|
|
const contentTopToItemMiddle = contentBorderTopWidth + contentPaddingTop + itemOffsetMiddle;
|
|
const itemMiddleToContentBottom = fullContentHeight - contentTopToItemMiddle;
|
|
const willAlignWithoutTopOverflow = contentTopToItemMiddle <= topEdgeToTriggerMiddle;
|
|
if (willAlignWithoutTopOverflow) {
|
|
const isLastItem = items.length > 0 && selectedItem === items[items.length - 1].ref.current;
|
|
contentWrapper.style.bottom = "0px";
|
|
const viewportOffsetBottom = content.clientHeight - viewport.offsetTop - viewport.offsetHeight;
|
|
const clampedTriggerMiddleToBottomEdge = Math.max(
|
|
triggerMiddleToBottomEdge,
|
|
selectedItemHalfHeight + // viewport might have padding bottom, include it to avoid a scrollable viewport
|
|
(isLastItem ? viewportPaddingBottom : 0) + viewportOffsetBottom + contentBorderBottomWidth
|
|
);
|
|
const height = contentTopToItemMiddle + clampedTriggerMiddleToBottomEdge;
|
|
contentWrapper.style.height = height + "px";
|
|
} else {
|
|
const isFirstItem = items.length > 0 && selectedItem === items[0].ref.current;
|
|
contentWrapper.style.top = "0px";
|
|
const clampedTopEdgeToTriggerMiddle = Math.max(
|
|
topEdgeToTriggerMiddle,
|
|
contentBorderTopWidth + viewport.offsetTop + // viewport might have padding top, include it to avoid a scrollable viewport
|
|
(isFirstItem ? viewportPaddingTop : 0) + selectedItemHalfHeight
|
|
);
|
|
const height = clampedTopEdgeToTriggerMiddle + itemMiddleToContentBottom;
|
|
contentWrapper.style.height = height + "px";
|
|
viewport.scrollTop = contentTopToItemMiddle - topEdgeToTriggerMiddle + viewport.offsetTop;
|
|
}
|
|
contentWrapper.style.margin = `${CONTENT_MARGIN}px 0`;
|
|
contentWrapper.style.minHeight = minContentHeight + "px";
|
|
contentWrapper.style.maxHeight = availableHeight + "px";
|
|
onPlaced == null ? void 0 : onPlaced();
|
|
requestAnimationFrame(() => shouldExpandOnScrollRef.current = true);
|
|
}
|
|
}, [
|
|
getItems,
|
|
context.trigger,
|
|
context.valueNode,
|
|
contentWrapper,
|
|
content,
|
|
viewport,
|
|
selectedItem,
|
|
selectedItemText,
|
|
context.dir,
|
|
onPlaced
|
|
]);
|
|
useLayoutEffect2(() => position(), [position]);
|
|
const [contentZIndex, setContentZIndex] = React5.useState();
|
|
useLayoutEffect2(() => {
|
|
if (content) setContentZIndex(window.getComputedStyle(content).zIndex);
|
|
}, [content]);
|
|
const handleScrollButtonChange = React5.useCallback(
|
|
(node) => {
|
|
if (node && shouldRepositionRef.current === true) {
|
|
position();
|
|
focusSelectedItem == null ? void 0 : focusSelectedItem();
|
|
shouldRepositionRef.current = false;
|
|
}
|
|
},
|
|
[position, focusSelectedItem]
|
|
);
|
|
return (0, import_jsx_runtime4.jsx)(
|
|
SelectViewportProvider,
|
|
{
|
|
scope: __scopeSelect,
|
|
contentWrapper,
|
|
shouldExpandOnScrollRef,
|
|
onScrollButtonChange: handleScrollButtonChange,
|
|
children: (0, import_jsx_runtime4.jsx)(
|
|
"div",
|
|
{
|
|
ref: setContentWrapper,
|
|
style: {
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
position: "fixed",
|
|
zIndex: contentZIndex
|
|
},
|
|
children: (0, import_jsx_runtime4.jsx)(
|
|
Primitive.div,
|
|
{
|
|
...popperProps,
|
|
ref: composedRefs,
|
|
style: {
|
|
// When we get the height of the content, it includes borders. If we were to set
|
|
// the height without having `boxSizing: 'border-box'` it would be too big.
|
|
boxSizing: "border-box",
|
|
// We need to ensure the content doesn't get taller than the wrapper
|
|
maxHeight: "100%",
|
|
...popperProps.style
|
|
}
|
|
}
|
|
)
|
|
}
|
|
)
|
|
}
|
|
);
|
|
});
|
|
SelectItemAlignedPosition.displayName = ITEM_ALIGNED_POSITION_NAME;
|
|
var POPPER_POSITION_NAME = "SelectPopperPosition";
|
|
var SelectPopperPosition = React5.forwardRef((props, forwardedRef) => {
|
|
const {
|
|
__scopeSelect,
|
|
align = "start",
|
|
collisionPadding = CONTENT_MARGIN,
|
|
...popperProps
|
|
} = props;
|
|
const popperScope = usePopperScope(__scopeSelect);
|
|
return (0, import_jsx_runtime4.jsx)(
|
|
Content,
|
|
{
|
|
...popperScope,
|
|
...popperProps,
|
|
ref: forwardedRef,
|
|
align,
|
|
collisionPadding,
|
|
style: {
|
|
// Ensure border-box for floating-ui calculations
|
|
boxSizing: "border-box",
|
|
...popperProps.style,
|
|
// re-namespace exposed content custom properties
|
|
...{
|
|
"--radix-select-content-transform-origin": "var(--radix-popper-transform-origin)",
|
|
"--radix-select-content-available-width": "var(--radix-popper-available-width)",
|
|
"--radix-select-content-available-height": "var(--radix-popper-available-height)",
|
|
"--radix-select-trigger-width": "var(--radix-popper-anchor-width)",
|
|
"--radix-select-trigger-height": "var(--radix-popper-anchor-height)"
|
|
}
|
|
}
|
|
}
|
|
);
|
|
});
|
|
SelectPopperPosition.displayName = POPPER_POSITION_NAME;
|
|
var [SelectViewportProvider, useSelectViewportContext] = createSelectContext(CONTENT_NAME2, {});
|
|
var VIEWPORT_NAME = "SelectViewport";
|
|
var SelectViewport = React5.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeSelect, nonce, ...viewportProps } = props;
|
|
const contentContext = useSelectContentContext(VIEWPORT_NAME, __scopeSelect);
|
|
const viewportContext = useSelectViewportContext(VIEWPORT_NAME, __scopeSelect);
|
|
const composedRefs = useComposedRefs(forwardedRef, contentContext.onViewportChange);
|
|
const prevScrollTopRef = React5.useRef(0);
|
|
return (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
(0, import_jsx_runtime4.jsx)(
|
|
"style",
|
|
{
|
|
dangerouslySetInnerHTML: {
|
|
__html: `[data-radix-select-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-radix-select-viewport]::-webkit-scrollbar{display:none}`
|
|
},
|
|
nonce
|
|
}
|
|
),
|
|
(0, import_jsx_runtime4.jsx)(Collection.Slot, { scope: __scopeSelect, children: (0, import_jsx_runtime4.jsx)(
|
|
Primitive.div,
|
|
{
|
|
"data-radix-select-viewport": "",
|
|
role: "presentation",
|
|
...viewportProps,
|
|
ref: composedRefs,
|
|
style: {
|
|
// we use position: 'relative' here on the `viewport` so that when we call
|
|
// `selectedItem.offsetTop` in calculations, the offset is relative to the viewport
|
|
// (independent of the scrollUpButton).
|
|
position: "relative",
|
|
flex: 1,
|
|
// Viewport should only be scrollable in the vertical direction.
|
|
// This won't work in vertical writing modes, so we'll need to
|
|
// revisit this if/when that is supported
|
|
// https://developer.chrome.com/blog/vertical-form-controls
|
|
overflow: "hidden auto",
|
|
...viewportProps.style
|
|
},
|
|
onScroll: composeEventHandlers(viewportProps.onScroll, (event) => {
|
|
const viewport = event.currentTarget;
|
|
const { contentWrapper, shouldExpandOnScrollRef } = viewportContext;
|
|
if ((shouldExpandOnScrollRef == null ? void 0 : shouldExpandOnScrollRef.current) && contentWrapper) {
|
|
const scrolledBy = Math.abs(prevScrollTopRef.current - viewport.scrollTop);
|
|
if (scrolledBy > 0) {
|
|
const availableHeight = window.innerHeight - CONTENT_MARGIN * 2;
|
|
const cssMinHeight = parseFloat(contentWrapper.style.minHeight);
|
|
const cssHeight = parseFloat(contentWrapper.style.height);
|
|
const prevHeight = Math.max(cssMinHeight, cssHeight);
|
|
if (prevHeight < availableHeight) {
|
|
const nextHeight = prevHeight + scrolledBy;
|
|
const clampedNextHeight = Math.min(availableHeight, nextHeight);
|
|
const heightDiff = nextHeight - clampedNextHeight;
|
|
contentWrapper.style.height = clampedNextHeight + "px";
|
|
if (contentWrapper.style.bottom === "0px") {
|
|
viewport.scrollTop = heightDiff > 0 ? heightDiff : 0;
|
|
contentWrapper.style.justifyContent = "flex-end";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
prevScrollTopRef.current = viewport.scrollTop;
|
|
})
|
|
}
|
|
) })
|
|
] });
|
|
}
|
|
);
|
|
SelectViewport.displayName = VIEWPORT_NAME;
|
|
var GROUP_NAME = "SelectGroup";
|
|
var [SelectGroupContextProvider, useSelectGroupContext] = createSelectContext(GROUP_NAME);
|
|
var SelectGroup = React5.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeSelect, ...groupProps } = props;
|
|
const groupId = useId();
|
|
return (0, import_jsx_runtime4.jsx)(SelectGroupContextProvider, { scope: __scopeSelect, id: groupId, children: (0, import_jsx_runtime4.jsx)(Primitive.div, { role: "group", "aria-labelledby": groupId, ...groupProps, ref: forwardedRef }) });
|
|
}
|
|
);
|
|
SelectGroup.displayName = GROUP_NAME;
|
|
var LABEL_NAME = "SelectLabel";
|
|
var SelectLabel = React5.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeSelect, ...labelProps } = props;
|
|
const groupContext = useSelectGroupContext(LABEL_NAME, __scopeSelect);
|
|
return (0, import_jsx_runtime4.jsx)(Primitive.div, { id: groupContext.id, ...labelProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
SelectLabel.displayName = LABEL_NAME;
|
|
var ITEM_NAME = "SelectItem";
|
|
var [SelectItemContextProvider, useSelectItemContext] = createSelectContext(ITEM_NAME);
|
|
var SelectItem = React5.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const {
|
|
__scopeSelect,
|
|
value,
|
|
disabled = false,
|
|
textValue: textValueProp,
|
|
...itemProps
|
|
} = props;
|
|
const context = useSelectContext(ITEM_NAME, __scopeSelect);
|
|
const contentContext = useSelectContentContext(ITEM_NAME, __scopeSelect);
|
|
const isSelected = context.value === value;
|
|
const [textValue, setTextValue] = React5.useState(textValueProp ?? "");
|
|
const [isFocused, setIsFocused] = React5.useState(false);
|
|
const composedRefs = useComposedRefs(
|
|
forwardedRef,
|
|
(node) => {
|
|
var _a;
|
|
return (_a = contentContext.itemRefCallback) == null ? void 0 : _a.call(contentContext, node, value, disabled);
|
|
}
|
|
);
|
|
const textId = useId();
|
|
const pointerTypeRef = React5.useRef("touch");
|
|
const handleSelect = () => {
|
|
if (!disabled) {
|
|
context.onValueChange(value);
|
|
context.onOpenChange(false);
|
|
}
|
|
};
|
|
if (value === "") {
|
|
throw new Error(
|
|
"A <Select.Item /> must have a value prop that is not an empty string. This is because the Select value can be set to an empty string to clear the selection and show the placeholder."
|
|
);
|
|
}
|
|
return (0, import_jsx_runtime4.jsx)(
|
|
SelectItemContextProvider,
|
|
{
|
|
scope: __scopeSelect,
|
|
value,
|
|
disabled,
|
|
textId,
|
|
isSelected,
|
|
onItemTextChange: React5.useCallback((node) => {
|
|
setTextValue((prevTextValue) => prevTextValue || ((node == null ? void 0 : node.textContent) ?? "").trim());
|
|
}, []),
|
|
children: (0, import_jsx_runtime4.jsx)(
|
|
Collection.ItemSlot,
|
|
{
|
|
scope: __scopeSelect,
|
|
value,
|
|
disabled,
|
|
textValue,
|
|
children: (0, import_jsx_runtime4.jsx)(
|
|
Primitive.div,
|
|
{
|
|
role: "option",
|
|
"aria-labelledby": textId,
|
|
"data-highlighted": isFocused ? "" : void 0,
|
|
"aria-selected": isSelected && isFocused,
|
|
"data-state": isSelected ? "checked" : "unchecked",
|
|
"aria-disabled": disabled || void 0,
|
|
"data-disabled": disabled ? "" : void 0,
|
|
tabIndex: disabled ? void 0 : -1,
|
|
...itemProps,
|
|
ref: composedRefs,
|
|
onFocus: composeEventHandlers(itemProps.onFocus, () => setIsFocused(true)),
|
|
onBlur: composeEventHandlers(itemProps.onBlur, () => setIsFocused(false)),
|
|
onClick: composeEventHandlers(itemProps.onClick, () => {
|
|
if (pointerTypeRef.current !== "mouse") handleSelect();
|
|
}),
|
|
onPointerUp: composeEventHandlers(itemProps.onPointerUp, () => {
|
|
if (pointerTypeRef.current === "mouse") handleSelect();
|
|
}),
|
|
onPointerDown: composeEventHandlers(itemProps.onPointerDown, (event) => {
|
|
pointerTypeRef.current = event.pointerType;
|
|
}),
|
|
onPointerMove: composeEventHandlers(itemProps.onPointerMove, (event) => {
|
|
var _a;
|
|
pointerTypeRef.current = event.pointerType;
|
|
if (disabled) {
|
|
(_a = contentContext.onItemLeave) == null ? void 0 : _a.call(contentContext);
|
|
} else if (pointerTypeRef.current === "mouse") {
|
|
event.currentTarget.focus({ preventScroll: true });
|
|
}
|
|
}),
|
|
onPointerLeave: composeEventHandlers(itemProps.onPointerLeave, (event) => {
|
|
var _a;
|
|
if (event.currentTarget === document.activeElement) {
|
|
(_a = contentContext.onItemLeave) == null ? void 0 : _a.call(contentContext);
|
|
}
|
|
}),
|
|
onKeyDown: composeEventHandlers(itemProps.onKeyDown, (event) => {
|
|
var _a;
|
|
const isTypingAhead = ((_a = contentContext.searchRef) == null ? void 0 : _a.current) !== "";
|
|
if (isTypingAhead && event.key === " ") return;
|
|
if (SELECTION_KEYS.includes(event.key)) handleSelect();
|
|
if (event.key === " ") event.preventDefault();
|
|
})
|
|
}
|
|
)
|
|
}
|
|
)
|
|
}
|
|
);
|
|
}
|
|
);
|
|
SelectItem.displayName = ITEM_NAME;
|
|
var ITEM_TEXT_NAME = "SelectItemText";
|
|
var SelectItemText = React5.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeSelect, className, style, ...itemTextProps } = props;
|
|
const context = useSelectContext(ITEM_TEXT_NAME, __scopeSelect);
|
|
const contentContext = useSelectContentContext(ITEM_TEXT_NAME, __scopeSelect);
|
|
const itemContext = useSelectItemContext(ITEM_TEXT_NAME, __scopeSelect);
|
|
const nativeOptionsContext = useSelectNativeOptionsContext(ITEM_TEXT_NAME, __scopeSelect);
|
|
const [itemTextNode, setItemTextNode] = React5.useState(null);
|
|
const composedRefs = useComposedRefs(
|
|
forwardedRef,
|
|
(node) => setItemTextNode(node),
|
|
itemContext.onItemTextChange,
|
|
(node) => {
|
|
var _a;
|
|
return (_a = contentContext.itemTextRefCallback) == null ? void 0 : _a.call(contentContext, node, itemContext.value, itemContext.disabled);
|
|
}
|
|
);
|
|
const textContent = itemTextNode == null ? void 0 : itemTextNode.textContent;
|
|
const nativeOption = React5.useMemo(
|
|
() => (0, import_jsx_runtime4.jsx)("option", { value: itemContext.value, disabled: itemContext.disabled, children: textContent }, itemContext.value),
|
|
[itemContext.disabled, itemContext.value, textContent]
|
|
);
|
|
const { onNativeOptionAdd, onNativeOptionRemove } = nativeOptionsContext;
|
|
useLayoutEffect2(() => {
|
|
onNativeOptionAdd(nativeOption);
|
|
return () => onNativeOptionRemove(nativeOption);
|
|
}, [onNativeOptionAdd, onNativeOptionRemove, nativeOption]);
|
|
return (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
(0, import_jsx_runtime4.jsx)(Primitive.span, { id: itemContext.textId, ...itemTextProps, ref: composedRefs }),
|
|
itemContext.isSelected && context.valueNode && !context.valueNodeHasChildren ? ReactDOM2.createPortal(itemTextProps.children, context.valueNode) : null
|
|
] });
|
|
}
|
|
);
|
|
SelectItemText.displayName = ITEM_TEXT_NAME;
|
|
var ITEM_INDICATOR_NAME = "SelectItemIndicator";
|
|
var SelectItemIndicator = React5.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeSelect, ...itemIndicatorProps } = props;
|
|
const itemContext = useSelectItemContext(ITEM_INDICATOR_NAME, __scopeSelect);
|
|
return itemContext.isSelected ? (0, import_jsx_runtime4.jsx)(Primitive.span, { "aria-hidden": true, ...itemIndicatorProps, ref: forwardedRef }) : null;
|
|
}
|
|
);
|
|
SelectItemIndicator.displayName = ITEM_INDICATOR_NAME;
|
|
var SCROLL_UP_BUTTON_NAME = "SelectScrollUpButton";
|
|
var SelectScrollUpButton = React5.forwardRef((props, forwardedRef) => {
|
|
const contentContext = useSelectContentContext(SCROLL_UP_BUTTON_NAME, props.__scopeSelect);
|
|
const viewportContext = useSelectViewportContext(SCROLL_UP_BUTTON_NAME, props.__scopeSelect);
|
|
const [canScrollUp, setCanScrollUp] = React5.useState(false);
|
|
const composedRefs = useComposedRefs(forwardedRef, viewportContext.onScrollButtonChange);
|
|
useLayoutEffect2(() => {
|
|
if (contentContext.viewport && contentContext.isPositioned) {
|
|
let handleScroll2 = function() {
|
|
const canScrollUp2 = viewport.scrollTop > 0;
|
|
setCanScrollUp(canScrollUp2);
|
|
};
|
|
var handleScroll = handleScroll2;
|
|
const viewport = contentContext.viewport;
|
|
handleScroll2();
|
|
viewport.addEventListener("scroll", handleScroll2);
|
|
return () => viewport.removeEventListener("scroll", handleScroll2);
|
|
}
|
|
}, [contentContext.viewport, contentContext.isPositioned]);
|
|
return canScrollUp ? (0, import_jsx_runtime4.jsx)(
|
|
SelectScrollButtonImpl,
|
|
{
|
|
...props,
|
|
ref: composedRefs,
|
|
onAutoScroll: () => {
|
|
const { viewport, selectedItem } = contentContext;
|
|
if (viewport && selectedItem) {
|
|
viewport.scrollTop = viewport.scrollTop - selectedItem.offsetHeight;
|
|
}
|
|
}
|
|
}
|
|
) : null;
|
|
});
|
|
SelectScrollUpButton.displayName = SCROLL_UP_BUTTON_NAME;
|
|
var SCROLL_DOWN_BUTTON_NAME = "SelectScrollDownButton";
|
|
var SelectScrollDownButton = React5.forwardRef((props, forwardedRef) => {
|
|
const contentContext = useSelectContentContext(SCROLL_DOWN_BUTTON_NAME, props.__scopeSelect);
|
|
const viewportContext = useSelectViewportContext(SCROLL_DOWN_BUTTON_NAME, props.__scopeSelect);
|
|
const [canScrollDown, setCanScrollDown] = React5.useState(false);
|
|
const composedRefs = useComposedRefs(forwardedRef, viewportContext.onScrollButtonChange);
|
|
useLayoutEffect2(() => {
|
|
if (contentContext.viewport && contentContext.isPositioned) {
|
|
let handleScroll2 = function() {
|
|
const maxScroll = viewport.scrollHeight - viewport.clientHeight;
|
|
const canScrollDown2 = Math.ceil(viewport.scrollTop) < maxScroll;
|
|
setCanScrollDown(canScrollDown2);
|
|
};
|
|
var handleScroll = handleScroll2;
|
|
const viewport = contentContext.viewport;
|
|
handleScroll2();
|
|
viewport.addEventListener("scroll", handleScroll2);
|
|
return () => viewport.removeEventListener("scroll", handleScroll2);
|
|
}
|
|
}, [contentContext.viewport, contentContext.isPositioned]);
|
|
return canScrollDown ? (0, import_jsx_runtime4.jsx)(
|
|
SelectScrollButtonImpl,
|
|
{
|
|
...props,
|
|
ref: composedRefs,
|
|
onAutoScroll: () => {
|
|
const { viewport, selectedItem } = contentContext;
|
|
if (viewport && selectedItem) {
|
|
viewport.scrollTop = viewport.scrollTop + selectedItem.offsetHeight;
|
|
}
|
|
}
|
|
}
|
|
) : null;
|
|
});
|
|
SelectScrollDownButton.displayName = SCROLL_DOWN_BUTTON_NAME;
|
|
var SelectScrollButtonImpl = React5.forwardRef((props, forwardedRef) => {
|
|
const { __scopeSelect, onAutoScroll, ...scrollIndicatorProps } = props;
|
|
const contentContext = useSelectContentContext("SelectScrollButton", __scopeSelect);
|
|
const autoScrollTimerRef = React5.useRef(null);
|
|
const getItems = useCollection(__scopeSelect);
|
|
const clearAutoScrollTimer = React5.useCallback(() => {
|
|
if (autoScrollTimerRef.current !== null) {
|
|
window.clearInterval(autoScrollTimerRef.current);
|
|
autoScrollTimerRef.current = null;
|
|
}
|
|
}, []);
|
|
React5.useEffect(() => {
|
|
return () => clearAutoScrollTimer();
|
|
}, [clearAutoScrollTimer]);
|
|
useLayoutEffect2(() => {
|
|
var _a;
|
|
const activeItem = getItems().find((item) => item.ref.current === document.activeElement);
|
|
(_a = activeItem == null ? void 0 : activeItem.ref.current) == null ? void 0 : _a.scrollIntoView({ block: "nearest" });
|
|
}, [getItems]);
|
|
return (0, import_jsx_runtime4.jsx)(
|
|
Primitive.div,
|
|
{
|
|
"aria-hidden": true,
|
|
...scrollIndicatorProps,
|
|
ref: forwardedRef,
|
|
style: { flexShrink: 0, ...scrollIndicatorProps.style },
|
|
onPointerDown: composeEventHandlers(scrollIndicatorProps.onPointerDown, () => {
|
|
if (autoScrollTimerRef.current === null) {
|
|
autoScrollTimerRef.current = window.setInterval(onAutoScroll, 50);
|
|
}
|
|
}),
|
|
onPointerMove: composeEventHandlers(scrollIndicatorProps.onPointerMove, () => {
|
|
var _a;
|
|
(_a = contentContext.onItemLeave) == null ? void 0 : _a.call(contentContext);
|
|
if (autoScrollTimerRef.current === null) {
|
|
autoScrollTimerRef.current = window.setInterval(onAutoScroll, 50);
|
|
}
|
|
}),
|
|
onPointerLeave: composeEventHandlers(scrollIndicatorProps.onPointerLeave, () => {
|
|
clearAutoScrollTimer();
|
|
})
|
|
}
|
|
);
|
|
});
|
|
var SEPARATOR_NAME = "SelectSeparator";
|
|
var SelectSeparator = React5.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeSelect, ...separatorProps } = props;
|
|
return (0, import_jsx_runtime4.jsx)(Primitive.div, { "aria-hidden": true, ...separatorProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
SelectSeparator.displayName = SEPARATOR_NAME;
|
|
var ARROW_NAME2 = "SelectArrow";
|
|
var SelectArrow = React5.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeSelect, ...arrowProps } = props;
|
|
const popperScope = usePopperScope(__scopeSelect);
|
|
const context = useSelectContext(ARROW_NAME2, __scopeSelect);
|
|
const contentContext = useSelectContentContext(ARROW_NAME2, __scopeSelect);
|
|
return context.open && contentContext.position === "popper" ? (0, import_jsx_runtime4.jsx)(Arrow2, { ...popperScope, ...arrowProps, ref: forwardedRef }) : null;
|
|
}
|
|
);
|
|
SelectArrow.displayName = ARROW_NAME2;
|
|
var BUBBLE_INPUT_NAME = "SelectBubbleInput";
|
|
var SelectBubbleInput = React5.forwardRef(
|
|
({ __scopeSelect, value, ...props }, forwardedRef) => {
|
|
const ref = React5.useRef(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, ref);
|
|
const prevValue = usePrevious(value);
|
|
React5.useEffect(() => {
|
|
const select = ref.current;
|
|
if (!select) return;
|
|
const selectProto = window.HTMLSelectElement.prototype;
|
|
const descriptor = Object.getOwnPropertyDescriptor(
|
|
selectProto,
|
|
"value"
|
|
);
|
|
const setValue = descriptor.set;
|
|
if (prevValue !== value && setValue) {
|
|
const event = new Event("change", { bubbles: true });
|
|
setValue.call(select, value);
|
|
select.dispatchEvent(event);
|
|
}
|
|
}, [prevValue, value]);
|
|
return (0, import_jsx_runtime4.jsx)(
|
|
Primitive.select,
|
|
{
|
|
...props,
|
|
style: { ...VISUALLY_HIDDEN_STYLES, ...props.style },
|
|
ref: composedRefs,
|
|
defaultValue: value
|
|
}
|
|
);
|
|
}
|
|
);
|
|
SelectBubbleInput.displayName = BUBBLE_INPUT_NAME;
|
|
function shouldShowPlaceholder(value) {
|
|
return value === "" || value === void 0;
|
|
}
|
|
function useTypeaheadSearch(onSearchChange) {
|
|
const handleSearchChange = useCallbackRef(onSearchChange);
|
|
const searchRef = React5.useRef("");
|
|
const timerRef = React5.useRef(0);
|
|
const handleTypeaheadSearch = React5.useCallback(
|
|
(key) => {
|
|
const search = searchRef.current + key;
|
|
handleSearchChange(search);
|
|
(function updateSearch(value) {
|
|
searchRef.current = value;
|
|
window.clearTimeout(timerRef.current);
|
|
if (value !== "") timerRef.current = window.setTimeout(() => updateSearch(""), 1e3);
|
|
})(search);
|
|
},
|
|
[handleSearchChange]
|
|
);
|
|
const resetTypeahead = React5.useCallback(() => {
|
|
searchRef.current = "";
|
|
window.clearTimeout(timerRef.current);
|
|
}, []);
|
|
React5.useEffect(() => {
|
|
return () => window.clearTimeout(timerRef.current);
|
|
}, []);
|
|
return [searchRef, handleTypeaheadSearch, resetTypeahead];
|
|
}
|
|
function findNextItem(items, search, currentItem) {
|
|
const isRepeated = search.length > 1 && Array.from(search).every((char) => char === search[0]);
|
|
const normalizedSearch = isRepeated ? search[0] : search;
|
|
const currentItemIndex = currentItem ? items.indexOf(currentItem) : -1;
|
|
let wrappedItems = wrapArray(items, Math.max(currentItemIndex, 0));
|
|
const excludeCurrentItem = normalizedSearch.length === 1;
|
|
if (excludeCurrentItem) wrappedItems = wrappedItems.filter((v) => v !== currentItem);
|
|
const nextItem = wrappedItems.find(
|
|
(item) => item.textValue.toLowerCase().startsWith(normalizedSearch.toLowerCase())
|
|
);
|
|
return nextItem !== currentItem ? nextItem : void 0;
|
|
}
|
|
function wrapArray(array, startIndex) {
|
|
return array.map((_, index2) => array[(startIndex + index2) % array.length]);
|
|
}
|
|
var Root22 = Select;
|
|
var Trigger = SelectTrigger;
|
|
var Value = SelectValue;
|
|
var Icon = SelectIcon;
|
|
var Portal2 = SelectPortal;
|
|
var Content2 = SelectContent;
|
|
var Viewport = SelectViewport;
|
|
var Group = SelectGroup;
|
|
var Label = SelectLabel;
|
|
var Item = SelectItem;
|
|
var ItemText = SelectItemText;
|
|
var ItemIndicator = SelectItemIndicator;
|
|
var ScrollUpButton = SelectScrollUpButton;
|
|
var ScrollDownButton = SelectScrollDownButton;
|
|
var Separator = SelectSeparator;
|
|
var Arrow22 = SelectArrow;
|
|
export {
|
|
Arrow22 as Arrow,
|
|
Content2 as Content,
|
|
Group,
|
|
Icon,
|
|
Item,
|
|
ItemIndicator,
|
|
ItemText,
|
|
Label,
|
|
Portal2 as Portal,
|
|
Root22 as Root,
|
|
ScrollDownButton,
|
|
ScrollUpButton,
|
|
Select,
|
|
SelectArrow,
|
|
SelectContent,
|
|
SelectGroup,
|
|
SelectIcon,
|
|
SelectItem,
|
|
SelectItemIndicator,
|
|
SelectItemText,
|
|
SelectLabel,
|
|
SelectPortal,
|
|
SelectScrollDownButton,
|
|
SelectScrollUpButton,
|
|
SelectSeparator,
|
|
SelectTrigger,
|
|
SelectValue,
|
|
SelectViewport,
|
|
Separator,
|
|
Trigger,
|
|
Value,
|
|
Viewport,
|
|
createSelectScope
|
|
};
|
|
//# sourceMappingURL=@radix-ui_react-select.js.map
|