mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-25 04:20:02 +00:00
UI: Improve theme toggle on Notebook layout
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'fumadocs-ui': patch
|
||||
---
|
||||
|
||||
Improve theme toggle on Notebook layout
|
||||
@@ -1,4 +1,4 @@
|
||||
import { DocsLayout, type DocsLayoutProps } from 'fumadocs-ui/layouts/docs';
|
||||
import { DocsLayout, type DocsLayoutProps } from 'fumadocs-ui/layouts/notebook';
|
||||
import type { ReactNode } from 'react';
|
||||
import { MessageCircle } from 'lucide-react';
|
||||
import { baseOptions, linkItems } from '@/app/layout.config';
|
||||
|
||||
@@ -19,7 +19,6 @@ import {
|
||||
type IconItemType,
|
||||
BaseLinkItem,
|
||||
} from '@/layouts/links';
|
||||
import { getSidebarTabs, type TabOptions } from '@/utils/get-sidebar-tabs';
|
||||
import { RootToggle } from '@/components/layout/root-toggle';
|
||||
import { type BaseLayoutProps, getLinks } from './shared';
|
||||
import {
|
||||
@@ -268,4 +267,5 @@ function SidebarFooterItems({
|
||||
);
|
||||
}
|
||||
|
||||
export { getSidebarTabs, type TabOptions, type LinkItemType };
|
||||
export { getSidebarTabsFromOptions, type TabOptions } from './docs/shared';
|
||||
export { type LinkItemType };
|
||||
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
import { cn } from '@/utils/cn';
|
||||
import { buttonVariants } from '@/components/ui/button';
|
||||
import type { PageTree } from 'fumadocs-core/server';
|
||||
import { getSidebarTabs, type TabOptions } from '@/utils/get-sidebar-tabs';
|
||||
import type { FC, ReactNode } from 'react';
|
||||
import type { Option } from '@/components/layout/root-toggle';
|
||||
|
||||
@@ -18,6 +17,10 @@ export const layoutVariables = {
|
||||
'--fd-layout-offset': 'max(calc(50vw - var(--fd-layout-width) / 2), 0px)',
|
||||
};
|
||||
|
||||
export interface TabOptions {
|
||||
transform?: (option: Option, node: PageTree.Folder) => Option | null;
|
||||
}
|
||||
|
||||
export interface SidebarOptions extends SidebarProps {
|
||||
enabled: boolean;
|
||||
component: ReactNode;
|
||||
@@ -108,3 +111,63 @@ export function getSidebarTabsFromOptions(
|
||||
return getSidebarTabs(tree);
|
||||
}
|
||||
}
|
||||
|
||||
const defaultTransform: TabOptions['transform'] = (option, node) => {
|
||||
if (!node.icon) return option;
|
||||
|
||||
return {
|
||||
...option,
|
||||
icon: (
|
||||
<div className="rounded-md border bg-fd-secondary p-1 shadow-md [&_svg]:size-5">
|
||||
{node.icon}
|
||||
</div>
|
||||
),
|
||||
};
|
||||
};
|
||||
|
||||
function getSidebarTabs(
|
||||
pageTree: PageTree.Root,
|
||||
{ transform = defaultTransform }: TabOptions = {},
|
||||
): Option[] {
|
||||
function findOptions(node: PageTree.Folder): Option[] {
|
||||
const results: Option[] = [];
|
||||
|
||||
if (node.root) {
|
||||
const index = node.index ?? node.children.at(0);
|
||||
|
||||
if (index?.type === 'page') {
|
||||
const option: Option = {
|
||||
url: index.url,
|
||||
title: node.name,
|
||||
icon: node.icon,
|
||||
description: node.description,
|
||||
|
||||
urls: getFolderUrls(node),
|
||||
};
|
||||
|
||||
const mapped = transform ? transform(option, node) : option;
|
||||
if (mapped) results.push(mapped);
|
||||
}
|
||||
}
|
||||
|
||||
for (const child of node.children) {
|
||||
if (child.type === 'folder') results.push(...findOptions(child));
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
return findOptions(pageTree as PageTree.Folder);
|
||||
}
|
||||
|
||||
function getFolderUrls(folder: PageTree.Folder): string[] {
|
||||
const results: string[] = [];
|
||||
if (folder.index) results.push(folder.index.url);
|
||||
|
||||
for (const child of folder.children) {
|
||||
if (child.type === 'page') results.push(child.url);
|
||||
if (child.type === 'folder') results.push(...getFolderUrls(child));
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
@@ -125,7 +125,12 @@ export function DocsLayout({
|
||||
<SidebarPageTree components={sidebarComponents} />
|
||||
</div>
|
||||
</SidebarViewport>
|
||||
<SidebarFooter>{sidebarFooter}</SidebarFooter>
|
||||
<SidebarFooter className={cn(!sidebarFooter && 'md:hidden')}>
|
||||
{!props.disableThemeSwitch ? (
|
||||
<ThemeToggle className="w-fit md:hidden" />
|
||||
) : null}
|
||||
{sidebarFooter}
|
||||
</SidebarFooter>
|
||||
</Aside>
|
||||
<DocsNavbar
|
||||
nav={nav}
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
import type { PageTree } from 'fumadocs-core/server';
|
||||
import type { Option } from '@/components/layout/root-toggle';
|
||||
|
||||
export interface TabOptions {
|
||||
transform?: (option: Option, node: PageTree.Folder) => Option | null;
|
||||
}
|
||||
|
||||
const defaultTransform: TabOptions['transform'] = (option, node) => {
|
||||
if (!node.icon) return option;
|
||||
|
||||
return {
|
||||
...option,
|
||||
icon: (
|
||||
<div className="rounded-md border bg-fd-secondary p-1 shadow-md [&_svg]:size-5">
|
||||
{node.icon}
|
||||
</div>
|
||||
),
|
||||
};
|
||||
};
|
||||
|
||||
export function getSidebarTabs(
|
||||
pageTree: PageTree.Root,
|
||||
{ transform = defaultTransform }: TabOptions = {},
|
||||
): Option[] {
|
||||
function findOptions(node: PageTree.Folder): Option[] {
|
||||
const results: Option[] = [];
|
||||
|
||||
if (node.root) {
|
||||
const index = node.index ?? node.children.at(0);
|
||||
|
||||
if (index?.type === 'page') {
|
||||
const option: Option = {
|
||||
url: index.url,
|
||||
title: node.name,
|
||||
icon: node.icon,
|
||||
description: node.description,
|
||||
|
||||
urls: getFolderUrls(node),
|
||||
};
|
||||
|
||||
const mapped = transform ? transform(option, node) : option;
|
||||
if (mapped) results.push(mapped);
|
||||
}
|
||||
}
|
||||
|
||||
for (const child of node.children) {
|
||||
if (child.type === 'folder') results.push(...findOptions(child));
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
return findOptions(pageTree as PageTree.Folder);
|
||||
}
|
||||
|
||||
function getFolderUrls(folder: PageTree.Folder): string[] {
|
||||
const results: string[] = [];
|
||||
if (folder.index) results.push(folder.index.url);
|
||||
|
||||
for (const child of folder.children) {
|
||||
if (child.type === 'page') results.push(child.url);
|
||||
if (child.type === 'folder') results.push(...getFolderUrls(child));
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
Reference in New Issue
Block a user