'use client';
import { useEffect, useMemo, useState } from 'react';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { ChevronDownIcon, MenuIcon } from 'lucide-react';
import { isBrowser } from '@kit/shared/utils';
import { Button } from '@kit/ui/button';
import { Heading } from '@kit/ui/heading';
import { If } from '@kit/ui/if';
import { cn } from '@kit/ui/utils';
import type { ProcessedDocumentationPage } from '../utils/build-documentation-tree';
const DocsNavLink: React.FC<{
label: string;
url: string;
level: number;
activePath: string;
collapsible: boolean;
collapsed: boolean;
toggleCollapsed: () => void;
}> = ({
label,
url,
level,
activePath,
collapsible,
collapsed,
toggleCollapsed,
}) => {
const isCurrent = url == activePath;
const isFirstLevel = level === 0;
return (
{label}
{collapsible && (
)}
);
};
const Node: React.FC<{
node: ProcessedDocumentationPage;
level: number;
activePath: string;
}> = ({ node, level, activePath }) => {
const [collapsed, setCollapsed] = useState(node.collapsed ?? false);
const toggleCollapsed = () => setCollapsed(!collapsed);
useEffect(() => {
if (
activePath == node.resolvedPath ||
node.children.map((_) => _.resolvedPath).includes(activePath)
) {
setCollapsed(false);
}
}, [activePath, node.children, node.resolvedPath]);
return (
<>
{node.children.length > 0 && !collapsed && (
)}
>
);
};
function Tree({
tree,
level,
activePath,
}: {
tree: ProcessedDocumentationPage[];
level: number;
activePath: string;
}) {
return (
0 ? 'border-l' : '')}>
{tree.map((treeNode, index) => (
))}
);
}
export default function DocsNavigation({
tree,
}: {
tree: ProcessedDocumentationPage[];
}) {
const activePath = usePathname().replace('/docs/', '');
return (
<>
>
);
}
function getNavLinkClassName(isCurrent: boolean, isFirstLevel: boolean) {
return cn(
'group flex h-8 items-center justify-between space-x-2 whitespace-nowrap rounded-md px-3 text-sm leading-none transition-colors',
{
[`bg-muted`]: isCurrent,
[`hover:bg-muted`]: !isCurrent,
[`font-semibold`]: isFirstLevel,
[`font-normal`]: !isFirstLevel && isCurrent,
[`hover:text-foreground-muted`]: !isFirstLevel && !isCurrent,
},
);
}
function FloatingDocumentationNavigation({
tree,
activePath,
}: React.PropsWithChildren<{
tree: ProcessedDocumentationPage[];
activePath: string;
}>) {
const body = useMemo(() => {
return isBrowser() ? document.body : null;
}, []);
const [isVisible, setIsVisible] = useState(false);
const enableScrolling = (element: HTMLElement) =>
(element.style.overflowY = '');
const disableScrolling = (element: HTMLElement) =>
(element.style.overflowY = 'hidden');
// enable/disable body scrolling when the docs are toggled
useEffect(() => {
if (!body) {
return;
}
if (isVisible) {
disableScrolling(body);
} else {
enableScrolling(body);
}
}, [isVisible, body]);
// hide docs when navigating to another page
useEffect(() => {
setIsVisible(false);
}, [activePath]);
const onClick = () => {
setIsVisible(!isVisible);
};
return (
<>
Table of Contents
>
);
}