- Added ResponsiveDialog component for handling responsive dialogs in the UI. - Created ExpensesProvider to manage state and API interactions for expenses. - Developed ExpensesTabContent to display expenses with filtering options and dialogs for new and pay expense actions. - Implemented ExpensesTable for rendering expense data in a tabular format with actions. - Added dialogs for creating new expenses and paying existing ones with form validation. - Introduced PeriodicExpenseForm for managing periodic expenses with month selection. - Created PeriodicExpensesTabContent to manage and display periodic expenses with create/edit functionality. - Added GenerateCurrentMonthDialog for confirming monthly expense generation. - Implemented PeriodicExpensesTable for displaying periodic expenses with edit and delete actions.
11058 lines
420 KiB
JavaScript
11058 lines
420 KiB
JavaScript
import {
|
|
Close,
|
|
Content as Content2,
|
|
Description,
|
|
Overlay,
|
|
Portal as Portal2,
|
|
Root as Root3,
|
|
Title,
|
|
Trigger,
|
|
WarningProvider,
|
|
createDialogScope,
|
|
dist_exports as dist_exports4
|
|
} from "./chunk-O6J3DKHL.js";
|
|
import {
|
|
require_shim
|
|
} from "./chunk-X37QSMNJ.js";
|
|
import {
|
|
Anchor,
|
|
Arrow,
|
|
Content,
|
|
Root2 as Root22,
|
|
createPopperScope,
|
|
dist_exports as dist_exports3,
|
|
useSize
|
|
} from "./chunk-R6CVIFUM.js";
|
|
import {
|
|
Branch,
|
|
Combination_default,
|
|
DismissableLayer,
|
|
FocusScope,
|
|
Portal,
|
|
Presence,
|
|
Primitive,
|
|
Root,
|
|
Root2,
|
|
composeEventHandlers,
|
|
composeRefs,
|
|
createContextScope,
|
|
createSlot,
|
|
createSlottable,
|
|
dispatchDiscreteCustomEvent,
|
|
dist_exports,
|
|
dist_exports2,
|
|
hideOthers,
|
|
useCallbackRef,
|
|
useComposedRefs,
|
|
useControllableState,
|
|
useEffectEvent,
|
|
useFocusGuards,
|
|
useId,
|
|
useLayoutEffect2
|
|
} from "./chunk-2EY3U74L.js";
|
|
import {
|
|
require_jsx_runtime
|
|
} from "./chunk-SOQCU2R6.js";
|
|
import {
|
|
require_react_dom
|
|
} from "./chunk-JCMTJHXH.js";
|
|
import {
|
|
require_react
|
|
} from "./chunk-6VO5C3OI.js";
|
|
import {
|
|
__export,
|
|
__privateAdd,
|
|
__privateGet,
|
|
__privateSet,
|
|
__toESM
|
|
} from "./chunk-WOOG5QLI.js";
|
|
|
|
// ../../node_modules/@radix-ui/react-accessible-icon/dist/index.mjs
|
|
var dist_exports6 = {};
|
|
__export(dist_exports6, {
|
|
AccessibleIcon: () => AccessibleIcon,
|
|
Root: () => Root23
|
|
});
|
|
var React2 = __toESM(require_react(), 1);
|
|
|
|
// ../../node_modules/@radix-ui/react-visually-hidden/dist/index.mjs
|
|
var dist_exports5 = {};
|
|
__export(dist_exports5, {
|
|
Root: () => Root4,
|
|
VISUALLY_HIDDEN_STYLES: () => VISUALLY_HIDDEN_STYLES,
|
|
VisuallyHidden: () => VisuallyHidden
|
|
});
|
|
var React = __toESM(require_react(), 1);
|
|
var import_jsx_runtime = __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 NAME = "VisuallyHidden";
|
|
var VisuallyHidden = React.forwardRef(
|
|
(props, forwardedRef) => {
|
|
return (0, import_jsx_runtime.jsx)(
|
|
Primitive.span,
|
|
{
|
|
...props,
|
|
ref: forwardedRef,
|
|
style: { ...VISUALLY_HIDDEN_STYLES, ...props.style }
|
|
}
|
|
);
|
|
}
|
|
);
|
|
VisuallyHidden.displayName = NAME;
|
|
var Root4 = VisuallyHidden;
|
|
|
|
// ../../node_modules/@radix-ui/react-accessible-icon/dist/index.mjs
|
|
var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
|
|
var NAME2 = "AccessibleIcon";
|
|
var AccessibleIcon = ({ children, label }) => {
|
|
const child = React2.Children.only(children);
|
|
return (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
React2.cloneElement(child, {
|
|
// accessibility
|
|
"aria-hidden": "true",
|
|
focusable: "false"
|
|
// See: https://allyjs.io/tutorials/focusing-in-svg.html#making-svg-elements-focusable
|
|
}),
|
|
(0, import_jsx_runtime2.jsx)(Root4, { children: label })
|
|
] });
|
|
};
|
|
AccessibleIcon.displayName = NAME2;
|
|
var Root23 = AccessibleIcon;
|
|
|
|
// ../../node_modules/@radix-ui/react-accordion/dist/index.mjs
|
|
var dist_exports9 = {};
|
|
__export(dist_exports9, {
|
|
Accordion: () => Accordion,
|
|
AccordionContent: () => AccordionContent,
|
|
AccordionHeader: () => AccordionHeader,
|
|
AccordionItem: () => AccordionItem,
|
|
AccordionTrigger: () => AccordionTrigger,
|
|
Content: () => Content22,
|
|
Header: () => Header,
|
|
Item: () => Item,
|
|
Root: () => Root24,
|
|
Trigger: () => Trigger22,
|
|
createAccordionScope: () => createAccordionScope
|
|
});
|
|
var import_react3 = __toESM(require_react(), 1);
|
|
|
|
// ../../node_modules/@radix-ui/react-collection/dist/index.mjs
|
|
var import_react = __toESM(require_react(), 1);
|
|
var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1);
|
|
var import_react2 = __toESM(require_react(), 1);
|
|
var import_jsx_runtime4 = __toESM(require_jsx_runtime(), 1);
|
|
function createCollection(name) {
|
|
const PROVIDER_NAME3 = name + "CollectionProvider";
|
|
const [createCollectionContext, createCollectionScope10] = createContextScope(PROVIDER_NAME3);
|
|
const [CollectionProviderImpl, useCollectionContext] = createCollectionContext(
|
|
PROVIDER_NAME3,
|
|
{ collectionRef: { current: null }, itemMap: /* @__PURE__ */ new Map() }
|
|
);
|
|
const CollectionProvider = (props) => {
|
|
const { scope, children } = props;
|
|
const ref = import_react.default.useRef(null);
|
|
const itemMap = import_react.default.useRef(/* @__PURE__ */ new Map()).current;
|
|
return (0, import_jsx_runtime3.jsx)(CollectionProviderImpl, { scope, itemMap, collectionRef: ref, children });
|
|
};
|
|
CollectionProvider.displayName = PROVIDER_NAME3;
|
|
const COLLECTION_SLOT_NAME = name + "CollectionSlot";
|
|
const CollectionSlotImpl = createSlot(COLLECTION_SLOT_NAME);
|
|
const CollectionSlot = import_react.default.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { scope, children } = props;
|
|
const context = useCollectionContext(COLLECTION_SLOT_NAME, scope);
|
|
const composedRefs = useComposedRefs(forwardedRef, context.collectionRef);
|
|
return (0, import_jsx_runtime3.jsx)(CollectionSlotImpl, { ref: composedRefs, children });
|
|
}
|
|
);
|
|
CollectionSlot.displayName = COLLECTION_SLOT_NAME;
|
|
const ITEM_SLOT_NAME = name + "CollectionItemSlot";
|
|
const ITEM_DATA_ATTR = "data-radix-collection-item";
|
|
const CollectionItemSlotImpl = createSlot(ITEM_SLOT_NAME);
|
|
const CollectionItemSlot = import_react.default.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { scope, children, ...itemData } = props;
|
|
const ref = import_react.default.useRef(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, ref);
|
|
const context = useCollectionContext(ITEM_SLOT_NAME, scope);
|
|
import_react.default.useEffect(() => {
|
|
context.itemMap.set(ref, { ref, ...itemData });
|
|
return () => void context.itemMap.delete(ref);
|
|
});
|
|
return (0, import_jsx_runtime3.jsx)(CollectionItemSlotImpl, { ...{ [ITEM_DATA_ATTR]: "" }, ref: composedRefs, children });
|
|
}
|
|
);
|
|
CollectionItemSlot.displayName = ITEM_SLOT_NAME;
|
|
function useCollection10(scope) {
|
|
const context = useCollectionContext(name + "CollectionConsumer", scope);
|
|
const getItems = import_react.default.useCallback(() => {
|
|
const collectionNode = context.collectionRef.current;
|
|
if (!collectionNode) return [];
|
|
const orderedNodes = Array.from(collectionNode.querySelectorAll(`[${ITEM_DATA_ATTR}]`));
|
|
const items = Array.from(context.itemMap.values());
|
|
const orderedItems = items.sort(
|
|
(a, b) => orderedNodes.indexOf(a.ref.current) - orderedNodes.indexOf(b.ref.current)
|
|
);
|
|
return orderedItems;
|
|
}, [context.collectionRef, context.itemMap]);
|
|
return getItems;
|
|
}
|
|
return [
|
|
{ Provider: CollectionProvider, Slot: CollectionSlot, ItemSlot: CollectionItemSlot },
|
|
useCollection10,
|
|
createCollectionScope10
|
|
];
|
|
}
|
|
var __instanciated = /* @__PURE__ */ new WeakMap();
|
|
var _keys, _a;
|
|
var OrderedDict = (_a = class extends Map {
|
|
constructor(entries) {
|
|
super(entries);
|
|
__privateAdd(this, _keys);
|
|
__privateSet(this, _keys, [...super.keys()]);
|
|
__instanciated.set(this, true);
|
|
}
|
|
set(key, value) {
|
|
if (__instanciated.get(this)) {
|
|
if (this.has(key)) {
|
|
__privateGet(this, _keys)[__privateGet(this, _keys).indexOf(key)] = key;
|
|
} else {
|
|
__privateGet(this, _keys).push(key);
|
|
}
|
|
}
|
|
super.set(key, value);
|
|
return this;
|
|
}
|
|
insert(index, key, value) {
|
|
const has = this.has(key);
|
|
const length = __privateGet(this, _keys).length;
|
|
const relativeIndex = toSafeInteger(index);
|
|
let actualIndex = relativeIndex >= 0 ? relativeIndex : length + relativeIndex;
|
|
const safeIndex = actualIndex < 0 || actualIndex >= length ? -1 : actualIndex;
|
|
if (safeIndex === this.size || has && safeIndex === this.size - 1 || safeIndex === -1) {
|
|
this.set(key, value);
|
|
return this;
|
|
}
|
|
const size = this.size + (has ? 0 : 1);
|
|
if (relativeIndex < 0) {
|
|
actualIndex++;
|
|
}
|
|
const keys = [...__privateGet(this, _keys)];
|
|
let nextValue;
|
|
let shouldSkip = false;
|
|
for (let i = actualIndex; i < size; i++) {
|
|
if (actualIndex === i) {
|
|
let nextKey = keys[i];
|
|
if (keys[i] === key) {
|
|
nextKey = keys[i + 1];
|
|
}
|
|
if (has) {
|
|
this.delete(key);
|
|
}
|
|
nextValue = this.get(nextKey);
|
|
this.set(key, value);
|
|
} else {
|
|
if (!shouldSkip && keys[i - 1] === key) {
|
|
shouldSkip = true;
|
|
}
|
|
const currentKey = keys[shouldSkip ? i : i - 1];
|
|
const currentValue = nextValue;
|
|
nextValue = this.get(currentKey);
|
|
this.delete(currentKey);
|
|
this.set(currentKey, currentValue);
|
|
}
|
|
}
|
|
return this;
|
|
}
|
|
with(index, key, value) {
|
|
const copy = new _a(this);
|
|
copy.insert(index, key, value);
|
|
return copy;
|
|
}
|
|
before(key) {
|
|
const index = __privateGet(this, _keys).indexOf(key) - 1;
|
|
if (index < 0) {
|
|
return void 0;
|
|
}
|
|
return this.entryAt(index);
|
|
}
|
|
/**
|
|
* Sets a new key-value pair at the position before the given key.
|
|
*/
|
|
setBefore(key, newKey, value) {
|
|
const index = __privateGet(this, _keys).indexOf(key);
|
|
if (index === -1) {
|
|
return this;
|
|
}
|
|
return this.insert(index, newKey, value);
|
|
}
|
|
after(key) {
|
|
let index = __privateGet(this, _keys).indexOf(key);
|
|
index = index === -1 || index === this.size - 1 ? -1 : index + 1;
|
|
if (index === -1) {
|
|
return void 0;
|
|
}
|
|
return this.entryAt(index);
|
|
}
|
|
/**
|
|
* Sets a new key-value pair at the position after the given key.
|
|
*/
|
|
setAfter(key, newKey, value) {
|
|
const index = __privateGet(this, _keys).indexOf(key);
|
|
if (index === -1) {
|
|
return this;
|
|
}
|
|
return this.insert(index + 1, newKey, value);
|
|
}
|
|
first() {
|
|
return this.entryAt(0);
|
|
}
|
|
last() {
|
|
return this.entryAt(-1);
|
|
}
|
|
clear() {
|
|
__privateSet(this, _keys, []);
|
|
return super.clear();
|
|
}
|
|
delete(key) {
|
|
const deleted = super.delete(key);
|
|
if (deleted) {
|
|
__privateGet(this, _keys).splice(__privateGet(this, _keys).indexOf(key), 1);
|
|
}
|
|
return deleted;
|
|
}
|
|
deleteAt(index) {
|
|
const key = this.keyAt(index);
|
|
if (key !== void 0) {
|
|
return this.delete(key);
|
|
}
|
|
return false;
|
|
}
|
|
at(index) {
|
|
const key = at(__privateGet(this, _keys), index);
|
|
if (key !== void 0) {
|
|
return this.get(key);
|
|
}
|
|
}
|
|
entryAt(index) {
|
|
const key = at(__privateGet(this, _keys), index);
|
|
if (key !== void 0) {
|
|
return [key, this.get(key)];
|
|
}
|
|
}
|
|
indexOf(key) {
|
|
return __privateGet(this, _keys).indexOf(key);
|
|
}
|
|
keyAt(index) {
|
|
return at(__privateGet(this, _keys), index);
|
|
}
|
|
from(key, offset) {
|
|
const index = this.indexOf(key);
|
|
if (index === -1) {
|
|
return void 0;
|
|
}
|
|
let dest = index + offset;
|
|
if (dest < 0) dest = 0;
|
|
if (dest >= this.size) dest = this.size - 1;
|
|
return this.at(dest);
|
|
}
|
|
keyFrom(key, offset) {
|
|
const index = this.indexOf(key);
|
|
if (index === -1) {
|
|
return void 0;
|
|
}
|
|
let dest = index + offset;
|
|
if (dest < 0) dest = 0;
|
|
if (dest >= this.size) dest = this.size - 1;
|
|
return this.keyAt(dest);
|
|
}
|
|
find(predicate, thisArg) {
|
|
let index = 0;
|
|
for (const entry of this) {
|
|
if (Reflect.apply(predicate, thisArg, [entry, index, this])) {
|
|
return entry;
|
|
}
|
|
index++;
|
|
}
|
|
return void 0;
|
|
}
|
|
findIndex(predicate, thisArg) {
|
|
let index = 0;
|
|
for (const entry of this) {
|
|
if (Reflect.apply(predicate, thisArg, [entry, index, this])) {
|
|
return index;
|
|
}
|
|
index++;
|
|
}
|
|
return -1;
|
|
}
|
|
filter(predicate, thisArg) {
|
|
const entries = [];
|
|
let index = 0;
|
|
for (const entry of this) {
|
|
if (Reflect.apply(predicate, thisArg, [entry, index, this])) {
|
|
entries.push(entry);
|
|
}
|
|
index++;
|
|
}
|
|
return new _a(entries);
|
|
}
|
|
map(callbackfn, thisArg) {
|
|
const entries = [];
|
|
let index = 0;
|
|
for (const entry of this) {
|
|
entries.push([entry[0], Reflect.apply(callbackfn, thisArg, [entry, index, this])]);
|
|
index++;
|
|
}
|
|
return new _a(entries);
|
|
}
|
|
reduce(...args) {
|
|
const [callbackfn, initialValue] = args;
|
|
let index = 0;
|
|
let accumulator = initialValue ?? this.at(0);
|
|
for (const entry of this) {
|
|
if (index === 0 && args.length === 1) {
|
|
accumulator = entry;
|
|
} else {
|
|
accumulator = Reflect.apply(callbackfn, this, [accumulator, entry, index, this]);
|
|
}
|
|
index++;
|
|
}
|
|
return accumulator;
|
|
}
|
|
reduceRight(...args) {
|
|
const [callbackfn, initialValue] = args;
|
|
let accumulator = initialValue ?? this.at(-1);
|
|
for (let index = this.size - 1; index >= 0; index--) {
|
|
const entry = this.at(index);
|
|
if (index === this.size - 1 && args.length === 1) {
|
|
accumulator = entry;
|
|
} else {
|
|
accumulator = Reflect.apply(callbackfn, this, [accumulator, entry, index, this]);
|
|
}
|
|
}
|
|
return accumulator;
|
|
}
|
|
toSorted(compareFn) {
|
|
const entries = [...this.entries()].sort(compareFn);
|
|
return new _a(entries);
|
|
}
|
|
toReversed() {
|
|
const reversed = new _a();
|
|
for (let index = this.size - 1; index >= 0; index--) {
|
|
const key = this.keyAt(index);
|
|
const element = this.get(key);
|
|
reversed.set(key, element);
|
|
}
|
|
return reversed;
|
|
}
|
|
toSpliced(...args) {
|
|
const entries = [...this.entries()];
|
|
entries.splice(...args);
|
|
return new _a(entries);
|
|
}
|
|
slice(start, end) {
|
|
const result = new _a();
|
|
let stop = this.size - 1;
|
|
if (start === void 0) {
|
|
return result;
|
|
}
|
|
if (start < 0) {
|
|
start = start + this.size;
|
|
}
|
|
if (end !== void 0 && end > 0) {
|
|
stop = end - 1;
|
|
}
|
|
for (let index = start; index <= stop; index++) {
|
|
const key = this.keyAt(index);
|
|
const element = this.get(key);
|
|
result.set(key, element);
|
|
}
|
|
return result;
|
|
}
|
|
every(predicate, thisArg) {
|
|
let index = 0;
|
|
for (const entry of this) {
|
|
if (!Reflect.apply(predicate, thisArg, [entry, index, this])) {
|
|
return false;
|
|
}
|
|
index++;
|
|
}
|
|
return true;
|
|
}
|
|
some(predicate, thisArg) {
|
|
let index = 0;
|
|
for (const entry of this) {
|
|
if (Reflect.apply(predicate, thisArg, [entry, index, this])) {
|
|
return true;
|
|
}
|
|
index++;
|
|
}
|
|
return false;
|
|
}
|
|
}, _keys = new WeakMap(), _a);
|
|
function at(array, index) {
|
|
if ("at" in Array.prototype) {
|
|
return Array.prototype.at.call(array, index);
|
|
}
|
|
const actualIndex = toSafeIndex(array, index);
|
|
return actualIndex === -1 ? void 0 : array[actualIndex];
|
|
}
|
|
function toSafeIndex(array, index) {
|
|
const length = array.length;
|
|
const relativeIndex = toSafeInteger(index);
|
|
const actualIndex = relativeIndex >= 0 ? relativeIndex : length + relativeIndex;
|
|
return actualIndex < 0 || actualIndex >= length ? -1 : actualIndex;
|
|
}
|
|
function toSafeInteger(number) {
|
|
return number !== number || number === 0 ? 0 : Math.trunc(number);
|
|
}
|
|
function createCollection2(name) {
|
|
const PROVIDER_NAME3 = name + "CollectionProvider";
|
|
const [createCollectionContext, createCollectionScope10] = createContextScope(PROVIDER_NAME3);
|
|
const [CollectionContextProvider, useCollectionContext] = createCollectionContext(
|
|
PROVIDER_NAME3,
|
|
{
|
|
collectionElement: null,
|
|
collectionRef: { current: null },
|
|
collectionRefObject: { current: null },
|
|
itemMap: new OrderedDict(),
|
|
setItemMap: () => void 0
|
|
}
|
|
);
|
|
const CollectionProvider = ({ state, ...props }) => {
|
|
return state ? (0, import_jsx_runtime4.jsx)(CollectionProviderImpl, { ...props, state }) : (0, import_jsx_runtime4.jsx)(CollectionInit, { ...props });
|
|
};
|
|
CollectionProvider.displayName = PROVIDER_NAME3;
|
|
const CollectionInit = (props) => {
|
|
const state = useInitCollection2();
|
|
return (0, import_jsx_runtime4.jsx)(CollectionProviderImpl, { ...props, state });
|
|
};
|
|
CollectionInit.displayName = PROVIDER_NAME3 + "Init";
|
|
const CollectionProviderImpl = (props) => {
|
|
const { scope, children, state } = props;
|
|
const ref = import_react2.default.useRef(null);
|
|
const [collectionElement, setCollectionElement] = import_react2.default.useState(
|
|
null
|
|
);
|
|
const composeRefs2 = useComposedRefs(ref, setCollectionElement);
|
|
const [itemMap, setItemMap] = state;
|
|
import_react2.default.useEffect(() => {
|
|
if (!collectionElement) return;
|
|
const observer = getChildListObserver(() => {
|
|
});
|
|
observer.observe(collectionElement, {
|
|
childList: true,
|
|
subtree: true
|
|
});
|
|
return () => {
|
|
observer.disconnect();
|
|
};
|
|
}, [collectionElement]);
|
|
return (0, import_jsx_runtime4.jsx)(
|
|
CollectionContextProvider,
|
|
{
|
|
scope,
|
|
itemMap,
|
|
setItemMap,
|
|
collectionRef: composeRefs2,
|
|
collectionRefObject: ref,
|
|
collectionElement,
|
|
children
|
|
}
|
|
);
|
|
};
|
|
CollectionProviderImpl.displayName = PROVIDER_NAME3 + "Impl";
|
|
const COLLECTION_SLOT_NAME = name + "CollectionSlot";
|
|
const CollectionSlotImpl = createSlot(COLLECTION_SLOT_NAME);
|
|
const CollectionSlot = import_react2.default.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { scope, children } = props;
|
|
const context = useCollectionContext(COLLECTION_SLOT_NAME, scope);
|
|
const composedRefs = useComposedRefs(forwardedRef, context.collectionRef);
|
|
return (0, import_jsx_runtime4.jsx)(CollectionSlotImpl, { ref: composedRefs, children });
|
|
}
|
|
);
|
|
CollectionSlot.displayName = COLLECTION_SLOT_NAME;
|
|
const ITEM_SLOT_NAME = name + "CollectionItemSlot";
|
|
const ITEM_DATA_ATTR = "data-radix-collection-item";
|
|
const CollectionItemSlotImpl = createSlot(ITEM_SLOT_NAME);
|
|
const CollectionItemSlot = import_react2.default.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { scope, children, ...itemData } = props;
|
|
const ref = import_react2.default.useRef(null);
|
|
const [element, setElement] = import_react2.default.useState(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, ref, setElement);
|
|
const context = useCollectionContext(ITEM_SLOT_NAME, scope);
|
|
const { setItemMap } = context;
|
|
const itemDataRef = import_react2.default.useRef(itemData);
|
|
if (!shallowEqual(itemDataRef.current, itemData)) {
|
|
itemDataRef.current = itemData;
|
|
}
|
|
const memoizedItemData = itemDataRef.current;
|
|
import_react2.default.useEffect(() => {
|
|
const itemData2 = memoizedItemData;
|
|
setItemMap((map) => {
|
|
if (!element) {
|
|
return map;
|
|
}
|
|
if (!map.has(element)) {
|
|
map.set(element, { ...itemData2, element });
|
|
return map.toSorted(sortByDocumentPosition);
|
|
}
|
|
return map.set(element, { ...itemData2, element }).toSorted(sortByDocumentPosition);
|
|
});
|
|
return () => {
|
|
setItemMap((map) => {
|
|
if (!element || !map.has(element)) {
|
|
return map;
|
|
}
|
|
map.delete(element);
|
|
return new OrderedDict(map);
|
|
});
|
|
};
|
|
}, [element, memoizedItemData, setItemMap]);
|
|
return (0, import_jsx_runtime4.jsx)(CollectionItemSlotImpl, { ...{ [ITEM_DATA_ATTR]: "" }, ref: composedRefs, children });
|
|
}
|
|
);
|
|
CollectionItemSlot.displayName = ITEM_SLOT_NAME;
|
|
function useInitCollection2() {
|
|
return import_react2.default.useState(new OrderedDict());
|
|
}
|
|
function useCollection10(scope) {
|
|
const { itemMap } = useCollectionContext(name + "CollectionConsumer", scope);
|
|
return itemMap;
|
|
}
|
|
const functions = {
|
|
createCollectionScope: createCollectionScope10,
|
|
useCollection: useCollection10,
|
|
useInitCollection: useInitCollection2
|
|
};
|
|
return [
|
|
{ Provider: CollectionProvider, Slot: CollectionSlot, ItemSlot: CollectionItemSlot },
|
|
functions
|
|
];
|
|
}
|
|
function shallowEqual(a, b) {
|
|
if (a === b) return true;
|
|
if (typeof a !== "object" || typeof b !== "object") return false;
|
|
if (a == null || b == null) return false;
|
|
const keysA = Object.keys(a);
|
|
const keysB = Object.keys(b);
|
|
if (keysA.length !== keysB.length) return false;
|
|
for (const key of keysA) {
|
|
if (!Object.prototype.hasOwnProperty.call(b, key)) return false;
|
|
if (a[key] !== b[key]) return false;
|
|
}
|
|
return true;
|
|
}
|
|
function isElementPreceding(a, b) {
|
|
return !!(b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_PRECEDING);
|
|
}
|
|
function sortByDocumentPosition(a, b) {
|
|
return !a[1].element || !b[1].element ? 0 : isElementPreceding(a[1].element, b[1].element) ? -1 : 1;
|
|
}
|
|
function getChildListObserver(callback) {
|
|
const observer = new MutationObserver((mutationsList) => {
|
|
for (const mutation of mutationsList) {
|
|
if (mutation.type === "childList") {
|
|
callback();
|
|
return;
|
|
}
|
|
}
|
|
});
|
|
return observer;
|
|
}
|
|
|
|
// ../../node_modules/@radix-ui/react-collapsible/dist/index.mjs
|
|
var dist_exports7 = {};
|
|
__export(dist_exports7, {
|
|
Collapsible: () => Collapsible,
|
|
CollapsibleContent: () => CollapsibleContent,
|
|
CollapsibleTrigger: () => CollapsibleTrigger,
|
|
Content: () => Content3,
|
|
Root: () => Root5,
|
|
Trigger: () => Trigger2,
|
|
createCollapsibleScope: () => createCollapsibleScope
|
|
});
|
|
var React4 = __toESM(require_react(), 1);
|
|
var import_jsx_runtime5 = __toESM(require_jsx_runtime(), 1);
|
|
var COLLAPSIBLE_NAME = "Collapsible";
|
|
var [createCollapsibleContext, createCollapsibleScope] = createContextScope(COLLAPSIBLE_NAME);
|
|
var [CollapsibleProvider, useCollapsibleContext] = createCollapsibleContext(COLLAPSIBLE_NAME);
|
|
var Collapsible = React4.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const {
|
|
__scopeCollapsible,
|
|
open: openProp,
|
|
defaultOpen,
|
|
disabled,
|
|
onOpenChange,
|
|
...collapsibleProps
|
|
} = props;
|
|
const [open, setOpen] = useControllableState({
|
|
prop: openProp,
|
|
defaultProp: defaultOpen ?? false,
|
|
onChange: onOpenChange,
|
|
caller: COLLAPSIBLE_NAME
|
|
});
|
|
return (0, import_jsx_runtime5.jsx)(
|
|
CollapsibleProvider,
|
|
{
|
|
scope: __scopeCollapsible,
|
|
disabled,
|
|
contentId: useId(),
|
|
open,
|
|
onOpenToggle: React4.useCallback(() => setOpen((prevOpen) => !prevOpen), [setOpen]),
|
|
children: (0, import_jsx_runtime5.jsx)(
|
|
Primitive.div,
|
|
{
|
|
"data-state": getState(open),
|
|
"data-disabled": disabled ? "" : void 0,
|
|
...collapsibleProps,
|
|
ref: forwardedRef
|
|
}
|
|
)
|
|
}
|
|
);
|
|
}
|
|
);
|
|
Collapsible.displayName = COLLAPSIBLE_NAME;
|
|
var TRIGGER_NAME = "CollapsibleTrigger";
|
|
var CollapsibleTrigger = React4.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeCollapsible, ...triggerProps } = props;
|
|
const context = useCollapsibleContext(TRIGGER_NAME, __scopeCollapsible);
|
|
return (0, import_jsx_runtime5.jsx)(
|
|
Primitive.button,
|
|
{
|
|
type: "button",
|
|
"aria-controls": context.contentId,
|
|
"aria-expanded": context.open || false,
|
|
"data-state": getState(context.open),
|
|
"data-disabled": context.disabled ? "" : void 0,
|
|
disabled: context.disabled,
|
|
...triggerProps,
|
|
ref: forwardedRef,
|
|
onClick: composeEventHandlers(props.onClick, context.onOpenToggle)
|
|
}
|
|
);
|
|
}
|
|
);
|
|
CollapsibleTrigger.displayName = TRIGGER_NAME;
|
|
var CONTENT_NAME = "CollapsibleContent";
|
|
var CollapsibleContent = React4.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { forceMount, ...contentProps } = props;
|
|
const context = useCollapsibleContext(CONTENT_NAME, props.__scopeCollapsible);
|
|
return (0, import_jsx_runtime5.jsx)(Presence, { present: forceMount || context.open, children: ({ present }) => (0, import_jsx_runtime5.jsx)(CollapsibleContentImpl, { ...contentProps, ref: forwardedRef, present }) });
|
|
}
|
|
);
|
|
CollapsibleContent.displayName = CONTENT_NAME;
|
|
var CollapsibleContentImpl = React4.forwardRef((props, forwardedRef) => {
|
|
const { __scopeCollapsible, present, children, ...contentProps } = props;
|
|
const context = useCollapsibleContext(CONTENT_NAME, __scopeCollapsible);
|
|
const [isPresent, setIsPresent] = React4.useState(present);
|
|
const ref = React4.useRef(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, ref);
|
|
const heightRef = React4.useRef(0);
|
|
const height = heightRef.current;
|
|
const widthRef = React4.useRef(0);
|
|
const width = widthRef.current;
|
|
const isOpen = context.open || isPresent;
|
|
const isMountAnimationPreventedRef = React4.useRef(isOpen);
|
|
const originalStylesRef = React4.useRef(void 0);
|
|
React4.useEffect(() => {
|
|
const rAF = requestAnimationFrame(() => isMountAnimationPreventedRef.current = false);
|
|
return () => cancelAnimationFrame(rAF);
|
|
}, []);
|
|
useLayoutEffect2(() => {
|
|
const node = ref.current;
|
|
if (node) {
|
|
originalStylesRef.current = originalStylesRef.current || {
|
|
transitionDuration: node.style.transitionDuration,
|
|
animationName: node.style.animationName
|
|
};
|
|
node.style.transitionDuration = "0s";
|
|
node.style.animationName = "none";
|
|
const rect = node.getBoundingClientRect();
|
|
heightRef.current = rect.height;
|
|
widthRef.current = rect.width;
|
|
if (!isMountAnimationPreventedRef.current) {
|
|
node.style.transitionDuration = originalStylesRef.current.transitionDuration;
|
|
node.style.animationName = originalStylesRef.current.animationName;
|
|
}
|
|
setIsPresent(present);
|
|
}
|
|
}, [context.open, present]);
|
|
return (0, import_jsx_runtime5.jsx)(
|
|
Primitive.div,
|
|
{
|
|
"data-state": getState(context.open),
|
|
"data-disabled": context.disabled ? "" : void 0,
|
|
id: context.contentId,
|
|
hidden: !isOpen,
|
|
...contentProps,
|
|
ref: composedRefs,
|
|
style: {
|
|
[`--radix-collapsible-content-height`]: height ? `${height}px` : void 0,
|
|
[`--radix-collapsible-content-width`]: width ? `${width}px` : void 0,
|
|
...props.style
|
|
},
|
|
children: isOpen && children
|
|
}
|
|
);
|
|
});
|
|
function getState(open) {
|
|
return open ? "open" : "closed";
|
|
}
|
|
var Root5 = Collapsible;
|
|
var Trigger2 = CollapsibleTrigger;
|
|
var Content3 = CollapsibleContent;
|
|
|
|
// ../../node_modules/@radix-ui/react-direction/dist/index.mjs
|
|
var dist_exports8 = {};
|
|
__export(dist_exports8, {
|
|
DirectionProvider: () => DirectionProvider,
|
|
Provider: () => Provider,
|
|
useDirection: () => useDirection
|
|
});
|
|
var React5 = __toESM(require_react(), 1);
|
|
var import_jsx_runtime6 = __toESM(require_jsx_runtime(), 1);
|
|
var DirectionContext = React5.createContext(void 0);
|
|
var DirectionProvider = (props) => {
|
|
const { dir, children } = props;
|
|
return (0, import_jsx_runtime6.jsx)(DirectionContext.Provider, { value: dir, children });
|
|
};
|
|
function useDirection(localDir) {
|
|
const globalDir = React5.useContext(DirectionContext);
|
|
return localDir || globalDir || "ltr";
|
|
}
|
|
var Provider = DirectionProvider;
|
|
|
|
// ../../node_modules/@radix-ui/react-accordion/dist/index.mjs
|
|
var import_jsx_runtime7 = __toESM(require_jsx_runtime(), 1);
|
|
var ACCORDION_NAME = "Accordion";
|
|
var ACCORDION_KEYS = ["Home", "End", "ArrowDown", "ArrowUp", "ArrowLeft", "ArrowRight"];
|
|
var [Collection, useCollection, createCollectionScope] = createCollection(ACCORDION_NAME);
|
|
var [createAccordionContext, createAccordionScope] = createContextScope(ACCORDION_NAME, [
|
|
createCollectionScope,
|
|
createCollapsibleScope
|
|
]);
|
|
var useCollapsibleScope = createCollapsibleScope();
|
|
var Accordion = import_react3.default.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { type, ...accordionProps } = props;
|
|
const singleProps = accordionProps;
|
|
const multipleProps = accordionProps;
|
|
return (0, import_jsx_runtime7.jsx)(Collection.Provider, { scope: props.__scopeAccordion, children: type === "multiple" ? (0, import_jsx_runtime7.jsx)(AccordionImplMultiple, { ...multipleProps, ref: forwardedRef }) : (0, import_jsx_runtime7.jsx)(AccordionImplSingle, { ...singleProps, ref: forwardedRef }) });
|
|
}
|
|
);
|
|
Accordion.displayName = ACCORDION_NAME;
|
|
var [AccordionValueProvider, useAccordionValueContext] = createAccordionContext(ACCORDION_NAME);
|
|
var [AccordionCollapsibleProvider, useAccordionCollapsibleContext] = createAccordionContext(
|
|
ACCORDION_NAME,
|
|
{ collapsible: false }
|
|
);
|
|
var AccordionImplSingle = import_react3.default.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const {
|
|
value: valueProp,
|
|
defaultValue,
|
|
onValueChange = () => {
|
|
},
|
|
collapsible = false,
|
|
...accordionSingleProps
|
|
} = props;
|
|
const [value, setValue] = useControllableState({
|
|
prop: valueProp,
|
|
defaultProp: defaultValue ?? "",
|
|
onChange: onValueChange,
|
|
caller: ACCORDION_NAME
|
|
});
|
|
return (0, import_jsx_runtime7.jsx)(
|
|
AccordionValueProvider,
|
|
{
|
|
scope: props.__scopeAccordion,
|
|
value: import_react3.default.useMemo(() => value ? [value] : [], [value]),
|
|
onItemOpen: setValue,
|
|
onItemClose: import_react3.default.useCallback(() => collapsible && setValue(""), [collapsible, setValue]),
|
|
children: (0, import_jsx_runtime7.jsx)(AccordionCollapsibleProvider, { scope: props.__scopeAccordion, collapsible, children: (0, import_jsx_runtime7.jsx)(AccordionImpl, { ...accordionSingleProps, ref: forwardedRef }) })
|
|
}
|
|
);
|
|
}
|
|
);
|
|
var AccordionImplMultiple = import_react3.default.forwardRef((props, forwardedRef) => {
|
|
const {
|
|
value: valueProp,
|
|
defaultValue,
|
|
onValueChange = () => {
|
|
},
|
|
...accordionMultipleProps
|
|
} = props;
|
|
const [value, setValue] = useControllableState({
|
|
prop: valueProp,
|
|
defaultProp: defaultValue ?? [],
|
|
onChange: onValueChange,
|
|
caller: ACCORDION_NAME
|
|
});
|
|
const handleItemOpen = import_react3.default.useCallback(
|
|
(itemValue) => setValue((prevValue = []) => [...prevValue, itemValue]),
|
|
[setValue]
|
|
);
|
|
const handleItemClose = import_react3.default.useCallback(
|
|
(itemValue) => setValue((prevValue = []) => prevValue.filter((value2) => value2 !== itemValue)),
|
|
[setValue]
|
|
);
|
|
return (0, import_jsx_runtime7.jsx)(
|
|
AccordionValueProvider,
|
|
{
|
|
scope: props.__scopeAccordion,
|
|
value,
|
|
onItemOpen: handleItemOpen,
|
|
onItemClose: handleItemClose,
|
|
children: (0, import_jsx_runtime7.jsx)(AccordionCollapsibleProvider, { scope: props.__scopeAccordion, collapsible: true, children: (0, import_jsx_runtime7.jsx)(AccordionImpl, { ...accordionMultipleProps, ref: forwardedRef }) })
|
|
}
|
|
);
|
|
});
|
|
var [AccordionImplProvider, useAccordionContext] = createAccordionContext(ACCORDION_NAME);
|
|
var AccordionImpl = import_react3.default.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeAccordion, disabled, dir, orientation = "vertical", ...accordionProps } = props;
|
|
const accordionRef = import_react3.default.useRef(null);
|
|
const composedRefs = useComposedRefs(accordionRef, forwardedRef);
|
|
const getItems = useCollection(__scopeAccordion);
|
|
const direction = useDirection(dir);
|
|
const isDirectionLTR = direction === "ltr";
|
|
const handleKeyDown = composeEventHandlers(props.onKeyDown, (event) => {
|
|
var _a2;
|
|
if (!ACCORDION_KEYS.includes(event.key)) return;
|
|
const target = event.target;
|
|
const triggerCollection = getItems().filter((item) => {
|
|
var _a3;
|
|
return !((_a3 = item.ref.current) == null ? void 0 : _a3.disabled);
|
|
});
|
|
const triggerIndex = triggerCollection.findIndex((item) => item.ref.current === target);
|
|
const triggerCount = triggerCollection.length;
|
|
if (triggerIndex === -1) return;
|
|
event.preventDefault();
|
|
let nextIndex = triggerIndex;
|
|
const homeIndex = 0;
|
|
const endIndex = triggerCount - 1;
|
|
const moveNext = () => {
|
|
nextIndex = triggerIndex + 1;
|
|
if (nextIndex > endIndex) {
|
|
nextIndex = homeIndex;
|
|
}
|
|
};
|
|
const movePrev = () => {
|
|
nextIndex = triggerIndex - 1;
|
|
if (nextIndex < homeIndex) {
|
|
nextIndex = endIndex;
|
|
}
|
|
};
|
|
switch (event.key) {
|
|
case "Home":
|
|
nextIndex = homeIndex;
|
|
break;
|
|
case "End":
|
|
nextIndex = endIndex;
|
|
break;
|
|
case "ArrowRight":
|
|
if (orientation === "horizontal") {
|
|
if (isDirectionLTR) {
|
|
moveNext();
|
|
} else {
|
|
movePrev();
|
|
}
|
|
}
|
|
break;
|
|
case "ArrowDown":
|
|
if (orientation === "vertical") {
|
|
moveNext();
|
|
}
|
|
break;
|
|
case "ArrowLeft":
|
|
if (orientation === "horizontal") {
|
|
if (isDirectionLTR) {
|
|
movePrev();
|
|
} else {
|
|
moveNext();
|
|
}
|
|
}
|
|
break;
|
|
case "ArrowUp":
|
|
if (orientation === "vertical") {
|
|
movePrev();
|
|
}
|
|
break;
|
|
}
|
|
const clampedIndex = nextIndex % triggerCount;
|
|
(_a2 = triggerCollection[clampedIndex].ref.current) == null ? void 0 : _a2.focus();
|
|
});
|
|
return (0, import_jsx_runtime7.jsx)(
|
|
AccordionImplProvider,
|
|
{
|
|
scope: __scopeAccordion,
|
|
disabled,
|
|
direction: dir,
|
|
orientation,
|
|
children: (0, import_jsx_runtime7.jsx)(Collection.Slot, { scope: __scopeAccordion, children: (0, import_jsx_runtime7.jsx)(
|
|
Primitive.div,
|
|
{
|
|
...accordionProps,
|
|
"data-orientation": orientation,
|
|
ref: composedRefs,
|
|
onKeyDown: disabled ? void 0 : handleKeyDown
|
|
}
|
|
) })
|
|
}
|
|
);
|
|
}
|
|
);
|
|
var ITEM_NAME = "AccordionItem";
|
|
var [AccordionItemProvider, useAccordionItemContext] = createAccordionContext(ITEM_NAME);
|
|
var AccordionItem = import_react3.default.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeAccordion, value, ...accordionItemProps } = props;
|
|
const accordionContext = useAccordionContext(ITEM_NAME, __scopeAccordion);
|
|
const valueContext = useAccordionValueContext(ITEM_NAME, __scopeAccordion);
|
|
const collapsibleScope = useCollapsibleScope(__scopeAccordion);
|
|
const triggerId = useId();
|
|
const open = value && valueContext.value.includes(value) || false;
|
|
const disabled = accordionContext.disabled || props.disabled;
|
|
return (0, import_jsx_runtime7.jsx)(
|
|
AccordionItemProvider,
|
|
{
|
|
scope: __scopeAccordion,
|
|
open,
|
|
disabled,
|
|
triggerId,
|
|
children: (0, import_jsx_runtime7.jsx)(
|
|
Root5,
|
|
{
|
|
"data-orientation": accordionContext.orientation,
|
|
"data-state": getState2(open),
|
|
...collapsibleScope,
|
|
...accordionItemProps,
|
|
ref: forwardedRef,
|
|
disabled,
|
|
open,
|
|
onOpenChange: (open2) => {
|
|
if (open2) {
|
|
valueContext.onItemOpen(value);
|
|
} else {
|
|
valueContext.onItemClose(value);
|
|
}
|
|
}
|
|
}
|
|
)
|
|
}
|
|
);
|
|
}
|
|
);
|
|
AccordionItem.displayName = ITEM_NAME;
|
|
var HEADER_NAME = "AccordionHeader";
|
|
var AccordionHeader = import_react3.default.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeAccordion, ...headerProps } = props;
|
|
const accordionContext = useAccordionContext(ACCORDION_NAME, __scopeAccordion);
|
|
const itemContext = useAccordionItemContext(HEADER_NAME, __scopeAccordion);
|
|
return (0, import_jsx_runtime7.jsx)(
|
|
Primitive.h3,
|
|
{
|
|
"data-orientation": accordionContext.orientation,
|
|
"data-state": getState2(itemContext.open),
|
|
"data-disabled": itemContext.disabled ? "" : void 0,
|
|
...headerProps,
|
|
ref: forwardedRef
|
|
}
|
|
);
|
|
}
|
|
);
|
|
AccordionHeader.displayName = HEADER_NAME;
|
|
var TRIGGER_NAME2 = "AccordionTrigger";
|
|
var AccordionTrigger = import_react3.default.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeAccordion, ...triggerProps } = props;
|
|
const accordionContext = useAccordionContext(ACCORDION_NAME, __scopeAccordion);
|
|
const itemContext = useAccordionItemContext(TRIGGER_NAME2, __scopeAccordion);
|
|
const collapsibleContext = useAccordionCollapsibleContext(TRIGGER_NAME2, __scopeAccordion);
|
|
const collapsibleScope = useCollapsibleScope(__scopeAccordion);
|
|
return (0, import_jsx_runtime7.jsx)(Collection.ItemSlot, { scope: __scopeAccordion, children: (0, import_jsx_runtime7.jsx)(
|
|
Trigger2,
|
|
{
|
|
"aria-disabled": itemContext.open && !collapsibleContext.collapsible || void 0,
|
|
"data-orientation": accordionContext.orientation,
|
|
id: itemContext.triggerId,
|
|
...collapsibleScope,
|
|
...triggerProps,
|
|
ref: forwardedRef
|
|
}
|
|
) });
|
|
}
|
|
);
|
|
AccordionTrigger.displayName = TRIGGER_NAME2;
|
|
var CONTENT_NAME2 = "AccordionContent";
|
|
var AccordionContent = import_react3.default.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeAccordion, ...contentProps } = props;
|
|
const accordionContext = useAccordionContext(ACCORDION_NAME, __scopeAccordion);
|
|
const itemContext = useAccordionItemContext(CONTENT_NAME2, __scopeAccordion);
|
|
const collapsibleScope = useCollapsibleScope(__scopeAccordion);
|
|
return (0, import_jsx_runtime7.jsx)(
|
|
Content3,
|
|
{
|
|
role: "region",
|
|
"aria-labelledby": itemContext.triggerId,
|
|
"data-orientation": accordionContext.orientation,
|
|
...collapsibleScope,
|
|
...contentProps,
|
|
ref: forwardedRef,
|
|
style: {
|
|
["--radix-accordion-content-height"]: "var(--radix-collapsible-content-height)",
|
|
["--radix-accordion-content-width"]: "var(--radix-collapsible-content-width)",
|
|
...props.style
|
|
}
|
|
}
|
|
);
|
|
}
|
|
);
|
|
AccordionContent.displayName = CONTENT_NAME2;
|
|
function getState2(open) {
|
|
return open ? "open" : "closed";
|
|
}
|
|
var Root24 = Accordion;
|
|
var Item = AccordionItem;
|
|
var Header = AccordionHeader;
|
|
var Trigger22 = AccordionTrigger;
|
|
var Content22 = AccordionContent;
|
|
|
|
// ../../node_modules/@radix-ui/react-alert-dialog/dist/index.mjs
|
|
var dist_exports10 = {};
|
|
__export(dist_exports10, {
|
|
Action: () => Action,
|
|
AlertDialog: () => AlertDialog,
|
|
AlertDialogAction: () => AlertDialogAction,
|
|
AlertDialogCancel: () => AlertDialogCancel,
|
|
AlertDialogContent: () => AlertDialogContent,
|
|
AlertDialogDescription: () => AlertDialogDescription,
|
|
AlertDialogOverlay: () => AlertDialogOverlay,
|
|
AlertDialogPortal: () => AlertDialogPortal,
|
|
AlertDialogTitle: () => AlertDialogTitle,
|
|
AlertDialogTrigger: () => AlertDialogTrigger,
|
|
Cancel: () => Cancel,
|
|
Content: () => Content23,
|
|
Description: () => Description2,
|
|
Overlay: () => Overlay2,
|
|
Portal: () => Portal22,
|
|
Root: () => Root25,
|
|
Title: () => Title2,
|
|
Trigger: () => Trigger23,
|
|
createAlertDialogScope: () => createAlertDialogScope
|
|
});
|
|
var React7 = __toESM(require_react(), 1);
|
|
var import_jsx_runtime8 = __toESM(require_jsx_runtime(), 1);
|
|
var ROOT_NAME = "AlertDialog";
|
|
var [createAlertDialogContext, createAlertDialogScope] = createContextScope(ROOT_NAME, [
|
|
createDialogScope
|
|
]);
|
|
var useDialogScope = createDialogScope();
|
|
var AlertDialog = (props) => {
|
|
const { __scopeAlertDialog, ...alertDialogProps } = props;
|
|
const dialogScope = useDialogScope(__scopeAlertDialog);
|
|
return (0, import_jsx_runtime8.jsx)(Root3, { ...dialogScope, ...alertDialogProps, modal: true });
|
|
};
|
|
AlertDialog.displayName = ROOT_NAME;
|
|
var TRIGGER_NAME3 = "AlertDialogTrigger";
|
|
var AlertDialogTrigger = React7.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeAlertDialog, ...triggerProps } = props;
|
|
const dialogScope = useDialogScope(__scopeAlertDialog);
|
|
return (0, import_jsx_runtime8.jsx)(Trigger, { ...dialogScope, ...triggerProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
AlertDialogTrigger.displayName = TRIGGER_NAME3;
|
|
var PORTAL_NAME = "AlertDialogPortal";
|
|
var AlertDialogPortal = (props) => {
|
|
const { __scopeAlertDialog, ...portalProps } = props;
|
|
const dialogScope = useDialogScope(__scopeAlertDialog);
|
|
return (0, import_jsx_runtime8.jsx)(Portal2, { ...dialogScope, ...portalProps });
|
|
};
|
|
AlertDialogPortal.displayName = PORTAL_NAME;
|
|
var OVERLAY_NAME = "AlertDialogOverlay";
|
|
var AlertDialogOverlay = React7.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeAlertDialog, ...overlayProps } = props;
|
|
const dialogScope = useDialogScope(__scopeAlertDialog);
|
|
return (0, import_jsx_runtime8.jsx)(Overlay, { ...dialogScope, ...overlayProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
AlertDialogOverlay.displayName = OVERLAY_NAME;
|
|
var CONTENT_NAME3 = "AlertDialogContent";
|
|
var [AlertDialogContentProvider, useAlertDialogContentContext] = createAlertDialogContext(CONTENT_NAME3);
|
|
var Slottable = createSlottable("AlertDialogContent");
|
|
var AlertDialogContent = React7.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeAlertDialog, children, ...contentProps } = props;
|
|
const dialogScope = useDialogScope(__scopeAlertDialog);
|
|
const contentRef = React7.useRef(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, contentRef);
|
|
const cancelRef = React7.useRef(null);
|
|
return (0, import_jsx_runtime8.jsx)(
|
|
WarningProvider,
|
|
{
|
|
contentName: CONTENT_NAME3,
|
|
titleName: TITLE_NAME,
|
|
docsSlug: "alert-dialog",
|
|
children: (0, import_jsx_runtime8.jsx)(AlertDialogContentProvider, { scope: __scopeAlertDialog, cancelRef, children: (0, import_jsx_runtime8.jsxs)(
|
|
Content2,
|
|
{
|
|
role: "alertdialog",
|
|
...dialogScope,
|
|
...contentProps,
|
|
ref: composedRefs,
|
|
onOpenAutoFocus: composeEventHandlers(contentProps.onOpenAutoFocus, (event) => {
|
|
var _a2;
|
|
event.preventDefault();
|
|
(_a2 = cancelRef.current) == null ? void 0 : _a2.focus({ preventScroll: true });
|
|
}),
|
|
onPointerDownOutside: (event) => event.preventDefault(),
|
|
onInteractOutside: (event) => event.preventDefault(),
|
|
children: [
|
|
(0, import_jsx_runtime8.jsx)(Slottable, { children }),
|
|
(0, import_jsx_runtime8.jsx)(DescriptionWarning, { contentRef })
|
|
]
|
|
}
|
|
) })
|
|
}
|
|
);
|
|
}
|
|
);
|
|
AlertDialogContent.displayName = CONTENT_NAME3;
|
|
var TITLE_NAME = "AlertDialogTitle";
|
|
var AlertDialogTitle = React7.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeAlertDialog, ...titleProps } = props;
|
|
const dialogScope = useDialogScope(__scopeAlertDialog);
|
|
return (0, import_jsx_runtime8.jsx)(Title, { ...dialogScope, ...titleProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
AlertDialogTitle.displayName = TITLE_NAME;
|
|
var DESCRIPTION_NAME = "AlertDialogDescription";
|
|
var AlertDialogDescription = React7.forwardRef((props, forwardedRef) => {
|
|
const { __scopeAlertDialog, ...descriptionProps } = props;
|
|
const dialogScope = useDialogScope(__scopeAlertDialog);
|
|
return (0, import_jsx_runtime8.jsx)(Description, { ...dialogScope, ...descriptionProps, ref: forwardedRef });
|
|
});
|
|
AlertDialogDescription.displayName = DESCRIPTION_NAME;
|
|
var ACTION_NAME = "AlertDialogAction";
|
|
var AlertDialogAction = React7.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeAlertDialog, ...actionProps } = props;
|
|
const dialogScope = useDialogScope(__scopeAlertDialog);
|
|
return (0, import_jsx_runtime8.jsx)(Close, { ...dialogScope, ...actionProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
AlertDialogAction.displayName = ACTION_NAME;
|
|
var CANCEL_NAME = "AlertDialogCancel";
|
|
var AlertDialogCancel = React7.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeAlertDialog, ...cancelProps } = props;
|
|
const { cancelRef } = useAlertDialogContentContext(CANCEL_NAME, __scopeAlertDialog);
|
|
const dialogScope = useDialogScope(__scopeAlertDialog);
|
|
const ref = useComposedRefs(forwardedRef, cancelRef);
|
|
return (0, import_jsx_runtime8.jsx)(Close, { ...dialogScope, ...cancelProps, ref });
|
|
}
|
|
);
|
|
AlertDialogCancel.displayName = CANCEL_NAME;
|
|
var DescriptionWarning = ({ contentRef }) => {
|
|
const MESSAGE = `\`${CONTENT_NAME3}\` requires a description for the component to be accessible for screen reader users.
|
|
|
|
You can add a description to the \`${CONTENT_NAME3}\` by passing a \`${DESCRIPTION_NAME}\` component as a child, which also benefits sighted users by adding visible context to the dialog.
|
|
|
|
Alternatively, you can use your own component as a description by assigning it an \`id\` and passing the same value to the \`aria-describedby\` prop in \`${CONTENT_NAME3}\`. If the description is confusing or duplicative for sighted users, you can use the \`@radix-ui/react-visually-hidden\` primitive as a wrapper around your description component.
|
|
|
|
For more information, see https://radix-ui.com/primitives/docs/components/alert-dialog`;
|
|
React7.useEffect(() => {
|
|
var _a2;
|
|
const hasDescription = document.getElementById(
|
|
(_a2 = contentRef.current) == null ? void 0 : _a2.getAttribute("aria-describedby")
|
|
);
|
|
if (!hasDescription) console.warn(MESSAGE);
|
|
}, [MESSAGE, contentRef]);
|
|
return null;
|
|
};
|
|
var Root25 = AlertDialog;
|
|
var Trigger23 = AlertDialogTrigger;
|
|
var Portal22 = AlertDialogPortal;
|
|
var Overlay2 = AlertDialogOverlay;
|
|
var Content23 = AlertDialogContent;
|
|
var Action = AlertDialogAction;
|
|
var Cancel = AlertDialogCancel;
|
|
var Title2 = AlertDialogTitle;
|
|
var Description2 = AlertDialogDescription;
|
|
|
|
// ../../node_modules/@radix-ui/react-aspect-ratio/dist/index.mjs
|
|
var dist_exports11 = {};
|
|
__export(dist_exports11, {
|
|
AspectRatio: () => AspectRatio,
|
|
Root: () => Root6
|
|
});
|
|
var React8 = __toESM(require_react(), 1);
|
|
var import_jsx_runtime9 = __toESM(require_jsx_runtime(), 1);
|
|
var NAME3 = "AspectRatio";
|
|
var AspectRatio = React8.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { ratio = 1 / 1, style, ...aspectRatioProps } = props;
|
|
return (0, import_jsx_runtime9.jsx)(
|
|
"div",
|
|
{
|
|
style: {
|
|
// ensures inner element is contained
|
|
position: "relative",
|
|
// ensures padding bottom trick maths works
|
|
width: "100%",
|
|
paddingBottom: `${100 / ratio}%`
|
|
},
|
|
"data-radix-aspect-ratio-wrapper": "",
|
|
children: (0, import_jsx_runtime9.jsx)(
|
|
Primitive.div,
|
|
{
|
|
...aspectRatioProps,
|
|
ref: forwardedRef,
|
|
style: {
|
|
...style,
|
|
// ensures children expand in ratio
|
|
position: "absolute",
|
|
top: 0,
|
|
right: 0,
|
|
bottom: 0,
|
|
left: 0
|
|
}
|
|
}
|
|
)
|
|
}
|
|
);
|
|
}
|
|
);
|
|
AspectRatio.displayName = NAME3;
|
|
var Root6 = AspectRatio;
|
|
|
|
// ../../node_modules/@radix-ui/react-avatar/dist/index.mjs
|
|
var dist_exports12 = {};
|
|
__export(dist_exports12, {
|
|
Avatar: () => Avatar,
|
|
AvatarFallback: () => AvatarFallback,
|
|
AvatarImage: () => AvatarImage,
|
|
Fallback: () => Fallback,
|
|
Image: () => Image,
|
|
Root: () => Root7,
|
|
createAvatarScope: () => createAvatarScope
|
|
});
|
|
var React9 = __toESM(require_react(), 1);
|
|
|
|
// ../../node_modules/@radix-ui/react-use-is-hydrated/dist/index.mjs
|
|
var import_shim = __toESM(require_shim(), 1);
|
|
function useIsHydrated() {
|
|
return (0, import_shim.useSyncExternalStore)(
|
|
subscribe,
|
|
() => true,
|
|
() => false
|
|
);
|
|
}
|
|
function subscribe() {
|
|
return () => {
|
|
};
|
|
}
|
|
|
|
// ../../node_modules/@radix-ui/react-avatar/dist/index.mjs
|
|
var import_jsx_runtime10 = __toESM(require_jsx_runtime(), 1);
|
|
var AVATAR_NAME = "Avatar";
|
|
var [createAvatarContext, createAvatarScope] = createContextScope(AVATAR_NAME);
|
|
var [AvatarProvider, useAvatarContext] = createAvatarContext(AVATAR_NAME);
|
|
var Avatar = React9.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeAvatar, ...avatarProps } = props;
|
|
const [imageLoadingStatus, setImageLoadingStatus] = React9.useState("idle");
|
|
return (0, import_jsx_runtime10.jsx)(
|
|
AvatarProvider,
|
|
{
|
|
scope: __scopeAvatar,
|
|
imageLoadingStatus,
|
|
onImageLoadingStatusChange: setImageLoadingStatus,
|
|
children: (0, import_jsx_runtime10.jsx)(Primitive.span, { ...avatarProps, ref: forwardedRef })
|
|
}
|
|
);
|
|
}
|
|
);
|
|
Avatar.displayName = AVATAR_NAME;
|
|
var IMAGE_NAME = "AvatarImage";
|
|
var AvatarImage = React9.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeAvatar, src, onLoadingStatusChange = () => {
|
|
}, ...imageProps } = props;
|
|
const context = useAvatarContext(IMAGE_NAME, __scopeAvatar);
|
|
const imageLoadingStatus = useImageLoadingStatus(src, imageProps);
|
|
const handleLoadingStatusChange = useCallbackRef((status) => {
|
|
onLoadingStatusChange(status);
|
|
context.onImageLoadingStatusChange(status);
|
|
});
|
|
useLayoutEffect2(() => {
|
|
if (imageLoadingStatus !== "idle") {
|
|
handleLoadingStatusChange(imageLoadingStatus);
|
|
}
|
|
}, [imageLoadingStatus, handleLoadingStatusChange]);
|
|
return imageLoadingStatus === "loaded" ? (0, import_jsx_runtime10.jsx)(Primitive.img, { ...imageProps, ref: forwardedRef, src }) : null;
|
|
}
|
|
);
|
|
AvatarImage.displayName = IMAGE_NAME;
|
|
var FALLBACK_NAME = "AvatarFallback";
|
|
var AvatarFallback = React9.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeAvatar, delayMs, ...fallbackProps } = props;
|
|
const context = useAvatarContext(FALLBACK_NAME, __scopeAvatar);
|
|
const [canRender, setCanRender] = React9.useState(delayMs === void 0);
|
|
React9.useEffect(() => {
|
|
if (delayMs !== void 0) {
|
|
const timerId = window.setTimeout(() => setCanRender(true), delayMs);
|
|
return () => window.clearTimeout(timerId);
|
|
}
|
|
}, [delayMs]);
|
|
return canRender && context.imageLoadingStatus !== "loaded" ? (0, import_jsx_runtime10.jsx)(Primitive.span, { ...fallbackProps, ref: forwardedRef }) : null;
|
|
}
|
|
);
|
|
AvatarFallback.displayName = FALLBACK_NAME;
|
|
function resolveLoadingStatus(image, src) {
|
|
if (!image) {
|
|
return "idle";
|
|
}
|
|
if (!src) {
|
|
return "error";
|
|
}
|
|
if (image.src !== src) {
|
|
image.src = src;
|
|
}
|
|
return image.complete && image.naturalWidth > 0 ? "loaded" : "loading";
|
|
}
|
|
function useImageLoadingStatus(src, { referrerPolicy, crossOrigin }) {
|
|
const isHydrated = useIsHydrated();
|
|
const imageRef = React9.useRef(null);
|
|
const image = (() => {
|
|
if (!isHydrated) return null;
|
|
if (!imageRef.current) {
|
|
imageRef.current = new window.Image();
|
|
}
|
|
return imageRef.current;
|
|
})();
|
|
const [loadingStatus, setLoadingStatus] = React9.useState(
|
|
() => resolveLoadingStatus(image, src)
|
|
);
|
|
useLayoutEffect2(() => {
|
|
setLoadingStatus(resolveLoadingStatus(image, src));
|
|
}, [image, src]);
|
|
useLayoutEffect2(() => {
|
|
const updateStatus = (status) => () => {
|
|
setLoadingStatus(status);
|
|
};
|
|
if (!image) return;
|
|
const handleLoad = updateStatus("loaded");
|
|
const handleError = updateStatus("error");
|
|
image.addEventListener("load", handleLoad);
|
|
image.addEventListener("error", handleError);
|
|
if (referrerPolicy) {
|
|
image.referrerPolicy = referrerPolicy;
|
|
}
|
|
if (typeof crossOrigin === "string") {
|
|
image.crossOrigin = crossOrigin;
|
|
}
|
|
return () => {
|
|
image.removeEventListener("load", handleLoad);
|
|
image.removeEventListener("error", handleError);
|
|
};
|
|
}, [image, crossOrigin, referrerPolicy]);
|
|
return loadingStatus;
|
|
}
|
|
var Root7 = Avatar;
|
|
var Image = AvatarImage;
|
|
var Fallback = AvatarFallback;
|
|
|
|
// ../../node_modules/@radix-ui/react-checkbox/dist/index.mjs
|
|
var dist_exports13 = {};
|
|
__export(dist_exports13, {
|
|
Checkbox: () => Checkbox,
|
|
CheckboxIndicator: () => CheckboxIndicator,
|
|
Indicator: () => CheckboxIndicator,
|
|
Root: () => Checkbox,
|
|
createCheckboxScope: () => createCheckboxScope,
|
|
unstable_BubbleInput: () => CheckboxBubbleInput,
|
|
unstable_CheckboxBubbleInput: () => CheckboxBubbleInput,
|
|
unstable_CheckboxProvider: () => CheckboxProvider,
|
|
unstable_CheckboxTrigger: () => CheckboxTrigger,
|
|
unstable_Provider: () => CheckboxProvider,
|
|
unstable_Trigger: () => CheckboxTrigger
|
|
});
|
|
var React11 = __toESM(require_react(), 1);
|
|
|
|
// ../../node_modules/@radix-ui/react-use-previous/dist/index.mjs
|
|
var React10 = __toESM(require_react(), 1);
|
|
function usePrevious(value) {
|
|
const ref = React10.useRef({ value, previous: value });
|
|
return React10.useMemo(() => {
|
|
if (ref.current.value !== value) {
|
|
ref.current.previous = ref.current.value;
|
|
ref.current.value = value;
|
|
}
|
|
return ref.current.previous;
|
|
}, [value]);
|
|
}
|
|
|
|
// ../../node_modules/@radix-ui/react-checkbox/dist/index.mjs
|
|
var import_jsx_runtime11 = __toESM(require_jsx_runtime(), 1);
|
|
var CHECKBOX_NAME = "Checkbox";
|
|
var [createCheckboxContext, createCheckboxScope] = createContextScope(CHECKBOX_NAME);
|
|
var [CheckboxProviderImpl, useCheckboxContext] = createCheckboxContext(CHECKBOX_NAME);
|
|
function CheckboxProvider(props) {
|
|
const {
|
|
__scopeCheckbox,
|
|
checked: checkedProp,
|
|
children,
|
|
defaultChecked,
|
|
disabled,
|
|
form,
|
|
name,
|
|
onCheckedChange,
|
|
required,
|
|
value = "on",
|
|
// @ts-expect-error
|
|
internal_do_not_use_render
|
|
} = props;
|
|
const [checked, setChecked] = useControllableState({
|
|
prop: checkedProp,
|
|
defaultProp: defaultChecked ?? false,
|
|
onChange: onCheckedChange,
|
|
caller: CHECKBOX_NAME
|
|
});
|
|
const [control, setControl] = React11.useState(null);
|
|
const [bubbleInput, setBubbleInput] = React11.useState(null);
|
|
const hasConsumerStoppedPropagationRef = React11.useRef(false);
|
|
const isFormControl2 = control ? !!form || !!control.closest("form") : (
|
|
// We set this to true by default so that events bubble to forms without JS (SSR)
|
|
true
|
|
);
|
|
const context = {
|
|
checked,
|
|
disabled,
|
|
setChecked,
|
|
control,
|
|
setControl,
|
|
name,
|
|
form,
|
|
value,
|
|
hasConsumerStoppedPropagationRef,
|
|
required,
|
|
defaultChecked: isIndeterminate(defaultChecked) ? false : defaultChecked,
|
|
isFormControl: isFormControl2,
|
|
bubbleInput,
|
|
setBubbleInput
|
|
};
|
|
return (0, import_jsx_runtime11.jsx)(
|
|
CheckboxProviderImpl,
|
|
{
|
|
scope: __scopeCheckbox,
|
|
...context,
|
|
children: isFunction(internal_do_not_use_render) ? internal_do_not_use_render(context) : children
|
|
}
|
|
);
|
|
}
|
|
var TRIGGER_NAME4 = "CheckboxTrigger";
|
|
var CheckboxTrigger = React11.forwardRef(
|
|
({ __scopeCheckbox, onKeyDown, onClick, ...checkboxProps }, forwardedRef) => {
|
|
const {
|
|
control,
|
|
value,
|
|
disabled,
|
|
checked,
|
|
required,
|
|
setControl,
|
|
setChecked,
|
|
hasConsumerStoppedPropagationRef,
|
|
isFormControl: isFormControl2,
|
|
bubbleInput
|
|
} = useCheckboxContext(TRIGGER_NAME4, __scopeCheckbox);
|
|
const composedRefs = useComposedRefs(forwardedRef, setControl);
|
|
const initialCheckedStateRef = React11.useRef(checked);
|
|
React11.useEffect(() => {
|
|
const form = control == null ? void 0 : control.form;
|
|
if (form) {
|
|
const reset = () => setChecked(initialCheckedStateRef.current);
|
|
form.addEventListener("reset", reset);
|
|
return () => form.removeEventListener("reset", reset);
|
|
}
|
|
}, [control, setChecked]);
|
|
return (0, import_jsx_runtime11.jsx)(
|
|
Primitive.button,
|
|
{
|
|
type: "button",
|
|
role: "checkbox",
|
|
"aria-checked": isIndeterminate(checked) ? "mixed" : checked,
|
|
"aria-required": required,
|
|
"data-state": getState3(checked),
|
|
"data-disabled": disabled ? "" : void 0,
|
|
disabled,
|
|
value,
|
|
...checkboxProps,
|
|
ref: composedRefs,
|
|
onKeyDown: composeEventHandlers(onKeyDown, (event) => {
|
|
if (event.key === "Enter") event.preventDefault();
|
|
}),
|
|
onClick: composeEventHandlers(onClick, (event) => {
|
|
setChecked((prevChecked) => isIndeterminate(prevChecked) ? true : !prevChecked);
|
|
if (bubbleInput && isFormControl2) {
|
|
hasConsumerStoppedPropagationRef.current = event.isPropagationStopped();
|
|
if (!hasConsumerStoppedPropagationRef.current) event.stopPropagation();
|
|
}
|
|
})
|
|
}
|
|
);
|
|
}
|
|
);
|
|
CheckboxTrigger.displayName = TRIGGER_NAME4;
|
|
var Checkbox = React11.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const {
|
|
__scopeCheckbox,
|
|
name,
|
|
checked,
|
|
defaultChecked,
|
|
required,
|
|
disabled,
|
|
value,
|
|
onCheckedChange,
|
|
form,
|
|
...checkboxProps
|
|
} = props;
|
|
return (0, import_jsx_runtime11.jsx)(
|
|
CheckboxProvider,
|
|
{
|
|
__scopeCheckbox,
|
|
checked,
|
|
defaultChecked,
|
|
disabled,
|
|
required,
|
|
onCheckedChange,
|
|
name,
|
|
form,
|
|
value,
|
|
internal_do_not_use_render: ({ isFormControl: isFormControl2 }) => (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
(0, import_jsx_runtime11.jsx)(
|
|
CheckboxTrigger,
|
|
{
|
|
...checkboxProps,
|
|
ref: forwardedRef,
|
|
__scopeCheckbox
|
|
}
|
|
),
|
|
isFormControl2 && (0, import_jsx_runtime11.jsx)(
|
|
CheckboxBubbleInput,
|
|
{
|
|
__scopeCheckbox
|
|
}
|
|
)
|
|
] })
|
|
}
|
|
);
|
|
}
|
|
);
|
|
Checkbox.displayName = CHECKBOX_NAME;
|
|
var INDICATOR_NAME = "CheckboxIndicator";
|
|
var CheckboxIndicator = React11.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeCheckbox, forceMount, ...indicatorProps } = props;
|
|
const context = useCheckboxContext(INDICATOR_NAME, __scopeCheckbox);
|
|
return (0, import_jsx_runtime11.jsx)(
|
|
Presence,
|
|
{
|
|
present: forceMount || isIndeterminate(context.checked) || context.checked === true,
|
|
children: (0, import_jsx_runtime11.jsx)(
|
|
Primitive.span,
|
|
{
|
|
"data-state": getState3(context.checked),
|
|
"data-disabled": context.disabled ? "" : void 0,
|
|
...indicatorProps,
|
|
ref: forwardedRef,
|
|
style: { pointerEvents: "none", ...props.style }
|
|
}
|
|
)
|
|
}
|
|
);
|
|
}
|
|
);
|
|
CheckboxIndicator.displayName = INDICATOR_NAME;
|
|
var BUBBLE_INPUT_NAME = "CheckboxBubbleInput";
|
|
var CheckboxBubbleInput = React11.forwardRef(
|
|
({ __scopeCheckbox, ...props }, forwardedRef) => {
|
|
const {
|
|
control,
|
|
hasConsumerStoppedPropagationRef,
|
|
checked,
|
|
defaultChecked,
|
|
required,
|
|
disabled,
|
|
name,
|
|
value,
|
|
form,
|
|
bubbleInput,
|
|
setBubbleInput
|
|
} = useCheckboxContext(BUBBLE_INPUT_NAME, __scopeCheckbox);
|
|
const composedRefs = useComposedRefs(forwardedRef, setBubbleInput);
|
|
const prevChecked = usePrevious(checked);
|
|
const controlSize = useSize(control);
|
|
React11.useEffect(() => {
|
|
const input = bubbleInput;
|
|
if (!input) return;
|
|
const inputProto = window.HTMLInputElement.prototype;
|
|
const descriptor = Object.getOwnPropertyDescriptor(
|
|
inputProto,
|
|
"checked"
|
|
);
|
|
const setChecked = descriptor.set;
|
|
const bubbles = !hasConsumerStoppedPropagationRef.current;
|
|
if (prevChecked !== checked && setChecked) {
|
|
const event = new Event("click", { bubbles });
|
|
input.indeterminate = isIndeterminate(checked);
|
|
setChecked.call(input, isIndeterminate(checked) ? false : checked);
|
|
input.dispatchEvent(event);
|
|
}
|
|
}, [bubbleInput, prevChecked, checked, hasConsumerStoppedPropagationRef]);
|
|
const defaultCheckedRef = React11.useRef(isIndeterminate(checked) ? false : checked);
|
|
return (0, import_jsx_runtime11.jsx)(
|
|
Primitive.input,
|
|
{
|
|
type: "checkbox",
|
|
"aria-hidden": true,
|
|
defaultChecked: defaultChecked ?? defaultCheckedRef.current,
|
|
required,
|
|
disabled,
|
|
name,
|
|
value,
|
|
form,
|
|
...props,
|
|
tabIndex: -1,
|
|
ref: composedRefs,
|
|
style: {
|
|
...props.style,
|
|
...controlSize,
|
|
position: "absolute",
|
|
pointerEvents: "none",
|
|
opacity: 0,
|
|
margin: 0,
|
|
// We transform because the input is absolutely positioned but we have
|
|
// rendered it **after** the button. This pulls it back to sit on top
|
|
// of the button.
|
|
transform: "translateX(-100%)"
|
|
}
|
|
}
|
|
);
|
|
}
|
|
);
|
|
CheckboxBubbleInput.displayName = BUBBLE_INPUT_NAME;
|
|
function isFunction(value) {
|
|
return typeof value === "function";
|
|
}
|
|
function isIndeterminate(checked) {
|
|
return checked === "indeterminate";
|
|
}
|
|
function getState3(checked) {
|
|
return isIndeterminate(checked) ? "indeterminate" : checked ? "checked" : "unchecked";
|
|
}
|
|
|
|
// ../../node_modules/@radix-ui/react-context-menu/dist/index.mjs
|
|
var dist_exports16 = {};
|
|
__export(dist_exports16, {
|
|
Arrow: () => Arrow22,
|
|
CheckboxItem: () => CheckboxItem2,
|
|
Content: () => Content25,
|
|
ContextMenu: () => ContextMenu,
|
|
ContextMenuArrow: () => ContextMenuArrow,
|
|
ContextMenuCheckboxItem: () => ContextMenuCheckboxItem,
|
|
ContextMenuContent: () => ContextMenuContent,
|
|
ContextMenuGroup: () => ContextMenuGroup,
|
|
ContextMenuItem: () => ContextMenuItem,
|
|
ContextMenuItemIndicator: () => ContextMenuItemIndicator,
|
|
ContextMenuLabel: () => ContextMenuLabel,
|
|
ContextMenuPortal: () => ContextMenuPortal,
|
|
ContextMenuRadioGroup: () => ContextMenuRadioGroup,
|
|
ContextMenuRadioItem: () => ContextMenuRadioItem,
|
|
ContextMenuSeparator: () => ContextMenuSeparator,
|
|
ContextMenuSub: () => ContextMenuSub,
|
|
ContextMenuSubContent: () => ContextMenuSubContent,
|
|
ContextMenuSubTrigger: () => ContextMenuSubTrigger,
|
|
ContextMenuTrigger: () => ContextMenuTrigger,
|
|
Group: () => Group2,
|
|
Item: () => Item23,
|
|
ItemIndicator: () => ItemIndicator2,
|
|
Label: () => Label2,
|
|
Portal: () => Portal23,
|
|
RadioGroup: () => RadioGroup2,
|
|
RadioItem: () => RadioItem2,
|
|
Root: () => Root26,
|
|
Separator: () => Separator2,
|
|
Sub: () => Sub2,
|
|
SubContent: () => SubContent2,
|
|
SubTrigger: () => SubTrigger2,
|
|
Trigger: () => Trigger3,
|
|
createContextMenuScope: () => createContextMenuScope
|
|
});
|
|
var React14 = __toESM(require_react(), 1);
|
|
|
|
// ../../node_modules/@radix-ui/react-menu/dist/index.mjs
|
|
var React13 = __toESM(require_react(), 1);
|
|
|
|
// ../../node_modules/@radix-ui/react-roving-focus/dist/index.mjs
|
|
var React12 = __toESM(require_react(), 1);
|
|
var import_jsx_runtime12 = __toESM(require_jsx_runtime(), 1);
|
|
var ENTRY_FOCUS = "rovingFocusGroup.onEntryFocus";
|
|
var EVENT_OPTIONS = { bubbles: false, cancelable: true };
|
|
var GROUP_NAME = "RovingFocusGroup";
|
|
var [Collection2, useCollection2, createCollectionScope2] = createCollection(GROUP_NAME);
|
|
var [createRovingFocusGroupContext, createRovingFocusGroupScope] = createContextScope(
|
|
GROUP_NAME,
|
|
[createCollectionScope2]
|
|
);
|
|
var [RovingFocusProvider, useRovingFocusContext] = createRovingFocusGroupContext(GROUP_NAME);
|
|
var RovingFocusGroup = React12.forwardRef(
|
|
(props, forwardedRef) => {
|
|
return (0, import_jsx_runtime12.jsx)(Collection2.Provider, { scope: props.__scopeRovingFocusGroup, children: (0, import_jsx_runtime12.jsx)(Collection2.Slot, { scope: props.__scopeRovingFocusGroup, children: (0, import_jsx_runtime12.jsx)(RovingFocusGroupImpl, { ...props, ref: forwardedRef }) }) });
|
|
}
|
|
);
|
|
RovingFocusGroup.displayName = GROUP_NAME;
|
|
var RovingFocusGroupImpl = React12.forwardRef((props, forwardedRef) => {
|
|
const {
|
|
__scopeRovingFocusGroup,
|
|
orientation,
|
|
loop = false,
|
|
dir,
|
|
currentTabStopId: currentTabStopIdProp,
|
|
defaultCurrentTabStopId,
|
|
onCurrentTabStopIdChange,
|
|
onEntryFocus,
|
|
preventScrollOnEntryFocus = false,
|
|
...groupProps
|
|
} = props;
|
|
const ref = React12.useRef(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, ref);
|
|
const direction = useDirection(dir);
|
|
const [currentTabStopId, setCurrentTabStopId] = useControllableState({
|
|
prop: currentTabStopIdProp,
|
|
defaultProp: defaultCurrentTabStopId ?? null,
|
|
onChange: onCurrentTabStopIdChange,
|
|
caller: GROUP_NAME
|
|
});
|
|
const [isTabbingBackOut, setIsTabbingBackOut] = React12.useState(false);
|
|
const handleEntryFocus = useCallbackRef(onEntryFocus);
|
|
const getItems = useCollection2(__scopeRovingFocusGroup);
|
|
const isClickFocusRef = React12.useRef(false);
|
|
const [focusableItemsCount, setFocusableItemsCount] = React12.useState(0);
|
|
React12.useEffect(() => {
|
|
const node = ref.current;
|
|
if (node) {
|
|
node.addEventListener(ENTRY_FOCUS, handleEntryFocus);
|
|
return () => node.removeEventListener(ENTRY_FOCUS, handleEntryFocus);
|
|
}
|
|
}, [handleEntryFocus]);
|
|
return (0, import_jsx_runtime12.jsx)(
|
|
RovingFocusProvider,
|
|
{
|
|
scope: __scopeRovingFocusGroup,
|
|
orientation,
|
|
dir: direction,
|
|
loop,
|
|
currentTabStopId,
|
|
onItemFocus: React12.useCallback(
|
|
(tabStopId) => setCurrentTabStopId(tabStopId),
|
|
[setCurrentTabStopId]
|
|
),
|
|
onItemShiftTab: React12.useCallback(() => setIsTabbingBackOut(true), []),
|
|
onFocusableItemAdd: React12.useCallback(
|
|
() => setFocusableItemsCount((prevCount) => prevCount + 1),
|
|
[]
|
|
),
|
|
onFocusableItemRemove: React12.useCallback(
|
|
() => setFocusableItemsCount((prevCount) => prevCount - 1),
|
|
[]
|
|
),
|
|
children: (0, import_jsx_runtime12.jsx)(
|
|
Primitive.div,
|
|
{
|
|
tabIndex: isTabbingBackOut || focusableItemsCount === 0 ? -1 : 0,
|
|
"data-orientation": orientation,
|
|
...groupProps,
|
|
ref: composedRefs,
|
|
style: { outline: "none", ...props.style },
|
|
onMouseDown: composeEventHandlers(props.onMouseDown, () => {
|
|
isClickFocusRef.current = true;
|
|
}),
|
|
onFocus: composeEventHandlers(props.onFocus, (event) => {
|
|
const isKeyboardFocus = !isClickFocusRef.current;
|
|
if (event.target === event.currentTarget && isKeyboardFocus && !isTabbingBackOut) {
|
|
const entryFocusEvent = new CustomEvent(ENTRY_FOCUS, EVENT_OPTIONS);
|
|
event.currentTarget.dispatchEvent(entryFocusEvent);
|
|
if (!entryFocusEvent.defaultPrevented) {
|
|
const items = getItems().filter((item) => item.focusable);
|
|
const activeItem = items.find((item) => item.active);
|
|
const currentItem = items.find((item) => item.id === currentTabStopId);
|
|
const candidateItems = [activeItem, currentItem, ...items].filter(
|
|
Boolean
|
|
);
|
|
const candidateNodes = candidateItems.map((item) => item.ref.current);
|
|
focusFirst(candidateNodes, preventScrollOnEntryFocus);
|
|
}
|
|
}
|
|
isClickFocusRef.current = false;
|
|
}),
|
|
onBlur: composeEventHandlers(props.onBlur, () => setIsTabbingBackOut(false))
|
|
}
|
|
)
|
|
}
|
|
);
|
|
});
|
|
var ITEM_NAME2 = "RovingFocusGroupItem";
|
|
var RovingFocusGroupItem = React12.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const {
|
|
__scopeRovingFocusGroup,
|
|
focusable = true,
|
|
active = false,
|
|
tabStopId,
|
|
children,
|
|
...itemProps
|
|
} = props;
|
|
const autoId = useId();
|
|
const id = tabStopId || autoId;
|
|
const context = useRovingFocusContext(ITEM_NAME2, __scopeRovingFocusGroup);
|
|
const isCurrentTabStop = context.currentTabStopId === id;
|
|
const getItems = useCollection2(__scopeRovingFocusGroup);
|
|
const { onFocusableItemAdd, onFocusableItemRemove, currentTabStopId } = context;
|
|
React12.useEffect(() => {
|
|
if (focusable) {
|
|
onFocusableItemAdd();
|
|
return () => onFocusableItemRemove();
|
|
}
|
|
}, [focusable, onFocusableItemAdd, onFocusableItemRemove]);
|
|
return (0, import_jsx_runtime12.jsx)(
|
|
Collection2.ItemSlot,
|
|
{
|
|
scope: __scopeRovingFocusGroup,
|
|
id,
|
|
focusable,
|
|
active,
|
|
children: (0, import_jsx_runtime12.jsx)(
|
|
Primitive.span,
|
|
{
|
|
tabIndex: isCurrentTabStop ? 0 : -1,
|
|
"data-orientation": context.orientation,
|
|
...itemProps,
|
|
ref: forwardedRef,
|
|
onMouseDown: composeEventHandlers(props.onMouseDown, (event) => {
|
|
if (!focusable) event.preventDefault();
|
|
else context.onItemFocus(id);
|
|
}),
|
|
onFocus: composeEventHandlers(props.onFocus, () => context.onItemFocus(id)),
|
|
onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
|
|
if (event.key === "Tab" && event.shiftKey) {
|
|
context.onItemShiftTab();
|
|
return;
|
|
}
|
|
if (event.target !== event.currentTarget) return;
|
|
const focusIntent = getFocusIntent(event, context.orientation, context.dir);
|
|
if (focusIntent !== void 0) {
|
|
if (event.metaKey || event.ctrlKey || event.altKey || event.shiftKey) return;
|
|
event.preventDefault();
|
|
const items = getItems().filter((item) => item.focusable);
|
|
let candidateNodes = items.map((item) => item.ref.current);
|
|
if (focusIntent === "last") candidateNodes.reverse();
|
|
else if (focusIntent === "prev" || focusIntent === "next") {
|
|
if (focusIntent === "prev") candidateNodes.reverse();
|
|
const currentIndex = candidateNodes.indexOf(event.currentTarget);
|
|
candidateNodes = context.loop ? wrapArray(candidateNodes, currentIndex + 1) : candidateNodes.slice(currentIndex + 1);
|
|
}
|
|
setTimeout(() => focusFirst(candidateNodes));
|
|
}
|
|
}),
|
|
children: typeof children === "function" ? children({ isCurrentTabStop, hasTabStop: currentTabStopId != null }) : children
|
|
}
|
|
)
|
|
}
|
|
);
|
|
}
|
|
);
|
|
RovingFocusGroupItem.displayName = ITEM_NAME2;
|
|
var MAP_KEY_TO_FOCUS_INTENT = {
|
|
ArrowLeft: "prev",
|
|
ArrowUp: "prev",
|
|
ArrowRight: "next",
|
|
ArrowDown: "next",
|
|
PageUp: "first",
|
|
Home: "first",
|
|
PageDown: "last",
|
|
End: "last"
|
|
};
|
|
function getDirectionAwareKey(key, dir) {
|
|
if (dir !== "rtl") return key;
|
|
return key === "ArrowLeft" ? "ArrowRight" : key === "ArrowRight" ? "ArrowLeft" : key;
|
|
}
|
|
function getFocusIntent(event, orientation, dir) {
|
|
const key = getDirectionAwareKey(event.key, dir);
|
|
if (orientation === "vertical" && ["ArrowLeft", "ArrowRight"].includes(key)) return void 0;
|
|
if (orientation === "horizontal" && ["ArrowUp", "ArrowDown"].includes(key)) return void 0;
|
|
return MAP_KEY_TO_FOCUS_INTENT[key];
|
|
}
|
|
function focusFirst(candidates, preventScroll = false) {
|
|
const PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement;
|
|
for (const candidate of candidates) {
|
|
if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return;
|
|
candidate.focus({ preventScroll });
|
|
if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT) return;
|
|
}
|
|
}
|
|
function wrapArray(array, startIndex) {
|
|
return array.map((_, index) => array[(startIndex + index) % array.length]);
|
|
}
|
|
var Root8 = RovingFocusGroup;
|
|
var Item2 = RovingFocusGroupItem;
|
|
|
|
// ../../node_modules/@radix-ui/react-menu/dist/index.mjs
|
|
var import_jsx_runtime13 = __toESM(require_jsx_runtime(), 1);
|
|
var SELECTION_KEYS = ["Enter", " "];
|
|
var FIRST_KEYS = ["ArrowDown", "PageUp", "Home"];
|
|
var LAST_KEYS = ["ArrowUp", "PageDown", "End"];
|
|
var FIRST_LAST_KEYS = [...FIRST_KEYS, ...LAST_KEYS];
|
|
var SUB_OPEN_KEYS = {
|
|
ltr: [...SELECTION_KEYS, "ArrowRight"],
|
|
rtl: [...SELECTION_KEYS, "ArrowLeft"]
|
|
};
|
|
var SUB_CLOSE_KEYS = {
|
|
ltr: ["ArrowLeft"],
|
|
rtl: ["ArrowRight"]
|
|
};
|
|
var MENU_NAME = "Menu";
|
|
var [Collection3, useCollection3, createCollectionScope3] = createCollection(MENU_NAME);
|
|
var [createMenuContext, createMenuScope] = createContextScope(MENU_NAME, [
|
|
createCollectionScope3,
|
|
createPopperScope,
|
|
createRovingFocusGroupScope
|
|
]);
|
|
var usePopperScope = createPopperScope();
|
|
var useRovingFocusGroupScope = createRovingFocusGroupScope();
|
|
var [MenuProvider, useMenuContext] = createMenuContext(MENU_NAME);
|
|
var [MenuRootProvider, useMenuRootContext] = createMenuContext(MENU_NAME);
|
|
var Menu = (props) => {
|
|
const { __scopeMenu, open = false, children, dir, onOpenChange, modal = true } = props;
|
|
const popperScope = usePopperScope(__scopeMenu);
|
|
const [content, setContent] = React13.useState(null);
|
|
const isUsingKeyboardRef = React13.useRef(false);
|
|
const handleOpenChange = useCallbackRef(onOpenChange);
|
|
const direction = useDirection(dir);
|
|
React13.useEffect(() => {
|
|
const handleKeyDown = () => {
|
|
isUsingKeyboardRef.current = true;
|
|
document.addEventListener("pointerdown", handlePointer, { capture: true, once: true });
|
|
document.addEventListener("pointermove", handlePointer, { capture: true, once: true });
|
|
};
|
|
const handlePointer = () => isUsingKeyboardRef.current = false;
|
|
document.addEventListener("keydown", handleKeyDown, { capture: true });
|
|
return () => {
|
|
document.removeEventListener("keydown", handleKeyDown, { capture: true });
|
|
document.removeEventListener("pointerdown", handlePointer, { capture: true });
|
|
document.removeEventListener("pointermove", handlePointer, { capture: true });
|
|
};
|
|
}, []);
|
|
return (0, import_jsx_runtime13.jsx)(Root22, { ...popperScope, children: (0, import_jsx_runtime13.jsx)(
|
|
MenuProvider,
|
|
{
|
|
scope: __scopeMenu,
|
|
open,
|
|
onOpenChange: handleOpenChange,
|
|
content,
|
|
onContentChange: setContent,
|
|
children: (0, import_jsx_runtime13.jsx)(
|
|
MenuRootProvider,
|
|
{
|
|
scope: __scopeMenu,
|
|
onClose: React13.useCallback(() => handleOpenChange(false), [handleOpenChange]),
|
|
isUsingKeyboardRef,
|
|
dir: direction,
|
|
modal,
|
|
children
|
|
}
|
|
)
|
|
}
|
|
) });
|
|
};
|
|
Menu.displayName = MENU_NAME;
|
|
var ANCHOR_NAME = "MenuAnchor";
|
|
var MenuAnchor = React13.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeMenu, ...anchorProps } = props;
|
|
const popperScope = usePopperScope(__scopeMenu);
|
|
return (0, import_jsx_runtime13.jsx)(Anchor, { ...popperScope, ...anchorProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
MenuAnchor.displayName = ANCHOR_NAME;
|
|
var PORTAL_NAME2 = "MenuPortal";
|
|
var [PortalProvider, usePortalContext] = createMenuContext(PORTAL_NAME2, {
|
|
forceMount: void 0
|
|
});
|
|
var MenuPortal = (props) => {
|
|
const { __scopeMenu, forceMount, children, container } = props;
|
|
const context = useMenuContext(PORTAL_NAME2, __scopeMenu);
|
|
return (0, import_jsx_runtime13.jsx)(PortalProvider, { scope: __scopeMenu, forceMount, children: (0, import_jsx_runtime13.jsx)(Presence, { present: forceMount || context.open, children: (0, import_jsx_runtime13.jsx)(Portal, { asChild: true, container, children }) }) });
|
|
};
|
|
MenuPortal.displayName = PORTAL_NAME2;
|
|
var CONTENT_NAME4 = "MenuContent";
|
|
var [MenuContentProvider, useMenuContentContext] = createMenuContext(CONTENT_NAME4);
|
|
var MenuContent = React13.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const portalContext = usePortalContext(CONTENT_NAME4, props.__scopeMenu);
|
|
const { forceMount = portalContext.forceMount, ...contentProps } = props;
|
|
const context = useMenuContext(CONTENT_NAME4, props.__scopeMenu);
|
|
const rootContext = useMenuRootContext(CONTENT_NAME4, props.__scopeMenu);
|
|
return (0, import_jsx_runtime13.jsx)(Collection3.Provider, { scope: props.__scopeMenu, children: (0, import_jsx_runtime13.jsx)(Presence, { present: forceMount || context.open, children: (0, import_jsx_runtime13.jsx)(Collection3.Slot, { scope: props.__scopeMenu, children: rootContext.modal ? (0, import_jsx_runtime13.jsx)(MenuRootContentModal, { ...contentProps, ref: forwardedRef }) : (0, import_jsx_runtime13.jsx)(MenuRootContentNonModal, { ...contentProps, ref: forwardedRef }) }) }) });
|
|
}
|
|
);
|
|
var MenuRootContentModal = React13.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const context = useMenuContext(CONTENT_NAME4, props.__scopeMenu);
|
|
const ref = React13.useRef(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, ref);
|
|
React13.useEffect(() => {
|
|
const content = ref.current;
|
|
if (content) return hideOthers(content);
|
|
}, []);
|
|
return (0, import_jsx_runtime13.jsx)(
|
|
MenuContentImpl,
|
|
{
|
|
...props,
|
|
ref: composedRefs,
|
|
trapFocus: context.open,
|
|
disableOutsidePointerEvents: context.open,
|
|
disableOutsideScroll: true,
|
|
onFocusOutside: composeEventHandlers(
|
|
props.onFocusOutside,
|
|
(event) => event.preventDefault(),
|
|
{ checkForDefaultPrevented: false }
|
|
),
|
|
onDismiss: () => context.onOpenChange(false)
|
|
}
|
|
);
|
|
}
|
|
);
|
|
var MenuRootContentNonModal = React13.forwardRef((props, forwardedRef) => {
|
|
const context = useMenuContext(CONTENT_NAME4, props.__scopeMenu);
|
|
return (0, import_jsx_runtime13.jsx)(
|
|
MenuContentImpl,
|
|
{
|
|
...props,
|
|
ref: forwardedRef,
|
|
trapFocus: false,
|
|
disableOutsidePointerEvents: false,
|
|
disableOutsideScroll: false,
|
|
onDismiss: () => context.onOpenChange(false)
|
|
}
|
|
);
|
|
});
|
|
var Slot = createSlot("MenuContent.ScrollLock");
|
|
var MenuContentImpl = React13.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const {
|
|
__scopeMenu,
|
|
loop = false,
|
|
trapFocus,
|
|
onOpenAutoFocus,
|
|
onCloseAutoFocus,
|
|
disableOutsidePointerEvents,
|
|
onEntryFocus,
|
|
onEscapeKeyDown,
|
|
onPointerDownOutside,
|
|
onFocusOutside,
|
|
onInteractOutside,
|
|
onDismiss,
|
|
disableOutsideScroll,
|
|
...contentProps
|
|
} = props;
|
|
const context = useMenuContext(CONTENT_NAME4, __scopeMenu);
|
|
const rootContext = useMenuRootContext(CONTENT_NAME4, __scopeMenu);
|
|
const popperScope = usePopperScope(__scopeMenu);
|
|
const rovingFocusGroupScope = useRovingFocusGroupScope(__scopeMenu);
|
|
const getItems = useCollection3(__scopeMenu);
|
|
const [currentItemId, setCurrentItemId] = React13.useState(null);
|
|
const contentRef = React13.useRef(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, contentRef, context.onContentChange);
|
|
const timerRef = React13.useRef(0);
|
|
const searchRef = React13.useRef("");
|
|
const pointerGraceTimerRef = React13.useRef(0);
|
|
const pointerGraceIntentRef = React13.useRef(null);
|
|
const pointerDirRef = React13.useRef("right");
|
|
const lastPointerXRef = React13.useRef(0);
|
|
const ScrollLockWrapper = disableOutsideScroll ? Combination_default : React13.Fragment;
|
|
const scrollLockWrapperProps = disableOutsideScroll ? { as: Slot, allowPinchZoom: true } : void 0;
|
|
const handleTypeaheadSearch = (key) => {
|
|
var _a2, _b;
|
|
const search = searchRef.current + key;
|
|
const items = getItems().filter((item) => !item.disabled);
|
|
const currentItem = document.activeElement;
|
|
const currentMatch = (_a2 = items.find((item) => item.ref.current === currentItem)) == null ? void 0 : _a2.textValue;
|
|
const values = items.map((item) => item.textValue);
|
|
const nextMatch = getNextMatch(values, search, currentMatch);
|
|
const newItem = (_b = items.find((item) => item.textValue === nextMatch)) == null ? void 0 : _b.ref.current;
|
|
(function updateSearch(value) {
|
|
searchRef.current = value;
|
|
window.clearTimeout(timerRef.current);
|
|
if (value !== "") timerRef.current = window.setTimeout(() => updateSearch(""), 1e3);
|
|
})(search);
|
|
if (newItem) {
|
|
setTimeout(() => newItem.focus());
|
|
}
|
|
};
|
|
React13.useEffect(() => {
|
|
return () => window.clearTimeout(timerRef.current);
|
|
}, []);
|
|
useFocusGuards();
|
|
const isPointerMovingToSubmenu = React13.useCallback((event) => {
|
|
var _a2, _b;
|
|
const isMovingTowards = pointerDirRef.current === ((_a2 = pointerGraceIntentRef.current) == null ? void 0 : _a2.side);
|
|
return isMovingTowards && isPointerInGraceArea(event, (_b = pointerGraceIntentRef.current) == null ? void 0 : _b.area);
|
|
}, []);
|
|
return (0, import_jsx_runtime13.jsx)(
|
|
MenuContentProvider,
|
|
{
|
|
scope: __scopeMenu,
|
|
searchRef,
|
|
onItemEnter: React13.useCallback(
|
|
(event) => {
|
|
if (isPointerMovingToSubmenu(event)) event.preventDefault();
|
|
},
|
|
[isPointerMovingToSubmenu]
|
|
),
|
|
onItemLeave: React13.useCallback(
|
|
(event) => {
|
|
var _a2;
|
|
if (isPointerMovingToSubmenu(event)) return;
|
|
(_a2 = contentRef.current) == null ? void 0 : _a2.focus();
|
|
setCurrentItemId(null);
|
|
},
|
|
[isPointerMovingToSubmenu]
|
|
),
|
|
onTriggerLeave: React13.useCallback(
|
|
(event) => {
|
|
if (isPointerMovingToSubmenu(event)) event.preventDefault();
|
|
},
|
|
[isPointerMovingToSubmenu]
|
|
),
|
|
pointerGraceTimerRef,
|
|
onPointerGraceIntentChange: React13.useCallback((intent) => {
|
|
pointerGraceIntentRef.current = intent;
|
|
}, []),
|
|
children: (0, import_jsx_runtime13.jsx)(ScrollLockWrapper, { ...scrollLockWrapperProps, children: (0, import_jsx_runtime13.jsx)(
|
|
FocusScope,
|
|
{
|
|
asChild: true,
|
|
trapped: trapFocus,
|
|
onMountAutoFocus: composeEventHandlers(onOpenAutoFocus, (event) => {
|
|
var _a2;
|
|
event.preventDefault();
|
|
(_a2 = contentRef.current) == null ? void 0 : _a2.focus({ preventScroll: true });
|
|
}),
|
|
onUnmountAutoFocus: onCloseAutoFocus,
|
|
children: (0, import_jsx_runtime13.jsx)(
|
|
DismissableLayer,
|
|
{
|
|
asChild: true,
|
|
disableOutsidePointerEvents,
|
|
onEscapeKeyDown,
|
|
onPointerDownOutside,
|
|
onFocusOutside,
|
|
onInteractOutside,
|
|
onDismiss,
|
|
children: (0, import_jsx_runtime13.jsx)(
|
|
Root8,
|
|
{
|
|
asChild: true,
|
|
...rovingFocusGroupScope,
|
|
dir: rootContext.dir,
|
|
orientation: "vertical",
|
|
loop,
|
|
currentTabStopId: currentItemId,
|
|
onCurrentTabStopIdChange: setCurrentItemId,
|
|
onEntryFocus: composeEventHandlers(onEntryFocus, (event) => {
|
|
if (!rootContext.isUsingKeyboardRef.current) event.preventDefault();
|
|
}),
|
|
preventScrollOnEntryFocus: true,
|
|
children: (0, import_jsx_runtime13.jsx)(
|
|
Content,
|
|
{
|
|
role: "menu",
|
|
"aria-orientation": "vertical",
|
|
"data-state": getOpenState(context.open),
|
|
"data-radix-menu-content": "",
|
|
dir: rootContext.dir,
|
|
...popperScope,
|
|
...contentProps,
|
|
ref: composedRefs,
|
|
style: { outline: "none", ...contentProps.style },
|
|
onKeyDown: composeEventHandlers(contentProps.onKeyDown, (event) => {
|
|
const target = event.target;
|
|
const isKeyDownInside = target.closest("[data-radix-menu-content]") === event.currentTarget;
|
|
const isModifierKey = event.ctrlKey || event.altKey || event.metaKey;
|
|
const isCharacterKey = event.key.length === 1;
|
|
if (isKeyDownInside) {
|
|
if (event.key === "Tab") event.preventDefault();
|
|
if (!isModifierKey && isCharacterKey) handleTypeaheadSearch(event.key);
|
|
}
|
|
const content = contentRef.current;
|
|
if (event.target !== content) return;
|
|
if (!FIRST_LAST_KEYS.includes(event.key)) return;
|
|
event.preventDefault();
|
|
const items = getItems().filter((item) => !item.disabled);
|
|
const candidateNodes = items.map((item) => item.ref.current);
|
|
if (LAST_KEYS.includes(event.key)) candidateNodes.reverse();
|
|
focusFirst2(candidateNodes);
|
|
}),
|
|
onBlur: composeEventHandlers(props.onBlur, (event) => {
|
|
if (!event.currentTarget.contains(event.target)) {
|
|
window.clearTimeout(timerRef.current);
|
|
searchRef.current = "";
|
|
}
|
|
}),
|
|
onPointerMove: composeEventHandlers(
|
|
props.onPointerMove,
|
|
whenMouse((event) => {
|
|
const target = event.target;
|
|
const pointerXHasChanged = lastPointerXRef.current !== event.clientX;
|
|
if (event.currentTarget.contains(target) && pointerXHasChanged) {
|
|
const newDir = event.clientX > lastPointerXRef.current ? "right" : "left";
|
|
pointerDirRef.current = newDir;
|
|
lastPointerXRef.current = event.clientX;
|
|
}
|
|
})
|
|
)
|
|
}
|
|
)
|
|
}
|
|
)
|
|
}
|
|
)
|
|
}
|
|
) })
|
|
}
|
|
);
|
|
}
|
|
);
|
|
MenuContent.displayName = CONTENT_NAME4;
|
|
var GROUP_NAME2 = "MenuGroup";
|
|
var MenuGroup = React13.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeMenu, ...groupProps } = props;
|
|
return (0, import_jsx_runtime13.jsx)(Primitive.div, { role: "group", ...groupProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
MenuGroup.displayName = GROUP_NAME2;
|
|
var LABEL_NAME = "MenuLabel";
|
|
var MenuLabel = React13.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeMenu, ...labelProps } = props;
|
|
return (0, import_jsx_runtime13.jsx)(Primitive.div, { ...labelProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
MenuLabel.displayName = LABEL_NAME;
|
|
var ITEM_NAME3 = "MenuItem";
|
|
var ITEM_SELECT = "menu.itemSelect";
|
|
var MenuItem = React13.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { disabled = false, onSelect, ...itemProps } = props;
|
|
const ref = React13.useRef(null);
|
|
const rootContext = useMenuRootContext(ITEM_NAME3, props.__scopeMenu);
|
|
const contentContext = useMenuContentContext(ITEM_NAME3, props.__scopeMenu);
|
|
const composedRefs = useComposedRefs(forwardedRef, ref);
|
|
const isPointerDownRef = React13.useRef(false);
|
|
const handleSelect = () => {
|
|
const menuItem = ref.current;
|
|
if (!disabled && menuItem) {
|
|
const itemSelectEvent = new CustomEvent(ITEM_SELECT, { bubbles: true, cancelable: true });
|
|
menuItem.addEventListener(ITEM_SELECT, (event) => onSelect == null ? void 0 : onSelect(event), { once: true });
|
|
dispatchDiscreteCustomEvent(menuItem, itemSelectEvent);
|
|
if (itemSelectEvent.defaultPrevented) {
|
|
isPointerDownRef.current = false;
|
|
} else {
|
|
rootContext.onClose();
|
|
}
|
|
}
|
|
};
|
|
return (0, import_jsx_runtime13.jsx)(
|
|
MenuItemImpl,
|
|
{
|
|
...itemProps,
|
|
ref: composedRefs,
|
|
disabled,
|
|
onClick: composeEventHandlers(props.onClick, handleSelect),
|
|
onPointerDown: (event) => {
|
|
var _a2;
|
|
(_a2 = props.onPointerDown) == null ? void 0 : _a2.call(props, event);
|
|
isPointerDownRef.current = true;
|
|
},
|
|
onPointerUp: composeEventHandlers(props.onPointerUp, (event) => {
|
|
var _a2;
|
|
if (!isPointerDownRef.current) (_a2 = event.currentTarget) == null ? void 0 : _a2.click();
|
|
}),
|
|
onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
|
|
const isTypingAhead = contentContext.searchRef.current !== "";
|
|
if (disabled || isTypingAhead && event.key === " ") return;
|
|
if (SELECTION_KEYS.includes(event.key)) {
|
|
event.currentTarget.click();
|
|
event.preventDefault();
|
|
}
|
|
})
|
|
}
|
|
);
|
|
}
|
|
);
|
|
MenuItem.displayName = ITEM_NAME3;
|
|
var MenuItemImpl = React13.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeMenu, disabled = false, textValue, ...itemProps } = props;
|
|
const contentContext = useMenuContentContext(ITEM_NAME3, __scopeMenu);
|
|
const rovingFocusGroupScope = useRovingFocusGroupScope(__scopeMenu);
|
|
const ref = React13.useRef(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, ref);
|
|
const [isFocused, setIsFocused] = React13.useState(false);
|
|
const [textContent, setTextContent] = React13.useState("");
|
|
React13.useEffect(() => {
|
|
const menuItem = ref.current;
|
|
if (menuItem) {
|
|
setTextContent((menuItem.textContent ?? "").trim());
|
|
}
|
|
}, [itemProps.children]);
|
|
return (0, import_jsx_runtime13.jsx)(
|
|
Collection3.ItemSlot,
|
|
{
|
|
scope: __scopeMenu,
|
|
disabled,
|
|
textValue: textValue ?? textContent,
|
|
children: (0, import_jsx_runtime13.jsx)(Item2, { asChild: true, ...rovingFocusGroupScope, focusable: !disabled, children: (0, import_jsx_runtime13.jsx)(
|
|
Primitive.div,
|
|
{
|
|
role: "menuitem",
|
|
"data-highlighted": isFocused ? "" : void 0,
|
|
"aria-disabled": disabled || void 0,
|
|
"data-disabled": disabled ? "" : void 0,
|
|
...itemProps,
|
|
ref: composedRefs,
|
|
onPointerMove: composeEventHandlers(
|
|
props.onPointerMove,
|
|
whenMouse((event) => {
|
|
if (disabled) {
|
|
contentContext.onItemLeave(event);
|
|
} else {
|
|
contentContext.onItemEnter(event);
|
|
if (!event.defaultPrevented) {
|
|
const item = event.currentTarget;
|
|
item.focus({ preventScroll: true });
|
|
}
|
|
}
|
|
})
|
|
),
|
|
onPointerLeave: composeEventHandlers(
|
|
props.onPointerLeave,
|
|
whenMouse((event) => contentContext.onItemLeave(event))
|
|
),
|
|
onFocus: composeEventHandlers(props.onFocus, () => setIsFocused(true)),
|
|
onBlur: composeEventHandlers(props.onBlur, () => setIsFocused(false))
|
|
}
|
|
) })
|
|
}
|
|
);
|
|
}
|
|
);
|
|
var CHECKBOX_ITEM_NAME = "MenuCheckboxItem";
|
|
var MenuCheckboxItem = React13.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { checked = false, onCheckedChange, ...checkboxItemProps } = props;
|
|
return (0, import_jsx_runtime13.jsx)(ItemIndicatorProvider, { scope: props.__scopeMenu, checked, children: (0, import_jsx_runtime13.jsx)(
|
|
MenuItem,
|
|
{
|
|
role: "menuitemcheckbox",
|
|
"aria-checked": isIndeterminate2(checked) ? "mixed" : checked,
|
|
...checkboxItemProps,
|
|
ref: forwardedRef,
|
|
"data-state": getCheckedState(checked),
|
|
onSelect: composeEventHandlers(
|
|
checkboxItemProps.onSelect,
|
|
() => onCheckedChange == null ? void 0 : onCheckedChange(isIndeterminate2(checked) ? true : !checked),
|
|
{ checkForDefaultPrevented: false }
|
|
)
|
|
}
|
|
) });
|
|
}
|
|
);
|
|
MenuCheckboxItem.displayName = CHECKBOX_ITEM_NAME;
|
|
var RADIO_GROUP_NAME = "MenuRadioGroup";
|
|
var [RadioGroupProvider, useRadioGroupContext] = createMenuContext(
|
|
RADIO_GROUP_NAME,
|
|
{ value: void 0, onValueChange: () => {
|
|
} }
|
|
);
|
|
var MenuRadioGroup = React13.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { value, onValueChange, ...groupProps } = props;
|
|
const handleValueChange = useCallbackRef(onValueChange);
|
|
return (0, import_jsx_runtime13.jsx)(RadioGroupProvider, { scope: props.__scopeMenu, value, onValueChange: handleValueChange, children: (0, import_jsx_runtime13.jsx)(MenuGroup, { ...groupProps, ref: forwardedRef }) });
|
|
}
|
|
);
|
|
MenuRadioGroup.displayName = RADIO_GROUP_NAME;
|
|
var RADIO_ITEM_NAME = "MenuRadioItem";
|
|
var MenuRadioItem = React13.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { value, ...radioItemProps } = props;
|
|
const context = useRadioGroupContext(RADIO_ITEM_NAME, props.__scopeMenu);
|
|
const checked = value === context.value;
|
|
return (0, import_jsx_runtime13.jsx)(ItemIndicatorProvider, { scope: props.__scopeMenu, checked, children: (0, import_jsx_runtime13.jsx)(
|
|
MenuItem,
|
|
{
|
|
role: "menuitemradio",
|
|
"aria-checked": checked,
|
|
...radioItemProps,
|
|
ref: forwardedRef,
|
|
"data-state": getCheckedState(checked),
|
|
onSelect: composeEventHandlers(
|
|
radioItemProps.onSelect,
|
|
() => {
|
|
var _a2;
|
|
return (_a2 = context.onValueChange) == null ? void 0 : _a2.call(context, value);
|
|
},
|
|
{ checkForDefaultPrevented: false }
|
|
)
|
|
}
|
|
) });
|
|
}
|
|
);
|
|
MenuRadioItem.displayName = RADIO_ITEM_NAME;
|
|
var ITEM_INDICATOR_NAME = "MenuItemIndicator";
|
|
var [ItemIndicatorProvider, useItemIndicatorContext] = createMenuContext(
|
|
ITEM_INDICATOR_NAME,
|
|
{ checked: false }
|
|
);
|
|
var MenuItemIndicator = React13.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeMenu, forceMount, ...itemIndicatorProps } = props;
|
|
const indicatorContext = useItemIndicatorContext(ITEM_INDICATOR_NAME, __scopeMenu);
|
|
return (0, import_jsx_runtime13.jsx)(
|
|
Presence,
|
|
{
|
|
present: forceMount || isIndeterminate2(indicatorContext.checked) || indicatorContext.checked === true,
|
|
children: (0, import_jsx_runtime13.jsx)(
|
|
Primitive.span,
|
|
{
|
|
...itemIndicatorProps,
|
|
ref: forwardedRef,
|
|
"data-state": getCheckedState(indicatorContext.checked)
|
|
}
|
|
)
|
|
}
|
|
);
|
|
}
|
|
);
|
|
MenuItemIndicator.displayName = ITEM_INDICATOR_NAME;
|
|
var SEPARATOR_NAME = "MenuSeparator";
|
|
var MenuSeparator = React13.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeMenu, ...separatorProps } = props;
|
|
return (0, import_jsx_runtime13.jsx)(
|
|
Primitive.div,
|
|
{
|
|
role: "separator",
|
|
"aria-orientation": "horizontal",
|
|
...separatorProps,
|
|
ref: forwardedRef
|
|
}
|
|
);
|
|
}
|
|
);
|
|
MenuSeparator.displayName = SEPARATOR_NAME;
|
|
var ARROW_NAME = "MenuArrow";
|
|
var MenuArrow = React13.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeMenu, ...arrowProps } = props;
|
|
const popperScope = usePopperScope(__scopeMenu);
|
|
return (0, import_jsx_runtime13.jsx)(Arrow, { ...popperScope, ...arrowProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
MenuArrow.displayName = ARROW_NAME;
|
|
var SUB_NAME = "MenuSub";
|
|
var [MenuSubProvider, useMenuSubContext] = createMenuContext(SUB_NAME);
|
|
var MenuSub = (props) => {
|
|
const { __scopeMenu, children, open = false, onOpenChange } = props;
|
|
const parentMenuContext = useMenuContext(SUB_NAME, __scopeMenu);
|
|
const popperScope = usePopperScope(__scopeMenu);
|
|
const [trigger, setTrigger] = React13.useState(null);
|
|
const [content, setContent] = React13.useState(null);
|
|
const handleOpenChange = useCallbackRef(onOpenChange);
|
|
React13.useEffect(() => {
|
|
if (parentMenuContext.open === false) handleOpenChange(false);
|
|
return () => handleOpenChange(false);
|
|
}, [parentMenuContext.open, handleOpenChange]);
|
|
return (0, import_jsx_runtime13.jsx)(Root22, { ...popperScope, children: (0, import_jsx_runtime13.jsx)(
|
|
MenuProvider,
|
|
{
|
|
scope: __scopeMenu,
|
|
open,
|
|
onOpenChange: handleOpenChange,
|
|
content,
|
|
onContentChange: setContent,
|
|
children: (0, import_jsx_runtime13.jsx)(
|
|
MenuSubProvider,
|
|
{
|
|
scope: __scopeMenu,
|
|
contentId: useId(),
|
|
triggerId: useId(),
|
|
trigger,
|
|
onTriggerChange: setTrigger,
|
|
children
|
|
}
|
|
)
|
|
}
|
|
) });
|
|
};
|
|
MenuSub.displayName = SUB_NAME;
|
|
var SUB_TRIGGER_NAME = "MenuSubTrigger";
|
|
var MenuSubTrigger = React13.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const context = useMenuContext(SUB_TRIGGER_NAME, props.__scopeMenu);
|
|
const rootContext = useMenuRootContext(SUB_TRIGGER_NAME, props.__scopeMenu);
|
|
const subContext = useMenuSubContext(SUB_TRIGGER_NAME, props.__scopeMenu);
|
|
const contentContext = useMenuContentContext(SUB_TRIGGER_NAME, props.__scopeMenu);
|
|
const openTimerRef = React13.useRef(null);
|
|
const { pointerGraceTimerRef, onPointerGraceIntentChange } = contentContext;
|
|
const scope = { __scopeMenu: props.__scopeMenu };
|
|
const clearOpenTimer = React13.useCallback(() => {
|
|
if (openTimerRef.current) window.clearTimeout(openTimerRef.current);
|
|
openTimerRef.current = null;
|
|
}, []);
|
|
React13.useEffect(() => clearOpenTimer, [clearOpenTimer]);
|
|
React13.useEffect(() => {
|
|
const pointerGraceTimer = pointerGraceTimerRef.current;
|
|
return () => {
|
|
window.clearTimeout(pointerGraceTimer);
|
|
onPointerGraceIntentChange(null);
|
|
};
|
|
}, [pointerGraceTimerRef, onPointerGraceIntentChange]);
|
|
return (0, import_jsx_runtime13.jsx)(MenuAnchor, { asChild: true, ...scope, children: (0, import_jsx_runtime13.jsx)(
|
|
MenuItemImpl,
|
|
{
|
|
id: subContext.triggerId,
|
|
"aria-haspopup": "menu",
|
|
"aria-expanded": context.open,
|
|
"aria-controls": subContext.contentId,
|
|
"data-state": getOpenState(context.open),
|
|
...props,
|
|
ref: composeRefs(forwardedRef, subContext.onTriggerChange),
|
|
onClick: (event) => {
|
|
var _a2;
|
|
(_a2 = props.onClick) == null ? void 0 : _a2.call(props, event);
|
|
if (props.disabled || event.defaultPrevented) return;
|
|
event.currentTarget.focus();
|
|
if (!context.open) context.onOpenChange(true);
|
|
},
|
|
onPointerMove: composeEventHandlers(
|
|
props.onPointerMove,
|
|
whenMouse((event) => {
|
|
contentContext.onItemEnter(event);
|
|
if (event.defaultPrevented) return;
|
|
if (!props.disabled && !context.open && !openTimerRef.current) {
|
|
contentContext.onPointerGraceIntentChange(null);
|
|
openTimerRef.current = window.setTimeout(() => {
|
|
context.onOpenChange(true);
|
|
clearOpenTimer();
|
|
}, 100);
|
|
}
|
|
})
|
|
),
|
|
onPointerLeave: composeEventHandlers(
|
|
props.onPointerLeave,
|
|
whenMouse((event) => {
|
|
var _a2, _b;
|
|
clearOpenTimer();
|
|
const contentRect = (_a2 = context.content) == null ? void 0 : _a2.getBoundingClientRect();
|
|
if (contentRect) {
|
|
const side = (_b = context.content) == null ? void 0 : _b.dataset.side;
|
|
const rightSide = side === "right";
|
|
const bleed = rightSide ? -5 : 5;
|
|
const contentNearEdge = contentRect[rightSide ? "left" : "right"];
|
|
const contentFarEdge = contentRect[rightSide ? "right" : "left"];
|
|
contentContext.onPointerGraceIntentChange({
|
|
area: [
|
|
// Apply a bleed on clientX to ensure that our exit point is
|
|
// consistently within polygon bounds
|
|
{ x: event.clientX + bleed, y: event.clientY },
|
|
{ x: contentNearEdge, y: contentRect.top },
|
|
{ x: contentFarEdge, y: contentRect.top },
|
|
{ x: contentFarEdge, y: contentRect.bottom },
|
|
{ x: contentNearEdge, y: contentRect.bottom }
|
|
],
|
|
side
|
|
});
|
|
window.clearTimeout(pointerGraceTimerRef.current);
|
|
pointerGraceTimerRef.current = window.setTimeout(
|
|
() => contentContext.onPointerGraceIntentChange(null),
|
|
300
|
|
);
|
|
} else {
|
|
contentContext.onTriggerLeave(event);
|
|
if (event.defaultPrevented) return;
|
|
contentContext.onPointerGraceIntentChange(null);
|
|
}
|
|
})
|
|
),
|
|
onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
|
|
var _a2;
|
|
const isTypingAhead = contentContext.searchRef.current !== "";
|
|
if (props.disabled || isTypingAhead && event.key === " ") return;
|
|
if (SUB_OPEN_KEYS[rootContext.dir].includes(event.key)) {
|
|
context.onOpenChange(true);
|
|
(_a2 = context.content) == null ? void 0 : _a2.focus();
|
|
event.preventDefault();
|
|
}
|
|
})
|
|
}
|
|
) });
|
|
}
|
|
);
|
|
MenuSubTrigger.displayName = SUB_TRIGGER_NAME;
|
|
var SUB_CONTENT_NAME = "MenuSubContent";
|
|
var MenuSubContent = React13.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const portalContext = usePortalContext(CONTENT_NAME4, props.__scopeMenu);
|
|
const { forceMount = portalContext.forceMount, ...subContentProps } = props;
|
|
const context = useMenuContext(CONTENT_NAME4, props.__scopeMenu);
|
|
const rootContext = useMenuRootContext(CONTENT_NAME4, props.__scopeMenu);
|
|
const subContext = useMenuSubContext(SUB_CONTENT_NAME, props.__scopeMenu);
|
|
const ref = React13.useRef(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, ref);
|
|
return (0, import_jsx_runtime13.jsx)(Collection3.Provider, { scope: props.__scopeMenu, children: (0, import_jsx_runtime13.jsx)(Presence, { present: forceMount || context.open, children: (0, import_jsx_runtime13.jsx)(Collection3.Slot, { scope: props.__scopeMenu, children: (0, import_jsx_runtime13.jsx)(
|
|
MenuContentImpl,
|
|
{
|
|
id: subContext.contentId,
|
|
"aria-labelledby": subContext.triggerId,
|
|
...subContentProps,
|
|
ref: composedRefs,
|
|
align: "start",
|
|
side: rootContext.dir === "rtl" ? "left" : "right",
|
|
disableOutsidePointerEvents: false,
|
|
disableOutsideScroll: false,
|
|
trapFocus: false,
|
|
onOpenAutoFocus: (event) => {
|
|
var _a2;
|
|
if (rootContext.isUsingKeyboardRef.current) (_a2 = ref.current) == null ? void 0 : _a2.focus();
|
|
event.preventDefault();
|
|
},
|
|
onCloseAutoFocus: (event) => event.preventDefault(),
|
|
onFocusOutside: composeEventHandlers(props.onFocusOutside, (event) => {
|
|
if (event.target !== subContext.trigger) context.onOpenChange(false);
|
|
}),
|
|
onEscapeKeyDown: composeEventHandlers(props.onEscapeKeyDown, (event) => {
|
|
rootContext.onClose();
|
|
event.preventDefault();
|
|
}),
|
|
onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
|
|
var _a2;
|
|
const isKeyDownInside = event.currentTarget.contains(event.target);
|
|
const isCloseKey = SUB_CLOSE_KEYS[rootContext.dir].includes(event.key);
|
|
if (isKeyDownInside && isCloseKey) {
|
|
context.onOpenChange(false);
|
|
(_a2 = subContext.trigger) == null ? void 0 : _a2.focus();
|
|
event.preventDefault();
|
|
}
|
|
})
|
|
}
|
|
) }) }) });
|
|
}
|
|
);
|
|
MenuSubContent.displayName = SUB_CONTENT_NAME;
|
|
function getOpenState(open) {
|
|
return open ? "open" : "closed";
|
|
}
|
|
function isIndeterminate2(checked) {
|
|
return checked === "indeterminate";
|
|
}
|
|
function getCheckedState(checked) {
|
|
return isIndeterminate2(checked) ? "indeterminate" : checked ? "checked" : "unchecked";
|
|
}
|
|
function focusFirst2(candidates) {
|
|
const PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement;
|
|
for (const candidate of candidates) {
|
|
if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return;
|
|
candidate.focus();
|
|
if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT) return;
|
|
}
|
|
}
|
|
function wrapArray2(array, startIndex) {
|
|
return array.map((_, index) => array[(startIndex + index) % array.length]);
|
|
}
|
|
function getNextMatch(values, search, currentMatch) {
|
|
const isRepeated = search.length > 1 && Array.from(search).every((char) => char === search[0]);
|
|
const normalizedSearch = isRepeated ? search[0] : search;
|
|
const currentMatchIndex = currentMatch ? values.indexOf(currentMatch) : -1;
|
|
let wrappedValues = wrapArray2(values, Math.max(currentMatchIndex, 0));
|
|
const excludeCurrentMatch = normalizedSearch.length === 1;
|
|
if (excludeCurrentMatch) wrappedValues = wrappedValues.filter((v) => v !== currentMatch);
|
|
const nextMatch = wrappedValues.find(
|
|
(value) => value.toLowerCase().startsWith(normalizedSearch.toLowerCase())
|
|
);
|
|
return nextMatch !== currentMatch ? nextMatch : void 0;
|
|
}
|
|
function isPointInPolygon(point, polygon) {
|
|
const { x, y } = point;
|
|
let inside = false;
|
|
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
|
|
const ii = polygon[i];
|
|
const jj = polygon[j];
|
|
const xi = ii.x;
|
|
const yi = ii.y;
|
|
const xj = jj.x;
|
|
const yj = jj.y;
|
|
const intersect = yi > y !== yj > y && x < (xj - xi) * (y - yi) / (yj - yi) + xi;
|
|
if (intersect) inside = !inside;
|
|
}
|
|
return inside;
|
|
}
|
|
function isPointerInGraceArea(event, area) {
|
|
if (!area) return false;
|
|
const cursorPos = { x: event.clientX, y: event.clientY };
|
|
return isPointInPolygon(cursorPos, area);
|
|
}
|
|
function whenMouse(handler) {
|
|
return (event) => event.pointerType === "mouse" ? handler(event) : void 0;
|
|
}
|
|
var Root32 = Menu;
|
|
var Anchor2 = MenuAnchor;
|
|
var Portal3 = MenuPortal;
|
|
var Content24 = MenuContent;
|
|
var Group = MenuGroup;
|
|
var Label = MenuLabel;
|
|
var Item22 = MenuItem;
|
|
var CheckboxItem = MenuCheckboxItem;
|
|
var RadioGroup = MenuRadioGroup;
|
|
var RadioItem = MenuRadioItem;
|
|
var ItemIndicator = MenuItemIndicator;
|
|
var Separator = MenuSeparator;
|
|
var Arrow2 = MenuArrow;
|
|
var Sub = MenuSub;
|
|
var SubTrigger = MenuSubTrigger;
|
|
var SubContent = MenuSubContent;
|
|
|
|
// ../../node_modules/@radix-ui/react-context-menu/dist/index.mjs
|
|
var import_jsx_runtime14 = __toESM(require_jsx_runtime(), 1);
|
|
var CONTEXT_MENU_NAME = "ContextMenu";
|
|
var [createContextMenuContext, createContextMenuScope] = createContextScope(CONTEXT_MENU_NAME, [
|
|
createMenuScope
|
|
]);
|
|
var useMenuScope = createMenuScope();
|
|
var [ContextMenuProvider, useContextMenuContext] = createContextMenuContext(CONTEXT_MENU_NAME);
|
|
var ContextMenu = (props) => {
|
|
const { __scopeContextMenu, children, onOpenChange, dir, modal = true } = props;
|
|
const [open, setOpen] = React14.useState(false);
|
|
const menuScope = useMenuScope(__scopeContextMenu);
|
|
const handleOpenChangeProp = useCallbackRef(onOpenChange);
|
|
const handleOpenChange = React14.useCallback(
|
|
(open2) => {
|
|
setOpen(open2);
|
|
handleOpenChangeProp(open2);
|
|
},
|
|
[handleOpenChangeProp]
|
|
);
|
|
return (0, import_jsx_runtime14.jsx)(
|
|
ContextMenuProvider,
|
|
{
|
|
scope: __scopeContextMenu,
|
|
open,
|
|
onOpenChange: handleOpenChange,
|
|
modal,
|
|
children: (0, import_jsx_runtime14.jsx)(
|
|
Root32,
|
|
{
|
|
...menuScope,
|
|
dir,
|
|
open,
|
|
onOpenChange: handleOpenChange,
|
|
modal,
|
|
children
|
|
}
|
|
)
|
|
}
|
|
);
|
|
};
|
|
ContextMenu.displayName = CONTEXT_MENU_NAME;
|
|
var TRIGGER_NAME5 = "ContextMenuTrigger";
|
|
var ContextMenuTrigger = React14.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeContextMenu, disabled = false, ...triggerProps } = props;
|
|
const context = useContextMenuContext(TRIGGER_NAME5, __scopeContextMenu);
|
|
const menuScope = useMenuScope(__scopeContextMenu);
|
|
const pointRef = React14.useRef({ x: 0, y: 0 });
|
|
const virtualRef = React14.useRef({
|
|
getBoundingClientRect: () => DOMRect.fromRect({ width: 0, height: 0, ...pointRef.current })
|
|
});
|
|
const longPressTimerRef = React14.useRef(0);
|
|
const clearLongPress = React14.useCallback(
|
|
() => window.clearTimeout(longPressTimerRef.current),
|
|
[]
|
|
);
|
|
const handleOpen = (event) => {
|
|
pointRef.current = { x: event.clientX, y: event.clientY };
|
|
context.onOpenChange(true);
|
|
};
|
|
React14.useEffect(() => clearLongPress, [clearLongPress]);
|
|
React14.useEffect(() => void (disabled && clearLongPress()), [disabled, clearLongPress]);
|
|
return (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
(0, import_jsx_runtime14.jsx)(Anchor2, { ...menuScope, virtualRef }),
|
|
(0, import_jsx_runtime14.jsx)(
|
|
Primitive.span,
|
|
{
|
|
"data-state": context.open ? "open" : "closed",
|
|
"data-disabled": disabled ? "" : void 0,
|
|
...triggerProps,
|
|
ref: forwardedRef,
|
|
style: { WebkitTouchCallout: "none", ...props.style },
|
|
onContextMenu: disabled ? props.onContextMenu : composeEventHandlers(props.onContextMenu, (event) => {
|
|
clearLongPress();
|
|
handleOpen(event);
|
|
event.preventDefault();
|
|
}),
|
|
onPointerDown: disabled ? props.onPointerDown : composeEventHandlers(
|
|
props.onPointerDown,
|
|
whenTouchOrPen((event) => {
|
|
clearLongPress();
|
|
longPressTimerRef.current = window.setTimeout(() => handleOpen(event), 700);
|
|
})
|
|
),
|
|
onPointerMove: disabled ? props.onPointerMove : composeEventHandlers(props.onPointerMove, whenTouchOrPen(clearLongPress)),
|
|
onPointerCancel: disabled ? props.onPointerCancel : composeEventHandlers(props.onPointerCancel, whenTouchOrPen(clearLongPress)),
|
|
onPointerUp: disabled ? props.onPointerUp : composeEventHandlers(props.onPointerUp, whenTouchOrPen(clearLongPress))
|
|
}
|
|
)
|
|
] });
|
|
}
|
|
);
|
|
ContextMenuTrigger.displayName = TRIGGER_NAME5;
|
|
var PORTAL_NAME3 = "ContextMenuPortal";
|
|
var ContextMenuPortal = (props) => {
|
|
const { __scopeContextMenu, ...portalProps } = props;
|
|
const menuScope = useMenuScope(__scopeContextMenu);
|
|
return (0, import_jsx_runtime14.jsx)(Portal3, { ...menuScope, ...portalProps });
|
|
};
|
|
ContextMenuPortal.displayName = PORTAL_NAME3;
|
|
var CONTENT_NAME5 = "ContextMenuContent";
|
|
var ContextMenuContent = React14.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeContextMenu, ...contentProps } = props;
|
|
const context = useContextMenuContext(CONTENT_NAME5, __scopeContextMenu);
|
|
const menuScope = useMenuScope(__scopeContextMenu);
|
|
const hasInteractedOutsideRef = React14.useRef(false);
|
|
return (0, import_jsx_runtime14.jsx)(
|
|
Content24,
|
|
{
|
|
...menuScope,
|
|
...contentProps,
|
|
ref: forwardedRef,
|
|
side: "right",
|
|
sideOffset: 2,
|
|
align: "start",
|
|
onCloseAutoFocus: (event) => {
|
|
var _a2;
|
|
(_a2 = props.onCloseAutoFocus) == null ? void 0 : _a2.call(props, event);
|
|
if (!event.defaultPrevented && hasInteractedOutsideRef.current) {
|
|
event.preventDefault();
|
|
}
|
|
hasInteractedOutsideRef.current = false;
|
|
},
|
|
onInteractOutside: (event) => {
|
|
var _a2;
|
|
(_a2 = props.onInteractOutside) == null ? void 0 : _a2.call(props, event);
|
|
if (!event.defaultPrevented && !context.modal) hasInteractedOutsideRef.current = true;
|
|
},
|
|
style: {
|
|
...props.style,
|
|
// re-namespace exposed content custom properties
|
|
...{
|
|
"--radix-context-menu-content-transform-origin": "var(--radix-popper-transform-origin)",
|
|
"--radix-context-menu-content-available-width": "var(--radix-popper-available-width)",
|
|
"--radix-context-menu-content-available-height": "var(--radix-popper-available-height)",
|
|
"--radix-context-menu-trigger-width": "var(--radix-popper-anchor-width)",
|
|
"--radix-context-menu-trigger-height": "var(--radix-popper-anchor-height)"
|
|
}
|
|
}
|
|
}
|
|
);
|
|
}
|
|
);
|
|
ContextMenuContent.displayName = CONTENT_NAME5;
|
|
var GROUP_NAME3 = "ContextMenuGroup";
|
|
var ContextMenuGroup = React14.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeContextMenu, ...groupProps } = props;
|
|
const menuScope = useMenuScope(__scopeContextMenu);
|
|
return (0, import_jsx_runtime14.jsx)(Group, { ...menuScope, ...groupProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
ContextMenuGroup.displayName = GROUP_NAME3;
|
|
var LABEL_NAME2 = "ContextMenuLabel";
|
|
var ContextMenuLabel = React14.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeContextMenu, ...labelProps } = props;
|
|
const menuScope = useMenuScope(__scopeContextMenu);
|
|
return (0, import_jsx_runtime14.jsx)(Label, { ...menuScope, ...labelProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
ContextMenuLabel.displayName = LABEL_NAME2;
|
|
var ITEM_NAME4 = "ContextMenuItem";
|
|
var ContextMenuItem = React14.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeContextMenu, ...itemProps } = props;
|
|
const menuScope = useMenuScope(__scopeContextMenu);
|
|
return (0, import_jsx_runtime14.jsx)(Item22, { ...menuScope, ...itemProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
ContextMenuItem.displayName = ITEM_NAME4;
|
|
var CHECKBOX_ITEM_NAME2 = "ContextMenuCheckboxItem";
|
|
var ContextMenuCheckboxItem = React14.forwardRef((props, forwardedRef) => {
|
|
const { __scopeContextMenu, ...checkboxItemProps } = props;
|
|
const menuScope = useMenuScope(__scopeContextMenu);
|
|
return (0, import_jsx_runtime14.jsx)(CheckboxItem, { ...menuScope, ...checkboxItemProps, ref: forwardedRef });
|
|
});
|
|
ContextMenuCheckboxItem.displayName = CHECKBOX_ITEM_NAME2;
|
|
var RADIO_GROUP_NAME2 = "ContextMenuRadioGroup";
|
|
var ContextMenuRadioGroup = React14.forwardRef((props, forwardedRef) => {
|
|
const { __scopeContextMenu, ...radioGroupProps } = props;
|
|
const menuScope = useMenuScope(__scopeContextMenu);
|
|
return (0, import_jsx_runtime14.jsx)(RadioGroup, { ...menuScope, ...radioGroupProps, ref: forwardedRef });
|
|
});
|
|
ContextMenuRadioGroup.displayName = RADIO_GROUP_NAME2;
|
|
var RADIO_ITEM_NAME2 = "ContextMenuRadioItem";
|
|
var ContextMenuRadioItem = React14.forwardRef((props, forwardedRef) => {
|
|
const { __scopeContextMenu, ...radioItemProps } = props;
|
|
const menuScope = useMenuScope(__scopeContextMenu);
|
|
return (0, import_jsx_runtime14.jsx)(RadioItem, { ...menuScope, ...radioItemProps, ref: forwardedRef });
|
|
});
|
|
ContextMenuRadioItem.displayName = RADIO_ITEM_NAME2;
|
|
var INDICATOR_NAME2 = "ContextMenuItemIndicator";
|
|
var ContextMenuItemIndicator = React14.forwardRef((props, forwardedRef) => {
|
|
const { __scopeContextMenu, ...itemIndicatorProps } = props;
|
|
const menuScope = useMenuScope(__scopeContextMenu);
|
|
return (0, import_jsx_runtime14.jsx)(ItemIndicator, { ...menuScope, ...itemIndicatorProps, ref: forwardedRef });
|
|
});
|
|
ContextMenuItemIndicator.displayName = INDICATOR_NAME2;
|
|
var SEPARATOR_NAME2 = "ContextMenuSeparator";
|
|
var ContextMenuSeparator = React14.forwardRef((props, forwardedRef) => {
|
|
const { __scopeContextMenu, ...separatorProps } = props;
|
|
const menuScope = useMenuScope(__scopeContextMenu);
|
|
return (0, import_jsx_runtime14.jsx)(Separator, { ...menuScope, ...separatorProps, ref: forwardedRef });
|
|
});
|
|
ContextMenuSeparator.displayName = SEPARATOR_NAME2;
|
|
var ARROW_NAME2 = "ContextMenuArrow";
|
|
var ContextMenuArrow = React14.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeContextMenu, ...arrowProps } = props;
|
|
const menuScope = useMenuScope(__scopeContextMenu);
|
|
return (0, import_jsx_runtime14.jsx)(Arrow2, { ...menuScope, ...arrowProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
ContextMenuArrow.displayName = ARROW_NAME2;
|
|
var SUB_NAME2 = "ContextMenuSub";
|
|
var ContextMenuSub = (props) => {
|
|
const { __scopeContextMenu, children, onOpenChange, open: openProp, defaultOpen } = props;
|
|
const menuScope = useMenuScope(__scopeContextMenu);
|
|
const [open, setOpen] = useControllableState({
|
|
prop: openProp,
|
|
defaultProp: defaultOpen ?? false,
|
|
onChange: onOpenChange,
|
|
caller: SUB_NAME2
|
|
});
|
|
return (0, import_jsx_runtime14.jsx)(Sub, { ...menuScope, open, onOpenChange: setOpen, children });
|
|
};
|
|
ContextMenuSub.displayName = SUB_NAME2;
|
|
var SUB_TRIGGER_NAME2 = "ContextMenuSubTrigger";
|
|
var ContextMenuSubTrigger = React14.forwardRef((props, forwardedRef) => {
|
|
const { __scopeContextMenu, ...triggerItemProps } = props;
|
|
const menuScope = useMenuScope(__scopeContextMenu);
|
|
return (0, import_jsx_runtime14.jsx)(SubTrigger, { ...menuScope, ...triggerItemProps, ref: forwardedRef });
|
|
});
|
|
ContextMenuSubTrigger.displayName = SUB_TRIGGER_NAME2;
|
|
var SUB_CONTENT_NAME2 = "ContextMenuSubContent";
|
|
var ContextMenuSubContent = React14.forwardRef((props, forwardedRef) => {
|
|
const { __scopeContextMenu, ...subContentProps } = props;
|
|
const menuScope = useMenuScope(__scopeContextMenu);
|
|
return (0, import_jsx_runtime14.jsx)(
|
|
SubContent,
|
|
{
|
|
...menuScope,
|
|
...subContentProps,
|
|
ref: forwardedRef,
|
|
style: {
|
|
...props.style,
|
|
// re-namespace exposed content custom properties
|
|
...{
|
|
"--radix-context-menu-content-transform-origin": "var(--radix-popper-transform-origin)",
|
|
"--radix-context-menu-content-available-width": "var(--radix-popper-available-width)",
|
|
"--radix-context-menu-content-available-height": "var(--radix-popper-available-height)",
|
|
"--radix-context-menu-trigger-width": "var(--radix-popper-anchor-width)",
|
|
"--radix-context-menu-trigger-height": "var(--radix-popper-anchor-height)"
|
|
}
|
|
}
|
|
}
|
|
);
|
|
});
|
|
ContextMenuSubContent.displayName = SUB_CONTENT_NAME2;
|
|
function whenTouchOrPen(handler) {
|
|
return (event) => event.pointerType !== "mouse" ? handler(event) : void 0;
|
|
}
|
|
var Root26 = ContextMenu;
|
|
var Trigger3 = ContextMenuTrigger;
|
|
var Portal23 = ContextMenuPortal;
|
|
var Content25 = ContextMenuContent;
|
|
var Group2 = ContextMenuGroup;
|
|
var Label2 = ContextMenuLabel;
|
|
var Item23 = ContextMenuItem;
|
|
var CheckboxItem2 = ContextMenuCheckboxItem;
|
|
var RadioGroup2 = ContextMenuRadioGroup;
|
|
var RadioItem2 = ContextMenuRadioItem;
|
|
var ItemIndicator2 = ContextMenuItemIndicator;
|
|
var Separator2 = ContextMenuSeparator;
|
|
var Arrow22 = ContextMenuArrow;
|
|
var Sub2 = ContextMenuSub;
|
|
var SubTrigger2 = ContextMenuSubTrigger;
|
|
var SubContent2 = ContextMenuSubContent;
|
|
|
|
// ../../node_modules/@radix-ui/react-dropdown-menu/dist/index.mjs
|
|
var dist_exports18 = {};
|
|
__export(dist_exports18, {
|
|
Arrow: () => Arrow23,
|
|
CheckboxItem: () => CheckboxItem22,
|
|
Content: () => Content26,
|
|
DropdownMenu: () => DropdownMenu,
|
|
DropdownMenuArrow: () => DropdownMenuArrow,
|
|
DropdownMenuCheckboxItem: () => DropdownMenuCheckboxItem,
|
|
DropdownMenuContent: () => DropdownMenuContent,
|
|
DropdownMenuGroup: () => DropdownMenuGroup,
|
|
DropdownMenuItem: () => DropdownMenuItem,
|
|
DropdownMenuItemIndicator: () => DropdownMenuItemIndicator,
|
|
DropdownMenuLabel: () => DropdownMenuLabel,
|
|
DropdownMenuPortal: () => DropdownMenuPortal,
|
|
DropdownMenuRadioGroup: () => DropdownMenuRadioGroup,
|
|
DropdownMenuRadioItem: () => DropdownMenuRadioItem,
|
|
DropdownMenuSeparator: () => DropdownMenuSeparator,
|
|
DropdownMenuSub: () => DropdownMenuSub,
|
|
DropdownMenuSubContent: () => DropdownMenuSubContent,
|
|
DropdownMenuSubTrigger: () => DropdownMenuSubTrigger,
|
|
DropdownMenuTrigger: () => DropdownMenuTrigger,
|
|
Group: () => Group22,
|
|
Item: () => Item24,
|
|
ItemIndicator: () => ItemIndicator22,
|
|
Label: () => Label22,
|
|
Portal: () => Portal24,
|
|
RadioGroup: () => RadioGroup22,
|
|
RadioItem: () => RadioItem22,
|
|
Root: () => Root27,
|
|
Separator: () => Separator22,
|
|
Sub: () => Sub22,
|
|
SubContent: () => SubContent22,
|
|
SubTrigger: () => SubTrigger22,
|
|
Trigger: () => Trigger4,
|
|
createDropdownMenuScope: () => createDropdownMenuScope
|
|
});
|
|
var React15 = __toESM(require_react(), 1);
|
|
var import_jsx_runtime15 = __toESM(require_jsx_runtime(), 1);
|
|
var DROPDOWN_MENU_NAME = "DropdownMenu";
|
|
var [createDropdownMenuContext, createDropdownMenuScope] = createContextScope(
|
|
DROPDOWN_MENU_NAME,
|
|
[createMenuScope]
|
|
);
|
|
var useMenuScope2 = createMenuScope();
|
|
var [DropdownMenuProvider, useDropdownMenuContext] = createDropdownMenuContext(DROPDOWN_MENU_NAME);
|
|
var DropdownMenu = (props) => {
|
|
const {
|
|
__scopeDropdownMenu,
|
|
children,
|
|
dir,
|
|
open: openProp,
|
|
defaultOpen,
|
|
onOpenChange,
|
|
modal = true
|
|
} = props;
|
|
const menuScope = useMenuScope2(__scopeDropdownMenu);
|
|
const triggerRef = React15.useRef(null);
|
|
const [open, setOpen] = useControllableState({
|
|
prop: openProp,
|
|
defaultProp: defaultOpen ?? false,
|
|
onChange: onOpenChange,
|
|
caller: DROPDOWN_MENU_NAME
|
|
});
|
|
return (0, import_jsx_runtime15.jsx)(
|
|
DropdownMenuProvider,
|
|
{
|
|
scope: __scopeDropdownMenu,
|
|
triggerId: useId(),
|
|
triggerRef,
|
|
contentId: useId(),
|
|
open,
|
|
onOpenChange: setOpen,
|
|
onOpenToggle: React15.useCallback(() => setOpen((prevOpen) => !prevOpen), [setOpen]),
|
|
modal,
|
|
children: (0, import_jsx_runtime15.jsx)(Root32, { ...menuScope, open, onOpenChange: setOpen, dir, modal, children })
|
|
}
|
|
);
|
|
};
|
|
DropdownMenu.displayName = DROPDOWN_MENU_NAME;
|
|
var TRIGGER_NAME6 = "DropdownMenuTrigger";
|
|
var DropdownMenuTrigger = React15.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeDropdownMenu, disabled = false, ...triggerProps } = props;
|
|
const context = useDropdownMenuContext(TRIGGER_NAME6, __scopeDropdownMenu);
|
|
const menuScope = useMenuScope2(__scopeDropdownMenu);
|
|
return (0, import_jsx_runtime15.jsx)(Anchor2, { asChild: true, ...menuScope, children: (0, import_jsx_runtime15.jsx)(
|
|
Primitive.button,
|
|
{
|
|
type: "button",
|
|
id: context.triggerId,
|
|
"aria-haspopup": "menu",
|
|
"aria-expanded": context.open,
|
|
"aria-controls": context.open ? context.contentId : void 0,
|
|
"data-state": context.open ? "open" : "closed",
|
|
"data-disabled": disabled ? "" : void 0,
|
|
disabled,
|
|
...triggerProps,
|
|
ref: composeRefs(forwardedRef, context.triggerRef),
|
|
onPointerDown: composeEventHandlers(props.onPointerDown, (event) => {
|
|
if (!disabled && event.button === 0 && event.ctrlKey === false) {
|
|
context.onOpenToggle();
|
|
if (!context.open) event.preventDefault();
|
|
}
|
|
}),
|
|
onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
|
|
if (disabled) return;
|
|
if (["Enter", " "].includes(event.key)) context.onOpenToggle();
|
|
if (event.key === "ArrowDown") context.onOpenChange(true);
|
|
if (["Enter", " ", "ArrowDown"].includes(event.key)) event.preventDefault();
|
|
})
|
|
}
|
|
) });
|
|
}
|
|
);
|
|
DropdownMenuTrigger.displayName = TRIGGER_NAME6;
|
|
var PORTAL_NAME4 = "DropdownMenuPortal";
|
|
var DropdownMenuPortal = (props) => {
|
|
const { __scopeDropdownMenu, ...portalProps } = props;
|
|
const menuScope = useMenuScope2(__scopeDropdownMenu);
|
|
return (0, import_jsx_runtime15.jsx)(Portal3, { ...menuScope, ...portalProps });
|
|
};
|
|
DropdownMenuPortal.displayName = PORTAL_NAME4;
|
|
var CONTENT_NAME6 = "DropdownMenuContent";
|
|
var DropdownMenuContent = React15.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeDropdownMenu, ...contentProps } = props;
|
|
const context = useDropdownMenuContext(CONTENT_NAME6, __scopeDropdownMenu);
|
|
const menuScope = useMenuScope2(__scopeDropdownMenu);
|
|
const hasInteractedOutsideRef = React15.useRef(false);
|
|
return (0, import_jsx_runtime15.jsx)(
|
|
Content24,
|
|
{
|
|
id: context.contentId,
|
|
"aria-labelledby": context.triggerId,
|
|
...menuScope,
|
|
...contentProps,
|
|
ref: forwardedRef,
|
|
onCloseAutoFocus: composeEventHandlers(props.onCloseAutoFocus, (event) => {
|
|
var _a2;
|
|
if (!hasInteractedOutsideRef.current) (_a2 = context.triggerRef.current) == null ? void 0 : _a2.focus();
|
|
hasInteractedOutsideRef.current = false;
|
|
event.preventDefault();
|
|
}),
|
|
onInteractOutside: composeEventHandlers(props.onInteractOutside, (event) => {
|
|
const originalEvent = event.detail.originalEvent;
|
|
const ctrlLeftClick = originalEvent.button === 0 && originalEvent.ctrlKey === true;
|
|
const isRightClick = originalEvent.button === 2 || ctrlLeftClick;
|
|
if (!context.modal || isRightClick) hasInteractedOutsideRef.current = true;
|
|
}),
|
|
style: {
|
|
...props.style,
|
|
// re-namespace exposed content custom properties
|
|
...{
|
|
"--radix-dropdown-menu-content-transform-origin": "var(--radix-popper-transform-origin)",
|
|
"--radix-dropdown-menu-content-available-width": "var(--radix-popper-available-width)",
|
|
"--radix-dropdown-menu-content-available-height": "var(--radix-popper-available-height)",
|
|
"--radix-dropdown-menu-trigger-width": "var(--radix-popper-anchor-width)",
|
|
"--radix-dropdown-menu-trigger-height": "var(--radix-popper-anchor-height)"
|
|
}
|
|
}
|
|
}
|
|
);
|
|
}
|
|
);
|
|
DropdownMenuContent.displayName = CONTENT_NAME6;
|
|
var GROUP_NAME4 = "DropdownMenuGroup";
|
|
var DropdownMenuGroup = React15.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeDropdownMenu, ...groupProps } = props;
|
|
const menuScope = useMenuScope2(__scopeDropdownMenu);
|
|
return (0, import_jsx_runtime15.jsx)(Group, { ...menuScope, ...groupProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
DropdownMenuGroup.displayName = GROUP_NAME4;
|
|
var LABEL_NAME3 = "DropdownMenuLabel";
|
|
var DropdownMenuLabel = React15.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeDropdownMenu, ...labelProps } = props;
|
|
const menuScope = useMenuScope2(__scopeDropdownMenu);
|
|
return (0, import_jsx_runtime15.jsx)(Label, { ...menuScope, ...labelProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
DropdownMenuLabel.displayName = LABEL_NAME3;
|
|
var ITEM_NAME5 = "DropdownMenuItem";
|
|
var DropdownMenuItem = React15.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeDropdownMenu, ...itemProps } = props;
|
|
const menuScope = useMenuScope2(__scopeDropdownMenu);
|
|
return (0, import_jsx_runtime15.jsx)(Item22, { ...menuScope, ...itemProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
DropdownMenuItem.displayName = ITEM_NAME5;
|
|
var CHECKBOX_ITEM_NAME3 = "DropdownMenuCheckboxItem";
|
|
var DropdownMenuCheckboxItem = React15.forwardRef((props, forwardedRef) => {
|
|
const { __scopeDropdownMenu, ...checkboxItemProps } = props;
|
|
const menuScope = useMenuScope2(__scopeDropdownMenu);
|
|
return (0, import_jsx_runtime15.jsx)(CheckboxItem, { ...menuScope, ...checkboxItemProps, ref: forwardedRef });
|
|
});
|
|
DropdownMenuCheckboxItem.displayName = CHECKBOX_ITEM_NAME3;
|
|
var RADIO_GROUP_NAME3 = "DropdownMenuRadioGroup";
|
|
var DropdownMenuRadioGroup = React15.forwardRef((props, forwardedRef) => {
|
|
const { __scopeDropdownMenu, ...radioGroupProps } = props;
|
|
const menuScope = useMenuScope2(__scopeDropdownMenu);
|
|
return (0, import_jsx_runtime15.jsx)(RadioGroup, { ...menuScope, ...radioGroupProps, ref: forwardedRef });
|
|
});
|
|
DropdownMenuRadioGroup.displayName = RADIO_GROUP_NAME3;
|
|
var RADIO_ITEM_NAME3 = "DropdownMenuRadioItem";
|
|
var DropdownMenuRadioItem = React15.forwardRef((props, forwardedRef) => {
|
|
const { __scopeDropdownMenu, ...radioItemProps } = props;
|
|
const menuScope = useMenuScope2(__scopeDropdownMenu);
|
|
return (0, import_jsx_runtime15.jsx)(RadioItem, { ...menuScope, ...radioItemProps, ref: forwardedRef });
|
|
});
|
|
DropdownMenuRadioItem.displayName = RADIO_ITEM_NAME3;
|
|
var INDICATOR_NAME3 = "DropdownMenuItemIndicator";
|
|
var DropdownMenuItemIndicator = React15.forwardRef((props, forwardedRef) => {
|
|
const { __scopeDropdownMenu, ...itemIndicatorProps } = props;
|
|
const menuScope = useMenuScope2(__scopeDropdownMenu);
|
|
return (0, import_jsx_runtime15.jsx)(ItemIndicator, { ...menuScope, ...itemIndicatorProps, ref: forwardedRef });
|
|
});
|
|
DropdownMenuItemIndicator.displayName = INDICATOR_NAME3;
|
|
var SEPARATOR_NAME3 = "DropdownMenuSeparator";
|
|
var DropdownMenuSeparator = React15.forwardRef((props, forwardedRef) => {
|
|
const { __scopeDropdownMenu, ...separatorProps } = props;
|
|
const menuScope = useMenuScope2(__scopeDropdownMenu);
|
|
return (0, import_jsx_runtime15.jsx)(Separator, { ...menuScope, ...separatorProps, ref: forwardedRef });
|
|
});
|
|
DropdownMenuSeparator.displayName = SEPARATOR_NAME3;
|
|
var ARROW_NAME3 = "DropdownMenuArrow";
|
|
var DropdownMenuArrow = React15.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeDropdownMenu, ...arrowProps } = props;
|
|
const menuScope = useMenuScope2(__scopeDropdownMenu);
|
|
return (0, import_jsx_runtime15.jsx)(Arrow2, { ...menuScope, ...arrowProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
DropdownMenuArrow.displayName = ARROW_NAME3;
|
|
var DropdownMenuSub = (props) => {
|
|
const { __scopeDropdownMenu, children, open: openProp, onOpenChange, defaultOpen } = props;
|
|
const menuScope = useMenuScope2(__scopeDropdownMenu);
|
|
const [open, setOpen] = useControllableState({
|
|
prop: openProp,
|
|
defaultProp: defaultOpen ?? false,
|
|
onChange: onOpenChange,
|
|
caller: "DropdownMenuSub"
|
|
});
|
|
return (0, import_jsx_runtime15.jsx)(Sub, { ...menuScope, open, onOpenChange: setOpen, children });
|
|
};
|
|
var SUB_TRIGGER_NAME3 = "DropdownMenuSubTrigger";
|
|
var DropdownMenuSubTrigger = React15.forwardRef((props, forwardedRef) => {
|
|
const { __scopeDropdownMenu, ...subTriggerProps } = props;
|
|
const menuScope = useMenuScope2(__scopeDropdownMenu);
|
|
return (0, import_jsx_runtime15.jsx)(SubTrigger, { ...menuScope, ...subTriggerProps, ref: forwardedRef });
|
|
});
|
|
DropdownMenuSubTrigger.displayName = SUB_TRIGGER_NAME3;
|
|
var SUB_CONTENT_NAME3 = "DropdownMenuSubContent";
|
|
var DropdownMenuSubContent = React15.forwardRef((props, forwardedRef) => {
|
|
const { __scopeDropdownMenu, ...subContentProps } = props;
|
|
const menuScope = useMenuScope2(__scopeDropdownMenu);
|
|
return (0, import_jsx_runtime15.jsx)(
|
|
SubContent,
|
|
{
|
|
...menuScope,
|
|
...subContentProps,
|
|
ref: forwardedRef,
|
|
style: {
|
|
...props.style,
|
|
// re-namespace exposed content custom properties
|
|
...{
|
|
"--radix-dropdown-menu-content-transform-origin": "var(--radix-popper-transform-origin)",
|
|
"--radix-dropdown-menu-content-available-width": "var(--radix-popper-available-width)",
|
|
"--radix-dropdown-menu-content-available-height": "var(--radix-popper-available-height)",
|
|
"--radix-dropdown-menu-trigger-width": "var(--radix-popper-anchor-width)",
|
|
"--radix-dropdown-menu-trigger-height": "var(--radix-popper-anchor-height)"
|
|
}
|
|
}
|
|
}
|
|
);
|
|
});
|
|
DropdownMenuSubContent.displayName = SUB_CONTENT_NAME3;
|
|
var Root27 = DropdownMenu;
|
|
var Trigger4 = DropdownMenuTrigger;
|
|
var Portal24 = DropdownMenuPortal;
|
|
var Content26 = DropdownMenuContent;
|
|
var Group22 = DropdownMenuGroup;
|
|
var Label22 = DropdownMenuLabel;
|
|
var Item24 = DropdownMenuItem;
|
|
var CheckboxItem22 = DropdownMenuCheckboxItem;
|
|
var RadioGroup22 = DropdownMenuRadioGroup;
|
|
var RadioItem22 = DropdownMenuRadioItem;
|
|
var ItemIndicator22 = DropdownMenuItemIndicator;
|
|
var Separator22 = DropdownMenuSeparator;
|
|
var Arrow23 = DropdownMenuArrow;
|
|
var Sub22 = DropdownMenuSub;
|
|
var SubTrigger22 = DropdownMenuSubTrigger;
|
|
var SubContent22 = DropdownMenuSubContent;
|
|
|
|
// ../../node_modules/@radix-ui/react-form/dist/index.mjs
|
|
var dist_exports20 = {};
|
|
__export(dist_exports20, {
|
|
Control: () => Control,
|
|
Field: () => Field,
|
|
Form: () => Form,
|
|
FormControl: () => FormControl,
|
|
FormField: () => FormField,
|
|
FormLabel: () => FormLabel,
|
|
FormMessage: () => FormMessage,
|
|
FormSubmit: () => FormSubmit,
|
|
FormValidityState: () => FormValidityState,
|
|
Label: () => Label4,
|
|
Message: () => Message,
|
|
Root: () => Root10,
|
|
Submit: () => Submit,
|
|
ValidityState: () => ValidityState,
|
|
createFormScope: () => createFormScope
|
|
});
|
|
var React17 = __toESM(require_react(), 1);
|
|
|
|
// ../../node_modules/@radix-ui/react-label/dist/index.mjs
|
|
var dist_exports19 = {};
|
|
__export(dist_exports19, {
|
|
Label: () => Label3,
|
|
Root: () => Root9
|
|
});
|
|
var React16 = __toESM(require_react(), 1);
|
|
var import_jsx_runtime16 = __toESM(require_jsx_runtime(), 1);
|
|
var NAME4 = "Label";
|
|
var Label3 = React16.forwardRef((props, forwardedRef) => {
|
|
return (0, import_jsx_runtime16.jsx)(
|
|
Primitive.label,
|
|
{
|
|
...props,
|
|
ref: forwardedRef,
|
|
onMouseDown: (event) => {
|
|
var _a2;
|
|
const target = event.target;
|
|
if (target.closest("button, input, select, textarea")) return;
|
|
(_a2 = props.onMouseDown) == null ? void 0 : _a2.call(props, event);
|
|
if (!event.defaultPrevented && event.detail > 1) event.preventDefault();
|
|
}
|
|
}
|
|
);
|
|
});
|
|
Label3.displayName = NAME4;
|
|
var Root9 = Label3;
|
|
|
|
// ../../node_modules/@radix-ui/react-form/dist/index.mjs
|
|
var import_jsx_runtime17 = __toESM(require_jsx_runtime(), 1);
|
|
var [createFormContext, createFormScope] = createContextScope("Form");
|
|
var FORM_NAME = "Form";
|
|
var [ValidationProvider, useValidationContext] = createFormContext(FORM_NAME);
|
|
var [AriaDescriptionProvider, useAriaDescriptionContext] = createFormContext(FORM_NAME);
|
|
var Form = React17.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeForm, onClearServerErrors = () => {
|
|
}, ...rootProps } = props;
|
|
const formRef = React17.useRef(null);
|
|
const composedFormRef = useComposedRefs(forwardedRef, formRef);
|
|
const [validityMap, setValidityMap] = React17.useState({});
|
|
const getFieldValidity = React17.useCallback(
|
|
(fieldName) => validityMap[fieldName],
|
|
[validityMap]
|
|
);
|
|
const handleFieldValidityChange = React17.useCallback(
|
|
(fieldName, validity) => setValidityMap((prevValidityMap) => ({
|
|
...prevValidityMap,
|
|
[fieldName]: { ...prevValidityMap[fieldName] ?? {}, ...validity }
|
|
})),
|
|
[]
|
|
);
|
|
const handleFieldValiditionClear = React17.useCallback((fieldName) => {
|
|
setValidityMap((prevValidityMap) => ({ ...prevValidityMap, [fieldName]: void 0 }));
|
|
setCustomErrorsMap((prevCustomErrorsMap) => ({ ...prevCustomErrorsMap, [fieldName]: {} }));
|
|
}, []);
|
|
const [customMatcherEntriesMap, setCustomMatcherEntriesMap] = React17.useState({});
|
|
const getFieldCustomMatcherEntries = React17.useCallback(
|
|
(fieldName) => customMatcherEntriesMap[fieldName] ?? [],
|
|
[customMatcherEntriesMap]
|
|
);
|
|
const handleFieldCustomMatcherAdd = React17.useCallback((fieldName, matcherEntry) => {
|
|
setCustomMatcherEntriesMap((prevCustomMatcherEntriesMap) => ({
|
|
...prevCustomMatcherEntriesMap,
|
|
[fieldName]: [...prevCustomMatcherEntriesMap[fieldName] ?? [], matcherEntry]
|
|
}));
|
|
}, []);
|
|
const handleFieldCustomMatcherRemove = React17.useCallback((fieldName, matcherEntryId) => {
|
|
setCustomMatcherEntriesMap((prevCustomMatcherEntriesMap) => ({
|
|
...prevCustomMatcherEntriesMap,
|
|
[fieldName]: (prevCustomMatcherEntriesMap[fieldName] ?? []).filter(
|
|
(matcherEntry) => matcherEntry.id !== matcherEntryId
|
|
)
|
|
}));
|
|
}, []);
|
|
const [customErrorsMap, setCustomErrorsMap] = React17.useState({});
|
|
const getFieldCustomErrors = React17.useCallback(
|
|
(fieldName) => customErrorsMap[fieldName] ?? {},
|
|
[customErrorsMap]
|
|
);
|
|
const handleFieldCustomErrorsChange = React17.useCallback((fieldName, customErrors) => {
|
|
setCustomErrorsMap((prevCustomErrorsMap) => ({
|
|
...prevCustomErrorsMap,
|
|
[fieldName]: { ...prevCustomErrorsMap[fieldName] ?? {}, ...customErrors }
|
|
}));
|
|
}, []);
|
|
const [messageIdsMap, setMessageIdsMap] = React17.useState({});
|
|
const handleFieldMessageIdAdd = React17.useCallback((fieldName, id) => {
|
|
setMessageIdsMap((prevMessageIdsMap) => {
|
|
const fieldDescriptionIds = new Set(prevMessageIdsMap[fieldName]).add(id);
|
|
return { ...prevMessageIdsMap, [fieldName]: fieldDescriptionIds };
|
|
});
|
|
}, []);
|
|
const handleFieldMessageIdRemove = React17.useCallback((fieldName, id) => {
|
|
setMessageIdsMap((prevMessageIdsMap) => {
|
|
const fieldDescriptionIds = new Set(prevMessageIdsMap[fieldName]);
|
|
fieldDescriptionIds.delete(id);
|
|
return { ...prevMessageIdsMap, [fieldName]: fieldDescriptionIds };
|
|
});
|
|
}, []);
|
|
const getFieldDescription = React17.useCallback(
|
|
(fieldName) => Array.from(messageIdsMap[fieldName] ?? []).join(" ") || void 0,
|
|
[messageIdsMap]
|
|
);
|
|
return (0, import_jsx_runtime17.jsx)(
|
|
ValidationProvider,
|
|
{
|
|
scope: __scopeForm,
|
|
getFieldValidity,
|
|
onFieldValidityChange: handleFieldValidityChange,
|
|
getFieldCustomMatcherEntries,
|
|
onFieldCustomMatcherEntryAdd: handleFieldCustomMatcherAdd,
|
|
onFieldCustomMatcherEntryRemove: handleFieldCustomMatcherRemove,
|
|
getFieldCustomErrors,
|
|
onFieldCustomErrorsChange: handleFieldCustomErrorsChange,
|
|
onFieldValiditionClear: handleFieldValiditionClear,
|
|
children: (0, import_jsx_runtime17.jsx)(
|
|
AriaDescriptionProvider,
|
|
{
|
|
scope: __scopeForm,
|
|
onFieldMessageIdAdd: handleFieldMessageIdAdd,
|
|
onFieldMessageIdRemove: handleFieldMessageIdRemove,
|
|
getFieldDescription,
|
|
children: (0, import_jsx_runtime17.jsx)(
|
|
Primitive.form,
|
|
{
|
|
...rootProps,
|
|
ref: composedFormRef,
|
|
onInvalid: composeEventHandlers(props.onInvalid, (event) => {
|
|
const firstInvalidControl = getFirstInvalidControl(event.currentTarget);
|
|
if (firstInvalidControl === event.target) firstInvalidControl.focus();
|
|
event.preventDefault();
|
|
}),
|
|
onSubmit: composeEventHandlers(props.onSubmit, onClearServerErrors, {
|
|
checkForDefaultPrevented: false
|
|
}),
|
|
onReset: composeEventHandlers(props.onReset, onClearServerErrors)
|
|
}
|
|
)
|
|
}
|
|
)
|
|
}
|
|
);
|
|
}
|
|
);
|
|
Form.displayName = FORM_NAME;
|
|
var FIELD_NAME = "FormField";
|
|
var [FormFieldProvider, useFormFieldContext] = createFormContext(FIELD_NAME);
|
|
var FormField = React17.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeForm, name, serverInvalid = false, ...fieldProps } = props;
|
|
const validationContext = useValidationContext(FIELD_NAME, __scopeForm);
|
|
const validity = validationContext.getFieldValidity(name);
|
|
const id = useId();
|
|
return (0, import_jsx_runtime17.jsx)(FormFieldProvider, { scope: __scopeForm, id, name, serverInvalid, children: (0, import_jsx_runtime17.jsx)(
|
|
Primitive.div,
|
|
{
|
|
"data-valid": getValidAttribute(validity, serverInvalid),
|
|
"data-invalid": getInvalidAttribute(validity, serverInvalid),
|
|
...fieldProps,
|
|
ref: forwardedRef
|
|
}
|
|
) });
|
|
}
|
|
);
|
|
FormField.displayName = FIELD_NAME;
|
|
var LABEL_NAME4 = "FormLabel";
|
|
var FormLabel = React17.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeForm, ...labelProps } = props;
|
|
const validationContext = useValidationContext(LABEL_NAME4, __scopeForm);
|
|
const fieldContext = useFormFieldContext(LABEL_NAME4, __scopeForm);
|
|
const htmlFor = labelProps.htmlFor || fieldContext.id;
|
|
const validity = validationContext.getFieldValidity(fieldContext.name);
|
|
return (0, import_jsx_runtime17.jsx)(
|
|
Label3,
|
|
{
|
|
"data-valid": getValidAttribute(validity, fieldContext.serverInvalid),
|
|
"data-invalid": getInvalidAttribute(validity, fieldContext.serverInvalid),
|
|
...labelProps,
|
|
ref: forwardedRef,
|
|
htmlFor
|
|
}
|
|
);
|
|
}
|
|
);
|
|
FormLabel.displayName = LABEL_NAME4;
|
|
var CONTROL_NAME = "FormControl";
|
|
var FormControl = React17.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeForm, ...controlProps } = props;
|
|
const validationContext = useValidationContext(CONTROL_NAME, __scopeForm);
|
|
const fieldContext = useFormFieldContext(CONTROL_NAME, __scopeForm);
|
|
const ariaDescriptionContext = useAriaDescriptionContext(CONTROL_NAME, __scopeForm);
|
|
const ref = React17.useRef(null);
|
|
const composedRef = useComposedRefs(forwardedRef, ref);
|
|
const name = controlProps.name || fieldContext.name;
|
|
const id = controlProps.id || fieldContext.id;
|
|
const customMatcherEntries = validationContext.getFieldCustomMatcherEntries(name);
|
|
const { onFieldValidityChange, onFieldCustomErrorsChange, onFieldValiditionClear } = validationContext;
|
|
const updateControlValidity = React17.useCallback(
|
|
async (control) => {
|
|
if (hasBuiltInError(control.validity)) {
|
|
const controlValidity2 = validityStateToObject(control.validity);
|
|
onFieldValidityChange(name, controlValidity2);
|
|
return;
|
|
}
|
|
const formData = control.form ? new FormData(control.form) : new FormData();
|
|
const matcherArgs = [control.value, formData];
|
|
const syncCustomMatcherEntries = [];
|
|
const ayncCustomMatcherEntries = [];
|
|
customMatcherEntries.forEach((customMatcherEntry) => {
|
|
if (isAsyncCustomMatcherEntry(customMatcherEntry, matcherArgs)) {
|
|
ayncCustomMatcherEntries.push(customMatcherEntry);
|
|
} else if (isSyncCustomMatcherEntry(customMatcherEntry)) {
|
|
syncCustomMatcherEntries.push(customMatcherEntry);
|
|
}
|
|
});
|
|
const syncCustomErrors = syncCustomMatcherEntries.map(({ id: id2, match }) => {
|
|
return [id2, match(...matcherArgs)];
|
|
});
|
|
const syncCustomErrorsById = Object.fromEntries(syncCustomErrors);
|
|
const hasSyncCustomErrors = Object.values(syncCustomErrorsById).some(Boolean);
|
|
const hasCustomError = hasSyncCustomErrors;
|
|
control.setCustomValidity(hasCustomError ? DEFAULT_INVALID_MESSAGE : "");
|
|
const controlValidity = validityStateToObject(control.validity);
|
|
onFieldValidityChange(name, controlValidity);
|
|
onFieldCustomErrorsChange(name, syncCustomErrorsById);
|
|
if (!hasSyncCustomErrors && ayncCustomMatcherEntries.length > 0) {
|
|
const promisedCustomErrors = ayncCustomMatcherEntries.map(
|
|
({ id: id2, match }) => match(...matcherArgs).then((matches) => [id2, matches])
|
|
);
|
|
const asyncCustomErrors = await Promise.all(promisedCustomErrors);
|
|
const asyncCustomErrorsById = Object.fromEntries(asyncCustomErrors);
|
|
const hasAsyncCustomErrors = Object.values(asyncCustomErrorsById).some(Boolean);
|
|
const hasCustomError2 = hasAsyncCustomErrors;
|
|
control.setCustomValidity(hasCustomError2 ? DEFAULT_INVALID_MESSAGE : "");
|
|
const controlValidity2 = validityStateToObject(control.validity);
|
|
onFieldValidityChange(name, controlValidity2);
|
|
onFieldCustomErrorsChange(name, asyncCustomErrorsById);
|
|
}
|
|
},
|
|
[customMatcherEntries, name, onFieldCustomErrorsChange, onFieldValidityChange]
|
|
);
|
|
React17.useEffect(() => {
|
|
const control = ref.current;
|
|
if (control) {
|
|
const handleChange = () => updateControlValidity(control);
|
|
control.addEventListener("change", handleChange);
|
|
return () => control.removeEventListener("change", handleChange);
|
|
}
|
|
}, [updateControlValidity]);
|
|
const resetControlValidity = React17.useCallback(() => {
|
|
const control = ref.current;
|
|
if (control) {
|
|
control.setCustomValidity("");
|
|
onFieldValiditionClear(name);
|
|
}
|
|
}, [name, onFieldValiditionClear]);
|
|
React17.useEffect(() => {
|
|
var _a2;
|
|
const form = (_a2 = ref.current) == null ? void 0 : _a2.form;
|
|
if (form) {
|
|
form.addEventListener("reset", resetControlValidity);
|
|
return () => form.removeEventListener("reset", resetControlValidity);
|
|
}
|
|
}, [resetControlValidity]);
|
|
React17.useEffect(() => {
|
|
const control = ref.current;
|
|
const form = control == null ? void 0 : control.closest("form");
|
|
if (form && fieldContext.serverInvalid) {
|
|
const firstInvalidControl = getFirstInvalidControl(form);
|
|
if (firstInvalidControl === control) firstInvalidControl.focus();
|
|
}
|
|
}, [fieldContext.serverInvalid]);
|
|
const validity = validationContext.getFieldValidity(name);
|
|
return (0, import_jsx_runtime17.jsx)(
|
|
Primitive.input,
|
|
{
|
|
"data-valid": getValidAttribute(validity, fieldContext.serverInvalid),
|
|
"data-invalid": getInvalidAttribute(validity, fieldContext.serverInvalid),
|
|
"aria-invalid": fieldContext.serverInvalid ? true : void 0,
|
|
"aria-describedby": ariaDescriptionContext.getFieldDescription(name),
|
|
title: "",
|
|
...controlProps,
|
|
ref: composedRef,
|
|
id,
|
|
name,
|
|
onInvalid: composeEventHandlers(props.onInvalid, (event) => {
|
|
const control = event.currentTarget;
|
|
updateControlValidity(control);
|
|
}),
|
|
onChange: composeEventHandlers(props.onChange, (_event) => {
|
|
resetControlValidity();
|
|
})
|
|
}
|
|
);
|
|
}
|
|
);
|
|
FormControl.displayName = CONTROL_NAME;
|
|
var DEFAULT_INVALID_MESSAGE = "This value is not valid";
|
|
var DEFAULT_BUILT_IN_MESSAGES = {
|
|
badInput: DEFAULT_INVALID_MESSAGE,
|
|
patternMismatch: "This value does not match the required pattern",
|
|
rangeOverflow: "This value is too large",
|
|
rangeUnderflow: "This value is too small",
|
|
stepMismatch: "This value does not match the required step",
|
|
tooLong: "This value is too long",
|
|
tooShort: "This value is too short",
|
|
typeMismatch: "This value does not match the required type",
|
|
valid: void 0,
|
|
valueMissing: "This value is missing"
|
|
};
|
|
var MESSAGE_NAME = "FormMessage";
|
|
var FormMessage = React17.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { match, name: nameProp, ...messageProps } = props;
|
|
const fieldContext = useFormFieldContext(MESSAGE_NAME, props.__scopeForm);
|
|
const name = nameProp ?? fieldContext.name;
|
|
if (match === void 0) {
|
|
return (0, import_jsx_runtime17.jsx)(FormMessageImpl, { ...messageProps, ref: forwardedRef, name, children: props.children || DEFAULT_INVALID_MESSAGE });
|
|
} else if (typeof match === "function") {
|
|
return (0, import_jsx_runtime17.jsx)(FormCustomMessage, { match, ...messageProps, ref: forwardedRef, name });
|
|
} else {
|
|
return (0, import_jsx_runtime17.jsx)(FormBuiltInMessage, { match, ...messageProps, ref: forwardedRef, name });
|
|
}
|
|
}
|
|
);
|
|
FormMessage.displayName = MESSAGE_NAME;
|
|
var FormBuiltInMessage = React17.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { match, forceMatch = false, name, children, ...messageProps } = props;
|
|
const validationContext = useValidationContext(MESSAGE_NAME, messageProps.__scopeForm);
|
|
const validity = validationContext.getFieldValidity(name);
|
|
const matches = forceMatch || (validity == null ? void 0 : validity[match]);
|
|
if (matches) {
|
|
return (0, import_jsx_runtime17.jsx)(FormMessageImpl, { ref: forwardedRef, ...messageProps, name, children: children ?? DEFAULT_BUILT_IN_MESSAGES[match] });
|
|
}
|
|
return null;
|
|
}
|
|
);
|
|
var FormCustomMessage = React17.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { match, forceMatch = false, name, id: idProp, children, ...messageProps } = props;
|
|
const validationContext = useValidationContext(MESSAGE_NAME, messageProps.__scopeForm);
|
|
const ref = React17.useRef(null);
|
|
const composedRef = useComposedRefs(forwardedRef, ref);
|
|
const _id = useId();
|
|
const id = idProp ?? _id;
|
|
const customMatcherEntry = React17.useMemo(() => ({ id, match }), [id, match]);
|
|
const { onFieldCustomMatcherEntryAdd, onFieldCustomMatcherEntryRemove } = validationContext;
|
|
React17.useEffect(() => {
|
|
onFieldCustomMatcherEntryAdd(name, customMatcherEntry);
|
|
return () => onFieldCustomMatcherEntryRemove(name, customMatcherEntry.id);
|
|
}, [customMatcherEntry, name, onFieldCustomMatcherEntryAdd, onFieldCustomMatcherEntryRemove]);
|
|
const validity = validationContext.getFieldValidity(name);
|
|
const customErrors = validationContext.getFieldCustomErrors(name);
|
|
const hasMatchingCustomError = customErrors[id];
|
|
const matches = forceMatch || validity && !hasBuiltInError(validity) && hasMatchingCustomError;
|
|
if (matches) {
|
|
return (0, import_jsx_runtime17.jsx)(FormMessageImpl, { id, ref: composedRef, ...messageProps, name, children: children ?? DEFAULT_INVALID_MESSAGE });
|
|
}
|
|
return null;
|
|
}
|
|
);
|
|
var FormMessageImpl = React17.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeForm, id: idProp, name, ...messageProps } = props;
|
|
const ariaDescriptionContext = useAriaDescriptionContext(MESSAGE_NAME, __scopeForm);
|
|
const _id = useId();
|
|
const id = idProp ?? _id;
|
|
const { onFieldMessageIdAdd, onFieldMessageIdRemove } = ariaDescriptionContext;
|
|
React17.useEffect(() => {
|
|
onFieldMessageIdAdd(name, id);
|
|
return () => onFieldMessageIdRemove(name, id);
|
|
}, [name, id, onFieldMessageIdAdd, onFieldMessageIdRemove]);
|
|
return (0, import_jsx_runtime17.jsx)(Primitive.span, { id, ...messageProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
var VALIDITY_STATE_NAME = "FormValidityState";
|
|
var FormValidityState = (props) => {
|
|
const { __scopeForm, name: nameProp, children } = props;
|
|
const validationContext = useValidationContext(VALIDITY_STATE_NAME, __scopeForm);
|
|
const fieldContext = useFormFieldContext(VALIDITY_STATE_NAME, __scopeForm);
|
|
const name = nameProp ?? fieldContext.name;
|
|
const validity = validationContext.getFieldValidity(name);
|
|
return (0, import_jsx_runtime17.jsx)(import_jsx_runtime17.Fragment, { children: children(validity) });
|
|
};
|
|
FormValidityState.displayName = VALIDITY_STATE_NAME;
|
|
var SUBMIT_NAME = "FormSubmit";
|
|
var FormSubmit = React17.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeForm, ...submitProps } = props;
|
|
return (0, import_jsx_runtime17.jsx)(Primitive.button, { type: "submit", ...submitProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
FormSubmit.displayName = SUBMIT_NAME;
|
|
function validityStateToObject(validity) {
|
|
const object = {};
|
|
for (const key in validity) {
|
|
object[key] = validity[key];
|
|
}
|
|
return object;
|
|
}
|
|
function isHTMLElement(element) {
|
|
return element instanceof HTMLElement;
|
|
}
|
|
function isFormControl(element) {
|
|
return "validity" in element;
|
|
}
|
|
function isInvalid(control) {
|
|
return isFormControl(control) && (control.validity.valid === false || control.getAttribute("aria-invalid") === "true");
|
|
}
|
|
function getFirstInvalidControl(form) {
|
|
const elements = form.elements;
|
|
const [firstInvalidControl] = Array.from(elements).filter(isHTMLElement).filter(isInvalid);
|
|
return firstInvalidControl;
|
|
}
|
|
function isAsyncCustomMatcherEntry(entry, args) {
|
|
return entry.match.constructor.name === "AsyncFunction" || returnsPromise(entry.match, args);
|
|
}
|
|
function isSyncCustomMatcherEntry(entry) {
|
|
return entry.match.constructor.name === "Function";
|
|
}
|
|
function returnsPromise(func, args) {
|
|
return func(...args) instanceof Promise;
|
|
}
|
|
function hasBuiltInError(validity) {
|
|
let error = false;
|
|
for (const validityKey in validity) {
|
|
const key = validityKey;
|
|
if (key !== "valid" && key !== "customError" && validity[key]) {
|
|
error = true;
|
|
break;
|
|
}
|
|
}
|
|
return error;
|
|
}
|
|
function getValidAttribute(validity, serverInvalid) {
|
|
if ((validity == null ? void 0 : validity.valid) === true && !serverInvalid) return true;
|
|
return void 0;
|
|
}
|
|
function getInvalidAttribute(validity, serverInvalid) {
|
|
if ((validity == null ? void 0 : validity.valid) === false || serverInvalid) return true;
|
|
return void 0;
|
|
}
|
|
var Root10 = Form;
|
|
var Field = FormField;
|
|
var Label4 = FormLabel;
|
|
var Control = FormControl;
|
|
var Message = FormMessage;
|
|
var ValidityState = FormValidityState;
|
|
var Submit = FormSubmit;
|
|
|
|
// ../../node_modules/@radix-ui/react-hover-card/dist/index.mjs
|
|
var dist_exports21 = {};
|
|
__export(dist_exports21, {
|
|
Arrow: () => Arrow24,
|
|
Content: () => Content27,
|
|
HoverCard: () => HoverCard,
|
|
HoverCardArrow: () => HoverCardArrow,
|
|
HoverCardContent: () => HoverCardContent,
|
|
HoverCardPortal: () => HoverCardPortal,
|
|
HoverCardTrigger: () => HoverCardTrigger,
|
|
Portal: () => Portal4,
|
|
Root: () => Root28,
|
|
Trigger: () => Trigger5,
|
|
createHoverCardScope: () => createHoverCardScope
|
|
});
|
|
var React18 = __toESM(require_react(), 1);
|
|
var import_jsx_runtime18 = __toESM(require_jsx_runtime(), 1);
|
|
var originalBodyUserSelect;
|
|
var HOVERCARD_NAME = "HoverCard";
|
|
var [createHoverCardContext, createHoverCardScope] = createContextScope(HOVERCARD_NAME, [
|
|
createPopperScope
|
|
]);
|
|
var usePopperScope2 = createPopperScope();
|
|
var [HoverCardProvider, useHoverCardContext] = createHoverCardContext(HOVERCARD_NAME);
|
|
var HoverCard = (props) => {
|
|
const {
|
|
__scopeHoverCard,
|
|
children,
|
|
open: openProp,
|
|
defaultOpen,
|
|
onOpenChange,
|
|
openDelay = 700,
|
|
closeDelay = 300
|
|
} = props;
|
|
const popperScope = usePopperScope2(__scopeHoverCard);
|
|
const openTimerRef = React18.useRef(0);
|
|
const closeTimerRef = React18.useRef(0);
|
|
const hasSelectionRef = React18.useRef(false);
|
|
const isPointerDownOnContentRef = React18.useRef(false);
|
|
const [open, setOpen] = useControllableState({
|
|
prop: openProp,
|
|
defaultProp: defaultOpen ?? false,
|
|
onChange: onOpenChange,
|
|
caller: HOVERCARD_NAME
|
|
});
|
|
const handleOpen = React18.useCallback(() => {
|
|
clearTimeout(closeTimerRef.current);
|
|
openTimerRef.current = window.setTimeout(() => setOpen(true), openDelay);
|
|
}, [openDelay, setOpen]);
|
|
const handleClose = React18.useCallback(() => {
|
|
clearTimeout(openTimerRef.current);
|
|
if (!hasSelectionRef.current && !isPointerDownOnContentRef.current) {
|
|
closeTimerRef.current = window.setTimeout(() => setOpen(false), closeDelay);
|
|
}
|
|
}, [closeDelay, setOpen]);
|
|
const handleDismiss = React18.useCallback(() => setOpen(false), [setOpen]);
|
|
React18.useEffect(() => {
|
|
return () => {
|
|
clearTimeout(openTimerRef.current);
|
|
clearTimeout(closeTimerRef.current);
|
|
};
|
|
}, []);
|
|
return (0, import_jsx_runtime18.jsx)(
|
|
HoverCardProvider,
|
|
{
|
|
scope: __scopeHoverCard,
|
|
open,
|
|
onOpenChange: setOpen,
|
|
onOpen: handleOpen,
|
|
onClose: handleClose,
|
|
onDismiss: handleDismiss,
|
|
hasSelectionRef,
|
|
isPointerDownOnContentRef,
|
|
children: (0, import_jsx_runtime18.jsx)(Root22, { ...popperScope, children })
|
|
}
|
|
);
|
|
};
|
|
HoverCard.displayName = HOVERCARD_NAME;
|
|
var TRIGGER_NAME7 = "HoverCardTrigger";
|
|
var HoverCardTrigger = React18.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeHoverCard, ...triggerProps } = props;
|
|
const context = useHoverCardContext(TRIGGER_NAME7, __scopeHoverCard);
|
|
const popperScope = usePopperScope2(__scopeHoverCard);
|
|
return (0, import_jsx_runtime18.jsx)(Anchor, { asChild: true, ...popperScope, children: (0, import_jsx_runtime18.jsx)(
|
|
Primitive.a,
|
|
{
|
|
"data-state": context.open ? "open" : "closed",
|
|
...triggerProps,
|
|
ref: forwardedRef,
|
|
onPointerEnter: composeEventHandlers(props.onPointerEnter, excludeTouch(context.onOpen)),
|
|
onPointerLeave: composeEventHandlers(props.onPointerLeave, excludeTouch(context.onClose)),
|
|
onFocus: composeEventHandlers(props.onFocus, context.onOpen),
|
|
onBlur: composeEventHandlers(props.onBlur, context.onClose),
|
|
onTouchStart: composeEventHandlers(props.onTouchStart, (event) => event.preventDefault())
|
|
}
|
|
) });
|
|
}
|
|
);
|
|
HoverCardTrigger.displayName = TRIGGER_NAME7;
|
|
var PORTAL_NAME5 = "HoverCardPortal";
|
|
var [PortalProvider2, usePortalContext2] = createHoverCardContext(PORTAL_NAME5, {
|
|
forceMount: void 0
|
|
});
|
|
var HoverCardPortal = (props) => {
|
|
const { __scopeHoverCard, forceMount, children, container } = props;
|
|
const context = useHoverCardContext(PORTAL_NAME5, __scopeHoverCard);
|
|
return (0, import_jsx_runtime18.jsx)(PortalProvider2, { scope: __scopeHoverCard, forceMount, children: (0, import_jsx_runtime18.jsx)(Presence, { present: forceMount || context.open, children: (0, import_jsx_runtime18.jsx)(Portal, { asChild: true, container, children }) }) });
|
|
};
|
|
HoverCardPortal.displayName = PORTAL_NAME5;
|
|
var CONTENT_NAME7 = "HoverCardContent";
|
|
var HoverCardContent = React18.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const portalContext = usePortalContext2(CONTENT_NAME7, props.__scopeHoverCard);
|
|
const { forceMount = portalContext.forceMount, ...contentProps } = props;
|
|
const context = useHoverCardContext(CONTENT_NAME7, props.__scopeHoverCard);
|
|
return (0, import_jsx_runtime18.jsx)(Presence, { present: forceMount || context.open, children: (0, import_jsx_runtime18.jsx)(
|
|
HoverCardContentImpl,
|
|
{
|
|
"data-state": context.open ? "open" : "closed",
|
|
...contentProps,
|
|
onPointerEnter: composeEventHandlers(props.onPointerEnter, excludeTouch(context.onOpen)),
|
|
onPointerLeave: composeEventHandlers(props.onPointerLeave, excludeTouch(context.onClose)),
|
|
ref: forwardedRef
|
|
}
|
|
) });
|
|
}
|
|
);
|
|
HoverCardContent.displayName = CONTENT_NAME7;
|
|
var HoverCardContentImpl = React18.forwardRef((props, forwardedRef) => {
|
|
const {
|
|
__scopeHoverCard,
|
|
onEscapeKeyDown,
|
|
onPointerDownOutside,
|
|
onFocusOutside,
|
|
onInteractOutside,
|
|
...contentProps
|
|
} = props;
|
|
const context = useHoverCardContext(CONTENT_NAME7, __scopeHoverCard);
|
|
const popperScope = usePopperScope2(__scopeHoverCard);
|
|
const ref = React18.useRef(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, ref);
|
|
const [containSelection, setContainSelection] = React18.useState(false);
|
|
React18.useEffect(() => {
|
|
if (containSelection) {
|
|
const body = document.body;
|
|
originalBodyUserSelect = body.style.userSelect || body.style.webkitUserSelect;
|
|
body.style.userSelect = "none";
|
|
body.style.webkitUserSelect = "none";
|
|
return () => {
|
|
body.style.userSelect = originalBodyUserSelect;
|
|
body.style.webkitUserSelect = originalBodyUserSelect;
|
|
};
|
|
}
|
|
}, [containSelection]);
|
|
React18.useEffect(() => {
|
|
if (ref.current) {
|
|
const handlePointerUp = () => {
|
|
setContainSelection(false);
|
|
context.isPointerDownOnContentRef.current = false;
|
|
setTimeout(() => {
|
|
var _a2;
|
|
const hasSelection = ((_a2 = document.getSelection()) == null ? void 0 : _a2.toString()) !== "";
|
|
if (hasSelection) context.hasSelectionRef.current = true;
|
|
});
|
|
};
|
|
document.addEventListener("pointerup", handlePointerUp);
|
|
return () => {
|
|
document.removeEventListener("pointerup", handlePointerUp);
|
|
context.hasSelectionRef.current = false;
|
|
context.isPointerDownOnContentRef.current = false;
|
|
};
|
|
}
|
|
}, [context.isPointerDownOnContentRef, context.hasSelectionRef]);
|
|
React18.useEffect(() => {
|
|
if (ref.current) {
|
|
const tabbables = getTabbableNodes(ref.current);
|
|
tabbables.forEach((tabbable) => tabbable.setAttribute("tabindex", "-1"));
|
|
}
|
|
});
|
|
return (0, import_jsx_runtime18.jsx)(
|
|
DismissableLayer,
|
|
{
|
|
asChild: true,
|
|
disableOutsidePointerEvents: false,
|
|
onInteractOutside,
|
|
onEscapeKeyDown,
|
|
onPointerDownOutside,
|
|
onFocusOutside: composeEventHandlers(onFocusOutside, (event) => {
|
|
event.preventDefault();
|
|
}),
|
|
onDismiss: context.onDismiss,
|
|
children: (0, import_jsx_runtime18.jsx)(
|
|
Content,
|
|
{
|
|
...popperScope,
|
|
...contentProps,
|
|
onPointerDown: composeEventHandlers(contentProps.onPointerDown, (event) => {
|
|
if (event.currentTarget.contains(event.target)) {
|
|
setContainSelection(true);
|
|
}
|
|
context.hasSelectionRef.current = false;
|
|
context.isPointerDownOnContentRef.current = true;
|
|
}),
|
|
ref: composedRefs,
|
|
style: {
|
|
...contentProps.style,
|
|
userSelect: containSelection ? "text" : void 0,
|
|
// Safari requires prefix
|
|
WebkitUserSelect: containSelection ? "text" : void 0,
|
|
// re-namespace exposed content custom properties
|
|
...{
|
|
"--radix-hover-card-content-transform-origin": "var(--radix-popper-transform-origin)",
|
|
"--radix-hover-card-content-available-width": "var(--radix-popper-available-width)",
|
|
"--radix-hover-card-content-available-height": "var(--radix-popper-available-height)",
|
|
"--radix-hover-card-trigger-width": "var(--radix-popper-anchor-width)",
|
|
"--radix-hover-card-trigger-height": "var(--radix-popper-anchor-height)"
|
|
}
|
|
}
|
|
}
|
|
)
|
|
}
|
|
);
|
|
});
|
|
var ARROW_NAME4 = "HoverCardArrow";
|
|
var HoverCardArrow = React18.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeHoverCard, ...arrowProps } = props;
|
|
const popperScope = usePopperScope2(__scopeHoverCard);
|
|
return (0, import_jsx_runtime18.jsx)(Arrow, { ...popperScope, ...arrowProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
HoverCardArrow.displayName = ARROW_NAME4;
|
|
function excludeTouch(eventHandler) {
|
|
return (event) => event.pointerType === "touch" ? void 0 : eventHandler();
|
|
}
|
|
function getTabbableNodes(container) {
|
|
const nodes = [];
|
|
const walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT, {
|
|
acceptNode: (node) => {
|
|
return node.tabIndex >= 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
|
|
}
|
|
});
|
|
while (walker.nextNode()) nodes.push(walker.currentNode);
|
|
return nodes;
|
|
}
|
|
var Root28 = HoverCard;
|
|
var Trigger5 = HoverCardTrigger;
|
|
var Portal4 = HoverCardPortal;
|
|
var Content27 = HoverCardContent;
|
|
var Arrow24 = HoverCardArrow;
|
|
|
|
// ../../node_modules/@radix-ui/react-menubar/dist/index.mjs
|
|
var dist_exports22 = {};
|
|
__export(dist_exports22, {
|
|
Arrow: () => Arrow25,
|
|
CheckboxItem: () => CheckboxItem23,
|
|
Content: () => Content28,
|
|
Group: () => Group23,
|
|
Item: () => Item3,
|
|
ItemIndicator: () => ItemIndicator23,
|
|
Label: () => Label23,
|
|
Menu: () => Menu2,
|
|
Menubar: () => Menubar,
|
|
MenubarArrow: () => MenubarArrow,
|
|
MenubarCheckboxItem: () => MenubarCheckboxItem,
|
|
MenubarContent: () => MenubarContent,
|
|
MenubarGroup: () => MenubarGroup,
|
|
MenubarItem: () => MenubarItem,
|
|
MenubarItemIndicator: () => MenubarItemIndicator,
|
|
MenubarLabel: () => MenubarLabel,
|
|
MenubarMenu: () => MenubarMenu,
|
|
MenubarPortal: () => MenubarPortal,
|
|
MenubarRadioGroup: () => MenubarRadioGroup,
|
|
MenubarRadioItem: () => MenubarRadioItem,
|
|
MenubarSeparator: () => MenubarSeparator,
|
|
MenubarSub: () => MenubarSub,
|
|
MenubarSubContent: () => MenubarSubContent,
|
|
MenubarSubTrigger: () => MenubarSubTrigger,
|
|
MenubarTrigger: () => MenubarTrigger,
|
|
Portal: () => Portal25,
|
|
RadioGroup: () => RadioGroup23,
|
|
RadioItem: () => RadioItem23,
|
|
Root: () => Root33,
|
|
Separator: () => Separator23,
|
|
Sub: () => Sub23,
|
|
SubContent: () => SubContent23,
|
|
SubTrigger: () => SubTrigger23,
|
|
Trigger: () => Trigger6,
|
|
createMenubarScope: () => createMenubarScope
|
|
});
|
|
var React19 = __toESM(require_react(), 1);
|
|
var import_jsx_runtime19 = __toESM(require_jsx_runtime(), 1);
|
|
var MENUBAR_NAME = "Menubar";
|
|
var [Collection4, useCollection4, createCollectionScope4] = createCollection(MENUBAR_NAME);
|
|
var [createMenubarContext, createMenubarScope] = createContextScope(MENUBAR_NAME, [
|
|
createCollectionScope4,
|
|
createRovingFocusGroupScope
|
|
]);
|
|
var useMenuScope3 = createMenuScope();
|
|
var useRovingFocusGroupScope2 = createRovingFocusGroupScope();
|
|
var [MenubarContextProvider, useMenubarContext] = createMenubarContext(MENUBAR_NAME);
|
|
var Menubar = React19.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const {
|
|
__scopeMenubar,
|
|
value: valueProp,
|
|
onValueChange,
|
|
defaultValue,
|
|
loop = true,
|
|
dir,
|
|
...menubarProps
|
|
} = props;
|
|
const direction = useDirection(dir);
|
|
const rovingFocusGroupScope = useRovingFocusGroupScope2(__scopeMenubar);
|
|
const [value, setValue] = useControllableState({
|
|
prop: valueProp,
|
|
onChange: onValueChange,
|
|
defaultProp: defaultValue ?? "",
|
|
caller: MENUBAR_NAME
|
|
});
|
|
const [currentTabStopId, setCurrentTabStopId] = React19.useState(null);
|
|
return (0, import_jsx_runtime19.jsx)(
|
|
MenubarContextProvider,
|
|
{
|
|
scope: __scopeMenubar,
|
|
value,
|
|
onMenuOpen: React19.useCallback(
|
|
(value2) => {
|
|
setValue(value2);
|
|
setCurrentTabStopId(value2);
|
|
},
|
|
[setValue]
|
|
),
|
|
onMenuClose: React19.useCallback(() => setValue(""), [setValue]),
|
|
onMenuToggle: React19.useCallback(
|
|
(value2) => {
|
|
setValue((prevValue) => prevValue ? "" : value2);
|
|
setCurrentTabStopId(value2);
|
|
},
|
|
[setValue]
|
|
),
|
|
dir: direction,
|
|
loop,
|
|
children: (0, import_jsx_runtime19.jsx)(Collection4.Provider, { scope: __scopeMenubar, children: (0, import_jsx_runtime19.jsx)(Collection4.Slot, { scope: __scopeMenubar, children: (0, import_jsx_runtime19.jsx)(
|
|
Root8,
|
|
{
|
|
asChild: true,
|
|
...rovingFocusGroupScope,
|
|
orientation: "horizontal",
|
|
loop,
|
|
dir: direction,
|
|
currentTabStopId,
|
|
onCurrentTabStopIdChange: setCurrentTabStopId,
|
|
children: (0, import_jsx_runtime19.jsx)(Primitive.div, { role: "menubar", ...menubarProps, ref: forwardedRef })
|
|
}
|
|
) }) })
|
|
}
|
|
);
|
|
}
|
|
);
|
|
Menubar.displayName = MENUBAR_NAME;
|
|
var MENU_NAME2 = "MenubarMenu";
|
|
var [MenubarMenuProvider, useMenubarMenuContext] = createMenubarContext(MENU_NAME2);
|
|
var MenubarMenu = (props) => {
|
|
const { __scopeMenubar, value: valueProp, ...menuProps } = props;
|
|
const autoValue = useId();
|
|
const value = valueProp || autoValue || "LEGACY_REACT_AUTO_VALUE";
|
|
const context = useMenubarContext(MENU_NAME2, __scopeMenubar);
|
|
const menuScope = useMenuScope3(__scopeMenubar);
|
|
const triggerRef = React19.useRef(null);
|
|
const wasKeyboardTriggerOpenRef = React19.useRef(false);
|
|
const open = context.value === value;
|
|
React19.useEffect(() => {
|
|
if (!open) wasKeyboardTriggerOpenRef.current = false;
|
|
}, [open]);
|
|
return (0, import_jsx_runtime19.jsx)(
|
|
MenubarMenuProvider,
|
|
{
|
|
scope: __scopeMenubar,
|
|
value,
|
|
triggerId: useId(),
|
|
triggerRef,
|
|
contentId: useId(),
|
|
wasKeyboardTriggerOpenRef,
|
|
children: (0, import_jsx_runtime19.jsx)(
|
|
Root32,
|
|
{
|
|
...menuScope,
|
|
open,
|
|
onOpenChange: (open2) => {
|
|
if (!open2) context.onMenuClose();
|
|
},
|
|
modal: false,
|
|
dir: context.dir,
|
|
...menuProps
|
|
}
|
|
)
|
|
}
|
|
);
|
|
};
|
|
MenubarMenu.displayName = MENU_NAME2;
|
|
var TRIGGER_NAME8 = "MenubarTrigger";
|
|
var MenubarTrigger = React19.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeMenubar, disabled = false, ...triggerProps } = props;
|
|
const rovingFocusGroupScope = useRovingFocusGroupScope2(__scopeMenubar);
|
|
const menuScope = useMenuScope3(__scopeMenubar);
|
|
const context = useMenubarContext(TRIGGER_NAME8, __scopeMenubar);
|
|
const menuContext = useMenubarMenuContext(TRIGGER_NAME8, __scopeMenubar);
|
|
const ref = React19.useRef(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, ref, menuContext.triggerRef);
|
|
const [isFocused, setIsFocused] = React19.useState(false);
|
|
const open = context.value === menuContext.value;
|
|
return (0, import_jsx_runtime19.jsx)(Collection4.ItemSlot, { scope: __scopeMenubar, value: menuContext.value, disabled, children: (0, import_jsx_runtime19.jsx)(
|
|
Item2,
|
|
{
|
|
asChild: true,
|
|
...rovingFocusGroupScope,
|
|
focusable: !disabled,
|
|
tabStopId: menuContext.value,
|
|
children: (0, import_jsx_runtime19.jsx)(Anchor2, { asChild: true, ...menuScope, children: (0, import_jsx_runtime19.jsx)(
|
|
Primitive.button,
|
|
{
|
|
type: "button",
|
|
role: "menuitem",
|
|
id: menuContext.triggerId,
|
|
"aria-haspopup": "menu",
|
|
"aria-expanded": open,
|
|
"aria-controls": open ? menuContext.contentId : void 0,
|
|
"data-highlighted": isFocused ? "" : void 0,
|
|
"data-state": open ? "open" : "closed",
|
|
"data-disabled": disabled ? "" : void 0,
|
|
disabled,
|
|
...triggerProps,
|
|
ref: composedRefs,
|
|
onPointerDown: composeEventHandlers(props.onPointerDown, (event) => {
|
|
if (!disabled && event.button === 0 && event.ctrlKey === false) {
|
|
context.onMenuOpen(menuContext.value);
|
|
if (!open) event.preventDefault();
|
|
}
|
|
}),
|
|
onPointerEnter: composeEventHandlers(props.onPointerEnter, () => {
|
|
var _a2;
|
|
const menubarOpen = Boolean(context.value);
|
|
if (menubarOpen && !open) {
|
|
context.onMenuOpen(menuContext.value);
|
|
(_a2 = ref.current) == null ? void 0 : _a2.focus();
|
|
}
|
|
}),
|
|
onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
|
|
if (disabled) return;
|
|
if (["Enter", " "].includes(event.key)) context.onMenuToggle(menuContext.value);
|
|
if (event.key === "ArrowDown") context.onMenuOpen(menuContext.value);
|
|
if (["Enter", " ", "ArrowDown"].includes(event.key)) {
|
|
menuContext.wasKeyboardTriggerOpenRef.current = true;
|
|
event.preventDefault();
|
|
}
|
|
}),
|
|
onFocus: composeEventHandlers(props.onFocus, () => setIsFocused(true)),
|
|
onBlur: composeEventHandlers(props.onBlur, () => setIsFocused(false))
|
|
}
|
|
) })
|
|
}
|
|
) });
|
|
}
|
|
);
|
|
MenubarTrigger.displayName = TRIGGER_NAME8;
|
|
var PORTAL_NAME6 = "MenubarPortal";
|
|
var MenubarPortal = (props) => {
|
|
const { __scopeMenubar, ...portalProps } = props;
|
|
const menuScope = useMenuScope3(__scopeMenubar);
|
|
return (0, import_jsx_runtime19.jsx)(Portal3, { ...menuScope, ...portalProps });
|
|
};
|
|
MenubarPortal.displayName = PORTAL_NAME6;
|
|
var CONTENT_NAME8 = "MenubarContent";
|
|
var MenubarContent = React19.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeMenubar, align = "start", ...contentProps } = props;
|
|
const menuScope = useMenuScope3(__scopeMenubar);
|
|
const context = useMenubarContext(CONTENT_NAME8, __scopeMenubar);
|
|
const menuContext = useMenubarMenuContext(CONTENT_NAME8, __scopeMenubar);
|
|
const getItems = useCollection4(__scopeMenubar);
|
|
const hasInteractedOutsideRef = React19.useRef(false);
|
|
return (0, import_jsx_runtime19.jsx)(
|
|
Content24,
|
|
{
|
|
id: menuContext.contentId,
|
|
"aria-labelledby": menuContext.triggerId,
|
|
"data-radix-menubar-content": "",
|
|
...menuScope,
|
|
...contentProps,
|
|
ref: forwardedRef,
|
|
align,
|
|
onCloseAutoFocus: composeEventHandlers(props.onCloseAutoFocus, (event) => {
|
|
var _a2;
|
|
const menubarOpen = Boolean(context.value);
|
|
if (!menubarOpen && !hasInteractedOutsideRef.current) {
|
|
(_a2 = menuContext.triggerRef.current) == null ? void 0 : _a2.focus();
|
|
}
|
|
hasInteractedOutsideRef.current = false;
|
|
event.preventDefault();
|
|
}),
|
|
onFocusOutside: composeEventHandlers(props.onFocusOutside, (event) => {
|
|
const target = event.target;
|
|
const isMenubarTrigger = getItems().some((item) => {
|
|
var _a2;
|
|
return (_a2 = item.ref.current) == null ? void 0 : _a2.contains(target);
|
|
});
|
|
if (isMenubarTrigger) event.preventDefault();
|
|
}),
|
|
onInteractOutside: composeEventHandlers(props.onInteractOutside, () => {
|
|
hasInteractedOutsideRef.current = true;
|
|
}),
|
|
onEntryFocus: (event) => {
|
|
if (!menuContext.wasKeyboardTriggerOpenRef.current) event.preventDefault();
|
|
},
|
|
onKeyDown: composeEventHandlers(
|
|
props.onKeyDown,
|
|
(event) => {
|
|
if (["ArrowRight", "ArrowLeft"].includes(event.key)) {
|
|
const target = event.target;
|
|
const targetIsSubTrigger = target.hasAttribute("data-radix-menubar-subtrigger");
|
|
const isKeyDownInsideSubMenu = target.closest("[data-radix-menubar-content]") !== event.currentTarget;
|
|
const prevMenuKey = context.dir === "rtl" ? "ArrowRight" : "ArrowLeft";
|
|
const isPrevKey = prevMenuKey === event.key;
|
|
const isNextKey = !isPrevKey;
|
|
if (isNextKey && targetIsSubTrigger) return;
|
|
if (isKeyDownInsideSubMenu && isPrevKey) return;
|
|
const items = getItems().filter((item) => !item.disabled);
|
|
let candidateValues = items.map((item) => item.value);
|
|
if (isPrevKey) candidateValues.reverse();
|
|
const currentIndex = candidateValues.indexOf(menuContext.value);
|
|
candidateValues = context.loop ? wrapArray3(candidateValues, currentIndex + 1) : candidateValues.slice(currentIndex + 1);
|
|
const [nextValue] = candidateValues;
|
|
if (nextValue) context.onMenuOpen(nextValue);
|
|
}
|
|
},
|
|
{ checkForDefaultPrevented: false }
|
|
),
|
|
style: {
|
|
...props.style,
|
|
// re-namespace exposed content custom properties
|
|
...{
|
|
"--radix-menubar-content-transform-origin": "var(--radix-popper-transform-origin)",
|
|
"--radix-menubar-content-available-width": "var(--radix-popper-available-width)",
|
|
"--radix-menubar-content-available-height": "var(--radix-popper-available-height)",
|
|
"--radix-menubar-trigger-width": "var(--radix-popper-anchor-width)",
|
|
"--radix-menubar-trigger-height": "var(--radix-popper-anchor-height)"
|
|
}
|
|
}
|
|
}
|
|
);
|
|
}
|
|
);
|
|
MenubarContent.displayName = CONTENT_NAME8;
|
|
var GROUP_NAME5 = "MenubarGroup";
|
|
var MenubarGroup = React19.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeMenubar, ...groupProps } = props;
|
|
const menuScope = useMenuScope3(__scopeMenubar);
|
|
return (0, import_jsx_runtime19.jsx)(Group, { ...menuScope, ...groupProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
MenubarGroup.displayName = GROUP_NAME5;
|
|
var LABEL_NAME5 = "MenubarLabel";
|
|
var MenubarLabel = React19.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeMenubar, ...labelProps } = props;
|
|
const menuScope = useMenuScope3(__scopeMenubar);
|
|
return (0, import_jsx_runtime19.jsx)(Label, { ...menuScope, ...labelProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
MenubarLabel.displayName = LABEL_NAME5;
|
|
var ITEM_NAME6 = "MenubarItem";
|
|
var MenubarItem = React19.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeMenubar, ...itemProps } = props;
|
|
const menuScope = useMenuScope3(__scopeMenubar);
|
|
return (0, import_jsx_runtime19.jsx)(Item22, { ...menuScope, ...itemProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
MenubarItem.displayName = ITEM_NAME6;
|
|
var CHECKBOX_ITEM_NAME4 = "MenubarCheckboxItem";
|
|
var MenubarCheckboxItem = React19.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeMenubar, ...checkboxItemProps } = props;
|
|
const menuScope = useMenuScope3(__scopeMenubar);
|
|
return (0, import_jsx_runtime19.jsx)(CheckboxItem, { ...menuScope, ...checkboxItemProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
MenubarCheckboxItem.displayName = CHECKBOX_ITEM_NAME4;
|
|
var RADIO_GROUP_NAME4 = "MenubarRadioGroup";
|
|
var MenubarRadioGroup = React19.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeMenubar, ...radioGroupProps } = props;
|
|
const menuScope = useMenuScope3(__scopeMenubar);
|
|
return (0, import_jsx_runtime19.jsx)(RadioGroup, { ...menuScope, ...radioGroupProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
MenubarRadioGroup.displayName = RADIO_GROUP_NAME4;
|
|
var RADIO_ITEM_NAME4 = "MenubarRadioItem";
|
|
var MenubarRadioItem = React19.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeMenubar, ...radioItemProps } = props;
|
|
const menuScope = useMenuScope3(__scopeMenubar);
|
|
return (0, import_jsx_runtime19.jsx)(RadioItem, { ...menuScope, ...radioItemProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
MenubarRadioItem.displayName = RADIO_ITEM_NAME4;
|
|
var INDICATOR_NAME4 = "MenubarItemIndicator";
|
|
var MenubarItemIndicator = React19.forwardRef((props, forwardedRef) => {
|
|
const { __scopeMenubar, ...itemIndicatorProps } = props;
|
|
const menuScope = useMenuScope3(__scopeMenubar);
|
|
return (0, import_jsx_runtime19.jsx)(ItemIndicator, { ...menuScope, ...itemIndicatorProps, ref: forwardedRef });
|
|
});
|
|
MenubarItemIndicator.displayName = INDICATOR_NAME4;
|
|
var SEPARATOR_NAME4 = "MenubarSeparator";
|
|
var MenubarSeparator = React19.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeMenubar, ...separatorProps } = props;
|
|
const menuScope = useMenuScope3(__scopeMenubar);
|
|
return (0, import_jsx_runtime19.jsx)(Separator, { ...menuScope, ...separatorProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
MenubarSeparator.displayName = SEPARATOR_NAME4;
|
|
var ARROW_NAME5 = "MenubarArrow";
|
|
var MenubarArrow = React19.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeMenubar, ...arrowProps } = props;
|
|
const menuScope = useMenuScope3(__scopeMenubar);
|
|
return (0, import_jsx_runtime19.jsx)(Arrow2, { ...menuScope, ...arrowProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
MenubarArrow.displayName = ARROW_NAME5;
|
|
var SUB_NAME3 = "MenubarSub";
|
|
var MenubarSub = (props) => {
|
|
const { __scopeMenubar, children, open: openProp, onOpenChange, defaultOpen } = props;
|
|
const menuScope = useMenuScope3(__scopeMenubar);
|
|
const [open, setOpen] = useControllableState({
|
|
prop: openProp,
|
|
defaultProp: defaultOpen ?? false,
|
|
onChange: onOpenChange,
|
|
caller: SUB_NAME3
|
|
});
|
|
return (0, import_jsx_runtime19.jsx)(Sub, { ...menuScope, open, onOpenChange: setOpen, children });
|
|
};
|
|
MenubarSub.displayName = SUB_NAME3;
|
|
var SUB_TRIGGER_NAME4 = "MenubarSubTrigger";
|
|
var MenubarSubTrigger = React19.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeMenubar, ...subTriggerProps } = props;
|
|
const menuScope = useMenuScope3(__scopeMenubar);
|
|
return (0, import_jsx_runtime19.jsx)(
|
|
SubTrigger,
|
|
{
|
|
"data-radix-menubar-subtrigger": "",
|
|
...menuScope,
|
|
...subTriggerProps,
|
|
ref: forwardedRef
|
|
}
|
|
);
|
|
}
|
|
);
|
|
MenubarSubTrigger.displayName = SUB_TRIGGER_NAME4;
|
|
var SUB_CONTENT_NAME4 = "MenubarSubContent";
|
|
var MenubarSubContent = React19.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeMenubar, ...subContentProps } = props;
|
|
const menuScope = useMenuScope3(__scopeMenubar);
|
|
return (0, import_jsx_runtime19.jsx)(
|
|
SubContent,
|
|
{
|
|
...menuScope,
|
|
"data-radix-menubar-content": "",
|
|
...subContentProps,
|
|
ref: forwardedRef,
|
|
style: {
|
|
...props.style,
|
|
// re-namespace exposed content custom properties
|
|
...{
|
|
"--radix-menubar-content-transform-origin": "var(--radix-popper-transform-origin)",
|
|
"--radix-menubar-content-available-width": "var(--radix-popper-available-width)",
|
|
"--radix-menubar-content-available-height": "var(--radix-popper-available-height)",
|
|
"--radix-menubar-trigger-width": "var(--radix-popper-anchor-width)",
|
|
"--radix-menubar-trigger-height": "var(--radix-popper-anchor-height)"
|
|
}
|
|
}
|
|
}
|
|
);
|
|
}
|
|
);
|
|
MenubarSubContent.displayName = SUB_CONTENT_NAME4;
|
|
function wrapArray3(array, startIndex) {
|
|
return array.map((_, index) => array[(startIndex + index) % array.length]);
|
|
}
|
|
var Root33 = Menubar;
|
|
var Menu2 = MenubarMenu;
|
|
var Trigger6 = MenubarTrigger;
|
|
var Portal25 = MenubarPortal;
|
|
var Content28 = MenubarContent;
|
|
var Group23 = MenubarGroup;
|
|
var Label23 = MenubarLabel;
|
|
var Item3 = MenubarItem;
|
|
var CheckboxItem23 = MenubarCheckboxItem;
|
|
var RadioGroup23 = MenubarRadioGroup;
|
|
var RadioItem23 = MenubarRadioItem;
|
|
var ItemIndicator23 = MenubarItemIndicator;
|
|
var Separator23 = MenubarSeparator;
|
|
var Arrow25 = MenubarArrow;
|
|
var Sub23 = MenubarSub;
|
|
var SubTrigger23 = MenubarSubTrigger;
|
|
var SubContent23 = MenubarSubContent;
|
|
|
|
// ../../node_modules/@radix-ui/react-navigation-menu/dist/index.mjs
|
|
var dist_exports23 = {};
|
|
__export(dist_exports23, {
|
|
Content: () => Content4,
|
|
Indicator: () => Indicator,
|
|
Item: () => Item4,
|
|
Link: () => Link,
|
|
List: () => List,
|
|
NavigationMenu: () => NavigationMenu,
|
|
NavigationMenuContent: () => NavigationMenuContent,
|
|
NavigationMenuIndicator: () => NavigationMenuIndicator,
|
|
NavigationMenuItem: () => NavigationMenuItem,
|
|
NavigationMenuLink: () => NavigationMenuLink,
|
|
NavigationMenuList: () => NavigationMenuList,
|
|
NavigationMenuSub: () => NavigationMenuSub,
|
|
NavigationMenuTrigger: () => NavigationMenuTrigger,
|
|
NavigationMenuViewport: () => NavigationMenuViewport,
|
|
Root: () => Root29,
|
|
Sub: () => Sub3,
|
|
Trigger: () => Trigger7,
|
|
Viewport: () => Viewport,
|
|
createNavigationMenuScope: () => createNavigationMenuScope
|
|
});
|
|
var React20 = __toESM(require_react(), 1);
|
|
var import_react_dom = __toESM(require_react_dom(), 1);
|
|
var import_jsx_runtime20 = __toESM(require_jsx_runtime(), 1);
|
|
var NAVIGATION_MENU_NAME = "NavigationMenu";
|
|
var [Collection5, useCollection5, createCollectionScope5] = createCollection(NAVIGATION_MENU_NAME);
|
|
var [FocusGroupCollection, useFocusGroupCollection, createFocusGroupCollectionScope] = createCollection(NAVIGATION_MENU_NAME);
|
|
var [createNavigationMenuContext, createNavigationMenuScope] = createContextScope(
|
|
NAVIGATION_MENU_NAME,
|
|
[createCollectionScope5, createFocusGroupCollectionScope]
|
|
);
|
|
var [NavigationMenuProviderImpl, useNavigationMenuContext] = createNavigationMenuContext(NAVIGATION_MENU_NAME);
|
|
var [ViewportContentProvider, useViewportContentContext] = createNavigationMenuContext(NAVIGATION_MENU_NAME);
|
|
var NavigationMenu = React20.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const {
|
|
__scopeNavigationMenu,
|
|
value: valueProp,
|
|
onValueChange,
|
|
defaultValue,
|
|
delayDuration = 200,
|
|
skipDelayDuration = 300,
|
|
orientation = "horizontal",
|
|
dir,
|
|
...NavigationMenuProps
|
|
} = props;
|
|
const [navigationMenu, setNavigationMenu] = React20.useState(null);
|
|
const composedRef = useComposedRefs(forwardedRef, (node) => setNavigationMenu(node));
|
|
const direction = useDirection(dir);
|
|
const openTimerRef = React20.useRef(0);
|
|
const closeTimerRef = React20.useRef(0);
|
|
const skipDelayTimerRef = React20.useRef(0);
|
|
const [isOpenDelayed, setIsOpenDelayed] = React20.useState(true);
|
|
const [value, setValue] = useControllableState({
|
|
prop: valueProp,
|
|
onChange: (value2) => {
|
|
const isOpen = value2 !== "";
|
|
const hasSkipDelayDuration = skipDelayDuration > 0;
|
|
if (isOpen) {
|
|
window.clearTimeout(skipDelayTimerRef.current);
|
|
if (hasSkipDelayDuration) setIsOpenDelayed(false);
|
|
} else {
|
|
window.clearTimeout(skipDelayTimerRef.current);
|
|
skipDelayTimerRef.current = window.setTimeout(
|
|
() => setIsOpenDelayed(true),
|
|
skipDelayDuration
|
|
);
|
|
}
|
|
onValueChange == null ? void 0 : onValueChange(value2);
|
|
},
|
|
defaultProp: defaultValue ?? "",
|
|
caller: NAVIGATION_MENU_NAME
|
|
});
|
|
const startCloseTimer = React20.useCallback(() => {
|
|
window.clearTimeout(closeTimerRef.current);
|
|
closeTimerRef.current = window.setTimeout(() => setValue(""), 150);
|
|
}, [setValue]);
|
|
const handleOpen = React20.useCallback(
|
|
(itemValue) => {
|
|
window.clearTimeout(closeTimerRef.current);
|
|
setValue(itemValue);
|
|
},
|
|
[setValue]
|
|
);
|
|
const handleDelayedOpen = React20.useCallback(
|
|
(itemValue) => {
|
|
const isOpenItem = value === itemValue;
|
|
if (isOpenItem) {
|
|
window.clearTimeout(closeTimerRef.current);
|
|
} else {
|
|
openTimerRef.current = window.setTimeout(() => {
|
|
window.clearTimeout(closeTimerRef.current);
|
|
setValue(itemValue);
|
|
}, delayDuration);
|
|
}
|
|
},
|
|
[value, setValue, delayDuration]
|
|
);
|
|
React20.useEffect(() => {
|
|
return () => {
|
|
window.clearTimeout(openTimerRef.current);
|
|
window.clearTimeout(closeTimerRef.current);
|
|
window.clearTimeout(skipDelayTimerRef.current);
|
|
};
|
|
}, []);
|
|
return (0, import_jsx_runtime20.jsx)(
|
|
NavigationMenuProvider,
|
|
{
|
|
scope: __scopeNavigationMenu,
|
|
isRootMenu: true,
|
|
value,
|
|
dir: direction,
|
|
orientation,
|
|
rootNavigationMenu: navigationMenu,
|
|
onTriggerEnter: (itemValue) => {
|
|
window.clearTimeout(openTimerRef.current);
|
|
if (isOpenDelayed) handleDelayedOpen(itemValue);
|
|
else handleOpen(itemValue);
|
|
},
|
|
onTriggerLeave: () => {
|
|
window.clearTimeout(openTimerRef.current);
|
|
startCloseTimer();
|
|
},
|
|
onContentEnter: () => window.clearTimeout(closeTimerRef.current),
|
|
onContentLeave: startCloseTimer,
|
|
onItemSelect: (itemValue) => {
|
|
setValue((prevValue) => prevValue === itemValue ? "" : itemValue);
|
|
},
|
|
onItemDismiss: () => setValue(""),
|
|
children: (0, import_jsx_runtime20.jsx)(
|
|
Primitive.nav,
|
|
{
|
|
"aria-label": "Main",
|
|
"data-orientation": orientation,
|
|
dir: direction,
|
|
...NavigationMenuProps,
|
|
ref: composedRef
|
|
}
|
|
)
|
|
}
|
|
);
|
|
}
|
|
);
|
|
NavigationMenu.displayName = NAVIGATION_MENU_NAME;
|
|
var SUB_NAME4 = "NavigationMenuSub";
|
|
var NavigationMenuSub = React20.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const {
|
|
__scopeNavigationMenu,
|
|
value: valueProp,
|
|
onValueChange,
|
|
defaultValue,
|
|
orientation = "horizontal",
|
|
...subProps
|
|
} = props;
|
|
const context = useNavigationMenuContext(SUB_NAME4, __scopeNavigationMenu);
|
|
const [value, setValue] = useControllableState({
|
|
prop: valueProp,
|
|
onChange: onValueChange,
|
|
defaultProp: defaultValue ?? "",
|
|
caller: SUB_NAME4
|
|
});
|
|
return (0, import_jsx_runtime20.jsx)(
|
|
NavigationMenuProvider,
|
|
{
|
|
scope: __scopeNavigationMenu,
|
|
isRootMenu: false,
|
|
value,
|
|
dir: context.dir,
|
|
orientation,
|
|
rootNavigationMenu: context.rootNavigationMenu,
|
|
onTriggerEnter: (itemValue) => setValue(itemValue),
|
|
onItemSelect: (itemValue) => setValue(itemValue),
|
|
onItemDismiss: () => setValue(""),
|
|
children: (0, import_jsx_runtime20.jsx)(Primitive.div, { "data-orientation": orientation, ...subProps, ref: forwardedRef })
|
|
}
|
|
);
|
|
}
|
|
);
|
|
NavigationMenuSub.displayName = SUB_NAME4;
|
|
var NavigationMenuProvider = (props) => {
|
|
const {
|
|
scope,
|
|
isRootMenu,
|
|
rootNavigationMenu,
|
|
dir,
|
|
orientation,
|
|
children,
|
|
value,
|
|
onItemSelect,
|
|
onItemDismiss,
|
|
onTriggerEnter,
|
|
onTriggerLeave,
|
|
onContentEnter,
|
|
onContentLeave
|
|
} = props;
|
|
const [viewport, setViewport] = React20.useState(null);
|
|
const [viewportContent, setViewportContent] = React20.useState(/* @__PURE__ */ new Map());
|
|
const [indicatorTrack, setIndicatorTrack] = React20.useState(null);
|
|
return (0, import_jsx_runtime20.jsx)(
|
|
NavigationMenuProviderImpl,
|
|
{
|
|
scope,
|
|
isRootMenu,
|
|
rootNavigationMenu,
|
|
value,
|
|
previousValue: usePrevious(value),
|
|
baseId: useId(),
|
|
dir,
|
|
orientation,
|
|
viewport,
|
|
onViewportChange: setViewport,
|
|
indicatorTrack,
|
|
onIndicatorTrackChange: setIndicatorTrack,
|
|
onTriggerEnter: useCallbackRef(onTriggerEnter),
|
|
onTriggerLeave: useCallbackRef(onTriggerLeave),
|
|
onContentEnter: useCallbackRef(onContentEnter),
|
|
onContentLeave: useCallbackRef(onContentLeave),
|
|
onItemSelect: useCallbackRef(onItemSelect),
|
|
onItemDismiss: useCallbackRef(onItemDismiss),
|
|
onViewportContentChange: React20.useCallback((contentValue, contentData) => {
|
|
setViewportContent((prevContent) => {
|
|
prevContent.set(contentValue, contentData);
|
|
return new Map(prevContent);
|
|
});
|
|
}, []),
|
|
onViewportContentRemove: React20.useCallback((contentValue) => {
|
|
setViewportContent((prevContent) => {
|
|
if (!prevContent.has(contentValue)) return prevContent;
|
|
prevContent.delete(contentValue);
|
|
return new Map(prevContent);
|
|
});
|
|
}, []),
|
|
children: (0, import_jsx_runtime20.jsx)(Collection5.Provider, { scope, children: (0, import_jsx_runtime20.jsx)(ViewportContentProvider, { scope, items: viewportContent, children }) })
|
|
}
|
|
);
|
|
};
|
|
var LIST_NAME = "NavigationMenuList";
|
|
var NavigationMenuList = React20.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeNavigationMenu, ...listProps } = props;
|
|
const context = useNavigationMenuContext(LIST_NAME, __scopeNavigationMenu);
|
|
const list = (0, import_jsx_runtime20.jsx)(Primitive.ul, { "data-orientation": context.orientation, ...listProps, ref: forwardedRef });
|
|
return (0, import_jsx_runtime20.jsx)(Primitive.div, { style: { position: "relative" }, ref: context.onIndicatorTrackChange, children: (0, import_jsx_runtime20.jsx)(Collection5.Slot, { scope: __scopeNavigationMenu, children: context.isRootMenu ? (0, import_jsx_runtime20.jsx)(FocusGroup, { asChild: true, children: list }) : list }) });
|
|
}
|
|
);
|
|
NavigationMenuList.displayName = LIST_NAME;
|
|
var ITEM_NAME7 = "NavigationMenuItem";
|
|
var [NavigationMenuItemContextProvider, useNavigationMenuItemContext] = createNavigationMenuContext(ITEM_NAME7);
|
|
var NavigationMenuItem = React20.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeNavigationMenu, value: valueProp, ...itemProps } = props;
|
|
const autoValue = useId();
|
|
const value = valueProp || autoValue || "LEGACY_REACT_AUTO_VALUE";
|
|
const contentRef = React20.useRef(null);
|
|
const triggerRef = React20.useRef(null);
|
|
const focusProxyRef = React20.useRef(null);
|
|
const restoreContentTabOrderRef = React20.useRef(() => {
|
|
});
|
|
const wasEscapeCloseRef = React20.useRef(false);
|
|
const handleContentEntry = React20.useCallback((side = "start") => {
|
|
if (contentRef.current) {
|
|
restoreContentTabOrderRef.current();
|
|
const candidates = getTabbableCandidates(contentRef.current);
|
|
if (candidates.length) focusFirst3(side === "start" ? candidates : candidates.reverse());
|
|
}
|
|
}, []);
|
|
const handleContentExit = React20.useCallback(() => {
|
|
if (contentRef.current) {
|
|
const candidates = getTabbableCandidates(contentRef.current);
|
|
if (candidates.length) restoreContentTabOrderRef.current = removeFromTabOrder(candidates);
|
|
}
|
|
}, []);
|
|
return (0, import_jsx_runtime20.jsx)(
|
|
NavigationMenuItemContextProvider,
|
|
{
|
|
scope: __scopeNavigationMenu,
|
|
value,
|
|
triggerRef,
|
|
contentRef,
|
|
focusProxyRef,
|
|
wasEscapeCloseRef,
|
|
onEntryKeyDown: handleContentEntry,
|
|
onFocusProxyEnter: handleContentEntry,
|
|
onRootContentClose: handleContentExit,
|
|
onContentFocusOutside: handleContentExit,
|
|
children: (0, import_jsx_runtime20.jsx)(Primitive.li, { ...itemProps, ref: forwardedRef })
|
|
}
|
|
);
|
|
}
|
|
);
|
|
NavigationMenuItem.displayName = ITEM_NAME7;
|
|
var TRIGGER_NAME9 = "NavigationMenuTrigger";
|
|
var NavigationMenuTrigger = React20.forwardRef((props, forwardedRef) => {
|
|
const { __scopeNavigationMenu, disabled, ...triggerProps } = props;
|
|
const context = useNavigationMenuContext(TRIGGER_NAME9, props.__scopeNavigationMenu);
|
|
const itemContext = useNavigationMenuItemContext(TRIGGER_NAME9, props.__scopeNavigationMenu);
|
|
const ref = React20.useRef(null);
|
|
const composedRefs = useComposedRefs(ref, itemContext.triggerRef, forwardedRef);
|
|
const triggerId = makeTriggerId(context.baseId, itemContext.value);
|
|
const contentId = makeContentId(context.baseId, itemContext.value);
|
|
const hasPointerMoveOpenedRef = React20.useRef(false);
|
|
const wasClickCloseRef = React20.useRef(false);
|
|
const open = itemContext.value === context.value;
|
|
return (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
|
|
(0, import_jsx_runtime20.jsx)(Collection5.ItemSlot, { scope: __scopeNavigationMenu, value: itemContext.value, children: (0, import_jsx_runtime20.jsx)(FocusGroupItem, { asChild: true, children: (0, import_jsx_runtime20.jsx)(
|
|
Primitive.button,
|
|
{
|
|
id: triggerId,
|
|
disabled,
|
|
"data-disabled": disabled ? "" : void 0,
|
|
"data-state": getOpenState2(open),
|
|
"aria-expanded": open,
|
|
"aria-controls": contentId,
|
|
...triggerProps,
|
|
ref: composedRefs,
|
|
onPointerEnter: composeEventHandlers(props.onPointerEnter, () => {
|
|
wasClickCloseRef.current = false;
|
|
itemContext.wasEscapeCloseRef.current = false;
|
|
}),
|
|
onPointerMove: composeEventHandlers(
|
|
props.onPointerMove,
|
|
whenMouse2(() => {
|
|
if (disabled || wasClickCloseRef.current || itemContext.wasEscapeCloseRef.current || hasPointerMoveOpenedRef.current)
|
|
return;
|
|
context.onTriggerEnter(itemContext.value);
|
|
hasPointerMoveOpenedRef.current = true;
|
|
})
|
|
),
|
|
onPointerLeave: composeEventHandlers(
|
|
props.onPointerLeave,
|
|
whenMouse2(() => {
|
|
if (disabled) return;
|
|
context.onTriggerLeave();
|
|
hasPointerMoveOpenedRef.current = false;
|
|
})
|
|
),
|
|
onClick: composeEventHandlers(props.onClick, () => {
|
|
context.onItemSelect(itemContext.value);
|
|
wasClickCloseRef.current = open;
|
|
}),
|
|
onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
|
|
const verticalEntryKey = context.dir === "rtl" ? "ArrowLeft" : "ArrowRight";
|
|
const entryKey = { horizontal: "ArrowDown", vertical: verticalEntryKey }[context.orientation];
|
|
if (open && event.key === entryKey) {
|
|
itemContext.onEntryKeyDown();
|
|
event.preventDefault();
|
|
}
|
|
})
|
|
}
|
|
) }) }),
|
|
open && (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
|
|
(0, import_jsx_runtime20.jsx)(
|
|
Root4,
|
|
{
|
|
"aria-hidden": true,
|
|
tabIndex: 0,
|
|
ref: itemContext.focusProxyRef,
|
|
onFocus: (event) => {
|
|
const content = itemContext.contentRef.current;
|
|
const prevFocusedElement = event.relatedTarget;
|
|
const wasTriggerFocused = prevFocusedElement === ref.current;
|
|
const wasFocusFromContent = content == null ? void 0 : content.contains(prevFocusedElement);
|
|
if (wasTriggerFocused || !wasFocusFromContent) {
|
|
itemContext.onFocusProxyEnter(wasTriggerFocused ? "start" : "end");
|
|
}
|
|
}
|
|
}
|
|
),
|
|
context.viewport && (0, import_jsx_runtime20.jsx)("span", { "aria-owns": contentId })
|
|
] })
|
|
] });
|
|
});
|
|
NavigationMenuTrigger.displayName = TRIGGER_NAME9;
|
|
var LINK_NAME = "NavigationMenuLink";
|
|
var LINK_SELECT = "navigationMenu.linkSelect";
|
|
var NavigationMenuLink = React20.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeNavigationMenu, active, onSelect, ...linkProps } = props;
|
|
return (0, import_jsx_runtime20.jsx)(FocusGroupItem, { asChild: true, children: (0, import_jsx_runtime20.jsx)(
|
|
Primitive.a,
|
|
{
|
|
"data-active": active ? "" : void 0,
|
|
"aria-current": active ? "page" : void 0,
|
|
...linkProps,
|
|
ref: forwardedRef,
|
|
onClick: composeEventHandlers(
|
|
props.onClick,
|
|
(event) => {
|
|
const target = event.target;
|
|
const linkSelectEvent = new CustomEvent(LINK_SELECT, {
|
|
bubbles: true,
|
|
cancelable: true
|
|
});
|
|
target.addEventListener(LINK_SELECT, (event2) => onSelect == null ? void 0 : onSelect(event2), { once: true });
|
|
dispatchDiscreteCustomEvent(target, linkSelectEvent);
|
|
if (!linkSelectEvent.defaultPrevented && !event.metaKey) {
|
|
const rootContentDismissEvent = new CustomEvent(ROOT_CONTENT_DISMISS, {
|
|
bubbles: true,
|
|
cancelable: true
|
|
});
|
|
dispatchDiscreteCustomEvent(target, rootContentDismissEvent);
|
|
}
|
|
},
|
|
{ checkForDefaultPrevented: false }
|
|
)
|
|
}
|
|
) });
|
|
}
|
|
);
|
|
NavigationMenuLink.displayName = LINK_NAME;
|
|
var INDICATOR_NAME5 = "NavigationMenuIndicator";
|
|
var NavigationMenuIndicator = React20.forwardRef((props, forwardedRef) => {
|
|
const { forceMount, ...indicatorProps } = props;
|
|
const context = useNavigationMenuContext(INDICATOR_NAME5, props.__scopeNavigationMenu);
|
|
const isVisible = Boolean(context.value);
|
|
return context.indicatorTrack ? import_react_dom.default.createPortal(
|
|
(0, import_jsx_runtime20.jsx)(Presence, { present: forceMount || isVisible, children: (0, import_jsx_runtime20.jsx)(NavigationMenuIndicatorImpl, { ...indicatorProps, ref: forwardedRef }) }),
|
|
context.indicatorTrack
|
|
) : null;
|
|
});
|
|
NavigationMenuIndicator.displayName = INDICATOR_NAME5;
|
|
var NavigationMenuIndicatorImpl = React20.forwardRef((props, forwardedRef) => {
|
|
const { __scopeNavigationMenu, ...indicatorProps } = props;
|
|
const context = useNavigationMenuContext(INDICATOR_NAME5, __scopeNavigationMenu);
|
|
const getItems = useCollection5(__scopeNavigationMenu);
|
|
const [activeTrigger, setActiveTrigger] = React20.useState(
|
|
null
|
|
);
|
|
const [position, setPosition] = React20.useState(null);
|
|
const isHorizontal = context.orientation === "horizontal";
|
|
const isVisible = Boolean(context.value);
|
|
React20.useEffect(() => {
|
|
var _a2;
|
|
const items = getItems();
|
|
const triggerNode = (_a2 = items.find((item) => item.value === context.value)) == null ? void 0 : _a2.ref.current;
|
|
if (triggerNode) setActiveTrigger(triggerNode);
|
|
}, [getItems, context.value]);
|
|
const handlePositionChange = () => {
|
|
if (activeTrigger) {
|
|
setPosition({
|
|
size: isHorizontal ? activeTrigger.offsetWidth : activeTrigger.offsetHeight,
|
|
offset: isHorizontal ? activeTrigger.offsetLeft : activeTrigger.offsetTop
|
|
});
|
|
}
|
|
};
|
|
useResizeObserver(activeTrigger, handlePositionChange);
|
|
useResizeObserver(context.indicatorTrack, handlePositionChange);
|
|
return position ? (0, import_jsx_runtime20.jsx)(
|
|
Primitive.div,
|
|
{
|
|
"aria-hidden": true,
|
|
"data-state": isVisible ? "visible" : "hidden",
|
|
"data-orientation": context.orientation,
|
|
...indicatorProps,
|
|
ref: forwardedRef,
|
|
style: {
|
|
position: "absolute",
|
|
...isHorizontal ? {
|
|
left: 0,
|
|
width: position.size + "px",
|
|
transform: `translateX(${position.offset}px)`
|
|
} : {
|
|
top: 0,
|
|
height: position.size + "px",
|
|
transform: `translateY(${position.offset}px)`
|
|
},
|
|
...indicatorProps.style
|
|
}
|
|
}
|
|
) : null;
|
|
});
|
|
var CONTENT_NAME9 = "NavigationMenuContent";
|
|
var NavigationMenuContent = React20.forwardRef((props, forwardedRef) => {
|
|
const { forceMount, ...contentProps } = props;
|
|
const context = useNavigationMenuContext(CONTENT_NAME9, props.__scopeNavigationMenu);
|
|
const itemContext = useNavigationMenuItemContext(CONTENT_NAME9, props.__scopeNavigationMenu);
|
|
const composedRefs = useComposedRefs(itemContext.contentRef, forwardedRef);
|
|
const open = itemContext.value === context.value;
|
|
const commonProps = {
|
|
value: itemContext.value,
|
|
triggerRef: itemContext.triggerRef,
|
|
focusProxyRef: itemContext.focusProxyRef,
|
|
wasEscapeCloseRef: itemContext.wasEscapeCloseRef,
|
|
onContentFocusOutside: itemContext.onContentFocusOutside,
|
|
onRootContentClose: itemContext.onRootContentClose,
|
|
...contentProps
|
|
};
|
|
return !context.viewport ? (0, import_jsx_runtime20.jsx)(Presence, { present: forceMount || open, children: (0, import_jsx_runtime20.jsx)(
|
|
NavigationMenuContentImpl,
|
|
{
|
|
"data-state": getOpenState2(open),
|
|
...commonProps,
|
|
ref: composedRefs,
|
|
onPointerEnter: composeEventHandlers(props.onPointerEnter, context.onContentEnter),
|
|
onPointerLeave: composeEventHandlers(
|
|
props.onPointerLeave,
|
|
whenMouse2(context.onContentLeave)
|
|
),
|
|
style: {
|
|
// Prevent interaction when animating out
|
|
pointerEvents: !open && context.isRootMenu ? "none" : void 0,
|
|
...commonProps.style
|
|
}
|
|
}
|
|
) }) : (0, import_jsx_runtime20.jsx)(ViewportContentMounter, { forceMount, ...commonProps, ref: composedRefs });
|
|
});
|
|
NavigationMenuContent.displayName = CONTENT_NAME9;
|
|
var ViewportContentMounter = React20.forwardRef((props, forwardedRef) => {
|
|
const context = useNavigationMenuContext(CONTENT_NAME9, props.__scopeNavigationMenu);
|
|
const { onViewportContentChange, onViewportContentRemove } = context;
|
|
useLayoutEffect2(() => {
|
|
onViewportContentChange(props.value, {
|
|
ref: forwardedRef,
|
|
...props
|
|
});
|
|
}, [props, forwardedRef, onViewportContentChange]);
|
|
useLayoutEffect2(() => {
|
|
return () => onViewportContentRemove(props.value);
|
|
}, [props.value, onViewportContentRemove]);
|
|
return null;
|
|
});
|
|
var ROOT_CONTENT_DISMISS = "navigationMenu.rootContentDismiss";
|
|
var NavigationMenuContentImpl = React20.forwardRef((props, forwardedRef) => {
|
|
const {
|
|
__scopeNavigationMenu,
|
|
value,
|
|
triggerRef,
|
|
focusProxyRef,
|
|
wasEscapeCloseRef,
|
|
onRootContentClose,
|
|
onContentFocusOutside,
|
|
...contentProps
|
|
} = props;
|
|
const context = useNavigationMenuContext(CONTENT_NAME9, __scopeNavigationMenu);
|
|
const ref = React20.useRef(null);
|
|
const composedRefs = useComposedRefs(ref, forwardedRef);
|
|
const triggerId = makeTriggerId(context.baseId, value);
|
|
const contentId = makeContentId(context.baseId, value);
|
|
const getItems = useCollection5(__scopeNavigationMenu);
|
|
const prevMotionAttributeRef = React20.useRef(null);
|
|
const { onItemDismiss } = context;
|
|
React20.useEffect(() => {
|
|
const content = ref.current;
|
|
if (context.isRootMenu && content) {
|
|
const handleClose = () => {
|
|
var _a2;
|
|
onItemDismiss();
|
|
onRootContentClose();
|
|
if (content.contains(document.activeElement)) (_a2 = triggerRef.current) == null ? void 0 : _a2.focus();
|
|
};
|
|
content.addEventListener(ROOT_CONTENT_DISMISS, handleClose);
|
|
return () => content.removeEventListener(ROOT_CONTENT_DISMISS, handleClose);
|
|
}
|
|
}, [context.isRootMenu, props.value, triggerRef, onItemDismiss, onRootContentClose]);
|
|
const motionAttribute = React20.useMemo(() => {
|
|
const items = getItems();
|
|
const values = items.map((item) => item.value);
|
|
if (context.dir === "rtl") values.reverse();
|
|
const index = values.indexOf(context.value);
|
|
const prevIndex = values.indexOf(context.previousValue);
|
|
const isSelected = value === context.value;
|
|
const wasSelected = prevIndex === values.indexOf(value);
|
|
if (!isSelected && !wasSelected) return prevMotionAttributeRef.current;
|
|
const attribute = (() => {
|
|
if (index !== prevIndex) {
|
|
if (isSelected && prevIndex !== -1) return index > prevIndex ? "from-end" : "from-start";
|
|
if (wasSelected && index !== -1) return index > prevIndex ? "to-start" : "to-end";
|
|
}
|
|
return null;
|
|
})();
|
|
prevMotionAttributeRef.current = attribute;
|
|
return attribute;
|
|
}, [context.previousValue, context.value, context.dir, getItems, value]);
|
|
return (0, import_jsx_runtime20.jsx)(FocusGroup, { asChild: true, children: (0, import_jsx_runtime20.jsx)(
|
|
DismissableLayer,
|
|
{
|
|
id: contentId,
|
|
"aria-labelledby": triggerId,
|
|
"data-motion": motionAttribute,
|
|
"data-orientation": context.orientation,
|
|
...contentProps,
|
|
ref: composedRefs,
|
|
disableOutsidePointerEvents: false,
|
|
onDismiss: () => {
|
|
var _a2;
|
|
const rootContentDismissEvent = new Event(ROOT_CONTENT_DISMISS, {
|
|
bubbles: true,
|
|
cancelable: true
|
|
});
|
|
(_a2 = ref.current) == null ? void 0 : _a2.dispatchEvent(rootContentDismissEvent);
|
|
},
|
|
onFocusOutside: composeEventHandlers(props.onFocusOutside, (event) => {
|
|
var _a2;
|
|
onContentFocusOutside();
|
|
const target = event.target;
|
|
if ((_a2 = context.rootNavigationMenu) == null ? void 0 : _a2.contains(target)) event.preventDefault();
|
|
}),
|
|
onPointerDownOutside: composeEventHandlers(props.onPointerDownOutside, (event) => {
|
|
var _a2;
|
|
const target = event.target;
|
|
const isTrigger = getItems().some((item) => {
|
|
var _a3;
|
|
return (_a3 = item.ref.current) == null ? void 0 : _a3.contains(target);
|
|
});
|
|
const isRootViewport = context.isRootMenu && ((_a2 = context.viewport) == null ? void 0 : _a2.contains(target));
|
|
if (isTrigger || isRootViewport || !context.isRootMenu) event.preventDefault();
|
|
}),
|
|
onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
|
|
var _a2;
|
|
const isMetaKey = event.altKey || event.ctrlKey || event.metaKey;
|
|
const isTabKey = event.key === "Tab" && !isMetaKey;
|
|
if (isTabKey) {
|
|
const candidates = getTabbableCandidates(event.currentTarget);
|
|
const focusedElement = document.activeElement;
|
|
const index = candidates.findIndex((candidate) => candidate === focusedElement);
|
|
const isMovingBackwards = event.shiftKey;
|
|
const nextCandidates = isMovingBackwards ? candidates.slice(0, index).reverse() : candidates.slice(index + 1, candidates.length);
|
|
if (focusFirst3(nextCandidates)) {
|
|
event.preventDefault();
|
|
} else {
|
|
(_a2 = focusProxyRef.current) == null ? void 0 : _a2.focus();
|
|
}
|
|
}
|
|
}),
|
|
onEscapeKeyDown: composeEventHandlers(props.onEscapeKeyDown, (_event) => {
|
|
wasEscapeCloseRef.current = true;
|
|
})
|
|
}
|
|
) });
|
|
});
|
|
var VIEWPORT_NAME = "NavigationMenuViewport";
|
|
var NavigationMenuViewport = React20.forwardRef((props, forwardedRef) => {
|
|
const { forceMount, ...viewportProps } = props;
|
|
const context = useNavigationMenuContext(VIEWPORT_NAME, props.__scopeNavigationMenu);
|
|
const open = Boolean(context.value);
|
|
return (0, import_jsx_runtime20.jsx)(Presence, { present: forceMount || open, children: (0, import_jsx_runtime20.jsx)(NavigationMenuViewportImpl, { ...viewportProps, ref: forwardedRef }) });
|
|
});
|
|
NavigationMenuViewport.displayName = VIEWPORT_NAME;
|
|
var NavigationMenuViewportImpl = React20.forwardRef((props, forwardedRef) => {
|
|
const { __scopeNavigationMenu, children, ...viewportImplProps } = props;
|
|
const context = useNavigationMenuContext(VIEWPORT_NAME, __scopeNavigationMenu);
|
|
const composedRefs = useComposedRefs(forwardedRef, context.onViewportChange);
|
|
const viewportContentContext = useViewportContentContext(
|
|
CONTENT_NAME9,
|
|
props.__scopeNavigationMenu
|
|
);
|
|
const [size, setSize] = React20.useState(null);
|
|
const [content, setContent] = React20.useState(null);
|
|
const viewportWidth = size ? (size == null ? void 0 : size.width) + "px" : void 0;
|
|
const viewportHeight = size ? (size == null ? void 0 : size.height) + "px" : void 0;
|
|
const open = Boolean(context.value);
|
|
const activeContentValue = open ? context.value : context.previousValue;
|
|
const handleSizeChange = () => {
|
|
if (content) setSize({ width: content.offsetWidth, height: content.offsetHeight });
|
|
};
|
|
useResizeObserver(content, handleSizeChange);
|
|
return (0, import_jsx_runtime20.jsx)(
|
|
Primitive.div,
|
|
{
|
|
"data-state": getOpenState2(open),
|
|
"data-orientation": context.orientation,
|
|
...viewportImplProps,
|
|
ref: composedRefs,
|
|
style: {
|
|
// Prevent interaction when animating out
|
|
pointerEvents: !open && context.isRootMenu ? "none" : void 0,
|
|
["--radix-navigation-menu-viewport-width"]: viewportWidth,
|
|
["--radix-navigation-menu-viewport-height"]: viewportHeight,
|
|
...viewportImplProps.style
|
|
},
|
|
onPointerEnter: composeEventHandlers(props.onPointerEnter, context.onContentEnter),
|
|
onPointerLeave: composeEventHandlers(props.onPointerLeave, whenMouse2(context.onContentLeave)),
|
|
children: Array.from(viewportContentContext.items).map(([value, { ref, forceMount, ...props2 }]) => {
|
|
const isActive = activeContentValue === value;
|
|
return (0, import_jsx_runtime20.jsx)(Presence, { present: forceMount || isActive, children: (0, import_jsx_runtime20.jsx)(
|
|
NavigationMenuContentImpl,
|
|
{
|
|
...props2,
|
|
ref: composeRefs(ref, (node) => {
|
|
if (isActive && node) setContent(node);
|
|
})
|
|
}
|
|
) }, value);
|
|
})
|
|
}
|
|
);
|
|
});
|
|
var FOCUS_GROUP_NAME = "FocusGroup";
|
|
var FocusGroup = React20.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeNavigationMenu, ...groupProps } = props;
|
|
const context = useNavigationMenuContext(FOCUS_GROUP_NAME, __scopeNavigationMenu);
|
|
return (0, import_jsx_runtime20.jsx)(FocusGroupCollection.Provider, { scope: __scopeNavigationMenu, children: (0, import_jsx_runtime20.jsx)(FocusGroupCollection.Slot, { scope: __scopeNavigationMenu, children: (0, import_jsx_runtime20.jsx)(Primitive.div, { dir: context.dir, ...groupProps, ref: forwardedRef }) }) });
|
|
}
|
|
);
|
|
var ARROW_KEYS = ["ArrowRight", "ArrowLeft", "ArrowUp", "ArrowDown"];
|
|
var FOCUS_GROUP_ITEM_NAME = "FocusGroupItem";
|
|
var FocusGroupItem = React20.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeNavigationMenu, ...groupProps } = props;
|
|
const getItems = useFocusGroupCollection(__scopeNavigationMenu);
|
|
const context = useNavigationMenuContext(FOCUS_GROUP_ITEM_NAME, __scopeNavigationMenu);
|
|
return (0, import_jsx_runtime20.jsx)(FocusGroupCollection.ItemSlot, { scope: __scopeNavigationMenu, children: (0, import_jsx_runtime20.jsx)(
|
|
Primitive.button,
|
|
{
|
|
...groupProps,
|
|
ref: forwardedRef,
|
|
onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
|
|
const isFocusNavigationKey = ["Home", "End", ...ARROW_KEYS].includes(event.key);
|
|
if (isFocusNavigationKey) {
|
|
let candidateNodes = getItems().map((item) => item.ref.current);
|
|
const prevItemKey = context.dir === "rtl" ? "ArrowRight" : "ArrowLeft";
|
|
const prevKeys = [prevItemKey, "ArrowUp", "End"];
|
|
if (prevKeys.includes(event.key)) candidateNodes.reverse();
|
|
if (ARROW_KEYS.includes(event.key)) {
|
|
const currentIndex = candidateNodes.indexOf(event.currentTarget);
|
|
candidateNodes = candidateNodes.slice(currentIndex + 1);
|
|
}
|
|
setTimeout(() => focusFirst3(candidateNodes));
|
|
event.preventDefault();
|
|
}
|
|
})
|
|
}
|
|
) });
|
|
}
|
|
);
|
|
function getTabbableCandidates(container) {
|
|
const nodes = [];
|
|
const walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT, {
|
|
acceptNode: (node) => {
|
|
const isHiddenInput = node.tagName === "INPUT" && node.type === "hidden";
|
|
if (node.disabled || node.hidden || isHiddenInput) return NodeFilter.FILTER_SKIP;
|
|
return node.tabIndex >= 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
|
|
}
|
|
});
|
|
while (walker.nextNode()) nodes.push(walker.currentNode);
|
|
return nodes;
|
|
}
|
|
function focusFirst3(candidates) {
|
|
const previouslyFocusedElement = document.activeElement;
|
|
return candidates.some((candidate) => {
|
|
if (candidate === previouslyFocusedElement) return true;
|
|
candidate.focus();
|
|
return document.activeElement !== previouslyFocusedElement;
|
|
});
|
|
}
|
|
function removeFromTabOrder(candidates) {
|
|
candidates.forEach((candidate) => {
|
|
candidate.dataset.tabindex = candidate.getAttribute("tabindex") || "";
|
|
candidate.setAttribute("tabindex", "-1");
|
|
});
|
|
return () => {
|
|
candidates.forEach((candidate) => {
|
|
const prevTabIndex = candidate.dataset.tabindex;
|
|
candidate.setAttribute("tabindex", prevTabIndex);
|
|
});
|
|
};
|
|
}
|
|
function useResizeObserver(element, onResize) {
|
|
const handleResize = useCallbackRef(onResize);
|
|
useLayoutEffect2(() => {
|
|
let rAF = 0;
|
|
if (element) {
|
|
const resizeObserver = new ResizeObserver(() => {
|
|
cancelAnimationFrame(rAF);
|
|
rAF = window.requestAnimationFrame(handleResize);
|
|
});
|
|
resizeObserver.observe(element);
|
|
return () => {
|
|
window.cancelAnimationFrame(rAF);
|
|
resizeObserver.unobserve(element);
|
|
};
|
|
}
|
|
}, [element, handleResize]);
|
|
}
|
|
function getOpenState2(open) {
|
|
return open ? "open" : "closed";
|
|
}
|
|
function makeTriggerId(baseId, value) {
|
|
return `${baseId}-trigger-${value}`;
|
|
}
|
|
function makeContentId(baseId, value) {
|
|
return `${baseId}-content-${value}`;
|
|
}
|
|
function whenMouse2(handler) {
|
|
return (event) => event.pointerType === "mouse" ? handler(event) : void 0;
|
|
}
|
|
var Root29 = NavigationMenu;
|
|
var Sub3 = NavigationMenuSub;
|
|
var List = NavigationMenuList;
|
|
var Item4 = NavigationMenuItem;
|
|
var Trigger7 = NavigationMenuTrigger;
|
|
var Link = NavigationMenuLink;
|
|
var Indicator = NavigationMenuIndicator;
|
|
var Content4 = NavigationMenuContent;
|
|
var Viewport = NavigationMenuViewport;
|
|
|
|
// ../../node_modules/@radix-ui/react-one-time-password-field/dist/index.mjs
|
|
var dist_exports24 = {};
|
|
__export(dist_exports24, {
|
|
HiddenInput: () => OneTimePasswordFieldHiddenInput,
|
|
Input: () => OneTimePasswordFieldInput,
|
|
OneTimePasswordField: () => OneTimePasswordField,
|
|
OneTimePasswordFieldHiddenInput: () => OneTimePasswordFieldHiddenInput,
|
|
OneTimePasswordFieldInput: () => OneTimePasswordFieldInput,
|
|
Root: () => OneTimePasswordField
|
|
});
|
|
var React21 = __toESM(require_react(), 1);
|
|
var import_react_dom2 = __toESM(require_react_dom(), 1);
|
|
|
|
// ../../node_modules/@radix-ui/number/dist/index.mjs
|
|
function clamp(value, [min, max]) {
|
|
return Math.min(max, Math.max(min, value));
|
|
}
|
|
|
|
// ../../node_modules/@radix-ui/react-one-time-password-field/dist/index.mjs
|
|
var import_jsx_runtime21 = __toESM(require_jsx_runtime(), 1);
|
|
var INPUT_VALIDATION_MAP = {
|
|
numeric: {
|
|
type: "numeric",
|
|
regexp: /[^\d]/g,
|
|
pattern: "\\d{1}",
|
|
inputMode: "numeric"
|
|
},
|
|
alpha: {
|
|
type: "alpha",
|
|
regexp: /[^a-zA-Z]/g,
|
|
pattern: "[a-zA-Z]{1}",
|
|
inputMode: "text"
|
|
},
|
|
alphanumeric: {
|
|
type: "alphanumeric",
|
|
regexp: /[^a-zA-Z0-9]/g,
|
|
pattern: "[a-zA-Z0-9]{1}",
|
|
inputMode: "text"
|
|
},
|
|
none: null
|
|
};
|
|
var ONE_TIME_PASSWORD_FIELD_NAME = "OneTimePasswordField";
|
|
var [Collection6, { useCollection: useCollection6, createCollectionScope: createCollectionScope6, useInitCollection }] = createCollection2(ONE_TIME_PASSWORD_FIELD_NAME);
|
|
var [createOneTimePasswordFieldContext] = createContextScope(ONE_TIME_PASSWORD_FIELD_NAME, [
|
|
createCollectionScope6,
|
|
createRovingFocusGroupScope
|
|
]);
|
|
var useRovingFocusGroupScope3 = createRovingFocusGroupScope();
|
|
var [OneTimePasswordFieldContext, useOneTimePasswordFieldContext] = createOneTimePasswordFieldContext(ONE_TIME_PASSWORD_FIELD_NAME);
|
|
var OneTimePasswordField = React21.forwardRef(
|
|
function OneTimePasswordFieldImpl({
|
|
__scopeOneTimePasswordField,
|
|
defaultValue,
|
|
value: valueProp,
|
|
onValueChange,
|
|
autoSubmit = false,
|
|
children,
|
|
onPaste,
|
|
onAutoSubmit,
|
|
disabled = false,
|
|
readOnly = false,
|
|
autoComplete = "one-time-code",
|
|
autoFocus = false,
|
|
form,
|
|
name,
|
|
placeholder,
|
|
type = "text",
|
|
// TODO: Change default to vertical when inputs use vertical writing mode
|
|
orientation = "horizontal",
|
|
dir,
|
|
validationType = "numeric",
|
|
sanitizeValue: sanitizeValueProp,
|
|
...domProps
|
|
}, forwardedRef) {
|
|
var _a2;
|
|
const rovingFocusGroupScope = useRovingFocusGroupScope3(__scopeOneTimePasswordField);
|
|
const direction = useDirection(dir);
|
|
const collectionState = useInitCollection();
|
|
const [collection] = collectionState;
|
|
const validation = INPUT_VALIDATION_MAP[validationType] ? INPUT_VALIDATION_MAP[validationType] : null;
|
|
const sanitizeValue = React21.useCallback(
|
|
(value2) => {
|
|
if (Array.isArray(value2)) {
|
|
value2 = value2.map(removeWhitespace).join("");
|
|
} else {
|
|
value2 = removeWhitespace(value2);
|
|
}
|
|
if (validation) {
|
|
const regexp = new RegExp(validation.regexp);
|
|
value2 = value2.replace(regexp, "");
|
|
} else if (sanitizeValueProp) {
|
|
value2 = sanitizeValueProp(value2);
|
|
}
|
|
return value2.split("");
|
|
},
|
|
[validation, sanitizeValueProp]
|
|
);
|
|
const controlledValue = React21.useMemo(() => {
|
|
return valueProp != null ? sanitizeValue(valueProp) : void 0;
|
|
}, [valueProp, sanitizeValue]);
|
|
const [value, setValue] = useControllableState({
|
|
caller: "OneTimePasswordField",
|
|
prop: controlledValue,
|
|
defaultProp: defaultValue != null ? sanitizeValue(defaultValue) : [],
|
|
onChange: React21.useCallback(
|
|
(value2) => onValueChange == null ? void 0 : onValueChange(value2.join("")),
|
|
[onValueChange]
|
|
)
|
|
});
|
|
const dispatch = useEffectEvent((action) => {
|
|
var _a3, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
switch (action.type) {
|
|
case "SET_CHAR": {
|
|
const { index, char } = action;
|
|
const currentTarget = (_a3 = collection.at(index)) == null ? void 0 : _a3.element;
|
|
if (value[index] === char) {
|
|
const next = currentTarget && ((_b = collection.from(currentTarget, 1)) == null ? void 0 : _b.element);
|
|
focusInput(next);
|
|
return;
|
|
}
|
|
if (char === "") {
|
|
return;
|
|
}
|
|
if (validation) {
|
|
const regexp = new RegExp(validation.regexp);
|
|
const clean = char.replace(regexp, "");
|
|
if (clean !== char) {
|
|
return;
|
|
}
|
|
}
|
|
if (value.length >= collection.size) {
|
|
const newValue2 = [...value];
|
|
newValue2[index] = char;
|
|
(0, import_react_dom2.flushSync)(() => setValue(newValue2));
|
|
const next = currentTarget && ((_c = collection.from(currentTarget, 1)) == null ? void 0 : _c.element);
|
|
focusInput(next);
|
|
return;
|
|
}
|
|
const newValue = [...value];
|
|
newValue[index] = char;
|
|
const lastElement = (_d = collection.at(-1)) == null ? void 0 : _d.element;
|
|
(0, import_react_dom2.flushSync)(() => setValue(newValue));
|
|
if (currentTarget !== lastElement) {
|
|
const next = currentTarget && ((_e = collection.from(currentTarget, 1)) == null ? void 0 : _e.element);
|
|
focusInput(next);
|
|
} else {
|
|
currentTarget == null ? void 0 : currentTarget.select();
|
|
}
|
|
return;
|
|
}
|
|
case "CLEAR_CHAR": {
|
|
const { index, reason } = action;
|
|
if (!value[index]) {
|
|
return;
|
|
}
|
|
const newValue = value.filter((_, i) => i !== index);
|
|
const currentTarget = (_f = collection.at(index)) == null ? void 0 : _f.element;
|
|
const previous = currentTarget && ((_g = collection.from(currentTarget, -1)) == null ? void 0 : _g.element);
|
|
(0, import_react_dom2.flushSync)(() => setValue(newValue));
|
|
if (reason === "Backspace") {
|
|
focusInput(previous);
|
|
} else if (reason === "Delete" || reason === "Cut") {
|
|
focusInput(currentTarget);
|
|
}
|
|
return;
|
|
}
|
|
case "CLEAR": {
|
|
if (value.length === 0) {
|
|
return;
|
|
}
|
|
if (action.reason === "Backspace" || action.reason === "Delete") {
|
|
(0, import_react_dom2.flushSync)(() => setValue([]));
|
|
focusInput((_h = collection.at(0)) == null ? void 0 : _h.element);
|
|
} else {
|
|
setValue([]);
|
|
}
|
|
return;
|
|
}
|
|
case "PASTE": {
|
|
const { value: pastedValue } = action;
|
|
const value2 = sanitizeValue(pastedValue);
|
|
if (!value2) {
|
|
return;
|
|
}
|
|
(0, import_react_dom2.flushSync)(() => setValue(value2));
|
|
focusInput((_i = collection.at(value2.length - 1)) == null ? void 0 : _i.element);
|
|
return;
|
|
}
|
|
}
|
|
});
|
|
const validationTypeRef = React21.useRef(validation);
|
|
React21.useEffect(() => {
|
|
var _a3;
|
|
if (!validation) {
|
|
return;
|
|
}
|
|
if (((_a3 = validationTypeRef.current) == null ? void 0 : _a3.type) !== validation.type) {
|
|
validationTypeRef.current = validation;
|
|
setValue(sanitizeValue(value.join("")));
|
|
}
|
|
}, [sanitizeValue, setValue, validation, value]);
|
|
const hiddenInputRef = React21.useRef(null);
|
|
const userActionRef = React21.useRef(null);
|
|
const rootRef = React21.useRef(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, rootRef);
|
|
const firstInput = (_a2 = collection.at(0)) == null ? void 0 : _a2.element;
|
|
const locateForm = React21.useCallback(() => {
|
|
var _a3;
|
|
let formElement;
|
|
if (form) {
|
|
const associatedElement = (((_a3 = rootRef.current) == null ? void 0 : _a3.ownerDocument) ?? document).getElementById(form);
|
|
if (isFormElement(associatedElement)) {
|
|
formElement = associatedElement;
|
|
}
|
|
} else if (hiddenInputRef.current) {
|
|
formElement = hiddenInputRef.current.form;
|
|
} else if (firstInput) {
|
|
formElement = firstInput.form;
|
|
}
|
|
return formElement ?? null;
|
|
}, [form, firstInput]);
|
|
const attemptSubmit = React21.useCallback(() => {
|
|
const formElement = locateForm();
|
|
formElement == null ? void 0 : formElement.requestSubmit();
|
|
}, [locateForm]);
|
|
React21.useEffect(() => {
|
|
const form2 = locateForm();
|
|
if (form2) {
|
|
const reset = () => dispatch({ type: "CLEAR", reason: "Reset" });
|
|
form2.addEventListener("reset", reset);
|
|
return () => form2.removeEventListener("reset", reset);
|
|
}
|
|
}, [dispatch, locateForm]);
|
|
const currentValue = value.join("");
|
|
const valueRef = React21.useRef(currentValue);
|
|
const length = collection.size;
|
|
React21.useEffect(() => {
|
|
const previousValue = valueRef.current;
|
|
valueRef.current = currentValue;
|
|
if (previousValue === currentValue) {
|
|
return;
|
|
}
|
|
if (autoSubmit && value.every((char) => char !== "") && value.length === length) {
|
|
onAutoSubmit == null ? void 0 : onAutoSubmit(value.join(""));
|
|
attemptSubmit();
|
|
}
|
|
}, [attemptSubmit, autoSubmit, currentValue, length, onAutoSubmit, value]);
|
|
const isHydrated = useIsHydrated();
|
|
return (0, import_jsx_runtime21.jsx)(
|
|
OneTimePasswordFieldContext,
|
|
{
|
|
scope: __scopeOneTimePasswordField,
|
|
value,
|
|
attemptSubmit,
|
|
disabled,
|
|
readOnly,
|
|
autoComplete,
|
|
autoFocus,
|
|
form,
|
|
name,
|
|
placeholder,
|
|
type,
|
|
hiddenInputRef,
|
|
userActionRef,
|
|
dispatch,
|
|
validationType,
|
|
orientation,
|
|
isHydrated,
|
|
sanitizeValue,
|
|
children: (0, import_jsx_runtime21.jsx)(Collection6.Provider, { scope: __scopeOneTimePasswordField, state: collectionState, children: (0, import_jsx_runtime21.jsx)(Collection6.Slot, { scope: __scopeOneTimePasswordField, children: (0, import_jsx_runtime21.jsx)(
|
|
Root8,
|
|
{
|
|
asChild: true,
|
|
...rovingFocusGroupScope,
|
|
orientation,
|
|
dir: direction,
|
|
children: (0, import_jsx_runtime21.jsx)(
|
|
Root.div,
|
|
{
|
|
...domProps,
|
|
role: "group",
|
|
ref: composedRefs,
|
|
onPaste: composeEventHandlers(
|
|
onPaste,
|
|
(event) => {
|
|
event.preventDefault();
|
|
const pastedValue = event.clipboardData.getData("Text");
|
|
dispatch({ type: "PASTE", value: pastedValue });
|
|
}
|
|
),
|
|
children
|
|
}
|
|
)
|
|
}
|
|
) }) })
|
|
}
|
|
);
|
|
}
|
|
);
|
|
var OneTimePasswordFieldHiddenInput = React21.forwardRef(function OneTimePasswordFieldHiddenInput2({ __scopeOneTimePasswordField, ...props }, forwardedRef) {
|
|
const { value, hiddenInputRef, name } = useOneTimePasswordFieldContext(
|
|
"OneTimePasswordFieldHiddenInput",
|
|
__scopeOneTimePasswordField
|
|
);
|
|
const ref = useComposedRefs(hiddenInputRef, forwardedRef);
|
|
return (0, import_jsx_runtime21.jsx)(
|
|
"input",
|
|
{
|
|
ref,
|
|
name,
|
|
value: value.join("").trim(),
|
|
autoComplete: "off",
|
|
autoFocus: false,
|
|
autoCapitalize: "off",
|
|
autoCorrect: "off",
|
|
autoSave: "off",
|
|
spellCheck: false,
|
|
...props,
|
|
type: "hidden",
|
|
readOnly: true
|
|
}
|
|
);
|
|
});
|
|
var OneTimePasswordFieldInput = React21.forwardRef(function OneTimePasswordFieldInput2({
|
|
__scopeOneTimePasswordField,
|
|
onInvalidChange,
|
|
index: indexProp,
|
|
...props
|
|
}, forwardedRef) {
|
|
const {
|
|
value: _value,
|
|
defaultValue: _defaultValue,
|
|
disabled: _disabled,
|
|
readOnly: _readOnly,
|
|
autoComplete: _autoComplete,
|
|
autoFocus: _autoFocus,
|
|
form: _form,
|
|
name: _name,
|
|
placeholder: _placeholder,
|
|
type: _type,
|
|
...domProps
|
|
} = props;
|
|
const context = useOneTimePasswordFieldContext(
|
|
"OneTimePasswordFieldInput",
|
|
__scopeOneTimePasswordField
|
|
);
|
|
const { dispatch, userActionRef, validationType, isHydrated, disabled } = context;
|
|
const collection = useCollection6(__scopeOneTimePasswordField);
|
|
const rovingFocusGroupScope = useRovingFocusGroupScope3(__scopeOneTimePasswordField);
|
|
const inputRef = React21.useRef(null);
|
|
const [element, setElement] = React21.useState(null);
|
|
const index = indexProp ?? (element ? collection.indexOf(element) : -1);
|
|
const canSetPlaceholder = indexProp != null || isHydrated;
|
|
let placeholder;
|
|
if (canSetPlaceholder && context.placeholder && context.value.length === 0) {
|
|
placeholder = context.placeholder[index];
|
|
}
|
|
const composedInputRef = useComposedRefs(forwardedRef, inputRef, setElement);
|
|
const char = context.value[index] ?? "";
|
|
const keyboardActionTimeoutRef = React21.useRef(null);
|
|
React21.useEffect(() => {
|
|
return () => {
|
|
window.clearTimeout(keyboardActionTimeoutRef.current);
|
|
};
|
|
}, []);
|
|
const totalValue = context.value.join("").trim();
|
|
const lastSelectableIndex = clamp(totalValue.length, [0, collection.size - 1]);
|
|
const isFocusable = index <= lastSelectableIndex;
|
|
const validation = validationType in INPUT_VALIDATION_MAP ? INPUT_VALIDATION_MAP[validationType] : void 0;
|
|
return (0, import_jsx_runtime21.jsx)(Collection6.ItemSlot, { scope: __scopeOneTimePasswordField, children: (0, import_jsx_runtime21.jsx)(
|
|
Item2,
|
|
{
|
|
...rovingFocusGroupScope,
|
|
asChild: true,
|
|
focusable: !context.disabled && isFocusable,
|
|
active: index === lastSelectableIndex,
|
|
children: ({ hasTabStop, isCurrentTabStop }) => {
|
|
const supportsAutoComplete = hasTabStop ? isCurrentTabStop : index === 0;
|
|
return (0, import_jsx_runtime21.jsx)(
|
|
Root.input,
|
|
{
|
|
ref: composedInputRef,
|
|
type: context.type,
|
|
disabled,
|
|
"aria-label": `Character ${index + 1} of ${collection.size}`,
|
|
autoComplete: supportsAutoComplete ? context.autoComplete : "off",
|
|
"data-1p-ignore": supportsAutoComplete ? void 0 : "true",
|
|
"data-lpignore": supportsAutoComplete ? void 0 : "true",
|
|
"data-protonpass-ignore": supportsAutoComplete ? void 0 : "true",
|
|
"data-bwignore": supportsAutoComplete ? void 0 : "true",
|
|
inputMode: validation == null ? void 0 : validation.inputMode,
|
|
maxLength: 1,
|
|
pattern: validation == null ? void 0 : validation.pattern,
|
|
readOnly: context.readOnly,
|
|
value: char,
|
|
placeholder,
|
|
"data-radix-otp-input": "",
|
|
"data-radix-index": index,
|
|
...domProps,
|
|
onFocus: composeEventHandlers(props.onFocus, (event) => {
|
|
event.currentTarget.select();
|
|
}),
|
|
onCut: composeEventHandlers(props.onCut, (event) => {
|
|
const currentValue = event.currentTarget.value;
|
|
if (currentValue !== "") {
|
|
userActionRef.current = {
|
|
type: "cut"
|
|
};
|
|
keyboardActionTimeoutRef.current = window.setTimeout(() => {
|
|
userActionRef.current = null;
|
|
}, 10);
|
|
}
|
|
}),
|
|
onInput: composeEventHandlers(props.onInput, (event) => {
|
|
const value = event.currentTarget.value;
|
|
if (value.length > 1) {
|
|
event.preventDefault();
|
|
dispatch({ type: "PASTE", value });
|
|
}
|
|
}),
|
|
onChange: composeEventHandlers(props.onChange, (event) => {
|
|
const value = event.target.value;
|
|
event.preventDefault();
|
|
const action = userActionRef.current;
|
|
userActionRef.current = null;
|
|
if (action) {
|
|
switch (action.type) {
|
|
case "cut":
|
|
dispatch({ type: "CLEAR_CHAR", index, reason: "Cut" });
|
|
return;
|
|
case "keydown": {
|
|
if (action.key === "Char") {
|
|
return;
|
|
}
|
|
const isClearing = action.key === "Backspace" && (action.metaKey || action.ctrlKey);
|
|
if (action.key === "Clear" || isClearing) {
|
|
dispatch({ type: "CLEAR", reason: "Backspace" });
|
|
} else {
|
|
dispatch({ type: "CLEAR_CHAR", index, reason: action.key });
|
|
}
|
|
return;
|
|
}
|
|
default:
|
|
return;
|
|
}
|
|
}
|
|
if (event.target.validity.valid) {
|
|
if (value === "") {
|
|
let reason = "Backspace";
|
|
if (isInputEvent(event.nativeEvent)) {
|
|
const inputType = event.nativeEvent.inputType;
|
|
if (inputType === "deleteContentBackward") {
|
|
reason = "Backspace";
|
|
} else if (inputType === "deleteByCut") {
|
|
reason = "Cut";
|
|
}
|
|
}
|
|
dispatch({ type: "CLEAR_CHAR", index, reason });
|
|
} else {
|
|
dispatch({ type: "SET_CHAR", char: value, index, event });
|
|
}
|
|
} else {
|
|
const element2 = event.target;
|
|
onInvalidChange == null ? void 0 : onInvalidChange(element2.value);
|
|
requestAnimationFrame(() => {
|
|
if (element2.ownerDocument.activeElement === element2) {
|
|
element2.select();
|
|
}
|
|
});
|
|
}
|
|
}),
|
|
onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
|
|
var _a2, _b, _c;
|
|
switch (event.key) {
|
|
case "Clear":
|
|
case "Delete":
|
|
case "Backspace": {
|
|
const currentValue = event.currentTarget.value;
|
|
if (currentValue === "") {
|
|
if (event.key === "Delete") return;
|
|
const isClearing = event.key === "Clear" || event.metaKey || event.ctrlKey;
|
|
if (isClearing) {
|
|
dispatch({ type: "CLEAR", reason: "Backspace" });
|
|
} else {
|
|
const element2 = event.currentTarget;
|
|
requestAnimationFrame(() => {
|
|
var _a3;
|
|
focusInput((_a3 = collection.from(element2, -1)) == null ? void 0 : _a3.element);
|
|
});
|
|
}
|
|
} else {
|
|
userActionRef.current = {
|
|
type: "keydown",
|
|
key: event.key,
|
|
metaKey: event.metaKey,
|
|
ctrlKey: event.ctrlKey
|
|
};
|
|
keyboardActionTimeoutRef.current = window.setTimeout(() => {
|
|
userActionRef.current = null;
|
|
}, 10);
|
|
}
|
|
return;
|
|
}
|
|
case "Enter": {
|
|
event.preventDefault();
|
|
context.attemptSubmit();
|
|
return;
|
|
}
|
|
case "ArrowDown":
|
|
case "ArrowUp": {
|
|
if (context.orientation === "horizontal") {
|
|
event.preventDefault();
|
|
}
|
|
return;
|
|
}
|
|
// TODO: Handle left/right arrow keys in vertical writing mode
|
|
default: {
|
|
if (event.currentTarget.value === event.key) {
|
|
const element2 = event.currentTarget;
|
|
event.preventDefault();
|
|
focusInput((_a2 = collection.from(element2, 1)) == null ? void 0 : _a2.element);
|
|
return;
|
|
} else if (
|
|
// input already has a value, but...
|
|
event.currentTarget.value && // the value is not selected
|
|
!(event.currentTarget.selectionStart === 0 && event.currentTarget.selectionEnd != null && event.currentTarget.selectionEnd > 0)
|
|
) {
|
|
const attemptedValue = event.key;
|
|
if (event.key.length > 1 || event.key === " ") {
|
|
return;
|
|
} else {
|
|
const nextInput = (_b = collection.from(event.currentTarget, 1)) == null ? void 0 : _b.element;
|
|
const lastInput = (_c = collection.at(-1)) == null ? void 0 : _c.element;
|
|
if (nextInput !== lastInput && event.currentTarget !== lastInput) {
|
|
if (event.currentTarget.selectionStart === 0) {
|
|
dispatch({ type: "SET_CHAR", char: attemptedValue, index, event });
|
|
} else {
|
|
dispatch({
|
|
type: "SET_CHAR",
|
|
char: attemptedValue,
|
|
index: index + 1,
|
|
event
|
|
});
|
|
}
|
|
userActionRef.current = {
|
|
type: "keydown",
|
|
key: "Char",
|
|
metaKey: event.metaKey,
|
|
ctrlKey: event.ctrlKey
|
|
};
|
|
keyboardActionTimeoutRef.current = window.setTimeout(() => {
|
|
userActionRef.current = null;
|
|
}, 10);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}),
|
|
onPointerDown: composeEventHandlers(props.onPointerDown, (event) => {
|
|
var _a2;
|
|
event.preventDefault();
|
|
const indexToFocus = Math.min(index, lastSelectableIndex);
|
|
const element2 = (_a2 = collection.at(indexToFocus)) == null ? void 0 : _a2.element;
|
|
focusInput(element2);
|
|
})
|
|
}
|
|
);
|
|
}
|
|
}
|
|
) });
|
|
});
|
|
function isFormElement(element) {
|
|
return (element == null ? void 0 : element.tagName) === "FORM";
|
|
}
|
|
function removeWhitespace(value) {
|
|
return value.replace(/\s/g, "");
|
|
}
|
|
function focusInput(element) {
|
|
if (!element) return;
|
|
if (element.ownerDocument.activeElement === element) {
|
|
window.requestAnimationFrame(() => {
|
|
var _a2;
|
|
(_a2 = element.select) == null ? void 0 : _a2.call(element);
|
|
});
|
|
} else {
|
|
element.focus();
|
|
}
|
|
}
|
|
function isInputEvent(event) {
|
|
return event.type === "input";
|
|
}
|
|
|
|
// ../../node_modules/@radix-ui/react-password-toggle-field/dist/index.mjs
|
|
var dist_exports26 = {};
|
|
__export(dist_exports26, {
|
|
Icon: () => PasswordToggleFieldIcon,
|
|
Input: () => PasswordToggleFieldInput,
|
|
PasswordToggleField: () => PasswordToggleField,
|
|
PasswordToggleFieldIcon: () => PasswordToggleFieldIcon,
|
|
PasswordToggleFieldInput: () => PasswordToggleFieldInput,
|
|
PasswordToggleFieldSlot: () => PasswordToggleFieldSlot,
|
|
PasswordToggleFieldToggle: () => PasswordToggleFieldToggle,
|
|
Root: () => PasswordToggleField,
|
|
Slot: () => PasswordToggleFieldSlot,
|
|
Toggle: () => PasswordToggleFieldToggle
|
|
});
|
|
var React23 = __toESM(require_react(), 1);
|
|
var import_react_dom3 = __toESM(require_react_dom(), 1);
|
|
var import_jsx_runtime22 = __toESM(require_jsx_runtime(), 1);
|
|
var PASSWORD_TOGGLE_FIELD_NAME = "PasswordToggleField";
|
|
var [createPasswordToggleFieldContext] = createContextScope(PASSWORD_TOGGLE_FIELD_NAME);
|
|
var [PasswordToggleFieldProvider, usePasswordToggleFieldContext] = createPasswordToggleFieldContext(PASSWORD_TOGGLE_FIELD_NAME);
|
|
var INITIAL_FOCUS_STATE = {
|
|
clickTriggered: false,
|
|
selectionStart: null,
|
|
selectionEnd: null
|
|
};
|
|
var PasswordToggleField = ({
|
|
__scopePasswordToggleField,
|
|
...props
|
|
}) => {
|
|
const baseId = useId(props.id);
|
|
const defaultInputId = `${baseId}-input`;
|
|
const [inputIdState, setInputIdState] = React23.useState(defaultInputId);
|
|
const inputId = inputIdState ?? defaultInputId;
|
|
const syncInputId = React23.useCallback(
|
|
(providedId) => setInputIdState(providedId != null ? String(providedId) : null),
|
|
[]
|
|
);
|
|
const { visible: visibleProp, defaultVisible, onVisiblityChange, children } = props;
|
|
const [visible = false, setVisible] = useControllableState({
|
|
caller: PASSWORD_TOGGLE_FIELD_NAME,
|
|
prop: visibleProp,
|
|
defaultProp: defaultVisible ?? false,
|
|
onChange: onVisiblityChange
|
|
});
|
|
const inputRef = React23.useRef(null);
|
|
const focusState = React23.useRef(INITIAL_FOCUS_STATE);
|
|
return (0, import_jsx_runtime22.jsx)(
|
|
PasswordToggleFieldProvider,
|
|
{
|
|
scope: __scopePasswordToggleField,
|
|
inputId,
|
|
inputRef,
|
|
setVisible,
|
|
syncInputId,
|
|
visible,
|
|
focusState,
|
|
children
|
|
}
|
|
);
|
|
};
|
|
PasswordToggleField.displayName = PASSWORD_TOGGLE_FIELD_NAME;
|
|
var PASSWORD_TOGGLE_FIELD_INPUT_NAME = PASSWORD_TOGGLE_FIELD_NAME + "Input";
|
|
var PasswordToggleFieldInput = React23.forwardRef(
|
|
({
|
|
__scopePasswordToggleField,
|
|
autoComplete = "current-password",
|
|
autoCapitalize = "off",
|
|
spellCheck = false,
|
|
id: idProp,
|
|
...props
|
|
}, forwardedRef) => {
|
|
const { visible, inputRef, inputId, syncInputId, setVisible, focusState } = usePasswordToggleFieldContext(PASSWORD_TOGGLE_FIELD_INPUT_NAME, __scopePasswordToggleField);
|
|
React23.useEffect(() => {
|
|
syncInputId(idProp);
|
|
}, [idProp, syncInputId]);
|
|
const _setVisible = useEffectEvent(setVisible);
|
|
React23.useEffect(() => {
|
|
const inputElement = inputRef.current;
|
|
const form = inputElement == null ? void 0 : inputElement.form;
|
|
if (!form) {
|
|
return;
|
|
}
|
|
const controller = new AbortController();
|
|
form.addEventListener(
|
|
"reset",
|
|
(event) => {
|
|
if (!event.defaultPrevented) {
|
|
_setVisible(false);
|
|
}
|
|
},
|
|
{ signal: controller.signal }
|
|
);
|
|
form.addEventListener(
|
|
"submit",
|
|
() => {
|
|
_setVisible(false);
|
|
},
|
|
{ signal: controller.signal }
|
|
);
|
|
return () => {
|
|
controller.abort();
|
|
};
|
|
}, [inputRef, _setVisible]);
|
|
return (0, import_jsx_runtime22.jsx)(
|
|
Primitive.input,
|
|
{
|
|
...props,
|
|
id: idProp ?? inputId,
|
|
autoCapitalize,
|
|
autoComplete,
|
|
ref: useComposedRefs(forwardedRef, inputRef),
|
|
spellCheck,
|
|
type: visible ? "text" : "password",
|
|
onBlur: composeEventHandlers(props.onBlur, (event) => {
|
|
const { selectionStart, selectionEnd } = event.currentTarget;
|
|
focusState.current.selectionStart = selectionStart;
|
|
focusState.current.selectionEnd = selectionEnd;
|
|
})
|
|
}
|
|
);
|
|
}
|
|
);
|
|
PasswordToggleFieldInput.displayName = PASSWORD_TOGGLE_FIELD_INPUT_NAME;
|
|
var PASSWORD_TOGGLE_FIELD_TOGGLE_NAME = PASSWORD_TOGGLE_FIELD_NAME + "Toggle";
|
|
var PasswordToggleFieldToggle = React23.forwardRef(
|
|
({
|
|
__scopePasswordToggleField,
|
|
onClick,
|
|
onPointerDown,
|
|
onPointerCancel,
|
|
onPointerUp,
|
|
onFocus,
|
|
children,
|
|
"aria-label": ariaLabelProp,
|
|
"aria-controls": ariaControls,
|
|
"aria-hidden": ariaHidden,
|
|
tabIndex,
|
|
...props
|
|
}, forwardedRef) => {
|
|
const { setVisible, visible, inputRef, inputId, focusState } = usePasswordToggleFieldContext(
|
|
PASSWORD_TOGGLE_FIELD_TOGGLE_NAME,
|
|
__scopePasswordToggleField
|
|
);
|
|
const [internalAriaLabel, setInternalAriaLabel] = React23.useState(void 0);
|
|
const elementRef = React23.useRef(null);
|
|
const ref = useComposedRefs(forwardedRef, elementRef);
|
|
const isHydrated = useIsHydrated();
|
|
React23.useEffect(() => {
|
|
const element = elementRef.current;
|
|
if (!element || ariaLabelProp) {
|
|
setInternalAriaLabel(void 0);
|
|
return;
|
|
}
|
|
const DEFAULT_ARIA_LABEL = visible ? "Hide password" : "Show password";
|
|
function checkForInnerTextLabel(textContent) {
|
|
const text = textContent ? textContent : void 0;
|
|
setInternalAriaLabel(text ? void 0 : DEFAULT_ARIA_LABEL);
|
|
}
|
|
checkForInnerTextLabel(element.textContent);
|
|
const observer = new MutationObserver((entries) => {
|
|
let textContent;
|
|
for (const entry of entries) {
|
|
if (entry.type === "characterData") {
|
|
if (element.textContent) {
|
|
textContent = element.textContent;
|
|
}
|
|
}
|
|
}
|
|
checkForInnerTextLabel(textContent);
|
|
});
|
|
observer.observe(element, { characterData: true, subtree: true });
|
|
return () => {
|
|
observer.disconnect();
|
|
};
|
|
}, [visible, ariaLabelProp]);
|
|
const ariaLabel = ariaLabelProp || internalAriaLabel;
|
|
if (!isHydrated) {
|
|
ariaHidden ?? (ariaHidden = true);
|
|
tabIndex ?? (tabIndex = -1);
|
|
} else {
|
|
ariaControls ?? (ariaControls = inputId);
|
|
}
|
|
React23.useEffect(() => {
|
|
var _a2, _b;
|
|
let cleanup = () => {
|
|
};
|
|
const ownerWindow = ((_b = (_a2 = elementRef.current) == null ? void 0 : _a2.ownerDocument) == null ? void 0 : _b.defaultView) || window;
|
|
const reset = () => focusState.current.clickTriggered = false;
|
|
const handlePointerUp = () => cleanup = requestIdleCallback(ownerWindow, reset);
|
|
ownerWindow.addEventListener("pointerup", handlePointerUp);
|
|
return () => {
|
|
cleanup();
|
|
ownerWindow.removeEventListener("pointerup", handlePointerUp);
|
|
};
|
|
}, [focusState]);
|
|
return (0, import_jsx_runtime22.jsx)(
|
|
Primitive.button,
|
|
{
|
|
"aria-controls": ariaControls,
|
|
"aria-hidden": ariaHidden,
|
|
"aria-label": ariaLabel,
|
|
ref,
|
|
id: inputId,
|
|
...props,
|
|
onPointerDown: composeEventHandlers(onPointerDown, () => {
|
|
focusState.current.clickTriggered = true;
|
|
}),
|
|
onPointerCancel: (event) => {
|
|
onPointerCancel == null ? void 0 : onPointerCancel(event);
|
|
focusState.current = INITIAL_FOCUS_STATE;
|
|
},
|
|
onClick: (event) => {
|
|
onClick == null ? void 0 : onClick(event);
|
|
if (event.defaultPrevented) {
|
|
focusState.current = INITIAL_FOCUS_STATE;
|
|
return;
|
|
}
|
|
(0, import_react_dom3.flushSync)(() => {
|
|
setVisible((s) => !s);
|
|
});
|
|
if (focusState.current.clickTriggered) {
|
|
const input = inputRef.current;
|
|
if (input) {
|
|
const { selectionStart, selectionEnd } = focusState.current;
|
|
input.focus();
|
|
if (selectionStart !== null || selectionEnd !== null) {
|
|
requestAnimationFrame(() => {
|
|
if (input.ownerDocument.activeElement === input) {
|
|
input.selectionStart = selectionStart;
|
|
input.selectionEnd = selectionEnd;
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
focusState.current = INITIAL_FOCUS_STATE;
|
|
},
|
|
onPointerUp: (event) => {
|
|
onPointerUp == null ? void 0 : onPointerUp(event);
|
|
setTimeout(() => {
|
|
focusState.current = INITIAL_FOCUS_STATE;
|
|
}, 50);
|
|
},
|
|
type: "button",
|
|
children
|
|
}
|
|
);
|
|
}
|
|
);
|
|
PasswordToggleFieldToggle.displayName = PASSWORD_TOGGLE_FIELD_TOGGLE_NAME;
|
|
var PASSWORD_TOGGLE_FIELD_SLOT_NAME = PASSWORD_TOGGLE_FIELD_NAME + "Slot";
|
|
var PasswordToggleFieldSlot = ({
|
|
__scopePasswordToggleField,
|
|
...props
|
|
}) => {
|
|
const { visible } = usePasswordToggleFieldContext(
|
|
PASSWORD_TOGGLE_FIELD_SLOT_NAME,
|
|
__scopePasswordToggleField
|
|
);
|
|
return "render" in props ? (
|
|
//
|
|
props.render({ visible })
|
|
) : visible ? props.visible : props.hidden;
|
|
};
|
|
PasswordToggleFieldSlot.displayName = PASSWORD_TOGGLE_FIELD_SLOT_NAME;
|
|
var PASSWORD_TOGGLE_FIELD_ICON_NAME = PASSWORD_TOGGLE_FIELD_NAME + "Icon";
|
|
var PasswordToggleFieldIcon = React23.forwardRef(
|
|
({
|
|
__scopePasswordToggleField,
|
|
// @ts-expect-error
|
|
children,
|
|
...props
|
|
}, forwardedRef) => {
|
|
const { visible } = usePasswordToggleFieldContext(
|
|
PASSWORD_TOGGLE_FIELD_ICON_NAME,
|
|
__scopePasswordToggleField
|
|
);
|
|
const { visible: visibleIcon, hidden: hiddenIcon, ...domProps } = props;
|
|
return (0, import_jsx_runtime22.jsx)(Primitive.svg, { ...domProps, ref: forwardedRef, "aria-hidden": true, asChild: true, children: visible ? visibleIcon : hiddenIcon });
|
|
}
|
|
);
|
|
PasswordToggleFieldIcon.displayName = PASSWORD_TOGGLE_FIELD_ICON_NAME;
|
|
function requestIdleCallback(window2, callback, options) {
|
|
if (window2.requestIdleCallback) {
|
|
const id2 = window2.requestIdleCallback(callback, options);
|
|
return () => {
|
|
window2.cancelIdleCallback(id2);
|
|
};
|
|
}
|
|
const start = Date.now();
|
|
const id = window2.setTimeout(() => {
|
|
const timeRemaining = () => Math.max(0, 50 - (Date.now() - start));
|
|
callback({ didTimeout: false, timeRemaining });
|
|
}, 1);
|
|
return () => {
|
|
window2.clearTimeout(id);
|
|
};
|
|
}
|
|
|
|
// ../../node_modules/@radix-ui/react-progress/dist/index.mjs
|
|
var dist_exports27 = {};
|
|
__export(dist_exports27, {
|
|
Indicator: () => Indicator2,
|
|
Progress: () => Progress,
|
|
ProgressIndicator: () => ProgressIndicator,
|
|
Root: () => Root11,
|
|
createProgressScope: () => createProgressScope
|
|
});
|
|
var React24 = __toESM(require_react(), 1);
|
|
var import_jsx_runtime23 = __toESM(require_jsx_runtime(), 1);
|
|
var PROGRESS_NAME = "Progress";
|
|
var DEFAULT_MAX = 100;
|
|
var [createProgressContext, createProgressScope] = createContextScope(PROGRESS_NAME);
|
|
var [ProgressProvider, useProgressContext] = createProgressContext(PROGRESS_NAME);
|
|
var Progress = React24.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const {
|
|
__scopeProgress,
|
|
value: valueProp = null,
|
|
max: maxProp,
|
|
getValueLabel = defaultGetValueLabel,
|
|
...progressProps
|
|
} = props;
|
|
if ((maxProp || maxProp === 0) && !isValidMaxNumber(maxProp)) {
|
|
console.error(getInvalidMaxError(`${maxProp}`, "Progress"));
|
|
}
|
|
const max = isValidMaxNumber(maxProp) ? maxProp : DEFAULT_MAX;
|
|
if (valueProp !== null && !isValidValueNumber(valueProp, max)) {
|
|
console.error(getInvalidValueError(`${valueProp}`, "Progress"));
|
|
}
|
|
const value = isValidValueNumber(valueProp, max) ? valueProp : null;
|
|
const valueLabel = isNumber(value) ? getValueLabel(value, max) : void 0;
|
|
return (0, import_jsx_runtime23.jsx)(ProgressProvider, { scope: __scopeProgress, value, max, children: (0, import_jsx_runtime23.jsx)(
|
|
Primitive.div,
|
|
{
|
|
"aria-valuemax": max,
|
|
"aria-valuemin": 0,
|
|
"aria-valuenow": isNumber(value) ? value : void 0,
|
|
"aria-valuetext": valueLabel,
|
|
role: "progressbar",
|
|
"data-state": getProgressState(value, max),
|
|
"data-value": value ?? void 0,
|
|
"data-max": max,
|
|
...progressProps,
|
|
ref: forwardedRef
|
|
}
|
|
) });
|
|
}
|
|
);
|
|
Progress.displayName = PROGRESS_NAME;
|
|
var INDICATOR_NAME6 = "ProgressIndicator";
|
|
var ProgressIndicator = React24.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeProgress, ...indicatorProps } = props;
|
|
const context = useProgressContext(INDICATOR_NAME6, __scopeProgress);
|
|
return (0, import_jsx_runtime23.jsx)(
|
|
Primitive.div,
|
|
{
|
|
"data-state": getProgressState(context.value, context.max),
|
|
"data-value": context.value ?? void 0,
|
|
"data-max": context.max,
|
|
...indicatorProps,
|
|
ref: forwardedRef
|
|
}
|
|
);
|
|
}
|
|
);
|
|
ProgressIndicator.displayName = INDICATOR_NAME6;
|
|
function defaultGetValueLabel(value, max) {
|
|
return `${Math.round(value / max * 100)}%`;
|
|
}
|
|
function getProgressState(value, maxValue) {
|
|
return value == null ? "indeterminate" : value === maxValue ? "complete" : "loading";
|
|
}
|
|
function isNumber(value) {
|
|
return typeof value === "number";
|
|
}
|
|
function isValidMaxNumber(max) {
|
|
return isNumber(max) && !isNaN(max) && max > 0;
|
|
}
|
|
function isValidValueNumber(value, max) {
|
|
return isNumber(value) && !isNaN(value) && value <= max && value >= 0;
|
|
}
|
|
function getInvalidMaxError(propValue, componentName) {
|
|
return `Invalid prop \`max\` of value \`${propValue}\` supplied to \`${componentName}\`. Only numbers greater than 0 are valid max values. Defaulting to \`${DEFAULT_MAX}\`.`;
|
|
}
|
|
function getInvalidValueError(propValue, componentName) {
|
|
return `Invalid prop \`value\` of value \`${propValue}\` supplied to \`${componentName}\`. The \`value\` prop must be:
|
|
- a positive number
|
|
- less than the value passed to \`max\` (or ${DEFAULT_MAX} if no \`max\` prop is set)
|
|
- \`null\` or \`undefined\` if the progress is indeterminate.
|
|
|
|
Defaulting to \`null\`.`;
|
|
}
|
|
var Root11 = Progress;
|
|
var Indicator2 = ProgressIndicator;
|
|
|
|
// ../../node_modules/@radix-ui/react-radio-group/dist/index.mjs
|
|
var dist_exports28 = {};
|
|
__export(dist_exports28, {
|
|
Indicator: () => Indicator3,
|
|
Item: () => Item25,
|
|
RadioGroup: () => RadioGroup3,
|
|
RadioGroupIndicator: () => RadioGroupIndicator,
|
|
RadioGroupItem: () => RadioGroupItem,
|
|
Root: () => Root210,
|
|
createRadioGroupScope: () => createRadioGroupScope
|
|
});
|
|
var React25 = __toESM(require_react(), 1);
|
|
var React26 = __toESM(require_react(), 1);
|
|
var import_jsx_runtime24 = __toESM(require_jsx_runtime(), 1);
|
|
var import_jsx_runtime25 = __toESM(require_jsx_runtime(), 1);
|
|
var RADIO_NAME = "Radio";
|
|
var [createRadioContext, createRadioScope] = createContextScope(RADIO_NAME);
|
|
var [RadioProvider, useRadioContext] = createRadioContext(RADIO_NAME);
|
|
var Radio = React26.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const {
|
|
__scopeRadio,
|
|
name,
|
|
checked = false,
|
|
required,
|
|
disabled,
|
|
value = "on",
|
|
onCheck,
|
|
form,
|
|
...radioProps
|
|
} = props;
|
|
const [button, setButton] = React26.useState(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, (node) => setButton(node));
|
|
const hasConsumerStoppedPropagationRef = React26.useRef(false);
|
|
const isFormControl2 = button ? form || !!button.closest("form") : true;
|
|
return (0, import_jsx_runtime24.jsxs)(RadioProvider, { scope: __scopeRadio, checked, disabled, children: [
|
|
(0, import_jsx_runtime24.jsx)(
|
|
Primitive.button,
|
|
{
|
|
type: "button",
|
|
role: "radio",
|
|
"aria-checked": checked,
|
|
"data-state": getState4(checked),
|
|
"data-disabled": disabled ? "" : void 0,
|
|
disabled,
|
|
value,
|
|
...radioProps,
|
|
ref: composedRefs,
|
|
onClick: composeEventHandlers(props.onClick, (event) => {
|
|
if (!checked) onCheck == null ? void 0 : onCheck();
|
|
if (isFormControl2) {
|
|
hasConsumerStoppedPropagationRef.current = event.isPropagationStopped();
|
|
if (!hasConsumerStoppedPropagationRef.current) event.stopPropagation();
|
|
}
|
|
})
|
|
}
|
|
),
|
|
isFormControl2 && (0, import_jsx_runtime24.jsx)(
|
|
RadioBubbleInput,
|
|
{
|
|
control: button,
|
|
bubbles: !hasConsumerStoppedPropagationRef.current,
|
|
name,
|
|
value,
|
|
checked,
|
|
required,
|
|
disabled,
|
|
form,
|
|
style: { transform: "translateX(-100%)" }
|
|
}
|
|
)
|
|
] });
|
|
}
|
|
);
|
|
Radio.displayName = RADIO_NAME;
|
|
var INDICATOR_NAME7 = "RadioIndicator";
|
|
var RadioIndicator = React26.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeRadio, forceMount, ...indicatorProps } = props;
|
|
const context = useRadioContext(INDICATOR_NAME7, __scopeRadio);
|
|
return (0, import_jsx_runtime24.jsx)(Presence, { present: forceMount || context.checked, children: (0, import_jsx_runtime24.jsx)(
|
|
Primitive.span,
|
|
{
|
|
"data-state": getState4(context.checked),
|
|
"data-disabled": context.disabled ? "" : void 0,
|
|
...indicatorProps,
|
|
ref: forwardedRef
|
|
}
|
|
) });
|
|
}
|
|
);
|
|
RadioIndicator.displayName = INDICATOR_NAME7;
|
|
var BUBBLE_INPUT_NAME2 = "RadioBubbleInput";
|
|
var RadioBubbleInput = React26.forwardRef(
|
|
({
|
|
__scopeRadio,
|
|
control,
|
|
checked,
|
|
bubbles = true,
|
|
...props
|
|
}, forwardedRef) => {
|
|
const ref = React26.useRef(null);
|
|
const composedRefs = useComposedRefs(ref, forwardedRef);
|
|
const prevChecked = usePrevious(checked);
|
|
const controlSize = useSize(control);
|
|
React26.useEffect(() => {
|
|
const input = ref.current;
|
|
if (!input) return;
|
|
const inputProto = window.HTMLInputElement.prototype;
|
|
const descriptor = Object.getOwnPropertyDescriptor(
|
|
inputProto,
|
|
"checked"
|
|
);
|
|
const setChecked = descriptor.set;
|
|
if (prevChecked !== checked && setChecked) {
|
|
const event = new Event("click", { bubbles });
|
|
setChecked.call(input, checked);
|
|
input.dispatchEvent(event);
|
|
}
|
|
}, [prevChecked, checked, bubbles]);
|
|
return (0, import_jsx_runtime24.jsx)(
|
|
Primitive.input,
|
|
{
|
|
type: "radio",
|
|
"aria-hidden": true,
|
|
defaultChecked: checked,
|
|
...props,
|
|
tabIndex: -1,
|
|
ref: composedRefs,
|
|
style: {
|
|
...props.style,
|
|
...controlSize,
|
|
position: "absolute",
|
|
pointerEvents: "none",
|
|
opacity: 0,
|
|
margin: 0
|
|
}
|
|
}
|
|
);
|
|
}
|
|
);
|
|
RadioBubbleInput.displayName = BUBBLE_INPUT_NAME2;
|
|
function getState4(checked) {
|
|
return checked ? "checked" : "unchecked";
|
|
}
|
|
var ARROW_KEYS2 = ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"];
|
|
var RADIO_GROUP_NAME5 = "RadioGroup";
|
|
var [createRadioGroupContext, createRadioGroupScope] = createContextScope(RADIO_GROUP_NAME5, [
|
|
createRovingFocusGroupScope,
|
|
createRadioScope
|
|
]);
|
|
var useRovingFocusGroupScope4 = createRovingFocusGroupScope();
|
|
var useRadioScope = createRadioScope();
|
|
var [RadioGroupProvider2, useRadioGroupContext2] = createRadioGroupContext(RADIO_GROUP_NAME5);
|
|
var RadioGroup3 = React25.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const {
|
|
__scopeRadioGroup,
|
|
name,
|
|
defaultValue,
|
|
value: valueProp,
|
|
required = false,
|
|
disabled = false,
|
|
orientation,
|
|
dir,
|
|
loop = true,
|
|
onValueChange,
|
|
...groupProps
|
|
} = props;
|
|
const rovingFocusGroupScope = useRovingFocusGroupScope4(__scopeRadioGroup);
|
|
const direction = useDirection(dir);
|
|
const [value, setValue] = useControllableState({
|
|
prop: valueProp,
|
|
defaultProp: defaultValue ?? null,
|
|
onChange: onValueChange,
|
|
caller: RADIO_GROUP_NAME5
|
|
});
|
|
return (0, import_jsx_runtime25.jsx)(
|
|
RadioGroupProvider2,
|
|
{
|
|
scope: __scopeRadioGroup,
|
|
name,
|
|
required,
|
|
disabled,
|
|
value,
|
|
onValueChange: setValue,
|
|
children: (0, import_jsx_runtime25.jsx)(
|
|
Root8,
|
|
{
|
|
asChild: true,
|
|
...rovingFocusGroupScope,
|
|
orientation,
|
|
dir: direction,
|
|
loop,
|
|
children: (0, import_jsx_runtime25.jsx)(
|
|
Primitive.div,
|
|
{
|
|
role: "radiogroup",
|
|
"aria-required": required,
|
|
"aria-orientation": orientation,
|
|
"data-disabled": disabled ? "" : void 0,
|
|
dir: direction,
|
|
...groupProps,
|
|
ref: forwardedRef
|
|
}
|
|
)
|
|
}
|
|
)
|
|
}
|
|
);
|
|
}
|
|
);
|
|
RadioGroup3.displayName = RADIO_GROUP_NAME5;
|
|
var ITEM_NAME8 = "RadioGroupItem";
|
|
var RadioGroupItem = React25.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeRadioGroup, disabled, ...itemProps } = props;
|
|
const context = useRadioGroupContext2(ITEM_NAME8, __scopeRadioGroup);
|
|
const isDisabled = context.disabled || disabled;
|
|
const rovingFocusGroupScope = useRovingFocusGroupScope4(__scopeRadioGroup);
|
|
const radioScope = useRadioScope(__scopeRadioGroup);
|
|
const ref = React25.useRef(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, ref);
|
|
const checked = context.value === itemProps.value;
|
|
const isArrowKeyPressedRef = React25.useRef(false);
|
|
React25.useEffect(() => {
|
|
const handleKeyDown = (event) => {
|
|
if (ARROW_KEYS2.includes(event.key)) {
|
|
isArrowKeyPressedRef.current = true;
|
|
}
|
|
};
|
|
const handleKeyUp = () => isArrowKeyPressedRef.current = false;
|
|
document.addEventListener("keydown", handleKeyDown);
|
|
document.addEventListener("keyup", handleKeyUp);
|
|
return () => {
|
|
document.removeEventListener("keydown", handleKeyDown);
|
|
document.removeEventListener("keyup", handleKeyUp);
|
|
};
|
|
}, []);
|
|
return (0, import_jsx_runtime25.jsx)(
|
|
Item2,
|
|
{
|
|
asChild: true,
|
|
...rovingFocusGroupScope,
|
|
focusable: !isDisabled,
|
|
active: checked,
|
|
children: (0, import_jsx_runtime25.jsx)(
|
|
Radio,
|
|
{
|
|
disabled: isDisabled,
|
|
required: context.required,
|
|
checked,
|
|
...radioScope,
|
|
...itemProps,
|
|
name: context.name,
|
|
ref: composedRefs,
|
|
onCheck: () => context.onValueChange(itemProps.value),
|
|
onKeyDown: composeEventHandlers((event) => {
|
|
if (event.key === "Enter") event.preventDefault();
|
|
}),
|
|
onFocus: composeEventHandlers(itemProps.onFocus, () => {
|
|
var _a2;
|
|
if (isArrowKeyPressedRef.current) (_a2 = ref.current) == null ? void 0 : _a2.click();
|
|
})
|
|
}
|
|
)
|
|
}
|
|
);
|
|
}
|
|
);
|
|
RadioGroupItem.displayName = ITEM_NAME8;
|
|
var INDICATOR_NAME22 = "RadioGroupIndicator";
|
|
var RadioGroupIndicator = React25.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeRadioGroup, ...indicatorProps } = props;
|
|
const radioScope = useRadioScope(__scopeRadioGroup);
|
|
return (0, import_jsx_runtime25.jsx)(RadioIndicator, { ...radioScope, ...indicatorProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
RadioGroupIndicator.displayName = INDICATOR_NAME22;
|
|
var Root210 = RadioGroup3;
|
|
var Item25 = RadioGroupItem;
|
|
var Indicator3 = RadioGroupIndicator;
|
|
|
|
// ../../node_modules/@radix-ui/react-scroll-area/dist/index.mjs
|
|
var dist_exports29 = {};
|
|
__export(dist_exports29, {
|
|
Corner: () => Corner,
|
|
Root: () => Root12,
|
|
ScrollArea: () => ScrollArea,
|
|
ScrollAreaCorner: () => ScrollAreaCorner,
|
|
ScrollAreaScrollbar: () => ScrollAreaScrollbar,
|
|
ScrollAreaThumb: () => ScrollAreaThumb,
|
|
ScrollAreaViewport: () => ScrollAreaViewport,
|
|
Scrollbar: () => Scrollbar,
|
|
Thumb: () => Thumb,
|
|
Viewport: () => Viewport2,
|
|
createScrollAreaScope: () => createScrollAreaScope
|
|
});
|
|
var React27 = __toESM(require_react(), 1);
|
|
var React28 = __toESM(require_react(), 1);
|
|
var import_jsx_runtime26 = __toESM(require_jsx_runtime(), 1);
|
|
function useStateMachine(initialState, machine) {
|
|
return React28.useReducer((state, event) => {
|
|
const nextState = machine[state][event];
|
|
return nextState ?? state;
|
|
}, initialState);
|
|
}
|
|
var SCROLL_AREA_NAME = "ScrollArea";
|
|
var [createScrollAreaContext, createScrollAreaScope] = createContextScope(SCROLL_AREA_NAME);
|
|
var [ScrollAreaProvider, useScrollAreaContext] = createScrollAreaContext(SCROLL_AREA_NAME);
|
|
var ScrollArea = React27.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const {
|
|
__scopeScrollArea,
|
|
type = "hover",
|
|
dir,
|
|
scrollHideDelay = 600,
|
|
...scrollAreaProps
|
|
} = props;
|
|
const [scrollArea, setScrollArea] = React27.useState(null);
|
|
const [viewport, setViewport] = React27.useState(null);
|
|
const [content, setContent] = React27.useState(null);
|
|
const [scrollbarX, setScrollbarX] = React27.useState(null);
|
|
const [scrollbarY, setScrollbarY] = React27.useState(null);
|
|
const [cornerWidth, setCornerWidth] = React27.useState(0);
|
|
const [cornerHeight, setCornerHeight] = React27.useState(0);
|
|
const [scrollbarXEnabled, setScrollbarXEnabled] = React27.useState(false);
|
|
const [scrollbarYEnabled, setScrollbarYEnabled] = React27.useState(false);
|
|
const composedRefs = useComposedRefs(forwardedRef, (node) => setScrollArea(node));
|
|
const direction = useDirection(dir);
|
|
return (0, import_jsx_runtime26.jsx)(
|
|
ScrollAreaProvider,
|
|
{
|
|
scope: __scopeScrollArea,
|
|
type,
|
|
dir: direction,
|
|
scrollHideDelay,
|
|
scrollArea,
|
|
viewport,
|
|
onViewportChange: setViewport,
|
|
content,
|
|
onContentChange: setContent,
|
|
scrollbarX,
|
|
onScrollbarXChange: setScrollbarX,
|
|
scrollbarXEnabled,
|
|
onScrollbarXEnabledChange: setScrollbarXEnabled,
|
|
scrollbarY,
|
|
onScrollbarYChange: setScrollbarY,
|
|
scrollbarYEnabled,
|
|
onScrollbarYEnabledChange: setScrollbarYEnabled,
|
|
onCornerWidthChange: setCornerWidth,
|
|
onCornerHeightChange: setCornerHeight,
|
|
children: (0, import_jsx_runtime26.jsx)(
|
|
Primitive.div,
|
|
{
|
|
dir: direction,
|
|
...scrollAreaProps,
|
|
ref: composedRefs,
|
|
style: {
|
|
position: "relative",
|
|
// Pass corner sizes as CSS vars to reduce re-renders of context consumers
|
|
["--radix-scroll-area-corner-width"]: cornerWidth + "px",
|
|
["--radix-scroll-area-corner-height"]: cornerHeight + "px",
|
|
...props.style
|
|
}
|
|
}
|
|
)
|
|
}
|
|
);
|
|
}
|
|
);
|
|
ScrollArea.displayName = SCROLL_AREA_NAME;
|
|
var VIEWPORT_NAME2 = "ScrollAreaViewport";
|
|
var ScrollAreaViewport = React27.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeScrollArea, children, nonce, ...viewportProps } = props;
|
|
const context = useScrollAreaContext(VIEWPORT_NAME2, __scopeScrollArea);
|
|
const ref = React27.useRef(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, ref, context.onViewportChange);
|
|
return (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
|
|
(0, import_jsx_runtime26.jsx)(
|
|
"style",
|
|
{
|
|
dangerouslySetInnerHTML: {
|
|
__html: `[data-radix-scroll-area-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-radix-scroll-area-viewport]::-webkit-scrollbar{display:none}`
|
|
},
|
|
nonce
|
|
}
|
|
),
|
|
(0, import_jsx_runtime26.jsx)(
|
|
Primitive.div,
|
|
{
|
|
"data-radix-scroll-area-viewport": "",
|
|
...viewportProps,
|
|
ref: composedRefs,
|
|
style: {
|
|
/**
|
|
* We don't support `visible` because the intention is to have at least one scrollbar
|
|
* if this component is used and `visible` will behave like `auto` in that case
|
|
* https://developer.mozilla.org/en-US/docs/Web/CSS/overflow#description
|
|
*
|
|
* We don't handle `auto` because the intention is for the native implementation
|
|
* to be hidden if using this component. We just want to ensure the node is scrollable
|
|
* so could have used either `scroll` or `auto` here. We picked `scroll` to prevent
|
|
* the browser from having to work out whether to render native scrollbars or not,
|
|
* we tell it to with the intention of hiding them in CSS.
|
|
*/
|
|
overflowX: context.scrollbarXEnabled ? "scroll" : "hidden",
|
|
overflowY: context.scrollbarYEnabled ? "scroll" : "hidden",
|
|
...props.style
|
|
},
|
|
children: (0, import_jsx_runtime26.jsx)("div", { ref: context.onContentChange, style: { minWidth: "100%", display: "table" }, children })
|
|
}
|
|
)
|
|
] });
|
|
}
|
|
);
|
|
ScrollAreaViewport.displayName = VIEWPORT_NAME2;
|
|
var SCROLLBAR_NAME = "ScrollAreaScrollbar";
|
|
var ScrollAreaScrollbar = React27.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { forceMount, ...scrollbarProps } = props;
|
|
const context = useScrollAreaContext(SCROLLBAR_NAME, props.__scopeScrollArea);
|
|
const { onScrollbarXEnabledChange, onScrollbarYEnabledChange } = context;
|
|
const isHorizontal = props.orientation === "horizontal";
|
|
React27.useEffect(() => {
|
|
isHorizontal ? onScrollbarXEnabledChange(true) : onScrollbarYEnabledChange(true);
|
|
return () => {
|
|
isHorizontal ? onScrollbarXEnabledChange(false) : onScrollbarYEnabledChange(false);
|
|
};
|
|
}, [isHorizontal, onScrollbarXEnabledChange, onScrollbarYEnabledChange]);
|
|
return context.type === "hover" ? (0, import_jsx_runtime26.jsx)(ScrollAreaScrollbarHover, { ...scrollbarProps, ref: forwardedRef, forceMount }) : context.type === "scroll" ? (0, import_jsx_runtime26.jsx)(ScrollAreaScrollbarScroll, { ...scrollbarProps, ref: forwardedRef, forceMount }) : context.type === "auto" ? (0, import_jsx_runtime26.jsx)(ScrollAreaScrollbarAuto, { ...scrollbarProps, ref: forwardedRef, forceMount }) : context.type === "always" ? (0, import_jsx_runtime26.jsx)(ScrollAreaScrollbarVisible, { ...scrollbarProps, ref: forwardedRef }) : null;
|
|
}
|
|
);
|
|
ScrollAreaScrollbar.displayName = SCROLLBAR_NAME;
|
|
var ScrollAreaScrollbarHover = React27.forwardRef((props, forwardedRef) => {
|
|
const { forceMount, ...scrollbarProps } = props;
|
|
const context = useScrollAreaContext(SCROLLBAR_NAME, props.__scopeScrollArea);
|
|
const [visible, setVisible] = React27.useState(false);
|
|
React27.useEffect(() => {
|
|
const scrollArea = context.scrollArea;
|
|
let hideTimer = 0;
|
|
if (scrollArea) {
|
|
const handlePointerEnter = () => {
|
|
window.clearTimeout(hideTimer);
|
|
setVisible(true);
|
|
};
|
|
const handlePointerLeave = () => {
|
|
hideTimer = window.setTimeout(() => setVisible(false), context.scrollHideDelay);
|
|
};
|
|
scrollArea.addEventListener("pointerenter", handlePointerEnter);
|
|
scrollArea.addEventListener("pointerleave", handlePointerLeave);
|
|
return () => {
|
|
window.clearTimeout(hideTimer);
|
|
scrollArea.removeEventListener("pointerenter", handlePointerEnter);
|
|
scrollArea.removeEventListener("pointerleave", handlePointerLeave);
|
|
};
|
|
}
|
|
}, [context.scrollArea, context.scrollHideDelay]);
|
|
return (0, import_jsx_runtime26.jsx)(Presence, { present: forceMount || visible, children: (0, import_jsx_runtime26.jsx)(
|
|
ScrollAreaScrollbarAuto,
|
|
{
|
|
"data-state": visible ? "visible" : "hidden",
|
|
...scrollbarProps,
|
|
ref: forwardedRef
|
|
}
|
|
) });
|
|
});
|
|
var ScrollAreaScrollbarScroll = React27.forwardRef((props, forwardedRef) => {
|
|
const { forceMount, ...scrollbarProps } = props;
|
|
const context = useScrollAreaContext(SCROLLBAR_NAME, props.__scopeScrollArea);
|
|
const isHorizontal = props.orientation === "horizontal";
|
|
const debounceScrollEnd = useDebounceCallback(() => send("SCROLL_END"), 100);
|
|
const [state, send] = useStateMachine("hidden", {
|
|
hidden: {
|
|
SCROLL: "scrolling"
|
|
},
|
|
scrolling: {
|
|
SCROLL_END: "idle",
|
|
POINTER_ENTER: "interacting"
|
|
},
|
|
interacting: {
|
|
SCROLL: "interacting",
|
|
POINTER_LEAVE: "idle"
|
|
},
|
|
idle: {
|
|
HIDE: "hidden",
|
|
SCROLL: "scrolling",
|
|
POINTER_ENTER: "interacting"
|
|
}
|
|
});
|
|
React27.useEffect(() => {
|
|
if (state === "idle") {
|
|
const hideTimer = window.setTimeout(() => send("HIDE"), context.scrollHideDelay);
|
|
return () => window.clearTimeout(hideTimer);
|
|
}
|
|
}, [state, context.scrollHideDelay, send]);
|
|
React27.useEffect(() => {
|
|
const viewport = context.viewport;
|
|
const scrollDirection = isHorizontal ? "scrollLeft" : "scrollTop";
|
|
if (viewport) {
|
|
let prevScrollPos = viewport[scrollDirection];
|
|
const handleScroll = () => {
|
|
const scrollPos = viewport[scrollDirection];
|
|
const hasScrollInDirectionChanged = prevScrollPos !== scrollPos;
|
|
if (hasScrollInDirectionChanged) {
|
|
send("SCROLL");
|
|
debounceScrollEnd();
|
|
}
|
|
prevScrollPos = scrollPos;
|
|
};
|
|
viewport.addEventListener("scroll", handleScroll);
|
|
return () => viewport.removeEventListener("scroll", handleScroll);
|
|
}
|
|
}, [context.viewport, isHorizontal, send, debounceScrollEnd]);
|
|
return (0, import_jsx_runtime26.jsx)(Presence, { present: forceMount || state !== "hidden", children: (0, import_jsx_runtime26.jsx)(
|
|
ScrollAreaScrollbarVisible,
|
|
{
|
|
"data-state": state === "hidden" ? "hidden" : "visible",
|
|
...scrollbarProps,
|
|
ref: forwardedRef,
|
|
onPointerEnter: composeEventHandlers(props.onPointerEnter, () => send("POINTER_ENTER")),
|
|
onPointerLeave: composeEventHandlers(props.onPointerLeave, () => send("POINTER_LEAVE"))
|
|
}
|
|
) });
|
|
});
|
|
var ScrollAreaScrollbarAuto = React27.forwardRef((props, forwardedRef) => {
|
|
const context = useScrollAreaContext(SCROLLBAR_NAME, props.__scopeScrollArea);
|
|
const { forceMount, ...scrollbarProps } = props;
|
|
const [visible, setVisible] = React27.useState(false);
|
|
const isHorizontal = props.orientation === "horizontal";
|
|
const handleResize = useDebounceCallback(() => {
|
|
if (context.viewport) {
|
|
const isOverflowX = context.viewport.offsetWidth < context.viewport.scrollWidth;
|
|
const isOverflowY = context.viewport.offsetHeight < context.viewport.scrollHeight;
|
|
setVisible(isHorizontal ? isOverflowX : isOverflowY);
|
|
}
|
|
}, 10);
|
|
useResizeObserver2(context.viewport, handleResize);
|
|
useResizeObserver2(context.content, handleResize);
|
|
return (0, import_jsx_runtime26.jsx)(Presence, { present: forceMount || visible, children: (0, import_jsx_runtime26.jsx)(
|
|
ScrollAreaScrollbarVisible,
|
|
{
|
|
"data-state": visible ? "visible" : "hidden",
|
|
...scrollbarProps,
|
|
ref: forwardedRef
|
|
}
|
|
) });
|
|
});
|
|
var ScrollAreaScrollbarVisible = React27.forwardRef((props, forwardedRef) => {
|
|
const { orientation = "vertical", ...scrollbarProps } = props;
|
|
const context = useScrollAreaContext(SCROLLBAR_NAME, props.__scopeScrollArea);
|
|
const thumbRef = React27.useRef(null);
|
|
const pointerOffsetRef = React27.useRef(0);
|
|
const [sizes, setSizes] = React27.useState({
|
|
content: 0,
|
|
viewport: 0,
|
|
scrollbar: { size: 0, paddingStart: 0, paddingEnd: 0 }
|
|
});
|
|
const thumbRatio = getThumbRatio(sizes.viewport, sizes.content);
|
|
const commonProps = {
|
|
...scrollbarProps,
|
|
sizes,
|
|
onSizesChange: setSizes,
|
|
hasThumb: Boolean(thumbRatio > 0 && thumbRatio < 1),
|
|
onThumbChange: (thumb) => thumbRef.current = thumb,
|
|
onThumbPointerUp: () => pointerOffsetRef.current = 0,
|
|
onThumbPointerDown: (pointerPos) => pointerOffsetRef.current = pointerPos
|
|
};
|
|
function getScrollPosition(pointerPos, dir) {
|
|
return getScrollPositionFromPointer(pointerPos, pointerOffsetRef.current, sizes, dir);
|
|
}
|
|
if (orientation === "horizontal") {
|
|
return (0, import_jsx_runtime26.jsx)(
|
|
ScrollAreaScrollbarX,
|
|
{
|
|
...commonProps,
|
|
ref: forwardedRef,
|
|
onThumbPositionChange: () => {
|
|
if (context.viewport && thumbRef.current) {
|
|
const scrollPos = context.viewport.scrollLeft;
|
|
const offset = getThumbOffsetFromScroll(scrollPos, sizes, context.dir);
|
|
thumbRef.current.style.transform = `translate3d(${offset}px, 0, 0)`;
|
|
}
|
|
},
|
|
onWheelScroll: (scrollPos) => {
|
|
if (context.viewport) context.viewport.scrollLeft = scrollPos;
|
|
},
|
|
onDragScroll: (pointerPos) => {
|
|
if (context.viewport) {
|
|
context.viewport.scrollLeft = getScrollPosition(pointerPos, context.dir);
|
|
}
|
|
}
|
|
}
|
|
);
|
|
}
|
|
if (orientation === "vertical") {
|
|
return (0, import_jsx_runtime26.jsx)(
|
|
ScrollAreaScrollbarY,
|
|
{
|
|
...commonProps,
|
|
ref: forwardedRef,
|
|
onThumbPositionChange: () => {
|
|
if (context.viewport && thumbRef.current) {
|
|
const scrollPos = context.viewport.scrollTop;
|
|
const offset = getThumbOffsetFromScroll(scrollPos, sizes);
|
|
thumbRef.current.style.transform = `translate3d(0, ${offset}px, 0)`;
|
|
}
|
|
},
|
|
onWheelScroll: (scrollPos) => {
|
|
if (context.viewport) context.viewport.scrollTop = scrollPos;
|
|
},
|
|
onDragScroll: (pointerPos) => {
|
|
if (context.viewport) context.viewport.scrollTop = getScrollPosition(pointerPos);
|
|
}
|
|
}
|
|
);
|
|
}
|
|
return null;
|
|
});
|
|
var ScrollAreaScrollbarX = React27.forwardRef((props, forwardedRef) => {
|
|
const { sizes, onSizesChange, ...scrollbarProps } = props;
|
|
const context = useScrollAreaContext(SCROLLBAR_NAME, props.__scopeScrollArea);
|
|
const [computedStyle, setComputedStyle] = React27.useState();
|
|
const ref = React27.useRef(null);
|
|
const composeRefs2 = useComposedRefs(forwardedRef, ref, context.onScrollbarXChange);
|
|
React27.useEffect(() => {
|
|
if (ref.current) setComputedStyle(getComputedStyle(ref.current));
|
|
}, [ref]);
|
|
return (0, import_jsx_runtime26.jsx)(
|
|
ScrollAreaScrollbarImpl,
|
|
{
|
|
"data-orientation": "horizontal",
|
|
...scrollbarProps,
|
|
ref: composeRefs2,
|
|
sizes,
|
|
style: {
|
|
bottom: 0,
|
|
left: context.dir === "rtl" ? "var(--radix-scroll-area-corner-width)" : 0,
|
|
right: context.dir === "ltr" ? "var(--radix-scroll-area-corner-width)" : 0,
|
|
["--radix-scroll-area-thumb-width"]: getThumbSize(sizes) + "px",
|
|
...props.style
|
|
},
|
|
onThumbPointerDown: (pointerPos) => props.onThumbPointerDown(pointerPos.x),
|
|
onDragScroll: (pointerPos) => props.onDragScroll(pointerPos.x),
|
|
onWheelScroll: (event, maxScrollPos) => {
|
|
if (context.viewport) {
|
|
const scrollPos = context.viewport.scrollLeft + event.deltaX;
|
|
props.onWheelScroll(scrollPos);
|
|
if (isScrollingWithinScrollbarBounds(scrollPos, maxScrollPos)) {
|
|
event.preventDefault();
|
|
}
|
|
}
|
|
},
|
|
onResize: () => {
|
|
if (ref.current && context.viewport && computedStyle) {
|
|
onSizesChange({
|
|
content: context.viewport.scrollWidth,
|
|
viewport: context.viewport.offsetWidth,
|
|
scrollbar: {
|
|
size: ref.current.clientWidth,
|
|
paddingStart: toInt(computedStyle.paddingLeft),
|
|
paddingEnd: toInt(computedStyle.paddingRight)
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
);
|
|
});
|
|
var ScrollAreaScrollbarY = React27.forwardRef((props, forwardedRef) => {
|
|
const { sizes, onSizesChange, ...scrollbarProps } = props;
|
|
const context = useScrollAreaContext(SCROLLBAR_NAME, props.__scopeScrollArea);
|
|
const [computedStyle, setComputedStyle] = React27.useState();
|
|
const ref = React27.useRef(null);
|
|
const composeRefs2 = useComposedRefs(forwardedRef, ref, context.onScrollbarYChange);
|
|
React27.useEffect(() => {
|
|
if (ref.current) setComputedStyle(getComputedStyle(ref.current));
|
|
}, [ref]);
|
|
return (0, import_jsx_runtime26.jsx)(
|
|
ScrollAreaScrollbarImpl,
|
|
{
|
|
"data-orientation": "vertical",
|
|
...scrollbarProps,
|
|
ref: composeRefs2,
|
|
sizes,
|
|
style: {
|
|
top: 0,
|
|
right: context.dir === "ltr" ? 0 : void 0,
|
|
left: context.dir === "rtl" ? 0 : void 0,
|
|
bottom: "var(--radix-scroll-area-corner-height)",
|
|
["--radix-scroll-area-thumb-height"]: getThumbSize(sizes) + "px",
|
|
...props.style
|
|
},
|
|
onThumbPointerDown: (pointerPos) => props.onThumbPointerDown(pointerPos.y),
|
|
onDragScroll: (pointerPos) => props.onDragScroll(pointerPos.y),
|
|
onWheelScroll: (event, maxScrollPos) => {
|
|
if (context.viewport) {
|
|
const scrollPos = context.viewport.scrollTop + event.deltaY;
|
|
props.onWheelScroll(scrollPos);
|
|
if (isScrollingWithinScrollbarBounds(scrollPos, maxScrollPos)) {
|
|
event.preventDefault();
|
|
}
|
|
}
|
|
},
|
|
onResize: () => {
|
|
if (ref.current && context.viewport && computedStyle) {
|
|
onSizesChange({
|
|
content: context.viewport.scrollHeight,
|
|
viewport: context.viewport.offsetHeight,
|
|
scrollbar: {
|
|
size: ref.current.clientHeight,
|
|
paddingStart: toInt(computedStyle.paddingTop),
|
|
paddingEnd: toInt(computedStyle.paddingBottom)
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
);
|
|
});
|
|
var [ScrollbarProvider, useScrollbarContext] = createScrollAreaContext(SCROLLBAR_NAME);
|
|
var ScrollAreaScrollbarImpl = React27.forwardRef((props, forwardedRef) => {
|
|
const {
|
|
__scopeScrollArea,
|
|
sizes,
|
|
hasThumb,
|
|
onThumbChange,
|
|
onThumbPointerUp,
|
|
onThumbPointerDown,
|
|
onThumbPositionChange,
|
|
onDragScroll,
|
|
onWheelScroll,
|
|
onResize,
|
|
...scrollbarProps
|
|
} = props;
|
|
const context = useScrollAreaContext(SCROLLBAR_NAME, __scopeScrollArea);
|
|
const [scrollbar, setScrollbar] = React27.useState(null);
|
|
const composeRefs2 = useComposedRefs(forwardedRef, (node) => setScrollbar(node));
|
|
const rectRef = React27.useRef(null);
|
|
const prevWebkitUserSelectRef = React27.useRef("");
|
|
const viewport = context.viewport;
|
|
const maxScrollPos = sizes.content - sizes.viewport;
|
|
const handleWheelScroll = useCallbackRef(onWheelScroll);
|
|
const handleThumbPositionChange = useCallbackRef(onThumbPositionChange);
|
|
const handleResize = useDebounceCallback(onResize, 10);
|
|
function handleDragScroll(event) {
|
|
if (rectRef.current) {
|
|
const x = event.clientX - rectRef.current.left;
|
|
const y = event.clientY - rectRef.current.top;
|
|
onDragScroll({ x, y });
|
|
}
|
|
}
|
|
React27.useEffect(() => {
|
|
const handleWheel = (event) => {
|
|
const element = event.target;
|
|
const isScrollbarWheel = scrollbar == null ? void 0 : scrollbar.contains(element);
|
|
if (isScrollbarWheel) handleWheelScroll(event, maxScrollPos);
|
|
};
|
|
document.addEventListener("wheel", handleWheel, { passive: false });
|
|
return () => document.removeEventListener("wheel", handleWheel, { passive: false });
|
|
}, [viewport, scrollbar, maxScrollPos, handleWheelScroll]);
|
|
React27.useEffect(handleThumbPositionChange, [sizes, handleThumbPositionChange]);
|
|
useResizeObserver2(scrollbar, handleResize);
|
|
useResizeObserver2(context.content, handleResize);
|
|
return (0, import_jsx_runtime26.jsx)(
|
|
ScrollbarProvider,
|
|
{
|
|
scope: __scopeScrollArea,
|
|
scrollbar,
|
|
hasThumb,
|
|
onThumbChange: useCallbackRef(onThumbChange),
|
|
onThumbPointerUp: useCallbackRef(onThumbPointerUp),
|
|
onThumbPositionChange: handleThumbPositionChange,
|
|
onThumbPointerDown: useCallbackRef(onThumbPointerDown),
|
|
children: (0, import_jsx_runtime26.jsx)(
|
|
Primitive.div,
|
|
{
|
|
...scrollbarProps,
|
|
ref: composeRefs2,
|
|
style: { position: "absolute", ...scrollbarProps.style },
|
|
onPointerDown: composeEventHandlers(props.onPointerDown, (event) => {
|
|
const mainPointer = 0;
|
|
if (event.button === mainPointer) {
|
|
const element = event.target;
|
|
element.setPointerCapture(event.pointerId);
|
|
rectRef.current = scrollbar.getBoundingClientRect();
|
|
prevWebkitUserSelectRef.current = document.body.style.webkitUserSelect;
|
|
document.body.style.webkitUserSelect = "none";
|
|
if (context.viewport) context.viewport.style.scrollBehavior = "auto";
|
|
handleDragScroll(event);
|
|
}
|
|
}),
|
|
onPointerMove: composeEventHandlers(props.onPointerMove, handleDragScroll),
|
|
onPointerUp: composeEventHandlers(props.onPointerUp, (event) => {
|
|
const element = event.target;
|
|
if (element.hasPointerCapture(event.pointerId)) {
|
|
element.releasePointerCapture(event.pointerId);
|
|
}
|
|
document.body.style.webkitUserSelect = prevWebkitUserSelectRef.current;
|
|
if (context.viewport) context.viewport.style.scrollBehavior = "";
|
|
rectRef.current = null;
|
|
})
|
|
}
|
|
)
|
|
}
|
|
);
|
|
});
|
|
var THUMB_NAME = "ScrollAreaThumb";
|
|
var ScrollAreaThumb = React27.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { forceMount, ...thumbProps } = props;
|
|
const scrollbarContext = useScrollbarContext(THUMB_NAME, props.__scopeScrollArea);
|
|
return (0, import_jsx_runtime26.jsx)(Presence, { present: forceMount || scrollbarContext.hasThumb, children: (0, import_jsx_runtime26.jsx)(ScrollAreaThumbImpl, { ref: forwardedRef, ...thumbProps }) });
|
|
}
|
|
);
|
|
var ScrollAreaThumbImpl = React27.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeScrollArea, style, ...thumbProps } = props;
|
|
const scrollAreaContext = useScrollAreaContext(THUMB_NAME, __scopeScrollArea);
|
|
const scrollbarContext = useScrollbarContext(THUMB_NAME, __scopeScrollArea);
|
|
const { onThumbPositionChange } = scrollbarContext;
|
|
const composedRef = useComposedRefs(
|
|
forwardedRef,
|
|
(node) => scrollbarContext.onThumbChange(node)
|
|
);
|
|
const removeUnlinkedScrollListenerRef = React27.useRef(void 0);
|
|
const debounceScrollEnd = useDebounceCallback(() => {
|
|
if (removeUnlinkedScrollListenerRef.current) {
|
|
removeUnlinkedScrollListenerRef.current();
|
|
removeUnlinkedScrollListenerRef.current = void 0;
|
|
}
|
|
}, 100);
|
|
React27.useEffect(() => {
|
|
const viewport = scrollAreaContext.viewport;
|
|
if (viewport) {
|
|
const handleScroll = () => {
|
|
debounceScrollEnd();
|
|
if (!removeUnlinkedScrollListenerRef.current) {
|
|
const listener = addUnlinkedScrollListener(viewport, onThumbPositionChange);
|
|
removeUnlinkedScrollListenerRef.current = listener;
|
|
onThumbPositionChange();
|
|
}
|
|
};
|
|
onThumbPositionChange();
|
|
viewport.addEventListener("scroll", handleScroll);
|
|
return () => viewport.removeEventListener("scroll", handleScroll);
|
|
}
|
|
}, [scrollAreaContext.viewport, debounceScrollEnd, onThumbPositionChange]);
|
|
return (0, import_jsx_runtime26.jsx)(
|
|
Primitive.div,
|
|
{
|
|
"data-state": scrollbarContext.hasThumb ? "visible" : "hidden",
|
|
...thumbProps,
|
|
ref: composedRef,
|
|
style: {
|
|
width: "var(--radix-scroll-area-thumb-width)",
|
|
height: "var(--radix-scroll-area-thumb-height)",
|
|
...style
|
|
},
|
|
onPointerDownCapture: composeEventHandlers(props.onPointerDownCapture, (event) => {
|
|
const thumb = event.target;
|
|
const thumbRect = thumb.getBoundingClientRect();
|
|
const x = event.clientX - thumbRect.left;
|
|
const y = event.clientY - thumbRect.top;
|
|
scrollbarContext.onThumbPointerDown({ x, y });
|
|
}),
|
|
onPointerUp: composeEventHandlers(props.onPointerUp, scrollbarContext.onThumbPointerUp)
|
|
}
|
|
);
|
|
}
|
|
);
|
|
ScrollAreaThumb.displayName = THUMB_NAME;
|
|
var CORNER_NAME = "ScrollAreaCorner";
|
|
var ScrollAreaCorner = React27.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const context = useScrollAreaContext(CORNER_NAME, props.__scopeScrollArea);
|
|
const hasBothScrollbarsVisible = Boolean(context.scrollbarX && context.scrollbarY);
|
|
const hasCorner = context.type !== "scroll" && hasBothScrollbarsVisible;
|
|
return hasCorner ? (0, import_jsx_runtime26.jsx)(ScrollAreaCornerImpl, { ...props, ref: forwardedRef }) : null;
|
|
}
|
|
);
|
|
ScrollAreaCorner.displayName = CORNER_NAME;
|
|
var ScrollAreaCornerImpl = React27.forwardRef((props, forwardedRef) => {
|
|
const { __scopeScrollArea, ...cornerProps } = props;
|
|
const context = useScrollAreaContext(CORNER_NAME, __scopeScrollArea);
|
|
const [width, setWidth] = React27.useState(0);
|
|
const [height, setHeight] = React27.useState(0);
|
|
const hasSize = Boolean(width && height);
|
|
useResizeObserver2(context.scrollbarX, () => {
|
|
var _a2;
|
|
const height2 = ((_a2 = context.scrollbarX) == null ? void 0 : _a2.offsetHeight) || 0;
|
|
context.onCornerHeightChange(height2);
|
|
setHeight(height2);
|
|
});
|
|
useResizeObserver2(context.scrollbarY, () => {
|
|
var _a2;
|
|
const width2 = ((_a2 = context.scrollbarY) == null ? void 0 : _a2.offsetWidth) || 0;
|
|
context.onCornerWidthChange(width2);
|
|
setWidth(width2);
|
|
});
|
|
return hasSize ? (0, import_jsx_runtime26.jsx)(
|
|
Primitive.div,
|
|
{
|
|
...cornerProps,
|
|
ref: forwardedRef,
|
|
style: {
|
|
width,
|
|
height,
|
|
position: "absolute",
|
|
right: context.dir === "ltr" ? 0 : void 0,
|
|
left: context.dir === "rtl" ? 0 : void 0,
|
|
bottom: 0,
|
|
...props.style
|
|
}
|
|
}
|
|
) : null;
|
|
});
|
|
function toInt(value) {
|
|
return value ? parseInt(value, 10) : 0;
|
|
}
|
|
function getThumbRatio(viewportSize, contentSize) {
|
|
const ratio = viewportSize / contentSize;
|
|
return isNaN(ratio) ? 0 : ratio;
|
|
}
|
|
function getThumbSize(sizes) {
|
|
const ratio = getThumbRatio(sizes.viewport, sizes.content);
|
|
const scrollbarPadding = sizes.scrollbar.paddingStart + sizes.scrollbar.paddingEnd;
|
|
const thumbSize = (sizes.scrollbar.size - scrollbarPadding) * ratio;
|
|
return Math.max(thumbSize, 18);
|
|
}
|
|
function getScrollPositionFromPointer(pointerPos, pointerOffset, sizes, dir = "ltr") {
|
|
const thumbSizePx = getThumbSize(sizes);
|
|
const thumbCenter = thumbSizePx / 2;
|
|
const offset = pointerOffset || thumbCenter;
|
|
const thumbOffsetFromEnd = thumbSizePx - offset;
|
|
const minPointerPos = sizes.scrollbar.paddingStart + offset;
|
|
const maxPointerPos = sizes.scrollbar.size - sizes.scrollbar.paddingEnd - thumbOffsetFromEnd;
|
|
const maxScrollPos = sizes.content - sizes.viewport;
|
|
const scrollRange = dir === "ltr" ? [0, maxScrollPos] : [maxScrollPos * -1, 0];
|
|
const interpolate = linearScale([minPointerPos, maxPointerPos], scrollRange);
|
|
return interpolate(pointerPos);
|
|
}
|
|
function getThumbOffsetFromScroll(scrollPos, sizes, dir = "ltr") {
|
|
const thumbSizePx = getThumbSize(sizes);
|
|
const scrollbarPadding = sizes.scrollbar.paddingStart + sizes.scrollbar.paddingEnd;
|
|
const scrollbar = sizes.scrollbar.size - scrollbarPadding;
|
|
const maxScrollPos = sizes.content - sizes.viewport;
|
|
const maxThumbPos = scrollbar - thumbSizePx;
|
|
const scrollClampRange = dir === "ltr" ? [0, maxScrollPos] : [maxScrollPos * -1, 0];
|
|
const scrollWithoutMomentum = clamp(scrollPos, scrollClampRange);
|
|
const interpolate = linearScale([0, maxScrollPos], [0, maxThumbPos]);
|
|
return interpolate(scrollWithoutMomentum);
|
|
}
|
|
function linearScale(input, output) {
|
|
return (value) => {
|
|
if (input[0] === input[1] || output[0] === output[1]) return output[0];
|
|
const ratio = (output[1] - output[0]) / (input[1] - input[0]);
|
|
return output[0] + ratio * (value - input[0]);
|
|
};
|
|
}
|
|
function isScrollingWithinScrollbarBounds(scrollPos, maxScrollPos) {
|
|
return scrollPos > 0 && scrollPos < maxScrollPos;
|
|
}
|
|
var addUnlinkedScrollListener = (node, handler = () => {
|
|
}) => {
|
|
let prevPosition = { left: node.scrollLeft, top: node.scrollTop };
|
|
let rAF = 0;
|
|
(function loop() {
|
|
const position = { left: node.scrollLeft, top: node.scrollTop };
|
|
const isHorizontalScroll = prevPosition.left !== position.left;
|
|
const isVerticalScroll = prevPosition.top !== position.top;
|
|
if (isHorizontalScroll || isVerticalScroll) handler();
|
|
prevPosition = position;
|
|
rAF = window.requestAnimationFrame(loop);
|
|
})();
|
|
return () => window.cancelAnimationFrame(rAF);
|
|
};
|
|
function useDebounceCallback(callback, delay) {
|
|
const handleCallback = useCallbackRef(callback);
|
|
const debounceTimerRef = React27.useRef(0);
|
|
React27.useEffect(() => () => window.clearTimeout(debounceTimerRef.current), []);
|
|
return React27.useCallback(() => {
|
|
window.clearTimeout(debounceTimerRef.current);
|
|
debounceTimerRef.current = window.setTimeout(handleCallback, delay);
|
|
}, [handleCallback, delay]);
|
|
}
|
|
function useResizeObserver2(element, onResize) {
|
|
const handleResize = useCallbackRef(onResize);
|
|
useLayoutEffect2(() => {
|
|
let rAF = 0;
|
|
if (element) {
|
|
const resizeObserver = new ResizeObserver(() => {
|
|
cancelAnimationFrame(rAF);
|
|
rAF = window.requestAnimationFrame(handleResize);
|
|
});
|
|
resizeObserver.observe(element);
|
|
return () => {
|
|
window.cancelAnimationFrame(rAF);
|
|
resizeObserver.unobserve(element);
|
|
};
|
|
}
|
|
}, [element, handleResize]);
|
|
}
|
|
var Root12 = ScrollArea;
|
|
var Viewport2 = ScrollAreaViewport;
|
|
var Scrollbar = ScrollAreaScrollbar;
|
|
var Thumb = ScrollAreaThumb;
|
|
var Corner = ScrollAreaCorner;
|
|
|
|
// ../../node_modules/@radix-ui/react-select/dist/index.mjs
|
|
var dist_exports30 = {};
|
|
__export(dist_exports30, {
|
|
Arrow: () => Arrow26,
|
|
Content: () => Content29,
|
|
Group: () => Group3,
|
|
Icon: () => Icon,
|
|
Item: () => Item5,
|
|
ItemIndicator: () => ItemIndicator3,
|
|
ItemText: () => ItemText,
|
|
Label: () => Label5,
|
|
Portal: () => Portal5,
|
|
Root: () => Root211,
|
|
ScrollDownButton: () => ScrollDownButton,
|
|
ScrollUpButton: () => ScrollUpButton,
|
|
Select: () => Select,
|
|
SelectArrow: () => SelectArrow,
|
|
SelectContent: () => SelectContent,
|
|
SelectGroup: () => SelectGroup,
|
|
SelectIcon: () => SelectIcon,
|
|
SelectItem: () => SelectItem,
|
|
SelectItemIndicator: () => SelectItemIndicator,
|
|
SelectItemText: () => SelectItemText,
|
|
SelectLabel: () => SelectLabel,
|
|
SelectPortal: () => SelectPortal,
|
|
SelectScrollDownButton: () => SelectScrollDownButton,
|
|
SelectScrollUpButton: () => SelectScrollUpButton,
|
|
SelectSeparator: () => SelectSeparator,
|
|
SelectTrigger: () => SelectTrigger,
|
|
SelectValue: () => SelectValue,
|
|
SelectViewport: () => SelectViewport,
|
|
Separator: () => Separator3,
|
|
Trigger: () => Trigger8,
|
|
Value: () => Value,
|
|
Viewport: () => Viewport3,
|
|
createSelectScope: () => createSelectScope
|
|
});
|
|
var React29 = __toESM(require_react(), 1);
|
|
var ReactDOM2 = __toESM(require_react_dom(), 1);
|
|
var import_jsx_runtime27 = __toESM(require_jsx_runtime(), 1);
|
|
var OPEN_KEYS = [" ", "Enter", "ArrowUp", "ArrowDown"];
|
|
var SELECTION_KEYS2 = [" ", "Enter"];
|
|
var SELECT_NAME = "Select";
|
|
var [Collection7, useCollection7, createCollectionScope7] = createCollection(SELECT_NAME);
|
|
var [createSelectContext, createSelectScope] = createContextScope(SELECT_NAME, [
|
|
createCollectionScope7,
|
|
createPopperScope
|
|
]);
|
|
var usePopperScope3 = 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 = usePopperScope3(__scopeSelect);
|
|
const [trigger, setTrigger] = React29.useState(null);
|
|
const [valueNode, setValueNode] = React29.useState(null);
|
|
const [valueNodeHasChildren, setValueNodeHasChildren] = React29.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 = React29.useRef(null);
|
|
const isFormControl2 = trigger ? form || !!trigger.closest("form") : true;
|
|
const [nativeOptionsSet, setNativeOptionsSet] = React29.useState(/* @__PURE__ */ new Set());
|
|
const nativeSelectKey = Array.from(nativeOptionsSet).map((option) => option.props.value).join(";");
|
|
return (0, import_jsx_runtime27.jsx)(Root22, { ...popperScope, children: (0, import_jsx_runtime27.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_runtime27.jsx)(Collection7.Provider, { scope: __scopeSelect, children: (0, import_jsx_runtime27.jsx)(
|
|
SelectNativeOptionsProvider,
|
|
{
|
|
scope: props.__scopeSelect,
|
|
onNativeOptionAdd: React29.useCallback((option) => {
|
|
setNativeOptionsSet((prev) => new Set(prev).add(option));
|
|
}, []),
|
|
onNativeOptionRemove: React29.useCallback((option) => {
|
|
setNativeOptionsSet((prev) => {
|
|
const optionsSet = new Set(prev);
|
|
optionsSet.delete(option);
|
|
return optionsSet;
|
|
});
|
|
}, []),
|
|
children
|
|
}
|
|
) }),
|
|
isFormControl2 ? (0, import_jsx_runtime27.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_runtime27.jsx)("option", { value: "" }) : null,
|
|
Array.from(nativeOptionsSet)
|
|
]
|
|
},
|
|
nativeSelectKey
|
|
) : null
|
|
]
|
|
}
|
|
) });
|
|
};
|
|
Select.displayName = SELECT_NAME;
|
|
var TRIGGER_NAME10 = "SelectTrigger";
|
|
var SelectTrigger = React29.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeSelect, disabled = false, ...triggerProps } = props;
|
|
const popperScope = usePopperScope3(__scopeSelect);
|
|
const context = useSelectContext(TRIGGER_NAME10, __scopeSelect);
|
|
const isDisabled = context.disabled || disabled;
|
|
const composedRefs = useComposedRefs(forwardedRef, context.onTriggerChange);
|
|
const getItems = useCollection7(__scopeSelect);
|
|
const pointerTypeRef = React29.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_runtime27.jsx)(Anchor, { asChild: true, ...popperScope, children: (0, import_jsx_runtime27.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_NAME10;
|
|
var VALUE_NAME = "SelectValue";
|
|
var SelectValue = React29.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_runtime27.jsx)(
|
|
Primitive.span,
|
|
{
|
|
...valueProps,
|
|
ref: composedRefs,
|
|
style: { pointerEvents: "none" },
|
|
children: shouldShowPlaceholder(context.value) ? (0, import_jsx_runtime27.jsx)(import_jsx_runtime27.Fragment, { children: placeholder }) : children
|
|
}
|
|
);
|
|
}
|
|
);
|
|
SelectValue.displayName = VALUE_NAME;
|
|
var ICON_NAME = "SelectIcon";
|
|
var SelectIcon = React29.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeSelect, children, ...iconProps } = props;
|
|
return (0, import_jsx_runtime27.jsx)(Primitive.span, { "aria-hidden": true, ...iconProps, ref: forwardedRef, children: children || "▼" });
|
|
}
|
|
);
|
|
SelectIcon.displayName = ICON_NAME;
|
|
var PORTAL_NAME7 = "SelectPortal";
|
|
var SelectPortal = (props) => {
|
|
return (0, import_jsx_runtime27.jsx)(Portal, { asChild: true, ...props });
|
|
};
|
|
SelectPortal.displayName = PORTAL_NAME7;
|
|
var CONTENT_NAME10 = "SelectContent";
|
|
var SelectContent = React29.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const context = useSelectContext(CONTENT_NAME10, props.__scopeSelect);
|
|
const [fragment, setFragment] = React29.useState();
|
|
useLayoutEffect2(() => {
|
|
setFragment(new DocumentFragment());
|
|
}, []);
|
|
if (!context.open) {
|
|
const frag = fragment;
|
|
return frag ? ReactDOM2.createPortal(
|
|
(0, import_jsx_runtime27.jsx)(SelectContentProvider, { scope: props.__scopeSelect, children: (0, import_jsx_runtime27.jsx)(Collection7.Slot, { scope: props.__scopeSelect, children: (0, import_jsx_runtime27.jsx)("div", { children: props.children }) }) }),
|
|
frag
|
|
) : null;
|
|
}
|
|
return (0, import_jsx_runtime27.jsx)(SelectContentImpl, { ...props, ref: forwardedRef });
|
|
}
|
|
);
|
|
SelectContent.displayName = CONTENT_NAME10;
|
|
var CONTENT_MARGIN = 10;
|
|
var [SelectContentProvider, useSelectContentContext] = createSelectContext(CONTENT_NAME10);
|
|
var CONTENT_IMPL_NAME = "SelectContentImpl";
|
|
var Slot2 = createSlot("SelectContent.RemoveScroll");
|
|
var SelectContentImpl = React29.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_NAME10, __scopeSelect);
|
|
const [content, setContent] = React29.useState(null);
|
|
const [viewport, setViewport] = React29.useState(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, (node) => setContent(node));
|
|
const [selectedItem, setSelectedItem] = React29.useState(null);
|
|
const [selectedItemText, setSelectedItemText] = React29.useState(
|
|
null
|
|
);
|
|
const getItems = useCollection7(__scopeSelect);
|
|
const [isPositioned, setIsPositioned] = React29.useState(false);
|
|
const firstValidItemFoundRef = React29.useRef(false);
|
|
React29.useEffect(() => {
|
|
if (content) return hideOthers(content);
|
|
}, [content]);
|
|
useFocusGuards();
|
|
const focusFirst5 = React29.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 = React29.useCallback(
|
|
() => focusFirst5([selectedItem, content]),
|
|
[focusFirst5, selectedItem, content]
|
|
);
|
|
React29.useEffect(() => {
|
|
if (isPositioned) {
|
|
focusSelectedItem();
|
|
}
|
|
}, [isPositioned, focusSelectedItem]);
|
|
const { onOpenChange, triggerPointerDownPosRef } = context;
|
|
React29.useEffect(() => {
|
|
if (content) {
|
|
let pointerMoveDelta = { x: 0, y: 0 };
|
|
const handlePointerMove = (event) => {
|
|
var _a2, _b;
|
|
pointerMoveDelta = {
|
|
x: Math.abs(Math.round(event.pageX) - (((_a2 = triggerPointerDownPosRef.current) == null ? void 0 : _a2.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]);
|
|
React29.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 = React29.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 = React29.useCallback(() => content == null ? void 0 : content.focus(), [content]);
|
|
const itemTextRefCallback = React29.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_runtime27.jsx)(
|
|
SelectContentProvider,
|
|
{
|
|
scope: __scopeSelect,
|
|
content,
|
|
viewport,
|
|
onViewportChange: setViewport,
|
|
itemRefCallback,
|
|
selectedItem,
|
|
onItemLeave: handleItemLeave,
|
|
itemTextRefCallback,
|
|
focusSelectedItem,
|
|
selectedItemText,
|
|
position,
|
|
isPositioned,
|
|
searchRef,
|
|
children: (0, import_jsx_runtime27.jsx)(Combination_default, { as: Slot2, allowPinchZoom: true, children: (0, import_jsx_runtime27.jsx)(
|
|
FocusScope,
|
|
{
|
|
asChild: true,
|
|
trapped: context.open,
|
|
onMountAutoFocus: (event) => {
|
|
event.preventDefault();
|
|
},
|
|
onUnmountAutoFocus: composeEventHandlers(onCloseAutoFocus, (event) => {
|
|
var _a2;
|
|
(_a2 = context.trigger) == null ? void 0 : _a2.focus({ preventScroll: true });
|
|
event.preventDefault();
|
|
}),
|
|
children: (0, import_jsx_runtime27.jsx)(
|
|
DismissableLayer,
|
|
{
|
|
asChild: true,
|
|
disableOutsidePointerEvents: true,
|
|
onEscapeKeyDown,
|
|
onPointerDownOutside,
|
|
onFocusOutside: (event) => event.preventDefault(),
|
|
onDismiss: () => context.onOpenChange(false),
|
|
children: (0, import_jsx_runtime27.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(() => focusFirst5(candidateNodes));
|
|
event.preventDefault();
|
|
}
|
|
})
|
|
}
|
|
)
|
|
}
|
|
)
|
|
}
|
|
) })
|
|
}
|
|
);
|
|
}
|
|
);
|
|
SelectContentImpl.displayName = CONTENT_IMPL_NAME;
|
|
var ITEM_ALIGNED_POSITION_NAME = "SelectItemAlignedPosition";
|
|
var SelectItemAlignedPosition = React29.forwardRef((props, forwardedRef) => {
|
|
const { __scopeSelect, onPlaced, ...popperProps } = props;
|
|
const context = useSelectContext(CONTENT_NAME10, __scopeSelect);
|
|
const contentContext = useSelectContentContext(CONTENT_NAME10, __scopeSelect);
|
|
const [contentWrapper, setContentWrapper] = React29.useState(null);
|
|
const [content, setContent] = React29.useState(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, (node) => setContent(node));
|
|
const getItems = useCollection7(__scopeSelect);
|
|
const shouldExpandOnScrollRef = React29.useRef(false);
|
|
const shouldRepositionRef = React29.useRef(true);
|
|
const { viewport, selectedItem, selectedItemText, focusSelectedItem } = contentContext;
|
|
const position = React29.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] = React29.useState();
|
|
useLayoutEffect2(() => {
|
|
if (content) setContentZIndex(window.getComputedStyle(content).zIndex);
|
|
}, [content]);
|
|
const handleScrollButtonChange = React29.useCallback(
|
|
(node) => {
|
|
if (node && shouldRepositionRef.current === true) {
|
|
position();
|
|
focusSelectedItem == null ? void 0 : focusSelectedItem();
|
|
shouldRepositionRef.current = false;
|
|
}
|
|
},
|
|
[position, focusSelectedItem]
|
|
);
|
|
return (0, import_jsx_runtime27.jsx)(
|
|
SelectViewportProvider,
|
|
{
|
|
scope: __scopeSelect,
|
|
contentWrapper,
|
|
shouldExpandOnScrollRef,
|
|
onScrollButtonChange: handleScrollButtonChange,
|
|
children: (0, import_jsx_runtime27.jsx)(
|
|
"div",
|
|
{
|
|
ref: setContentWrapper,
|
|
style: {
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
position: "fixed",
|
|
zIndex: contentZIndex
|
|
},
|
|
children: (0, import_jsx_runtime27.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 = React29.forwardRef((props, forwardedRef) => {
|
|
const {
|
|
__scopeSelect,
|
|
align = "start",
|
|
collisionPadding = CONTENT_MARGIN,
|
|
...popperProps
|
|
} = props;
|
|
const popperScope = usePopperScope3(__scopeSelect);
|
|
return (0, import_jsx_runtime27.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_NAME10, {});
|
|
var VIEWPORT_NAME3 = "SelectViewport";
|
|
var SelectViewport = React29.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeSelect, nonce, ...viewportProps } = props;
|
|
const contentContext = useSelectContentContext(VIEWPORT_NAME3, __scopeSelect);
|
|
const viewportContext = useSelectViewportContext(VIEWPORT_NAME3, __scopeSelect);
|
|
const composedRefs = useComposedRefs(forwardedRef, contentContext.onViewportChange);
|
|
const prevScrollTopRef = React29.useRef(0);
|
|
return (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
|
|
(0, import_jsx_runtime27.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_runtime27.jsx)(Collection7.Slot, { scope: __scopeSelect, children: (0, import_jsx_runtime27.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_NAME3;
|
|
var GROUP_NAME6 = "SelectGroup";
|
|
var [SelectGroupContextProvider, useSelectGroupContext] = createSelectContext(GROUP_NAME6);
|
|
var SelectGroup = React29.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeSelect, ...groupProps } = props;
|
|
const groupId = useId();
|
|
return (0, import_jsx_runtime27.jsx)(SelectGroupContextProvider, { scope: __scopeSelect, id: groupId, children: (0, import_jsx_runtime27.jsx)(Primitive.div, { role: "group", "aria-labelledby": groupId, ...groupProps, ref: forwardedRef }) });
|
|
}
|
|
);
|
|
SelectGroup.displayName = GROUP_NAME6;
|
|
var LABEL_NAME6 = "SelectLabel";
|
|
var SelectLabel = React29.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeSelect, ...labelProps } = props;
|
|
const groupContext = useSelectGroupContext(LABEL_NAME6, __scopeSelect);
|
|
return (0, import_jsx_runtime27.jsx)(Primitive.div, { id: groupContext.id, ...labelProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
SelectLabel.displayName = LABEL_NAME6;
|
|
var ITEM_NAME9 = "SelectItem";
|
|
var [SelectItemContextProvider, useSelectItemContext] = createSelectContext(ITEM_NAME9);
|
|
var SelectItem = React29.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const {
|
|
__scopeSelect,
|
|
value,
|
|
disabled = false,
|
|
textValue: textValueProp,
|
|
...itemProps
|
|
} = props;
|
|
const context = useSelectContext(ITEM_NAME9, __scopeSelect);
|
|
const contentContext = useSelectContentContext(ITEM_NAME9, __scopeSelect);
|
|
const isSelected = context.value === value;
|
|
const [textValue, setTextValue] = React29.useState(textValueProp ?? "");
|
|
const [isFocused, setIsFocused] = React29.useState(false);
|
|
const composedRefs = useComposedRefs(
|
|
forwardedRef,
|
|
(node) => {
|
|
var _a2;
|
|
return (_a2 = contentContext.itemRefCallback) == null ? void 0 : _a2.call(contentContext, node, value, disabled);
|
|
}
|
|
);
|
|
const textId = useId();
|
|
const pointerTypeRef = React29.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_runtime27.jsx)(
|
|
SelectItemContextProvider,
|
|
{
|
|
scope: __scopeSelect,
|
|
value,
|
|
disabled,
|
|
textId,
|
|
isSelected,
|
|
onItemTextChange: React29.useCallback((node) => {
|
|
setTextValue((prevTextValue) => prevTextValue || ((node == null ? void 0 : node.textContent) ?? "").trim());
|
|
}, []),
|
|
children: (0, import_jsx_runtime27.jsx)(
|
|
Collection7.ItemSlot,
|
|
{
|
|
scope: __scopeSelect,
|
|
value,
|
|
disabled,
|
|
textValue,
|
|
children: (0, import_jsx_runtime27.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 _a2;
|
|
pointerTypeRef.current = event.pointerType;
|
|
if (disabled) {
|
|
(_a2 = contentContext.onItemLeave) == null ? void 0 : _a2.call(contentContext);
|
|
} else if (pointerTypeRef.current === "mouse") {
|
|
event.currentTarget.focus({ preventScroll: true });
|
|
}
|
|
}),
|
|
onPointerLeave: composeEventHandlers(itemProps.onPointerLeave, (event) => {
|
|
var _a2;
|
|
if (event.currentTarget === document.activeElement) {
|
|
(_a2 = contentContext.onItemLeave) == null ? void 0 : _a2.call(contentContext);
|
|
}
|
|
}),
|
|
onKeyDown: composeEventHandlers(itemProps.onKeyDown, (event) => {
|
|
var _a2;
|
|
const isTypingAhead = ((_a2 = contentContext.searchRef) == null ? void 0 : _a2.current) !== "";
|
|
if (isTypingAhead && event.key === " ") return;
|
|
if (SELECTION_KEYS2.includes(event.key)) handleSelect();
|
|
if (event.key === " ") event.preventDefault();
|
|
})
|
|
}
|
|
)
|
|
}
|
|
)
|
|
}
|
|
);
|
|
}
|
|
);
|
|
SelectItem.displayName = ITEM_NAME9;
|
|
var ITEM_TEXT_NAME = "SelectItemText";
|
|
var SelectItemText = React29.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] = React29.useState(null);
|
|
const composedRefs = useComposedRefs(
|
|
forwardedRef,
|
|
(node) => setItemTextNode(node),
|
|
itemContext.onItemTextChange,
|
|
(node) => {
|
|
var _a2;
|
|
return (_a2 = contentContext.itemTextRefCallback) == null ? void 0 : _a2.call(contentContext, node, itemContext.value, itemContext.disabled);
|
|
}
|
|
);
|
|
const textContent = itemTextNode == null ? void 0 : itemTextNode.textContent;
|
|
const nativeOption = React29.useMemo(
|
|
() => (0, import_jsx_runtime27.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_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
|
|
(0, import_jsx_runtime27.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_NAME2 = "SelectItemIndicator";
|
|
var SelectItemIndicator = React29.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeSelect, ...itemIndicatorProps } = props;
|
|
const itemContext = useSelectItemContext(ITEM_INDICATOR_NAME2, __scopeSelect);
|
|
return itemContext.isSelected ? (0, import_jsx_runtime27.jsx)(Primitive.span, { "aria-hidden": true, ...itemIndicatorProps, ref: forwardedRef }) : null;
|
|
}
|
|
);
|
|
SelectItemIndicator.displayName = ITEM_INDICATOR_NAME2;
|
|
var SCROLL_UP_BUTTON_NAME = "SelectScrollUpButton";
|
|
var SelectScrollUpButton = React29.forwardRef((props, forwardedRef) => {
|
|
const contentContext = useSelectContentContext(SCROLL_UP_BUTTON_NAME, props.__scopeSelect);
|
|
const viewportContext = useSelectViewportContext(SCROLL_UP_BUTTON_NAME, props.__scopeSelect);
|
|
const [canScrollUp, setCanScrollUp] = React29.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_runtime27.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 = React29.forwardRef((props, forwardedRef) => {
|
|
const contentContext = useSelectContentContext(SCROLL_DOWN_BUTTON_NAME, props.__scopeSelect);
|
|
const viewportContext = useSelectViewportContext(SCROLL_DOWN_BUTTON_NAME, props.__scopeSelect);
|
|
const [canScrollDown, setCanScrollDown] = React29.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_runtime27.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 = React29.forwardRef((props, forwardedRef) => {
|
|
const { __scopeSelect, onAutoScroll, ...scrollIndicatorProps } = props;
|
|
const contentContext = useSelectContentContext("SelectScrollButton", __scopeSelect);
|
|
const autoScrollTimerRef = React29.useRef(null);
|
|
const getItems = useCollection7(__scopeSelect);
|
|
const clearAutoScrollTimer = React29.useCallback(() => {
|
|
if (autoScrollTimerRef.current !== null) {
|
|
window.clearInterval(autoScrollTimerRef.current);
|
|
autoScrollTimerRef.current = null;
|
|
}
|
|
}, []);
|
|
React29.useEffect(() => {
|
|
return () => clearAutoScrollTimer();
|
|
}, [clearAutoScrollTimer]);
|
|
useLayoutEffect2(() => {
|
|
var _a2;
|
|
const activeItem = getItems().find((item) => item.ref.current === document.activeElement);
|
|
(_a2 = activeItem == null ? void 0 : activeItem.ref.current) == null ? void 0 : _a2.scrollIntoView({ block: "nearest" });
|
|
}, [getItems]);
|
|
return (0, import_jsx_runtime27.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 _a2;
|
|
(_a2 = contentContext.onItemLeave) == null ? void 0 : _a2.call(contentContext);
|
|
if (autoScrollTimerRef.current === null) {
|
|
autoScrollTimerRef.current = window.setInterval(onAutoScroll, 50);
|
|
}
|
|
}),
|
|
onPointerLeave: composeEventHandlers(scrollIndicatorProps.onPointerLeave, () => {
|
|
clearAutoScrollTimer();
|
|
})
|
|
}
|
|
);
|
|
});
|
|
var SEPARATOR_NAME5 = "SelectSeparator";
|
|
var SelectSeparator = React29.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeSelect, ...separatorProps } = props;
|
|
return (0, import_jsx_runtime27.jsx)(Primitive.div, { "aria-hidden": true, ...separatorProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
SelectSeparator.displayName = SEPARATOR_NAME5;
|
|
var ARROW_NAME6 = "SelectArrow";
|
|
var SelectArrow = React29.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeSelect, ...arrowProps } = props;
|
|
const popperScope = usePopperScope3(__scopeSelect);
|
|
const context = useSelectContext(ARROW_NAME6, __scopeSelect);
|
|
const contentContext = useSelectContentContext(ARROW_NAME6, __scopeSelect);
|
|
return context.open && contentContext.position === "popper" ? (0, import_jsx_runtime27.jsx)(Arrow, { ...popperScope, ...arrowProps, ref: forwardedRef }) : null;
|
|
}
|
|
);
|
|
SelectArrow.displayName = ARROW_NAME6;
|
|
var BUBBLE_INPUT_NAME3 = "SelectBubbleInput";
|
|
var SelectBubbleInput = React29.forwardRef(
|
|
({ __scopeSelect, value, ...props }, forwardedRef) => {
|
|
const ref = React29.useRef(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, ref);
|
|
const prevValue = usePrevious(value);
|
|
React29.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_runtime27.jsx)(
|
|
Primitive.select,
|
|
{
|
|
...props,
|
|
style: { ...VISUALLY_HIDDEN_STYLES, ...props.style },
|
|
ref: composedRefs,
|
|
defaultValue: value
|
|
}
|
|
);
|
|
}
|
|
);
|
|
SelectBubbleInput.displayName = BUBBLE_INPUT_NAME3;
|
|
function shouldShowPlaceholder(value) {
|
|
return value === "" || value === void 0;
|
|
}
|
|
function useTypeaheadSearch(onSearchChange) {
|
|
const handleSearchChange = useCallbackRef(onSearchChange);
|
|
const searchRef = React29.useRef("");
|
|
const timerRef = React29.useRef(0);
|
|
const handleTypeaheadSearch = React29.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 = React29.useCallback(() => {
|
|
searchRef.current = "";
|
|
window.clearTimeout(timerRef.current);
|
|
}, []);
|
|
React29.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 = wrapArray4(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 wrapArray4(array, startIndex) {
|
|
return array.map((_, index) => array[(startIndex + index) % array.length]);
|
|
}
|
|
var Root211 = Select;
|
|
var Trigger8 = SelectTrigger;
|
|
var Value = SelectValue;
|
|
var Icon = SelectIcon;
|
|
var Portal5 = SelectPortal;
|
|
var Content29 = SelectContent;
|
|
var Viewport3 = SelectViewport;
|
|
var Group3 = SelectGroup;
|
|
var Label5 = SelectLabel;
|
|
var Item5 = SelectItem;
|
|
var ItemText = SelectItemText;
|
|
var ItemIndicator3 = SelectItemIndicator;
|
|
var ScrollUpButton = SelectScrollUpButton;
|
|
var ScrollDownButton = SelectScrollDownButton;
|
|
var Separator3 = SelectSeparator;
|
|
var Arrow26 = SelectArrow;
|
|
|
|
// ../../node_modules/@radix-ui/react-separator/dist/index.mjs
|
|
var dist_exports31 = {};
|
|
__export(dist_exports31, {
|
|
Root: () => Root13,
|
|
Separator: () => Separator4
|
|
});
|
|
var React30 = __toESM(require_react(), 1);
|
|
var import_jsx_runtime28 = __toESM(require_jsx_runtime(), 1);
|
|
var NAME5 = "Separator";
|
|
var DEFAULT_ORIENTATION = "horizontal";
|
|
var ORIENTATIONS = ["horizontal", "vertical"];
|
|
var Separator4 = React30.forwardRef((props, forwardedRef) => {
|
|
const { decorative, orientation: orientationProp = DEFAULT_ORIENTATION, ...domProps } = props;
|
|
const orientation = isValidOrientation(orientationProp) ? orientationProp : DEFAULT_ORIENTATION;
|
|
const ariaOrientation = orientation === "vertical" ? orientation : void 0;
|
|
const semanticProps = decorative ? { role: "none" } : { "aria-orientation": ariaOrientation, role: "separator" };
|
|
return (0, import_jsx_runtime28.jsx)(
|
|
Primitive.div,
|
|
{
|
|
"data-orientation": orientation,
|
|
...semanticProps,
|
|
...domProps,
|
|
ref: forwardedRef
|
|
}
|
|
);
|
|
});
|
|
Separator4.displayName = NAME5;
|
|
function isValidOrientation(orientation) {
|
|
return ORIENTATIONS.includes(orientation);
|
|
}
|
|
var Root13 = Separator4;
|
|
|
|
// ../../node_modules/@radix-ui/react-slider/dist/index.mjs
|
|
var dist_exports32 = {};
|
|
__export(dist_exports32, {
|
|
Range: () => Range,
|
|
Root: () => Root14,
|
|
Slider: () => Slider,
|
|
SliderRange: () => SliderRange,
|
|
SliderThumb: () => SliderThumb,
|
|
SliderTrack: () => SliderTrack,
|
|
Thumb: () => Thumb2,
|
|
Track: () => Track,
|
|
createSliderScope: () => createSliderScope
|
|
});
|
|
var React31 = __toESM(require_react(), 1);
|
|
var import_jsx_runtime29 = __toESM(require_jsx_runtime(), 1);
|
|
var PAGE_KEYS = ["PageUp", "PageDown"];
|
|
var ARROW_KEYS3 = ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"];
|
|
var BACK_KEYS = {
|
|
"from-left": ["Home", "PageDown", "ArrowDown", "ArrowLeft"],
|
|
"from-right": ["Home", "PageDown", "ArrowDown", "ArrowRight"],
|
|
"from-bottom": ["Home", "PageDown", "ArrowDown", "ArrowLeft"],
|
|
"from-top": ["Home", "PageDown", "ArrowUp", "ArrowLeft"]
|
|
};
|
|
var SLIDER_NAME = "Slider";
|
|
var [Collection8, useCollection8, createCollectionScope8] = createCollection(SLIDER_NAME);
|
|
var [createSliderContext, createSliderScope] = createContextScope(SLIDER_NAME, [
|
|
createCollectionScope8
|
|
]);
|
|
var [SliderProvider, useSliderContext] = createSliderContext(SLIDER_NAME);
|
|
var Slider = React31.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const {
|
|
name,
|
|
min = 0,
|
|
max = 100,
|
|
step = 1,
|
|
orientation = "horizontal",
|
|
disabled = false,
|
|
minStepsBetweenThumbs = 0,
|
|
defaultValue = [min],
|
|
value,
|
|
onValueChange = () => {
|
|
},
|
|
onValueCommit = () => {
|
|
},
|
|
inverted = false,
|
|
form,
|
|
...sliderProps
|
|
} = props;
|
|
const thumbRefs = React31.useRef(/* @__PURE__ */ new Set());
|
|
const valueIndexToChangeRef = React31.useRef(0);
|
|
const isHorizontal = orientation === "horizontal";
|
|
const SliderOrientation = isHorizontal ? SliderHorizontal : SliderVertical;
|
|
const [values = [], setValues] = useControllableState({
|
|
prop: value,
|
|
defaultProp: defaultValue,
|
|
onChange: (value2) => {
|
|
var _a2;
|
|
const thumbs = [...thumbRefs.current];
|
|
(_a2 = thumbs[valueIndexToChangeRef.current]) == null ? void 0 : _a2.focus();
|
|
onValueChange(value2);
|
|
}
|
|
});
|
|
const valuesBeforeSlideStartRef = React31.useRef(values);
|
|
function handleSlideStart(value2) {
|
|
const closestIndex = getClosestValueIndex(values, value2);
|
|
updateValues(value2, closestIndex);
|
|
}
|
|
function handleSlideMove(value2) {
|
|
updateValues(value2, valueIndexToChangeRef.current);
|
|
}
|
|
function handleSlideEnd() {
|
|
const prevValue = valuesBeforeSlideStartRef.current[valueIndexToChangeRef.current];
|
|
const nextValue = values[valueIndexToChangeRef.current];
|
|
const hasChanged = nextValue !== prevValue;
|
|
if (hasChanged) onValueCommit(values);
|
|
}
|
|
function updateValues(value2, atIndex, { commit } = { commit: false }) {
|
|
const decimalCount = getDecimalCount(step);
|
|
const snapToStep = roundValue(Math.round((value2 - min) / step) * step + min, decimalCount);
|
|
const nextValue = clamp(snapToStep, [min, max]);
|
|
setValues((prevValues = []) => {
|
|
const nextValues = getNextSortedValues(prevValues, nextValue, atIndex);
|
|
if (hasMinStepsBetweenValues(nextValues, minStepsBetweenThumbs * step)) {
|
|
valueIndexToChangeRef.current = nextValues.indexOf(nextValue);
|
|
const hasChanged = String(nextValues) !== String(prevValues);
|
|
if (hasChanged && commit) onValueCommit(nextValues);
|
|
return hasChanged ? nextValues : prevValues;
|
|
} else {
|
|
return prevValues;
|
|
}
|
|
});
|
|
}
|
|
return (0, import_jsx_runtime29.jsx)(
|
|
SliderProvider,
|
|
{
|
|
scope: props.__scopeSlider,
|
|
name,
|
|
disabled,
|
|
min,
|
|
max,
|
|
valueIndexToChangeRef,
|
|
thumbs: thumbRefs.current,
|
|
values,
|
|
orientation,
|
|
form,
|
|
children: (0, import_jsx_runtime29.jsx)(Collection8.Provider, { scope: props.__scopeSlider, children: (0, import_jsx_runtime29.jsx)(Collection8.Slot, { scope: props.__scopeSlider, children: (0, import_jsx_runtime29.jsx)(
|
|
SliderOrientation,
|
|
{
|
|
"aria-disabled": disabled,
|
|
"data-disabled": disabled ? "" : void 0,
|
|
...sliderProps,
|
|
ref: forwardedRef,
|
|
onPointerDown: composeEventHandlers(sliderProps.onPointerDown, () => {
|
|
if (!disabled) valuesBeforeSlideStartRef.current = values;
|
|
}),
|
|
min,
|
|
max,
|
|
inverted,
|
|
onSlideStart: disabled ? void 0 : handleSlideStart,
|
|
onSlideMove: disabled ? void 0 : handleSlideMove,
|
|
onSlideEnd: disabled ? void 0 : handleSlideEnd,
|
|
onHomeKeyDown: () => !disabled && updateValues(min, 0, { commit: true }),
|
|
onEndKeyDown: () => !disabled && updateValues(max, values.length - 1, { commit: true }),
|
|
onStepKeyDown: ({ event, direction: stepDirection }) => {
|
|
if (!disabled) {
|
|
const isPageKey = PAGE_KEYS.includes(event.key);
|
|
const isSkipKey = isPageKey || event.shiftKey && ARROW_KEYS3.includes(event.key);
|
|
const multiplier = isSkipKey ? 10 : 1;
|
|
const atIndex = valueIndexToChangeRef.current;
|
|
const value2 = values[atIndex];
|
|
const stepInDirection = step * multiplier * stepDirection;
|
|
updateValues(value2 + stepInDirection, atIndex, { commit: true });
|
|
}
|
|
}
|
|
}
|
|
) }) })
|
|
}
|
|
);
|
|
}
|
|
);
|
|
Slider.displayName = SLIDER_NAME;
|
|
var [SliderOrientationProvider, useSliderOrientationContext] = createSliderContext(SLIDER_NAME, {
|
|
startEdge: "left",
|
|
endEdge: "right",
|
|
size: "width",
|
|
direction: 1
|
|
});
|
|
var SliderHorizontal = React31.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const {
|
|
min,
|
|
max,
|
|
dir,
|
|
inverted,
|
|
onSlideStart,
|
|
onSlideMove,
|
|
onSlideEnd,
|
|
onStepKeyDown,
|
|
...sliderProps
|
|
} = props;
|
|
const [slider, setSlider] = React31.useState(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, (node) => setSlider(node));
|
|
const rectRef = React31.useRef(void 0);
|
|
const direction = useDirection(dir);
|
|
const isDirectionLTR = direction === "ltr";
|
|
const isSlidingFromLeft = isDirectionLTR && !inverted || !isDirectionLTR && inverted;
|
|
function getValueFromPointer(pointerPosition) {
|
|
const rect = rectRef.current || slider.getBoundingClientRect();
|
|
const input = [0, rect.width];
|
|
const output = isSlidingFromLeft ? [min, max] : [max, min];
|
|
const value = linearScale2(input, output);
|
|
rectRef.current = rect;
|
|
return value(pointerPosition - rect.left);
|
|
}
|
|
return (0, import_jsx_runtime29.jsx)(
|
|
SliderOrientationProvider,
|
|
{
|
|
scope: props.__scopeSlider,
|
|
startEdge: isSlidingFromLeft ? "left" : "right",
|
|
endEdge: isSlidingFromLeft ? "right" : "left",
|
|
direction: isSlidingFromLeft ? 1 : -1,
|
|
size: "width",
|
|
children: (0, import_jsx_runtime29.jsx)(
|
|
SliderImpl,
|
|
{
|
|
dir: direction,
|
|
"data-orientation": "horizontal",
|
|
...sliderProps,
|
|
ref: composedRefs,
|
|
style: {
|
|
...sliderProps.style,
|
|
["--radix-slider-thumb-transform"]: "translateX(-50%)"
|
|
},
|
|
onSlideStart: (event) => {
|
|
const value = getValueFromPointer(event.clientX);
|
|
onSlideStart == null ? void 0 : onSlideStart(value);
|
|
},
|
|
onSlideMove: (event) => {
|
|
const value = getValueFromPointer(event.clientX);
|
|
onSlideMove == null ? void 0 : onSlideMove(value);
|
|
},
|
|
onSlideEnd: () => {
|
|
rectRef.current = void 0;
|
|
onSlideEnd == null ? void 0 : onSlideEnd();
|
|
},
|
|
onStepKeyDown: (event) => {
|
|
const slideDirection = isSlidingFromLeft ? "from-left" : "from-right";
|
|
const isBackKey = BACK_KEYS[slideDirection].includes(event.key);
|
|
onStepKeyDown == null ? void 0 : onStepKeyDown({ event, direction: isBackKey ? -1 : 1 });
|
|
}
|
|
}
|
|
)
|
|
}
|
|
);
|
|
}
|
|
);
|
|
var SliderVertical = React31.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const {
|
|
min,
|
|
max,
|
|
inverted,
|
|
onSlideStart,
|
|
onSlideMove,
|
|
onSlideEnd,
|
|
onStepKeyDown,
|
|
...sliderProps
|
|
} = props;
|
|
const sliderRef = React31.useRef(null);
|
|
const ref = useComposedRefs(forwardedRef, sliderRef);
|
|
const rectRef = React31.useRef(void 0);
|
|
const isSlidingFromBottom = !inverted;
|
|
function getValueFromPointer(pointerPosition) {
|
|
const rect = rectRef.current || sliderRef.current.getBoundingClientRect();
|
|
const input = [0, rect.height];
|
|
const output = isSlidingFromBottom ? [max, min] : [min, max];
|
|
const value = linearScale2(input, output);
|
|
rectRef.current = rect;
|
|
return value(pointerPosition - rect.top);
|
|
}
|
|
return (0, import_jsx_runtime29.jsx)(
|
|
SliderOrientationProvider,
|
|
{
|
|
scope: props.__scopeSlider,
|
|
startEdge: isSlidingFromBottom ? "bottom" : "top",
|
|
endEdge: isSlidingFromBottom ? "top" : "bottom",
|
|
size: "height",
|
|
direction: isSlidingFromBottom ? 1 : -1,
|
|
children: (0, import_jsx_runtime29.jsx)(
|
|
SliderImpl,
|
|
{
|
|
"data-orientation": "vertical",
|
|
...sliderProps,
|
|
ref,
|
|
style: {
|
|
...sliderProps.style,
|
|
["--radix-slider-thumb-transform"]: "translateY(50%)"
|
|
},
|
|
onSlideStart: (event) => {
|
|
const value = getValueFromPointer(event.clientY);
|
|
onSlideStart == null ? void 0 : onSlideStart(value);
|
|
},
|
|
onSlideMove: (event) => {
|
|
const value = getValueFromPointer(event.clientY);
|
|
onSlideMove == null ? void 0 : onSlideMove(value);
|
|
},
|
|
onSlideEnd: () => {
|
|
rectRef.current = void 0;
|
|
onSlideEnd == null ? void 0 : onSlideEnd();
|
|
},
|
|
onStepKeyDown: (event) => {
|
|
const slideDirection = isSlidingFromBottom ? "from-bottom" : "from-top";
|
|
const isBackKey = BACK_KEYS[slideDirection].includes(event.key);
|
|
onStepKeyDown == null ? void 0 : onStepKeyDown({ event, direction: isBackKey ? -1 : 1 });
|
|
}
|
|
}
|
|
)
|
|
}
|
|
);
|
|
}
|
|
);
|
|
var SliderImpl = React31.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const {
|
|
__scopeSlider,
|
|
onSlideStart,
|
|
onSlideMove,
|
|
onSlideEnd,
|
|
onHomeKeyDown,
|
|
onEndKeyDown,
|
|
onStepKeyDown,
|
|
...sliderProps
|
|
} = props;
|
|
const context = useSliderContext(SLIDER_NAME, __scopeSlider);
|
|
return (0, import_jsx_runtime29.jsx)(
|
|
Primitive.span,
|
|
{
|
|
...sliderProps,
|
|
ref: forwardedRef,
|
|
onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
|
|
if (event.key === "Home") {
|
|
onHomeKeyDown(event);
|
|
event.preventDefault();
|
|
} else if (event.key === "End") {
|
|
onEndKeyDown(event);
|
|
event.preventDefault();
|
|
} else if (PAGE_KEYS.concat(ARROW_KEYS3).includes(event.key)) {
|
|
onStepKeyDown(event);
|
|
event.preventDefault();
|
|
}
|
|
}),
|
|
onPointerDown: composeEventHandlers(props.onPointerDown, (event) => {
|
|
const target = event.target;
|
|
target.setPointerCapture(event.pointerId);
|
|
event.preventDefault();
|
|
if (context.thumbs.has(target)) {
|
|
target.focus();
|
|
} else {
|
|
onSlideStart(event);
|
|
}
|
|
}),
|
|
onPointerMove: composeEventHandlers(props.onPointerMove, (event) => {
|
|
const target = event.target;
|
|
if (target.hasPointerCapture(event.pointerId)) onSlideMove(event);
|
|
}),
|
|
onPointerUp: composeEventHandlers(props.onPointerUp, (event) => {
|
|
const target = event.target;
|
|
if (target.hasPointerCapture(event.pointerId)) {
|
|
target.releasePointerCapture(event.pointerId);
|
|
onSlideEnd(event);
|
|
}
|
|
})
|
|
}
|
|
);
|
|
}
|
|
);
|
|
var TRACK_NAME = "SliderTrack";
|
|
var SliderTrack = React31.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeSlider, ...trackProps } = props;
|
|
const context = useSliderContext(TRACK_NAME, __scopeSlider);
|
|
return (0, import_jsx_runtime29.jsx)(
|
|
Primitive.span,
|
|
{
|
|
"data-disabled": context.disabled ? "" : void 0,
|
|
"data-orientation": context.orientation,
|
|
...trackProps,
|
|
ref: forwardedRef
|
|
}
|
|
);
|
|
}
|
|
);
|
|
SliderTrack.displayName = TRACK_NAME;
|
|
var RANGE_NAME = "SliderRange";
|
|
var SliderRange = React31.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeSlider, ...rangeProps } = props;
|
|
const context = useSliderContext(RANGE_NAME, __scopeSlider);
|
|
const orientation = useSliderOrientationContext(RANGE_NAME, __scopeSlider);
|
|
const ref = React31.useRef(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, ref);
|
|
const valuesCount = context.values.length;
|
|
const percentages = context.values.map(
|
|
(value) => convertValueToPercentage(value, context.min, context.max)
|
|
);
|
|
const offsetStart = valuesCount > 1 ? Math.min(...percentages) : 0;
|
|
const offsetEnd = 100 - Math.max(...percentages);
|
|
return (0, import_jsx_runtime29.jsx)(
|
|
Primitive.span,
|
|
{
|
|
"data-orientation": context.orientation,
|
|
"data-disabled": context.disabled ? "" : void 0,
|
|
...rangeProps,
|
|
ref: composedRefs,
|
|
style: {
|
|
...props.style,
|
|
[orientation.startEdge]: offsetStart + "%",
|
|
[orientation.endEdge]: offsetEnd + "%"
|
|
}
|
|
}
|
|
);
|
|
}
|
|
);
|
|
SliderRange.displayName = RANGE_NAME;
|
|
var THUMB_NAME2 = "SliderThumb";
|
|
var SliderThumb = React31.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const getItems = useCollection8(props.__scopeSlider);
|
|
const [thumb, setThumb] = React31.useState(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, (node) => setThumb(node));
|
|
const index = React31.useMemo(
|
|
() => thumb ? getItems().findIndex((item) => item.ref.current === thumb) : -1,
|
|
[getItems, thumb]
|
|
);
|
|
return (0, import_jsx_runtime29.jsx)(SliderThumbImpl, { ...props, ref: composedRefs, index });
|
|
}
|
|
);
|
|
var SliderThumbImpl = React31.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeSlider, index, name, ...thumbProps } = props;
|
|
const context = useSliderContext(THUMB_NAME2, __scopeSlider);
|
|
const orientation = useSliderOrientationContext(THUMB_NAME2, __scopeSlider);
|
|
const [thumb, setThumb] = React31.useState(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, (node) => setThumb(node));
|
|
const isFormControl2 = thumb ? context.form || !!thumb.closest("form") : true;
|
|
const size = useSize(thumb);
|
|
const value = context.values[index];
|
|
const percent = value === void 0 ? 0 : convertValueToPercentage(value, context.min, context.max);
|
|
const label = getLabel(index, context.values.length);
|
|
const orientationSize = size == null ? void 0 : size[orientation.size];
|
|
const thumbInBoundsOffset = orientationSize ? getThumbInBoundsOffset(orientationSize, percent, orientation.direction) : 0;
|
|
React31.useEffect(() => {
|
|
if (thumb) {
|
|
context.thumbs.add(thumb);
|
|
return () => {
|
|
context.thumbs.delete(thumb);
|
|
};
|
|
}
|
|
}, [thumb, context.thumbs]);
|
|
return (0, import_jsx_runtime29.jsxs)(
|
|
"span",
|
|
{
|
|
style: {
|
|
transform: "var(--radix-slider-thumb-transform)",
|
|
position: "absolute",
|
|
[orientation.startEdge]: `calc(${percent}% + ${thumbInBoundsOffset}px)`
|
|
},
|
|
children: [
|
|
(0, import_jsx_runtime29.jsx)(Collection8.ItemSlot, { scope: props.__scopeSlider, children: (0, import_jsx_runtime29.jsx)(
|
|
Primitive.span,
|
|
{
|
|
role: "slider",
|
|
"aria-label": props["aria-label"] || label,
|
|
"aria-valuemin": context.min,
|
|
"aria-valuenow": value,
|
|
"aria-valuemax": context.max,
|
|
"aria-orientation": context.orientation,
|
|
"data-orientation": context.orientation,
|
|
"data-disabled": context.disabled ? "" : void 0,
|
|
tabIndex: context.disabled ? void 0 : 0,
|
|
...thumbProps,
|
|
ref: composedRefs,
|
|
style: value === void 0 ? { display: "none" } : props.style,
|
|
onFocus: composeEventHandlers(props.onFocus, () => {
|
|
context.valueIndexToChangeRef.current = index;
|
|
})
|
|
}
|
|
) }),
|
|
isFormControl2 && (0, import_jsx_runtime29.jsx)(
|
|
SliderBubbleInput,
|
|
{
|
|
name: name ?? (context.name ? context.name + (context.values.length > 1 ? "[]" : "") : void 0),
|
|
form: context.form,
|
|
value
|
|
},
|
|
index
|
|
)
|
|
]
|
|
}
|
|
);
|
|
}
|
|
);
|
|
SliderThumb.displayName = THUMB_NAME2;
|
|
var BUBBLE_INPUT_NAME4 = "RadioBubbleInput";
|
|
var SliderBubbleInput = React31.forwardRef(
|
|
({ __scopeSlider, value, ...props }, forwardedRef) => {
|
|
const ref = React31.useRef(null);
|
|
const composedRefs = useComposedRefs(ref, forwardedRef);
|
|
const prevValue = usePrevious(value);
|
|
React31.useEffect(() => {
|
|
const input = ref.current;
|
|
if (!input) return;
|
|
const inputProto = window.HTMLInputElement.prototype;
|
|
const descriptor = Object.getOwnPropertyDescriptor(inputProto, "value");
|
|
const setValue = descriptor.set;
|
|
if (prevValue !== value && setValue) {
|
|
const event = new Event("input", { bubbles: true });
|
|
setValue.call(input, value);
|
|
input.dispatchEvent(event);
|
|
}
|
|
}, [prevValue, value]);
|
|
return (0, import_jsx_runtime29.jsx)(
|
|
Primitive.input,
|
|
{
|
|
style: { display: "none" },
|
|
...props,
|
|
ref: composedRefs,
|
|
defaultValue: value
|
|
}
|
|
);
|
|
}
|
|
);
|
|
SliderBubbleInput.displayName = BUBBLE_INPUT_NAME4;
|
|
function getNextSortedValues(prevValues = [], nextValue, atIndex) {
|
|
const nextValues = [...prevValues];
|
|
nextValues[atIndex] = nextValue;
|
|
return nextValues.sort((a, b) => a - b);
|
|
}
|
|
function convertValueToPercentage(value, min, max) {
|
|
const maxSteps = max - min;
|
|
const percentPerStep = 100 / maxSteps;
|
|
const percentage = percentPerStep * (value - min);
|
|
return clamp(percentage, [0, 100]);
|
|
}
|
|
function getLabel(index, totalValues) {
|
|
if (totalValues > 2) {
|
|
return `Value ${index + 1} of ${totalValues}`;
|
|
} else if (totalValues === 2) {
|
|
return ["Minimum", "Maximum"][index];
|
|
} else {
|
|
return void 0;
|
|
}
|
|
}
|
|
function getClosestValueIndex(values, nextValue) {
|
|
if (values.length === 1) return 0;
|
|
const distances = values.map((value) => Math.abs(value - nextValue));
|
|
const closestDistance = Math.min(...distances);
|
|
return distances.indexOf(closestDistance);
|
|
}
|
|
function getThumbInBoundsOffset(width, left, direction) {
|
|
const halfWidth = width / 2;
|
|
const halfPercent = 50;
|
|
const offset = linearScale2([0, halfPercent], [0, halfWidth]);
|
|
return (halfWidth - offset(left) * direction) * direction;
|
|
}
|
|
function getStepsBetweenValues(values) {
|
|
return values.slice(0, -1).map((value, index) => values[index + 1] - value);
|
|
}
|
|
function hasMinStepsBetweenValues(values, minStepsBetweenValues) {
|
|
if (minStepsBetweenValues > 0) {
|
|
const stepsBetweenValues = getStepsBetweenValues(values);
|
|
const actualMinStepsBetweenValues = Math.min(...stepsBetweenValues);
|
|
return actualMinStepsBetweenValues >= minStepsBetweenValues;
|
|
}
|
|
return true;
|
|
}
|
|
function linearScale2(input, output) {
|
|
return (value) => {
|
|
if (input[0] === input[1] || output[0] === output[1]) return output[0];
|
|
const ratio = (output[1] - output[0]) / (input[1] - input[0]);
|
|
return output[0] + ratio * (value - input[0]);
|
|
};
|
|
}
|
|
function getDecimalCount(value) {
|
|
return (String(value).split(".")[1] || "").length;
|
|
}
|
|
function roundValue(value, decimalCount) {
|
|
const rounder = Math.pow(10, decimalCount);
|
|
return Math.round(value * rounder) / rounder;
|
|
}
|
|
var Root14 = Slider;
|
|
var Track = SliderTrack;
|
|
var Range = SliderRange;
|
|
var Thumb2 = SliderThumb;
|
|
|
|
// ../../node_modules/@radix-ui/react-switch/dist/index.mjs
|
|
var dist_exports33 = {};
|
|
__export(dist_exports33, {
|
|
Root: () => Root15,
|
|
Switch: () => Switch,
|
|
SwitchThumb: () => SwitchThumb,
|
|
Thumb: () => Thumb3,
|
|
createSwitchScope: () => createSwitchScope
|
|
});
|
|
var React32 = __toESM(require_react(), 1);
|
|
var import_jsx_runtime30 = __toESM(require_jsx_runtime(), 1);
|
|
var SWITCH_NAME = "Switch";
|
|
var [createSwitchContext, createSwitchScope] = createContextScope(SWITCH_NAME);
|
|
var [SwitchProvider, useSwitchContext] = createSwitchContext(SWITCH_NAME);
|
|
var Switch = React32.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const {
|
|
__scopeSwitch,
|
|
name,
|
|
checked: checkedProp,
|
|
defaultChecked,
|
|
required,
|
|
disabled,
|
|
value = "on",
|
|
onCheckedChange,
|
|
form,
|
|
...switchProps
|
|
} = props;
|
|
const [button, setButton] = React32.useState(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, (node) => setButton(node));
|
|
const hasConsumerStoppedPropagationRef = React32.useRef(false);
|
|
const isFormControl2 = button ? form || !!button.closest("form") : true;
|
|
const [checked, setChecked] = useControllableState({
|
|
prop: checkedProp,
|
|
defaultProp: defaultChecked ?? false,
|
|
onChange: onCheckedChange,
|
|
caller: SWITCH_NAME
|
|
});
|
|
return (0, import_jsx_runtime30.jsxs)(SwitchProvider, { scope: __scopeSwitch, checked, disabled, children: [
|
|
(0, import_jsx_runtime30.jsx)(
|
|
Primitive.button,
|
|
{
|
|
type: "button",
|
|
role: "switch",
|
|
"aria-checked": checked,
|
|
"aria-required": required,
|
|
"data-state": getState5(checked),
|
|
"data-disabled": disabled ? "" : void 0,
|
|
disabled,
|
|
value,
|
|
...switchProps,
|
|
ref: composedRefs,
|
|
onClick: composeEventHandlers(props.onClick, (event) => {
|
|
setChecked((prevChecked) => !prevChecked);
|
|
if (isFormControl2) {
|
|
hasConsumerStoppedPropagationRef.current = event.isPropagationStopped();
|
|
if (!hasConsumerStoppedPropagationRef.current) event.stopPropagation();
|
|
}
|
|
})
|
|
}
|
|
),
|
|
isFormControl2 && (0, import_jsx_runtime30.jsx)(
|
|
SwitchBubbleInput,
|
|
{
|
|
control: button,
|
|
bubbles: !hasConsumerStoppedPropagationRef.current,
|
|
name,
|
|
value,
|
|
checked,
|
|
required,
|
|
disabled,
|
|
form,
|
|
style: { transform: "translateX(-100%)" }
|
|
}
|
|
)
|
|
] });
|
|
}
|
|
);
|
|
Switch.displayName = SWITCH_NAME;
|
|
var THUMB_NAME3 = "SwitchThumb";
|
|
var SwitchThumb = React32.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeSwitch, ...thumbProps } = props;
|
|
const context = useSwitchContext(THUMB_NAME3, __scopeSwitch);
|
|
return (0, import_jsx_runtime30.jsx)(
|
|
Primitive.span,
|
|
{
|
|
"data-state": getState5(context.checked),
|
|
"data-disabled": context.disabled ? "" : void 0,
|
|
...thumbProps,
|
|
ref: forwardedRef
|
|
}
|
|
);
|
|
}
|
|
);
|
|
SwitchThumb.displayName = THUMB_NAME3;
|
|
var BUBBLE_INPUT_NAME5 = "SwitchBubbleInput";
|
|
var SwitchBubbleInput = React32.forwardRef(
|
|
({
|
|
__scopeSwitch,
|
|
control,
|
|
checked,
|
|
bubbles = true,
|
|
...props
|
|
}, forwardedRef) => {
|
|
const ref = React32.useRef(null);
|
|
const composedRefs = useComposedRefs(ref, forwardedRef);
|
|
const prevChecked = usePrevious(checked);
|
|
const controlSize = useSize(control);
|
|
React32.useEffect(() => {
|
|
const input = ref.current;
|
|
if (!input) return;
|
|
const inputProto = window.HTMLInputElement.prototype;
|
|
const descriptor = Object.getOwnPropertyDescriptor(
|
|
inputProto,
|
|
"checked"
|
|
);
|
|
const setChecked = descriptor.set;
|
|
if (prevChecked !== checked && setChecked) {
|
|
const event = new Event("click", { bubbles });
|
|
setChecked.call(input, checked);
|
|
input.dispatchEvent(event);
|
|
}
|
|
}, [prevChecked, checked, bubbles]);
|
|
return (0, import_jsx_runtime30.jsx)(
|
|
"input",
|
|
{
|
|
type: "checkbox",
|
|
"aria-hidden": true,
|
|
defaultChecked: checked,
|
|
...props,
|
|
tabIndex: -1,
|
|
ref: composedRefs,
|
|
style: {
|
|
...props.style,
|
|
...controlSize,
|
|
position: "absolute",
|
|
pointerEvents: "none",
|
|
opacity: 0,
|
|
margin: 0
|
|
}
|
|
}
|
|
);
|
|
}
|
|
);
|
|
SwitchBubbleInput.displayName = BUBBLE_INPUT_NAME5;
|
|
function getState5(checked) {
|
|
return checked ? "checked" : "unchecked";
|
|
}
|
|
var Root15 = Switch;
|
|
var Thumb3 = SwitchThumb;
|
|
|
|
// ../../node_modules/@radix-ui/react-tabs/dist/index.mjs
|
|
var dist_exports34 = {};
|
|
__export(dist_exports34, {
|
|
Content: () => Content5,
|
|
List: () => List2,
|
|
Root: () => Root212,
|
|
Tabs: () => Tabs,
|
|
TabsContent: () => TabsContent,
|
|
TabsList: () => TabsList,
|
|
TabsTrigger: () => TabsTrigger,
|
|
Trigger: () => Trigger9,
|
|
createTabsScope: () => createTabsScope
|
|
});
|
|
var React33 = __toESM(require_react(), 1);
|
|
var import_jsx_runtime31 = __toESM(require_jsx_runtime(), 1);
|
|
var TABS_NAME = "Tabs";
|
|
var [createTabsContext, createTabsScope] = createContextScope(TABS_NAME, [
|
|
createRovingFocusGroupScope
|
|
]);
|
|
var useRovingFocusGroupScope5 = createRovingFocusGroupScope();
|
|
var [TabsProvider, useTabsContext] = createTabsContext(TABS_NAME);
|
|
var Tabs = React33.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const {
|
|
__scopeTabs,
|
|
value: valueProp,
|
|
onValueChange,
|
|
defaultValue,
|
|
orientation = "horizontal",
|
|
dir,
|
|
activationMode = "automatic",
|
|
...tabsProps
|
|
} = props;
|
|
const direction = useDirection(dir);
|
|
const [value, setValue] = useControllableState({
|
|
prop: valueProp,
|
|
onChange: onValueChange,
|
|
defaultProp: defaultValue ?? "",
|
|
caller: TABS_NAME
|
|
});
|
|
return (0, import_jsx_runtime31.jsx)(
|
|
TabsProvider,
|
|
{
|
|
scope: __scopeTabs,
|
|
baseId: useId(),
|
|
value,
|
|
onValueChange: setValue,
|
|
orientation,
|
|
dir: direction,
|
|
activationMode,
|
|
children: (0, import_jsx_runtime31.jsx)(
|
|
Primitive.div,
|
|
{
|
|
dir: direction,
|
|
"data-orientation": orientation,
|
|
...tabsProps,
|
|
ref: forwardedRef
|
|
}
|
|
)
|
|
}
|
|
);
|
|
}
|
|
);
|
|
Tabs.displayName = TABS_NAME;
|
|
var TAB_LIST_NAME = "TabsList";
|
|
var TabsList = React33.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeTabs, loop = true, ...listProps } = props;
|
|
const context = useTabsContext(TAB_LIST_NAME, __scopeTabs);
|
|
const rovingFocusGroupScope = useRovingFocusGroupScope5(__scopeTabs);
|
|
return (0, import_jsx_runtime31.jsx)(
|
|
Root8,
|
|
{
|
|
asChild: true,
|
|
...rovingFocusGroupScope,
|
|
orientation: context.orientation,
|
|
dir: context.dir,
|
|
loop,
|
|
children: (0, import_jsx_runtime31.jsx)(
|
|
Primitive.div,
|
|
{
|
|
role: "tablist",
|
|
"aria-orientation": context.orientation,
|
|
...listProps,
|
|
ref: forwardedRef
|
|
}
|
|
)
|
|
}
|
|
);
|
|
}
|
|
);
|
|
TabsList.displayName = TAB_LIST_NAME;
|
|
var TRIGGER_NAME11 = "TabsTrigger";
|
|
var TabsTrigger = React33.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeTabs, value, disabled = false, ...triggerProps } = props;
|
|
const context = useTabsContext(TRIGGER_NAME11, __scopeTabs);
|
|
const rovingFocusGroupScope = useRovingFocusGroupScope5(__scopeTabs);
|
|
const triggerId = makeTriggerId2(context.baseId, value);
|
|
const contentId = makeContentId2(context.baseId, value);
|
|
const isSelected = value === context.value;
|
|
return (0, import_jsx_runtime31.jsx)(
|
|
Item2,
|
|
{
|
|
asChild: true,
|
|
...rovingFocusGroupScope,
|
|
focusable: !disabled,
|
|
active: isSelected,
|
|
children: (0, import_jsx_runtime31.jsx)(
|
|
Primitive.button,
|
|
{
|
|
type: "button",
|
|
role: "tab",
|
|
"aria-selected": isSelected,
|
|
"aria-controls": contentId,
|
|
"data-state": isSelected ? "active" : "inactive",
|
|
"data-disabled": disabled ? "" : void 0,
|
|
disabled,
|
|
id: triggerId,
|
|
...triggerProps,
|
|
ref: forwardedRef,
|
|
onMouseDown: composeEventHandlers(props.onMouseDown, (event) => {
|
|
if (!disabled && event.button === 0 && event.ctrlKey === false) {
|
|
context.onValueChange(value);
|
|
} else {
|
|
event.preventDefault();
|
|
}
|
|
}),
|
|
onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
|
|
if ([" ", "Enter"].includes(event.key)) context.onValueChange(value);
|
|
}),
|
|
onFocus: composeEventHandlers(props.onFocus, () => {
|
|
const isAutomaticActivation = context.activationMode !== "manual";
|
|
if (!isSelected && !disabled && isAutomaticActivation) {
|
|
context.onValueChange(value);
|
|
}
|
|
})
|
|
}
|
|
)
|
|
}
|
|
);
|
|
}
|
|
);
|
|
TabsTrigger.displayName = TRIGGER_NAME11;
|
|
var CONTENT_NAME11 = "TabsContent";
|
|
var TabsContent = React33.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeTabs, value, forceMount, children, ...contentProps } = props;
|
|
const context = useTabsContext(CONTENT_NAME11, __scopeTabs);
|
|
const triggerId = makeTriggerId2(context.baseId, value);
|
|
const contentId = makeContentId2(context.baseId, value);
|
|
const isSelected = value === context.value;
|
|
const isMountAnimationPreventedRef = React33.useRef(isSelected);
|
|
React33.useEffect(() => {
|
|
const rAF = requestAnimationFrame(() => isMountAnimationPreventedRef.current = false);
|
|
return () => cancelAnimationFrame(rAF);
|
|
}, []);
|
|
return (0, import_jsx_runtime31.jsx)(Presence, { present: forceMount || isSelected, children: ({ present }) => (0, import_jsx_runtime31.jsx)(
|
|
Primitive.div,
|
|
{
|
|
"data-state": isSelected ? "active" : "inactive",
|
|
"data-orientation": context.orientation,
|
|
role: "tabpanel",
|
|
"aria-labelledby": triggerId,
|
|
hidden: !present,
|
|
id: contentId,
|
|
tabIndex: 0,
|
|
...contentProps,
|
|
ref: forwardedRef,
|
|
style: {
|
|
...props.style,
|
|
animationDuration: isMountAnimationPreventedRef.current ? "0s" : void 0
|
|
},
|
|
children: present && children
|
|
}
|
|
) });
|
|
}
|
|
);
|
|
TabsContent.displayName = CONTENT_NAME11;
|
|
function makeTriggerId2(baseId, value) {
|
|
return `${baseId}-trigger-${value}`;
|
|
}
|
|
function makeContentId2(baseId, value) {
|
|
return `${baseId}-content-${value}`;
|
|
}
|
|
var Root212 = Tabs;
|
|
var List2 = TabsList;
|
|
var Trigger9 = TabsTrigger;
|
|
var Content5 = TabsContent;
|
|
|
|
// ../../node_modules/@radix-ui/react-toast/dist/index.mjs
|
|
var dist_exports35 = {};
|
|
__export(dist_exports35, {
|
|
Action: () => Action2,
|
|
Close: () => Close2,
|
|
Description: () => Description3,
|
|
Provider: () => Provider2,
|
|
Root: () => Root213,
|
|
Title: () => Title3,
|
|
Toast: () => Toast,
|
|
ToastAction: () => ToastAction,
|
|
ToastClose: () => ToastClose,
|
|
ToastDescription: () => ToastDescription,
|
|
ToastProvider: () => ToastProvider,
|
|
ToastTitle: () => ToastTitle,
|
|
ToastViewport: () => ToastViewport,
|
|
Viewport: () => Viewport4,
|
|
createToastScope: () => createToastScope
|
|
});
|
|
var React34 = __toESM(require_react(), 1);
|
|
var ReactDOM3 = __toESM(require_react_dom(), 1);
|
|
var import_jsx_runtime32 = __toESM(require_jsx_runtime(), 1);
|
|
var PROVIDER_NAME = "ToastProvider";
|
|
var [Collection9, useCollection9, createCollectionScope9] = createCollection("Toast");
|
|
var [createToastContext, createToastScope] = createContextScope("Toast", [createCollectionScope9]);
|
|
var [ToastProviderProvider, useToastProviderContext] = createToastContext(PROVIDER_NAME);
|
|
var ToastProvider = (props) => {
|
|
const {
|
|
__scopeToast,
|
|
label = "Notification",
|
|
duration = 5e3,
|
|
swipeDirection = "right",
|
|
swipeThreshold = 50,
|
|
children
|
|
} = props;
|
|
const [viewport, setViewport] = React34.useState(null);
|
|
const [toastCount, setToastCount] = React34.useState(0);
|
|
const isFocusedToastEscapeKeyDownRef = React34.useRef(false);
|
|
const isClosePausedRef = React34.useRef(false);
|
|
if (!label.trim()) {
|
|
console.error(
|
|
`Invalid prop \`label\` supplied to \`${PROVIDER_NAME}\`. Expected non-empty \`string\`.`
|
|
);
|
|
}
|
|
return (0, import_jsx_runtime32.jsx)(Collection9.Provider, { scope: __scopeToast, children: (0, import_jsx_runtime32.jsx)(
|
|
ToastProviderProvider,
|
|
{
|
|
scope: __scopeToast,
|
|
label,
|
|
duration,
|
|
swipeDirection,
|
|
swipeThreshold,
|
|
toastCount,
|
|
viewport,
|
|
onViewportChange: setViewport,
|
|
onToastAdd: React34.useCallback(() => setToastCount((prevCount) => prevCount + 1), []),
|
|
onToastRemove: React34.useCallback(() => setToastCount((prevCount) => prevCount - 1), []),
|
|
isFocusedToastEscapeKeyDownRef,
|
|
isClosePausedRef,
|
|
children
|
|
}
|
|
) });
|
|
};
|
|
ToastProvider.displayName = PROVIDER_NAME;
|
|
var VIEWPORT_NAME4 = "ToastViewport";
|
|
var VIEWPORT_DEFAULT_HOTKEY = ["F8"];
|
|
var VIEWPORT_PAUSE = "toast.viewportPause";
|
|
var VIEWPORT_RESUME = "toast.viewportResume";
|
|
var ToastViewport = React34.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const {
|
|
__scopeToast,
|
|
hotkey = VIEWPORT_DEFAULT_HOTKEY,
|
|
label = "Notifications ({hotkey})",
|
|
...viewportProps
|
|
} = props;
|
|
const context = useToastProviderContext(VIEWPORT_NAME4, __scopeToast);
|
|
const getItems = useCollection9(__scopeToast);
|
|
const wrapperRef = React34.useRef(null);
|
|
const headFocusProxyRef = React34.useRef(null);
|
|
const tailFocusProxyRef = React34.useRef(null);
|
|
const ref = React34.useRef(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, ref, context.onViewportChange);
|
|
const hotkeyLabel = hotkey.join("+").replace(/Key/g, "").replace(/Digit/g, "");
|
|
const hasToasts = context.toastCount > 0;
|
|
React34.useEffect(() => {
|
|
const handleKeyDown = (event) => {
|
|
var _a2;
|
|
const isHotkeyPressed = hotkey.length !== 0 && hotkey.every((key) => event[key] || event.code === key);
|
|
if (isHotkeyPressed) (_a2 = ref.current) == null ? void 0 : _a2.focus();
|
|
};
|
|
document.addEventListener("keydown", handleKeyDown);
|
|
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
}, [hotkey]);
|
|
React34.useEffect(() => {
|
|
const wrapper = wrapperRef.current;
|
|
const viewport = ref.current;
|
|
if (hasToasts && wrapper && viewport) {
|
|
const handlePause = () => {
|
|
if (!context.isClosePausedRef.current) {
|
|
const pauseEvent = new CustomEvent(VIEWPORT_PAUSE);
|
|
viewport.dispatchEvent(pauseEvent);
|
|
context.isClosePausedRef.current = true;
|
|
}
|
|
};
|
|
const handleResume = () => {
|
|
if (context.isClosePausedRef.current) {
|
|
const resumeEvent = new CustomEvent(VIEWPORT_RESUME);
|
|
viewport.dispatchEvent(resumeEvent);
|
|
context.isClosePausedRef.current = false;
|
|
}
|
|
};
|
|
const handleFocusOutResume = (event) => {
|
|
const isFocusMovingOutside = !wrapper.contains(event.relatedTarget);
|
|
if (isFocusMovingOutside) handleResume();
|
|
};
|
|
const handlePointerLeaveResume = () => {
|
|
const isFocusInside = wrapper.contains(document.activeElement);
|
|
if (!isFocusInside) handleResume();
|
|
};
|
|
wrapper.addEventListener("focusin", handlePause);
|
|
wrapper.addEventListener("focusout", handleFocusOutResume);
|
|
wrapper.addEventListener("pointermove", handlePause);
|
|
wrapper.addEventListener("pointerleave", handlePointerLeaveResume);
|
|
window.addEventListener("blur", handlePause);
|
|
window.addEventListener("focus", handleResume);
|
|
return () => {
|
|
wrapper.removeEventListener("focusin", handlePause);
|
|
wrapper.removeEventListener("focusout", handleFocusOutResume);
|
|
wrapper.removeEventListener("pointermove", handlePause);
|
|
wrapper.removeEventListener("pointerleave", handlePointerLeaveResume);
|
|
window.removeEventListener("blur", handlePause);
|
|
window.removeEventListener("focus", handleResume);
|
|
};
|
|
}
|
|
}, [hasToasts, context.isClosePausedRef]);
|
|
const getSortedTabbableCandidates = React34.useCallback(
|
|
({ tabbingDirection }) => {
|
|
const toastItems = getItems();
|
|
const tabbableCandidates = toastItems.map((toastItem) => {
|
|
const toastNode = toastItem.ref.current;
|
|
const toastTabbableCandidates = [toastNode, ...getTabbableCandidates2(toastNode)];
|
|
return tabbingDirection === "forwards" ? toastTabbableCandidates : toastTabbableCandidates.reverse();
|
|
});
|
|
return (tabbingDirection === "forwards" ? tabbableCandidates.reverse() : tabbableCandidates).flat();
|
|
},
|
|
[getItems]
|
|
);
|
|
React34.useEffect(() => {
|
|
const viewport = ref.current;
|
|
if (viewport) {
|
|
const handleKeyDown = (event) => {
|
|
var _a2, _b, _c;
|
|
const isMetaKey = event.altKey || event.ctrlKey || event.metaKey;
|
|
const isTabKey = event.key === "Tab" && !isMetaKey;
|
|
if (isTabKey) {
|
|
const focusedElement = document.activeElement;
|
|
const isTabbingBackwards = event.shiftKey;
|
|
const targetIsViewport = event.target === viewport;
|
|
if (targetIsViewport && isTabbingBackwards) {
|
|
(_a2 = headFocusProxyRef.current) == null ? void 0 : _a2.focus();
|
|
return;
|
|
}
|
|
const tabbingDirection = isTabbingBackwards ? "backwards" : "forwards";
|
|
const sortedCandidates = getSortedTabbableCandidates({ tabbingDirection });
|
|
const index = sortedCandidates.findIndex((candidate) => candidate === focusedElement);
|
|
if (focusFirst4(sortedCandidates.slice(index + 1))) {
|
|
event.preventDefault();
|
|
} else {
|
|
isTabbingBackwards ? (_b = headFocusProxyRef.current) == null ? void 0 : _b.focus() : (_c = tailFocusProxyRef.current) == null ? void 0 : _c.focus();
|
|
}
|
|
}
|
|
};
|
|
viewport.addEventListener("keydown", handleKeyDown);
|
|
return () => viewport.removeEventListener("keydown", handleKeyDown);
|
|
}
|
|
}, [getItems, getSortedTabbableCandidates]);
|
|
return (0, import_jsx_runtime32.jsxs)(
|
|
Branch,
|
|
{
|
|
ref: wrapperRef,
|
|
role: "region",
|
|
"aria-label": label.replace("{hotkey}", hotkeyLabel),
|
|
tabIndex: -1,
|
|
style: { pointerEvents: hasToasts ? void 0 : "none" },
|
|
children: [
|
|
hasToasts && (0, import_jsx_runtime32.jsx)(
|
|
FocusProxy,
|
|
{
|
|
ref: headFocusProxyRef,
|
|
onFocusFromOutsideViewport: () => {
|
|
const tabbableCandidates = getSortedTabbableCandidates({
|
|
tabbingDirection: "forwards"
|
|
});
|
|
focusFirst4(tabbableCandidates);
|
|
}
|
|
}
|
|
),
|
|
(0, import_jsx_runtime32.jsx)(Collection9.Slot, { scope: __scopeToast, children: (0, import_jsx_runtime32.jsx)(Primitive.ol, { tabIndex: -1, ...viewportProps, ref: composedRefs }) }),
|
|
hasToasts && (0, import_jsx_runtime32.jsx)(
|
|
FocusProxy,
|
|
{
|
|
ref: tailFocusProxyRef,
|
|
onFocusFromOutsideViewport: () => {
|
|
const tabbableCandidates = getSortedTabbableCandidates({
|
|
tabbingDirection: "backwards"
|
|
});
|
|
focusFirst4(tabbableCandidates);
|
|
}
|
|
}
|
|
)
|
|
]
|
|
}
|
|
);
|
|
}
|
|
);
|
|
ToastViewport.displayName = VIEWPORT_NAME4;
|
|
var FOCUS_PROXY_NAME = "ToastFocusProxy";
|
|
var FocusProxy = React34.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeToast, onFocusFromOutsideViewport, ...proxyProps } = props;
|
|
const context = useToastProviderContext(FOCUS_PROXY_NAME, __scopeToast);
|
|
return (0, import_jsx_runtime32.jsx)(
|
|
VisuallyHidden,
|
|
{
|
|
tabIndex: 0,
|
|
...proxyProps,
|
|
ref: forwardedRef,
|
|
style: { position: "fixed" },
|
|
onFocus: (event) => {
|
|
var _a2;
|
|
const prevFocusedElement = event.relatedTarget;
|
|
const isFocusFromOutsideViewport = !((_a2 = context.viewport) == null ? void 0 : _a2.contains(prevFocusedElement));
|
|
if (isFocusFromOutsideViewport) onFocusFromOutsideViewport();
|
|
}
|
|
}
|
|
);
|
|
}
|
|
);
|
|
FocusProxy.displayName = FOCUS_PROXY_NAME;
|
|
var TOAST_NAME = "Toast";
|
|
var TOAST_SWIPE_START = "toast.swipeStart";
|
|
var TOAST_SWIPE_MOVE = "toast.swipeMove";
|
|
var TOAST_SWIPE_CANCEL = "toast.swipeCancel";
|
|
var TOAST_SWIPE_END = "toast.swipeEnd";
|
|
var Toast = React34.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { forceMount, open: openProp, defaultOpen, onOpenChange, ...toastProps } = props;
|
|
const [open, setOpen] = useControllableState({
|
|
prop: openProp,
|
|
defaultProp: defaultOpen ?? true,
|
|
onChange: onOpenChange,
|
|
caller: TOAST_NAME
|
|
});
|
|
return (0, import_jsx_runtime32.jsx)(Presence, { present: forceMount || open, children: (0, import_jsx_runtime32.jsx)(
|
|
ToastImpl,
|
|
{
|
|
open,
|
|
...toastProps,
|
|
ref: forwardedRef,
|
|
onClose: () => setOpen(false),
|
|
onPause: useCallbackRef(props.onPause),
|
|
onResume: useCallbackRef(props.onResume),
|
|
onSwipeStart: composeEventHandlers(props.onSwipeStart, (event) => {
|
|
event.currentTarget.setAttribute("data-swipe", "start");
|
|
}),
|
|
onSwipeMove: composeEventHandlers(props.onSwipeMove, (event) => {
|
|
const { x, y } = event.detail.delta;
|
|
event.currentTarget.setAttribute("data-swipe", "move");
|
|
event.currentTarget.style.setProperty("--radix-toast-swipe-move-x", `${x}px`);
|
|
event.currentTarget.style.setProperty("--radix-toast-swipe-move-y", `${y}px`);
|
|
}),
|
|
onSwipeCancel: composeEventHandlers(props.onSwipeCancel, (event) => {
|
|
event.currentTarget.setAttribute("data-swipe", "cancel");
|
|
event.currentTarget.style.removeProperty("--radix-toast-swipe-move-x");
|
|
event.currentTarget.style.removeProperty("--radix-toast-swipe-move-y");
|
|
event.currentTarget.style.removeProperty("--radix-toast-swipe-end-x");
|
|
event.currentTarget.style.removeProperty("--radix-toast-swipe-end-y");
|
|
}),
|
|
onSwipeEnd: composeEventHandlers(props.onSwipeEnd, (event) => {
|
|
const { x, y } = event.detail.delta;
|
|
event.currentTarget.setAttribute("data-swipe", "end");
|
|
event.currentTarget.style.removeProperty("--radix-toast-swipe-move-x");
|
|
event.currentTarget.style.removeProperty("--radix-toast-swipe-move-y");
|
|
event.currentTarget.style.setProperty("--radix-toast-swipe-end-x", `${x}px`);
|
|
event.currentTarget.style.setProperty("--radix-toast-swipe-end-y", `${y}px`);
|
|
setOpen(false);
|
|
})
|
|
}
|
|
) });
|
|
}
|
|
);
|
|
Toast.displayName = TOAST_NAME;
|
|
var [ToastInteractiveProvider, useToastInteractiveContext] = createToastContext(TOAST_NAME, {
|
|
onClose() {
|
|
}
|
|
});
|
|
var ToastImpl = React34.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const {
|
|
__scopeToast,
|
|
type = "foreground",
|
|
duration: durationProp,
|
|
open,
|
|
onClose,
|
|
onEscapeKeyDown,
|
|
onPause,
|
|
onResume,
|
|
onSwipeStart,
|
|
onSwipeMove,
|
|
onSwipeCancel,
|
|
onSwipeEnd,
|
|
...toastProps
|
|
} = props;
|
|
const context = useToastProviderContext(TOAST_NAME, __scopeToast);
|
|
const [node, setNode] = React34.useState(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, (node2) => setNode(node2));
|
|
const pointerStartRef = React34.useRef(null);
|
|
const swipeDeltaRef = React34.useRef(null);
|
|
const duration = durationProp || context.duration;
|
|
const closeTimerStartTimeRef = React34.useRef(0);
|
|
const closeTimerRemainingTimeRef = React34.useRef(duration);
|
|
const closeTimerRef = React34.useRef(0);
|
|
const { onToastAdd, onToastRemove } = context;
|
|
const handleClose = useCallbackRef(() => {
|
|
var _a2;
|
|
const isFocusInToast = node == null ? void 0 : node.contains(document.activeElement);
|
|
if (isFocusInToast) (_a2 = context.viewport) == null ? void 0 : _a2.focus();
|
|
onClose();
|
|
});
|
|
const startTimer = React34.useCallback(
|
|
(duration2) => {
|
|
if (!duration2 || duration2 === Infinity) return;
|
|
window.clearTimeout(closeTimerRef.current);
|
|
closeTimerStartTimeRef.current = (/* @__PURE__ */ new Date()).getTime();
|
|
closeTimerRef.current = window.setTimeout(handleClose, duration2);
|
|
},
|
|
[handleClose]
|
|
);
|
|
React34.useEffect(() => {
|
|
const viewport = context.viewport;
|
|
if (viewport) {
|
|
const handleResume = () => {
|
|
startTimer(closeTimerRemainingTimeRef.current);
|
|
onResume == null ? void 0 : onResume();
|
|
};
|
|
const handlePause = () => {
|
|
const elapsedTime = (/* @__PURE__ */ new Date()).getTime() - closeTimerStartTimeRef.current;
|
|
closeTimerRemainingTimeRef.current = closeTimerRemainingTimeRef.current - elapsedTime;
|
|
window.clearTimeout(closeTimerRef.current);
|
|
onPause == null ? void 0 : onPause();
|
|
};
|
|
viewport.addEventListener(VIEWPORT_PAUSE, handlePause);
|
|
viewport.addEventListener(VIEWPORT_RESUME, handleResume);
|
|
return () => {
|
|
viewport.removeEventListener(VIEWPORT_PAUSE, handlePause);
|
|
viewport.removeEventListener(VIEWPORT_RESUME, handleResume);
|
|
};
|
|
}
|
|
}, [context.viewport, duration, onPause, onResume, startTimer]);
|
|
React34.useEffect(() => {
|
|
if (open && !context.isClosePausedRef.current) startTimer(duration);
|
|
}, [open, duration, context.isClosePausedRef, startTimer]);
|
|
React34.useEffect(() => {
|
|
onToastAdd();
|
|
return () => onToastRemove();
|
|
}, [onToastAdd, onToastRemove]);
|
|
const announceTextContent = React34.useMemo(() => {
|
|
return node ? getAnnounceTextContent(node) : null;
|
|
}, [node]);
|
|
if (!context.viewport) return null;
|
|
return (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
|
|
announceTextContent && (0, import_jsx_runtime32.jsx)(
|
|
ToastAnnounce,
|
|
{
|
|
__scopeToast,
|
|
role: "status",
|
|
"aria-live": type === "foreground" ? "assertive" : "polite",
|
|
children: announceTextContent
|
|
}
|
|
),
|
|
(0, import_jsx_runtime32.jsx)(ToastInteractiveProvider, { scope: __scopeToast, onClose: handleClose, children: ReactDOM3.createPortal(
|
|
(0, import_jsx_runtime32.jsx)(Collection9.ItemSlot, { scope: __scopeToast, children: (0, import_jsx_runtime32.jsx)(
|
|
Root2,
|
|
{
|
|
asChild: true,
|
|
onEscapeKeyDown: composeEventHandlers(onEscapeKeyDown, () => {
|
|
if (!context.isFocusedToastEscapeKeyDownRef.current) handleClose();
|
|
context.isFocusedToastEscapeKeyDownRef.current = false;
|
|
}),
|
|
children: (0, import_jsx_runtime32.jsx)(
|
|
Primitive.li,
|
|
{
|
|
tabIndex: 0,
|
|
"data-state": open ? "open" : "closed",
|
|
"data-swipe-direction": context.swipeDirection,
|
|
...toastProps,
|
|
ref: composedRefs,
|
|
style: { userSelect: "none", touchAction: "none", ...props.style },
|
|
onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
|
|
if (event.key !== "Escape") return;
|
|
onEscapeKeyDown == null ? void 0 : onEscapeKeyDown(event.nativeEvent);
|
|
if (!event.nativeEvent.defaultPrevented) {
|
|
context.isFocusedToastEscapeKeyDownRef.current = true;
|
|
handleClose();
|
|
}
|
|
}),
|
|
onPointerDown: composeEventHandlers(props.onPointerDown, (event) => {
|
|
if (event.button !== 0) return;
|
|
pointerStartRef.current = { x: event.clientX, y: event.clientY };
|
|
}),
|
|
onPointerMove: composeEventHandlers(props.onPointerMove, (event) => {
|
|
if (!pointerStartRef.current) return;
|
|
const x = event.clientX - pointerStartRef.current.x;
|
|
const y = event.clientY - pointerStartRef.current.y;
|
|
const hasSwipeMoveStarted = Boolean(swipeDeltaRef.current);
|
|
const isHorizontalSwipe = ["left", "right"].includes(context.swipeDirection);
|
|
const clamp2 = ["left", "up"].includes(context.swipeDirection) ? Math.min : Math.max;
|
|
const clampedX = isHorizontalSwipe ? clamp2(0, x) : 0;
|
|
const clampedY = !isHorizontalSwipe ? clamp2(0, y) : 0;
|
|
const moveStartBuffer = event.pointerType === "touch" ? 10 : 2;
|
|
const delta = { x: clampedX, y: clampedY };
|
|
const eventDetail = { originalEvent: event, delta };
|
|
if (hasSwipeMoveStarted) {
|
|
swipeDeltaRef.current = delta;
|
|
handleAndDispatchCustomEvent(TOAST_SWIPE_MOVE, onSwipeMove, eventDetail, {
|
|
discrete: false
|
|
});
|
|
} else if (isDeltaInDirection(delta, context.swipeDirection, moveStartBuffer)) {
|
|
swipeDeltaRef.current = delta;
|
|
handleAndDispatchCustomEvent(TOAST_SWIPE_START, onSwipeStart, eventDetail, {
|
|
discrete: false
|
|
});
|
|
event.target.setPointerCapture(event.pointerId);
|
|
} else if (Math.abs(x) > moveStartBuffer || Math.abs(y) > moveStartBuffer) {
|
|
pointerStartRef.current = null;
|
|
}
|
|
}),
|
|
onPointerUp: composeEventHandlers(props.onPointerUp, (event) => {
|
|
const delta = swipeDeltaRef.current;
|
|
const target = event.target;
|
|
if (target.hasPointerCapture(event.pointerId)) {
|
|
target.releasePointerCapture(event.pointerId);
|
|
}
|
|
swipeDeltaRef.current = null;
|
|
pointerStartRef.current = null;
|
|
if (delta) {
|
|
const toast = event.currentTarget;
|
|
const eventDetail = { originalEvent: event, delta };
|
|
if (isDeltaInDirection(delta, context.swipeDirection, context.swipeThreshold)) {
|
|
handleAndDispatchCustomEvent(TOAST_SWIPE_END, onSwipeEnd, eventDetail, {
|
|
discrete: true
|
|
});
|
|
} else {
|
|
handleAndDispatchCustomEvent(
|
|
TOAST_SWIPE_CANCEL,
|
|
onSwipeCancel,
|
|
eventDetail,
|
|
{
|
|
discrete: true
|
|
}
|
|
);
|
|
}
|
|
toast.addEventListener("click", (event2) => event2.preventDefault(), {
|
|
once: true
|
|
});
|
|
}
|
|
})
|
|
}
|
|
)
|
|
}
|
|
) }),
|
|
context.viewport
|
|
) })
|
|
] });
|
|
}
|
|
);
|
|
var ToastAnnounce = (props) => {
|
|
const { __scopeToast, children, ...announceProps } = props;
|
|
const context = useToastProviderContext(TOAST_NAME, __scopeToast);
|
|
const [renderAnnounceText, setRenderAnnounceText] = React34.useState(false);
|
|
const [isAnnounced, setIsAnnounced] = React34.useState(false);
|
|
useNextFrame(() => setRenderAnnounceText(true));
|
|
React34.useEffect(() => {
|
|
const timer = window.setTimeout(() => setIsAnnounced(true), 1e3);
|
|
return () => window.clearTimeout(timer);
|
|
}, []);
|
|
return isAnnounced ? null : (0, import_jsx_runtime32.jsx)(Portal, { asChild: true, children: (0, import_jsx_runtime32.jsx)(VisuallyHidden, { ...announceProps, children: renderAnnounceText && (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
|
|
context.label,
|
|
" ",
|
|
children
|
|
] }) }) });
|
|
};
|
|
var TITLE_NAME2 = "ToastTitle";
|
|
var ToastTitle = React34.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeToast, ...titleProps } = props;
|
|
return (0, import_jsx_runtime32.jsx)(Primitive.div, { ...titleProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
ToastTitle.displayName = TITLE_NAME2;
|
|
var DESCRIPTION_NAME2 = "ToastDescription";
|
|
var ToastDescription = React34.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeToast, ...descriptionProps } = props;
|
|
return (0, import_jsx_runtime32.jsx)(Primitive.div, { ...descriptionProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
ToastDescription.displayName = DESCRIPTION_NAME2;
|
|
var ACTION_NAME2 = "ToastAction";
|
|
var ToastAction = React34.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { altText, ...actionProps } = props;
|
|
if (!altText.trim()) {
|
|
console.error(
|
|
`Invalid prop \`altText\` supplied to \`${ACTION_NAME2}\`. Expected non-empty \`string\`.`
|
|
);
|
|
return null;
|
|
}
|
|
return (0, import_jsx_runtime32.jsx)(ToastAnnounceExclude, { altText, asChild: true, children: (0, import_jsx_runtime32.jsx)(ToastClose, { ...actionProps, ref: forwardedRef }) });
|
|
}
|
|
);
|
|
ToastAction.displayName = ACTION_NAME2;
|
|
var CLOSE_NAME = "ToastClose";
|
|
var ToastClose = React34.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeToast, ...closeProps } = props;
|
|
const interactiveContext = useToastInteractiveContext(CLOSE_NAME, __scopeToast);
|
|
return (0, import_jsx_runtime32.jsx)(ToastAnnounceExclude, { asChild: true, children: (0, import_jsx_runtime32.jsx)(
|
|
Primitive.button,
|
|
{
|
|
type: "button",
|
|
...closeProps,
|
|
ref: forwardedRef,
|
|
onClick: composeEventHandlers(props.onClick, interactiveContext.onClose)
|
|
}
|
|
) });
|
|
}
|
|
);
|
|
ToastClose.displayName = CLOSE_NAME;
|
|
var ToastAnnounceExclude = React34.forwardRef((props, forwardedRef) => {
|
|
const { __scopeToast, altText, ...announceExcludeProps } = props;
|
|
return (0, import_jsx_runtime32.jsx)(
|
|
Primitive.div,
|
|
{
|
|
"data-radix-toast-announce-exclude": "",
|
|
"data-radix-toast-announce-alt": altText || void 0,
|
|
...announceExcludeProps,
|
|
ref: forwardedRef
|
|
}
|
|
);
|
|
});
|
|
function getAnnounceTextContent(container) {
|
|
const textContent = [];
|
|
const childNodes = Array.from(container.childNodes);
|
|
childNodes.forEach((node) => {
|
|
if (node.nodeType === node.TEXT_NODE && node.textContent) textContent.push(node.textContent);
|
|
if (isHTMLElement2(node)) {
|
|
const isHidden = node.ariaHidden || node.hidden || node.style.display === "none";
|
|
const isExcluded = node.dataset.radixToastAnnounceExclude === "";
|
|
if (!isHidden) {
|
|
if (isExcluded) {
|
|
const altText = node.dataset.radixToastAnnounceAlt;
|
|
if (altText) textContent.push(altText);
|
|
} else {
|
|
textContent.push(...getAnnounceTextContent(node));
|
|
}
|
|
}
|
|
}
|
|
});
|
|
return textContent;
|
|
}
|
|
function handleAndDispatchCustomEvent(name, handler, detail, { discrete }) {
|
|
const currentTarget = detail.originalEvent.currentTarget;
|
|
const event = new CustomEvent(name, { bubbles: true, cancelable: true, detail });
|
|
if (handler) currentTarget.addEventListener(name, handler, { once: true });
|
|
if (discrete) {
|
|
dispatchDiscreteCustomEvent(currentTarget, event);
|
|
} else {
|
|
currentTarget.dispatchEvent(event);
|
|
}
|
|
}
|
|
var isDeltaInDirection = (delta, direction, threshold = 0) => {
|
|
const deltaX = Math.abs(delta.x);
|
|
const deltaY = Math.abs(delta.y);
|
|
const isDeltaX = deltaX > deltaY;
|
|
if (direction === "left" || direction === "right") {
|
|
return isDeltaX && deltaX > threshold;
|
|
} else {
|
|
return !isDeltaX && deltaY > threshold;
|
|
}
|
|
};
|
|
function useNextFrame(callback = () => {
|
|
}) {
|
|
const fn = useCallbackRef(callback);
|
|
useLayoutEffect2(() => {
|
|
let raf1 = 0;
|
|
let raf2 = 0;
|
|
raf1 = window.requestAnimationFrame(() => raf2 = window.requestAnimationFrame(fn));
|
|
return () => {
|
|
window.cancelAnimationFrame(raf1);
|
|
window.cancelAnimationFrame(raf2);
|
|
};
|
|
}, [fn]);
|
|
}
|
|
function isHTMLElement2(node) {
|
|
return node.nodeType === node.ELEMENT_NODE;
|
|
}
|
|
function getTabbableCandidates2(container) {
|
|
const nodes = [];
|
|
const walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT, {
|
|
acceptNode: (node) => {
|
|
const isHiddenInput = node.tagName === "INPUT" && node.type === "hidden";
|
|
if (node.disabled || node.hidden || isHiddenInput) return NodeFilter.FILTER_SKIP;
|
|
return node.tabIndex >= 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
|
|
}
|
|
});
|
|
while (walker.nextNode()) nodes.push(walker.currentNode);
|
|
return nodes;
|
|
}
|
|
function focusFirst4(candidates) {
|
|
const previouslyFocusedElement = document.activeElement;
|
|
return candidates.some((candidate) => {
|
|
if (candidate === previouslyFocusedElement) return true;
|
|
candidate.focus();
|
|
return document.activeElement !== previouslyFocusedElement;
|
|
});
|
|
}
|
|
var Provider2 = ToastProvider;
|
|
var Viewport4 = ToastViewport;
|
|
var Root213 = Toast;
|
|
var Title3 = ToastTitle;
|
|
var Description3 = ToastDescription;
|
|
var Action2 = ToastAction;
|
|
var Close2 = ToastClose;
|
|
|
|
// ../../node_modules/@radix-ui/react-toggle/dist/index.mjs
|
|
var dist_exports37 = {};
|
|
__export(dist_exports37, {
|
|
Root: () => Root16,
|
|
Toggle: () => Toggle
|
|
});
|
|
var React35 = __toESM(require_react(), 1);
|
|
var import_jsx_runtime33 = __toESM(require_jsx_runtime(), 1);
|
|
var NAME6 = "Toggle";
|
|
var Toggle = React35.forwardRef((props, forwardedRef) => {
|
|
const { pressed: pressedProp, defaultPressed, onPressedChange, ...buttonProps } = props;
|
|
const [pressed, setPressed] = useControllableState({
|
|
prop: pressedProp,
|
|
onChange: onPressedChange,
|
|
defaultProp: defaultPressed ?? false,
|
|
caller: NAME6
|
|
});
|
|
return (0, import_jsx_runtime33.jsx)(
|
|
Primitive.button,
|
|
{
|
|
type: "button",
|
|
"aria-pressed": pressed,
|
|
"data-state": pressed ? "on" : "off",
|
|
"data-disabled": props.disabled ? "" : void 0,
|
|
...buttonProps,
|
|
ref: forwardedRef,
|
|
onClick: composeEventHandlers(props.onClick, () => {
|
|
if (!props.disabled) {
|
|
setPressed(!pressed);
|
|
}
|
|
})
|
|
}
|
|
);
|
|
});
|
|
Toggle.displayName = NAME6;
|
|
var Root16 = Toggle;
|
|
|
|
// ../../node_modules/@radix-ui/react-toggle-group/dist/index.mjs
|
|
var dist_exports38 = {};
|
|
__export(dist_exports38, {
|
|
Item: () => Item26,
|
|
Root: () => Root214,
|
|
ToggleGroup: () => ToggleGroup,
|
|
ToggleGroupItem: () => ToggleGroupItem,
|
|
createToggleGroupScope: () => createToggleGroupScope
|
|
});
|
|
var import_react4 = __toESM(require_react(), 1);
|
|
var import_jsx_runtime34 = __toESM(require_jsx_runtime(), 1);
|
|
var TOGGLE_GROUP_NAME = "ToggleGroup";
|
|
var [createToggleGroupContext, createToggleGroupScope] = createContextScope(TOGGLE_GROUP_NAME, [
|
|
createRovingFocusGroupScope
|
|
]);
|
|
var useRovingFocusGroupScope6 = createRovingFocusGroupScope();
|
|
var ToggleGroup = import_react4.default.forwardRef((props, forwardedRef) => {
|
|
const { type, ...toggleGroupProps } = props;
|
|
if (type === "single") {
|
|
const singleProps = toggleGroupProps;
|
|
return (0, import_jsx_runtime34.jsx)(ToggleGroupImplSingle, { ...singleProps, ref: forwardedRef });
|
|
}
|
|
if (type === "multiple") {
|
|
const multipleProps = toggleGroupProps;
|
|
return (0, import_jsx_runtime34.jsx)(ToggleGroupImplMultiple, { ...multipleProps, ref: forwardedRef });
|
|
}
|
|
throw new Error(`Missing prop \`type\` expected on \`${TOGGLE_GROUP_NAME}\``);
|
|
});
|
|
ToggleGroup.displayName = TOGGLE_GROUP_NAME;
|
|
var [ToggleGroupValueProvider, useToggleGroupValueContext] = createToggleGroupContext(TOGGLE_GROUP_NAME);
|
|
var ToggleGroupImplSingle = import_react4.default.forwardRef((props, forwardedRef) => {
|
|
const {
|
|
value: valueProp,
|
|
defaultValue,
|
|
onValueChange = () => {
|
|
},
|
|
...toggleGroupSingleProps
|
|
} = props;
|
|
const [value, setValue] = useControllableState({
|
|
prop: valueProp,
|
|
defaultProp: defaultValue ?? "",
|
|
onChange: onValueChange,
|
|
caller: TOGGLE_GROUP_NAME
|
|
});
|
|
return (0, import_jsx_runtime34.jsx)(
|
|
ToggleGroupValueProvider,
|
|
{
|
|
scope: props.__scopeToggleGroup,
|
|
type: "single",
|
|
value: import_react4.default.useMemo(() => value ? [value] : [], [value]),
|
|
onItemActivate: setValue,
|
|
onItemDeactivate: import_react4.default.useCallback(() => setValue(""), [setValue]),
|
|
children: (0, import_jsx_runtime34.jsx)(ToggleGroupImpl, { ...toggleGroupSingleProps, ref: forwardedRef })
|
|
}
|
|
);
|
|
});
|
|
var ToggleGroupImplMultiple = import_react4.default.forwardRef((props, forwardedRef) => {
|
|
const {
|
|
value: valueProp,
|
|
defaultValue,
|
|
onValueChange = () => {
|
|
},
|
|
...toggleGroupMultipleProps
|
|
} = props;
|
|
const [value, setValue] = useControllableState({
|
|
prop: valueProp,
|
|
defaultProp: defaultValue ?? [],
|
|
onChange: onValueChange,
|
|
caller: TOGGLE_GROUP_NAME
|
|
});
|
|
const handleButtonActivate = import_react4.default.useCallback(
|
|
(itemValue) => setValue((prevValue = []) => [...prevValue, itemValue]),
|
|
[setValue]
|
|
);
|
|
const handleButtonDeactivate = import_react4.default.useCallback(
|
|
(itemValue) => setValue((prevValue = []) => prevValue.filter((value2) => value2 !== itemValue)),
|
|
[setValue]
|
|
);
|
|
return (0, import_jsx_runtime34.jsx)(
|
|
ToggleGroupValueProvider,
|
|
{
|
|
scope: props.__scopeToggleGroup,
|
|
type: "multiple",
|
|
value,
|
|
onItemActivate: handleButtonActivate,
|
|
onItemDeactivate: handleButtonDeactivate,
|
|
children: (0, import_jsx_runtime34.jsx)(ToggleGroupImpl, { ...toggleGroupMultipleProps, ref: forwardedRef })
|
|
}
|
|
);
|
|
});
|
|
ToggleGroup.displayName = TOGGLE_GROUP_NAME;
|
|
var [ToggleGroupContext, useToggleGroupContext] = createToggleGroupContext(TOGGLE_GROUP_NAME);
|
|
var ToggleGroupImpl = import_react4.default.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const {
|
|
__scopeToggleGroup,
|
|
disabled = false,
|
|
rovingFocus = true,
|
|
orientation,
|
|
dir,
|
|
loop = true,
|
|
...toggleGroupProps
|
|
} = props;
|
|
const rovingFocusGroupScope = useRovingFocusGroupScope6(__scopeToggleGroup);
|
|
const direction = useDirection(dir);
|
|
const commonProps = { role: "group", dir: direction, ...toggleGroupProps };
|
|
return (0, import_jsx_runtime34.jsx)(ToggleGroupContext, { scope: __scopeToggleGroup, rovingFocus, disabled, children: rovingFocus ? (0, import_jsx_runtime34.jsx)(
|
|
Root8,
|
|
{
|
|
asChild: true,
|
|
...rovingFocusGroupScope,
|
|
orientation,
|
|
dir: direction,
|
|
loop,
|
|
children: (0, import_jsx_runtime34.jsx)(Primitive.div, { ...commonProps, ref: forwardedRef })
|
|
}
|
|
) : (0, import_jsx_runtime34.jsx)(Primitive.div, { ...commonProps, ref: forwardedRef }) });
|
|
}
|
|
);
|
|
var ITEM_NAME10 = "ToggleGroupItem";
|
|
var ToggleGroupItem = import_react4.default.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const valueContext = useToggleGroupValueContext(ITEM_NAME10, props.__scopeToggleGroup);
|
|
const context = useToggleGroupContext(ITEM_NAME10, props.__scopeToggleGroup);
|
|
const rovingFocusGroupScope = useRovingFocusGroupScope6(props.__scopeToggleGroup);
|
|
const pressed = valueContext.value.includes(props.value);
|
|
const disabled = context.disabled || props.disabled;
|
|
const commonProps = { ...props, pressed, disabled };
|
|
const ref = import_react4.default.useRef(null);
|
|
return context.rovingFocus ? (0, import_jsx_runtime34.jsx)(
|
|
Item2,
|
|
{
|
|
asChild: true,
|
|
...rovingFocusGroupScope,
|
|
focusable: !disabled,
|
|
active: pressed,
|
|
ref,
|
|
children: (0, import_jsx_runtime34.jsx)(ToggleGroupItemImpl, { ...commonProps, ref: forwardedRef })
|
|
}
|
|
) : (0, import_jsx_runtime34.jsx)(ToggleGroupItemImpl, { ...commonProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
ToggleGroupItem.displayName = ITEM_NAME10;
|
|
var ToggleGroupItemImpl = import_react4.default.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeToggleGroup, value, ...itemProps } = props;
|
|
const valueContext = useToggleGroupValueContext(ITEM_NAME10, __scopeToggleGroup);
|
|
const singleProps = { role: "radio", "aria-checked": props.pressed, "aria-pressed": void 0 };
|
|
const typeProps = valueContext.type === "single" ? singleProps : void 0;
|
|
return (0, import_jsx_runtime34.jsx)(
|
|
Toggle,
|
|
{
|
|
...typeProps,
|
|
...itemProps,
|
|
ref: forwardedRef,
|
|
onPressedChange: (pressed) => {
|
|
if (pressed) {
|
|
valueContext.onItemActivate(value);
|
|
} else {
|
|
valueContext.onItemDeactivate(value);
|
|
}
|
|
}
|
|
}
|
|
);
|
|
}
|
|
);
|
|
var Root214 = ToggleGroup;
|
|
var Item26 = ToggleGroupItem;
|
|
|
|
// ../../node_modules/@radix-ui/react-toolbar/dist/index.mjs
|
|
var dist_exports39 = {};
|
|
__export(dist_exports39, {
|
|
Button: () => Button,
|
|
Link: () => Link2,
|
|
Root: () => Root42,
|
|
Separator: () => Separator5,
|
|
ToggleGroup: () => ToggleGroup2,
|
|
ToggleItem: () => ToggleItem,
|
|
Toolbar: () => Toolbar,
|
|
ToolbarButton: () => ToolbarButton,
|
|
ToolbarLink: () => ToolbarLink,
|
|
ToolbarSeparator: () => ToolbarSeparator,
|
|
ToolbarToggleGroup: () => ToolbarToggleGroup,
|
|
ToolbarToggleItem: () => ToolbarToggleItem,
|
|
createToolbarScope: () => createToolbarScope
|
|
});
|
|
var React37 = __toESM(require_react(), 1);
|
|
var import_jsx_runtime35 = __toESM(require_jsx_runtime(), 1);
|
|
var TOOLBAR_NAME = "Toolbar";
|
|
var [createToolbarContext, createToolbarScope] = createContextScope(TOOLBAR_NAME, [
|
|
createRovingFocusGroupScope,
|
|
createToggleGroupScope
|
|
]);
|
|
var useRovingFocusGroupScope7 = createRovingFocusGroupScope();
|
|
var useToggleGroupScope = createToggleGroupScope();
|
|
var [ToolbarProvider, useToolbarContext] = createToolbarContext(TOOLBAR_NAME);
|
|
var Toolbar = React37.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeToolbar, orientation = "horizontal", dir, loop = true, ...toolbarProps } = props;
|
|
const rovingFocusGroupScope = useRovingFocusGroupScope7(__scopeToolbar);
|
|
const direction = useDirection(dir);
|
|
return (0, import_jsx_runtime35.jsx)(ToolbarProvider, { scope: __scopeToolbar, orientation, dir: direction, children: (0, import_jsx_runtime35.jsx)(
|
|
Root8,
|
|
{
|
|
asChild: true,
|
|
...rovingFocusGroupScope,
|
|
orientation,
|
|
dir: direction,
|
|
loop,
|
|
children: (0, import_jsx_runtime35.jsx)(
|
|
Primitive.div,
|
|
{
|
|
role: "toolbar",
|
|
"aria-orientation": orientation,
|
|
dir: direction,
|
|
...toolbarProps,
|
|
ref: forwardedRef
|
|
}
|
|
)
|
|
}
|
|
) });
|
|
}
|
|
);
|
|
Toolbar.displayName = TOOLBAR_NAME;
|
|
var SEPARATOR_NAME6 = "ToolbarSeparator";
|
|
var ToolbarSeparator = React37.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeToolbar, ...separatorProps } = props;
|
|
const context = useToolbarContext(SEPARATOR_NAME6, __scopeToolbar);
|
|
return (0, import_jsx_runtime35.jsx)(
|
|
Root13,
|
|
{
|
|
orientation: context.orientation === "horizontal" ? "vertical" : "horizontal",
|
|
...separatorProps,
|
|
ref: forwardedRef
|
|
}
|
|
);
|
|
}
|
|
);
|
|
ToolbarSeparator.displayName = SEPARATOR_NAME6;
|
|
var BUTTON_NAME = "ToolbarButton";
|
|
var ToolbarButton = React37.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeToolbar, ...buttonProps } = props;
|
|
const rovingFocusGroupScope = useRovingFocusGroupScope7(__scopeToolbar);
|
|
return (0, import_jsx_runtime35.jsx)(Item2, { asChild: true, ...rovingFocusGroupScope, focusable: !props.disabled, children: (0, import_jsx_runtime35.jsx)(Primitive.button, { type: "button", ...buttonProps, ref: forwardedRef }) });
|
|
}
|
|
);
|
|
ToolbarButton.displayName = BUTTON_NAME;
|
|
var LINK_NAME2 = "ToolbarLink";
|
|
var ToolbarLink = React37.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeToolbar, ...linkProps } = props;
|
|
const rovingFocusGroupScope = useRovingFocusGroupScope7(__scopeToolbar);
|
|
return (0, import_jsx_runtime35.jsx)(Item2, { asChild: true, ...rovingFocusGroupScope, focusable: true, children: (0, import_jsx_runtime35.jsx)(
|
|
Primitive.a,
|
|
{
|
|
...linkProps,
|
|
ref: forwardedRef,
|
|
onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
|
|
if (event.key === " ") event.currentTarget.click();
|
|
})
|
|
}
|
|
) });
|
|
}
|
|
);
|
|
ToolbarLink.displayName = LINK_NAME2;
|
|
var TOGGLE_GROUP_NAME2 = "ToolbarToggleGroup";
|
|
var ToolbarToggleGroup = React37.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeToolbar, ...toggleGroupProps } = props;
|
|
const context = useToolbarContext(TOGGLE_GROUP_NAME2, __scopeToolbar);
|
|
const toggleGroupScope = useToggleGroupScope(__scopeToolbar);
|
|
return (0, import_jsx_runtime35.jsx)(
|
|
Root214,
|
|
{
|
|
"data-orientation": context.orientation,
|
|
dir: context.dir,
|
|
...toggleGroupScope,
|
|
...toggleGroupProps,
|
|
ref: forwardedRef,
|
|
rovingFocus: false
|
|
}
|
|
);
|
|
}
|
|
);
|
|
ToolbarToggleGroup.displayName = TOGGLE_GROUP_NAME2;
|
|
var TOGGLE_ITEM_NAME = "ToolbarToggleItem";
|
|
var ToolbarToggleItem = React37.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeToolbar, ...toggleItemProps } = props;
|
|
const toggleGroupScope = useToggleGroupScope(__scopeToolbar);
|
|
const scope = { __scopeToolbar: props.__scopeToolbar };
|
|
return (0, import_jsx_runtime35.jsx)(ToolbarButton, { asChild: true, ...scope, children: (0, import_jsx_runtime35.jsx)(Item26, { ...toggleGroupScope, ...toggleItemProps, ref: forwardedRef }) });
|
|
}
|
|
);
|
|
ToolbarToggleItem.displayName = TOGGLE_ITEM_NAME;
|
|
var Root42 = Toolbar;
|
|
var Separator5 = ToolbarSeparator;
|
|
var Button = ToolbarButton;
|
|
var Link2 = ToolbarLink;
|
|
var ToggleGroup2 = ToolbarToggleGroup;
|
|
var ToggleItem = ToolbarToggleItem;
|
|
|
|
// ../../node_modules/@radix-ui/react-tooltip/dist/index.mjs
|
|
var dist_exports40 = {};
|
|
__export(dist_exports40, {
|
|
Arrow: () => Arrow27,
|
|
Content: () => Content210,
|
|
Portal: () => Portal6,
|
|
Provider: () => Provider3,
|
|
Root: () => Root34,
|
|
Tooltip: () => Tooltip,
|
|
TooltipArrow: () => TooltipArrow,
|
|
TooltipContent: () => TooltipContent,
|
|
TooltipPortal: () => TooltipPortal,
|
|
TooltipProvider: () => TooltipProvider,
|
|
TooltipTrigger: () => TooltipTrigger,
|
|
Trigger: () => Trigger10,
|
|
createTooltipScope: () => createTooltipScope
|
|
});
|
|
var React38 = __toESM(require_react(), 1);
|
|
var import_jsx_runtime36 = __toESM(require_jsx_runtime(), 1);
|
|
var [createTooltipContext, createTooltipScope] = createContextScope("Tooltip", [
|
|
createPopperScope
|
|
]);
|
|
var usePopperScope4 = createPopperScope();
|
|
var PROVIDER_NAME2 = "TooltipProvider";
|
|
var DEFAULT_DELAY_DURATION = 700;
|
|
var TOOLTIP_OPEN = "tooltip.open";
|
|
var [TooltipProviderContextProvider, useTooltipProviderContext] = createTooltipContext(PROVIDER_NAME2);
|
|
var TooltipProvider = (props) => {
|
|
const {
|
|
__scopeTooltip,
|
|
delayDuration = DEFAULT_DELAY_DURATION,
|
|
skipDelayDuration = 300,
|
|
disableHoverableContent = false,
|
|
children
|
|
} = props;
|
|
const isOpenDelayedRef = React38.useRef(true);
|
|
const isPointerInTransitRef = React38.useRef(false);
|
|
const skipDelayTimerRef = React38.useRef(0);
|
|
React38.useEffect(() => {
|
|
const skipDelayTimer = skipDelayTimerRef.current;
|
|
return () => window.clearTimeout(skipDelayTimer);
|
|
}, []);
|
|
return (0, import_jsx_runtime36.jsx)(
|
|
TooltipProviderContextProvider,
|
|
{
|
|
scope: __scopeTooltip,
|
|
isOpenDelayedRef,
|
|
delayDuration,
|
|
onOpen: React38.useCallback(() => {
|
|
window.clearTimeout(skipDelayTimerRef.current);
|
|
isOpenDelayedRef.current = false;
|
|
}, []),
|
|
onClose: React38.useCallback(() => {
|
|
window.clearTimeout(skipDelayTimerRef.current);
|
|
skipDelayTimerRef.current = window.setTimeout(
|
|
() => isOpenDelayedRef.current = true,
|
|
skipDelayDuration
|
|
);
|
|
}, [skipDelayDuration]),
|
|
isPointerInTransitRef,
|
|
onPointerInTransitChange: React38.useCallback((inTransit) => {
|
|
isPointerInTransitRef.current = inTransit;
|
|
}, []),
|
|
disableHoverableContent,
|
|
children
|
|
}
|
|
);
|
|
};
|
|
TooltipProvider.displayName = PROVIDER_NAME2;
|
|
var TOOLTIP_NAME = "Tooltip";
|
|
var [TooltipContextProvider, useTooltipContext] = createTooltipContext(TOOLTIP_NAME);
|
|
var Tooltip = (props) => {
|
|
const {
|
|
__scopeTooltip,
|
|
children,
|
|
open: openProp,
|
|
defaultOpen,
|
|
onOpenChange,
|
|
disableHoverableContent: disableHoverableContentProp,
|
|
delayDuration: delayDurationProp
|
|
} = props;
|
|
const providerContext = useTooltipProviderContext(TOOLTIP_NAME, props.__scopeTooltip);
|
|
const popperScope = usePopperScope4(__scopeTooltip);
|
|
const [trigger, setTrigger] = React38.useState(null);
|
|
const contentId = useId();
|
|
const openTimerRef = React38.useRef(0);
|
|
const disableHoverableContent = disableHoverableContentProp ?? providerContext.disableHoverableContent;
|
|
const delayDuration = delayDurationProp ?? providerContext.delayDuration;
|
|
const wasOpenDelayedRef = React38.useRef(false);
|
|
const [open, setOpen] = useControllableState({
|
|
prop: openProp,
|
|
defaultProp: defaultOpen ?? false,
|
|
onChange: (open2) => {
|
|
if (open2) {
|
|
providerContext.onOpen();
|
|
document.dispatchEvent(new CustomEvent(TOOLTIP_OPEN));
|
|
} else {
|
|
providerContext.onClose();
|
|
}
|
|
onOpenChange == null ? void 0 : onOpenChange(open2);
|
|
},
|
|
caller: TOOLTIP_NAME
|
|
});
|
|
const stateAttribute = React38.useMemo(() => {
|
|
return open ? wasOpenDelayedRef.current ? "delayed-open" : "instant-open" : "closed";
|
|
}, [open]);
|
|
const handleOpen = React38.useCallback(() => {
|
|
window.clearTimeout(openTimerRef.current);
|
|
openTimerRef.current = 0;
|
|
wasOpenDelayedRef.current = false;
|
|
setOpen(true);
|
|
}, [setOpen]);
|
|
const handleClose = React38.useCallback(() => {
|
|
window.clearTimeout(openTimerRef.current);
|
|
openTimerRef.current = 0;
|
|
setOpen(false);
|
|
}, [setOpen]);
|
|
const handleDelayedOpen = React38.useCallback(() => {
|
|
window.clearTimeout(openTimerRef.current);
|
|
openTimerRef.current = window.setTimeout(() => {
|
|
wasOpenDelayedRef.current = true;
|
|
setOpen(true);
|
|
openTimerRef.current = 0;
|
|
}, delayDuration);
|
|
}, [delayDuration, setOpen]);
|
|
React38.useEffect(() => {
|
|
return () => {
|
|
if (openTimerRef.current) {
|
|
window.clearTimeout(openTimerRef.current);
|
|
openTimerRef.current = 0;
|
|
}
|
|
};
|
|
}, []);
|
|
return (0, import_jsx_runtime36.jsx)(Root22, { ...popperScope, children: (0, import_jsx_runtime36.jsx)(
|
|
TooltipContextProvider,
|
|
{
|
|
scope: __scopeTooltip,
|
|
contentId,
|
|
open,
|
|
stateAttribute,
|
|
trigger,
|
|
onTriggerChange: setTrigger,
|
|
onTriggerEnter: React38.useCallback(() => {
|
|
if (providerContext.isOpenDelayedRef.current) handleDelayedOpen();
|
|
else handleOpen();
|
|
}, [providerContext.isOpenDelayedRef, handleDelayedOpen, handleOpen]),
|
|
onTriggerLeave: React38.useCallback(() => {
|
|
if (disableHoverableContent) {
|
|
handleClose();
|
|
} else {
|
|
window.clearTimeout(openTimerRef.current);
|
|
openTimerRef.current = 0;
|
|
}
|
|
}, [handleClose, disableHoverableContent]),
|
|
onOpen: handleOpen,
|
|
onClose: handleClose,
|
|
disableHoverableContent,
|
|
children
|
|
}
|
|
) });
|
|
};
|
|
Tooltip.displayName = TOOLTIP_NAME;
|
|
var TRIGGER_NAME12 = "TooltipTrigger";
|
|
var TooltipTrigger = React38.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeTooltip, ...triggerProps } = props;
|
|
const context = useTooltipContext(TRIGGER_NAME12, __scopeTooltip);
|
|
const providerContext = useTooltipProviderContext(TRIGGER_NAME12, __scopeTooltip);
|
|
const popperScope = usePopperScope4(__scopeTooltip);
|
|
const ref = React38.useRef(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, ref, context.onTriggerChange);
|
|
const isPointerDownRef = React38.useRef(false);
|
|
const hasPointerMoveOpenedRef = React38.useRef(false);
|
|
const handlePointerUp = React38.useCallback(() => isPointerDownRef.current = false, []);
|
|
React38.useEffect(() => {
|
|
return () => document.removeEventListener("pointerup", handlePointerUp);
|
|
}, [handlePointerUp]);
|
|
return (0, import_jsx_runtime36.jsx)(Anchor, { asChild: true, ...popperScope, children: (0, import_jsx_runtime36.jsx)(
|
|
Primitive.button,
|
|
{
|
|
"aria-describedby": context.open ? context.contentId : void 0,
|
|
"data-state": context.stateAttribute,
|
|
...triggerProps,
|
|
ref: composedRefs,
|
|
onPointerMove: composeEventHandlers(props.onPointerMove, (event) => {
|
|
if (event.pointerType === "touch") return;
|
|
if (!hasPointerMoveOpenedRef.current && !providerContext.isPointerInTransitRef.current) {
|
|
context.onTriggerEnter();
|
|
hasPointerMoveOpenedRef.current = true;
|
|
}
|
|
}),
|
|
onPointerLeave: composeEventHandlers(props.onPointerLeave, () => {
|
|
context.onTriggerLeave();
|
|
hasPointerMoveOpenedRef.current = false;
|
|
}),
|
|
onPointerDown: composeEventHandlers(props.onPointerDown, () => {
|
|
if (context.open) {
|
|
context.onClose();
|
|
}
|
|
isPointerDownRef.current = true;
|
|
document.addEventListener("pointerup", handlePointerUp, { once: true });
|
|
}),
|
|
onFocus: composeEventHandlers(props.onFocus, () => {
|
|
if (!isPointerDownRef.current) context.onOpen();
|
|
}),
|
|
onBlur: composeEventHandlers(props.onBlur, context.onClose),
|
|
onClick: composeEventHandlers(props.onClick, context.onClose)
|
|
}
|
|
) });
|
|
}
|
|
);
|
|
TooltipTrigger.displayName = TRIGGER_NAME12;
|
|
var PORTAL_NAME8 = "TooltipPortal";
|
|
var [PortalProvider3, usePortalContext3] = createTooltipContext(PORTAL_NAME8, {
|
|
forceMount: void 0
|
|
});
|
|
var TooltipPortal = (props) => {
|
|
const { __scopeTooltip, forceMount, children, container } = props;
|
|
const context = useTooltipContext(PORTAL_NAME8, __scopeTooltip);
|
|
return (0, import_jsx_runtime36.jsx)(PortalProvider3, { scope: __scopeTooltip, forceMount, children: (0, import_jsx_runtime36.jsx)(Presence, { present: forceMount || context.open, children: (0, import_jsx_runtime36.jsx)(Portal, { asChild: true, container, children }) }) });
|
|
};
|
|
TooltipPortal.displayName = PORTAL_NAME8;
|
|
var CONTENT_NAME12 = "TooltipContent";
|
|
var TooltipContent = React38.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const portalContext = usePortalContext3(CONTENT_NAME12, props.__scopeTooltip);
|
|
const { forceMount = portalContext.forceMount, side = "top", ...contentProps } = props;
|
|
const context = useTooltipContext(CONTENT_NAME12, props.__scopeTooltip);
|
|
return (0, import_jsx_runtime36.jsx)(Presence, { present: forceMount || context.open, children: context.disableHoverableContent ? (0, import_jsx_runtime36.jsx)(TooltipContentImpl, { side, ...contentProps, ref: forwardedRef }) : (0, import_jsx_runtime36.jsx)(TooltipContentHoverable, { side, ...contentProps, ref: forwardedRef }) });
|
|
}
|
|
);
|
|
var TooltipContentHoverable = React38.forwardRef((props, forwardedRef) => {
|
|
const context = useTooltipContext(CONTENT_NAME12, props.__scopeTooltip);
|
|
const providerContext = useTooltipProviderContext(CONTENT_NAME12, props.__scopeTooltip);
|
|
const ref = React38.useRef(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, ref);
|
|
const [pointerGraceArea, setPointerGraceArea] = React38.useState(null);
|
|
const { trigger, onClose } = context;
|
|
const content = ref.current;
|
|
const { onPointerInTransitChange } = providerContext;
|
|
const handleRemoveGraceArea = React38.useCallback(() => {
|
|
setPointerGraceArea(null);
|
|
onPointerInTransitChange(false);
|
|
}, [onPointerInTransitChange]);
|
|
const handleCreateGraceArea = React38.useCallback(
|
|
(event, hoverTarget) => {
|
|
const currentTarget = event.currentTarget;
|
|
const exitPoint = { x: event.clientX, y: event.clientY };
|
|
const exitSide = getExitSideFromRect(exitPoint, currentTarget.getBoundingClientRect());
|
|
const paddedExitPoints = getPaddedExitPoints(exitPoint, exitSide);
|
|
const hoverTargetPoints = getPointsFromRect(hoverTarget.getBoundingClientRect());
|
|
const graceArea = getHull([...paddedExitPoints, ...hoverTargetPoints]);
|
|
setPointerGraceArea(graceArea);
|
|
onPointerInTransitChange(true);
|
|
},
|
|
[onPointerInTransitChange]
|
|
);
|
|
React38.useEffect(() => {
|
|
return () => handleRemoveGraceArea();
|
|
}, [handleRemoveGraceArea]);
|
|
React38.useEffect(() => {
|
|
if (trigger && content) {
|
|
const handleTriggerLeave = (event) => handleCreateGraceArea(event, content);
|
|
const handleContentLeave = (event) => handleCreateGraceArea(event, trigger);
|
|
trigger.addEventListener("pointerleave", handleTriggerLeave);
|
|
content.addEventListener("pointerleave", handleContentLeave);
|
|
return () => {
|
|
trigger.removeEventListener("pointerleave", handleTriggerLeave);
|
|
content.removeEventListener("pointerleave", handleContentLeave);
|
|
};
|
|
}
|
|
}, [trigger, content, handleCreateGraceArea, handleRemoveGraceArea]);
|
|
React38.useEffect(() => {
|
|
if (pointerGraceArea) {
|
|
const handleTrackPointerGrace = (event) => {
|
|
const target = event.target;
|
|
const pointerPosition = { x: event.clientX, y: event.clientY };
|
|
const hasEnteredTarget = (trigger == null ? void 0 : trigger.contains(target)) || (content == null ? void 0 : content.contains(target));
|
|
const isPointerOutsideGraceArea = !isPointInPolygon2(pointerPosition, pointerGraceArea);
|
|
if (hasEnteredTarget) {
|
|
handleRemoveGraceArea();
|
|
} else if (isPointerOutsideGraceArea) {
|
|
handleRemoveGraceArea();
|
|
onClose();
|
|
}
|
|
};
|
|
document.addEventListener("pointermove", handleTrackPointerGrace);
|
|
return () => document.removeEventListener("pointermove", handleTrackPointerGrace);
|
|
}
|
|
}, [trigger, content, pointerGraceArea, onClose, handleRemoveGraceArea]);
|
|
return (0, import_jsx_runtime36.jsx)(TooltipContentImpl, { ...props, ref: composedRefs });
|
|
});
|
|
var [VisuallyHiddenContentContextProvider, useVisuallyHiddenContentContext] = createTooltipContext(TOOLTIP_NAME, { isInside: false });
|
|
var Slottable2 = createSlottable("TooltipContent");
|
|
var TooltipContentImpl = React38.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const {
|
|
__scopeTooltip,
|
|
children,
|
|
"aria-label": ariaLabel,
|
|
onEscapeKeyDown,
|
|
onPointerDownOutside,
|
|
...contentProps
|
|
} = props;
|
|
const context = useTooltipContext(CONTENT_NAME12, __scopeTooltip);
|
|
const popperScope = usePopperScope4(__scopeTooltip);
|
|
const { onClose } = context;
|
|
React38.useEffect(() => {
|
|
document.addEventListener(TOOLTIP_OPEN, onClose);
|
|
return () => document.removeEventListener(TOOLTIP_OPEN, onClose);
|
|
}, [onClose]);
|
|
React38.useEffect(() => {
|
|
if (context.trigger) {
|
|
const handleScroll = (event) => {
|
|
const target = event.target;
|
|
if (target == null ? void 0 : target.contains(context.trigger)) onClose();
|
|
};
|
|
window.addEventListener("scroll", handleScroll, { capture: true });
|
|
return () => window.removeEventListener("scroll", handleScroll, { capture: true });
|
|
}
|
|
}, [context.trigger, onClose]);
|
|
return (0, import_jsx_runtime36.jsx)(
|
|
DismissableLayer,
|
|
{
|
|
asChild: true,
|
|
disableOutsidePointerEvents: false,
|
|
onEscapeKeyDown,
|
|
onPointerDownOutside,
|
|
onFocusOutside: (event) => event.preventDefault(),
|
|
onDismiss: onClose,
|
|
children: (0, import_jsx_runtime36.jsxs)(
|
|
Content,
|
|
{
|
|
"data-state": context.stateAttribute,
|
|
...popperScope,
|
|
...contentProps,
|
|
ref: forwardedRef,
|
|
style: {
|
|
...contentProps.style,
|
|
// re-namespace exposed content custom properties
|
|
...{
|
|
"--radix-tooltip-content-transform-origin": "var(--radix-popper-transform-origin)",
|
|
"--radix-tooltip-content-available-width": "var(--radix-popper-available-width)",
|
|
"--radix-tooltip-content-available-height": "var(--radix-popper-available-height)",
|
|
"--radix-tooltip-trigger-width": "var(--radix-popper-anchor-width)",
|
|
"--radix-tooltip-trigger-height": "var(--radix-popper-anchor-height)"
|
|
}
|
|
},
|
|
children: [
|
|
(0, import_jsx_runtime36.jsx)(Slottable2, { children }),
|
|
(0, import_jsx_runtime36.jsx)(VisuallyHiddenContentContextProvider, { scope: __scopeTooltip, isInside: true, children: (0, import_jsx_runtime36.jsx)(Root4, { id: context.contentId, role: "tooltip", children: ariaLabel || children }) })
|
|
]
|
|
}
|
|
)
|
|
}
|
|
);
|
|
}
|
|
);
|
|
TooltipContent.displayName = CONTENT_NAME12;
|
|
var ARROW_NAME7 = "TooltipArrow";
|
|
var TooltipArrow = React38.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeTooltip, ...arrowProps } = props;
|
|
const popperScope = usePopperScope4(__scopeTooltip);
|
|
const visuallyHiddenContentContext = useVisuallyHiddenContentContext(
|
|
ARROW_NAME7,
|
|
__scopeTooltip
|
|
);
|
|
return visuallyHiddenContentContext.isInside ? null : (0, import_jsx_runtime36.jsx)(Arrow, { ...popperScope, ...arrowProps, ref: forwardedRef });
|
|
}
|
|
);
|
|
TooltipArrow.displayName = ARROW_NAME7;
|
|
function getExitSideFromRect(point, rect) {
|
|
const top = Math.abs(rect.top - point.y);
|
|
const bottom = Math.abs(rect.bottom - point.y);
|
|
const right = Math.abs(rect.right - point.x);
|
|
const left = Math.abs(rect.left - point.x);
|
|
switch (Math.min(top, bottom, right, left)) {
|
|
case left:
|
|
return "left";
|
|
case right:
|
|
return "right";
|
|
case top:
|
|
return "top";
|
|
case bottom:
|
|
return "bottom";
|
|
default:
|
|
throw new Error("unreachable");
|
|
}
|
|
}
|
|
function getPaddedExitPoints(exitPoint, exitSide, padding = 5) {
|
|
const paddedExitPoints = [];
|
|
switch (exitSide) {
|
|
case "top":
|
|
paddedExitPoints.push(
|
|
{ x: exitPoint.x - padding, y: exitPoint.y + padding },
|
|
{ x: exitPoint.x + padding, y: exitPoint.y + padding }
|
|
);
|
|
break;
|
|
case "bottom":
|
|
paddedExitPoints.push(
|
|
{ x: exitPoint.x - padding, y: exitPoint.y - padding },
|
|
{ x: exitPoint.x + padding, y: exitPoint.y - padding }
|
|
);
|
|
break;
|
|
case "left":
|
|
paddedExitPoints.push(
|
|
{ x: exitPoint.x + padding, y: exitPoint.y - padding },
|
|
{ x: exitPoint.x + padding, y: exitPoint.y + padding }
|
|
);
|
|
break;
|
|
case "right":
|
|
paddedExitPoints.push(
|
|
{ x: exitPoint.x - padding, y: exitPoint.y - padding },
|
|
{ x: exitPoint.x - padding, y: exitPoint.y + padding }
|
|
);
|
|
break;
|
|
}
|
|
return paddedExitPoints;
|
|
}
|
|
function getPointsFromRect(rect) {
|
|
const { top, right, bottom, left } = rect;
|
|
return [
|
|
{ x: left, y: top },
|
|
{ x: right, y: top },
|
|
{ x: right, y: bottom },
|
|
{ x: left, y: bottom }
|
|
];
|
|
}
|
|
function isPointInPolygon2(point, polygon) {
|
|
const { x, y } = point;
|
|
let inside = false;
|
|
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
|
|
const ii = polygon[i];
|
|
const jj = polygon[j];
|
|
const xi = ii.x;
|
|
const yi = ii.y;
|
|
const xj = jj.x;
|
|
const yj = jj.y;
|
|
const intersect = yi > y !== yj > y && x < (xj - xi) * (y - yi) / (yj - yi) + xi;
|
|
if (intersect) inside = !inside;
|
|
}
|
|
return inside;
|
|
}
|
|
function getHull(points) {
|
|
const newPoints = points.slice();
|
|
newPoints.sort((a, b) => {
|
|
if (a.x < b.x) return -1;
|
|
else if (a.x > b.x) return 1;
|
|
else if (a.y < b.y) return -1;
|
|
else if (a.y > b.y) return 1;
|
|
else return 0;
|
|
});
|
|
return getHullPresorted(newPoints);
|
|
}
|
|
function getHullPresorted(points) {
|
|
if (points.length <= 1) return points.slice();
|
|
const upperHull = [];
|
|
for (let i = 0; i < points.length; i++) {
|
|
const p = points[i];
|
|
while (upperHull.length >= 2) {
|
|
const q = upperHull[upperHull.length - 1];
|
|
const r = upperHull[upperHull.length - 2];
|
|
if ((q.x - r.x) * (p.y - r.y) >= (q.y - r.y) * (p.x - r.x)) upperHull.pop();
|
|
else break;
|
|
}
|
|
upperHull.push(p);
|
|
}
|
|
upperHull.pop();
|
|
const lowerHull = [];
|
|
for (let i = points.length - 1; i >= 0; i--) {
|
|
const p = points[i];
|
|
while (lowerHull.length >= 2) {
|
|
const q = lowerHull[lowerHull.length - 1];
|
|
const r = lowerHull[lowerHull.length - 2];
|
|
if ((q.x - r.x) * (p.y - r.y) >= (q.y - r.y) * (p.x - r.x)) lowerHull.pop();
|
|
else break;
|
|
}
|
|
lowerHull.push(p);
|
|
}
|
|
lowerHull.pop();
|
|
if (upperHull.length === 1 && lowerHull.length === 1 && upperHull[0].x === lowerHull[0].x && upperHull[0].y === lowerHull[0].y) {
|
|
return upperHull;
|
|
} else {
|
|
return upperHull.concat(lowerHull);
|
|
}
|
|
}
|
|
var Provider3 = TooltipProvider;
|
|
var Root34 = Tooltip;
|
|
var Trigger10 = TooltipTrigger;
|
|
var Portal6 = TooltipPortal;
|
|
var Content210 = TooltipContent;
|
|
var Arrow27 = TooltipArrow;
|
|
export {
|
|
dist_exports6 as AccessibleIcon,
|
|
dist_exports9 as Accordion,
|
|
dist_exports10 as AlertDialog,
|
|
dist_exports11 as AspectRatio,
|
|
dist_exports12 as Avatar,
|
|
dist_exports13 as Checkbox,
|
|
dist_exports7 as Collapsible,
|
|
dist_exports16 as ContextMenu,
|
|
dist_exports4 as Dialog,
|
|
dist_exports8 as Direction,
|
|
dist_exports18 as DropdownMenu,
|
|
dist_exports20 as Form,
|
|
dist_exports21 as HoverCard,
|
|
dist_exports19 as Label,
|
|
dist_exports22 as Menubar,
|
|
dist_exports23 as NavigationMenu,
|
|
dist_exports3 as Popover,
|
|
dist_exports2 as Portal,
|
|
dist_exports27 as Progress,
|
|
dist_exports28 as RadioGroup,
|
|
dist_exports29 as ScrollArea,
|
|
dist_exports30 as Select,
|
|
dist_exports31 as Separator,
|
|
dist_exports32 as Slider,
|
|
dist_exports as Slot,
|
|
dist_exports33 as Switch,
|
|
dist_exports34 as Tabs,
|
|
dist_exports35 as Toast,
|
|
dist_exports37 as Toggle,
|
|
dist_exports38 as ToggleGroup,
|
|
dist_exports39 as Toolbar,
|
|
dist_exports40 as Tooltip,
|
|
dist_exports5 as VisuallyHidden,
|
|
dist_exports24 as unstable_OneTimePasswordField,
|
|
dist_exports26 as unstable_PasswordToggleField
|
|
};
|
|
//# sourceMappingURL=radix-ui.js.map
|