UNPKG

@react-md/menu

Version:

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

71 lines 2.88 kB
var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; import { useEffect, useMemo, useState } from "react"; import { extractTextContent, getFocusableElements, MovementPresets, useKeyboardMovement, } from "@react-md/utils"; /** * This hook allows for the keyboard movement within a menu. It'll make sure * that the arrow keys and typing letters can correctly focus menu items. In * addition, it'll automatically swap to the left and right arrow keys if the * menu is displayed horizontally. */ export function useMenuKeyDown(_a) { var menu = _a.menu, onKeyDown = _a.onKeyDown, onRequestClose = _a.onRequestClose, portalled = _a.portalled, horizontal = _a.horizontal, defaultFocus = _a.defaultFocus; var _b = useState(0), focusedIndex = _b[0], setFocusedIndex = _b[1]; var items = useMemo(function () { if (!menu) { return []; } return getFocusableElements(menu, true); }, [menu]); useEffect(function () { if (!menu) { return; } if (defaultFocus === "last") { setFocusedIndex(items.length - 1); } else { setFocusedIndex(0); } // only want to trigger this on initial menu mount // eslint-disable-next-line react-hooks/exhaustive-deps }, [menu]); return useKeyboardMovement(__assign(__assign({}, (horizontal ? MovementPresets.HORIZONTAL_MENU : MovementPresets.VERTICAL_MENU)), { focusedIndex: focusedIndex, onChange: function (_a) { var index = _a.index; setFocusedIndex(index); if (items[index]) { items[index].focus(); } }, items: items.map(function (item) { return extractTextContent(item); }), onKeyDown: function (event) { if (onKeyDown) { onKeyDown(event); } if (event.key === "Escape") { event.stopPropagation(); onRequestClose(); } else if (event.key === "Tab") { if (portalled) { // have to prevent default tab behavior since tab order is ruined when // something is portalled. this will make it interact the same as if // it was an escape keypress. it's too much work to try to emulate a // real tab here event.preventDefault(); } onRequestClose(); } } }))[1]; } //# sourceMappingURL=useMenuKeyDown.js.map