Skip to content

Commit

Permalink
feat: new layout (#285)
Browse files Browse the repository at this point in the history
* wip

* wip

* menu

* fix
  • Loading branch information
abernier committed Sep 5, 2024
1 parent c3ccc0d commit 22defec
Show file tree
Hide file tree
Showing 18 changed files with 440 additions and 334 deletions.
21 changes: 21 additions & 0 deletions src/app/[...slug]/Burger.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
'use client'

import Icon from '@/components/Icon'
import cn from '@/lib/cn'
import { ComponentProps } from 'react'
import { useMenu } from './MenuContext'

export function Burger({ className }: ComponentProps<'button'>) {
const [menuOpen, setMenuOpen] = useMenu()

return (
<button
className={cn(className, 'flex size-9 items-center justify-center')}
type="button"
aria-label="Menu"
onClick={() => setMenuOpen(!menuOpen)}
>
{menuOpen ? <Icon icon="close" /> : <Icon icon="menu" />}
</button>
)
}
96 changes: 16 additions & 80 deletions src/app/[...slug]/Menu.tsx
Original file line number Diff line number Diff line change
@@ -1,92 +1,28 @@
'use client'

import Icon from '@/components/Icon'
import { useLockBodyScroll } from '@/hooks/useLockBodyScroll'
import { Nav } from '@/components/Nav'
import cn from '@/lib/cn'
import * as React from 'react'
import { ComponentProps, ElementRef, useEffect, useRef } from 'react'
import { useDocs } from './DocsContext'
import { useMenu } from './MenuContext'

export function Menu({
header,
nav,
children,
aside,
footer,
}: {
header: React.ReactNode
nav: React.ReactNode
children: React.ReactNode
aside: React.ReactNode
footer: React.ReactNode
}) {
const { doc } = useDocs()
export function Menu({ className, asPath }: ComponentProps<'dialog'> & { asPath: string }) {
const { doc, docs } = useDocs()

const [menuOpen, setMenuOpen] = useMenu()
useLockBodyScroll(menuOpen)
const [opened, setOpened] = useMenu()
const dialogRef = useRef<ElementRef<'dialog'>>(null)

React.useEffect(() => setMenuOpen(false), [setMenuOpen])

const NEXT_PUBLIC_LIBNAME = process.env.NEXT_PUBLIC_LIBNAME
useEffect(() => {
if (opened) {
dialogRef.current?.show()
} else {
dialogRef.current?.close()
}
}, [opened])

return (
<>
<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">
<div className="flex w-full items-center justify-between pr-2">
{header}
<button
className="flex size-9 items-center justify-center lg:hidden"
onClick={() => setMenuOpen((v) => !v)}
type="button"
aria-label="Menu"
>
<Icon icon="menu" />
</button>
</div>
</header>

<div className="max-w-8xl mx-auto w-full">
<div className="lg:flex">
<div
id="sidebar"
className={cn(
'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',
!menuOpen && 'hidden',
)}
>
<div
id="nav-wrapper"
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"
>
<nav
id="nav"
className="sticky?lg:h-(screen-16) relative z-10 overflow-y-auto px-4 pb-10 pl-0 lg:pb-14 lg:text-sm"
>
{nav}
</nav>
</div>
<button
onClick={() => setMenuOpen(false)}
className={cn(
'bg-surface/70',
'fixed right-0 top-0 z-0 h-screen w-screen',
!menuOpen && 'hidden',
)}
/>
</div>
<div id="content-wrapper" className={cn('flex-auto', menuOpen && 'overflow-hidden')}>
<div className="flex w-full">
<main className="min-w-0 flex-auto px-4 pb-24 pt-8 sm:px-6 lg:pb-16 xl:px-8">
<div>{children}</div>

<footer>{footer}</footer>
</main>

<aside className="hidden w-64 flex-none pl-8 pr-8 xl:block xl:text-sm">{aside}</aside>
</div>
</div>
</div>
</div>
</>
<dialog ref={dialogRef} className={cn(className, 'bg-surface-dim/95 backdrop-blur-xl')}>
<Nav docs={docs} asPath={asPath} collapsible={false} />
</dialog>
)
}
16 changes: 15 additions & 1 deletion src/app/[...slug]/MenuContext.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
'use client'

import { useLockBodyScroll } from '@/hooks/useLockBodyScroll'
import { createRequiredContext } from '@/lib/createRequiredContext'
import { Dispatch, ReactNode, SetStateAction, useState } from 'react'
import { Dispatch, ElementRef, ReactNode, SetStateAction, useEffect, useRef, useState } from 'react'

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

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

const [opened, setOpened] = state
const dialogRef = useRef<ElementRef<'dialog'>>(null)

useEffect(() => {
if (opened) {
dialogRef.current?.show()
} else {
dialogRef.current?.close()
}
}, [opened])

useLockBodyScroll(opened)

return <Provider value={state}>{children}</Provider>
}
Loading

0 comments on commit 22defec

Please sign in to comment.