@mantine/core
Version:
React components library focused on usability, accessibility and developer experience
186 lines (183 loc) • 5.99 kB
JavaScript
import React, { useRef, cloneElement } from 'react';
import { useId, useUncontrolled, useWindowEvent, useClickOutside, useMergedRef } from '@mantine/hooks';
import { ActionIcon } from '../ActionIcon/ActionIcon.js';
import { MenuIcon } from './MenuIcon.js';
import { MenuBody } from './MenuBody/MenuBody.js';
export { MenuBody } from './MenuBody/MenuBody.js';
import { sizes } from './MenuBody/MenuBody.styles.js';
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var __objRest = (source, exclude) => {
var target = {};
for (var prop in source)
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
target[prop] = source[prop];
if (source != null && __getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(source)) {
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
target[prop] = source[prop];
}
return target;
};
const MENU_SIZES = sizes;
const defaultControl = /* @__PURE__ */ React.createElement(ActionIcon, null, /* @__PURE__ */ React.createElement(MenuIcon, null));
function Menu(_a) {
var _b = _a, {
control = defaultControl,
children,
onClose,
onOpen,
opened,
themeOverride,
menuPosition = { top: 0, left: 0 },
style,
menuId,
menuBodyProps = {},
closeOnItemClick = true,
transitionDuration = 250,
size = "md",
shadow = "md",
transition = "skew-up",
transitionTimingFunction,
menuButtonLabel,
controlRefProp = "elementRef",
trigger = "click",
delay = 0,
zIndex = 1e3,
elementRef,
classNames,
styles,
onMouseLeave,
onMouseEnter,
onChange
} = _b, others = __objRest(_b, [
"control",
"children",
"onClose",
"onOpen",
"opened",
"themeOverride",
"menuPosition",
"style",
"menuId",
"menuBodyProps",
"closeOnItemClick",
"transitionDuration",
"size",
"shadow",
"transition",
"transitionTimingFunction",
"menuButtonLabel",
"controlRefProp",
"trigger",
"delay",
"zIndex",
"elementRef",
"classNames",
"styles",
"onMouseLeave",
"onMouseEnter",
"onChange"
]);
const controlRefFocusTimeout = useRef();
const delayTimeout = useRef();
const controlRef = useRef(null);
const uuid = useId(menuId);
const [_opened, setOpened] = useUncontrolled({
value: opened,
defaultValue: false,
finalValue: false,
rule: (val) => typeof val === "boolean",
onChange: (value) => !value ? typeof onOpen === "function" && onOpen() : typeof onClose === "function" && onClose()
});
const openedRef = useRef(_opened);
const handleClose = (scroll = false) => {
if (openedRef.current) {
openedRef.current = false;
setOpened(false);
if (trigger === "click") {
controlRefFocusTimeout.current = window.setTimeout(() => {
var _a2;
!scroll && typeof ((_a2 = controlRef.current) == null ? void 0 : _a2.focus) === "function" && controlRef.current.focus();
}, transitionDuration + 10);
}
}
};
const handleOpen = () => {
openedRef.current = true;
setOpened(true);
window.clearTimeout(controlRefFocusTimeout.current);
};
useWindowEvent("scroll", () => handleClose(true));
const wrapperRef = useClickOutside(() => _opened && handleClose());
const toggleMenu = () => {
_opened ? handleClose() : handleOpen();
};
const controlEventHandlers = trigger === "click" ? { onClick: toggleMenu } : { onMouseEnter: handleOpen, onFocus: handleOpen };
const handleMouseLeave = (event) => {
typeof onMouseLeave === "function" && onMouseLeave(event);
if (trigger === "hover") {
if (delay > 0) {
delayTimeout.current = window.setTimeout(() => handleClose(true), delay);
} else {
handleClose(true);
}
}
};
const handleMouseEnter = (event) => {
typeof onMouseEnter === "function" && onMouseEnter(event);
window.clearTimeout(delayTimeout.current);
};
const menuControl = cloneElement(control, __spreadProps(__spreadValues({}, controlEventHandlers), {
role: "button",
"aria-haspopup": "menu",
"aria-expanded": _opened,
"aria-controls": uuid,
"aria-label": menuButtonLabel,
"data-mantine-menu": true,
title: menuButtonLabel,
[controlRefProp]: useMergedRef(controlRef, elementRef)
}));
return /* @__PURE__ */ React.createElement("div", __spreadValues({
ref: wrapperRef,
style: __spreadValues({ display: "inline-block", position: "relative" }, style),
onMouseLeave: handleMouseLeave,
onMouseEnter: handleMouseEnter
}, others), menuControl, /* @__PURE__ */ React.createElement(MenuBody, __spreadProps(__spreadValues({}, menuBodyProps), {
opened: _opened,
onClose: handleClose,
id: uuid,
themeOverride,
closeOnClickOutside: false,
closeOnItemClick,
style: __spreadValues(__spreadValues({}, menuBodyProps.style), menuPosition),
transitionDuration,
transition,
transitionTimingFunction,
size,
shadow,
zIndex,
classNames,
styles
}), children));
}
Menu.displayName = "@mantine/core/Menu";
export { MENU_SIZES, Menu };
//# sourceMappingURL=Menu.js.map