UNPKG

@octopusdeploy/design-system-components

Version:
41 lines (40 loc) 3.07 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.CustomMenu = CustomMenu; const jsx_runtime_1 = require("react/jsx-runtime"); const css_1 = require("@emotion/css"); const Menu_1 = __importDefault(require("@mui/material/Menu")); const design_system_tokens_1 = require("@octopusdeploy/design-system-tokens"); const react_1 = require("react"); const flattenFragments_1 = require("../../utils/flattenFragments"); function CustomMenu(props) { const { children, anchorOrigin, onKeyDown, accessibleName } = props; const { isOpen, onClose, anchorElement, menuId } = "menuState" in props ? props.menuState : props; const anchorOriginWithDefaults = (0, react_1.useMemo)(() => ({ horizontal: anchorOrigin?.horizontal ?? "left", vertical: anchorOrigin?.vertical ?? "bottom", }), [anchorOrigin]); //Menus are generally removed from the usual flow of elements so mouse events like click / mouse down etc. are a bit //surprising to receive in containing elements such as overflow titles etc. as these can have unintended behaviors. const stopEventPropagation = (0, react_1.useCallback)((event) => event.stopPropagation(), []); // If we specify an onKeyDown prop (even if it is undefined), this will overwrite material-uis onkeydown handler for modals (i.e. escape handling) // It looks like this might be fixed in more recent versions of material-ui (https://github.com/mui-org/material-ui/blob/4323c7706b6b641dcc9ed51f00ff163e5f80966f/packages/mui-base/src/ModalUnstyled/ModalUnstyled.js#L210-L212) // Currently, this means that escape won't work for nested menus const onKeyDownProps = onKeyDown ? { onKeyDown } : {}; // Material-ui Menus don't support fragments as children // This is so that they can inspect the props of their children in order to work out which one is selected // This is using a feature of menus (selection) that we don't use, so for our usages we can allow fragments const childrenWithoutFragments = (0, flattenFragments_1.flattenFragments)(children); return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsx)(Menu_1.default, { id: menuId, open: isOpen, onClose: onClose, anchorEl: anchorElement, autoFocus: false, MenuListProps: { component: "div", "aria-label": accessibleName, className: menuListStyles }, anchorOrigin: anchorOriginWithDefaults, onMouseDown: stopEventPropagation, onMouseUp: stopEventPropagation, onClick: stopEventPropagation, ...onKeyDownProps, children: childrenWithoutFragments }) })); } const menuListStyles = (0, css_1.css)({ "&.MuiList-root": { backgroundColor: design_system_tokens_1.themeTokens.color.menuList.background.default, border: `solid 1px ${design_system_tokens_1.themeTokens.color.border.primary}`, borderRadius: design_system_tokens_1.borderRadius.small, }, }); CustomMenu.displayName = "CustomMenu";