UNPKG

fumadocs-ui

Version:

The framework for building a documentation website in Next.js

53 lines (52 loc) 3 kB
'use client'; import { jsx as _jsx } from "react/jsx-runtime"; import { cn } from '../utils/cn.js'; import { useMemo } from 'react'; import { useSidebar } from '../contexts/sidebar.js'; import { useNav } from '../contexts/layout.js'; import { buttonVariants } from '../components/ui/button.js'; import { Sidebar as SidebarIcon } from '../icons.js'; import Link from 'fumadocs-core/link'; import { usePathname } from 'fumadocs-core/framework'; import { isActive } from '../utils/is-active.js'; export function Navbar({ mode, ...props }) { const { open, collapsed } = useSidebar(); const { isTransparent } = useNav(); return (_jsx("header", { id: "nd-subnav", ...props, className: cn('fixed flex flex-col inset-x-0 top-(--fd-banner-height) z-10 px-(--fd-layout-offset) h-(--fd-nav-height) backdrop-blur-sm transition-colors', (!isTransparent || open) && 'bg-fd-background/80', mode === 'auto' && !collapsed && 'ps-[calc(var(--fd-layout-offset)+var(--fd-sidebar-width))]', props.className), children: props.children })); } export function LayoutBody(props) { const { collapsed } = useSidebar(); return (_jsx("main", { id: "nd-docs-layout", ...props, className: cn('flex flex-1 flex-col transition-[padding] pt-(--fd-nav-height) fd-notebook-layout', props.className), style: { ...props.style, paddingInlineStart: collapsed ? 'min(calc(100vw - var(--fd-page-width)), var(--fd-sidebar-width))' : 'calc(var(--fd-sidebar-width) + var(--fd-layout-offset))', paddingInlineEnd: collapsed ? '0px' : 'var(--fd-layout-offset)', }, children: props.children })); } export function NavbarSidebarTrigger({ className, ...props }) { const { setOpen } = useSidebar(); return (_jsx("button", { ...props, className: cn(buttonVariants({ color: 'ghost', size: 'icon-sm', className, })), onClick: () => setOpen((prev) => !prev), children: _jsx(SidebarIcon, {}) })); } export function LayoutTabs({ options, ...props }) { const pathname = usePathname(); const selected = useMemo(() => { const url = pathname.endsWith('/') ? pathname.slice(0, -1) : pathname; return options.findLast((option) => { if (option.urls) { return option.urls.has(url); } return isActive(option.url, pathname, true); }); }, [options, pathname]); return (_jsx("div", { ...props, className: cn('flex flex-row items-center gap-2 overflow-auto', props.className), children: options.map((option) => (_jsx(LayoutTab, { selected: selected === option, option: option }, option.url))) })); } function LayoutTab({ option, selected = false, }) { return (_jsx(Link, { className: cn('inline-flex rounded-full items-center px-2 py-1.5 font-medium gap-2 text-fd-muted-foreground text-sm text-nowrap', selected && 'bg-fd-primary/10 text-fd-primary'), href: option.url, children: option.title })); }