UNPKG

@navikt/ds-react

Version:

React components from the Norwegian Labour and Welfare Administration.

487 lines 29.1 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.MenuSubTrigger = exports.MenuSubContent = exports.MenuSub = exports.MenuRadioItem = exports.MenuRadioGroup = exports.MenuPortal = exports.MenuItemIndicator = exports.MenuItem = exports.MenuGroup = exports.MenuDivider = exports.MenuContent = exports.MenuCheckboxItem = exports.MenuAnchor = exports.Menu = void 0; const react_1 = __importStar(require("react")); const react_dom_1 = __importDefault(require("react-dom")); const portal_1 = require("../../portal"); const composeEventHandlers_1 = require("../../util/composeEventHandlers"); const create_context_1 = require("../../util/create-context"); const FocusBoundary_1 = require("../../util/focus-boundary/FocusBoundary"); const hooks_1 = require("../../util/hooks"); const useDescendant_1 = require("../../util/hooks/descendants/useDescendant"); const DismissableLayer_1 = require("../dismissablelayer/DismissableLayer"); const Floating_1 = require("../floating/Floating"); const RovingFocus_1 = require("./parts/RovingFocus"); const SlottedDivElement_1 = require("./parts/SlottedDivElement"); /* -------------------------------------------------------------------------- */ /* Constants */ /* -------------------------------------------------------------------------- */ const FIRST_KEYS = ["ArrowDown", "PageUp", "Home"]; const LAST_KEYS = ["ArrowUp", "PageDown", "End"]; const FIRST_LAST_KEYS = [...FIRST_KEYS, ...LAST_KEYS]; const [MenuDescendantsProvider, useMenuDescendantsContext, useMenuDescendants, useMenuDescendant,] = (0, useDescendant_1.createDescendantContext)(); const [MenuProvider, useMenuContext] = (0, create_context_1.createContext)({ providerName: "MenuProvider", hookName: "useMenuContext", }); const [MenuRootProvider, useMenuRootContext] = (0, create_context_1.createContext)({ providerName: "MenuRootProvider", hookName: "useMenuRootContext", }); const MenuRoot = ({ open = false, children, onOpenChange, modal = true, }) => { const [content, setContent] = (0, react_1.useState)(null); const isUsingKeyboardRef = (0, react_1.useRef)(false); const handleOpenChange = (0, hooks_1.useCallbackRef)(onOpenChange); (0, react_1.useEffect)(() => { const globalDocument = globalThis.document; // Capturephase ensures we set the boolean before any side effects execute // in response to the key or pointer event as they might depend on this value. const handlePointer = () => { isUsingKeyboardRef.current = false; }; const handleKeyDown = () => { isUsingKeyboardRef.current = true; globalDocument.addEventListener("pointerdown", handlePointer, { capture: true, once: true, }); globalDocument.addEventListener("pointermove", handlePointer, { capture: true, once: true, }); }; globalDocument.addEventListener("keydown", handleKeyDown, { capture: true, }); return () => { globalDocument.removeEventListener("keydown", handleKeyDown, { capture: true, }); globalDocument.removeEventListener("pointerdown", handlePointer, { capture: true, }); globalDocument.removeEventListener("pointermove", handlePointer, { capture: true, }); }; }, []); return (react_1.default.createElement(Floating_1.Floating, null, react_1.default.createElement(MenuProvider, { open: open, onOpenChange: handleOpenChange, content: content, onContentChange: setContent }, react_1.default.createElement(MenuRootProvider, { onClose: react_1.default.useCallback(() => handleOpenChange(false), [handleOpenChange]), isUsingKeyboardRef: isUsingKeyboardRef, modal: modal }, children)))); }; const Menu = MenuRoot; exports.Menu = Menu; const MenuAnchor = (0, react_1.forwardRef)((props, forwardedRef) => { return react_1.default.createElement(Floating_1.Floating.Anchor, Object.assign({}, props, { ref: forwardedRef })); }); exports.MenuAnchor = MenuAnchor; const MenuContent = react_1.default.forwardRef((props, ref) => { const descendants = useMenuDescendants(); const rootContext = useMenuRootContext(); return (react_1.default.createElement(MenuDescendantsProvider, { value: descendants }, rootContext.modal ? (react_1.default.createElement(MenuRootContentModal, Object.assign({}, props, { ref: ref }))) : (react_1.default.createElement(MenuRootContentNonModal, Object.assign({}, props, { ref: ref }))))); }); exports.MenuContent = MenuContent; /* ---------------------------- Non-modal content --------------------------- */ const MenuRootContentNonModal = react_1.default.forwardRef((props, ref) => { const context = useMenuContext(); return (react_1.default.createElement(MenuContentInternal, Object.assign({}, props, { ref: ref, disableOutsidePointerEvents: false, onDismiss: () => context.onOpenChange(false) }))); }); /* ------------------------------ Modal content ----------------------------- */ const MenuRootContentModal = (0, react_1.forwardRef)((props, ref) => { const context = useMenuContext(); return (react_1.default.createElement(MenuContentInternal, Object.assign({}, props, { ref: ref, // make sure to only disable pointer events when open // this avoids blocking interactions while animating out disableOutsidePointerEvents: context.open, // When focus is trapped, a `focusout` event may still happen. // We make sure we don't trigger our `onDismiss` in such case. onFocusOutside: (0, composeEventHandlers_1.composeEventHandlers)(props.onFocusOutside, (event) => event.preventDefault(), { checkForDefaultPrevented: false }), onDismiss: () => context.onOpenChange(false) }))); }); const MenuContentInternal = (0, react_1.forwardRef)((_a, forwardedRef) => { var { initialFocus, returnFocus, disableOutsidePointerEvents, onEntryFocus, onEscapeKeyDown, onPointerDownOutside, onFocusOutside, onInteractOutside, onDismiss, safeZone } = _a, rest = __rest(_a, ["initialFocus", "returnFocus", "disableOutsidePointerEvents", "onEntryFocus", "onEscapeKeyDown", "onPointerDownOutside", "onFocusOutside", "onInteractOutside", "onDismiss", "safeZone"]); const descendants = useMenuDescendantsContext(); const context = useMenuContext(); const rootContext = useMenuRootContext(); const contentRef = (0, react_1.useRef)(null); const composedRefs = (0, hooks_1.useMergeRefs)(forwardedRef, contentRef, context.onContentChange); return (react_1.default.createElement(FocusBoundary_1.FocusBoundary, { initialFocus: initialFocus !== null && initialFocus !== void 0 ? initialFocus : contentRef, returnFocus: returnFocus, /* Focus trapping is handled in `Floating.Content: onKeyDown */ trapped: false, loop: false }, react_1.default.createElement(DismissableLayer_1.DismissableLayer, { asChild: true, disableOutsidePointerEvents: disableOutsidePointerEvents, onEscapeKeyDown: onEscapeKeyDown, onPointerDownOutside: onPointerDownOutside, onFocusOutside: onFocusOutside, onInteractOutside: onInteractOutside, onDismiss: onDismiss, safeZone: safeZone }, react_1.default.createElement(RovingFocus_1.RovingFocus, { asChild: true, descendants: descendants, onEntryFocus: (0, composeEventHandlers_1.composeEventHandlers)(onEntryFocus, (event) => { // only focus first item when using keyboard if (!rootContext.isUsingKeyboardRef.current) { event.preventDefault(); } }) }, react_1.default.createElement(Floating_1.Floating.Content, Object.assign({ role: "menu", "aria-orientation": "vertical", "data-state": getOpenState(context.open), "data-aksel-menu-content": "", dir: "ltr" }, rest, { ref: composedRefs, style: Object.assign({ outline: "none" }, rest.style), onKeyDown: (0, composeEventHandlers_1.composeEventHandlers)(rest.onKeyDown, (event) => { var _a, _b, _c, _d; // submenu key events bubble through portals. We only care about keys in this menu. const target = event.target; const isKeyDownInside = target.closest("[data-aksel-menu-content]") === event.currentTarget; if (isKeyDownInside) { // menus should not be navigated using tab key so we prevent it if (event.key === "Tab") event.preventDefault(); } // focus first/last item based on key pressed const content = contentRef.current; if (event.target !== content) return; if (!FIRST_LAST_KEYS.includes(event.key)) return; event.preventDefault(); if (LAST_KEYS.includes(event.key)) { (_b = (_a = descendants.lastEnabled()) === null || _a === void 0 ? void 0 : _a.node) === null || _b === void 0 ? void 0 : _b.focus(); return; } (_d = (_c = descendants.firstEnabled()) === null || _c === void 0 ? void 0 : _c.node) === null || _d === void 0 ? void 0 : _d.focus(); }) })))))); }); /* -------------------------------------------------------------------------- */ /* Menu item */ /* -------------------------------------------------------------------------- */ const ITEM_SELECT_EVENT = "menu.itemSelect"; const MenuItem = (0, react_1.forwardRef)((_a, forwardedRef) => { var { disabled = false, onSelect, onClick, onPointerUp, onPointerDown, onKeyDown, onKeyUp } = _a, rest = __rest(_a, ["disabled", "onSelect", "onClick", "onPointerUp", "onPointerDown", "onKeyDown", "onKeyUp"]); const ref = (0, react_1.useRef)(null); const rootContext = useMenuRootContext(); const composedRefs = (0, hooks_1.useMergeRefs)(forwardedRef, ref); const isPointerDownRef = (0, react_1.useRef)(false); const handleSelect = () => { const menuItem = ref.current; if (!disabled && menuItem && onSelect) { const itemSelectEvent = new CustomEvent(ITEM_SELECT_EVENT, { bubbles: true, cancelable: true, }); menuItem.addEventListener(ITEM_SELECT_EVENT, onSelect, { once: true }); /** * We flush the event synchronously to ensure that the event is dispatched before other events react to side-effect from event. * This is necessary to prevent the menu from potentially closing before we are able to prevent it. */ react_dom_1.default.flushSync(() => menuItem.dispatchEvent(itemSelectEvent)); if (itemSelectEvent.defaultPrevented) { isPointerDownRef.current = false; } else { rootContext.onClose(); } } else if (!disabled && menuItem) { rootContext.onClose(); } }; const handleKey = (event, key) => { if (disabled || event.repeat) { return; } if (key === event.key) { event.currentTarget.click(); /** * We prevent default browser behaviour for selection keys as they should only trigger * selection. * - Prevents space from scrolling the page. * - If keydown causes focus to move, prevents keydown from firing on the new target. */ event.preventDefault(); } }; return (react_1.default.createElement(MenuItemInternal, Object.assign({}, rest, { tabIndex: disabled ? -1 : 0, ref: composedRefs, disabled: disabled, onClick: (0, composeEventHandlers_1.composeEventHandlers)(onClick, handleSelect, { /** * Nextjs prevents default on click when using Link component, so we have to force click-event * https://github.com/vercel/next.js/blob/77dcd4c66a35d0e8ef639bda4d05873bd3c0f52d/packages/next/src/client/link.tsx#L211 */ checkForDefaultPrevented: false, }), onPointerDown: (0, composeEventHandlers_1.composeEventHandlers)(onPointerDown, () => { isPointerDownRef.current = true; }, { checkForDefaultPrevented: false }), onPointerUp: (0, composeEventHandlers_1.composeEventHandlers)(onPointerUp, (event) => { var _a; // Pointer down can move to a different menu item which should activate it on pointer up. // We dispatch a click for selection to allow composition with click based triggers and to // prevent Firefox from getting stuck in text selection mode when the menu closes. if (!isPointerDownRef.current) (_a = event.currentTarget) === null || _a === void 0 ? void 0 : _a.click(); }), onKeyDown: (0, composeEventHandlers_1.composeEventHandlers)(onKeyDown, (event) => handleKey(event, "Enter")), onKeyUp: (0, composeEventHandlers_1.composeEventHandlers)(onKeyUp, (event) => handleKey(event, " ")) }))); }); exports.MenuItem = MenuItem; const MenuItemInternal = (0, react_1.forwardRef)((_a, forwardedRef) => { var { disabled = false, onPointerMove, onPointerLeave } = _a, rest = __rest(_a, ["disabled", "onPointerMove", "onPointerLeave"]); const context = useMenuContext(); const { register } = useMenuDescendant({ disabled, closeMenu: () => { rest["data-submenu-trigger"] && context.open && context.onOpenChange(false); }, }); const ref = (0, react_1.useRef)(null); const composedRefs = (0, hooks_1.useMergeRefs)(forwardedRef, ref, register); return (react_1.default.createElement(SlottedDivElement_1.SlottedDivElement, Object.assign({ role: "menuitem", "aria-disabled": disabled || undefined, "data-disabled": disabled ? "" : undefined, tabIndex: -1 }, rest, { style: Object.assign({ userSelect: "none" }, rest === null || rest === void 0 ? void 0 : rest.style), ref: composedRefs, /** * We focus items on `pointerMove` make sure that the item is focused or re-focused * when the mouse wiggles. If we used `mouseOver`/`mouseEnter` it would not re-focus. * This is mostly to handle edgecases where the user uses mouse and keyboard together. */ onPointerMove: (0, composeEventHandlers_1.composeEventHandlers)(onPointerMove, whenMouse((event) => { var _a; if (disabled) { /** * In the edgecase the focus is still stuck on a previous item, we make sure to reset it * even when the disabled item can't be focused itself to reset it. */ (_a = context.content) === null || _a === void 0 ? void 0 : _a.focus(); } else { event.currentTarget.focus(); } })), onPointerLeave: (0, composeEventHandlers_1.composeEventHandlers)(onPointerLeave, whenMouse(() => { var _a; return (_a = context.content) === null || _a === void 0 ? void 0 : _a.focus(); })) }))); }); const MenuGroup = (0, react_1.forwardRef)((props, ref) => { return react_1.default.createElement(SlottedDivElement_1.SlottedDivElement, Object.assign({ role: "group" }, props, { ref: ref })); }); exports.MenuGroup = MenuGroup; const MenuPortal = (0, react_1.forwardRef)(({ children, rootElement }, ref) => { const context = useMenuContext(); if (!context.open) { return null; } return (react_1.default.createElement(portal_1.Portal, { rootElement: rootElement, ref: ref }, children)); }); exports.MenuPortal = MenuPortal; /* -------------------------------------------------------------------------- */ /* Menu Radio */ /* -------------------------------------------------------------------------- */ const [RadioGroupProvider, useMenuRadioGroupContext] = (0, create_context_1.createContext)({ providerName: "MenuRadioGroupProvider", hookName: "useMenuRadioGroupContext", defaultValue: { value: undefined, onValueChange: () => { }, }, }); const MenuRadioGroup = react_1.default.forwardRef((_a, ref) => { var { value, onValueChange } = _a, rest = __rest(_a, ["value", "onValueChange"]); const handleValueChange = (0, hooks_1.useCallbackRef)(onValueChange); return (react_1.default.createElement(RadioGroupProvider, { value: value, onValueChange: handleValueChange }, react_1.default.createElement(MenuGroup, Object.assign({}, rest, { ref: ref })))); }); exports.MenuRadioGroup = MenuRadioGroup; /* -------------------------------------------------------------------------- */ /* Menu Item Indicator */ /* -------------------------------------------------------------------------- */ const [MenuItemIndicatorProvider, useMenuItemIndicatorContext] = (0, create_context_1.createContext)({ providerName: "MenuItemIndicatorProvider", hookName: "useMenuItemIndicatorContext", }); const MenuItemIndicator = (0, react_1.forwardRef)((_a, ref) => { var { asChild } = _a, rest = __rest(_a, ["asChild"]); const ctx = useMenuItemIndicatorContext(); return (react_1.default.createElement(SlottedDivElement_1.SlottedDivElement, Object.assign({}, rest, { ref: ref, "data-state": getCheckedState(ctx.state), "aria-hidden": true, asChild: asChild }))); }); exports.MenuItemIndicator = MenuItemIndicator; const MenuRadioItem = (0, react_1.forwardRef)((_a, forwardedRef) => { var { value, onSelect } = _a, rest = __rest(_a, ["value", "onSelect"]); const context = useMenuRadioGroupContext(); const checked = value === context.value; return (react_1.default.createElement(MenuItemIndicatorProvider, { state: checked }, react_1.default.createElement(MenuItem, Object.assign({ role: "menuitemradio", "aria-checked": checked }, rest, { ref: forwardedRef, "data-state": getCheckedState(checked), onSelect: (0, composeEventHandlers_1.composeEventHandlers)(onSelect, () => { var _a; return (_a = context.onValueChange) === null || _a === void 0 ? void 0 : _a.call(context, value); }, { checkForDefaultPrevented: false }) })))); }); exports.MenuRadioItem = MenuRadioItem; const MenuCheckboxItem = (0, react_1.forwardRef)((_a, forwardedRef) => { var { checked = false, onCheckedChange, onSelect } = _a, rest = __rest(_a, ["checked", "onCheckedChange", "onSelect"]); return (react_1.default.createElement(MenuItemIndicatorProvider, { state: checked }, react_1.default.createElement(MenuItem, Object.assign({ role: "menuitemcheckbox", "aria-checked": isIndeterminate(checked) ? "mixed" : checked }, rest, { ref: forwardedRef, "data-state": getCheckedState(checked), onSelect: (0, composeEventHandlers_1.composeEventHandlers)(onSelect, () => onCheckedChange === null || onCheckedChange === void 0 ? void 0 : onCheckedChange(isIndeterminate(checked) ? true : !checked), { checkForDefaultPrevented: false }) })))); }); exports.MenuCheckboxItem = MenuCheckboxItem; const MenuDivider = (0, react_1.forwardRef)((props, ref) => { return (react_1.default.createElement(SlottedDivElement_1.SlottedDivElement, Object.assign({ role: "separator", "aria-orientation": "horizontal" }, props, { ref: ref }))); }); exports.MenuDivider = MenuDivider; const [MenuSubProvider, useMenuSubContext] = (0, create_context_1.createContext)({ providerName: "MenuSubProvider", hookName: "useMenuSubContext", }); const MenuSub = ({ children, onOpenChange, open = false, }) => { const parentMenuContext = useMenuContext(); const { values } = useMenuDescendantsContext(); const [trigger, setTrigger] = (0, react_1.useState)(null); const [content, setContent] = (0, react_1.useState)(null); const handleOpenChange = (0, hooks_1.useCallbackRef)(onOpenChange); // Prevent the parent menu from reopening with open submenus. (0, react_1.useEffect)(() => { if (parentMenuContext.open === false) { handleOpenChange(false); } return () => handleOpenChange(false); }, [parentMenuContext.open, handleOpenChange]); return (react_1.default.createElement(Floating_1.Floating, null, react_1.default.createElement(MenuProvider, { open: open, onOpenChange: (_open) => { handleOpenChange(_open); if (_open) { /* Makes sure to close all adjacent submenus if they are open */ values().forEach((descendant) => { if (descendant.node !== trigger) { descendant.closeMenu(); } }); } }, content: content, onContentChange: setContent }, react_1.default.createElement(MenuSubProvider, { contentId: (0, hooks_1.useId)(), triggerId: (0, hooks_1.useId)(), trigger: trigger, onTriggerChange: setTrigger }, children)))); }; exports.MenuSub = MenuSub; const MenuSubTrigger = (0, react_1.forwardRef)((props, forwardedRef) => { const context = useMenuContext(); const subContext = useMenuSubContext(); const composedRefs = (0, hooks_1.useMergeRefs)(forwardedRef, subContext.onTriggerChange); const handleKey = (event, keys) => { var _a; if (props.disabled) { return; } if (keys.includes(event.key)) { context.onOpenChange(true); // The trigger may hold focus if opened via pointer interaction // so we ensure content is given focus again when switching to keyboard. (_a = context.content) === null || _a === void 0 ? void 0 : _a.focus(); // prevent window from scrolling event.preventDefault(); } }; return (react_1.default.createElement(MenuAnchor, { asChild: true }, react_1.default.createElement(MenuItemInternal, Object.assign({ id: subContext.triggerId, "aria-haspopup": "menu", "aria-expanded": context.open, "aria-controls": subContext.contentId, "data-state": getOpenState(context.open) }, props, { ref: composedRefs, "data-submenu-trigger": true, onClick: (event) => { var _a; if (props.disabled || event.defaultPrevented) { return; } (_a = props.onClick) === null || _a === void 0 ? void 0 : _a.call(props, event); /* * Solves edgecase where the user clicks the trigger, * but the focus is outside browser-window or viewport at first. */ event.currentTarget.focus(); context.onOpenChange(!context.open); }, onKeyDown: (0, composeEventHandlers_1.composeEventHandlers)(props.onKeyDown, (event) => handleKey(event, ["Enter", "ArrowRight"])), onKeyUp: (0, composeEventHandlers_1.composeEventHandlers)(props.onKeyUp, (event) => handleKey(event, [" "])) })))); }); exports.MenuSubTrigger = MenuSubTrigger; const MenuSubContent = (0, react_1.forwardRef)((props, forwardedRef) => { const descendants = useMenuDescendants(); const context = useMenuContext(); const rootContext = useMenuRootContext(); const subContext = useMenuSubContext(); const ref = (0, react_1.useRef)(null); const composedRefs = (0, hooks_1.useMergeRefs)(forwardedRef, ref); return (react_1.default.createElement(MenuDescendantsProvider, { value: descendants }, react_1.default.createElement(MenuContentInternal, Object.assign({ id: subContext.contentId, "aria-labelledby": subContext.triggerId }, props, { ref: composedRefs, align: "start", side: "right", disableOutsidePointerEvents: false, initialFocus: () => { if (rootContext.isUsingKeyboardRef.current) { return ref.current; } return false; }, /* Since we manually focus Subtrigger, we prevent use of auto-focus */ returnFocus: false, onEscapeKeyDown: (0, composeEventHandlers_1.composeEventHandlers)(props.onEscapeKeyDown, (event) => { rootContext.onClose(); // Ensure pressing escape in submenu doesn't escape full screen mode event.preventDefault(); }), onKeyDown: (0, composeEventHandlers_1.composeEventHandlers)(props.onKeyDown, (event) => { var _a, _b; // Submenu key events bubble through portals. We only care about keys in this menu. const isKeyDownInside = event.currentTarget.contains(event.target); let isCloseKey = event.key === "ArrowLeft"; /* When submenu opens to the left, we allow closing it with ArrowRight */ if (((_a = context.content) === null || _a === void 0 ? void 0 : _a.dataset.side) === "left") { isCloseKey = isCloseKey || event.key === "ArrowRight"; } if (isKeyDownInside && isCloseKey) { context.onOpenChange(false); // We focus manually because we prevented it in `onCloseAutoFocus` (_b = subContext.trigger) === null || _b === void 0 ? void 0 : _b.focus(); // Prevent window from scrolling event.preventDefault(); } }) })))); }); exports.MenuSubContent = MenuSubContent; /* -------------------------------------------------------------------------- */ /* Utilities */ /* -------------------------------------------------------------------------- */ function getOpenState(open) { return open ? "open" : "closed"; } function isIndeterminate(checked) { return checked === "indeterminate"; } function getCheckedState(checked) { return isIndeterminate(checked) ? "indeterminate" : checked ? "checked" : "unchecked"; } function whenMouse(handler) { return (event) => event.pointerType === "mouse" ? handler(event) : undefined; } /* -------------------------------------------------------------------------- */ Menu.Anchor = MenuAnchor; Menu.Portal = MenuPortal; Menu.Content = MenuContent; Menu.Group = MenuGroup; Menu.Item = MenuItem; Menu.CheckboxItem = MenuCheckboxItem; Menu.RadioGroup = MenuRadioGroup; Menu.RadioItem = MenuRadioItem; Menu.Divider = MenuDivider; Menu.Sub = MenuSub; Menu.SubTrigger = MenuSubTrigger; Menu.SubContent = MenuSubContent; Menu.ItemIndicator = MenuItemIndicator; //# sourceMappingURL=Menu.js.map