UNPKG

@etsoo/toolpad

Version:

Dashboard framework extention based on Toolpad Core

145 lines (144 loc) 5.27 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getItemTitle = exports.isPageItem = exports.getItemKind = void 0; exports.getPageItemFullPath = getPageItemFullPath; exports.isPageItemSelected = isPageItemSelected; exports.hasSelectedNavigationChildren = hasSelectedNavigationChildren; exports.matchPath = matchPath; exports.getItemPath = getItemPath; const path_to_regexp_1 = require("path-to-regexp"); const invariant_1 = __importDefault(require("invariant")); const getItemKind = (item) => item.kind ?? "page"; exports.getItemKind = getItemKind; const isPageItem = (item) => (0, exports.getItemKind)(item) === "page"; exports.isPageItem = isPageItem; const getItemTitle = (item) => { return (0, exports.isPageItem)(item) ? item.title ?? item.segment ?? "" : item.title; }; exports.getItemTitle = getItemTitle; function getPageItemFullPath(basePath, navigationItem) { return `${basePath}${basePath && !navigationItem.segment ? "" : "/"}${navigationItem.segment ?? ""}`; } function isPageItemSelected(navigationItem, basePath, pathname) { if (navigationItem.pattern) { return (0, path_to_regexp_1.pathToRegexp)(`${basePath}/${navigationItem.pattern}`).test(pathname); } return getPageItemFullPath(basePath, navigationItem) === pathname; } function hasSelectedNavigationChildren(navigationItem, basePath, pathname) { if ((0, exports.isPageItem)(navigationItem) && navigationItem.children) { const navigationItemFullPath = getPageItemFullPath(basePath, navigationItem); return navigationItem.children.some((nestedNavigationItem) => { if (!(0, exports.isPageItem)(nestedNavigationItem)) { return false; } if (nestedNavigationItem.children) { return hasSelectedNavigationChildren(nestedNavigationItem, navigationItemFullPath, pathname); } return isPageItemSelected(nestedNavigationItem, navigationItemFullPath, pathname); }); } return false; } /** * Builds a map of navigation page items to their respective paths. This map is used to quickly * lookup the path of a navigation item. It will be cached for the lifetime of the navigation. */ function buildItemToPathMap(navigation) { const map = new Map(); const visit = (item, base) => { if ((0, exports.isPageItem)(item)) { const path = `${base}${item.segment ? `/${item.segment}` : ""}` || "/"; map.set(item, path); if (item.children) { for (const child of item.children) { visit(child, path); } } } }; for (const item of navigation) { visit(item, ""); } return map; } const itemToPathMapCache = new WeakMap(); /** * Gets the cached map of navigation page items to their respective paths. */ function getItemToPathMap(navigation) { let map = itemToPathMapCache.get(navigation); if (!map) { map = buildItemToPathMap(navigation); itemToPathMapCache.set(navigation, map); } return map; } /** * Build a lookup map of paths to navigation items. This map is used to match paths against * to find the active page. */ function buildItemLookup(navigation) { const map = new Map(); const visit = (item) => { if ((0, exports.isPageItem)(item)) { const path = getItemPath(navigation, item); if (map.has(path)) { console.warn(`Duplicate path in navigation: ${path}`); } map.set(path, item); if (item.pattern) { const basePath = item.segment ? path.slice(0, -item.segment.length) : path; map.set((0, path_to_regexp_1.pathToRegexp)(basePath + item.pattern), item); } if (item.children) { for (const child of item.children) { visit(child); } } } }; for (const item of navigation) { visit(item); } return map; } const itemLookupMapCache = new WeakMap(); function getItemLookup(navigation) { let map = itemLookupMapCache.get(navigation); if (!map) { map = buildItemLookup(navigation); itemLookupMapCache.set(navigation, map); } return map; } /** * Matches a path against the navigation to find the active page. i.e. the page that should be * marked as selected in the navigation. */ function matchPath(navigation, path) { const lookup = getItemLookup(navigation); for (const [key, item] of lookup.entries()) { if (typeof key === "string" && key === path) { return item; } if (key instanceof RegExp && key.test(path)) { return item; } } return null; } /** * Gets the path for a specific navigation page item. */ function getItemPath(navigation, item) { const map = getItemToPathMap(navigation); const path = map.get(item); (0, invariant_1.default)(path, `Item not found in navigation: ${item.title}`); return path; }