Skip to content

Commit 22defec

Browse files
authored
feat: new layout (#285)
* wip * wip * menu * fix
1 parent c3ccc0d commit 22defec

File tree

18 files changed

+440
-334
lines changed

18 files changed

+440
-334
lines changed

src/app/[...slug]/Burger.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
'use client'
2+
3+
import Icon from '@/components/Icon'
4+
import cn from '@/lib/cn'
5+
import { ComponentProps } from 'react'
6+
import { useMenu } from './MenuContext'
7+
8+
export function Burger({ className }: ComponentProps<'button'>) {
9+
const [menuOpen, setMenuOpen] = useMenu()
10+
11+
return (
12+
<button
13+
className={cn(className, 'flex size-9 items-center justify-center')}
14+
type="button"
15+
aria-label="Menu"
16+
onClick={() => setMenuOpen(!menuOpen)}
17+
>
18+
{menuOpen ? <Icon icon="close" /> : <Icon icon="menu" />}
19+
</button>
20+
)
21+
}

src/app/[...slug]/Menu.tsx

Lines changed: 16 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,28 @@
11
'use client'
22

3-
import Icon from '@/components/Icon'
4-
import { useLockBodyScroll } from '@/hooks/useLockBodyScroll'
3+
import { Nav } from '@/components/Nav'
54
import cn from '@/lib/cn'
6-
import * as React from 'react'
5+
import { ComponentProps, ElementRef, useEffect, useRef } from 'react'
76
import { useDocs } from './DocsContext'
87
import { useMenu } from './MenuContext'
98

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()
2411

25-
const [menuOpen, setMenuOpen] = useMenu()
26-
useLockBodyScroll(menuOpen)
12+
const [opened, setOpened] = useMenu()
13+
const dialogRef = useRef<ElementRef<'dialog'>>(null)
2714

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])
3122

3223
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>
9127
)
9228
}

src/app/[...slug]/MenuContext.tsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
'use client'
22

3+
import { useLockBodyScroll } from '@/hooks/useLockBodyScroll'
34
import { createRequiredContext } from '@/lib/createRequiredContext'
4-
import { Dispatch, ReactNode, SetStateAction, useState } from 'react'
5+
import { Dispatch, ElementRef, ReactNode, SetStateAction, useEffect, useRef, useState } from 'react'
56

67
export type Ctx = [boolean, Dispatch<SetStateAction<boolean>>]
78

@@ -12,5 +13,18 @@ export { hook as useMenu }
1213
export function MenuContext({ children }: { children?: ReactNode }) {
1314
const state = useState(false)
1415

16+
const [opened, setOpened] = state
17+
const dialogRef = useRef<ElementRef<'dialog'>>(null)
18+
19+
useEffect(() => {
20+
if (opened) {
21+
dialogRef.current?.show()
22+
} else {
23+
dialogRef.current?.close()
24+
}
25+
}, [opened])
26+
27+
useLockBodyScroll(opened)
28+
1529
return <Provider value={state}>{children}</Provider>
1630
}

0 commit comments

Comments
 (0)