@alauda/doom
Version:
Doctor Doom making docs.
119 lines (118 loc) • 6.34 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { isEqualPath, usePage, usePages, useSidebar, } from '@rspress/core/runtime';
import { FallbackHeading, Link, renderInlineMarkdown, } from '@rspress/core/theme-original';
import { Fragment, useCallback, useMemo } from 'react';
import classes from '../../../styles/overview.module.scss';
import { Masonry } from './Masonry.js';
import { findItemByRoutePath, isSidebarDivider, isSidebarSectionHeader, isSingleFile, } from './_utils.js';
const getChildLink = (traverseItem) => {
if ('link' in traverseItem && traverseItem.link) {
return traverseItem.link;
}
if ('items' in traverseItem && traverseItem.items.length) {
return getChildLink(traverseItem.items[0]);
}
return '';
};
const masonryOptions = {
itemSelector: `.masonry-item`,
gutter: 16,
};
// The sidebar data include two types: sidebar item and sidebar group.
// In overpage page, we select all the related sidebar groups and show the groups in the page.
// In the meantime, some sidebar items also should be shown in the page, we collect them in the group named 'Others' and show them in the page.
export function Overview(props) {
const { pages } = usePages();
const { page: { routePath, frontmatter, title }, } = usePage();
const { content, groups: customGroups, defaultGroupTitle = 'Others' } = props;
const subFilter = useCallback((link) => link.startsWith(routePath.replace(/overview$/, '')) &&
!isEqualPath(link, routePath), [routePath]);
const overviewModules = useMemo(() => pages.filter((page) => subFilter(page.routePath)), [pages, subFilter]);
let overviewSidebarGroups = useSidebar();
if (overviewSidebarGroups[0] &&
'link' in overviewSidebarGroups[0] &&
overviewSidebarGroups[0].link !== routePath) {
overviewSidebarGroups = findItemByRoutePath(overviewSidebarGroups, routePath);
}
const normalizeSidebarItem = useCallback((item, sidebarGroup, frontmatter) => {
if (isSidebarDivider(item) || isSidebarSectionHeader(item)) {
return false;
}
// do not display overview title in sub pages overview
if (item.link === `${routePath}index` && frontmatter?.overview === true) {
return false;
}
// props > frontmatter in single file > _meta.json config in a file > frontmatter in overview page > _meta.json config in sidebar
const overviewHeaders = props.overviewHeaders ??
item.overviewHeaders ??
frontmatter?.overviewHeaders ??
sidebarGroup?.overviewHeaders ?? [2];
// sidebar items link without base path
const pageModule = overviewModules.find((m) => isEqualPath(m.routePath, item.link || ''));
const link = getChildLink(item);
return {
...item,
description: pageModule?.frontmatter.description,
link,
headers: pageModule?.toc.filter((header) => overviewHeaders.some((depth) => header.depth === depth)) || [],
};
}, [overviewModules, props.overviewHeaders, routePath]);
const getGroup = useCallback((sidebarGroups) => {
const group = sidebarGroups
.filter((sidebarGroup) => {
if ('items' in sidebarGroup) {
return (sidebarGroup.items.filter((item) => subFilter(getChildLink(item)))
.length > 0);
}
if (isSingleFile(sidebarGroup) &&
subFilter(getChildLink(sidebarGroup))) {
return true;
}
return false;
})
.map((sidebarGroup) => {
let items = [];
if ('items' in sidebarGroup) {
items = sidebarGroup.items
.map((item) => normalizeSidebarItem(item, sidebarGroup, frontmatter))
.filter(Boolean);
}
else if (isSingleFile(sidebarGroup)) {
items = [
normalizeSidebarItem({
link: sidebarGroup.link,
text: sidebarGroup.text || '',
tag: sidebarGroup.tag,
_fileKey: sidebarGroup._fileKey,
overviewHeaders: sidebarGroup.overviewHeaders,
}, undefined, frontmatter),
].filter(Boolean);
}
return {
name: ('text' in sidebarGroup && sidebarGroup.text) || '',
items,
};
});
return group;
}, [frontmatter, normalizeSidebarItem, subFilter]);
const defaultGroups = useMemo(() => {
const group = getGroup(overviewSidebarGroups);
if (group.length) {
return group;
}
for (const sidebarGroup of overviewSidebarGroups) {
if (!('items' in sidebarGroup)) {
continue;
}
const group = getGroup(sidebarGroup.items);
if (group.length) {
return group;
}
}
return [];
}, [getGroup, overviewSidebarGroups]);
const groups = customGroups ?? defaultGroups;
return (_jsxs("div", { className: "overview-index doom-overview-index", children: [content, groups.map((group) => (_jsxs(Fragment, { children: [(!title || [title, defaultGroupTitle].includes(group.name)) &&
groups.length === 1 ? (_jsx("h2", { style: { paddingTop: 0 } })) : (_jsx(FallbackHeading, { level: 2, title: group.name })), _jsx(Masonry, { className: classes.overviewGroups, options: masonryOptions, children: group.items.map((item) => (_jsxs("div", { className: `${classes.overviewGroup} masonry-item`, children: [_jsx("h3", { children: _jsx(Link, { href: item.link, ...renderInlineMarkdown(item.text) }) }), item.description && (_jsx("div", { className: classes.overviewDescription, children: item.description })), !item.headers?.length || (_jsx("ul", { className: classes.overviewList, children: item.headers.map((header) => (_jsx("li", { className: `${classes.overviewGroupLi} ${classes[`level${header.depth}`]}`, children: _jsx(Link, { href: `${item.link}#${header.id}`, ...renderInlineMarkdown(header.text) }) }, header.id))) }))] }, item.link))) })] }, group.name)))] }));
}
export default Overview;