docs-mobile-nav.tsx 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. "use client";
  2. import { useState, useMemo } from "react";
  3. import Link from "next/link";
  4. import { usePathname } from "next/navigation";
  5. import { List } from "lucide-react";
  6. import {
  7. Sheet,
  8. SheetTrigger,
  9. SheetContent,
  10. SheetTitle,
  11. } from "@/components/ui/sheet";
  12. import { docsNavigation, allDocsPages } from "@/lib/docs-navigation";
  13. export function DocsMobileNav() {
  14. const [open, setOpen] = useState(false);
  15. const pathname = usePathname();
  16. const currentPage = useMemo(() => {
  17. const page = allDocsPages.find((page) => page.href === pathname);
  18. return page ?? allDocsPages[0];
  19. }, [pathname]);
  20. return (
  21. <Sheet open={open} onOpenChange={setOpen}>
  22. <SheetTrigger className="lg:hidden sticky top-[calc(3.5rem+1px)] z-40 w-full px-6 py-3 bg-background/80 backdrop-blur-sm border-b border-border flex items-center justify-between focus:outline-none">
  23. <div className="text-sm font-medium">{currentPage?.title}</div>
  24. <div className="w-8 h-8 flex items-center justify-center">
  25. <List className="h-4 w-4 text-muted-foreground" />
  26. </div>
  27. </SheetTrigger>
  28. <SheetContent className="overflow-y-auto p-6">
  29. <SheetTitle className="mb-6">Table of Contents</SheetTitle>
  30. <nav className="space-y-6">
  31. {docsNavigation.map((section) => (
  32. <div key={section.title}>
  33. <h4 className="text-xs font-medium text-muted-foreground uppercase tracking-wider mb-2">
  34. {section.title}
  35. </h4>
  36. <ul className="space-y-1">
  37. {section.items.map((item) => {
  38. const isExternal = item.external;
  39. return (
  40. <li key={item.href}>
  41. <Link
  42. href={item.href}
  43. onClick={() => setOpen(false)}
  44. {...(isExternal && {
  45. target: "_blank",
  46. rel: "noopener noreferrer",
  47. })}
  48. className={`text-sm block py-2 transition-colors ${
  49. pathname === item.href
  50. ? "text-primary font-medium"
  51. : "text-muted-foreground hover:text-foreground"
  52. } ${isExternal ? "inline-flex items-center gap-1" : ""}`}
  53. >
  54. {item.title}
  55. {isExternal && (
  56. <svg
  57. className="w-3 h-3"
  58. fill="none"
  59. stroke="currentColor"
  60. viewBox="0 0 24 24"
  61. >
  62. <path
  63. strokeLinecap="round"
  64. strokeLinejoin="round"
  65. strokeWidth={2}
  66. d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
  67. />
  68. </svg>
  69. )}
  70. </Link>
  71. </li>
  72. );
  73. })}
  74. </ul>
  75. </div>
  76. ))}
  77. </nav>
  78. </SheetContent>
  79. </Sheet>
  80. );
  81. }