@yamada-ui/menu
Version:
Yamada UI menu component
208 lines (205 loc) • 7.38 kB
JavaScript
"use client"
;
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