shelving
Version:
Toolkit for using data in JavaScript.
34 lines (33 loc) • 2 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import { NotFoundError } from "../../error/RequestError.js";
import { resolveElementPath } from "../../util/element.js";
import { splitPath } from "../../util/path.js";
import { DirectoryPage } from "../docs/DirectoryPage.js";
import { DocumentationPage } from "../docs/DocumentationPage.js";
import { FilePage } from "../docs/FilePage.js";
import { createMapper } from "../misc/Mapper.js";
import { MetaContext, requireMetaURL } from "../misc/MetaContext.js";
/** Mapping + Mapper pair for tree routers — wrap children in `<TreeRouterMapping>` to override. */
export const [TreeRouterMapping, TreeRouterMapper] = createMapper({
"tree-directory": DirectoryPage,
"tree-file": FilePage,
"tree-documentation": DocumentationPage,
});
/**
* Resolve a URL path to a tree element and render it as a full page.
* - Walks the tree by matching each path segment to a descendant's `key` (via `resolveElementPath()`).
* - `/` renders the root itself; deeper paths render the matching descendant.
* - `path` is the site-root-relative path (already stripped of any `APP_URL` subfolder by `<Router>`); it is threaded to the page renderer so child cards build correct hrefs.
* - Throws `NotFoundError` if no element matches at any level.
* - To override the renderer for a specific element type, wrap in `<TreeRouterMapping mapping={…}>`.
*/
export function TreeRouter({ tree, fallback, ...meta }) {
const { path, ...combined } = requireMetaURL(meta);
// Find a `TreeElement` matching the current URL meta path.
const element = resolveElementPath(tree, splitPath(path));
// We render either a mapped version of the tree element, or the fallback element.
const route = element ? _jsx(TreeRouterMapper, { path: path, children: element }) : fallback;
if (route !== undefined)
return _jsx(MetaContext, { value: combined, children: route });
throw new NotFoundError("Tree route not found", { received: path });
}