UNPKG

@mantine/core

Version:

React components library focused on usability, accessibility and developer experience

186 lines (183 loc) 5.99 kB
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