UI: support folder groups on sidebar tabs

This commit is contained in:
Fuma Nama
2024-11-23 09:20:51 +08:00
parent f8e5157217
commit ad00dd39e0
3 changed files with 35 additions and 12 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'fumadocs-ui': patch
---
Support folder groups on sidebar tabs
@@ -7,6 +7,8 @@ import { cn } from '@/utils/cn';
import { isActive } from '@/utils/is-active';
import { useSidebar } from '@/contexts/sidebar';
import { Popover, PopoverContent, PopoverTrigger } from '../ui/popover';
import type { PageTree } from 'fumadocs-core/server';
import { useTreePath } from '@/contexts/tree';
export interface Option {
/**
@@ -18,6 +20,11 @@ export interface Option {
title: ReactNode;
description?: ReactNode;
/**
* Detect from page tree nodes
*/
folder?: PageTree.Folder;
props?: HTMLAttributes<HTMLElement>;
}
@@ -30,9 +37,15 @@ export function RootToggle({
const [open, setOpen] = useState(false);
const { closeOnRedirect } = useSidebar();
const pathname = usePathname();
const path = useTreePath();
const selected = useMemo(() => {
return options.find((item) => isActive(item.url, pathname, true));
}, [options, pathname]);
return options.findLast((item) =>
item.folder
? path.includes(item.folder)
: isActive(item.url, pathname, true),
);
}, [path, options, pathname]);
const onClick = () => {
closeOnRedirect.current = false;
+15 -10
View File
@@ -11,17 +11,22 @@ export function getSidebarTabs(
): Option[] {
const options: Option[] = [];
function traverse(node: PageTree.Node): void {
if (node.type === 'folder' && node.root && node.index) {
const option: Option = {
url: node.index.url,
title: node.name,
icon: node.icon,
description: node.description,
};
function traverse(node: PageTree.Node) {
if (node.type === 'folder' && node.root) {
const index = node.index ?? node.children.at(0);
const mapped = transform ? transform(option, node) : option;
if (mapped) options.push(mapped);
if (index?.type === 'page') {
const option: Option = {
url: index.url,
title: node.name,
icon: node.icon,
folder: node,
description: node.description,
};
const mapped = transform ? transform(option, node) : option;
if (mapped) options.push(mapped);
}
}
if (node.type === 'folder') node.children.forEach(traverse);