UNPKG

fumadocs-ui

Version:

The framework for building a documentation website in Next.js

61 lines (60 loc) 6.94 kB
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; import { useMemo, } from 'react'; import { Languages, Sidebar as SidebarIcon } from '../icons.js'; import { cn } from '../utils/cn.js'; import { buttonVariants } from '../components/ui/button.js'; import { Sidebar, SidebarCollapseTrigger, SidebarContent, SidebarContentMobile, SidebarFooter, SidebarHeader, SidebarPageTree, SidebarTrigger, SidebarViewport, } from '../components/layout/sidebar.js'; import { BaseLinkItem, } from '../layouts/links.js'; import { RootToggle } from '../components/layout/root-toggle.js'; import { getLinks } from './shared.js'; import { LanguageToggle, LanguageToggleText, } from '../components/layout/language-toggle.js'; import { CollapsibleControl, LayoutBody, Navbar } from '../layouts/docs-client.js'; import { TreeContextProvider } from '../contexts/tree.js'; import { ThemeToggle } from '../components/layout/theme-toggle.js'; import { getSidebarTabsFromOptions, SidebarLinkItem, } from '../layouts/docs/shared.js'; import { NavProvider } from '../contexts/layout.js'; import Link from 'fumadocs-core/link'; import { LargeSearchToggle, SearchToggle, } from '../components/layout/search-toggle.js'; import { HideIfEmpty } from 'fumadocs-core/hide-if-empty'; export function DocsLayout({ nav: { transparentMode, ...nav } = {}, sidebar: { tabs: sidebarTabs, enabled: sidebarEnabled = true, ...sidebarProps } = {}, searchToggle = {}, disableThemeSwitch = false, themeSwitch = { enabled: !disableThemeSwitch }, i18n = false, children, ...props }) { const tabs = useMemo(() => getSidebarTabsFromOptions(sidebarTabs, props.tree) ?? [], [sidebarTabs, props.tree]); const links = getLinks(props.links ?? [], props.githubUrl); const sidebarVariables = cn('md:[--fd-sidebar-width:268px] lg:[--fd-sidebar-width:286px]'); function sidebar() { const { footer, banner, collapsible = true, component, components, defaultOpenLevel, prefetch, ...rest } = sidebarProps; if (component) return component; const iconLinks = links.filter((item) => item.type === 'icon'); const viewport = (_jsxs(SidebarViewport, { children: [links .filter((v) => v.type !== 'icon') .map((item, i, list) => (_jsx(SidebarLinkItem, { item: item, className: cn(i === list.length - 1 && 'mb-4') }, i))), _jsx(SidebarPageTree, { components: components })] })); const mobile = (_jsxs(SidebarContentMobile, { ...rest, children: [_jsxs(HideIfEmpty, { as: SidebarHeader, children: [_jsxs("div", { className: "flex text-fd-muted-foreground items-center justify-end empty:hidden", children: [iconLinks.map((item, i) => (_jsx(BaseLinkItem, { item: item, className: cn(buttonVariants({ size: 'icon-sm', color: 'ghost', className: 'p-2', }), i === iconLinks.length - 1 && 'me-auto'), "aria-label": item.label, children: item.icon }, i))), i18n ? (_jsxs(LanguageToggle, { children: [_jsx(Languages, { className: "size-4.5" }), _jsx(LanguageToggleText, {})] })) : null, themeSwitch.enabled !== false && (themeSwitch.component ?? (_jsx(ThemeToggle, { className: "p-0 ms-1.5", mode: themeSwitch.mode }))), _jsx(SidebarTrigger, { className: cn(buttonVariants({ color: 'ghost', size: 'icon-sm', className: 'p-2 ms-1.5', })), children: _jsx(SidebarIcon, {}) })] }), tabs.length > 0 && _jsx(RootToggle, { options: tabs }), banner] }), viewport, _jsx(SidebarFooter, { className: "empty:hidden", children: footer })] })); const content = (_jsxs(SidebarContent, { ...rest, children: [_jsxs(SidebarHeader, { children: [_jsxs("div", { className: "flex", children: [_jsx(Link, { href: nav.url ?? '/', className: "inline-flex text-[15px] items-center gap-2.5 font-medium me-auto", children: nav.title }), nav.children, collapsible && (_jsx(SidebarCollapseTrigger, { className: cn(buttonVariants({ color: 'ghost', size: 'icon-sm', className: 'mb-auto text-fd-muted-foreground', })), children: _jsx(SidebarIcon, {}) }))] }), searchToggle.enabled !== false && (searchToggle.components?.lg ?? (_jsx(LargeSearchToggle, { hideIfDisabled: true }))), tabs.length > 0 && _jsx(RootToggle, { options: tabs }), banner] }), viewport, _jsxs(HideIfEmpty, { as: SidebarFooter, children: [_jsxs("div", { className: "flex text-fd-muted-foreground items-center justify-end empty:hidden", children: [iconLinks.map((item, i) => (_jsx(BaseLinkItem, { item: item, className: cn(buttonVariants({ size: 'icon-sm', color: 'ghost' }), i === iconLinks.length - 1 && 'me-auto'), "aria-label": item.label, children: item.icon }, i))), i18n ? (_jsx(LanguageToggle, { children: _jsx(Languages, { className: "size-4.5" }) })) : null, themeSwitch.enabled !== false && (themeSwitch.component ?? (_jsx(ThemeToggle, { className: "p-0 ms-1.5", mode: themeSwitch.mode })))] }), footer] })] })); return (_jsx(Sidebar, { defaultOpenLevel: defaultOpenLevel, prefetch: prefetch, Mobile: mobile, Content: _jsxs(_Fragment, { children: [collapsible && _jsx(CollapsibleControl, {}), content] }) })); } return (_jsx(TreeContextProvider, { tree: props.tree, children: _jsxs(NavProvider, { transparentMode: transparentMode, children: [nav.enabled !== false && (nav.component ?? (_jsxs(Navbar, { className: "h-14 md:hidden", children: [_jsx(Link, { href: nav.url ?? '/', className: "inline-flex items-center gap-2.5 font-semibold", children: nav.title }), _jsx("div", { className: "flex-1", children: nav.children }), searchToggle.enabled !== false && (searchToggle.components?.sm ?? (_jsx(SearchToggle, { className: "p-2", hideIfDisabled: true }))), sidebarEnabled && (_jsx(SidebarTrigger, { className: cn(buttonVariants({ color: 'ghost', size: 'icon-sm', className: 'p-2', })), children: _jsx(SidebarIcon, {}) }))] }))), _jsxs(LayoutBody, { ...props.containerProps, className: cn('xl:[--fd-toc-width:286px]', sidebarEnabled && sidebarVariables, !nav.component && nav.enabled !== false && '[--fd-nav-height:56px] md:[--fd-nav-height:0px]', props.containerProps?.className), children: [sidebarEnabled && sidebar(), children] })] }) })); } export { CollapsibleControl, Navbar, SidebarTrigger };