"use client"; import { useState } from "react"; import { cn, docsHtmlHref } from "../node/utils"; import { Dropdown, DropdownItem } from "@docubook/ui-react/dropdown"; import { routes, config as docuConfig } from "../node/client-routes"; import { ChevronsUpDown, Check } from "lucide-react"; import { renderLucideIcon } from "./Lucide"; interface ContextProps { className?: string; } function getContextRoutes() { return routes.filter((route) => route.context); } function getFirstItemHref(route: { href: string; items?: { href: string }[] }): string { if (!route.items?.length) return route.href; return `${route.href}${getFirstItemHref(route.items[0])}`; } function getActiveContextRoute(path: string) { const docPath = path.replace(/^\/docs/, ""); return getContextRoutes().find((route) => docPath.startsWith(route.href)); } export function Context({ className }: ContextProps) { const [pathname] = useState(() => typeof window !== "undefined" ? window.location.pathname : "/" ); const mounted = typeof window !== "undefined"; const mode = docuConfig.sidebar?.context || "dropdown"; if (mode === "separator") return null; const activeRoute = pathname.startsWith("/docs") ? getActiveContextRoute(pathname) : undefined; const contextRoutes = getContextRoutes(); const fallbackRoute = routes[0]; const displayRoute = activeRoute || fallbackRoute; if (!mounted || !pathname.startsWith("/docs") || contextRoutes.length === 0) { return null; } const navigate = (href: string) => { window.location.href = href; }; return (
{displayRoute?.context?.icon && ( {renderLucideIcon(displayRoute.context.icon, "h-4 w-4")} )} {displayRoute?.context?.title || displayRoute?.title}
} > {contextRoutes.map((route) => { const isActive = activeRoute?.href === route.href; const firstItemPath = getFirstItemHref(route); const contextPath = docsHtmlHref(`/docs${firstItemPath}`); return ( navigate(contextPath)} className={cn( "relative flex cursor-pointer items-center gap-2 rounded px-2 py-2 text-sm", "text-left transition-colors outline-none", isActive ? "bg-primary/20 text-primary" : "hover:bg-base-200 text-base-content/80 hover:text-base-content" )} > {route.context?.icon && ( {renderLucideIcon(route.context.icon)} )}
{route.context?.title || route.title}
{route.context?.description && (
{route.context.description}
)}
{isActive && }
); })}
); }