Merge branch 'master' of github.com:ant-design/ant-design

This commit is contained in:
afc163 2016-05-17 00:01:48 +08:00
commit 511bfa73c1
69 changed files with 1050 additions and 759 deletions

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 固钉
type: 其它
type: Other
english: Affix
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 警告提示
type: 展示
type: Presentation
english: Alert
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 徽标数
type: 展示
type: Presentation
english: Badge
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 面包屑
type: 导航
type: Navigation
english: Breadcrumb
---

View File

@ -1,28 +1,36 @@
---
order: 0
title: 按钮类型
title:
zh-CN: 按钮类型
en-US: Type
---
按钮有三种类型:主按钮、次按钮、幽灵按钮。
## zh-CN
通过设置 `type``primary` `ghost` 可分别创建主按钮、幽灵按钮,若不设置 `type` 值则为次按钮。不同的样式可以用来区别其重要程度
按钮有四种类型:主按钮、次按钮、幽灵按钮、虚线按钮
主按钮和次按钮可独立使用,需要强引导用主按钮。幽灵按钮用于和主按钮组合。主按钮在同一个操作区域最多出现一次。
通过设置 `type``primary` `ghost` `dashed` 可分别创建主按钮、幽灵按钮、虚线按钮,若不设置 `type` 值则为次按钮。不同的样式可以用来区别其重要程度。
主按钮和次按钮可独立使用,幽灵按钮用于和主按钮组合。需要强引导用主按钮,切记主按钮在同一个操作区域最多出现一次。
## en-US
There are primary button, default button, ghost button and dashed button in antd.
`type` can be set as `primary` or `ghost` or `dashed`, in order to create primary button or ghost button or dashed button. If nothing is provided to `type`, we will get default button. Users can tell the significance of button from it's appearance.
Primary button and default button can be used without other button, but ghost button must be used with primary button.
````jsx
import { Button } from 'antd';
ReactDOM.render(<div>
<Button type="primary">主按钮</Button>
<Button>次按钮</Button>
<Button type="ghost">幽灵按钮</Button>
<Button type="dashed">虚线按钮</Button>
</div>, mountNode);
ReactDOM.render(
<div>
<Button type="primary">Primary</Button>
<Button>Default</Button>
<Button type="ghost">Ghost</Button>
<Button type="dashed">Dashed</Button>
</div>,
mountNode
);
````
<style>
#components-button-demo-basic .ant-btn {
margin-right: 8px;
margin-bottom: 12px;
}
</style>

View File

@ -1,65 +1,75 @@
---
order: 5
title: 按钮组合
title:
zh-CN: 按钮组合
en-US: Button Group
---
## zh-CN
可以将多个 `Button` 放入 `Button.Group` 的容器中。
通过设置 `size``large` `small` 分别把按钮组合设为大、小尺寸。若不设置 `size`,则尺寸为中。
## en-US
Buttons can be grouped by placing multiple `Button` components into a `Button.Group`.
The `size` can be set to `large`, `small` or left unset resulting in a default size.
````jsx
import { Button, Icon } from 'antd';
const ButtonGroup = Button.Group;
ReactDOM.render(<div>
<h4>基本组合</h4>
<ButtonGroup>
<Button type="primary">确定</Button>
<Button type="primary">取消</Button>
</ButtonGroup>
<ButtonGroup>
<Button disabled></Button>
<Button disabled></Button>
<Button disabled></Button>
</ButtonGroup>
<ButtonGroup>
<Button type="primary"></Button>
<Button type="ghost"></Button>
<Button type="ghost"></Button>
<Button></Button>
</ButtonGroup>
ReactDOM.render(
<div>
<h4>Basic</h4>
<ButtonGroup>
<Button>Cancel</Button>
<Button type="primary">OK</Button>
</ButtonGroup>
<ButtonGroup>
<Button disabled>L</Button>
<Button disabled>M</Button>
<Button disabled>R</Button>
</ButtonGroup>
<ButtonGroup>
<Button type="primary">L</Button>
<Button>M</Button>
<Button type="ghost">M</Button>
<Button type="dashed">R</Button>
</ButtonGroup>
<h4>带图标按钮组合</h4>
<ButtonGroup>
<Button type="primary">
<Icon type="left" />后退
</Button>
<Button type="primary">
前进<Icon type="right" />
</Button>
</ButtonGroup>
<ButtonGroup>
<Button type="primary" icon="cloud" />
<Button type="primary" icon="cloud-download" />
</ButtonGroup>
<h4>With Icon</h4>
<ButtonGroup>
<Button type="primary">
<Icon type="left" />Go back
</Button>
<Button type="primary">
Go forward<Icon type="right" />
</Button>
</ButtonGroup>
<ButtonGroup>
<Button type="primary" icon="cloud" />
<Button type="primary" icon="cloud-download" />
</ButtonGroup>
<h4>尺寸</h4>
<ButtonGroup size="large">
<Button type="ghost"></Button>
<Button type="ghost"></Button>
<Button type="ghost"></Button>
</ButtonGroup>
<ButtonGroup>
<Button type="ghost">默认</Button>
<Button type="ghost">默认</Button>
<Button type="ghost">默认</Button>
</ButtonGroup>
<ButtonGroup size="small">
<Button type="ghost"></Button>
<Button type="ghost"></Button>
<Button type="ghost"></Button>
</ButtonGroup>
</div>, mountNode);
<h4>Size</h4>
<ButtonGroup size="large">
<Button type="ghost">Large</Button>
<Button type="ghost">Large</Button>
</ButtonGroup>
<ButtonGroup>
<Button type="ghost">Default</Button>
<Button type="ghost">Default</Button>
</ButtonGroup>
<ButtonGroup size="small">
<Button type="ghost">Small</Button>
<Button type="ghost">Small</Button>
</ButtonGroup>
</div>,
mountNode
);
````
<style>
@ -72,13 +82,11 @@ ReactDOM.render(<div>
#components-button-demo-button-group h4:first-child {
margin-top: 0;
}
#components-button-demo-button-group .ant-btn {
margin-bottom: 8px;
}
#components-button-demo-button-group .ant-btn-group {
margin-right: 8px;
}
#components-button-demo-button-group .ant-btn {
margin-bottom: 12px;
margin-right: 0;
}
</style>

