mirror of
https://github.com/zhigang1992/react.git
synced 2026-01-29 17:18:13 +08:00
docs: add menu bar and optimize navigation
This commit is contained in:
@@ -1,10 +1,9 @@
|
||||
import React, { useCallback, useMemo } from 'react'
|
||||
import { Button, useTheme, Spacer } from 'components'
|
||||
import { Button, useTheme, Select, Spacer } from 'components'
|
||||
import { useConfigs } from 'lib/config-context'
|
||||
import Router, { useRouter } from 'next/router'
|
||||
import MoonIcon from './icons/moon'
|
||||
import SunIcon from './icons/sun'
|
||||
import GithubIcon from './icons/github'
|
||||
|
||||
const Controls: React.FC<{}> = React.memo(({
|
||||
}) => {
|
||||
@@ -12,14 +11,14 @@ const Controls: React.FC<{}> = React.memo(({
|
||||
const { onChange, updateChineseState } = useConfigs()
|
||||
const { pathname } = useRouter()
|
||||
const currentLocaleText = useMemo(() => {
|
||||
return pathname.toLowerCase().includes('zh-cn') ? 'EN' : '中'
|
||||
return pathname.toLowerCase().includes('zh-cn') ? 'English' : '中文文档'
|
||||
}, [pathname])
|
||||
const isDark = useMemo(() => theme.type === 'dark', [theme.type])
|
||||
const switchThemes = useCallback(() => {
|
||||
const isDark = theme.type === 'dark'
|
||||
onChange && onChange(!isDark)
|
||||
}, [theme.type])
|
||||
|
||||
const switchThemes = (val: string) => {
|
||||
const isDark = val === 'dark'
|
||||
onChange && onChange(isDark)
|
||||
}
|
||||
|
||||
const switchLanguages = useCallback(() => {
|
||||
const currentIsChinese = pathname.toLowerCase().includes('zh-cn')
|
||||
const nextPath = `/${currentIsChinese ? 'en-us' : 'zh-cn'}`
|
||||
@@ -36,39 +35,45 @@ const Controls: React.FC<{}> = React.memo(({
|
||||
return (
|
||||
<div className="controls">
|
||||
<div className="tools">
|
||||
<Spacer x={.5} />
|
||||
<Button className="button" auto type="abort"
|
||||
onClick={switchThemes}>
|
||||
{isDark ? <SunIcon width={16} height={16} /> : <MoonIcon width={16} height={16} />}
|
||||
</Button>
|
||||
<Button className="button" auto type="abort"
|
||||
onClick={redirectGithub}>
|
||||
<GithubIcon width={16} height={16} />
|
||||
</Button>
|
||||
<Button className="button" auto type="abort"
|
||||
onClick={switchLanguages}>
|
||||
<span>{currentLocaleText}</span>
|
||||
</Button>
|
||||
<Button auto type="abort" size="small" onClick={redirectGithub}>Github</Button>
|
||||
<Spacer x={.25} />
|
||||
<Button auto type="abort" size="small" onClick={switchLanguages}>{currentLocaleText}</Button>
|
||||
<Spacer x={.75} />
|
||||
<Select size="small" pure onChange={switchThemes} initialValue={isDark ? 'dark' : 'light'}>
|
||||
<Select.Option value="light">
|
||||
<div className="select-content">
|
||||
<SunIcon width={16} height={16} /> Light
|
||||
</div>
|
||||
</Select.Option>
|
||||
<Select.Option value="dark">
|
||||
<div className="select-content">
|
||||
<MoonIcon width={16} height={16} /> Dark
|
||||
</div>
|
||||
</Select.Option>
|
||||
</Select>
|
||||
</div>
|
||||
<style jsx>{`
|
||||
.controls {
|
||||
height: 110px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
flex-direction: column-reverse;
|
||||
margin: 0;
|
||||
padding-bottom: ${theme.layout.gapHalf};
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.controls :global(.button) {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
padding: 0;
|
||||
.controls :global(.select) {
|
||||
width: min-content;
|
||||
min-width: unset;
|
||||
}
|
||||
|
||||
.select-content {
|
||||
width: auto;
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.select-content :global(svg) {
|
||||
margin-right: .5rem;
|
||||
}
|
||||
|
||||
.tools {
|
||||
@@ -78,25 +83,6 @@ const Controls: React.FC<{}> = React.memo(({
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.tools:before {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
height: 1.25rem;
|
||||
width: .3125rem;
|
||||
background-color: ${theme.palette.accents_2};
|
||||
}
|
||||
|
||||
.controls :global(.line) {
|
||||
width: 150px;
|
||||
height: 55px;
|
||||
cursor: pointer;
|
||||
background-color: ${theme.palette.background};
|
||||
position: relative;
|
||||
z-index: 100;
|
||||
transition: all 200ms ease;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 767px) {
|
||||
.controls {
|
||||
display: none;
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import React, { useMemo, useState } from 'react'
|
||||
import { useRouter } from 'next/router'
|
||||
import React, { useState } from 'react'
|
||||
import { useTheme } from 'components'
|
||||
import Controls from './controls'
|
||||
import Sidebar from './sidebar'
|
||||
import { Sides } from './sidebar/side-item'
|
||||
import TabbarMobile from './sidebar/tabbar-mobile'
|
||||
import useBodyScroll from 'components/utils/use-body-scroll'
|
||||
import sides from 'lib/data/metadata.json'
|
||||
import { useConfigs } from '../config-context'
|
||||
|
||||
export interface Meta {
|
||||
title: string
|
||||
@@ -23,27 +21,19 @@ export interface MultilLocaleMetaInformation {
|
||||
|
||||
export const Layout: React.FC<React.PropsWithChildren<Props>> = React.memo(({ children }) => {
|
||||
const theme = useTheme()
|
||||
const { pathname } = useRouter()
|
||||
const { sides, tabbarFixed } = useConfigs()
|
||||
const [, setBodyScroll] = useBodyScroll(null, { scrollLayer: true })
|
||||
const [expanded, setExpanded] = useState<boolean>(false)
|
||||
const mobileTabbarClickHandler = () => {
|
||||
setExpanded(!expanded)
|
||||
setBodyScroll(!expanded)
|
||||
}
|
||||
const sideData = useMemo(() => {
|
||||
const language = pathname
|
||||
.split('/')
|
||||
.filter(r => !!r)
|
||||
const locale: string = language[0] || 'en-us'
|
||||
return (sides as MultilLocaleMetaInformation)[locale]
|
||||
}, [pathname, sides])
|
||||
|
||||
return (
|
||||
<div className="layout">
|
||||
<TabbarMobile onClick={mobileTabbarClickHandler} />
|
||||
<aside className="sidebar">
|
||||
<Controls />
|
||||
<Sidebar sides={sideData}/>
|
||||
<Sidebar sides={sides}/>
|
||||
</aside>
|
||||
<div className="side-shadow" />
|
||||
<main className="main">
|
||||
@@ -52,7 +42,7 @@ export const Layout: React.FC<React.PropsWithChildren<Props>> = React.memo(({ ch
|
||||
|
||||
<style jsx>{`
|
||||
.layout {
|
||||
min-height: 100vh;
|
||||
min-height: calc(100vh - 108px);
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
padding: 0 ${theme.layout.gap};
|
||||
@@ -65,10 +55,15 @@ export const Layout: React.FC<React.PropsWithChildren<Props>> = React.memo(({ ch
|
||||
margin-right: 20px;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
-webkit-flex-shrink: 0;
|
||||
height: 100%;
|
||||
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;
|
||||
|
||||
14
lib/components/menu/index.tsx
Normal file
14
lib/components/menu/index.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import React from 'react'
|
||||
import MenuLinks from './menu-links'
|
||||
import MenuSticker from './menu-sticker'
|
||||
|
||||
const Menu = () => {
|
||||
return (
|
||||
<div>
|
||||
<MenuLinks />
|
||||
<MenuSticker />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Menu
|
||||
33
lib/components/menu/menu-links.tsx
Normal file
33
lib/components/menu/menu-links.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
import React from 'react'
|
||||
import { useTheme } from 'components'
|
||||
import Controls from 'lib/components/controls'
|
||||
|
||||
|
||||
const MenuLinks = () => {
|
||||
const theme = useTheme()
|
||||
return (
|
||||
<nav>
|
||||
<div className="site-name">
|
||||
<h3>ZEIT UI - React</h3>
|
||||
</div>
|
||||
<div className="links">
|
||||
<Controls />
|
||||
</div>
|
||||
<style jsx>{`
|
||||
nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
max-width: 1000px;
|
||||
user-select: none;
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
padding: 0 ${theme.layout.gap};
|
||||
height: 60px;
|
||||
}
|
||||
`}</style>
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
|
||||
export default MenuLinks
|
||||
170
lib/components/menu/menu-sticker.tsx
Normal file
170
lib/components/menu/menu-sticker.tsx
Normal file
@@ -0,0 +1,170 @@
|
||||
import React, { useEffect, useMemo } from 'react'
|
||||
import { Tabs, useTheme } from 'components'
|
||||
import useCurrentState from 'components/utils/use-current-state'
|
||||
import sides from 'lib/data/metadata.json'
|
||||
import { Sides } from 'lib/components/sidebar/side-item'
|
||||
import Router, { useRouter } from 'next/router'
|
||||
import { useConfigs } from '../../config-context'
|
||||
|
||||
export interface MultilLocaleMetaInformation {
|
||||
[key: string]: Sides[]
|
||||
}
|
||||
|
||||
const MenuSticker = () => {
|
||||
const theme = useTheme()
|
||||
const { pathname } = useRouter()
|
||||
const { updateSides, updateTabbarFixed } = useConfigs()
|
||||
const [fixed, setFixed, fixedRef] = useCurrentState<boolean>(false)
|
||||
|
||||
useEffect(() => updateTabbarFixed(fixed), [fixed])
|
||||
|
||||
const tabbarData = useMemo(() => {
|
||||
const language = pathname
|
||||
.split('/')
|
||||
.filter(r => !!r)
|
||||
const locale: string = language[0] || 'en-us'
|
||||
return (sides as MultilLocaleMetaInformation)[locale]
|
||||
}, [pathname, sides])
|
||||
|
||||
const currentTabValue = useMemo(() => {
|
||||
const language = pathname
|
||||
.split('/')
|
||||
.filter(r => !!r)
|
||||
return language[1]
|
||||
}, [pathname])
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
const scrollHandler = () => {
|
||||
const shouldFixed = document.documentElement.scrollTop > 60
|
||||
if (shouldFixed === fixedRef.current) return
|
||||
setFixed(shouldFixed)
|
||||
}
|
||||
document.addEventListener('scroll', scrollHandler)
|
||||
return () => document.removeEventListener('scroll', scrollHandler)
|
||||
}, [])
|
||||
|
||||
const tabChangeHandler = (value: string) => {
|
||||
const currentTab = tabbarData.find(tab => tab.name === value)
|
||||
if (!currentTab || !Array.isArray(currentTab.children)) return
|
||||
|
||||
let firstChildren = currentTab.children
|
||||
if (Array.isArray(firstChildren[0].children)) {
|
||||
firstChildren = firstChildren[0].children
|
||||
}
|
||||
|
||||
const defaultPath = firstChildren[0].url
|
||||
if (!defaultPath) return
|
||||
updateSides(currentTab.children)
|
||||
Router.push(defaultPath)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
tabbarData && tabChangeHandler(currentTabValue)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={`nav-fill ${fixed ? 'active' : ''}`} />
|
||||
<nav className={fixed ? 'fixed' : ''}>
|
||||
<div className="sticker">
|
||||
<div className="inner">
|
||||
<Tabs value={currentTabValue} onChange={tabChangeHandler}>
|
||||
{tabbarData ? tabbarData.map(tab => (
|
||||
<Tabs.Item label={tab.localeName || tab.name}
|
||||
value={tab.name}
|
||||
key={tab.name} />
|
||||
)) : null}
|
||||
</Tabs>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<style jsx>{`
|
||||
.nav-fill {
|
||||
width: 0;
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.nav-fill.active {
|
||||
height: 48px;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
nav {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 48px;
|
||||
background-color: ${theme.palette.background};
|
||||
}
|
||||
|
||||
nav.fixed {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 3000;
|
||||
background-color: ${theme.palette.background};
|
||||
box-shadow: rgba(0, 0, 0, 0.1) 0 0 15px 0;
|
||||
}
|
||||
|
||||
.sticker {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.sticker:before {
|
||||
position: absolute;
|
||||
content: '';
|
||||
height: 1px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: ${theme.palette.border};
|
||||
}
|
||||
|
||||
.inner {
|
||||
max-width: 1000px;
|
||||
padding: 0 ${theme.layout.gap};
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
z-index: 1000;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.inner :global(.content) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.inner :global(.tabs), .inner :global(header) {
|
||||
height: 100%;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.inner :global(.tab) {
|
||||
height: calc(100% - 2px);
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
color: ${theme.palette.accents_5};
|
||||
font-size: .875rem;
|
||||
}
|
||||
|
||||
.inner :global(.tab):hover {
|
||||
color: ${theme.palette.foreground};
|
||||
}
|
||||
|
||||
.inner :global(.active) {
|
||||
color: ${theme.palette.foreground};
|
||||
}
|
||||
`}</style>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default MenuSticker
|
||||
@@ -56,7 +56,7 @@ export const Sidebar: React.FC<SideGroupProps> = React.memo(({ sides }) => {
|
||||
.box {
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
height: calc(100vh - 140px);
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React from 'react'
|
||||
import { Sides } from 'lib/components/sidebar/side-item'
|
||||
|
||||
export interface Configs {
|
||||
onChange?: Function
|
||||
@@ -6,12 +7,24 @@ export interface Configs {
|
||||
updateChineseState: Function
|
||||
sidebarScrollHeight: number
|
||||
updateSidebarScrollHeight: Function
|
||||
|
||||
sides: Sides[]
|
||||
updateSides: Function
|
||||
|
||||
tabbarFixed: boolean
|
||||
updateTabbarFixed: Function
|
||||
}
|
||||
|
||||
export const defaultConfigs: Configs = {
|
||||
sidebarScrollHeight: 0,
|
||||
updateSidebarScrollHeight: () => {},
|
||||
updateChineseState: () => {},
|
||||
|
||||
sides: [],
|
||||
updateSides: () => {},
|
||||
|
||||
tabbarFixed: false,
|
||||
updateTabbarFixed: () => {},
|
||||
}
|
||||
|
||||
export const ConfigContext = React.createContext<Configs>(defaultConfigs)
|
||||
|
||||
@@ -2,6 +2,7 @@ import React, { useMemo, useState } from 'react'
|
||||
import withDefaults from 'components/utils/with-defaults'
|
||||
import { ConfigContext, Configs } from 'lib/config-context'
|
||||
import { useRouter } from 'next/router'
|
||||
import { Sides } from 'lib/components/sidebar/side-item'
|
||||
|
||||
interface Props {
|
||||
onChange?: Function
|
||||
@@ -18,16 +19,21 @@ const ConfigProvider: React.FC<React.PropsWithChildren<ConfigProviderProps>> = R
|
||||
const { pathname } = useRouter()
|
||||
const [isChinese, setIsChinese] = useState<boolean>(() => pathname.includes('zh-cn'))
|
||||
const [scrollHeight, setScrollHeight] = useState<number>(0)
|
||||
const [sides, setSides] = useState<Sides[]>([] as Sides[])
|
||||
const [tabbarFixed, setTabbarFixed] = useState<boolean>(false)
|
||||
const updateSidebarScrollHeight = (height: number) => setScrollHeight(height)
|
||||
const updateChineseState = (state: boolean) => setIsChinese(state)
|
||||
const updateSides = (sides: Sides[]) => setSides(sides)
|
||||
const updateTabbarFixed = (state: boolean) => setTabbarFixed(state)
|
||||
|
||||
const initialValue = useMemo<Configs>(() => ({
|
||||
onChange,
|
||||
isChinese,
|
||||
onChange, sides, isChinese, tabbarFixed,
|
||||
updateSides,
|
||||
updateTabbarFixed,
|
||||
updateChineseState,
|
||||
sidebarScrollHeight: scrollHeight,
|
||||
updateSidebarScrollHeight,
|
||||
}), [onChange, scrollHeight])
|
||||
}), [onChange, scrollHeight, sides, tabbarFixed])
|
||||
|
||||
return (
|
||||
<ConfigContext.Provider value={initialValue}>
|
||||
|
||||
@@ -30,9 +30,29 @@ const nextConfig = {
|
||||
redirects() {
|
||||
return [
|
||||
{
|
||||
source: '/docs/:path*',
|
||||
source: '/docs/getting-started/:path*',
|
||||
permanent: true,
|
||||
destination: '/en-us/:path*'
|
||||
destination: '/en-us/guide/:path*'
|
||||
},
|
||||
{
|
||||
source: '/en-us/getting-started/:path*',
|
||||
permanent: true,
|
||||
destination: '/en-us/guide/:path*'
|
||||
},
|
||||
{
|
||||
source: '/en-us/customization/:path*',
|
||||
permanent: true,
|
||||
destination: '/en-us/guide/:path*'
|
||||
},
|
||||
{
|
||||
source: '/zh-cn/getting-started/:path*',
|
||||
permanent: true,
|
||||
destination: '/zh-cn/guide/:path*'
|
||||
},
|
||||
{
|
||||
source: '/zh-cn/customization/:path*',
|
||||
permanent: true,
|
||||
destination: '/zh-cn/guide/:path*'
|
||||
},
|
||||
{
|
||||
source: '/zh-cn/',
|
||||
|
||||
@@ -3,6 +3,7 @@ import { NextPage } from 'next'
|
||||
import { AppProps } from 'next/app'
|
||||
import { useCallback, useState } from 'react'
|
||||
import { CSSBaseline, ZEITUIProvider, useTheme } from 'components'
|
||||
import Menu from 'lib/components/menu'
|
||||
import ConfigContext from 'lib/config-provider'
|
||||
|
||||
const Application: NextPage<AppProps> = ({ Component, pageProps }) => {
|
||||
@@ -33,6 +34,7 @@ const Application: NextPage<AppProps> = ({ Component, pageProps }) => {
|
||||
<ZEITUIProvider theme={{ type: themeType }}>
|
||||
<CSSBaseline />
|
||||
<ConfigContext onChange={changeHandle}>
|
||||
<Menu />
|
||||
<Component {...pageProps} />
|
||||
</ConfigContext>
|
||||
<style global jsx>{`
|
||||
|
||||
@@ -4,7 +4,7 @@ import { useState, useRef, useEffect } from 'react'
|
||||
|
||||
export const meta = {
|
||||
title: 'Auto-Complete',
|
||||
description: 'auto-complete',
|
||||
group: 'Data Entry',
|
||||
}
|
||||
|
||||
## Auto Complete
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Avatar, Spacer } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'avatar',
|
||||
description: 'avatar',
|
||||
group: 'Data Display',
|
||||
}
|
||||
|
||||
## Avatar
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Badge, Spacer } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Badge',
|
||||
description: 'Badge',
|
||||
group: 'Data Display',
|
||||
}
|
||||
|
||||
## Badge
|
||||
|
||||
@@ -5,7 +5,7 @@ import { ButtonDropdown, Spacer } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'button-dropdown',
|
||||
description: 'tenotext',
|
||||
group: 'Navigation',
|
||||
index: 101,
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import Router from 'next/router'
|
||||
|
||||
export const meta = {
|
||||
title: 'button',
|
||||
description: 'tenotext',
|
||||
group: 'General',
|
||||
}
|
||||
|
||||
## Button
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Capacity, Spacer, useTheme } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Capacity',
|
||||
description: 'tenotext',
|
||||
group: 'Data Display'
|
||||
}
|
||||
|
||||
## Capacity
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Card } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'card',
|
||||
description: 'tenotext',
|
||||
group: 'Surfaces',
|
||||
}
|
||||
|
||||
## Card
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Checkbox, Spacer } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'checkbox',
|
||||
description: 'tenotext',
|
||||
group: 'Data Entry',
|
||||
}
|
||||
|
||||
## Checkbox
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
import { Layout, Playground, Attributes } from 'lib/components'
|
||||
import { Code, Note, Link } from 'components'
|
||||
import NextLink from 'next/link'
|
||||
|
||||
export const meta = {
|
||||
title: 'Code',
|
||||
description: 'tenotext',
|
||||
group: 'General',
|
||||
}
|
||||
|
||||
## Code
|
||||
|
||||
Show source code in a standardized way.
|
||||
|
||||
<Note>Want to display <Code>shell</Code> code snippets? Try <Link pure color href="/en-us/components/snippet">Snippet</Link>.</Note>
|
||||
<Note>
|
||||
Want to display <Code>shell</Code> code snippets?
|
||||
Try <NextLink href="/en-us/components/snippet"><Link pure color>Snippet</Link></NextLink>.
|
||||
</Note>
|
||||
|
||||
<Playground
|
||||
desc="Basic inline codes."
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Collapse, Spacer, Text } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'collapse',
|
||||
description: 'collapse',
|
||||
group: 'Surfaces',
|
||||
}
|
||||
|
||||
## Collapse
|
||||
|
||||
@@ -2,8 +2,8 @@ import { Layout, Playground, Attributes } from 'lib/components'
|
||||
import { Description, Code } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'description',
|
||||
description: 'tenotext',
|
||||
title: 'Description',
|
||||
group: 'Data Display',
|
||||
}
|
||||
|
||||
## Description
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Display, Code, Snippet } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Display',
|
||||
description: 'tenotext',
|
||||
group: 'Data Display',
|
||||
}
|
||||
|
||||
## Display
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Dot } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Dot',
|
||||
description: 'tenotext',
|
||||
group: 'Data Display',
|
||||
}
|
||||
|
||||
## Dot
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Card, Fieldset, Button, Text } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'fieldset',
|
||||
description: 'tenotext',
|
||||
group: 'Surfaces',
|
||||
}
|
||||
|
||||
## Fieldset
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Tree, useToasts } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'File-Tree',
|
||||
description: 'File-Tree',
|
||||
group: 'Data Display',
|
||||
}
|
||||
|
||||
## File Tree
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Image, Display, Code } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Image',
|
||||
description: 'tenotext',
|
||||
group: 'Data Display'
|
||||
}
|
||||
|
||||
## Image
|
||||
|
||||
@@ -5,6 +5,7 @@ import { useState, useEffect } from 'react'
|
||||
|
||||
export const meta = {
|
||||
title: 'Input',
|
||||
group: 'Data Entry',
|
||||
}
|
||||
|
||||
## Input
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Keyboard } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'keyboard',
|
||||
description: 'tenotext',
|
||||
group: 'Data Display',
|
||||
}
|
||||
|
||||
## Keyboard
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Row, Col } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'layout',
|
||||
description: 'tenotext',
|
||||
group: 'layout',
|
||||
}
|
||||
|
||||
## Layout
|
||||
|
||||
@@ -4,7 +4,7 @@ import NextLink from 'next/link'
|
||||
|
||||
export const meta = {
|
||||
title: 'link',
|
||||
description: 'tenotext',
|
||||
group: 'Navigation',
|
||||
}
|
||||
|
||||
## Link
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Loading, Spacer, Row } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Loading',
|
||||
description: 'Loading',
|
||||
group: 'Feedback',
|
||||
}
|
||||
|
||||
## Loading
|
||||
|
||||
@@ -1,16 +1,21 @@
|
||||
import { Layout, Playground, Attributes } from 'lib/components'
|
||||
import { Modal, Button, Code, useModal, Note, Link } from 'components'
|
||||
import NextLink from 'next/link'
|
||||
import { useState } from 'react'
|
||||
|
||||
export const meta = {
|
||||
title: 'modal',
|
||||
group: 'Feedback',
|
||||
}
|
||||
|
||||
## Modal
|
||||
|
||||
Display popup content that requires attention or provides additional information.
|
||||
|
||||
<Note>Just want a text notification? Try <Link pure color href="/en-us/components/toast">Toast component</Link>.</Note>
|
||||
<Note>
|
||||
Just want a text notification?
|
||||
Try <NextLink href="/en-us/components/toast"><Link pure color>Toast component</Link></NextLink>.
|
||||
</Note>
|
||||
|
||||
<Playground
|
||||
title="Basic"
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Note } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'note',
|
||||
description: 'tenotext',
|
||||
group: 'Feedback',
|
||||
}
|
||||
|
||||
## Note
|
||||
|
||||
@@ -4,6 +4,7 @@ import { useState } from 'react'
|
||||
|
||||
export const meta = {
|
||||
title: 'Progress',
|
||||
group: 'Feedback',
|
||||
}
|
||||
|
||||
## Progress
|
||||
|
||||
@@ -4,7 +4,7 @@ import { useState } from 'react'
|
||||
|
||||
export const meta = {
|
||||
title: 'radio',
|
||||
description: 'avatar',
|
||||
group: 'Data Entry',
|
||||
}
|
||||
|
||||
## Radio
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Select, Spacer, Code } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'select',
|
||||
description: 'select',
|
||||
group: 'Data Entry',
|
||||
}
|
||||
|
||||
## Select
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Snippet, Spacer, Code } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Snippet',
|
||||
description: 'Snippet',
|
||||
group: 'Others',
|
||||
}
|
||||
|
||||
## Snippet
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Spacer, Container, Col } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Spacer',
|
||||
description: 'tenotext',
|
||||
group: 'General',
|
||||
}
|
||||
|
||||
## Spacer
|
||||
|
||||
@@ -4,7 +4,7 @@ import NextLink from 'next/link'
|
||||
|
||||
export const meta = {
|
||||
title: 'Spinner',
|
||||
description: 'tenotext',
|
||||
group: 'Feedback',
|
||||
}
|
||||
|
||||
## Spinner
|
||||
|
||||
@@ -3,6 +3,7 @@ import { Table, Spacer, Code, Text, Button } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Table',
|
||||
group: 'Data Display',
|
||||
}
|
||||
|
||||
## Table
|
||||
|
||||
@@ -7,6 +7,7 @@ import ReactIcon from 'lib/components/icons/react'
|
||||
|
||||
export const meta = {
|
||||
title: 'tabs',
|
||||
group: 'Navigation',
|
||||
}
|
||||
|
||||
## Tabs
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Tag } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Tag',
|
||||
description: 'tenotext',
|
||||
group: 'Data Display',
|
||||
}
|
||||
|
||||
## Tag
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Text } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'text',
|
||||
description: 'text',
|
||||
group: 'General',
|
||||
}
|
||||
|
||||
## Text
|
||||
|
||||
@@ -4,6 +4,7 @@ import { useState } from 'react'
|
||||
|
||||
export const meta = {
|
||||
title: 'textarea',
|
||||
group: 'Data Entry',
|
||||
}
|
||||
|
||||
## Textarea
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useToasts, Button, Spacer } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'toast',
|
||||
description: 'tenotext',
|
||||
group: 'Feedback',
|
||||
}
|
||||
|
||||
## Toast
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Toggle, Spacer } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Toggle',
|
||||
description: 'Toggle',
|
||||
group: 'Data Entry',
|
||||
}
|
||||
|
||||
## Toggle
|
||||
|
||||
@@ -5,7 +5,7 @@ import Colors from 'lib/components/displays/colors'
|
||||
|
||||
export const meta = {
|
||||
title: 'Colors',
|
||||
description: 'description',
|
||||
group: 'customization',
|
||||
}
|
||||
|
||||
## Colors
|
||||
@@ -3,7 +3,7 @@ import { Note, Link, Code, Spacer, Tabs, Row, Dot, Display, Snippet } from 'comp
|
||||
|
||||
export const meta = {
|
||||
title: 'installation',
|
||||
description: 'description',
|
||||
group: 'getting-started',
|
||||
index: 10,
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { Code, Link, Text, Spacer, Note } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'introduction',
|
||||
group: 'getting-started',
|
||||
index: 5,
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Code, Link, Text, Spacer, Note } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Server Render',
|
||||
description: 'description',
|
||||
group: 'getting-started',
|
||||
index: 15,
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Note, Code, Spacer, Link } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Themes',
|
||||
description: 'description',
|
||||
group: 'customization',
|
||||
}
|
||||
|
||||
## Themes
|
||||
@@ -3,7 +3,8 @@ import { AutoComplete, Spacer, Badge, Row } from 'components'
|
||||
import { useState, useRef, useEffect } from 'react'
|
||||
|
||||
export const meta = {
|
||||
title: 'Auto-Complete / 自动完成',
|
||||
title: '自动完成 Auto-Complete',
|
||||
group: '数据录入',
|
||||
index: 104,
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@ import { Layout, Playground, Attributes } from 'lib/components'
|
||||
import { Avatar, Spacer } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'avatar / 头像',
|
||||
description: 'avatar',
|
||||
title: '头像 Avatar',
|
||||
group: '数据展示',
|
||||
}
|
||||
|
||||
## Avatar / 头像
|
||||
|
||||
@@ -2,7 +2,8 @@ import { Layout, Playground, Attributes } from 'lib/components'
|
||||
import { Badge, Spacer } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Badge / 徽章',
|
||||
title: '徽章 Badge',
|
||||
group: '数据展示',
|
||||
}
|
||||
|
||||
## Badge / 徽章
|
||||
|
||||
@@ -4,7 +4,8 @@ import Playground from 'lib/components/playground'
|
||||
import { ButtonDropdown, Spacer } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Btn-Dropdown / 下拉按钮',
|
||||
title: '下拉按钮 Btn Dropdown',
|
||||
group: '导航',
|
||||
index: 105,
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,8 @@ import { Button, Spacer } from 'components'
|
||||
import Router from 'next/router'
|
||||
|
||||
export const meta = {
|
||||
title: 'Button / 按钮',
|
||||
title: '按钮 Button',
|
||||
group: '通用',
|
||||
}
|
||||
|
||||
## Button / 按钮
|
||||
|
||||
@@ -2,7 +2,8 @@ import { Layout, Playground, Attributes } from 'lib/components'
|
||||
import { Capacity, Spacer, useTheme } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Capacity / 容量',
|
||||
title: '容量 Capacity',
|
||||
group: '数据展示',
|
||||
}
|
||||
|
||||
## Capacity / 容量
|
||||
|
||||
@@ -2,8 +2,8 @@ import { Layout, Playground, Attributes } from 'lib/components'
|
||||
import { Card } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Card / 卡片',
|
||||
description: 'tenotext',
|
||||
title: '卡片 Card',
|
||||
group: '表面',
|
||||
}
|
||||
|
||||
## Card / 卡片
|
||||
|
||||
@@ -2,7 +2,8 @@ import { Layout, Playground, Attributes } from 'lib/components'
|
||||
import { Checkbox, Spacer } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Checkbox / 复选框',
|
||||
title: '复选框 Checkbox',
|
||||
group: '数据录入',
|
||||
}
|
||||
|
||||
## Checkbox / 复选框
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
import { Layout, Playground, Attributes } from 'lib/components'
|
||||
import { Code, Note, Link } from 'components'
|
||||
import NextLink from 'next/link'
|
||||
|
||||
export const meta = {
|
||||
title: 'Code / 代码',
|
||||
title: '代码 Code',
|
||||
group: '通用',
|
||||
}
|
||||
|
||||
## Code / 代码
|
||||
|
||||
以标准化的方式展示源代码。
|
||||
|
||||
<Note label="提示">想要展示 <Code>Shell</Code> 代码片段或一个命令?可以试试 <Link pure color href="/zh-cn/components/snippet">Snippet / 片段</Link> 组件。</Note>
|
||||
<Note label="提示">
|
||||
想要展示 <Code>Shell</Code> 代码片段或一个命令?
|
||||
可以试试 <NextLink href="/zh-cn/components/snippet"><Link pure color>Snippet / 片段</Link></NextLink> 组件。
|
||||
</Note>
|
||||
|
||||
<Playground
|
||||
desc="基础的行内代码。"
|
||||
|
||||
@@ -2,7 +2,8 @@ import { Layout, Playground, Attributes } from 'lib/components'
|
||||
import { Collapse, Spacer, Text, Code } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Collapse / 折叠框',
|
||||
title: '折叠框 Collapse',
|
||||
group: '表面',
|
||||
}
|
||||
|
||||
## Collapse / 折叠框
|
||||
|
||||
@@ -2,7 +2,8 @@ import { Layout, Playground, Attributes } from 'lib/components'
|
||||
import { Description, Code } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Description / 描述',
|
||||
title: '描述 Description',
|
||||
group: '数据展示',
|
||||
}
|
||||
|
||||
## Description / 描述
|
||||
|
||||
@@ -2,8 +2,8 @@ import { Layout, Playground, Attributes } from 'lib/components'
|
||||
import { Display, Code, Snippet } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Display / 陈列框',
|
||||
description: 'tenotext',
|
||||
title: '陈列框 Display',
|
||||
group: '数据展示',
|
||||
}
|
||||
|
||||
## Display / 陈列框
|
||||
|
||||
@@ -2,8 +2,8 @@ import { Layout, Playground, Attributes } from 'lib/components'
|
||||
import { Dot } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Dot / 点',
|
||||
description: 'tenotext',
|
||||
title: '点 Dot',
|
||||
group: '数据展示',
|
||||
}
|
||||
|
||||
## Dot / 点
|
||||
|
||||
@@ -2,8 +2,8 @@ import { Layout, Playground, Attributes } from 'lib/components'
|
||||
import { Card, Fieldset, Button, Text } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Fieldset / 控件组',
|
||||
description: 'tenotext',
|
||||
title: '控件组 Fieldset',
|
||||
group: '表面',
|
||||
}
|
||||
|
||||
## Fieldset / 控件组
|
||||
|
||||
@@ -2,8 +2,8 @@ import { Layout, Playground, Attributes } from 'lib/components'
|
||||
import { Tree, useToasts } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'File-Tree / 文件树',
|
||||
description: 'File-Tree',
|
||||
title: '文件树 File Tree',
|
||||
group: '数据展示',
|
||||
}
|
||||
|
||||
## File-Tree / 文件树
|
||||
|
||||
@@ -2,8 +2,8 @@ import { Layout, Playground, Attributes } from 'lib/components'
|
||||
import { Image, Display, Code } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Image / 图片',
|
||||
description: 'tenotext',
|
||||
title: '图片 Image',
|
||||
group: '数据展示',
|
||||
}
|
||||
|
||||
## Image / 图片
|
||||
|
||||
@@ -4,7 +4,8 @@ import { Input, Spacer, useInput, Button, Code, Text, Dot } from 'components'
|
||||
import { useState, useEffect } from 'react'
|
||||
|
||||
export const meta = {
|
||||
title: 'Input / 输入框',
|
||||
title: '输入框 Input',
|
||||
group: '数据录入',
|
||||
}
|
||||
|
||||
## Input / 输入框
|
||||
|
||||
@@ -2,8 +2,8 @@ import { Layout, Playground, Attributes } from 'lib/components'
|
||||
import { Keyboard } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'keyboard / 键盘',
|
||||
description: 'tenotext',
|
||||
title: '键盘 keyboard',
|
||||
group: '数据展示',
|
||||
}
|
||||
|
||||
## Keyboard / 键盘
|
||||
|
||||
@@ -2,8 +2,8 @@ import { Layout, Playground, ExampleBlock, Attributes } from 'lib/components'
|
||||
import { Row, Col } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Layout / 布局',
|
||||
description: 'tenotext',
|
||||
title: '布局 Layout',
|
||||
group: '布局',
|
||||
}
|
||||
|
||||
## Layout / 布局
|
||||
|
||||
@@ -3,8 +3,8 @@ import { Link, Text, Code } from 'components'
|
||||
import NextLink from 'next/link'
|
||||
|
||||
export const meta = {
|
||||
title: 'Link / 链接',
|
||||
description: 'tenotext',
|
||||
title: '链接 Link',
|
||||
group: '导航',
|
||||
}
|
||||
|
||||
## Link / 链接
|
||||
|
||||
@@ -2,8 +2,8 @@ import { Layout, Playground, Attributes } from 'lib/components'
|
||||
import { Loading, Spacer, Row } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Loading / 加载中',
|
||||
description: 'Loading',
|
||||
title: '加载中 Loading',
|
||||
group: '反馈',
|
||||
}
|
||||
|
||||
## Loading / 加载中
|
||||
|
||||
@@ -1,16 +1,21 @@
|
||||
import { Layout, Playground, Attributes } from 'lib/components'
|
||||
import { Modal, Button, Code, useModal, Note, Link } from 'components'
|
||||
import NextLink from 'next/link'
|
||||
import { useState } from 'react'
|
||||
|
||||
export const meta = {
|
||||
title: 'Modal / 对话框',
|
||||
title: '对话框 Modal',
|
||||
group: '反馈',
|
||||
}
|
||||
|
||||
## Modal / 对话框
|
||||
|
||||
弹出显示需要额外注意或重要的内容。
|
||||
|
||||
<Note>仅仅需要弹出文本信息?试试 <Link pure color href="/zh-cn/components/toast">Toast / 通知</Link> 组件。</Note>
|
||||
<Note>
|
||||
仅仅需要弹出文本信息?
|
||||
试试 <NextLink href="/zh-cn/components/toast"><Link pure color>Toast / 通知</Link></NextLink> 组件。
|
||||
</Note>
|
||||
|
||||
<Playground
|
||||
desc="使用 `open` 属性控制何时显示对话框。"
|
||||
|
||||
@@ -2,7 +2,8 @@ import { Layout, Playground, Attributes } from 'lib/components'
|
||||
import { Note, Code } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Note / 提示',
|
||||
title: '提示 Note',
|
||||
group: '反馈',
|
||||
}
|
||||
|
||||
## Note / 提示
|
||||
|
||||
@@ -3,7 +3,8 @@ import { Progress, Spacer, useTheme, Button } from 'components'
|
||||
import { useState } from 'react'
|
||||
|
||||
export const meta = {
|
||||
title: 'Progress / 进度条',
|
||||
title: '进度条 Progress',
|
||||
group: '反馈',
|
||||
}
|
||||
|
||||
## Progress / 进度条
|
||||
|
||||
@@ -3,7 +3,8 @@ import { Radio, Spacer, Code, Text } from 'components'
|
||||
import { useState } from 'react'
|
||||
|
||||
export const meta = {
|
||||
title: 'Radio / 单选框',
|
||||
title: '单选框 Radio',
|
||||
group: '数据录入',
|
||||
}
|
||||
|
||||
## Radio / 单选框
|
||||
|
||||
@@ -2,7 +2,8 @@ import { Layout, Playground, Attributes } from 'lib/components'
|
||||
import { Select, Spacer, Code } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Select / 选择器',
|
||||
title: '选择器 Select',
|
||||
group: '数据录入',
|
||||
}
|
||||
|
||||
## Select / 选择器
|
||||
|
||||
@@ -2,7 +2,8 @@ import { Layout, Playground, Attributes } from 'lib/components'
|
||||
import { Snippet, Spacer, Code } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Snippet / 片段',
|
||||
title: '片段 Snippet',
|
||||
group: '其他',
|
||||
}
|
||||
|
||||
## Snippet / 片段
|
||||
|
||||
@@ -2,8 +2,8 @@ import { Layout, Playground, Attributes } from 'lib/components'
|
||||
import { Spacer, Container, Col } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Spacer / 间距',
|
||||
description: 'tenotext',
|
||||
title: 'Spacer 间距',
|
||||
group: '通用',
|
||||
}
|
||||
|
||||
## Spacer / 间距
|
||||
|
||||
@@ -3,7 +3,8 @@ import { Spinner, Spacer, Note, Code, Link } from 'components'
|
||||
import NextLink from 'next/link'
|
||||
|
||||
export const meta = {
|
||||
title: 'Spinner / 指示器',
|
||||
title: '指示器 Spinner',
|
||||
group: '反馈',
|
||||
}
|
||||
|
||||
## Spinner / 指示器
|
||||
|
||||
@@ -2,7 +2,8 @@ import { Layout, Playground, Attributes } from 'lib/components'
|
||||
import { Table, Spacer, Code, Text, Button } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Table / 表格',
|
||||
title: '表格 Table',
|
||||
group: '数据展示',
|
||||
}
|
||||
|
||||
## Table / 表格
|
||||
|
||||
@@ -6,7 +6,8 @@ import ZeitIcon from 'lib/components/icons/zeit'
|
||||
import ReactIcon from 'lib/components/icons/react'
|
||||
|
||||
export const meta = {
|
||||
title: 'Tabs / 选项卡',
|
||||
title: '选项卡 Tabs',
|
||||
group: '导航',
|
||||
}
|
||||
|
||||
## Tabs / 选项卡
|
||||
|
||||
@@ -2,7 +2,8 @@ import { Layout, Playground, Attributes } from 'lib/components'
|
||||
import { Tag, Spacer } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Tag / 标签',
|
||||
title: '标签 Tag',
|
||||
group: '数据展示',
|
||||
}
|
||||
|
||||
## Tag / 标签
|
||||
|
||||
@@ -2,7 +2,8 @@ import { Layout, Playground, Attributes } from 'lib/components'
|
||||
import { Text } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Text / 文本',
|
||||
title: '文本 Text',
|
||||
group: '通用',
|
||||
}
|
||||
|
||||
## Text / 文本
|
||||
|
||||
@@ -3,7 +3,8 @@ import { Textarea, Spacer, useInput, Button, Code } from 'components'
|
||||
import { useState } from 'react'
|
||||
|
||||
export const meta = {
|
||||
title: 'Textarea / 文本输入框',
|
||||
title: '文本输入框 Textarea',
|
||||
group: '数据录入',
|
||||
}
|
||||
|
||||
## Textarea / 文本输入框
|
||||
|
||||
@@ -2,7 +2,8 @@ import { Layout, Playground, Attributes } from 'lib/components'
|
||||
import { useToasts, Button, Spacer } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Toast / 通知',
|
||||
title: '通知 Toast',
|
||||
group: '反馈',
|
||||
}
|
||||
|
||||
## Toast / 通知
|
||||
|
||||
@@ -2,7 +2,8 @@ import { Layout, Playground, Attributes } from 'lib/components'
|
||||
import { Toggle, Spacer } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: 'Toggle / 开关',
|
||||
title: '开关 Toggle',
|
||||
group: '数据录入',
|
||||
}
|
||||
|
||||
## Toggle / 开关
|
||||
|
||||
@@ -5,6 +5,7 @@ import Colors from 'lib/components/displays/colors'
|
||||
|
||||
export const meta = {
|
||||
title: '色彩',
|
||||
group: '定制化',
|
||||
}
|
||||
|
||||
## 色彩
|
||||
@@ -3,6 +3,7 @@ import { Note, Link, Code, Spacer, Tabs, Row, Dot, Display, Snippet } from 'comp
|
||||
|
||||
export const meta = {
|
||||
title: '安装',
|
||||
group: '快速上手',
|
||||
index: 10,
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { Code, Link, Text, Spacer, Note } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: '什么是 ZEIT UI',
|
||||
group: '快速上手',
|
||||
index: 5,
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { Code, Link, Text, Spacer, Note } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: '服务端渲染',
|
||||
group: '快速上手',
|
||||
index: 15,
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { Note, Code, Spacer, Link } from 'components'
|
||||
|
||||
export const meta = {
|
||||
title: '主题',
|
||||
group: '定制化',
|
||||
}
|
||||
|
||||
## 主题
|
||||
@@ -5,9 +5,32 @@ const metaLocales = require('./locales')
|
||||
const pagePrefix = path.join(__dirname, '../pages')
|
||||
const targetPath = path.join(__dirname, '../lib/data/metadata.json')
|
||||
const weights = {
|
||||
'getting-started': 1,
|
||||
'customization': 2,
|
||||
'components': 3,
|
||||
'guide': 1,
|
||||
'docs': 2,
|
||||
'getting-started': 3,
|
||||
'customization': 4,
|
||||
'components': 5,
|
||||
}
|
||||
const groupWeights = {
|
||||
'快速上手': 1,
|
||||
'起步': 2,
|
||||
'定制化': 5,
|
||||
'general': 1,
|
||||
'通用': 1,
|
||||
'layout': 2,
|
||||
'布局': 2,
|
||||
'surfaces': 3,
|
||||
'表面': 3,
|
||||
'data entry': 4,
|
||||
'数据录入': 4,
|
||||
'data display': 5,
|
||||
'数据展示': 5,
|
||||
'feedback': 6,
|
||||
'反馈': 6,
|
||||
'navigation': 7,
|
||||
'导航': 7,
|
||||
'others': 8,
|
||||
'其他': 8,
|
||||
}
|
||||
|
||||
const getMetadata = async (files, parentPath) => {
|
||||
@@ -21,6 +44,27 @@ const getMetadata = async (files, parentPath) => {
|
||||
const children = await fs.readdir(filePath)
|
||||
const childrenMetadata = await getMetadata(children, filePath)
|
||||
const sorted = childrenMetadata.sort((a, b) => a.index - b.index)
|
||||
|
||||
// grouping
|
||||
const childrenHasGroup = sorted.find(item => item.group)
|
||||
if (childrenHasGroup) {
|
||||
const groups = [...new Set(sorted.map(item => item.group || 'others'))]
|
||||
const groupChildren = groups
|
||||
.map(groupName => ({
|
||||
name: groupName,
|
||||
children: sorted.filter(item => (item.group || 'others') === groupName)
|
||||
}))
|
||||
.sort((a, b) => {
|
||||
const pre = a.name.toLowerCase()
|
||||
const current = b.name.toLowerCase()
|
||||
return groupWeights[pre] - groupWeights[current]
|
||||
})
|
||||
return {
|
||||
name: file,
|
||||
children: groupChildren,
|
||||
}
|
||||
}
|
||||
|
||||
return { name: file, children: sorted }
|
||||
}
|
||||
const content = await fs.readFile(filePath, 'utf-8')
|
||||
@@ -28,11 +72,32 @@ const getMetadata = async (files, parentPath) => {
|
||||
const url = filePath
|
||||
.replace(pagePrefix, '')
|
||||
.replace('.mdx', '')
|
||||
return { name: meta.title || file, url, index: meta.index || 100 }
|
||||
return {
|
||||
name: meta.title || file,
|
||||
url,
|
||||
index: meta.index || 100,
|
||||
group: meta.group || null,
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
const deepTranslate = (metadata, locales) => {
|
||||
if (!metadata || !Array.isArray(metadata)) return metadata
|
||||
return metadata.map(data => {
|
||||
if (typeof data !== 'object') return data
|
||||
if (data.children) {
|
||||
data.children = deepTranslate(data.children, locales)
|
||||
}
|
||||
const localeName = locales[data.name]
|
||||
if (!localeName) return data
|
||||
return {
|
||||
...data,
|
||||
localeName,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
;(async () => {
|
||||
try {
|
||||
const locales = (await fs.readdir(pagePrefix))
|
||||
@@ -49,18 +114,11 @@ const getMetadata = async (files, parentPath) => {
|
||||
const data = await getMetadata(childDirs, dir)
|
||||
const sorted = data
|
||||
.sort((a, b) => weights[a.name] - weights[b.name])
|
||||
.map(item => {
|
||||
const localeName = currentLocale[item.name]
|
||||
if (!localeName) return item
|
||||
return {
|
||||
...item,
|
||||
localeName: localeName
|
||||
}
|
||||
})
|
||||
const translatedData = deepTranslate(sorted, currentLocale)
|
||||
|
||||
return {
|
||||
name,
|
||||
content: sorted
|
||||
content: translatedData
|
||||
}
|
||||
}))
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ module.exports = {
|
||||
'getting-started': '快速开始',
|
||||
customization: '定制化',
|
||||
components: '所有组件',
|
||||
guide: '上手指南',
|
||||
docs: '文档',
|
||||
},
|
||||
'en-us': {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user