@gpm-lds-astro/components
Version:
Components of the LDS Astro template.
107 lines (81 loc) • 2.86 kB
text/typescript
import type { MarkdownInstance } from 'astro';
import type { LeftSidebarNode, LeftSidebarSectionItem } from '../types';
import { findPage } from '../utils';
export function generateTree(items: LeftSidebarSectionItem[], pages: MarkdownInstance<any>[]) {
const tree: any = {};
items.forEach(item => {
const pathSplitted = item.path.split('/');
const firstEl = pathSplitted[0]!;
const splittedHref = item.href.split('/');
splittedHref.pop();
let parentItem;
if (pathSplitted.length > 1) {
const parentHref = splittedHref.join('/');
parentItem = items.find(item => item.href === parentHref);
} else {
parentItem = item;
}
if (!tree[firstEl]) {
tree[firstEl] = {
children: [],
item: parentItem,
};
}
if (pathSplitted.length > 1) {
item = { ...item };
item.path = pathSplitted.slice(1).join('/');
tree[firstEl].children.push(item);
}
});
for (let node in tree) {
tree[node].children = generateTree(tree[node].children, pages);
}
return tree;
}
export function transformTree(tree: any, currentId: { id: number }, nodes: LeftSidebarNode[], depth: number): number[] | undefined {
const newNodes: any[] = [];
for (let subPath in tree) {
const nodesToAssign = transformTree(tree[subPath].children, currentId, nodes, depth + 1);
const item = tree[subPath].item;
const node: LeftSidebarNode = {
label: item?.label || subPath,
id: currentId.id++,
depth: depth,
nodes: nodesToAssign,
type: nodesToAssign ? 'branch' : 'item',
href: item?.href || null,
};
nodes.push(node);
newNodes.push(node);
}
return newNodes.length ? newNodes.map(n => n.id) : undefined;
}
export function getSidebarSectionsDictionary(currentDirectoryPages: MarkdownInstance<any>[], pathname: string) {
const dictionary = currentDirectoryPages.reduce((dic: Record<string, any>, page: any) => {
const { url, frontmatter } = page;
const { sidebarLabel } = frontmatter || {};
const urlWithoutBase = url.replace(RegExp(`${pathname}\/?`, 'g'), '');
if (!urlWithoutBase) return dic;
const urlSplitted = urlWithoutBase.split('/');
const sectionKey = urlSplitted[0] as string;
const path = urlSplitted.join('/');
const lastUrlElement = urlSplitted[urlSplitted.length - 1];
const item = {
href: url,
label: sidebarLabel || lastUrlElement,
path,
};
const items = dic[sectionKey] ? [...dic[sectionKey].items!, item] : [item];
// Heading
const sectionPage = findPage(currentDirectoryPages, `${pathname}/${sectionKey}`);
const heading = sectionPage?.frontmatter.sectionLabel || sectionKey;
return {
...dic,
[sectionKey]: {
heading,
items,
},
};
}, {});
return dictionary;
}