UNPKG

@react-md/menu

Version:

Create menus that auto-position themselves within the viewport and adhere to the accessibility guidelines

59 lines 2.73 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useMenu = void 0; var utils_1 = require("@react-md/utils"); var useMenuClick_1 = require("./useMenuClick"); var useMenuKeyDown_1 = require("./useMenuKeyDown"); /** * This hook is used to provide all the menu functionality within the `Menu` * component. It'll ensure that: * * - the menu will be closed if an element outside of the menu is clicked * - the menu items within the menu are keyboard focusable after typing or using * the arrow keys * - the menu will close if the Escape key or Tab key is pressed (tab since * it'll lose focus) * - conditionally close the menu if the page is scrolled while visible. */ function useMenu(_a) { var propRef = _a.ref, visible = _a.visible, controlId = _a.controlId, _b = _a.horizontal, horizontal = _b === void 0 ? false : _b, propOnClick = _a.onClick, propOnKeyDown = _a.onKeyDown, _c = _a.portalled, portalled = _c === void 0 ? false : _c, defaultFocus = _a.defaultFocus, onRequestClose = _a.onRequestClose, _d = _a.disableControlClickOkay, disableControlClickOkay = _d === void 0 ? false : _d; var _e = utils_1.useEnsuredRef(propRef), ref = _e[0], refHandler = _e[1]; utils_1.useCloseOnOutsideClick({ element: ref, enabled: visible, onOutsideClick: function (element, target, contains) { if (!element || !target) { return; } var control = document.getElementById(controlId); // Need to also check if we have an `aria-expanded` visible anywhere since // the child menus need to be portalled out to fix the overflow issue in // Safari. If we didn't need to portal, this line could be removed as the // `menu.current` would contain the child menu and not close. var expanded = ref.current && ref.current.querySelector('[aria-expanded="true"]') && target.closest('[role="menu"]'); if ((disableControlClickOkay || !contains(control, target)) && !expanded) { onRequestClose(); } }, }); var onClick = useMenuClick_1.useMenuClick({ onClick: propOnClick, onRequestClose: onRequestClose }); var onKeyDown = useMenuKeyDown_1.useMenuKeyDown({ menu: ref.current, onKeyDown: propOnKeyDown, onRequestClose: onRequestClose, portalled: portalled, horizontal: horizontal, defaultFocus: defaultFocus, }); return { ref: refHandler, menuRef: ref, onClick: onClick, onKeyDown: onKeyDown, }; } exports.useMenu = useMenu; //# sourceMappingURL=useMenu.js.map