fumadocs-core
Version:
The library for building a documentation website in any React.js framework
98 lines (96 loc) • 2.62 kB
JavaScript
// src/page-tree/utils.ts
function flattenTree(nodes) {
const out = [];
for (const node of nodes) {
if (node.type === "folder") {
if (node.index) out.push(node.index);
out.push(...flattenTree(node.children));
} else if (node.type === "page") {
out.push(node);
}
}
return out;
}
function findNeighbour(tree, url, options) {
const { separateRoot = true } = options ?? {};
const roots = separateRoot ? getPageTreeRoots(tree) : [tree];
if (tree.fallback) roots.push(tree.fallback);
for (const root of roots) {
const list = flattenTree(root.children);
const idx = list.findIndex((item) => item.url === url);
if (idx === -1) continue;
return {
previous: list[idx - 1],
next: list[idx + 1]
};
}
return {};
}
function getPageTreeRoots(pageTree) {
const result = pageTree.children.flatMap((child) => {
if (child.type !== "folder") return [];
const roots = getPageTreeRoots(child);
if (child.root) roots.push(child);
return roots;
});
if (!("type" in pageTree)) result.push(pageTree);
return result;
}
function getPageTreePeers(tree, url) {
const parent = findParentFromTree(tree, url);
if (!parent) return [];
return parent.children.filter(
(item) => item.type === "page" && item.url !== url
);
}
function findParentFromTree(node, url) {
if ("index" in node && node.index?.url === url) {
return node;
}
for (const child of node.children) {
if (child.type === "folder") {
const parent = findParentFromTree(child, url);
if (parent) return parent;
}
if (child.type === "page" && child.url === url) {
return node;
}
}
if ("fallback" in node && node.fallback) {
return findParentFromTree(node.fallback, url);
}
}
function findPath(nodes, matcher, options = {}) {
const { includeSeparator = true } = options;
function run(nodes2) {
let separator;
for (const node of nodes2) {
if (matcher(node)) {
const items = [];
if (separator) items.push(separator);
items.push(node);
return items;
}
if (node.type === "separator" && includeSeparator) {
separator = node;
continue;
}
if (node.type === "folder") {
const items = node.index && matcher(node.index) ? [node.index] : run(node.children);
if (items) {
items.unshift(node);
if (separator) items.unshift(separator);
return items;
}
}
}
}
return run(nodes) ?? null;
}
export {
flattenTree,
findNeighbour,
getPageTreeRoots,
getPageTreePeers,
findPath
};