Standard.site landing page built in Next.js
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add documentation components

+230
+126
app/components/docs/DocsNav.tsx
··· 1 + 'use client' 2 + 3 + import { useEffect, useState } from 'react' 4 + import Link from 'next/link' 5 + import { usePathname } from 'next/navigation' 6 + import { ArrowLeftIcon, MenuIcon, XIcon } from 'lucide-react' 7 + import BlurEffect from 'react-progressive-blur' 8 + import { AnimateIn, StandardSiteLogo } from '@/app/components' 9 + import { DOCS_NAV } from '@/app/data/docs-nav' 10 + 11 + export function DocsNav() { 12 + const [isOpen, setIsOpen] = useState(false) 13 + const pathname = usePathname() 14 + const [prevPathname, setPrevPathname] = useState(pathname) 15 + 16 + // Close menu when route changes (adjusting state during render) 17 + if (pathname !== prevPathname) { 18 + setPrevPathname(pathname) 19 + setIsOpen(false) 20 + } 21 + 22 + useEffect(() => { 23 + if (isOpen) { 24 + document.body.style.overflow = 'hidden' 25 + } else { 26 + document.body.style.overflow = '' 27 + } 28 + 29 + return () => { 30 + document.body.style.overflow = '' 31 + } 32 + }, [isOpen]) 33 + 34 + return ( 35 + <> 36 + <AnimateIn 37 + as="header" 38 + direction="down" 39 + delay={0.5} 40 + onScroll={false} 41 + className="fixed left-0 right-0 top-0 z-30 px-4 py-2 md:hidden" 42 + > 43 + <div 44 + className={`p-4 relative flex flex-col gap-6 z-40 mx-auto max-w-[38rem] w-full min-h-0 overflow-hidden rounded-2xl transition-all duration-300 ease-in-out ${ 45 + isOpen 46 + ? 'bg-zinc-950 dark:bg-zinc-50 text-zinc-50 dark:text-zinc-950 max-h-[80vh] overflow-y-auto' 47 + : 'text-base-content h-15' 48 + }`} 49 + > 50 + <div className="flex justify-between items-center"> 51 + <Link href="/" className="flex items-center gap-2"> 52 + <StandardSiteLogo className="size-7" /> 53 + <span className="font-medium text-sm tracking-tight">Docs</span> 54 + </Link> 55 + {!isOpen && ( 56 + <button 57 + onClick={() => setIsOpen(true)} 58 + aria-label="Open menu" 59 + > 60 + <MenuIcon className="size-6" /> 61 + </button> 62 + )} 63 + {isOpen && ( 64 + <button 65 + onClick={() => setIsOpen(false)} 66 + aria-label="Close menu" 67 + > 68 + <XIcon className="size-6" /> 69 + </button> 70 + )} 71 + </div> 72 + 73 + {isOpen && ( 74 + <nav className="flex flex-col gap-6"> 75 + {DOCS_NAV.map((section) => ( 76 + <div key={section.title} className="flex flex-col gap-2"> 77 + <span className="font-mono text-xs font-medium tracking-tight text-muted-content uppercase"> 78 + {section.title} 79 + </span> 80 + <div className="flex flex-col gap-2"> 81 + {section.items.map((item) => ( 82 + <Link 83 + key={item.href} 84 + href={item.href} 85 + className={`font-medium text-lg tracking-tight ${ 86 + pathname === item.href 87 + ? 'text-zinc-50 dark:text-zinc-950' 88 + : 'text-muted-content' 89 + } hover:text-zinc-50 dark:hover:text-zinc-950 transition-colors`} 90 + > 91 + {item.label} 92 + </Link> 93 + ))} 94 + </div> 95 + </div> 96 + ))} 97 + 98 + <div className="h-px w-full bg-border/10" /> 99 + 100 + <Link 101 + href="/" 102 + className="flex items-center gap-2 font-medium text-lg tracking-tight text-muted-content hover:text-zinc-50 dark:hover:text-zinc-950 transition-colors" 103 + > 104 + <ArrowLeftIcon className="size-5" /> 105 + Back home 106 + </Link> 107 + </nav> 108 + )} 109 + </div> 110 + <BlurEffect 111 + className="bg-gradient-to-b from-base-100 to-transparent absolute inset-0 w-full h-full -z-10" 112 + position="top" 113 + intensity={75} 114 + /> 115 + </AnimateIn> 116 + 117 + {/* Overlay */} 118 + <div 119 + className={`fixed inset-0 z-10 bg-base-100/50 backdrop-blur-sm transition-opacity duration-300 md:hidden ${ 120 + isOpen ? 'opacity-100' : 'opacity-0 pointer-events-none' 121 + }`} 122 + onClick={() => setIsOpen(false)} 123 + /> 124 + </> 125 + ) 126 + }
+61
app/components/docs/DocsSidebar.tsx
··· 1 + 'use client' 2 + 3 + import Link from 'next/link' 4 + import { usePathname } from 'next/navigation' 5 + import { ArrowLeftIcon } from 'lucide-react' 6 + import { AnimateIn, StandardSiteLogo } from '@/app/components' 7 + import { DOCS_NAV } from '@/app/data/docs-nav' 8 + 9 + export function DocsSidebar() { 10 + const pathname = usePathname() 11 + 12 + return ( 13 + <AnimateIn 14 + as="aside" 15 + direction="left" 16 + delay={0.3} 17 + onScroll={false} 18 + className="flex sticky top-8 w-32 shrink-0 flex-col gap-6" 19 + > 20 + <Link href="/" className="flex items-center gap-2"> 21 + <StandardSiteLogo className="size-7 text-base-content" /> 22 + <span className="font-medium text-sm tracking-tight text-base-content">Docs</span> 23 + </Link> 24 + 25 + <nav className="flex flex-col gap-6"> 26 + {DOCS_NAV.map((section) => ( 27 + <div key={section.title} className="flex flex-col gap-2"> 28 + <span className="font-mono text-xs font-medium tracking-tight text-muted-content uppercase"> 29 + {section.title} 30 + </span> 31 + <div className="flex flex-col gap-1"> 32 + {section.items.map((item) => ( 33 + <Link 34 + key={item.href} 35 + href={item.href} 36 + className={`font-medium text-base tracking-tight py-0.5 ${ 37 + pathname === item.href 38 + ? 'text-base-content' 39 + : 'text-muted-content' 40 + } hover:text-base-content transition-colors`} 41 + > 42 + {item.label} 43 + </Link> 44 + ))} 45 + </div> 46 + </div> 47 + ))} 48 + </nav> 49 + 50 + <div className="h-px w-full bg-border" /> 51 + 52 + <Link 53 + href="/" 54 + className="flex items-center gap-2 font-medium text-base tracking-tight text-muted-content hover:text-base-content transition-colors" 55 + > 56 + <ArrowLeftIcon className="size-4" /> 57 + Back home 58 + </Link> 59 + </AnimateIn> 60 + ) 61 + }
+39
app/components/docs/Table.tsx
··· 1 + interface TableProps { 2 + headers: string[] 3 + rows: string[][] 4 + } 5 + 6 + export function Table({ headers, rows }: TableProps) { 7 + return ( 8 + <div className="overflow-x-auto mb-6"> 9 + <table className="w-full text-base border-collapse"> 10 + <thead> 11 + <tr> 12 + {headers.map((header, i) => ( 13 + <th 14 + key={i} 15 + className="text-left font-medium text-base-content border-b border-border px-3 py-2" 16 + > 17 + {header} 18 + </th> 19 + ))} 20 + </tr> 21 + </thead> 22 + <tbody> 23 + {rows.map((row, i) => ( 24 + <tr key={i}> 25 + {row.map((cell, j) => ( 26 + <td 27 + key={j} 28 + className="text-muted border-b border-border px-3 py-2" 29 + > 30 + {cell} 31 + </td> 32 + ))} 33 + </tr> 34 + ))} 35 + </tbody> 36 + </table> 37 + </div> 38 + ) 39 + }
+3
app/components/docs/index.ts
··· 1 + export { DocsSidebar } from './DocsSidebar' 2 + export { DocsNav } from './DocsNav' 3 + export { Table } from './Table'
+1
app/components/index.ts
··· 7 7 export * from "@/app/components/ExpandableField"; 8 8 export * from "@/app/components/sections"; 9 9 export * from "@/app/components/icons"; 10 + export * from "@/app/components/docs";