View File

@ -1,32 +1,35 @@
---
order: 3
title: 不可用
title:
zh-CN: 不可用状态
en-US: Disabled
---
## zh-CN
添加 `disabled` 属性即可让按钮处于不可用状态,同时按钮样式也会改变。
## en-US
To mark a button as disabled, add the `disabled` property to the `Button`.
````jsx
import { Button } from 'antd';
ReactDOM.render(<div>
<Button type="primary">主按钮</Button>
<Button type="primary" disabled>主按钮(失效)</Button>
<br />
<Button>次按钮</Button>
<Button disabled>次按钮(失效)</Button>
<br />
<Button type="ghost">幽灵按钮</Button>
<Button type="ghost" disabled>幽灵按钮(失效)</Button>
<br />
<Button type="dashed">虚线按钮</Button>
<Button type="dashed" disabled>虚线按钮(失效)</Button>
</div>
, mountNode);
ReactDOM.render(
<div>
<Button type="primary">Primary</Button>
<Button type="primary" disabled>Primary(disabled)</Button>
<br />
<Button>Default</Button>
<Button disabled>Default(disabled)</Button>
<br />
<Button type="ghost">Ghost</Button>
<Button type="ghost" disabled>Ghost(disabled)</Button>
<br />
<Button type="dashed">Dashed</Button>
<Button type="dashed" disabled>Dashed(disabled)</Button>
</div>,
mountNode
);
````
<style>
#components-button-demo-disabled .ant-btn {
margin-right: 8px;
margin-bottom: 12px;
}
</style>

View File

@ -1,25 +1,33 @@
---
order: 1
title: 图标按钮
title:
zh-CN: 图标按钮
en-US: Icon
---
`Button` 内可以嵌套图标,图标可以放在文字前、后,也可以单独存在。
## zh-CN
当需要在 `Button` 内嵌入 `Icon` 时,可以设置 `icon` 属性,或者直接在 `Button` 内使用 `Icon` 组件。
如果想控制 `Icon` 具体的位置,只能直接使用 `Icon` 组件,而非 `icon` 属性。
## en-US
`Button` components can contain an `Icon`. This is done by setting the `icon` property or placing an `Icon` component within the `Button`
If you want specific control over the positioning and placement of the `Icon`, then that should be done by placing the `Icon` component within the `Button` rather than using the `icon` property.
````jsx
import { Button } from 'antd';
import { Button, Icon } from 'antd';
ReactDOM.render(<div>
<Button type="primary" shape="circle" icon="search" />
<Button type="primary" icon="search">按钮</Button>
<br />
<Button type="ghost" shape="circle-outline" icon="search" />
<Button type="ghost" icon="search">按钮</Button>
</div>, mountNode);
ReactDOM.render(
<div>
<Button type="primary" shape="circle" icon="search" />
<Button type="primary" icon="search">Button</Button>
<br />
<Button type="ghost" shape="circle-outline"><Icon type="search" /></Button>
<Button type="ghost"><Icon type="search" />Button</Button>
</div>,
mountNode
);
````
<style>
#components-button-demo-icon .ant-btn {
margin-right: 8px;
margin-bottom: 12px;
}
</style>

View File

