UNPKG

shelving

Version:

Toolkit for using data in JavaScript.

45 lines (44 loc) 2.33 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { filterElements } from "../../util/element.js"; import { joinPath } from "../../util/path.js"; import { Menu } from "../menu/Menu.js"; import { MenuItem } from "../menu/MenuItem.js"; import { createMapper } from "../misc/Mapper.js"; /** * Match an element that should appear in the sidebar menu. * - Directories and plain files always qualify. * - For documentation elements, only `kind: "module"` qualifies — functions, classes, methods, properties, etc. are kept off the navigation. */ export function matchMenuElement(element) { const { type, props } = element; if (type === "tree-directory" || type === "tree-file") return true; if (type === "tree-documentation") return props.kind === "module"; return false; } /** * Default menu item renderer for any `tree-*` element. * - Computes its own URL path by appending its `name` to the parent's `path`. * - Passes both the label and the nested `<TreeMenuMapper>` to `<MenuItem>`; `<MenuItem>` itself decides whether to reveal the nested submenu based on the current URL. */ export function TreeMenuItem({ path = "/", name, title, children }) { const href = joinPath(path, name); const submenu = Array.from(filterElements(children, matchMenuElement)); return (_jsxs(MenuItem, { href: href, children: [title ?? name, submenu.length ? (_jsx(Menu, { children: _jsx(TreeMenuMapper, { path: href, children: submenu }) })) : null] })); } /** Mapping + Mapper pair for the menu — wrap children in `<TreeMenuMapping>` to override. */ export const [TreeMenuMapping, TreeMenuMapper] = createMapper({ "tree-directory": TreeMenuItem, "tree-file": TreeMenuItem, "tree-documentation": TreeMenuItem, }); /** * Sidebar navigation menu built from the children of a root tree element. * - Renders each child via `<TreeMenuItem>` (the default mapping for `tree-directory` / `tree-file`). * - To customise renderers for specific types, wrap in `<TreeMenuMapping mapping={…}>`. * - Only directories and files appear — code symbols are kept off the navigation. */ export function TreeMenu({ path = "/", tree }) { return (_jsx(Menu, { children: _jsx(TreeMenuMapper, { path: path, children: filterElements(tree.props.children, matchMenuElement) }) })); }