1798 lines
72 KiB
JavaScript
1798 lines
72 KiB
JavaScript
"use client";
|
|
import {
|
|
usePrevious
|
|
} from "./chunk-DDW565K2.js";
|
|
import {
|
|
VisuallyHidden
|
|
} from "./chunk-3GV3KT4M.js";
|
|
import {
|
|
FocusScope,
|
|
RemoveScrollBar,
|
|
__assign,
|
|
__rest,
|
|
__spreadArray,
|
|
createSidecarMedium,
|
|
exportSidecar,
|
|
fullWidthClassName,
|
|
hideOthers,
|
|
styleSingleton,
|
|
useMergeRefs,
|
|
zeroRightClassName
|
|
} from "./chunk-QYKEMCE4.js";
|
|
import {
|
|
createCollection
|
|
} from "./chunk-6SPNF6KQ.js";
|
|
import {
|
|
Anchor,
|
|
Arrow,
|
|
Content,
|
|
Root2,
|
|
createPopperScope
|
|
} from "./chunk-6UE7W7QM.js";
|
|
import "./chunk-MR3TNHRB.js";
|
|
import {
|
|
useEscapeKeydown
|
|
} from "./chunk-J3JCCWF4.js";
|
|
import {
|
|
useId
|
|
} from "./chunk-5I6CIHEW.js";
|
|
import {
|
|
useControllableState
|
|
} from "./chunk-H4VE5LV5.js";
|
|
import {
|
|
clamp
|
|
} from "./chunk-6ZMM2PAV.js";
|
|
import {
|
|
useDirection
|
|
} from "./chunk-O2UA4OQB.js";
|
|
import {
|
|
createContextScope
|
|
} from "./chunk-OAV3HHWW.js";
|
|
import {
|
|
composeEventHandlers,
|
|
useCallbackRef,
|
|
useLayoutEffect2
|
|
} from "./chunk-SZRZRZSM.js";
|
|
import {
|
|
Primitive,
|
|
dispatchDiscreteCustomEvent
|
|
} from "./chunk-H55D7VYG.js";
|
|
import {
|
|
require_react_dom
|
|
} from "./chunk-R6S4VRB5.js";
|
|
import {
|
|
Slot,
|
|
useComposedRefs
|
|
} from "./chunk-4WIT4MX7.js";
|
|
import {
|
|
require_jsx_runtime
|
|
} from "./chunk-S77I6LSE.js";
|
|
import {
|
|
require_react
|
|
} from "./chunk-3TFVT2CW.js";
|
|
import {
|
|
__toESM
|
|
} from "./chunk-4MBMRILA.js";
|
|
|
|
// node_modules/@radix-ui/react-select/dist/index.mjs
|
|
var React7 = __toESM(require_react(), 1);
|
|
var ReactDOM2 = __toESM(require_react_dom(), 1);
|
|
|
|
// node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-dismissable-layer/dist/index.mjs
|
|
var React = __toESM(require_react(), 1);
|
|
var import_jsx_runtime = __toESM(require_jsx_runtime(), 1);
|
|
var DISMISSABLE_LAYER_NAME = "DismissableLayer";
|
|
var CONTEXT_UPDATE = "dismissableLayer.update";
|
|
var POINTER_DOWN_OUTSIDE = "dismissableLayer.pointerDownOutside";
|
|
var FOCUS_OUTSIDE = "dismissableLayer.focusOutside";
|
|
var originalBodyPointerEvents;
|
|
var DismissableLayerContext = React.createContext({
|
|
layers: /* @__PURE__ */ new Set(),
|
|
layersWithOutsidePointerEventsDisabled: /* @__PURE__ */ new Set(),
|
|
branches: /* @__PURE__ */ new Set()
|
|
});
|
|
var DismissableLayer = React.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const {
|
|
disableOutsidePointerEvents = false,
|
|
onEscapeKeyDown,
|
|
onPointerDownOutside,
|
|
onFocusOutside,
|
|
onInteractOutside,
|
|
onDismiss,
|
|
...layerProps
|
|
} = props;
|
|
const context = React.useContext(DismissableLayerContext);
|
|
const [node, setNode] = React.useState(null);
|
|
const ownerDocument = (node == null ? void 0 : node.ownerDocument) ?? (globalThis == null ? void 0 : globalThis.document);
|
|
const [, force] = React.useState({});
|
|
const composedRefs = useComposedRefs(forwardedRef, (node2) => setNode(node2));
|
|
const layers = Array.from(context.layers);
|
|
const [highestLayerWithOutsidePointerEventsDisabled] = [...context.layersWithOutsidePointerEventsDisabled].slice(-1);
|
|
const highestLayerWithOutsidePointerEventsDisabledIndex = layers.indexOf(highestLayerWithOutsidePointerEventsDisabled);
|
|
const index = node ? layers.indexOf(node) : -1;
|
|
const isBodyPointerEventsDisabled = context.layersWithOutsidePointerEventsDisabled.size > 0;
|
|
const isPointerEventsEnabled = index >= highestLayerWithOutsidePointerEventsDisabledIndex;
|
|
const pointerDownOutside = usePointerDownOutside((event) => {
|
|
const target = event.target;
|
|
const isPointerDownOnBranch = [...context.branches].some((branch) => branch.contains(target));
|
|
if (!isPointerEventsEnabled || isPointerDownOnBranch) return;
|
|
onPointerDownOutside == null ? void 0 : onPointerDownOutside(event);
|
|
onInteractOutside == null ? void 0 : onInteractOutside(event);
|
|
if (!event.defaultPrevented) onDismiss == null ? void 0 : onDismiss();
|
|
}, ownerDocument);
|
|
const focusOutside = useFocusOutside((event) => {
|
|
const target = event.target;
|
|
const isFocusInBranch = [...context.branches].some((branch) => branch.contains(target));
|
|
if (isFocusInBranch) return;
|
|
onFocusOutside == null ? void 0 : onFocusOutside(event);
|
|
onInteractOutside == null ? void 0 : onInteractOutside(event);
|
|
if (!event.defaultPrevented) onDismiss == null ? void 0 : onDismiss();
|
|
}, ownerDocument);
|
|
useEscapeKeydown((event) => {
|
|
const isHighestLayer = index === context.layers.size - 1;
|
|
if (!isHighestLayer) return;
|
|
onEscapeKeyDown == null ? void 0 : onEscapeKeyDown(event);
|
|
if (!event.defaultPrevented && onDismiss) {
|
|
event.preventDefault();
|
|
onDismiss();
|
|
}
|
|
}, ownerDocument);
|
|
React.useEffect(() => {
|
|
if (!node) return;
|
|
if (disableOutsidePointerEvents) {
|
|
if (context.layersWithOutsidePointerEventsDisabled.size === 0) {
|
|
originalBodyPointerEvents = ownerDocument.body.style.pointerEvents;
|
|
ownerDocument.body.style.pointerEvents = "none";
|
|
}
|
|
context.layersWithOutsidePointerEventsDisabled.add(node);
|
|
}
|
|
context.layers.add(node);
|
|
dispatchUpdate();
|
|
return () => {
|
|
if (disableOutsidePointerEvents && context.layersWithOutsidePointerEventsDisabled.size === 1) {
|
|
ownerDocument.body.style.pointerEvents = originalBodyPointerEvents;
|
|
}
|
|
};
|
|
}, [node, ownerDocument, disableOutsidePointerEvents, context]);
|
|
React.useEffect(() => {
|
|
return () => {
|
|
if (!node) return;
|
|
context.layers.delete(node);
|
|
context.layersWithOutsidePointerEventsDisabled.delete(node);
|
|
dispatchUpdate();
|
|
};
|
|
}, [node, context]);
|
|
React.useEffect(() => {
|
|
const handleUpdate = () => force({});
|
|
document.addEventListener(CONTEXT_UPDATE, handleUpdate);
|
|
return () => document.removeEventListener(CONTEXT_UPDATE, handleUpdate);
|
|
}, []);
|
|
return (0, import_jsx_runtime.jsx)(
|
|
Primitive.div,
|
|
{
|
|
...layerProps,
|
|
ref: composedRefs,
|
|
style: {
|
|
pointerEvents: isBodyPointerEventsDisabled ? isPointerEventsEnabled ? "auto" : "none" : void 0,
|
|
...props.style
|
|
},
|
|
onFocusCapture: composeEventHandlers(props.onFocusCapture, focusOutside.onFocusCapture),
|
|
onBlurCapture: composeEventHandlers(props.onBlurCapture, focusOutside.onBlurCapture),
|
|
onPointerDownCapture: composeEventHandlers(
|
|
props.onPointerDownCapture,
|
|
pointerDownOutside.onPointerDownCapture
|
|
)
|
|
}
|
|
);
|
|
}
|
|
);
|
|
DismissableLayer.displayName = DISMISSABLE_LAYER_NAME;
|
|
var BRANCH_NAME = "DismissableLayerBranch";
|
|
var DismissableLayerBranch = React.forwardRef((props, forwardedRef) => {
|
|
const context = React.useContext(DismissableLayerContext);
|
|
const ref = React.useRef(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, ref);
|
|
React.useEffect(() => {
|
|
const node = ref.current;
|
|
if (node) {
|
|
context.branches.add(node);
|
|
return () => {
|
|
context.branches.delete(node);
|
|
};
|
|
}
|
|
}, [context.branches]);
|
|
return (0, import_jsx_runtime.jsx)(Primitive.div, { ...props, ref: composedRefs });
|
|
});
|
|
DismissableLayerBranch.displayName = BRANCH_NAME;
|
|
function usePointerDownOutside(onPointerDownOutside, ownerDocument = globalThis == null ? void 0 : globalThis.document) {
|
|
const handlePointerDownOutside = useCallbackRef(onPointerDownOutside);
|
|
const isPointerInsideReactTreeRef = React.useRef(false);
|
|
const handleClickRef = React.useRef(() => {
|
|
});
|
|
React.useEffect(() => {
|
|
const handlePointerDown = (event) => {
|
|
if (event.target && !isPointerInsideReactTreeRef.current) {
|
|
let handleAndDispatchPointerDownOutsideEvent2 = function() {
|
|
handleAndDispatchCustomEvent(
|
|
POINTER_DOWN_OUTSIDE,
|
|
handlePointerDownOutside,
|
|
eventDetail,
|
|
{ discrete: true }
|
|
);
|
|
};
|
|
var handleAndDispatchPointerDownOutsideEvent = handleAndDispatchPointerDownOutsideEvent2;
|
|
const eventDetail = { originalEvent: event };
|
|
if (event.pointerType === "touch") {
|
|
ownerDocument.removeEventListener("click", handleClickRef.current);
|
|
handleClickRef.current = handleAndDispatchPointerDownOutsideEvent2;
|
|
ownerDocument.addEventListener("click", handleClickRef.current, { once: true });
|
|
} else {
|
|
handleAndDispatchPointerDownOutsideEvent2();
|
|
}
|
|
} else {
|
|
ownerDocument.removeEventListener("click", handleClickRef.current);
|
|
}
|
|
isPointerInsideReactTreeRef.current = false;
|
|
};
|
|
const timerId = window.setTimeout(() => {
|
|
ownerDocument.addEventListener("pointerdown", handlePointerDown);
|
|
}, 0);
|
|
return () => {
|
|
window.clearTimeout(timerId);
|
|
ownerDocument.removeEventListener("pointerdown", handlePointerDown);
|
|
ownerDocument.removeEventListener("click", handleClickRef.current);
|
|
};
|
|
}, [ownerDocument, handlePointerDownOutside]);
|
|
return {
|
|
// ensures we check React component tree (not just DOM tree)
|
|
onPointerDownCapture: () => isPointerInsideReactTreeRef.current = true
|
|
};
|
|
}
|
|
function useFocusOutside(onFocusOutside, ownerDocument = globalThis == null ? void 0 : globalThis.document) {
|
|
const handleFocusOutside = useCallbackRef(onFocusOutside);
|
|
const isFocusInsideReactTreeRef = React.useRef(false);
|
|
React.useEffect(() => {
|
|
const handleFocus = (event) => {
|
|
if (event.target && !isFocusInsideReactTreeRef.current) {
|
|
const eventDetail = { originalEvent: event };
|
|
handleAndDispatchCustomEvent(FOCUS_OUTSIDE, handleFocusOutside, eventDetail, {
|
|
discrete: false
|
|
});
|
|
}
|
|
};
|
|
ownerDocument.addEventListener("focusin", handleFocus);
|
|
return () => ownerDocument.removeEventListener("focusin", handleFocus);
|
|
}, [ownerDocument, handleFocusOutside]);
|
|
return {
|
|
onFocusCapture: () => isFocusInsideReactTreeRef.current = true,
|
|
onBlurCapture: () => isFocusInsideReactTreeRef.current = false
|
|
};
|
|
}
|
|
function dispatchUpdate() {
|
|
const event = new CustomEvent(CONTEXT_UPDATE);
|
|
document.dispatchEvent(event);
|
|
}
|
|
function handleAndDispatchCustomEvent(name, handler, detail, { discrete }) {
|
|
const target = detail.originalEvent.target;
|
|
const event = new CustomEvent(name, { bubbles: false, cancelable: true, detail });
|
|
if (handler) target.addEventListener(name, handler, { once: true });
|
|
if (discrete) {
|
|
dispatchDiscreteCustomEvent(target, event);
|
|
} else {
|
|
target.dispatchEvent(event);
|
|
}
|
|
}
|
|
|
|
// node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-focus-guards/dist/index.mjs
|
|
var React2 = __toESM(require_react(), 1);
|
|
var count = 0;
|
|
function useFocusGuards() {
|
|
React2.useEffect(() => {
|
|
const edgeGuards = document.querySelectorAll("[data-radix-focus-guard]");
|
|
document.body.insertAdjacentElement("afterbegin", edgeGuards[0] ?? createFocusGuard());
|
|
document.body.insertAdjacentElement("beforeend", edgeGuards[1] ?? createFocusGuard());
|
|
count++;
|
|
return () => {
|
|
if (count === 1) {
|
|
document.querySelectorAll("[data-radix-focus-guard]").forEach((node) => node.remove());
|
|
}
|
|
count--;
|
|
};
|
|
}, []);
|
|
}
|
|
function createFocusGuard() {
|
|
const element = document.createElement("span");
|
|
element.setAttribute("data-radix-focus-guard", "");
|
|
element.tabIndex = 0;
|
|
element.style.cssText = "outline: none; opacity: 0; position: fixed; pointer-events: none";
|
|
return element;
|
|
}
|
|
|
|
// node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-portal/dist/index.mjs
|
|
var React3 = __toESM(require_react(), 1);
|
|
var import_react_dom = __toESM(require_react_dom(), 1);
|
|
var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
|
|
var PORTAL_NAME = "Portal";
|
|
var Portal = React3.forwardRef((props, forwardedRef) => {
|
|
var _a;
|
|
const { container: containerProp, ...portalProps } = props;
|
|
const [mounted, setMounted] = React3.useState(false);
|
|
useLayoutEffect2(() => setMounted(true), []);
|
|
const container = containerProp || mounted && ((_a = globalThis == null ? void 0 : globalThis.document) == null ? void 0 : _a.body);
|
|
return container ? import_react_dom.default.createPortal((0, import_jsx_runtime2.jsx)(Primitive.div, { ...portalProps, ref: forwardedRef }), container) : null;
|
|
});
|
|
Portal.displayName = PORTAL_NAME;
|
|
|
|
// node_modules/@radix-ui/react-select/node_modules/react-remove-scroll/dist/es2015/Combination.js
|
|
var React6 = __toESM(require_react());
|
|
|
|
// node_modules/@radix-ui/react-select/node_modules/react-remove-scroll/dist/es2015/UI.js
|
|
var React4 = __toESM(require_react());
|
|
|
|
// node_modules/@radix-ui/react-select/node_modules/react-remove-scroll/dist/es2015/medium.js
|
|
var effectCar = createSidecarMedium();
|
|
|
|
// node_modules/@radix-ui/react-select/node_modules/react-remove-scroll/dist/es2015/UI.js
|
|
var nothing = function() {
|
|
return;
|
|
};
|
|
var RemoveScroll = React4.forwardRef(function(props, parentRef) {
|
|
var ref = React4.useRef(null);
|
|
var _a = React4.useState({
|
|
onScrollCapture: nothing,
|
|
onWheelCapture: nothing,
|
|
onTouchMoveCapture: nothing
|
|
}), callbacks = _a[0], setCallbacks = _a[1];
|
|
var forwardProps = props.forwardProps, children = props.children, className = props.className, removeScrollBar = props.removeScrollBar, enabled = props.enabled, shards = props.shards, sideCar = props.sideCar, noIsolation = props.noIsolation, inert = props.inert, allowPinchZoom = props.allowPinchZoom, _b = props.as, Container = _b === void 0 ? "div" : _b, gapMode = props.gapMode, rest = __rest(props, ["forwardProps", "children", "className", "removeScrollBar", "enabled", "shards", "sideCar", "noIsolation", "inert", "allowPinchZoom", "as", "gapMode"]);
|
|
var SideCar = sideCar;
|
|
var containerRef = useMergeRefs([ref, parentRef]);
|
|
var containerProps = __assign(__assign({}, rest), callbacks);
|
|
return React4.createElement(
|
|
React4.Fragment,
|
|
null,
|
|
enabled && React4.createElement(SideCar, { sideCar: effectCar, removeScrollBar, shards, noIsolation, inert, setCallbacks, allowPinchZoom: !!allowPinchZoom, lockRef: ref, gapMode }),
|
|
forwardProps ? React4.cloneElement(React4.Children.only(children), __assign(__assign({}, containerProps), { ref: containerRef })) : React4.createElement(Container, __assign({}, containerProps, { className, ref: containerRef }), children)
|
|
);
|
|
});
|
|
RemoveScroll.defaultProps = {
|
|
enabled: true,
|
|
removeScrollBar: true,
|
|
inert: false
|
|
};
|
|
RemoveScroll.classNames = {
|
|
fullWidth: fullWidthClassName,
|
|
zeroRight: zeroRightClassName
|
|
};
|
|
|
|
// node_modules/@radix-ui/react-select/node_modules/react-remove-scroll/dist/es2015/SideEffect.js
|
|
var React5 = __toESM(require_react());
|
|
|
|
// node_modules/@radix-ui/react-select/node_modules/react-remove-scroll/dist/es2015/aggresiveCapture.js
|
|
var passiveSupported = false;
|
|
if (typeof window !== "undefined") {
|
|
try {
|
|
options = Object.defineProperty({}, "passive", {
|
|
get: function() {
|
|
passiveSupported = true;
|
|
return true;
|
|
}
|
|
});
|
|
window.addEventListener("test", options, options);
|
|
window.removeEventListener("test", options, options);
|
|
} catch (err) {
|
|
passiveSupported = false;
|
|
}
|
|
}
|
|
var options;
|
|
var nonPassive = passiveSupported ? { passive: false } : false;
|
|
|
|
// node_modules/@radix-ui/react-select/node_modules/react-remove-scroll/dist/es2015/handleScroll.js
|
|
var alwaysContainsScroll = function(node) {
|
|
return node.tagName === "TEXTAREA";
|
|
};
|
|
var elementCanBeScrolled = function(node, overflow) {
|
|
var styles = window.getComputedStyle(node);
|
|
return (
|
|
// not-not-scrollable
|
|
styles[overflow] !== "hidden" && // contains scroll inside self
|
|
!(styles.overflowY === styles.overflowX && !alwaysContainsScroll(node) && styles[overflow] === "visible")
|
|
);
|
|
};
|
|
var elementCouldBeVScrolled = function(node) {
|
|
return elementCanBeScrolled(node, "overflowY");
|
|
};
|
|
var elementCouldBeHScrolled = function(node) {
|
|
return elementCanBeScrolled(node, "overflowX");
|
|
};
|
|
var locationCouldBeScrolled = function(axis, node) {
|
|
var ownerDocument = node.ownerDocument;
|
|
var current = node;
|
|
do {
|
|
if (typeof ShadowRoot !== "undefined" && current instanceof ShadowRoot) {
|
|
current = current.host;
|
|
}
|
|
var isScrollable = elementCouldBeScrolled(axis, current);
|
|
if (isScrollable) {
|
|
var _a = getScrollVariables(axis, current), s = _a[1], d = _a[2];
|
|
if (s > d) {
|
|
return true;
|
|
}
|
|
}
|
|
current = current.parentNode;
|
|
} while (current && current !== ownerDocument.body);
|
|
return false;
|
|
};
|
|
var getVScrollVariables = function(_a) {
|
|
var scrollTop = _a.scrollTop, scrollHeight = _a.scrollHeight, clientHeight = _a.clientHeight;
|
|
return [
|
|
scrollTop,
|
|
scrollHeight,
|
|
clientHeight
|
|
];
|
|
};
|
|
var getHScrollVariables = function(_a) {
|
|
var scrollLeft = _a.scrollLeft, scrollWidth = _a.scrollWidth, clientWidth = _a.clientWidth;
|
|
return [
|
|
scrollLeft,
|
|
scrollWidth,
|
|
clientWidth
|
|
];
|
|
};
|
|
var elementCouldBeScrolled = function(axis, node) {
|
|
return axis === "v" ? elementCouldBeVScrolled(node) : elementCouldBeHScrolled(node);
|
|
};
|
|
var getScrollVariables = function(axis, node) {
|
|
return axis === "v" ? getVScrollVariables(node) : getHScrollVariables(node);
|
|
};
|
|
var getDirectionFactor = function(axis, direction) {
|
|
return axis === "h" && direction === "rtl" ? -1 : 1;
|
|
};
|
|
var handleScroll = function(axis, endTarget, event, sourceDelta, noOverscroll) {
|
|
var directionFactor = getDirectionFactor(axis, window.getComputedStyle(endTarget).direction);
|
|
var delta = directionFactor * sourceDelta;
|
|
var target = event.target;
|
|
var targetInLock = endTarget.contains(target);
|
|
var shouldCancelScroll = false;
|
|
var isDeltaPositive = delta > 0;
|
|
var availableScroll = 0;
|
|
var availableScrollTop = 0;
|
|
do {
|
|
var _a = getScrollVariables(axis, target), position = _a[0], scroll_1 = _a[1], capacity = _a[2];
|
|
var elementScroll = scroll_1 - capacity - directionFactor * position;
|
|
if (position || elementScroll) {
|
|
if (elementCouldBeScrolled(axis, target)) {
|
|
availableScroll += elementScroll;
|
|
availableScrollTop += position;
|
|
}
|
|
}
|
|
if (target instanceof ShadowRoot) {
|
|
target = target.host;
|
|
} else {
|
|
target = target.parentNode;
|
|
}
|
|
} while (
|
|
// portaled content
|
|
!targetInLock && target !== document.body || // self content
|
|
targetInLock && (endTarget.contains(target) || endTarget === target)
|
|
);
|
|
if (isDeltaPositive && (noOverscroll && Math.abs(availableScroll) < 1 || !noOverscroll && delta > availableScroll)) {
|
|
shouldCancelScroll = true;
|
|
} else if (!isDeltaPositive && (noOverscroll && Math.abs(availableScrollTop) < 1 || !noOverscroll && -delta > availableScrollTop)) {
|
|
shouldCancelScroll = true;
|
|
}
|
|
return shouldCancelScroll;
|
|
};
|
|
|
|
// node_modules/@radix-ui/react-select/node_modules/react-remove-scroll/dist/es2015/SideEffect.js
|
|
var getTouchXY = function(event) {
|
|
return "changedTouches" in event ? [event.changedTouches[0].clientX, event.changedTouches[0].clientY] : [0, 0];
|
|
};
|
|
var getDeltaXY = function(event) {
|
|
return [event.deltaX, event.deltaY];
|
|
};
|
|
var extractRef = function(ref) {
|
|
return ref && "current" in ref ? ref.current : ref;
|
|
};
|
|
var deltaCompare = function(x, y) {
|
|
return x[0] === y[0] && x[1] === y[1];
|
|
};
|
|
var generateStyle = function(id) {
|
|
return "\n .block-interactivity-".concat(id, " {pointer-events: none;}\n .allow-interactivity-").concat(id, " {pointer-events: all;}\n");
|
|
};
|
|
var idCounter = 0;
|
|
var lockStack = [];
|
|
function RemoveScrollSideCar(props) {
|
|
var shouldPreventQueue = React5.useRef([]);
|
|
var touchStartRef = React5.useRef([0, 0]);
|
|
var activeAxis = React5.useRef();
|
|
var id = React5.useState(idCounter++)[0];
|
|
var Style = React5.useState(styleSingleton)[0];
|
|
var lastProps = React5.useRef(props);
|
|
React5.useEffect(function() {
|
|
lastProps.current = props;
|
|
}, [props]);
|
|
React5.useEffect(function() {
|
|
if (props.inert) {
|
|
document.body.classList.add("block-interactivity-".concat(id));
|
|
var allow_1 = __spreadArray([props.lockRef.current], (props.shards || []).map(extractRef), true).filter(Boolean);
|
|
allow_1.forEach(function(el) {
|
|
return el.classList.add("allow-interactivity-".concat(id));
|
|
});
|
|
return function() {
|
|
document.body.classList.remove("block-interactivity-".concat(id));
|
|
allow_1.forEach(function(el) {
|
|
return el.classList.remove("allow-interactivity-".concat(id));
|
|
});
|
|
};
|
|
}
|
|
return;
|
|
}, [props.inert, props.lockRef.current, props.shards]);
|
|
var shouldCancelEvent = React5.useCallback(function(event, parent) {
|
|
if ("touches" in event && event.touches.length === 2) {
|
|
return !lastProps.current.allowPinchZoom;
|
|
}
|
|
var touch = getTouchXY(event);
|
|
var touchStart = touchStartRef.current;
|
|
var deltaX = "deltaX" in event ? event.deltaX : touchStart[0] - touch[0];
|
|
var deltaY = "deltaY" in event ? event.deltaY : touchStart[1] - touch[1];
|
|
var currentAxis;
|
|
var target = event.target;
|
|
var moveDirection = Math.abs(deltaX) > Math.abs(deltaY) ? "h" : "v";
|
|
if ("touches" in event && moveDirection === "h" && target.type === "range") {
|
|
return false;
|
|
}
|
|
var canBeScrolledInMainDirection = locationCouldBeScrolled(moveDirection, target);
|
|
if (!canBeScrolledInMainDirection) {
|
|
return true;
|
|
}
|
|
if (canBeScrolledInMainDirection) {
|
|
currentAxis = moveDirection;
|
|
} else {
|
|
currentAxis = moveDirection === "v" ? "h" : "v";
|
|
canBeScrolledInMainDirection = locationCouldBeScrolled(moveDirection, target);
|
|
}
|
|
if (!canBeScrolledInMainDirection) {
|
|
return false;
|
|
}
|
|
if (!activeAxis.current && "changedTouches" in event && (deltaX || deltaY)) {
|
|
activeAxis.current = currentAxis;
|
|
}
|
|
if (!currentAxis) {
|
|
return true;
|
|
}
|
|
var cancelingAxis = activeAxis.current || currentAxis;
|
|
return handleScroll(cancelingAxis, parent, event, cancelingAxis === "h" ? deltaX : deltaY, true);
|
|
}, []);
|
|
var shouldPrevent = React5.useCallback(function(_event) {
|
|
var event = _event;
|
|
if (!lockStack.length || lockStack[lockStack.length - 1] !== Style) {
|
|
return;
|
|
}
|
|
var delta = "deltaY" in event ? getDeltaXY(event) : getTouchXY(event);
|
|
var sourceEvent = shouldPreventQueue.current.filter(function(e) {
|
|
return e.name === event.type && (e.target === event.target || event.target === e.shadowParent) && deltaCompare(e.delta, delta);
|
|
})[0];
|
|
if (sourceEvent && sourceEvent.should) {
|
|
if (event.cancelable) {
|
|
event.preventDefault();
|
|
}
|
|
return;
|
|
}
|
|
if (!sourceEvent) {
|
|
var shardNodes = (lastProps.current.shards || []).map(extractRef).filter(Boolean).filter(function(node) {
|
|
return node.contains(event.target);
|
|
});
|
|
var shouldStop = shardNodes.length > 0 ? shouldCancelEvent(event, shardNodes[0]) : !lastProps.current.noIsolation;
|
|
if (shouldStop) {
|
|
if (event.cancelable) {
|
|
event.preventDefault();
|
|
}
|
|
}
|
|
}
|
|
}, []);
|
|
var shouldCancel = React5.useCallback(function(name, delta, target, should) {
|
|
var event = { name, delta, target, should, shadowParent: getOutermostShadowParent(target) };
|
|
shouldPreventQueue.current.push(event);
|
|
setTimeout(function() {
|
|
shouldPreventQueue.current = shouldPreventQueue.current.filter(function(e) {
|
|
return e !== event;
|
|
});
|
|
}, 1);
|
|
}, []);
|
|
var scrollTouchStart = React5.useCallback(function(event) {
|
|
touchStartRef.current = getTouchXY(event);
|
|
activeAxis.current = void 0;
|
|
}, []);
|
|
var scrollWheel = React5.useCallback(function(event) {
|
|
shouldCancel(event.type, getDeltaXY(event), event.target, shouldCancelEvent(event, props.lockRef.current));
|
|
}, []);
|
|
var scrollTouchMove = React5.useCallback(function(event) {
|
|
shouldCancel(event.type, getTouchXY(event), event.target, shouldCancelEvent(event, props.lockRef.current));
|
|
}, []);
|
|
React5.useEffect(function() {
|
|
lockStack.push(Style);
|
|
props.setCallbacks({
|
|
onScrollCapture: scrollWheel,
|
|
onWheelCapture: scrollWheel,
|
|
onTouchMoveCapture: scrollTouchMove
|
|
});
|
|
document.addEventListener("wheel", shouldPrevent, nonPassive);
|
|
document.addEventListener("touchmove", shouldPrevent, nonPassive);
|
|
document.addEventListener("touchstart", scrollTouchStart, nonPassive);
|
|
return function() {
|
|
lockStack = lockStack.filter(function(inst) {
|
|
return inst !== Style;
|
|
});
|
|
document.removeEventListener("wheel", shouldPrevent, nonPassive);
|
|
document.removeEventListener("touchmove", shouldPrevent, nonPassive);
|
|
document.removeEventListener("touchstart", scrollTouchStart, nonPassive);
|
|
};
|
|
}, []);
|
|
var removeScrollBar = props.removeScrollBar, inert = props.inert;
|
|
return React5.createElement(
|
|
React5.Fragment,
|
|
null,
|
|
inert ? React5.createElement(Style, { styles: generateStyle(id) }) : null,
|
|
removeScrollBar ? React5.createElement(RemoveScrollBar, { gapMode: props.gapMode }) : null
|
|
);
|
|
}
|
|
function getOutermostShadowParent(node) {
|
|
var shadowParent = null;
|
|
while (node !== null) {
|
|
if (node instanceof ShadowRoot) {
|
|
shadowParent = node.host;
|
|
node = node.host;
|
|
}
|
|
node = node.parentNode;
|
|
}
|
|
return shadowParent;
|
|
}
|
|
|
|
// node_modules/@radix-ui/react-select/node_modules/react-remove-scroll/dist/es2015/sidecar.js
|
|
var sidecar_default = exportSidecar(effectCar, RemoveScrollSideCar);
|
|
|
|
// node_modules/@radix-ui/react-select/node_modules/react-remove-scroll/dist/es2015/Combination.js
|
|
var ReactRemoveScroll = React6.forwardRef(function(props, ref) {
|
|
return React6.createElement(RemoveScroll, __assign({}, props, { ref, sideCar: sidecar_default }));
|
|
});
|
|
ReactRemoveScroll.classNames = RemoveScroll.classNames;
|
|
var Combination_default = ReactRemoveScroll;
|
|
|
|
// node_modules/@radix-ui/react-select/dist/index.mjs
|
|
var import_jsx_runtime3 = __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
|
|
} = props;
|
|
const popperScope = usePopperScope(__scopeSelect);
|
|
const [trigger, setTrigger] = React7.useState(null);
|
|
const [valueNode, setValueNode] = React7.useState(null);
|
|
const [valueNodeHasChildren, setValueNodeHasChildren] = React7.useState(false);
|
|
const direction = useDirection(dir);
|
|
const [open = false, setOpen] = useControllableState({
|
|
prop: openProp,
|
|
defaultProp: defaultOpen,
|
|
onChange: onOpenChange
|
|
});
|
|
const [value, setValue] = useControllableState({
|
|
prop: valueProp,
|
|
defaultProp: defaultValue,
|
|
onChange: onValueChange
|
|
});
|
|
const triggerPointerDownPosRef = React7.useRef(null);
|
|
const isFormControl = trigger ? Boolean(trigger.closest("form")) : true;
|
|
const [nativeOptionsSet, setNativeOptionsSet] = React7.useState(/* @__PURE__ */ new Set());
|
|
const nativeSelectKey = Array.from(nativeOptionsSet).map((option) => option.props.value).join(";");
|
|
return (0, import_jsx_runtime3.jsx)(Root2, { ...popperScope, children: (0, import_jsx_runtime3.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_runtime3.jsx)(Collection.Provider, { scope: __scopeSelect, children: (0, import_jsx_runtime3.jsx)(
|
|
SelectNativeOptionsProvider,
|
|
{
|
|
scope: props.__scopeSelect,
|
|
onNativeOptionAdd: React7.useCallback((option) => {
|
|
setNativeOptionsSet((prev) => new Set(prev).add(option));
|
|
}, []),
|
|
onNativeOptionRemove: React7.useCallback((option) => {
|
|
setNativeOptionsSet((prev) => {
|
|
const optionsSet = new Set(prev);
|
|
optionsSet.delete(option);
|
|
return optionsSet;
|
|
});
|
|
}, []),
|
|
children
|
|
}
|
|
) }),
|
|
isFormControl ? (0, import_jsx_runtime3.jsxs)(
|
|
BubbleSelect,
|
|
{
|
|
"aria-hidden": true,
|
|
required,
|
|
tabIndex: -1,
|
|
name,
|
|
autoComplete,
|
|
value,
|
|
onChange: (event) => setValue(event.target.value),
|
|
disabled,
|
|
children: [
|
|
value === void 0 ? (0, import_jsx_runtime3.jsx)("option", { value: "" }) : null,
|
|
Array.from(nativeOptionsSet)
|
|
]
|
|
},
|
|
nativeSelectKey
|
|
) : null
|
|
]
|
|
}
|
|
) });
|
|
};
|
|
Select.displayName = SELECT_NAME;
|
|
var TRIGGER_NAME = "SelectTrigger";
|
|
var SelectTrigger = React7.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 [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 = () => {
|
|
if (!isDisabled) {
|
|
context.onOpenChange(true);
|
|
resetTypeahead();
|
|
}
|
|
};
|
|
return (0, import_jsx_runtime3.jsx)(Anchor, { asChild: true, ...popperScope, children: (0, import_jsx_runtime3.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();
|
|
}),
|
|
onPointerDown: composeEventHandlers(triggerProps.onPointerDown, (event) => {
|
|
const target = event.target;
|
|
if (target.hasPointerCapture(event.pointerId)) {
|
|
target.releasePointerCapture(event.pointerId);
|
|
}
|
|
if (event.button === 0 && event.ctrlKey === false) {
|
|
handleOpen();
|
|
context.triggerPointerDownPosRef.current = {
|
|
x: Math.round(event.pageX),
|
|
y: Math.round(event.pageY)
|
|
};
|
|
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 = React7.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_runtime3.jsx)(
|
|
Primitive.span,
|
|
{
|
|
...valueProps,
|
|
ref: composedRefs,
|
|
style: { pointerEvents: "none" },
|
|
children: shouldShowPlaceholder(context.value) ? (0, import_jsx_runtime3.jsx)(import_jsx_runtime3.Fragment, { children: placeholder }) : children
|
|
}
|
|
);
|
|
}
|
|
);
|
|
SelectValue.displayName = VALUE_NAME;
|
|
var ICON_NAME = "SelectIcon";
|
|
var SelectIcon = React7.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeSelect, children, ...iconProps } = props;
|
|
return (0, import_jsx_runtime3.jsx)(Primitive.span, { "aria-hidden": true, ...iconProps, ref: forwardedRef, children: children || "▼" });
|
|
}
|
|
);
|
|
SelectIcon.displayName = ICON_NAME;
|
|
var PORTAL_NAME2 = "SelectPortal";
|
|
var SelectPortal = (props) => {
|
|
return (0, import_jsx_runtime3.jsx)(Portal, { asChild: true, ...props });
|
|
};
|
|
SelectPortal.displayName = PORTAL_NAME2;
|
|
var CONTENT_NAME = "SelectContent";
|
|
var SelectContent = React7.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const context = useSelectContext(CONTENT_NAME, props.__scopeSelect);
|
|
const [fragment, setFragment] = React7.useState();
|
|
useLayoutEffect2(() => {
|
|
setFragment(new DocumentFragment());
|
|
}, []);
|
|
if (!context.open) {
|
|
const frag = fragment;
|
|
return frag ? ReactDOM2.createPortal(
|
|
(0, import_jsx_runtime3.jsx)(SelectContentProvider, { scope: props.__scopeSelect, children: (0, import_jsx_runtime3.jsx)(Collection.Slot, { scope: props.__scopeSelect, children: (0, import_jsx_runtime3.jsx)("div", { children: props.children }) }) }),
|
|
frag
|
|
) : null;
|
|
}
|
|
return (0, import_jsx_runtime3.jsx)(SelectContentImpl, { ...props, ref: forwardedRef });
|
|
}
|
|
);
|
|
SelectContent.displayName = CONTENT_NAME;
|
|
var CONTENT_MARGIN = 10;
|
|
var [SelectContentProvider, useSelectContentContext] = createSelectContext(CONTENT_NAME);
|
|
var CONTENT_IMPL_NAME = "SelectContentImpl";
|
|
var SelectContentImpl = React7.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_NAME, __scopeSelect);
|
|
const [content, setContent] = React7.useState(null);
|
|
const [viewport, setViewport] = React7.useState(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, (node) => setContent(node));
|
|
const [selectedItem, setSelectedItem] = React7.useState(null);
|
|
const [selectedItemText, setSelectedItemText] = React7.useState(
|
|
null
|
|
);
|
|
const getItems = useCollection(__scopeSelect);
|
|
const [isPositioned, setIsPositioned] = React7.useState(false);
|
|
const firstValidItemFoundRef = React7.useRef(false);
|
|
React7.useEffect(() => {
|
|
if (content) return hideOthers(content);
|
|
}, [content]);
|
|
useFocusGuards();
|
|
const focusFirst = React7.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 = React7.useCallback(
|
|
() => focusFirst([selectedItem, content]),
|
|
[focusFirst, selectedItem, content]
|
|
);
|
|
React7.useEffect(() => {
|
|
if (isPositioned) {
|
|
focusSelectedItem();
|
|
}
|
|
}, [isPositioned, focusSelectedItem]);
|
|
const { onOpenChange, triggerPointerDownPosRef } = context;
|
|
React7.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]);
|
|
React7.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 = React7.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 = React7.useCallback(() => content == null ? void 0 : content.focus(), [content]);
|
|
const itemTextRefCallback = React7.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_runtime3.jsx)(
|
|
SelectContentProvider,
|
|
{
|
|
scope: __scopeSelect,
|
|
content,
|
|
viewport,
|
|
onViewportChange: setViewport,
|
|
itemRefCallback,
|
|
selectedItem,
|
|
onItemLeave: handleItemLeave,
|
|
itemTextRefCallback,
|
|
focusSelectedItem,
|
|
selectedItemText,
|
|
position,
|
|
isPositioned,
|
|
searchRef,
|
|
children: (0, import_jsx_runtime3.jsx)(Combination_default, { as: Slot, allowPinchZoom: true, children: (0, import_jsx_runtime3.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_runtime3.jsx)(
|
|
DismissableLayer,
|
|
{
|
|
asChild: true,
|
|
disableOutsidePointerEvents: true,
|
|
onEscapeKeyDown,
|
|
onPointerDownOutside,
|
|
onFocusOutside: (event) => event.preventDefault(),
|
|
onDismiss: () => context.onOpenChange(false),
|
|
children: (0, import_jsx_runtime3.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 = React7.forwardRef((props, forwardedRef) => {
|
|
const { __scopeSelect, onPlaced, ...popperProps } = props;
|
|
const context = useSelectContext(CONTENT_NAME, __scopeSelect);
|
|
const contentContext = useSelectContentContext(CONTENT_NAME, __scopeSelect);
|
|
const [contentWrapper, setContentWrapper] = React7.useState(null);
|
|
const [content, setContent] = React7.useState(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, (node) => setContent(node));
|
|
const getItems = useCollection(__scopeSelect);
|
|
const shouldExpandOnScrollRef = React7.useRef(false);
|
|
const shouldRepositionRef = React7.useRef(true);
|
|
const { viewport, selectedItem, selectedItemText, focusSelectedItem } = contentContext;
|
|
const position = React7.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, 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, 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 = 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 = 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] = React7.useState();
|
|
useLayoutEffect2(() => {
|
|
if (content) setContentZIndex(window.getComputedStyle(content).zIndex);
|
|
}, [content]);
|
|
const handleScrollButtonChange = React7.useCallback(
|
|
(node) => {
|
|
if (node && shouldRepositionRef.current === true) {
|
|
position();
|
|
focusSelectedItem == null ? void 0 : focusSelectedItem();
|
|
shouldRepositionRef.current = false;
|
|
}
|
|
},
|
|
[position, focusSelectedItem]
|
|
);
|
|
return (0, import_jsx_runtime3.jsx)(
|
|
SelectViewportProvider,
|
|
{
|
|
scope: __scopeSelect,
|
|
contentWrapper,
|
|
shouldExpandOnScrollRef,
|
|
onScrollButtonChange: handleScrollButtonChange,
|
|
children: (0, import_jsx_runtime3.jsx)(
|
|
"div",
|
|
{
|
|
ref: setContentWrapper,
|
|
style: {
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
position: "fixed",
|
|
zIndex: contentZIndex
|
|
},
|
|
children: (0, import_jsx_runtime3.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 = React7.forwardRef((props, forwardedRef) => {
|
|
const {
|
|
__scopeSelect,
|
|
align = "start",
|
|
collisionPadding = CONTENT_MARGIN,
|
|
...popperProps
|
|
} = props;
|
|
const popperScope = usePopperScope(__scopeSelect);
|
|
return (0, import_jsx_runtime3.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_NAME, {});
|
|
var VIEWPORT_NAME = "SelectViewport";
|
|
var SelectViewport = React7.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 = React7.useRef(0);
|
|
return (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
(0, import_jsx_runtime3.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_runtime3.jsx)(Collection.Slot, { scope: __scopeSelect, children: (0, import_jsx_runtime3.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,
|
|
overflow: "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 = React7.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeSelect, ...groupProps } = props;
|
|
const groupId = useId();
|
|
return (0, import_jsx_runtime3.jsx)(SelectGroupContextProvider, { scope: __scopeSelect, id: groupId, children: (0, import_jsx_runtime3.jsx)(Primitive.div, { role: "group", "aria-labelledby": groupId, ...groupProps, ref: forwardedRef }) });
|
|
}
|
|
);
|
|
SelectGroup.displayName = GROUP_NAME;
|
|
var LABEL_NAME = "SelectLabel";
|
|
var SelectLabel = React7.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeSelect, ...labelProps } = props;
|
|
const groupContext = useSelectGroupContext(LABEL_NAME, __scopeSelect);
|
|
return (0, import_jsx_runtime3.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 = React7.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] = React7.useState(textValueProp ?? "");
|
|
const [isFocused, setIsFocused] = React7.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 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_runtime3.jsx)(
|
|
SelectItemContextProvider,
|
|
{
|
|
scope: __scopeSelect,
|
|
value,
|
|
disabled,
|
|
textId,
|
|
isSelected,
|
|
onItemTextChange: React7.useCallback((node) => {
|
|
setTextValue((prevTextValue) => prevTextValue || ((node == null ? void 0 : node.textContent) ?? "").trim());
|
|
}, []),
|
|
children: (0, import_jsx_runtime3.jsx)(
|
|
Collection.ItemSlot,
|
|
{
|
|
scope: __scopeSelect,
|
|
value,
|
|
disabled,
|
|
textValue,
|
|
children: (0, import_jsx_runtime3.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)),
|
|
onPointerUp: composeEventHandlers(itemProps.onPointerUp, handleSelect),
|
|
onPointerMove: composeEventHandlers(itemProps.onPointerMove, (event) => {
|
|
var _a;
|
|
if (disabled) {
|
|
(_a = contentContext.onItemLeave) == null ? void 0 : _a.call(contentContext);
|
|
} else {
|
|
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 = React7.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] = React7.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 = React7.useMemo(
|
|
() => (0, import_jsx_runtime3.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_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
(0, import_jsx_runtime3.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 = React7.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeSelect, ...itemIndicatorProps } = props;
|
|
const itemContext = useSelectItemContext(ITEM_INDICATOR_NAME, __scopeSelect);
|
|
return itemContext.isSelected ? (0, import_jsx_runtime3.jsx)(Primitive.span, { "aria-hidden": true, ...itemIndicatorProps, ref: forwardedRef }) : null;
|
|
}
|
|
);
|
|
SelectItemIndicator.displayName = ITEM_INDICATOR_NAME;
|
|
var SCROLL_UP_BUTTON_NAME = "SelectScrollUpButton";
|
|
var SelectScrollUpButton = React7.forwardRef((props, forwardedRef) => {
|
|
const contentContext = useSelectContentContext(SCROLL_UP_BUTTON_NAME, props.__scopeSelect);
|
|
const viewportContext = useSelectViewportContext(SCROLL_UP_BUTTON_NAME, props.__scopeSelect);
|
|
const [canScrollUp, setCanScrollUp] = React7.useState(false);
|
|
const composedRefs = useComposedRefs(forwardedRef, viewportContext.onScrollButtonChange);
|
|
useLayoutEffect2(() => {
|
|
if (contentContext.viewport && contentContext.isPositioned) {
|
|
let handleScroll22 = function() {
|
|
const canScrollUp2 = viewport.scrollTop > 0;
|
|
setCanScrollUp(canScrollUp2);
|
|
};
|
|
var handleScroll2 = handleScroll22;
|
|
const viewport = contentContext.viewport;
|
|
handleScroll22();
|
|
viewport.addEventListener("scroll", handleScroll22);
|
|
return () => viewport.removeEventListener("scroll", handleScroll22);
|
|
}
|
|
}, [contentContext.viewport, contentContext.isPositioned]);
|
|
return canScrollUp ? (0, import_jsx_runtime3.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 = React7.forwardRef((props, forwardedRef) => {
|
|
const contentContext = useSelectContentContext(SCROLL_DOWN_BUTTON_NAME, props.__scopeSelect);
|
|
const viewportContext = useSelectViewportContext(SCROLL_DOWN_BUTTON_NAME, props.__scopeSelect);
|
|
const [canScrollDown, setCanScrollDown] = React7.useState(false);
|
|
const composedRefs = useComposedRefs(forwardedRef, viewportContext.onScrollButtonChange);
|
|
useLayoutEffect2(() => {
|
|
if (contentContext.viewport && contentContext.isPositioned) {
|
|
let handleScroll22 = function() {
|
|
const maxScroll = viewport.scrollHeight - viewport.clientHeight;
|
|
const canScrollDown2 = Math.ceil(viewport.scrollTop) < maxScroll;
|
|
setCanScrollDown(canScrollDown2);
|
|
};
|
|
var handleScroll2 = handleScroll22;
|
|
const viewport = contentContext.viewport;
|
|
handleScroll22();
|
|
viewport.addEventListener("scroll", handleScroll22);
|
|
return () => viewport.removeEventListener("scroll", handleScroll22);
|
|
}
|
|
}, [contentContext.viewport, contentContext.isPositioned]);
|
|
return canScrollDown ? (0, import_jsx_runtime3.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 = React7.forwardRef((props, forwardedRef) => {
|
|
const { __scopeSelect, onAutoScroll, ...scrollIndicatorProps } = props;
|
|
const contentContext = useSelectContentContext("SelectScrollButton", __scopeSelect);
|
|
const autoScrollTimerRef = React7.useRef(null);
|
|
const getItems = useCollection(__scopeSelect);
|
|
const clearAutoScrollTimer = React7.useCallback(() => {
|
|
if (autoScrollTimerRef.current !== null) {
|
|
window.clearInterval(autoScrollTimerRef.current);
|
|
autoScrollTimerRef.current = null;
|
|
}
|
|
}, []);
|
|
React7.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_runtime3.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 = React7.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeSelect, ...separatorProps } = props;
|
|
return (0, import_jsx_runtime3.jsx)(Primitive.div, { "aria-hidden": true, ...separatorProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
SelectSeparator.displayName = SEPARATOR_NAME;
|
|
var ARROW_NAME = "SelectArrow";
|
|
var SelectArrow = React7.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeSelect, ...arrowProps } = props;
|
|
const popperScope = usePopperScope(__scopeSelect);
|
|
const context = useSelectContext(ARROW_NAME, __scopeSelect);
|
|
const contentContext = useSelectContentContext(ARROW_NAME, __scopeSelect);
|
|
return context.open && contentContext.position === "popper" ? (0, import_jsx_runtime3.jsx)(Arrow, { ...popperScope, ...arrowProps, ref: forwardedRef }) : null;
|
|
}
|
|
);
|
|
SelectArrow.displayName = ARROW_NAME;
|
|
function shouldShowPlaceholder(value) {
|
|
return value === "" || value === void 0;
|
|
}
|
|
var BubbleSelect = React7.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { value, ...selectProps } = props;
|
|
const ref = React7.useRef(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, ref);
|
|
const prevValue = usePrevious(value);
|
|
React7.useEffect(() => {
|
|
const select = ref.current;
|
|
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_runtime3.jsx)(VisuallyHidden, { asChild: true, children: (0, import_jsx_runtime3.jsx)("select", { ...selectProps, ref: composedRefs, defaultValue: value }) });
|
|
}
|
|
);
|
|
BubbleSelect.displayName = "BubbleSelect";
|
|
function useTypeaheadSearch(onSearchChange) {
|
|
const handleSearchChange = useCallbackRef(onSearchChange);
|
|
const searchRef = React7.useRef("");
|
|
const timerRef = React7.useRef(0);
|
|
const handleTypeaheadSearch = React7.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 = React7.useCallback(() => {
|
|
searchRef.current = "";
|
|
window.clearTimeout(timerRef.current);
|
|
}, []);
|
|
React7.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((_, index) => array[(startIndex + index) % 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 Arrow2 = SelectArrow;
|
|
export {
|
|
Arrow2 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
|