UNPKG

mui-nav-menu

Version:

Navigation menu component based on material ui

112 lines (111 loc) 4.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const MenuContext_1 = require("../contexts/MenuContext"); const utils_1 = require("../utils"); const useKeyboardNavigation = () => { const { openIds, focusedNodeId, selectedIds, getChildrenIds, setFocusedNodeId, getNode, onInternalOpenChange, onSelectedChange, mode, onItemClick, } = (0, MenuContext_1.useMenuContext)(); const isExpanded = (nodeInfo) => { return openIds.includes(nodeInfo.id); }; const getCurrFocusedNodeId = () => { return focusedNodeId ? focusedNodeId : selectedIds[selectedIds.length - 1]; }; const getNextId = () => { const currFocusedNodeId = getCurrFocusedNodeId(); let nodeInfo = getNode(currFocusedNodeId); if (nodeInfo.hasChildren && isExpanded(nodeInfo)) { const expandIds = getChildrenIds(nodeInfo.id, true); if (expandIds.length > 0) { return expandIds[0]; } } while (nodeInfo) { const siblings = getChildrenIds(nodeInfo.parentId, true); const nextId = siblings[siblings.indexOf(nodeInfo.id) + 1]; if (nextId) { return nextId; } nodeInfo = getNode(nodeInfo.parentId); } return null; }; const getExpandLastId = (prevNode) => { if (prevNode.hasChildren && isExpanded(prevNode)) { const siblings = getChildrenIds(prevNode.id, true); if (siblings.length == 0) { return prevNode?.id; } const prevId = siblings[siblings.length - 1]; return getExpandLastId(getNode(prevId)); } return prevNode?.id; }; const getPrevId = () => { const currFocusedNodeId = getCurrFocusedNodeId(); let nodeInfo = getNode(currFocusedNodeId); let siblings = getChildrenIds(nodeInfo.parentId, true); let prevId = siblings[siblings.indexOf(nodeInfo.id) - 1]; const prevNode = getNode(prevId); if (!prevNode) { return nodeInfo.parentId; } return getExpandLastId(prevNode); }; const openSub = () => { const currFocusedNodeId = getCurrFocusedNodeId(); let nodeInfo = getNode(currFocusedNodeId); if (nodeInfo.hasChildren) { const subIsOpen = openIds.includes(currFocusedNodeId); onInternalOpenChange(currFocusedNodeId, !subIsOpen, (0, utils_1.getNodeIdPaths)(nodeInfo, getNode)); if (mode != "inline" && !subIsOpen) { //auto focus to first node let childIds = getChildrenIds(nodeInfo.id, true); setFocusedNodeId(childIds[0]); } } }; const closeSub = () => { const currFocusedNodeId = getCurrFocusedNodeId(); const nodeInfo = getNode(currFocusedNodeId); const parentNode = getNode(nodeInfo.parentId); if (parentNode && parentNode.hasChildren) { onInternalOpenChange(parentNode.id, false, (0, utils_1.getNodeIdPaths)(parentNode, getNode)); setFocusedNodeId(nodeInfo.parentId); } }; const handleKeyDown = (event) => { const key = event.key; event.preventDefault(); event.stopPropagation(); const currFocusedNodeId = getCurrFocusedNodeId(); const nodeInfo = getNode(currFocusedNodeId); switch (key) { case "ArrowUp": { setFocusedNodeId(getPrevId()); return; } case "ArrowDown": setFocusedNodeId(getNextId()); return; case "ArrowRight": mode != "inline" && openSub(); return; case "ArrowLeft": case "Escape": mode != "inline" && closeSub(); return; case "Enter": openSub(); if (!nodeInfo.hasChildren) { onSelectedChange((0, utils_1.getNodeIdPaths)(nodeInfo, getNode), false); onItemClick && onItemClick(nodeInfo.id, (0, utils_1.getNodeIdPaths)(nodeInfo, getNode), event, nodeInfo.link); } return; } }; return { handleKeyDown }; }; exports.default = useKeyboardNavigation;