|
1 | | -'use client' |
2 | | - |
3 | | -import { ChevronUp, Menu } from 'lucide-react' |
4 | | -import { usePathname } from 'next/navigation' |
5 | | -import { useState, useEffect, useRef } from 'react' |
6 | | - |
7 | | -import { DocSidebar, sections } from '@/components/docs/doc-sidebar' |
8 | | -import { |
9 | | - Sheet, |
10 | | - SheetContent, |
11 | | - SheetTitle, |
12 | | - SheetTrigger, |
13 | | -} from '@/components/ui/sheet' |
14 | | -import { VisuallyHidden } from '@radix-ui/react-visually-hidden' |
| 1 | +import { DocsLayoutClient } from '@/components/docs/docs-layout-client' |
15 | 2 |
|
16 | 3 | export default function DocsLayout({ |
17 | 4 | children, |
18 | 5 | }: { |
19 | 6 | children: React.ReactNode |
20 | 7 | }) { |
21 | | - const pathname = usePathname() ?? '/docs' |
22 | | - const [open, setOpen] = useState(false) |
23 | | - const [showTopFade, setShowTopFade] = useState(false) |
24 | | - const [showBottomFade, setShowBottomFade] = useState(false) |
25 | | - const sidebarRef = useRef<HTMLDivElement>(null) |
26 | | - const containerRef = useRef<HTMLDivElement>(null) |
27 | | - const stickyTop = 64 // navbar height |
28 | | - |
29 | | - // Handle sidebar scroll for dynamic fade effects |
30 | | - useEffect(() => { |
31 | | - const sidebarElement = sidebarRef.current |
32 | | - if (!sidebarElement) return |
33 | | - |
34 | | - const handleScroll = () => { |
35 | | - const { scrollTop, scrollHeight, clientHeight } = sidebarElement |
36 | | - const isAtTop = scrollTop === 0 |
37 | | - const isAtBottom = scrollTop + clientHeight >= scrollHeight - 1 |
38 | | - |
39 | | - setShowTopFade(!isAtTop) |
40 | | - setShowBottomFade(!isAtBottom) |
41 | | - } |
42 | | - |
43 | | - // Check initial state |
44 | | - handleScroll() |
45 | | - |
46 | | - sidebarElement.addEventListener('scroll', handleScroll) |
47 | | - return () => sidebarElement.removeEventListener('scroll', handleScroll) |
48 | | - }, []) |
49 | | - |
50 | | - return ( |
51 | | - <div className="pt-8"> |
52 | | - <div ref={containerRef} className="container flex md:space-x-8"> |
53 | | - <div className="hidden lg:block w-64 shrink-0"> |
54 | | - <div |
55 | | - className="w-64 sticky z-40" |
56 | | - style={{ |
57 | | - top: `${stickyTop}px`, |
58 | | - height: `calc(100vh - ${stickyTop}px - 3rem)`, |
59 | | - }} |
60 | | - > |
61 | | - {/* Dynamic gradient fade indicators */} |
62 | | - {showTopFade && ( |
63 | | - <div className="absolute top-0 left-0 right-0 h-12 bg-gradient-to-b from-background via-background/60 to-transparent pointer-events-none z-10 rounded-t-lg transition-opacity duration-200" /> |
64 | | - )} |
65 | | - {showBottomFade && ( |
66 | | - <div className="absolute bottom-0 left-0 right-0 h-12 bg-gradient-to-t from-background via-background/60 to-transparent pointer-events-none z-10 rounded-b-lg transition-opacity duration-200" /> |
67 | | - )} |
68 | | - |
69 | | - {/* Enhanced scrollable container */} |
70 | | - <div |
71 | | - ref={sidebarRef} |
72 | | - className="relative h-full overflow-y-auto pr-4 pl-4 pt-4 pb-6 custom-scrollbar bg-background/95 backdrop-blur-sm rounded-lg border border-border/50 shadow-lg" |
73 | | - > |
74 | | - <DocSidebar className="" onNavigate={() => setOpen(false)} /> |
75 | | - </div> |
76 | | - </div> |
77 | | - </div> |
78 | | - <main className="flex-1 mx-auto pb-36 md:px-8 min-w-0 pt-8"> |
79 | | - {children} |
80 | | - </main> |
81 | | - </div> |
82 | | - <div className="lg:hidden sticky bottom-0 z-50 bg-background/80 backdrop-blur-sm rounded-t-lg border-t"> |
83 | | - <Sheet |
84 | | - open={open} |
85 | | - onOpenChange={(isOpen) => { |
86 | | - setOpen(isOpen) |
87 | | - if (!open) { |
88 | | - document.body.style.position = '' |
89 | | - document.body.style.overflow = '' |
90 | | - document.body.style.top = '' |
91 | | - } |
92 | | - }} |
93 | | - > |
94 | | - <SheetTrigger asChild> |
95 | | - <button className="flex items-center w-full px-4 py-4 hover:bg-accent/50 transition-colors"> |
96 | | - <div className="container flex items-center justify-between"> |
97 | | - <div className="flex items-center"> |
98 | | - <Menu className="h-5 w-5 mr-4" /> |
99 | | - <span className="text-xl font-semibold"> |
100 | | - {sections.find((section) => pathname.startsWith(section.href)) |
101 | | - ?.title || 'Documentation'} |
102 | | - </span> |
103 | | - </div> |
104 | | - <ChevronUp className="h-5 w-5 text-muted-foreground" /> |
105 | | - </div> |
106 | | - </button> |
107 | | - </SheetTrigger> |
108 | | - <SheetContent |
109 | | - side="bottom" |
110 | | - className="h-[80vh] p-6 pt-12 overflow-y-auto" |
111 | | - > |
112 | | - <VisuallyHidden> |
113 | | - <SheetTitle>Documentation Navigation</SheetTitle> |
114 | | - </VisuallyHidden> |
115 | | - <DocSidebar onNavigate={() => setOpen(false)} /> |
116 | | - </SheetContent> |
117 | | - </Sheet> |
118 | | - </div> |
119 | | - </div> |
120 | | - ) |
| 8 | + return <DocsLayoutClient>{children}</DocsLayoutClient> |
121 | 9 | } |
0 commit comments