UNPKG

@yamada-ui/menu

Version:

Yamada UI menu component

208 lines (205 loc) • 7.38 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/menu.tsx var menu_exports = {}; __export(menu_exports, { Menu: () => Menu }); module.exports = __toCommonJS(menu_exports); 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"; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { Menu }); //# sourceMappingURL=menu.js.map