|
1 | 1 | 'use client'
|
2 | 2 |
|
3 |
| -import Icon from '@/components/Icon' |
4 |
| -import { useLockBodyScroll } from '@/hooks/useLockBodyScroll' |
| 3 | +import { Nav } from '@/components/Nav' |
5 | 4 | import cn from '@/lib/cn'
|
6 |
| -import * as React from 'react' |
| 5 | +import { ComponentProps, ElementRef, useEffect, useRef } from 'react' |
7 | 6 | import { useDocs } from './DocsContext'
|
8 | 7 | import { useMenu } from './MenuContext'
|
9 | 8 |
|
10 |
| -export function Menu({ |
11 |
| - header, |
12 |
| - nav, |
13 |
| - children, |
14 |
| - aside, |
15 |
| - footer, |
16 |
| -}: { |
17 |
| - header: React.ReactNode |
18 |
| - nav: React.ReactNode |
19 |
| - children: React.ReactNode |
20 |
| - aside: React.ReactNode |
21 |
| - footer: React.ReactNode |
22 |
| -}) { |
23 |
| - const { doc } = useDocs() |
| 9 | +export function Menu({ className, asPath }: ComponentProps<'dialog'> & { asPath: string }) { |
| 10 | + const { doc, docs } = useDocs() |
24 | 11 |
|
25 |
| - const [menuOpen, setMenuOpen] = useMenu() |
26 |
| - useLockBodyScroll(menuOpen) |
| 12 | + const [opened, setOpened] = useMenu() |
| 13 | + const dialogRef = useRef<ElementRef<'dialog'>>(null) |
27 | 14 |
|
28 |
| - React.useEffect(() => setMenuOpen(false), [setMenuOpen]) |
29 |
| - |
30 |
| - const NEXT_PUBLIC_LIBNAME = process.env.NEXT_PUBLIC_LIBNAME |
| 15 | + useEffect(() => { |
| 16 | + if (opened) { |
| 17 | + dialogRef.current?.show() |
| 18 | + } else { |
| 19 | + dialogRef.current?.close() |
| 20 | + } |
| 21 | + }, [opened]) |
31 | 22 |
|
32 | 23 | return (
|
33 |
| - <> |
34 |
| - <header className="max-w-8xl bg-surface sticky top-0 z-40 mx-auto flex w-full flex-none border-b border-outline-variant/50 lg:z-50"> |
35 |
| - <div className="flex w-full items-center justify-between pr-2"> |
36 |
| - {header} |
37 |
| - <button |
38 |
| - className="flex size-9 items-center justify-center lg:hidden" |
39 |
| - onClick={() => setMenuOpen((v) => !v)} |
40 |
| - type="button" |
41 |
| - aria-label="Menu" |
42 |
| - > |
43 |
| - <Icon icon="menu" /> |
44 |
| - </button> |
45 |
| - </div> |
46 |
| - </header> |
47 |
| - |
48 |
| - <div className="max-w-8xl mx-auto w-full"> |
49 |
| - <div className="lg:flex"> |
50 |
| - <div |
51 |
| - id="sidebar" |
52 |
| - className={cn( |
53 |
| - 'fixed inset-0 z-40 h-full w-full flex-none lg:static lg:block lg:h-auto lg:w-60 lg:overflow-y-visible lg:pt-0 xl:w-72', |
54 |
| - !menuOpen && 'hidden', |
55 |
| - )} |
56 |
| - > |
57 |
| - <div |
58 |
| - id="nav-wrapper" |
59 |
| - className="scrolling-touch bg-surface relative z-10 mr-24 h-full overflow-hidden overflow-y-auto lg:sticky lg:top-16 lg:mr-0 lg:block lg:h-auto lg:bg-transparent" |
60 |
| - > |
61 |
| - <nav |
62 |
| - id="nav" |
63 |
| - className="sticky?lg:h-(screen-16) relative z-10 overflow-y-auto px-4 pb-10 pl-0 lg:pb-14 lg:text-sm" |
64 |
| - > |
65 |
| - {nav} |
66 |
| - </nav> |
67 |
| - </div> |
68 |
| - <button |
69 |
| - onClick={() => setMenuOpen(false)} |
70 |
| - className={cn( |
71 |
| - 'bg-surface/70', |
72 |
| - 'fixed right-0 top-0 z-0 h-screen w-screen', |
73 |
| - !menuOpen && 'hidden', |
74 |
| - )} |
75 |
| - /> |
76 |
| - </div> |
77 |
| - <div id="content-wrapper" className={cn('flex-auto', menuOpen && 'overflow-hidden')}> |
78 |
| - <div className="flex w-full"> |
79 |
| - <main className="min-w-0 flex-auto px-4 pb-24 pt-8 sm:px-6 lg:pb-16 xl:px-8"> |
80 |
| - <div>{children}</div> |
81 |
| - |
82 |
| - <footer>{footer}</footer> |
83 |
| - </main> |
84 |
| - |
85 |
| - <aside className="hidden w-64 flex-none pl-8 pr-8 xl:block xl:text-sm">{aside}</aside> |
86 |
| - </div> |
87 |
| - </div> |
88 |
| - </div> |
89 |
| - </div> |
90 |
| - </> |
| 24 | + <dialog ref={dialogRef} className={cn(className, 'bg-surface-dim/95 backdrop-blur-xl')}> |
| 25 | + <Nav docs={docs} asPath={asPath} collapsible={false} /> |
| 26 | + </dialog> |
91 | 27 | )
|
92 | 28 | }
|
0 commit comments