mirror of
https://github.com/zhigang1992/react.git
synced 2026-03-26 06:55:07 +08:00
docs: support chinese
This commit is contained in:
@@ -1,15 +1,16 @@
|
||||
import React from 'react'
|
||||
import { Spacer, Code, useTheme } from 'components'
|
||||
import VirtualAnchor from 'lib/components/anchor'
|
||||
import { useConfigs } from 'lib/config-context'
|
||||
|
||||
export interface AttributesTitleProps {
|
||||
alias?: string
|
||||
}
|
||||
|
||||
const getAlias = (alias?: string) => {
|
||||
const getAlias = (isChinese: boolean, alias?: string, ) => {
|
||||
if (!alias) return null
|
||||
return (
|
||||
<small><span>[</span>alias: <Code>{alias}</Code><span>]</span></small>
|
||||
<small><span>[</span>{isChinese ? '别名' : 'alias'}: <Code>{alias}</Code><span>]</span></small>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -17,12 +18,13 @@ const AttributesTitle: React.FC<React.PropsWithChildren<AttributesTitleProps>> =
|
||||
children, alias,
|
||||
}) => {
|
||||
const theme = useTheme()
|
||||
const { isChinese } = useConfigs()
|
||||
|
||||
return (
|
||||
<>
|
||||
<h4 className="title">
|
||||
<Code><VirtualAnchor pure>{children}</VirtualAnchor></Code>
|
||||
{getAlias(alias)}
|
||||
{getAlias(!!isChinese, alias)}
|
||||
</h4>
|
||||
<Spacer y={.6} />
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import React, { useMemo } from 'react'
|
||||
import { Card, Link, Spacer, useTheme } from 'components'
|
||||
import AttributesTitle from './attributes-title'
|
||||
import VirtualAnchor from 'lib/components/anchor'
|
||||
import { useConfigs } from '../../config-context'
|
||||
|
||||
export interface AttributesProps {
|
||||
edit: string
|
||||
@@ -11,6 +12,7 @@ const Attributes: React.FC<React.PropsWithChildren<AttributesProps>> = React.mem
|
||||
edit, children,
|
||||
}) => {
|
||||
const theme = useTheme()
|
||||
const { isChinese } = useConfigs()
|
||||
const link = useMemo(() => {
|
||||
return `https://github.com/zeit-ui/react/blob/master${edit || '/pages'}`
|
||||
}, [])
|
||||
@@ -18,12 +20,14 @@ const Attributes: React.FC<React.PropsWithChildren<AttributesProps>> = React.mem
|
||||
return (
|
||||
<>
|
||||
<Spacer y={5} />
|
||||
<h3><VirtualAnchor>Attributes</VirtualAnchor></h3>
|
||||
<h3><VirtualAnchor>APIs</VirtualAnchor>{isChinese && ' / 接口文档'}</h3>
|
||||
<Card className="attr">
|
||||
{children}
|
||||
</Card>
|
||||
<Spacer y={1} />
|
||||
<Link color target="_blank" className="attributes-link" href={link} rel="nofollow">Edit this page on GitHub</Link>
|
||||
<Link color target="_blank" className="attributes-link" href={link} rel="nofollow">
|
||||
{isChinese ? '在 GitHub 上编辑此页面' : 'Edit this page on GitHub'}
|
||||
</Link>
|
||||
|
||||
<style global jsx>{`
|
||||
.attr table {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { useCallback, useMemo } from 'react'
|
||||
import { Button, useTheme, Spacer } from 'components'
|
||||
import { useConfigs } from './config-context'
|
||||
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'
|
||||
@@ -8,19 +9,30 @@ import GithubIcon from './icons/github'
|
||||
const Controls: React.FC<{}> = React.memo(({
|
||||
}) => {
|
||||
const theme = useTheme()
|
||||
const config = useConfigs()
|
||||
const { onChange, updateChineseState } = useConfigs()
|
||||
const { pathname } = useRouter()
|
||||
const currentLocaleText = useMemo(() => {
|
||||
return pathname.toLowerCase().includes('zh-cn') ? 'EN' : '中'
|
||||
}, [pathname])
|
||||
const isDark = useMemo(() => theme.type === 'dark', [theme.type])
|
||||
const switchThemes = useCallback(() => {
|
||||
const isDark = theme.type === 'dark'
|
||||
config.onChange && config.onChange(!isDark)
|
||||
onChange && onChange(!isDark)
|
||||
}, [theme.type])
|
||||
|
||||
const switchLanguages = useCallback(() => {
|
||||
const currentIsChinese = pathname.toLowerCase().includes('zh-cn')
|
||||
const nextPath = `/${currentIsChinese ? 'en-us' : 'zh-cn'}`
|
||||
updateChineseState(!currentIsChinese)
|
||||
Router.push(nextPath)
|
||||
}, [pathname])
|
||||
|
||||
const redirectGithub = () => {
|
||||
if (typeof window !== 'undefined') {
|
||||
window.open('https://github.com/zeit-ui/react')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<div className="controls">
|
||||
<div className="tools">
|
||||
@@ -33,6 +45,10 @@ const Controls: React.FC<{}> = React.memo(({
|
||||
onClick={redirectGithub}>
|
||||
<GithubIcon width={16} height={16} />
|
||||
</Button>
|
||||
<Button className="button" auto type="abort"
|
||||
onClick={switchLanguages}>
|
||||
<span>{currentLocaleText}</span>
|
||||
</Button>
|
||||
</div>
|
||||
<style jsx>{`
|
||||
.controls {
|
||||
|
||||
@@ -1,37 +1,49 @@
|
||||
import React, { useState } from 'react'
|
||||
import { withRouter, Router } from 'next/router'
|
||||
import { useTheme } from 'components/index'
|
||||
import React, { useMemo, useState } from 'react'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useTheme } from 'components'
|
||||
import Controls from './controls'
|
||||
import Sidebar from './sidebar'
|
||||
import Controls from 'lib/components/controls'
|
||||
import sides from 'lib/data/metadata.json'
|
||||
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'
|
||||
|
||||
export interface Meta {
|
||||
title: string
|
||||
description: string
|
||||
editUrl?: string
|
||||
}
|
||||
|
||||
export interface Props {
|
||||
router: Router
|
||||
meta: Meta
|
||||
getStaticProps?: any
|
||||
}
|
||||
|
||||
export interface MultilLocaleMetaInformation {
|
||||
[key: string]: Sides[]
|
||||
}
|
||||
|
||||
export const Layout: React.FC<React.PropsWithChildren<Props>> = React.memo(({ children }) => {
|
||||
const theme = useTheme()
|
||||
const { pathname } = useRouter()
|
||||
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={sides}/>
|
||||
<Sidebar sides={sideData}/>
|
||||
</aside>
|
||||
<div className="side-shadow" />
|
||||
<main className="main">
|
||||
@@ -110,4 +122,4 @@ export const Layout: React.FC<React.PropsWithChildren<Props>> = React.memo(({ ch
|
||||
)
|
||||
})
|
||||
|
||||
export default withRouter(Layout)
|
||||
export default Layout
|
||||
|
||||
@@ -3,6 +3,7 @@ import { LivePreview, LiveProvider, LiveEditor, LiveError } from 'react-live'
|
||||
import withDefaults from 'components/utils/with-defaults'
|
||||
import useClipboard from 'components/utils/use-clipboard'
|
||||
import { useTheme, useToasts } from 'components'
|
||||
import { useConfigs } from '../../config-context'
|
||||
import makeCodeTheme from './code-theme'
|
||||
import RightIcon from 'lib/components/icons/right'
|
||||
import CopyIcon from 'lib/components/icons/copy'
|
||||
@@ -18,7 +19,6 @@ interface Props {
|
||||
}
|
||||
|
||||
const defaultProps = {
|
||||
title: 'Default',
|
||||
desc: '',
|
||||
code: '',
|
||||
bindings: {},
|
||||
@@ -26,7 +26,7 @@ const defaultProps = {
|
||||
|
||||
export type PlaygroundProps = Props & typeof defaultProps
|
||||
|
||||
const editor = (code: string, copy: Function) => {
|
||||
const editor = (code: string, copy: Function, isChinese: boolean) => {
|
||||
const theme = useTheme()
|
||||
const [visible, setVisible] = useState(false)
|
||||
|
||||
@@ -41,7 +41,7 @@ const editor = (code: string, copy: Function) => {
|
||||
event.stopPropagation()
|
||||
event.preventDefault()
|
||||
copy(code)
|
||||
setToast({ text: 'code copied.' })
|
||||
setToast({ text: isChinese ? '代码已拷贝至剪切板。' : 'code copied.' })
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -50,7 +50,7 @@ const editor = (code: string, copy: Function) => {
|
||||
<summary onClick={clickHandler}>
|
||||
<div>
|
||||
<RightIcon active={visible} />
|
||||
<span>Code Editor</span>
|
||||
<span>{isChinese ? '编辑代码' : 'Code Editor'}</span>
|
||||
</div>
|
||||
<div>
|
||||
{visible && <CopyIcon onClick={copyHandler} />}
|
||||
@@ -115,22 +115,26 @@ const editor = (code: string, copy: Function) => {
|
||||
)
|
||||
}
|
||||
|
||||
const Playground: React.FC<PlaygroundProps> = React.memo(props => {
|
||||
const Playground: React.FC<PlaygroundProps> = React.memo(({
|
||||
title: inputTitle, code: inputCode, desc, scope,
|
||||
}) => {
|
||||
const theme = useTheme()
|
||||
const { isChinese } = useConfigs()
|
||||
const codeTheme = makeCodeTheme(theme)
|
||||
const { copy } = useClipboard()
|
||||
const code = props.code.trim()
|
||||
const code = inputCode.trim()
|
||||
const title = inputTitle || (isChinese ? '基础的' : 'Default')
|
||||
|
||||
return (
|
||||
<>
|
||||
<Title title={props.title} desc={props.desc} />
|
||||
<Title title={title} desc={desc} />
|
||||
<div className="playground">
|
||||
<LiveProvider code={code} scope={props.scope} theme={codeTheme}>
|
||||
<LiveProvider code={code} scope={scope} theme={codeTheme}>
|
||||
<div className="wrapper">
|
||||
<LivePreview />
|
||||
<LiveError />
|
||||
</div>
|
||||
{editor(code, copy)}
|
||||
{editor(code, copy, !!isChinese)}
|
||||
</LiveProvider>
|
||||
|
||||
<style jsx>{`
|
||||
|
||||
@@ -4,32 +4,34 @@ import useTheme from 'components/styles/use-theme'
|
||||
|
||||
export interface Props {
|
||||
name: string
|
||||
localeName?: string
|
||||
}
|
||||
|
||||
const ActiveCatalog: React.FC<Props> = React.memo(
|
||||
({ name, ...props }) => {
|
||||
const theme = useTheme()
|
||||
const { pathname } = useRouter()
|
||||
const isActive = pathname.includes(`/${name}/`)
|
||||
|
||||
return (
|
||||
<span {...props} className={isActive ? 'active' : ''}>
|
||||
{name}
|
||||
<style jsx>{`
|
||||
span {
|
||||
font-size: .8125rem;
|
||||
transition: all .2s ease;
|
||||
color: ${theme.palette.accents_4};
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1.3px;
|
||||
}
|
||||
|
||||
.active {
|
||||
color: ${theme.palette.foreground};
|
||||
}
|
||||
`}</style>
|
||||
</span>
|
||||
)
|
||||
})
|
||||
const ActiveCatalog: React.FC<Props> = React.memo(({
|
||||
name, localeName, ...props
|
||||
}) => {
|
||||
const theme = useTheme()
|
||||
const { pathname } = useRouter()
|
||||
const isActive = pathname.includes(`/${name}/`)
|
||||
|
||||
return (
|
||||
<span {...props} className={isActive ? 'active' : ''}>
|
||||
{localeName || name}
|
||||
<style jsx>{`
|
||||
span {
|
||||
font-size: .8125rem;
|
||||
transition: all .2s ease;
|
||||
color: ${theme.palette.accents_4};
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1.3px;
|
||||
}
|
||||
|
||||
.active {
|
||||
color: ${theme.palette.foreground};
|
||||
}
|
||||
`}</style>
|
||||
</span>
|
||||
)
|
||||
})
|
||||
|
||||
export default ActiveCatalog
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { PropsWithChildren, useEffect, useRef } from 'react'
|
||||
import Router from 'next/router'
|
||||
import { useTheme, Spacer } from 'components'
|
||||
import SideItem, { SideItemProps, Sides } from './side-item'
|
||||
import { useConfigs } from '../config-context'
|
||||
import { useConfigs } from 'lib/config-context'
|
||||
|
||||
export interface Props {
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import { useTheme } from 'components'
|
||||
export type Sides = {
|
||||
name: string
|
||||
url?: string
|
||||
localeName?: string
|
||||
children?: Sides | Array<Sides>
|
||||
}
|
||||
|
||||
@@ -23,7 +24,7 @@ const SideItem: React.FC<React.PropsWithChildren<SideItemProps>> = React.memo(({
|
||||
{sides.map((side, index) => {
|
||||
return (
|
||||
<div key={`${side.name}-${index}`} className="item">
|
||||
{!side.url && <ActiveCatalog name={side.name} />}
|
||||
{!side.url && <ActiveCatalog name={side.name} localeName={side.localeName} />}
|
||||
{side.url && (
|
||||
<div className="link">
|
||||
<ActiveLink href={side.url}><a>{side.name}</a></ActiveLink>
|
||||
|
||||
@@ -2,6 +2,8 @@ import React from 'react'
|
||||
|
||||
export interface Configs {
|
||||
onChange?: Function
|
||||
isChinese?: boolean
|
||||
updateChineseState: Function
|
||||
sidebarScrollHeight: number
|
||||
updateSidebarScrollHeight: Function
|
||||
}
|
||||
@@ -9,6 +11,7 @@ export interface Configs {
|
||||
export const defaultConfigs: Configs = {
|
||||
sidebarScrollHeight: 0,
|
||||
updateSidebarScrollHeight: () => {},
|
||||
updateChineseState: () => {},
|
||||
}
|
||||
|
||||
export const ConfigContext = React.createContext<Configs>(defaultConfigs)
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { useMemo, useState } from 'react'
|
||||
import withDefaults from 'components/utils/with-defaults'
|
||||
import { ConfigContext, Configs } from './config-context'
|
||||
import { ConfigContext, Configs } from 'lib/config-context'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
interface Props {
|
||||
onChange?: Function
|
||||
@@ -14,12 +15,16 @@ export type ConfigProviderProps = Props & typeof defaultProps
|
||||
const ConfigProvider: React.FC<React.PropsWithChildren<ConfigProviderProps>> = React.memo(({
|
||||
onChange, children,
|
||||
}) => {
|
||||
const { pathname } = useRouter()
|
||||
const [isChinese, setIsChinese] = useState<boolean>(() => pathname.includes('zh-cn'))
|
||||
const [scrollHeight, setScrollHeight] = useState<number>(0)
|
||||
const updateSidebarScrollHeight = (height: number) => {
|
||||
setScrollHeight(height)
|
||||
}
|
||||
const updateSidebarScrollHeight = (height: number) => setScrollHeight(height)
|
||||
const updateChineseState = (state: boolean) => setIsChinese(state)
|
||||
|
||||
const initialValue = useMemo<Configs>(() => ({
|
||||
onChange,
|
||||
isChinese,
|
||||
updateChineseState,
|
||||
sidebarScrollHeight: scrollHeight,
|
||||
updateSidebarScrollHeight,
|
||||
}), [onChange, scrollHeight])
|
||||
Reference in New Issue
Block a user