@ -1,10 +1,18 @@
---
order: 4
title: 加载中
title:
zh-CN: 加载中状态
en-US: Loading
---
## zh-CN
添加 `loading` 属性即可让按钮处于加载状态,最后两个按钮演示点击后进入加载状态。
## en-US
A loading indicator can be added to a button by setting the `loading` property on the `Button`.
````jsx
import { Button } from 'antd';
@ -25,20 +33,17 @@ const App = React.createClass({
return (
<div>
<Button type="primary" loading>
加载中
Loading
</Button>
<Button type="primary" size="small" loading>
加载中
</Button>
<Button loading>
加载中
Loading
</Button>
<br />
<Button type="primary" loading={this.state.loading} onClick={this.enterLoading}>
点击变加载
Click me!
</Button>
<Button type="primary" icon="poweroff" loading={this.state.iconLoading} onClick={this.enterIconLoading}>
点击变加载
Click me!
</Button>
</div>
);
@ -47,10 +52,3 @@ const App = React.createClass({
ReactDOM.render(<App />, mountNode);
````
<style>
#components-button-demo-loading .ant-btn {
margin-right: 8px;
margin-bottom: 12px;
}
</style>

View File

@ -1,24 +1,28 @@
---
order: 2
title: 按钮尺寸
title:
zh-CN: 按钮尺寸
en-US: Size
---
## zh-CN
按钮有大、中、小三种尺寸。
通过设置 `size``large` `small` 分别把按钮设为大、小尺寸。若不设置 `size`,则尺寸为中。
## en-US
Ant Design supports a default button size as well as a large and small size.
If a large or small button is desired, set the `size` property to either `large` or `small` respectively. Omit the `size` property for a button with the default size.
````jsx
import { Button } from 'antd';
ReactDOM.render(<div>
<Button type="primary" size="large">大号按钮</Button>
<Button type="primary">中号按钮(默认)</Button>
<Button type="primary" size="small">小号按钮</Button>
<Button type="primary" size="large">Large</Button>
<Button type="primary">Default</Button>
<Button type="primary" size="small">Small</Button>
</div>, mountNode);
````
<style>
#components-button-demo-size .ant-btn {
margin-right: 8px;
}
</style>

View File

@ -0,0 +1,34 @@
---
category: Components
type: Basic
title: Button
---
To trigger an operation.
## Occasion
A button means an operation(or a series of operations). Click a button will trigger corresponding business logic.
## API
To get a customized button, just set `type`/`shape`/`size`/`loading`/`disabled`.
Property | Description | Type | Default
-----|-----|-----|------
type | can be set to `primary` `ghost` or omitted | string | -
htmlType | to set the original `type` of `button`, see: [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-type) | string | `button`
icon | set the icon of button, see: Icon component | string | -
shape | can be set to `circle` `circle-outline` or omitted | string | -
size | can be set to `small` `large` or omitted | string | `default`
loading | to set the loading status of button | boolean | false
onClick | set the handler to handle `click` event | function | -
`<Button>Hello world!</Button>` will be rendered into `<button>Hello world!</button>`, and all the properties which are not listed above will be transferred to the `<button>` tag.
<style>
[id^="components-button-demo-"] .ant-btn {
margin-right: 8px;
margin-bottom: 12px;
}
</style>

View File

@ -1,8 +1,8 @@
---
category: Components
chinese: 按钮
type: 基本
english: Button
type: Basic
title: Button
subtitle: 按钮
---
按钮用于开始一个即时操作。
@ -11,7 +11,6 @@ english: Button
标记了一个(或封装一组)操作命令,响应用户点击行为,触发相应的业务逻辑。
## API
通过设置 Button 的属性来产生不同的按钮样式,推荐顺序为:`type` -> `shape` -> `size` -> `loading` -> `disabled`
@ -21,7 +20,7 @@ english: Button
属性 | 说明 | 类型 | 默认值
-----|-----|-----|------
type | 设置按钮类型,可选值为 `primary` `ghost` 或者不设 | string | -
htmlType | 设置 `button` 原生的 `type` 值,可选值请参考 HTML标准 | string | `button`
htmlType | 设置 `button` 原生的 `type` 值,可选值请参考 [HTML 标准](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-type) | string | `button`
icon | 设置按钮的图标类型 | string | -
shape | 设置按钮形状,可选值为 `circle` `circle-outline` 或者不设 | string | -
size | 设置按钮大小,可选值为 `small` `large` 或者不设 | string | `default`
@ -29,3 +28,10 @@ loading | 设置按钮载入状态 | boolean | false
onClick | `click` 事件的 handler | function | -
`<Button>Hello world!</Button>` 最终会被渲染为 `<button>Hello world!</button>`,并且除了上表中的属性,其它属性都会直接传到 `<button></button>`
<style>
[id^="components-button-demo-"] .ant-btn {
margin-right: 8px;
margin-bottom: 12px;
}
</style>

View File

@ -1,6 +1,6 @@
---
category: Components
type: 展示
type: Presentation
chinese: 日历
cols: 1
english: Calendar

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 卡片
type: 展示
type: Presentation
cols: 1
english: Card
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 走马灯
type: 展示
type: Presentation
english: Carousel
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 级联选择
type: 表单
type: Form Control
english: Cascader
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 多选框
type: 表单
type: Form Control
english: Checkbox
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 折叠面板
type: 展示
type: Presentation
english: Collapse
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 日期选择框
type: 表单
type: Form Control
english: DatePicker
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 下拉菜单
type: 展示
type: Presentation
english: Dropdown
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 表单
type: 表单
type: Form Control
cols: 1
english: Form
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 图标
type: 基本
type: Basic
english: Icon
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 数字输入框
type: 表单
type: Form Control
english: InputNumber
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 布局
type: 基本
type: Basic
cols: 1
english: Layout
---

View File

@ -2,7 +2,7 @@
category: Components
chinese: 国际化
cols: 1
type: 其它
type: Other
english: LocaleProvider
---

View File

@ -2,7 +2,7 @@
category: Components
chinese: 导航菜单
cols: 1
type: 导航
type: Navigation
english: Menu
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 全局提示
type: 展示
type: Presentation
noinstant: true
english: Message
---

View File

@ -1,5 +1,5 @@
---
type: 展示
type: Presentation
category: Components
chinese: 对话框
english: Modal

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 通知提醒框
type: 展示
type: Presentation
noinstant: true
english: Notification
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 分页
type: 导航
type: Navigation
english: Pagination
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 气泡确认框
type: 展示
type: Presentation
english: Popconfirm
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 气泡卡片
type: 展示
type: Presentation
english: Popover
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 进度条
type: 展示
type: Presentation
english: Progress
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 进出场动画
type: 其它
type: Other
english: QueueAnim
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 单选框
type: 表单
type: Form Control
english: Radio
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 评分
type: 表单
type: Form Control
english: Rate
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 选择器
type: 表单
type: Form Control
english: Select
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 滑动输入条
type: 表单
type: Form Control
english: Slider
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 加载中
type: 其它
type: Other
english: Spin
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 步骤条
type: 导航
type: Navigation
cols: 1
english: Steps
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 开关
type: 表单
type: Form Control
english: Switch
---

View File

@ -2,7 +2,7 @@
category: Components
chinese: 表格
cols: 1
type: 展示
type: Presentation
english: Table
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 标签页
type: 导航
type: Navigation
english: Tabs
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 标签
type: 展示
type: Presentation
english: Tag
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 时间选择框
type: 表单
type: Form Control
english: TimePicker
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 时间轴
type: 展示
type: Presentation
english: Timeline
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 文字提示
type: 展示
type: Presentation
english: Tooltip
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 穿梭框
type: 表单
type: Form Control
cols: 1
english: Transfer
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 树选择
type: 表单
type: Form Control
english: TreeSelect
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 树形控件
type: 展示
type: Presentation
english: Tree
---

View File

@ -1,7 +1,7 @@
---
category: Components
chinese: 上传
type: 表单
type: Form Control
english: Upload
---

View File

@ -0,0 +1,7 @@
---
order: 0
chinese: 资源下载
english: Download
---
TBD

View File

@ -1,6 +1,6 @@
<!DOCTYPE html>
<html>
<head>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
@ -10,26 +10,27 @@
<!--[if lt IE 10]>
<script src="https://as.alipayobjects.com/g/component/??console-polyfill/0.2.2/index.js,es5-shim/4.1.14/es5-shim.min.js,es5-shim/4.1.14/es5-sham.min.js,html5shiv/3.7.2/html5shiv.min.js,media-match/2.0.2/media.match.min.js"></script>
<![endif]-->
</head>
<body>
<div id="react-content"></div>
<div class="ant-site-loading">
<img src='https://t.alipayobjects.com/images/rmsweb/T1B9hfXcdvXXXXXXXX.svg' />
<div id="loading-text">A Design Language</div>
</div>
<script>
const content = document.getElementById('loading-text');
content.innerHTML = content.innerText.split('').map(function(letter, i) {
var className;
if (i > 0 && i < content.innerText.length - 1) {
className = 'yoyo-x-' + (i % 6);
}
if (letter.trim() === '') {
className += ' blank';
}
return '<span class="' + className + '">' + letter + '</span>';
}).join('');
</script>
</body>
<script src="./index.js"></script>
</head>
<body>
<div id="react-content"></div>
<div class="ant-site-loading">
<img src='https://t.alipayobjects.com/images/rmsweb/T1B9hfXcdvXXXXXXXX.svg' />
<div id="loading-text">A Design Language</div>
</div>
<script>
const content = document.getElementById('loading-text');
content.innerHTML = content.innerText.split('').map(function(letter, i) {
var className;
if (i > 0 && i < content.innerText.length - 1) {
className = 'yoyo-x-' + (i % 6);
}
if (letter.trim() === '') {
className += ' blank';
}
return '<span class="' + className + '">' + letter + '</span>';
}).join('');
</script>
<script src="./zh-Hans-CN.js"></script>
<script src="./index.js"></script>
</body>
</html>

View File

@ -104,6 +104,7 @@
"react-copy-to-clipboard": "^4.0.1",
"react-dom": "^15.0.0",
"react-github-button": "^0.1.1",
"react-intl": "^2.0.1",
"react-router": "^2.0.0",
"react-stateless-wrapper": "^1.0.2",
"react-sublime-video": "^0.2.0-beta",

36
scripts/build-common.js Normal file
View File

@ -0,0 +1,36 @@
/* eslint strict: 0 */
'use strict';
const fs = require('fs');
const path = require('path');
const utils = require('./utils');
module.exports = function buildCommon(dirs, outputFile) {
const mds = utils.findMDFile(dirs, true)
.filter((file) => !/\/demo$/i.test(path.dirname(file)))
.filter((file) => !/install_en\.md$/gi.test(file)); // TODO
const addedMd = [];
let content = 'module.exports = {';
mds.forEach((fileName) => {
const localeId = path.basename(fileName, '.md').split('.')[1];
const simplifiedFileName = fileName.replace(`.${localeId}`, '');
if (addedMd.indexOf(simplifiedFileName) > -1) return;
const isLocalized = ['zh-CN', 'en-US'].indexOf(localeId) > -1;
if (isLocalized) {
content += `\n '${simplifiedFileName}': {` +
'\n localized: true,' +
`\n 'zh-CN': require('${path.relative(path.dirname(outputFile), fileName.replace(localeId, 'zh-CN'))}'),` +
`\n 'en-US': require('${path.relative(path.dirname(outputFile), fileName.replace(localeId, 'en-US'))}'),` +
'\n },';
addedMd.push(simplifiedFileName);
} else {
const requirePath = path.relative(path.dirname(outputFile), fileName);
content += `\n '${simplifiedFileName}': require('${requirePath}'),`;
}
});
content += '\n};';
fs.writeFile(outputFile, content);
};

View File

@ -9,8 +9,8 @@ export default class Article extends React.Component {
this.componentDidUpdate();
}
componentDidUpdate() {
const { chinese, english } = this.props.content.meta;
utils.setTitle(`${chinese || english} - Ant Design`);
const { title, chinese, english } = this.props.content.meta;
utils.setTitle(`${title || chinese || english} - Ant Design`);
const links = Array.apply(null, document.querySelectorAll('.outside-link.internal'));
if (links.length === 0) {
return;

View File

@ -7,6 +7,10 @@ import * as utils from '../utils';
import demosList from '../../../_data/demos-list';
export default class ComponentDoc extends React.Component {
static contextTypes = {
intl: React.PropTypes.object,
}
constructor(props) {
super(props);
@ -19,8 +23,8 @@ export default class ComponentDoc extends React.Component {
this.componentDidUpdate();
}
componentDidUpdate() {
const { chinese, english } = this.props.doc.meta;
utils.setTitle(`${chinese} ${english} - Ant Design`);
const { title, subtitle, chinese, english } = this.props.doc.meta;
utils.setTitle(`${subtitle || chinese || ''} ${title || english} - Ant Design`);
}
handleExpandToggle = () => {
@ -33,7 +37,8 @@ export default class ComponentDoc extends React.Component {
const { doc, location } = this.props;
const scrollTo = location.query.scrollTo;
const { description, meta } = doc;
const demos = (demosList[meta.fileName] || [])
const locale = this.context.intl.locale;
const demos = (demosList[meta.fileName.replace(`.${locale}`, '')] || [])
.filter((demoData) => !demoData.meta.hidden);
const expand = this.state.expandAll;
@ -63,11 +68,14 @@ export default class ComponentDoc extends React.Component {
});
const jumper = demos.map((demo) => {
const title = demo.meta.title;
const localizeTitle = typeof title === 'object' ?
title[locale] : title;
return (
<li key={demo.id}>
<Link className={demo.id === scrollTo ? 'current' : ''}
to={{ pathname: location.pathname, query: { scrollTo: `${demo.id}` } }}>
{demo.meta.title}
{localizeTitle}
</Link>
</li>
);
@ -81,7 +89,7 @@ export default class ComponentDoc extends React.Component {
</ul>
</Affix>
<section className="markdown">
<h1>{meta.english} {meta.chinese}</h1>
<h1>{meta.title || meta.english} {meta.subtitle || meta.chinese}</h1>
{
utils.jsonmlToComponent(
location.pathname,

View File

@ -6,6 +6,10 @@ import * as utils from '../utils';
const isLocal = location.port;
export default class Demo extends React.Component {
static contextTypes = {
intl: React.PropTypes.object,
}
constructor(props) {
super(props);
@ -35,7 +39,12 @@ export default class Demo extends React.Component {
[className]: className,
expand: codeExpand,
});
const introChildren = utils.jsonmlToComponent(pathname, ['div'].concat(intro));
const locale = this.context.intl.locale;
const localizeIntro = intro[locale] || intro;
const introChildren = utils.jsonmlToComponent(pathname, ['div'].concat(localizeIntro));
const localizedTitle = typeof meta.title === 'object' ?
meta.title[locale] : meta.title;
return (
<section className={codeBoxClass} id={id}>
<section className="code-box-demo">
@ -53,7 +62,7 @@ export default class Demo extends React.Component {
<section className="code-box-meta markdown">
<div className="code-box-title">
<Link to={{ pathname, query: { scrollTo: id } }}>
{meta.title}
{localizedTitle}
</Link>
</div>
{introChildren}

View File

@ -1,9 +1,10 @@
import React from 'react';
import { FormattedMessage } from 'react-intl';
import { Link } from 'react-router';
import enquire from 'enquire.js';
import debounce from 'lodash.debounce';
import classNames from 'classnames';
import { Select, Menu, Row, Col, Icon } from 'antd';
import { Select, Menu, Row, Col, Icon, Button } from 'antd';
const Option = Select.Option;
import './index.less';
@ -12,6 +13,7 @@ import componentsList from '../../../_data/react-components';
export default class Header extends React.Component {
static contextTypes = {
router: React.PropTypes.object.isRequired,
intl: React.PropTypes.object.isRequired,
}
constructor(props) {
@ -76,23 +78,38 @@ export default class Header extends React.Component {
return option.props['data-label'].indexOf(value.toLowerCase()) > -1;
}
handleLangChange = () => {
if (typeof localStorage !== 'undefined') {
const locale = this.context.intl.locale === 'zh-CN' ? 'en-US' : 'zh-CN';
localStorage.setItem('locale', locale);
location.reload();
}
}
render() {
const routes = this.props.routes;
let activeMenuItem = routes[1].path || 'home';
activeMenuItem = activeMenuItem === 'components' ? 'docs/react' : activeMenuItem;
const options = Object.keys(componentsList).map(key => componentsList[key])
.filter(({ meta }) => /^component/.test(meta.fileName))
.map(({ meta }) => {
const pathSnippet = meta.fileName.split('/')[1];
const url = `/components/${pathSnippet}`;
return (
<Option value={url} key={url} data-label={`${meta.english.toLowerCase()} ${meta.chinese}`}>
<strong>{meta.english}</strong>
<span className="ant-component-decs">{meta.chinese}</span>
</Option>
);
});
const locale = this.context.intl.locale;
const options = Object.keys(componentsList)
.map((key) => {
const value = componentsList[key];
return value.localized ? value[locale] : value;
})
.filter(({ meta }) => {
return /^component/.test(meta.fileName);
})
.map(({ meta }) => {
const pathSnippet = meta.fileName.split('/')[1];
const url = `/components/${pathSnippet}`;
return (
<Option value={url} key={url} data-label={`${(meta.title || meta.english).toLowerCase()} ${meta.subtitle || meta.chinese}`}>
<strong>{meta.title || meta.english}</strong>
<span className="ant-component-decs">{meta.subtitle || meta.chinese}</span>
</Option>
);
});
const menuStyle = {
display: this.state.menuVisible ? 'block' : '',
@ -129,35 +146,42 @@ export default class Header extends React.Component {
{options}
</Select>
</div>
{
location.port ? (
<Button id="lang" type="ghost" size="small" onClick={this.handleLangChange}>
<FormattedMessage id="app.header.lang" />
</Button>
) : null
}
<Menu mode={this.state.menuMode} selectedKeys={[activeMenuItem]} id="nav">
<Menu.Item key="home">
<Link to="/">
首页
<FormattedMessage id="app.header.menu.home" />
</Link>
</Menu.Item>
<Menu.Item key="docs/practice">
<Link to="/docs/practice">
实践
<FormattedMessage id="app.header.menu.practice" />
</Link>
</Menu.Item>
<Menu.Item key="docs/pattern">
<Link to="/docs/pattern">
模式
<FormattedMessage id="app.header.menu.pattern" />
</Link>
</Menu.Item>
<Menu.Item key="docs/react">
<Link to="/docs/react">
组件
<FormattedMessage id="app.header.menu.react" />
</Link>
</Menu.Item>
<Menu.Item key="docs/spec">
<Link to="/docs/spec">
语言
<FormattedMessage id="app.header.menu.spec" />
</Link>
</Menu.Item>
<Menu.Item key="docs/resource">
<Link to="/docs/resource">
资源
<FormattedMessage id="app.header.menu.resource" />
</Link>
</Menu.Item>
</Menu>

View File

@ -63,6 +63,11 @@
box-shadow: none;
}
#lang {
float: right;
margin-top: 29px;
}
#nav {
border: 0;
float: right;
@ -72,7 +77,7 @@
#nav li {
height: @header-height;
line-height: @header-height;
width: 72px;
min-width: 72px;
text-align: center;
border-bottom-width: 3px;

View File

@ -62,6 +62,7 @@ export default class Home extends React.Component {
background: #777;
box-shadow: 0 7px 0 0 #777, 0 14px 0 0 #777;
}
#lang,
#nav a {
color: #eee;
transition: color 0.5s cubic-bezier(0.455, 0.03, 0.515, 0.955);

View File

@ -40,19 +40,19 @@ export default class MainContent extends React.Component {
}
fileNameToPath(fileName) {
const snippets = fileName.replace(/(\/index)?\.md$/i, '').split('/');
const snippets = fileName.replace(/(\/index)?((\.zh-CN)|(\.en-US))?\.md$/i, '').split('/');
return snippets[snippets.length - 1];
}
generateMenuItem(isTop, item) {
const key = this.fileNameToPath(item.fileName);
const text = isTop ?
item.chinese || item.english : [
<span key="english">{item.english}</span>,
<span className="chinese" key="chinese">{item.chinese}</span>,
];
item.chinese || item.english : [
<span key="english">{item.title || item.english}</span>,
<span className="chinese" key="chinese">{item.subtitle || item.chinese}</span>,
];
const disabled = item.disabled;
const url = item.fileName.replace(/(\/index)?\.md$/i, '');
const url = item.fileName.replace(/(\/index)?((\.zh-CN)|(\.en-US))?\.md$/i, '');
const child = !item.link ?
<Link to={url} disabled={disabled}>
{text}
@ -75,20 +75,21 @@ export default class MainContent extends React.Component {
generateSubMenuItems(obj) {
const topLevel = (obj.topLevel || []).map(this.generateMenuItem.bind(this, true));
const itemGroups = Object.keys(obj).filter(this.isNotTopLevel)
.sort((a, b) => {
return config.typeOrder[a] - config.typeOrder[b];
})
.map((type, index) => {
const groupItems = obj[type].sort((a, b) => {
return a.english.charCodeAt(0) - b.english.charCodeAt(0);
}).map(this.generateMenuItem.bind(this, false));
.sort((a, b) => {
return config.typeOrder[a] - config.typeOrder[b];
})
.map((type, index) => {
const groupItems = obj[type].sort((a, b) => {
return (a.title || a.english).charCodeAt(0) -
(b.title || b.english).charCodeAt(0);
}).map(this.generateMenuItem.bind(this, false));
return (
<Menu.ItemGroup title={type} key={index}>
{groupItems}
</Menu.ItemGroup>
);
});
return (
<Menu.ItemGroup title={type} key={index}>
{groupItems}
</Menu.ItemGroup>
);
});
return [...topLevel, ...itemGroups];
}

15
site/entry/en-US.js Normal file
View File

@ -0,0 +1,15 @@
import appLocaleData from 'react-intl/locale-data/en';
module.exports = {
locale: 'en-US',
data: appLocaleData,
messages: {
'app.header.menu.home': 'Home',
'app.header.menu.practice': 'Practice',
'app.header.menu.pattern': 'Pattern',
'app.header.menu.react': 'React',
'app.header.menu.spec': 'Specification',
'app.header.menu.resource': 'Resource',
'app.header.lang': '中文',
},
};

View File

@ -1,5 +1,6 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { addLocaleData, IntlProvider } from 'react-intl';
import { Router, Route, IndexRoute, Redirect, useRouterHistory } from 'react-router';
import antd from '../../index.js';
import * as utils from './utils';
@ -13,6 +14,8 @@ import reactComponents from '../../_data/react-components';
import spec from '../../_data/spec';
import resource from '../../_data/resource';
import config from '../website.config';
import enLocale from './en-US.js';
import cnLocale from './zh-CN.js';
import { createHashHistory } from 'history';
// useRouterHistory creates a composable higher-order function
@ -49,49 +52,57 @@ if (!location.port) {
/* eslint-enable */
}
const isZhCN =
(typeof localStorage !== 'undefined' && localStorage.getItem('locale') === 'zh-CN') ||
(navigator.language === 'zh-CN');
const appLocale = isZhCN ? cnLocale : enLocale;
addLocaleData(appLocale.data);
ReactDOM.render(
<Router history={appHistory}>
<Route path="/" component={App}>
<IndexRoute component={Home} />
<Route path="components" component={ReactComponents}>
{utils.generateIndex(reactComponents)}
<Route path=":children"
onEnter={utils.getEnterHandler(reactComponents)}
component={utils.getChildrenWrapper(reactComponents)} />
<IntlProvider locale={appLocale.locale} messages={appLocale.messages}>
<Router history={appHistory}>
<Route path="/" component={App}>
<IndexRoute component={Home} />
<Route path="components" component={ReactComponents}>
{utils.generateIndex(reactComponents)}
<Route path=":children"
onEnter={utils.getEnterHandler(reactComponents)}
component={utils.getChildrenWrapper(reactComponents)} />
</Route>
{redirects}
<Route path="docs/react" component={ReactComponents}>
{utils.generateIndex(reactComponents)}
<Route path=":children"
onEnter={utils.getEnterHandler(reactComponents)}
component={utils.getChildrenWrapper(reactComponents)} />
</Route>
<Route path="docs/practice" component={Practice}>
{utils.generateIndex(practice)}
<Route path=":children"
onEnter={utils.getEnterHandler(practice)}
component={utils.getChildrenWrapper(practice)} />
</Route>
<Route path="docs/pattern" component={Pattern}>
{utils.generateIndex(pattern)}
<Route path=":children"
onEnter={utils.getEnterHandler(pattern)}
component={utils.getChildrenWrapper(pattern)} />
</Route>
<Route path="docs/spec" component={Spec}>
{utils.generateIndex(spec)}
<Route path=":children"
onEnter={utils.getEnterHandler(spec)}
component={utils.getChildrenWrapper(spec)} />
</Route>
<Route path="docs/resource" component={Resource}>
{utils.generateIndex(resource)}
<Route path=":children"
onEnter={utils.getEnterHandler(resource)}
component={utils.getChildrenWrapper(resource)} />
</Route>
<Route path="*" component={NotFound} />
</Route>
{redirects}
<Route path="docs/react" component={ReactComponents}>
{utils.generateIndex(reactComponents)}
<Route path=":children"
onEnter={utils.getEnterHandler(reactComponents)}
component={utils.getChildrenWrapper(reactComponents)} />
</Route>
<Route path="docs/practice" component={Practice}>
{utils.generateIndex(practice)}
<Route path=":children"
onEnter={utils.getEnterHandler(practice)}
component={utils.getChildrenWrapper(practice)} />
</Route>
<Route path="docs/pattern" component={Pattern}>
{utils.generateIndex(pattern)}
<Route path=":children"
onEnter={utils.getEnterHandler(pattern)}
component={utils.getChildrenWrapper(pattern)} />
</Route>
<Route path="docs/spec" component={Spec}>
{utils.generateIndex(spec)}
<Route path=":children"
onEnter={utils.getEnterHandler(spec)}
component={utils.getChildrenWrapper(spec)} />
</Route>
<Route path="docs/resource" component={Resource}>
{utils.generateIndex(resource)}
<Route path=":children"
onEnter={utils.getEnterHandler(resource)}
component={utils.getChildrenWrapper(resource)} />
</Route>
</Route>
<Route path="*" component={NotFound} />
</Router>
</Router>
</IntlProvider>
, document.getElementById('react-content')
);

View File

@ -1,3 +1,4 @@
/* eslint-disable react/prefer-stateless-function, react/no-multi-comp */
import React from 'react';
import { IndexRedirect } from 'react-router';
import MainContent from '../component/MainContent';
@ -11,14 +12,20 @@ if (module.hot) {
}
function fileNameToPath(fileName) {
const snippets = fileName.replace(/(\/index)?\.md$/i, '').split('/');
const snippets = fileName
.replace(/(\/index)?((\.zh-CN)|(\.en-US))?\.md$/i, '').split('/');
return snippets[snippets.length - 1];
}
function getMenuItems(data) {
function getMenuItems(data, locale) {
const menuMeta = Object.keys(data)
.map((key) => data[key])
.map((file) => file.meta);
.map((file) => {
if (file.localized) {
return file[locale].meta;
}
return file.meta;
});
const menuItems = {};
menuMeta.sort((a, b) => {
@ -41,17 +48,26 @@ function getMenuItems(data) {
}
export function generateContainer(data) {
const menuItems = getMenuItems(data);
return (props) => {
return (
<MainContent {...props} menuItems={menuItems} />
);
return class containerWrapper extends React.Component {
static contextTypes = {
intl: React.PropTypes.object,
}
render() {
const locale = this.context.intl.locale;
const menuItems = getMenuItems(data, locale);
return (
<MainContent {...this.props} menuItems={menuItems} />
);
}
};
}
export function generateIndex(data) {
const menuItems = getMenuItems(data);
const firstChild = menuItems.topLevel.topLevel.filter((item) => !item.disabled)[0];
const menuItems = getMenuItems(data, 'zh-CN'); // 以中文版配置为准
const firstChild = menuItems.topLevel.topLevel.filter((item) => {
return !item.disabled;
})[0];
return (
<IndexRedirect key="index"
to={fileNameToPath(firstChild.fileName)} />
@ -71,12 +87,26 @@ function getDoc(data, props) {
}
export function getChildrenWrapper(data) {
return function childrenWrapper(props) {
const doc = getDoc(data, props);
const hasDemos = demosList[doc.meta.fileName];
return !hasDemos ?
<Article {...props} content={doc} /> :
<ComponentDoc {...props} doc={doc} />;
return class childrenWrapper extends React.Component {
static contextTypes = {
intl: React.PropTypes.object,
}
render() {
const props = this.props;
const trimedPathname = props.location.pathname.replace(/^\//, '');
const processedPathname = pathToFile[trimedPathname] || trimedPathname;
const rawDoc = data[`${processedPathname}.md`] ||
data[`${processedPathname}/index.md`];
const locale = this.context.intl.locale;
const doc = rawDoc.localized ? rawDoc[locale] : rawDoc;
const hasDemos = demosList[doc.meta.fileName.replace(`.${locale}`, '')];
return !hasDemos ?
<Article {...props} content={doc} /> :
<ComponentDoc {...props} doc={doc} />;
}
};
}

15
site/entry/zh-CN.js Normal file
View File

@ -0,0 +1,15 @@
import appLocaleData from 'react-intl/locale-data/zh';
module.exports = {
locale: 'zh-CN',
data: appLocaleData,
messages: {
'app.header.menu.home': '首页',
'app.header.menu.practice': '实践',
'app.header.menu.pattern': '模式',
'app.header.menu.react': '组件',
'app.header.menu.spec': '语言',
'app.header.menu.resource': '资源',
'app.header.lang': 'EN',
},
};

View File

@ -6,11 +6,11 @@ export default {
动画: 2,
},
typeOrder: {
基本: 0,
表单: 1,
展示: 2,
导航: 3,
其它: 4,
Basic: 0,
'Form Control': 1,
Presentation: 2,
Navigation: 3,
Other: 4,
},
redirects: {
CHANGELOG: 'docs/react/changelog',

File diff suppressed because it is too large Load Diff