UNPKG

@yamada-ui/menu

Version:

Yamada UI menu component

866 lines (851 loc) • 30.9 kB
"use client" "use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var index_exports = {}; __export(index_exports, { ContextMenu: () => ContextMenu, ContextMenuTrigger: () => ContextMenuTrigger, Menu: () => Menu, MenuButton: () => MenuButton, MenuCommand: () => MenuCommand, MenuDivider: () => MenuDivider, MenuGroup: () => MenuGroup, MenuIcon: () => MenuIcon, MenuItem: () => MenuItem, MenuItemButton: () => MenuItemButton, MenuList: () => MenuList, MenuOptionGroup: () => MenuOptionGroup, MenuOptionItem: () => MenuOptionItem, MenuSeparator: () => MenuSeparator }); module.exports = __toCommonJS(index_exports); // src/context-menu.tsx var import_core2 = require("@yamada-ui/core"); // src/menu.tsx var import_core = require("@yamada-ui/core"); var import_popover = require("@yamada-ui/popover"); var import_use_disclosure = require("@yamada-ui/use-disclosure"); var import_utils2 = require("@yamada-ui/utils"); var import_react = require("react"); // src/menu-context.ts var import_use_descendant = require("@yamada-ui/use-descendant"); var import_utils = require("@yamada-ui/utils"); var { DescendantsContextProvider, useDescendant: useMenuDescendant, useDescendants, useDescendantsContext: useMenuDescendantsContext } = (0, import_use_descendant.createDescendant)(); var [MenuProvider, useMenu] = (0, import_utils.createContext)({ name: "MenuContext", errorMessage: `useMenu returned is 'undefined'. Seems you forgot to wrap the components in "<Menu />"` }); var [ContextMenuProvider, useContextMenu] = (0, import_utils.createContext)({ name: "ContextMenuContext", strict: false }); var [UpstreamMenuProvider, useUpstreamMenu] = (0, import_utils.createContext)({ name: "UpstreamMenuContext", strict: false }); var [UpstreamMenuItemProvider, useUpstreamMenuItem] = (0, import_utils.createContext)({ name: "UpstreamMenuItemContext", strict: false }); // src/menu.tsx var import_jsx_runtime = require("react/jsx-runtime"); var Menu = (props) => { var _a, _b, _c; const { styles: contextMenuStyles } = (_a = useContextMenu()) != null ? _a : {}; const [styles, mergedProps] = (0, import_core.useComponentMultiStyle)("Menu", props, { isProcessSkip: !!contextMenuStyles, styles: contextMenuStyles }); const { relatedRef, onDownstreamCloseMapRef, onUpstreamClose } = (_b = useUpstreamMenu()) != null ? _b : {}; const nested = !!relatedRef; const { closeOnBlur = !nested, closeOnSelect = true, duration = 0.2, initialFocusRef, offset = nested ? [-8, 8] : void 0, placement = nested ? "right-start" : "bottom-start", onClose: onCloseProp, onOpen: onOpenProp, ...rest } = (0, import_core.omitThemeProps)(mergedProps); const { hasDownstreamRef, setDownstreamOpen } = (_c = useUpstreamMenuItem()) != null ? _c : {}; const descendants = useDescendants(); const [focusedIndex, setFocusedIndex] = (0, import_react.useState)(-1); const menuRef = (0, import_react.useRef)(null); const buttonRef = (0, import_react.useRef)(null); const timeoutIds = (0, import_react.useRef)(/* @__PURE__ */ new Set([])); const requestAnimationFrameId = (0, import_react.useRef)(null); const onCloseMapRef = (0, import_react.useRef)(/* @__PURE__ */ new Map()); const onFocusMenu = (0, import_react.useCallback)(() => { requestAnimationFrame( () => { var _a2; return (_a2 = menuRef.current) == null ? void 0 : _a2.focus({ preventScroll: false }); } ); }, []); const onFocusFirstItem = (0, import_react.useCallback)(() => { const id2 = setTimeout(() => { if (initialFocusRef) return; const first = descendants.enabledFirstValue(); if (first) setFocusedIndex(first.index); }); timeoutIds.current.add(id2); }, [descendants, initialFocusRef]); const onFocusLastItem = (0, import_react.useCallback)(() => { const id2 = setTimeout(() => { if (initialFocusRef) return; const last = descendants.enabledLastValue(); if (last) setFocusedIndex(last.index); }); timeoutIds.current.add(id2); }, [descendants, initialFocusRef]); const onOpenInternal = (0, import_react.useCallback)(() => { onOpenProp == null ? void 0 : onOpenProp(); if (!nested) onFocusMenu(); }, [onOpenProp, nested, onFocusMenu]); const onCloseInternal = (0, import_react.useCallback)(() => { onCloseProp == null ? void 0 : onCloseProp(); for (const onClose2 of onCloseMapRef.current.values()) { onClose2(); } }, [onCloseProp]); const id = (0, import_react.useId)(); const { open, onClose, onOpen } = (0, import_use_disclosure.useDisclosure)({ ...props, onClose: onCloseInternal, onOpen: onOpenInternal }); (0, import_react.useEffect)(() => { const onCloseMap = onDownstreamCloseMapRef == null ? void 0 : onDownstreamCloseMapRef.current; onCloseMap == null ? void 0 : onCloseMap.set(id, onClose); return () => { onCloseMap == null ? void 0 : onCloseMap.delete(id); }; }, [id, onClose, onDownstreamCloseMapRef]); (0, import_react.useEffect)(() => { if (setDownstreamOpen) setDownstreamOpen(open); }, [setDownstreamOpen, open]); (0, import_react.useEffect)(() => { if (hasDownstreamRef) hasDownstreamRef.current = true; return () => { if (hasDownstreamRef) hasDownstreamRef.current = false; }; }); (0, import_utils2.useUpdateEffect)(() => { if (!open) setFocusedIndex(-1); }, [open]); (0, import_utils2.useUnmountEffect)(() => { timeoutIds.current.forEach((id2) => clearTimeout(id2)); timeoutIds.current.clear(); }); return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DescendantsContextProvider, { value: descendants, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( UpstreamMenuProvider, { value: { relatedRef: menuRef, onDownstreamCloseMapRef: onCloseMapRef, onUpstreamClose: (0, import_utils2.funcAll)(onUpstreamClose, onClose) }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( MenuProvider, { value: { buttonRef, closeOnSelect, focusedIndex, menuRef, nested, open, requestAnimationFrameId, setFocusedIndex, styles, onClose, onFocusFirstItem, onFocusLastItem, onOpen, onUpstreamClose }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( import_popover.Popover, { ...{ trigger: nested ? "hover" : "click", ...rest, closeOnBlur, closeOnButton: false, duration, initialFocusRef, offset, open, placement, relatedRef, onClose, onOpen } } ) } ) } ) }); }; Menu.__ui__ = "Menu"; // src/context-menu.tsx var import_jsx_runtime2 = require("react/jsx-runtime"); var ContextMenu = (props) => { const [styles, mergedProps] = (0, import_core2.useComponentMultiStyle)("ContextMenu", props); const { ...rest } = (0, import_core2.omitThemeProps)(mergedProps); return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ContextMenuProvider, { value: { styles }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Menu, { trigger: "contextmenu", ...rest }) }); }; ContextMenu.__ui__ = "ContextMenu"; // src/context-menu-trigger.tsx var import_core3 = require("@yamada-ui/core"); var import_popover2 = require("@yamada-ui/popover"); var import_utils3 = require("@yamada-ui/utils"); var import_react2 = require("react"); var import_jsx_runtime3 = require("react/jsx-runtime"); var ContextMenuTrigger = (0, import_core3.forwardRef)( ({ className, children, ...rest }, ref) => { var _a; const { styles } = (_a = useContextMenu()) != null ? _a : {}; const [position, setPosition] = (0, import_react2.useState)({ left: 0, top: 0 }); const css = { ...styles == null ? void 0 : styles.container }; const onContextMenu = (ev) => { setPosition({ left: ev.pageX, top: ev.pageY }); }; return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_popover2.PopoverAnchor, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)( import_core3.ui.div, { className: "ui-context-menu__anchor", style: { position: "absolute", ...position } } ) }), /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_popover2.PopoverTrigger, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)( import_core3.ui.div, { ref, className: (0, import_utils3.cx)("ui-context-menu", className), "aria-haspopup": "menu", role: "application", __css: css, ...rest, onContextMenu: (0, import_utils3.handlerAll)(rest.onContextMenu, onContextMenu), children } ) }) ] }); } ); ContextMenuTrigger.displayName = "ContextMenuTrigger"; ContextMenuTrigger.__ui__ = "ContextMenuTrigger"; // src/menu-button.tsx var import_core5 = require("@yamada-ui/core"); var import_icon = require("@yamada-ui/icon"); var import_popover3 = require("@yamada-ui/popover"); var import_utils5 = require("@yamada-ui/utils"); var import_react4 = require("react"); // src/menu-item.tsx var import_core4 = require("@yamada-ui/core"); var import_use_clickable = require("@yamada-ui/use-clickable"); var import_utils4 = require("@yamada-ui/utils"); var import_react3 = require("react"); var import_jsx_runtime4 = require("react/jsx-runtime"); var isTargetMenuItem = (target) => { var _a; return (0, import_utils4.isHTMLElement)(target) && !!((_a = target.getAttribute("role")) == null ? void 0 : _a.startsWith("menuitem")); }; var MenuItem = (0, import_core4.forwardRef)( ({ id, className, children, closeOnSelect: customCloseOnSelect, command, isDisabled, disabled = isDisabled, isFocusable, focusable = isFocusable, icon, ...props }, ref) => { var _a, _b; const { closeOnSelect, focusedIndex, menuRef, nested, open, requestAnimationFrameId, setFocusedIndex, styles, onClose, onUpstreamClose } = useMenu(); const { onUpstreamRestoreFocus } = (_a = useUpstreamMenuItem()) != null ? _a : {}; const [downstreamOpen, setDownstreamOpen] = (0, import_react3.useState)(false); const uuid = (0, import_react3.useId)(); const itemRef = (0, import_react3.useRef)(null); const hasDownstreamRef = (0, import_react3.useRef)(false); const onKeyDownRef = (0, import_react3.useRef)( () => void 0 ); const trulyDisabled = disabled && !focusable; const type = (_b = itemRef.current) == null ? void 0 : _b.getAttribute("type"); const role = !!type ? type === "checkbox" ? "menuitemcheckbox" : "menuitemradio" : "menuitem"; const { index, register } = useMenuDescendant({ disabled: trulyDisabled }); const focused = index === focusedIndex; const css = { alignItems: "center", color: "inherit", display: "flex", flex: "0 0 auto", gap: "0.75rem", outline: 0, textAlign: "start", textDecoration: "none", userSelect: "none", width: "100%", ...styles.item }; id != null ? id : id = uuid; const onMouseOver = (0, import_react3.useCallback)(() => { if (disabled) return; setFocusedIndex(index); }, [index, disabled, setFocusedIndex]); const onMouseLeave = (0, import_react3.useCallback)(() => { if (disabled) return; setFocusedIndex(-1); }, [setFocusedIndex, disabled]); const onClick = (0, import_react3.useCallback)( (ev) => { if (!isTargetMenuItem(ev.currentTarget)) return; const hasDownstream = hasDownstreamRef.current; if (customCloseOnSelect != null ? customCloseOnSelect : !hasDownstream && closeOnSelect) { onClose(); onUpstreamClose == null ? void 0 : onUpstreamClose(); } }, [customCloseOnSelect, closeOnSelect, onClose, onUpstreamClose] ); const onFocus = (0, import_react3.useCallback)(() => { setFocusedIndex(index); }, [setFocusedIndex, index]); const onRestoreFocus = (0, import_react3.useCallback)(() => { var _a2; (_a2 = itemRef.current) == null ? void 0 : _a2.focus(); setFocusedIndex(index); }, [setFocusedIndex, index]); const onKeyDown = (0, import_react3.useCallback)( (ev) => { if (ev.key === " ") ev.key = ev.code; const actions = { ArrowLeft: nested ? (0, import_utils4.funcAll)(onUpstreamRestoreFocus, onClose) : void 0, Space: !hasDownstreamRef.current ? (0, import_utils4.funcAll)(onUpstreamClose, onClose) : void 0 }; const action = actions[ev.key]; if (!action) return; ev.preventDefault(); ev.stopPropagation(); action(); }, [nested, onUpstreamRestoreFocus, onClose, onUpstreamClose] ); const rest = (0, import_use_clickable.useClickable)({ clickOnSpace: false, focusOnClick: false, ...props, ref: (0, import_utils4.mergeRefs)(register, itemRef, ref), disabled, focusable, onClick: (0, import_utils4.handlerAll)(props.onClick, onClick), onFocus: (0, import_utils4.handlerAll)(props.onFocus, onFocus), onKeyDown: (0, import_utils4.handlerAll)(props.onKeyDown, onKeyDown, onKeyDownRef.current), onMouseLeave: (0, import_utils4.handlerAll)(props.onMouseLeave, onMouseLeave), onMouseOver: (0, import_utils4.handlerAll)(props.onMouseOver, onMouseOver) }); (0, import_utils4.useUpdateEffect)(() => { if (!open) return; const id2 = requestAnimationFrameId.current; if (focused && !trulyDisabled && itemRef.current) { if (id2) cancelAnimationFrame(id2); requestAnimationFrameId.current = requestAnimationFrame(() => { var _a2; (_a2 = itemRef.current) == null ? void 0 : _a2.focus({ preventScroll: true }); requestAnimationFrameId.current = null; }); } else if (menuRef.current && !(0, import_utils4.isActiveElement)(menuRef.current)) { menuRef.current.focus({ preventScroll: true }); } return () => { if (id2) cancelAnimationFrame(id2); }; }, [focused, trulyDisabled, menuRef, open]); children = icon || command ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_core4.ui.span, { style: { flex: 1 }, children }) : children; return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)( UpstreamMenuItemProvider, { value: { hasDownstreamRef, setDownstreamOpen, onKeyDownRef, onUpstreamRestoreFocus: onRestoreFocus }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)( import_core4.ui.div, { id, className: (0, import_utils4.cx)("ui-menu__item", className), "data-focus": (0, import_utils4.dataAttr)(downstreamOpen), __css: css, ...rest, role, tabIndex: !downstreamOpen && focused ? 0 : -1, children: [ icon ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MenuIcon, { children: icon }) : null, children, command ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MenuCommand, { children: command }) : null ] } ) } ); } ); MenuItem.displayName = "MenuItem"; MenuItem.__ui__ = "MenuItem"; var MenuOptionItem = (0, import_core4.forwardRef)( ({ className, isChecked, checked = isChecked, children, closeOnSelect = false, icon, ...rest }, ref) => { return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)( MenuItem, { ref, className: (0, import_utils4.cx)("ui-menu__item--option", className), "aria-checked": checked, closeOnSelect, ...rest, children: [ icon !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MenuIcon, { opacity: checked ? 1 : 0, children: icon || /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CheckIcon, {}) }) : null, children ] } ); } ); MenuOptionItem.displayName = "MenuOptionItem"; MenuOptionItem.__ui__ = "MenuOptionItem"; var MenuIcon = (0, import_core4.forwardRef)( ({ className, ...rest }, ref) => { const { styles } = useMenu(); const css = { alignItems: "center", display: "inline-flex", flexShrink: 0, fontSize: "0.85em", justifyContent: "center", ...styles.icon }; return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)( import_core4.ui.span, { ref, className: (0, import_utils4.cx)("ui-menu__item__icon", className), "aria-hidden": true, __css: css, ...rest } ); } ); MenuIcon.displayName = "MenuIcon"; MenuIcon.__ui__ = "MenuIcon"; var MenuCommand = (0, import_core4.forwardRef)( ({ className, ...rest }, ref) => { const { styles } = useMenu(); const css = { ...styles.command }; return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)( import_core4.ui.span, { ref, className: (0, import_utils4.cx)("ui-menu__item__command", className), __css: css, ...rest } ); } ); MenuCommand.displayName = "MenuCommand"; MenuCommand.__ui__ = "MenuCommand"; var CheckIcon = () => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { height: "1em", viewBox: "0 0 14 14", width: "1em", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)( "polygon", { fill: "currentColor", points: "5.5 11.9993304 14 3.49933039 12.5 2 5.5 8.99933039 1.5 4.9968652 0 6.49933039" } ) }); // src/menu-button.tsx var import_jsx_runtime5 = require("react/jsx-runtime"); var MenuButton = (0, import_core5.forwardRef)( ({ id, as, className, children, ...rest }, ref) => { var _a; const { onKeyDownRef, onUpstreamRestoreFocus } = (_a = useUpstreamMenuItem()) != null ? _a : {}; const { buttonRef, open, onClose, onFocusFirstItem, onFocusLastItem, onOpen } = useMenu(); const uuid = (0, import_react4.useId)(); id != null ? id : id = uuid; const onKeyDown = (0, import_react4.useCallback)( (ev) => { if (ev.key === " ") ev.key = ev.code; const actions = { ArrowDown: (0, import_utils5.funcAll)(onOpen, onFocusFirstItem), ArrowUp: (0, import_utils5.funcAll)(onOpen, onFocusLastItem), Enter: (0, import_utils5.funcAll)(onOpen, onFocusFirstItem), Space: (0, import_utils5.funcAll)(onOpen, onFocusFirstItem) }; const action = actions[ev.key]; if (!action) return; ev.preventDefault(); action(); }, [onFocusFirstItem, onFocusLastItem, onOpen] ); const onItemKeyDown = (0, import_react4.useCallback)( (ev) => { if (ev.key === " ") ev.key = ev.code; const actions = { ArrowLeft: open ? (0, import_utils5.funcAll)(onUpstreamRestoreFocus, onClose) : void 0, ArrowRight: !open ? (0, import_utils5.funcAll)(onOpen, onFocusFirstItem) : void 0, Enter: !open ? (0, import_utils5.funcAll)(onOpen, onFocusFirstItem) : void 0, Space: !open ? (0, import_utils5.funcAll)(onOpen, onFocusFirstItem) : void 0 }; const action = actions[ev.key]; if (!action) return; ev.preventDefault(); action(); }, [open, onOpen, onFocusFirstItem, onUpstreamRestoreFocus, onClose] ); (0, import_utils5.assignRef)(onKeyDownRef, onItemKeyDown); const Component = (0, import_react4.useMemo)(() => as ? (0, import_core5.ui)(as) : Button, [as]); return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_popover3.PopoverTrigger, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)( Component, { id, ref: (0, import_utils5.mergeRefs)(buttonRef, ref), className: (0, import_utils5.cx)("ui-menu", className), "aria-haspopup": "menu", ...rest, "data-active": (0, import_utils5.dataAttr)(open), onKeyDown: (0, import_utils5.handlerAll)(rest.onKeyDown, onKeyDown), children } ) }); } ); MenuButton.displayName = "MenuButton"; MenuButton.__ui__ = "MenuButton"; var Button = (0, import_core5.forwardRef)((rest, ref) => { const { styles } = useMenu(); const css = { alignItems: "center", appearance: "none", display: "inline-flex", outline: 0, ...styles.button }; return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core5.ui.button, { ref, __css: css, ...rest }); }); var MenuItemButton = (0, import_core5.forwardRef)( ({ className, children, icon, iconProps, innerProps, ...rest }, ref) => { return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)( MenuButton, { ref, className: (0, import_utils5.cx)("ui-menu__item-button", className), flex: "1", ...rest, children: [ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core5.ui.span, { as: "span", flex: "1", ...innerProps, children }), /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MenuIcon, { ...iconProps, children: icon != null ? icon : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_icon.ChevronIcon, { fontSize: "1.5em", transform: "rotate(-90deg)" }) }) ] } ); } ); MenuItemButton.displayName = "MenuItemButton"; MenuItemButton.__ui__ = "MenuItemButton"; // src/menu-divider.tsx var import_core6 = require("@yamada-ui/core"); var import_utils6 = require("@yamada-ui/utils"); var import_jsx_runtime6 = require("react/jsx-runtime"); var MenuDivider = (0, import_core6.forwardRef)( ({ className, ...rest }, ref) => { const { styles } = useMenu(); const css = { ...styles.divider }; return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)( import_core6.ui.hr, { ref, className: (0, import_utils6.cx)("ui-menu__divider", className), __css: css, ...rest } ); } ); MenuDivider.displayName = "MenuDivider"; MenuDivider.__ui__ = "MenuDivider"; // src/menu-group.tsx var import_core7 = require("@yamada-ui/core"); var import_utils7 = require("@yamada-ui/utils"); var import_react5 = require("react"); var import_jsx_runtime7 = require("react/jsx-runtime"); var MenuGroup = (0, import_core7.forwardRef)( ({ className, children, label, labelProps, ...rest }, ref) => { var _a; const { styles } = useMenu(); const id = (0, import_react5.useId)(); const labelId = (_a = labelProps == null ? void 0 : labelProps.id) != null ? _a : id; const css = { ...styles.group }; return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)( import_core7.ui.section, { ref, className: (0, import_utils7.cx)("ui-menu__item", "ui-menu__item--group", className), "aria-labelledby": labelId, role: "group", __css: css, ...rest, children: [ label ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)( import_core7.ui.header, { className: (0, import_utils7.cx)("ui-menu__item--group-label"), role: "presentation", __css: styles.groupLabel, ...labelProps, id: labelId, children: label } ) : null, /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_core7.ui.div, { className: "ui-menu__item__group", children }) ] } ); } ); MenuGroup.displayName = "MenuGroup"; MenuGroup.__ui__ = "MenuGroup"; // src/menu-list.tsx var import_core8 = require("@yamada-ui/core"); var import_popover4 = require("@yamada-ui/popover"); var import_utils8 = require("@yamada-ui/utils"); var import_react6 = require("react"); var import_jsx_runtime8 = require("react/jsx-runtime"); var MenuList = (0, import_core8.forwardRef)( ({ className, children, contentProps, ...rest }, ref) => { var _a, _b; const { buttonRef, focusedIndex, menuRef, setFocusedIndex, styles, onClose } = useMenu(); const descendants = useMenuDescendantsContext(); const activedescendantId = (_a = descendants.value(focusedIndex)) == null ? void 0 : _a.node.id; const onNext = (0, import_react6.useCallback)(() => { const next = descendants.enabledNextValue(focusedIndex); if (next) setFocusedIndex(next.index); }, [descendants, focusedIndex, setFocusedIndex]); const onPrev = (0, import_react6.useCallback)(() => { const prev = descendants.enabledPrevValue(focusedIndex); if (prev) setFocusedIndex(prev.index); }, [descendants, focusedIndex, setFocusedIndex]); const onFirst = (0, import_react6.useCallback)(() => { const first = descendants.enabledFirstValue(); if (first) setFocusedIndex(first.index); }, [descendants, setFocusedIndex]); const onLast = (0, import_react6.useCallback)(() => { const last = descendants.enabledLastValue(); if (last) setFocusedIndex(last.index); }, [descendants, setFocusedIndex]); const onKeyDown = (0, import_react6.useCallback)( (ev) => { const actions = { ArrowDown: focusedIndex === -1 ? onFirst : onNext, ArrowUp: focusedIndex === -1 ? onLast : onPrev, End: onLast, Escape: onClose, Home: onFirst, Tab: onClose }; const action = actions[ev.key]; if (!action) return; ev.preventDefault(); action(ev); }, [focusedIndex, onClose, onFirst, onLast, onNext, onPrev] ); return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)( import_popover4.PopoverContent, { as: "div", className: "ui-menu__content", "aria-activedescendant": activedescendantId, "aria-labelledby": (_b = buttonRef.current) == null ? void 0 : _b.id, role: "menu", __css: { ...styles.content }, ...contentProps, onKeyDown: (0, import_utils8.handlerAll)(contentProps == null ? void 0 : contentProps.onKeyDown, onKeyDown), children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)( import_core8.ui.div, { ref: (0, import_utils8.mergeRefs)(menuRef, ref), className: (0, import_utils8.cx)("ui-menu__list", className), tabIndex: -1, __css: { ...styles.list }, ...rest, children } ) } ); } ); MenuList.displayName = "MenuList"; MenuList.__ui__ = "MenuList"; // src/menu-option-group.tsx var import_use_controllable_state = require("@yamada-ui/use-controllable-state"); var import_utils9 = require("@yamada-ui/utils"); var import_react7 = require("react"); var import_jsx_runtime9 = require("react/jsx-runtime"); var MenuOptionGroup = (0, import_react7.forwardRef)( ({ type, className, children, defaultValue, value: valueProp, onChange: onChangeProp, ...rest }, ref) => { const radio = type === "radio"; defaultValue != null ? defaultValue : defaultValue = radio ? "" : []; const [value, setValue] = (0, import_use_controllable_state.useControllableState)({ defaultValue, value: valueProp, onChange: onChangeProp }); const onChange = (0, import_react7.useCallback)( (selectedValue) => { if (radio && (0, import_utils9.isString)(value)) setValue(selectedValue); if (!radio && (0, import_utils9.isArray)(value)) { const nextValue = value.includes(selectedValue) ? value.filter((item) => item !== selectedValue) : value.concat(selectedValue); setValue(nextValue); } }, [radio, value, setValue] ); const validChildren = (0, import_utils9.getValidChildren)(children); const cloneChildren = validChildren.map((child) => { if (child.type !== MenuOptionItem) return child; const onClick = (ev) => { var _a, _b; onChange(child.props.value); (_b = (_a = child.props).onClick) == null ? void 0 : _b.call(_a, ev); }; const checked = !radio && (0, import_utils9.isArray)(value) ? value.includes(child.props.value) : child.props.value === value; return (0, import_react7.cloneElement)(child, { type, checked, onClick }); }); return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)( MenuGroup, { ref, className: (0, import_utils9.cx)("ui-menu__item--group--option", className), ...rest, children: cloneChildren } ); } ); MenuOptionGroup.displayName = "MenuOptionGroup"; MenuOptionGroup.__ui__ = "MenuOptionGroup"; // src/menu-separator.tsx var import_core9 = require("@yamada-ui/core"); var import_utils10 = require("@yamada-ui/utils"); var import_jsx_runtime10 = require("react/jsx-runtime"); var MenuSeparator = (0, import_core9.forwardRef)( ({ className, ...rest }, ref) => { const { styles } = useMenu(); const css = { ...styles.divider, ...styles.separator }; return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)( import_core9.ui.hr, { ref, className: (0, import_utils10.cx)("ui-menu__separator", className), __css: css, ...rest } ); } ); MenuSeparator.displayName = "MenuSeparator"; MenuSeparator.__ui__ = "MenuSeparator"; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { ContextMenu, ContextMenuTrigger, Menu, MenuButton, MenuCommand, MenuDivider, MenuGroup, MenuIcon, MenuItem, MenuItemButton, MenuList, MenuOptionGroup, MenuOptionItem, MenuSeparator }); //# sourceMappingURL=index.js.map