Skip to content

Commit

Permalink
docs: redesign menu (geist-org#723)
Browse files Browse the repository at this point in the history
  • Loading branch information
ofekashery committed Feb 9, 2022
1 parent 7d1845b commit 65e0978
Show file tree
Hide file tree
Showing 17 changed files with 420 additions and 470 deletions.
7 changes: 1 addition & 6 deletions lib/components/layout/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
import Menu from './menu'
import { Layout } from './layout'

export type LayoutComponentType = typeof Layout & {
Menu: typeof Menu
}
;(Layout as LayoutComponentType).Menu = Menu

export type LayoutComponentType = typeof Layout
export type { LayoutProps } from './layout'
export default Layout as LayoutComponentType
55 changes: 14 additions & 41 deletions lib/components/layout/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import React, { useEffect, useState } from 'react'
import PageHeader from './header'
import { useTheme, useBodyScroll } from 'components'
import Sidebar, { TabbarMobile } from './sidebar'
import { useConfigs } from '../../config-context'
import { useTheme } from 'components'
import Sidebar from './sidebar'

export interface Meta {
title: string
Expand All @@ -17,14 +16,6 @@ export const Layout: React.FC<React.PropsWithChildren<LayoutProps>> = React.memo
({ children, meta }) => {
const theme = useTheme()
const [showAfterRender, setShowAfterRender] = useState<boolean>(false)
const { tabbarFixed } = useConfigs()
const [, setBodyScroll] = useBodyScroll(null, { scrollLayer: true })
const [expanded, setExpanded] = useState<boolean>(false)
const mobileTabbarClickHandler = () => {
setExpanded(!expanded)
setBodyScroll(!expanded)
}

useEffect(() => setShowAfterRender(true), [])

if (!showAfterRender)
Expand All @@ -43,11 +34,11 @@ export const Layout: React.FC<React.PropsWithChildren<LayoutProps>> = React.memo
return (
<div className="layout">
<PageHeader meta={meta} />
<TabbarMobile onClick={mobileTabbarClickHandler} />
<aside className="sidebar">
<Sidebar />
<div className="content">
<Sidebar />
</div>
</aside>
<div className="side-shadow" />
<main className="main">
<div>{children}</div>
</main>
Expand All @@ -74,23 +65,20 @@ export const Layout: React.FC<React.PropsWithChildren<LayoutProps>> = React.memo
box-sizing: border-box;
}
.sidebar {
flex-grow: 1;
}
.sidebar > .content {
height: calc(100% - 2rem - 96px + var(--geist-page-nav-height));
position: fixed;
top: 96px;
bottom: 2rem;
width: 200px;
margin-right: 20px;
-webkit-overflow-scrolling: touch;
-webkit-flex-shrink: 0;
height: calc(100% - 2rem - 140px + ${tabbarFixed ? '60px' : 0});
position: fixed;
top: 140px;
bottom: 2rem;
transform: translateY(${tabbarFixed ? '-60px' : 0});
transition: transform 200ms ease-out;
z-index: 100;
}
.side-shadow {
width: 220px;
flex-shrink: 0;
height: 100vh;
}
.main {
display: flex;
max-width: calc(100% - 220px);
Expand All @@ -107,28 +95,13 @@ export const Layout: React.FC<React.PropsWithChildren<LayoutProps>> = React.memo
padding: 20px 1rem;
}
.sidebar {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 10;
width: 100vw;
box-sizing: border-box;
height: ${expanded ? '100vh' : '0'};
background-color: ${theme.palette.background};
padding: var(--geist-page-nav-height) 0 0 0;
overflow: hidden;
transition: height 250ms ease;
display: none;
}
.main {
width: 90vw;
max-width: 90vw;
padding: 0;
}
.side-shadow {
display: none;
visibility: hidden;
}
}
`}</style>
</div>
Expand Down
186 changes: 176 additions & 10 deletions lib/components/layout/menu/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
import React, { useEffect, useState } from 'react'
import React, { useCallback, useEffect, useMemo, useState } from 'react'
import { useRouter } from 'next/router'
import MenuLinks from './menu-links'
import MenuSticker from './menu-sticker'
import NextLink from 'next/link'
import { Controls } from 'lib/components/pures'
import { useConfigs } from 'lib/config-context'
import { useBodyScroll, useTheme, Button, Image, useMediaQuery, Tabs } from 'components'
import { addColorAlpha } from 'components/utils/color'
import MenuIcon from '@geist-ui/icons/menu'
import MenuMobile from './menu-mobile'
import Metadata from 'lib/data'
import useLocale from 'lib/use-locale'

const Menu: React.FC<unknown> = () => {
const router = useRouter()
const theme = useTheme()
const { isChinese } = useConfigs()
const [showAfterRender, setShowAfterRender] = useState<boolean>(false)
useEffect(() => setShowAfterRender(true), [])
const { tabbar: currentUrlTabValue, locale } = useLocale()
const [expanded, setExpanded] = useState<boolean>(false)
const [, setBodyHidden] = useBodyScroll(null, { scrollLayer: true })
const isMobile = useMediaQuery('xs', { match: 'down' })
const allSides = useMemo(() => Metadata[locale], [locale])

useEffect(() => {
const prefetch = async () => {
const urls = isChinese
Expand All @@ -25,12 +36,167 @@ const Menu: React.FC<unknown> = () => {
.catch(err => console.log(err))
}, [isChinese])

if (!showAfterRender) return null
useEffect(() => {
setBodyHidden(expanded)
}, [expanded])

useEffect(() => {
if (!isMobile) {
setExpanded(false)
}
}, [isMobile])

useEffect(() => {
const handleRouteChange = () => {
setExpanded(false)
}

router.events.on('routeChangeComplete', handleRouteChange)
return () => router.events.off('routeChangeComplete', handleRouteChange)
}, [router.events])

const handleTabChange = useCallback(
(tab: string) => {
const shouldRedirectDefaultPage = currentUrlTabValue !== tab
if (!shouldRedirectDefaultPage) return
const defaultPath = `/${locale}/${tab}`
router.push(defaultPath)
},
[currentUrlTabValue],
)

return (
<div>
<MenuLinks />
<MenuSticker />
</div>
<>
<div className="menu-wrapper">
<nav className="menu">
<div className="content">
<div className="logo">
<NextLink href={`/${locale}`}>
<a aria-label="Go Home">
<Image
src="/images/logo.png"
width="20px"
height="20px"
mr={0.5}
draggable={false}
title="Logo"
/>
Geist
</a>
</NextLink>
</div>

<div className="tabs">
<Tabs
value={currentUrlTabValue}
leftSpace={0}
activeClassName="current"
align="center"
hideDivider
hideBorder
onChange={handleTabChange}>
<Tabs.Item font="14px" label={isChinese ? '主页' : 'Home'} value="" />
{allSides.map((tab, index) => (
<Tabs.Item
font="14px"
label={tab.localeName || tab.name}
value={tab.name}
key={`${tab.localeName || tab.name}-${index}`}
/>
))}
</Tabs>
</div>

<div className="controls">
{isMobile ? (
<Button
className="menu-toggle"
auto
type="abort"
onClick={() => setExpanded(!expanded)}>
<MenuIcon size="1.125rem" />
</Button>
) : (
<Controls />
)}
</div>
</div>
</nav>
</div>
<MenuMobile expanded={expanded} />

<style jsx>{`
.menu-wrapper {
height: var(--geist-page-nav-height);
}
.menu {
position: fixed;
top: 0;
height: var(--geist-page-nav-height);
width: 100%;
backdrop-filter: saturate(180%) blur(5px);
background-color: ${addColorAlpha(theme.palette.background, 0.8)};
box-shadow: ${theme.type === 'dark'
? '0 0 0 1px #333'
: '0 0 15px 0 rgba(0, 0, 0, 0.1)'};
z-index: 999;
}
nav .content {
display: flex;
align-items: center;
justify-content: space-between;
max-width: 1000px;
height: 100%;
margin: 0 auto;
user-select: none;
padding: 0 ${theme.layout.gap};
}
.logo {
flex: 1 1;
display: flex;
align-items: center;
justify-content: flex-start;
}
.logo a {
display: inline-flex;
flex-direction: row;
align-items: center;
font-size: 1.125rem;
font-weight: 500;
color: inherit;
height: 28px;
}
.logo :global(.image) {
border: 1px solid ${theme.palette.border};
border-radius: 2rem;
}
.tabs {
flex: 1 1;
padding: 0 ${theme.layout.gap};
}
.tabs :global(.content) {
display: none;
}
@media only screen and (max-width: ${theme.breakpoints.xs.max}) {
.tabs {
display: none;
}
}
.controls {
flex: 1 1;
display: flex;
align-items: center;
justify-content: flex-end;
}
.controls :global(.menu-toggle) {
display: flex;
align-items: center;
min-width: 40px;
height: 40px;
padding: 0;
}
`}</style>
</>
)
}

Expand Down
61 changes: 0 additions & 61 deletions lib/components/layout/menu/menu-links.tsx

This file was deleted.

Loading

0 comments on commit 65e0978

Please sign in to comment.