Merge branch 'master' into feature-3.7.0

This commit is contained in:
Wei Zhu 2018-06-25 11:44:35 +08:00
commit b374297ca6
106 changed files with 412 additions and 281 deletions

View File

@ -26,6 +26,8 @@ const eslintrc = {
'react/sort-comp': 0, 'react/sort-comp': 0,
'react/prop-types': 0, 'react/prop-types': 0,
'react/jsx-first-prop-new-line': 0, 'react/jsx-first-prop-new-line': 0,
'react/jsx-one-expression-per-line': 0,
'react/forbid-prop-types': 0,
'react/jsx-filename-extension': [1, { extensions: ['.js', '.jsx', '.md'] }], 'react/jsx-filename-extension': [1, { extensions: ['.js', '.jsx', '.md'] }],
'import/extensions': 0, 'import/extensions': 0,
'import/no-unresolved': 0, 'import/no-unresolved': 0,

View File

@ -15,6 +15,17 @@ timeline: true
--- ---
## 3.6.4
`2018-06-23`
- 🐞 Fixed `Steps` theme `@process-icon-color`. [#10973](https://github.com/ant-design/ant-design/issues/10973)
- 🐞 Fixed style of RangePicker with preset ranges. [#10986](https://github.com/ant-design/ant-design/issues/10986)
- 🐞 Fixed `Dropdown` non-boolean attribute warning. [#7798](https://github.com/ant-design/ant-design/issues/7798)
- TypeScript
- 🌟 Add `Tree` prop `className` definition. [#10950](https://github.com/ant-design/ant-design/issues/10950)
- 🌟 Add `Tree` prop `selectable` definition. [3fb478e](https://github.com/ant-design/ant-design/commit/3fb478e743f3bad23dc300f501df11e5423468ba)
## 3.6.3 ## 3.6.3
`2018-06-17` `2018-06-17`

View File

@ -15,6 +15,18 @@ timeline: true
--- ---
## 3.6.4
`2018-06-23`
- 🐞 修复 `Steps` 组件的 `@process-icon-color` 样式定义。[#10973](https://github.com/ant-design/ant-design/issues/10973)
- 🐞 修复 `RangePicker` 组件使用预置范围时的样式问题。[#10986]
(https://github.com/ant-design/ant-design/issues/10986)
- 🐞 修复 `Dropdown` 组件可能报出的 `non-boolean attribute` 的警告。[#7798](https://github.com/ant-design/ant-design/issues/7798)
- TypeScript
- 🌟 给 `Tree` 组件添加 `className` 的定义。[#10950](https://github.com/ant-design/ant-design/issues/10950)
- 🌟 给 `Tree` 组件添加 `selectable` 的定义。[3fb478e](https://github.com/ant-design/ant-design/commit/3fb478e743f3bad23dc300f501df11e5423468ba)
## 3.6.3 ## 3.6.3
`2018-06-17` `2018-06-17`

View File

@ -11,9 +11,11 @@ class AffixMounter extends React.Component {
events[event] = cb; events[event] = cb;
}); });
} }
getTarget = () => { getTarget = () => {
return this.container; return this.container;
} }
render() { render() {
return ( return (
<div <div
@ -35,7 +37,7 @@ class AffixMounter extends React.Component {
ref={ele => this.affix = ele} ref={ele => this.affix = ele}
{...this.props} {...this.props}
> >
<Button type="primary" > <Button type="primary">
Fixed at the top of container Fixed at the top of container
</Button> </Button>
</Affix> </Affix>

View File

@ -20,8 +20,8 @@ Alert component for feedback.
| closable | Whether Alert can be closed | boolean | - | | closable | Whether Alert can be closed | boolean | - |
| closeText | Close text to show | string\|ReactNode | - | | closeText | Close text to show | string\|ReactNode | - |
| description | Additional content of Alert | string\|ReactNode | - | | description | Additional content of Alert | string\|ReactNode | - |
| iconType | Icon type, effective when `showIcon` is `true` | string | - |
| message | Content of Alert | string\|ReactNode | - | | message | Content of Alert | string\|ReactNode | - |
| showIcon | Whether to show icon | boolean | false, in `banner` mode default is true | | showIcon | Whether to show icon | boolean | false, in `banner` mode default is true |
| iconType | Icon type, effective when `showIcon` is `true` | string | - |
| type | Type of Alert styles, options: `success`, `info`, `warning`, `error` | string | `info`, in `banner` mode default is `warning` | | type | Type of Alert styles, options: `success`, `info`, `warning`, `error` | string | `info`, in `banner` mode default is `warning` |
| onClose | Callback when Alert is closed | (e: MouseEvent) => void | - | | onClose | Callback when Alert is closed | (e: MouseEvent) => void | - |

View File

@ -21,8 +21,8 @@ title: Alert
| closable | 默认不显示关闭按钮 | boolean | 无 | | closable | 默认不显示关闭按钮 | boolean | 无 |
| closeText | 自定义关闭按钮 | string\|ReactNode | 无 | | closeText | 自定义关闭按钮 | string\|ReactNode | 无 |
| description | 警告提示的辅助性文字介绍 | string\|ReactNode | 无 | | description | 警告提示的辅助性文字介绍 | string\|ReactNode | 无 |
| iconType | 自定义图标类型,`showIcon` 为 `true` 时有效 | string | - |
| message | 警告提示内容 | string\|ReactNode | 无 | | message | 警告提示内容 | string\|ReactNode | 无 |
| showIcon | 是否显示辅助图标 | boolean | false`banner` 模式下默认值为 true | | showIcon | 是否显示辅助图标 | boolean | false`banner` 模式下默认值为 true |
| iconType | 自定义图标类型,`showIcon` 为 `true` 时有效 | string | - |
| type | 指定警告提示的样式,有四种选择 `success`、`info`、`warning`、`error` | string | `info``banner` 模式下默认值为 `warning` | | type | 指定警告提示的样式,有四种选择 `success`、`info`、`warning`、`error` | string | `info``banner` 模式下默认值为 `warning` |
| onClose | 关闭时触发的回调函数 | (e: MouseEvent) => void | 无 | | onClose | 关闭时触发的回调函数 | (e: MouseEvent) => void | 无 |

View File

@ -19,7 +19,7 @@ For displaying anchor hyperlinks on page and jumping between them.
| -------- | ----------- | ---- | ------- | | -------- | ----------- | ---- | ------- |
| affix | Fixed mode of Anchor | boolean | true | | affix | Fixed mode of Anchor | boolean | true |
| bounds | Bounding distance of anchor area | number | 5(px) | | bounds | Bounding distance of anchor area | number | 5(px) |
| getContainer | Scrolling container | () => HTMLElement | () => window | | getContainer | Scrolling container | () => HTMLElement | () => window |
| offsetBottom | Pixels to offset from bottom when calculating position of scroll | number | - | | offsetBottom | Pixels to offset from bottom when calculating position of scroll | number | - |
| offsetTop | Pixels to offset from top when calculating position of scroll | number | 0 | | offsetTop | Pixels to offset from top when calculating position of scroll | number | 0 |
| showInkInFixed | Whether show ink-balls in Fixed mode | boolean | false | | showInkInFixed | Whether show ink-balls in Fixed mode | boolean | false |

View File

@ -33,7 +33,9 @@ const dataSource = ['12345', '23456', '34567'];
| optionLabelProp | Which prop value of option will render as content of select. | string | `children` | | optionLabelProp | Which prop value of option will render as content of select. | string | `children` |
| placeholder | placeholder of input | string | - | | placeholder | placeholder of input | string | - |
| value | selected option | string\|string\[]\|{ key: string, label: string\|ReactNode }\|Array&lt;{ key: string, label: string\|ReactNode }> | - | | value | selected option | string\|string\[]\|{ key: string, label: string\|ReactNode }\|Array&lt;{ key: string, label: string\|ReactNode }> | - |
| onBlur | Called when leaving the component. | function() | - |
| onChange | Called when select an option or input value change, or value of input is changed | function(value) | - | | onChange | Called when select an option or input value change, or value of input is changed | function(value) | - |
| onFocus | Called when entering the component | function() | - |
| onSearch | Called when searching items. | function(value) | - | | onSearch | Called when searching items. | function(value) | - |
| onSelect | Called when a option is selected. param is option's value and option instance. | function(value, option) | - | | onSelect | Called when a option is selected. param is option's value and option instance. | function(value, option) | - |

View File

@ -34,7 +34,9 @@ const dataSource = ['12345', '23456', '34567'];
| optionLabelProp | 回填到选择框的 Option 的属性值,默认是 Option 的子元素。比如在子元素需要高亮效果时,此值可以设为 `value`。 | string | `children` | | optionLabelProp | 回填到选择框的 Option 的属性值,默认是 Option 的子元素。比如在子元素需要高亮效果时,此值可以设为 `value`。 | string | `children` |
| placeholder | 输入框提示 | string | - | | placeholder | 输入框提示 | string | - |
| value | 指定当前选中的条目 | string\|string\[]\|{ key: string, label: string\|ReactNode }\|Array&lt;{ key: string, label: string\|ReactNode }> | 无 | | value | 指定当前选中的条目 | string\|string\[]\|{ key: string, label: string\|ReactNode }\|Array&lt;{ key: string, label: string\|ReactNode }> | 无 |
| onBlur | 获取焦点时的回调 | function() | - |
| onChange | 选中 option或 input 的 value 变化时,调用此函数 | function(value) | 无 | | onChange | 选中 option或 input 的 value 变化时,调用此函数 | function(value) | 无 |
| onFocus | 失去焦点时的回调 | function() | - |
| onSearch | 搜索补全项的时候调用 | function(value) | 无 | | onSearch | 搜索补全项的时候调用 | function(value) | 无 |
| onSelect | 被选中时调用,参数为选中项的 value 值 | function(value, option) | 无 | | onSelect | 被选中时调用,参数为选中项的 value 值 | function(value, option) | 无 |

View File

@ -25,7 +25,7 @@ title: Badge
| 参数 | 说明 | 类型 | 默认值 | | 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- | | --- | --- | --- | --- |
| count | 展示的数字,大于 overflowCount 时显示为 `${overflowCount}+`,为 0 时隐藏 | number\|ReactNode | | | count | 展示的数字,大于 overflowCount 时显示为 `${overflowCount}+`,为 0 时隐藏 | number\|ReactNode | |
| dot | 不展示数字,只有一个小红点 | boolean | false | | dot | 不展示数字,只有一个小红点 | boolean | false |
| offset | 设置状态点的位置偏移,格式为 `[x, y]` | `[number, number]` | - | | offset | 设置状态点的位置偏移,格式为 `[x, y]` | `[number, number]` | - |
| overflowCount | 展示封顶的数字值 | number | 99 | | overflowCount | 展示封顶的数字值 | number | 99 |

View File

@ -44,7 +44,7 @@ describe('Button', () => {
}); });
it('renders Chinese characters correctly in HOC', () => { it('renders Chinese characters correctly in HOC', () => {
const Text = props => <span>{props.children}</span>; const Text = ({ children }) => <span>{children}</span>;
const wrapper = mount( const wrapper = mount(
<Button><Text>按钮</Text></Button> <Button><Text>按钮</Text></Button>
); );
@ -74,11 +74,14 @@ describe('Button', () => {
state = { state = {
loading: false, loading: false,
}; };
enterLoading = () => { enterLoading = () => {
this.setState({ loading: true }); this.setState({ loading: true });
} }
render() { render() {
return <Button loading={this.state.loading} onClick={this.enterLoading}>Button</Button>; const { loading } = this.state;
return <Button loading={loading} onClick={this.enterLoading}>Button</Button>;
} }
} }
const wrapper = mount( const wrapper = mount(
@ -94,11 +97,14 @@ describe('Button', () => {
state = { state = {
loading: false, loading: false,
}; };
enterLoading = () => { enterLoading = () => {
this.setState({ loading: { delay: 1000 } }); this.setState({ loading: { delay: 1000 } });
} }
render() { render() {
return <Button loading={this.state.loading} onClick={this.enterLoading}>Button</Button>; const { loading } = this.state;
return <Button loading={loading} onClick={this.enterLoading}>Button</Button>;
} }
} }
const wrapper = mount( const wrapper = mount(

View File

@ -16,12 +16,12 @@ To get a customized button, just set `type`/`shape`/`size`/`loading`/`disabled`.
| Property | Description | Type | Default | | Property | Description | Type | Default |
| -------- | ----------- | ---- | ------- | | -------- | ----------- | ---- | ------- |
| disabled | disabled state of button | boolean | `false` |
| ghost | make background transparent and invert text and border colors, added in 2.7 | boolean | false | | ghost | make background transparent and invert text and border colors, added in 2.7 | boolean | false |
| href | redirect url of link button | string | - | | href | redirect url of link button | string | - |
| htmlType | set the original html `type` of `button`, see: [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-type) | string | `button` | | htmlType | set the original html `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 | - | | icon | set the icon of button, see: Icon component | string | - |
| loading | set the loading status of button | boolean \| { delay: number } | false | | loading | set the loading status of button | boolean \| { delay: number } | false |
| disabled | disabled state of button | boolean | `false` |
| shape | can be set to `circle` or omitted | string | - | | shape | can be set to `circle` or omitted | string | - |
| size | can be set to `small` `large` or omitted | string | `default` | | size | can be set to `small` `large` or omitted | string | `default` |
| target | same as target attribute of a, works when href is specified | string | - | | target | same as target attribute of a, works when href is specified | string | - |

View File

@ -19,12 +19,12 @@ subtitle: 按钮
| 属性 | 说明 | 类型 | 默认值 | | 属性 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- | | --- | --- | --- | --- |
| disabled | 按钮失效状态 | boolean | `false` |
| ghost | 幽灵属性,使按钮背景透明,版本 2.7 中增加 | boolean | false | | ghost | 幽灵属性,使按钮背景透明,版本 2.7 中增加 | boolean | false |
| href | 点击跳转的地址,指定此属性 button 的行为和 a 链接一致 | string | - | | href | 点击跳转的地址,指定此属性 button 的行为和 a 链接一致 | string | - |
| htmlType | 设置 `button` 原生的 `type` 值,可选值请参考 [HTML 标准](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-type) | string | `button` | | htmlType | 设置 `button` 原生的 `type` 值,可选值请参考 [HTML 标准](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-type) | string | `button` |
| icon | 设置按钮的图标类型 | string | - | | icon | 设置按钮的图标类型 | string | - |
| loading | 设置按钮载入状态 | boolean \| { delay: number } | `false` | | loading | 设置按钮载入状态 | boolean \| { delay: number } | `false` |
| disabled | 按钮失效状态 | boolean | `false` |
| shape | 设置按钮形状,可选值为 `circle` 或者不设 | string | - | | shape | 设置按钮形状,可选值为 `circle` 或者不设 | string | - |
| size | 设置按钮大小,可选值为 `small` `large` 或者不设 | string | `default` | | size | 设置按钮大小,可选值为 `small` `large` 或者不设 | string | `default` |
| target | 相当于 a 链接的 target 属性href 存在时生效 | string | - | | target | 相当于 a 链接的 target 属性href 存在时生效 | string | - |

View File

@ -22,15 +22,15 @@ A card can be used to display content related to a single subject. The content c
| Property | Description | Type | Default | | Property | Description | Type | Default |
| -------- | ----------- | ---- | ------- | | -------- | ----------- | ---- | ------- |
| actions | The action list, shows at the bottom of the Card. | Array<ReactNode> | - | | actions | The action list, shows at the bottom of the Card. | Array<ReactNode> | - |
| activeTabKey | Current TabPane's key | string | - |
| bodyStyle | Inline style to apply to the card content | object | - | | bodyStyle | Inline style to apply to the card content | object | - |
| bordered | Toggles rendering of the border around the card | boolean | `true` | | bordered | Toggles rendering of the border around the card | boolean | `true` |
| cover | Card cover | ReactNode | - | | cover | Card cover | ReactNode | - |
| defaultActiveTabKey | Initial active TabPane's key, if `activeTabKey` is not set. | string | - |
| extra | Content to render in the top-right corner of the card | string\|ReactNode | - | | extra | Content to render in the top-right corner of the card | string\|ReactNode | - |
| hoverable | Lift up when hovering card | boolean | false | | hoverable | Lift up when hovering card | boolean | false |
| loading | Shows a loading indicator while the contents of the card are being fetched | boolean | false | | loading | Shows a loading indicator while the contents of the card are being fetched | boolean | false |
| tabList | List of TabPane's head. | Array&lt;{key: string, tab: ReactNode}> | - | | tabList | List of TabPane's head. | Array&lt;{key: string, tab: ReactNode}> | - |
| activeTabKey | Current TabPane's key | string | - |
| defaultActiveTabKey | Initial active TabPane's key, if `activeTabKey` is not set. | string | - |
| title | Card title | string\|ReactNode | - | | title | Card title | string\|ReactNode | - |
| type | Card style type, can be set to `inner` or not set | string | - | | type | Card style type, can be set to `inner` or not set | string | - |
| onTabChange | Callback when tab is switched | (key) => void | - | | onTabChange | Callback when tab is switched | (key) => void | - |

View File

@ -23,15 +23,15 @@ cols: 1
| 参数 | 说明 | 类型 | 默认值 | | 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- | | --- | --- | --- | --- |
| actions | 卡片操作组,位置在卡片底部 | Array<ReactNode> | - | | actions | 卡片操作组,位置在卡片底部 | Array<ReactNode> | - |
| activeTabKey | 当前激活页签的 key | string | - |
| bodyStyle | 内容区域自定义样式 | object | - | | bodyStyle | 内容区域自定义样式 | object | - |
| bordered | 是否有边框 | boolean | true | | bordered | 是否有边框 | boolean | true |
| cover | 卡片封面 | ReactNode | - | | cover | 卡片封面 | ReactNode | - |
| defaultActiveTabKey | 初始化选中页签的 key如果没有设置 activeTabKey | string | 第一个页签 |
| extra | 卡片右上角的操作区域 | string\|ReactNode | - | | extra | 卡片右上角的操作区域 | string\|ReactNode | - |
| hoverable | 鼠标移过时可浮起 | boolean | false | | hoverable | 鼠标移过时可浮起 | boolean | false |
| loading | 当卡片内容还在加载中时,可以用 loading 展示一个占位 | boolean | false | | loading | 当卡片内容还在加载中时,可以用 loading 展示一个占位 | boolean | false |
| tabList | 页签标题列表 | Array&lt;{key: string, tab: ReactNode}> | - | | tabList | 页签标题列表 | Array&lt;{key: string, tab: ReactNode}> | - |
| activeTabKey | 当前激活页签的 key | string | - |
| defaultActiveTabKey | 初始化选中页签的 key如果没有设置 activeTabKey | string | 第一个页签 |
| title | 卡片标题 | string\|ReactNode | - | | title | 卡片标题 | string\|ReactNode | - |
| type | 卡片类型,可设置为 `inner` 或 不设置 | string | - | | type | 卡片类型,可设置为 `inner` 或 不设置 | string | - |
| onTabChange | 页签切换的回调 | (key) => void | - | | onTabChange | 页签切换的回调 | (key) => void | - |

View File

@ -28,6 +28,7 @@ Cascade selection box.
| disabled | whether disabled select | boolean | false | | disabled | whether disabled select | boolean | false |
| displayRender | render function of displaying selected options | `(label, selectedOptions) => ReactNode` | `label => label.join(' / ')` | | displayRender | render function of displaying selected options | `(label, selectedOptions) => ReactNode` | `label => label.join(' / ')` |
| expandTrigger | expand current item when click or hover, one of 'click' 'hover' | string | 'click' | | expandTrigger | expand current item when click or hover, one of 'click' 'hover' | string | 'click' |
| filedNames | custom field name for label and value and children | object | `{ label: 'label', value: 'value', children: 'children' }` |
| getPopupContainer | Parent Node which the selector should be rendered to. Default to `body`. When position issues happen, try to modify it into scrollable content and position it relative.[example](https://codepen.io/afc163/pen/zEjNOy?editors=0010) | Function(triggerNode) | () => document.body | | getPopupContainer | Parent Node which the selector should be rendered to. Default to `body`. When position issues happen, try to modify it into scrollable content and position it relative.[example](https://codepen.io/afc163/pen/zEjNOy?editors=0010) | Function(triggerNode) | () => document.body |
| loadData | To load option lazily, and it cannot work with `showSearch` | `(selectedOptions) => void` | - | | loadData | To load option lazily, and it cannot work with `showSearch` | `(selectedOptions) => void` | - |
| notFoundContent | Specify content to show when no result matches. | string | 'Not Found' | | notFoundContent | Specify content to show when no result matches. | string | 'Not Found' |
@ -42,7 +43,6 @@ Cascade selection box.
| value | selected value | string\[] | - | | value | selected value | string\[] | - |
| onChange | callback when finishing cascader select | `(value, selectedOptions) => void` | - | | onChange | callback when finishing cascader select | `(value, selectedOptions) => void` | - |
| onPopupVisibleChange | callback when popup shown or hidden | `(value) => void` | - | | onPopupVisibleChange | callback when popup shown or hidden | `(value) => void` | - |
| filedNames | custom field name for label and value and children | object | `{ label: 'label', value: 'value', children: 'children' }` |
Fields in `showSearch`: Fields in `showSearch`:

View File

@ -29,6 +29,7 @@ subtitle: 级联选择
| disabled | 禁用 | boolean | false | | disabled | 禁用 | boolean | false |
| displayRender | 选择后展示的渲染函数 | `(label, selectedOptions) => ReactNode` | `label => label.join(' / ')` | | displayRender | 选择后展示的渲染函数 | `(label, selectedOptions) => ReactNode` | `label => label.join(' / ')` |
| expandTrigger | 次级菜单的展开方式,可选 'click' 和 'hover' | string | 'click' | | expandTrigger | 次级菜单的展开方式,可选 'click' 和 'hover' | string | 'click' |
| filedNames | 自定义 options 中 label name children 的字段 | object | `{ label: 'label', value: 'value', children: 'children' }` |
| getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。[示例](https://codepen.io/afc163/pen/zEjNOy?editors=0010) | Function(triggerNode) | () => document.body | | getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。[示例](https://codepen.io/afc163/pen/zEjNOy?editors=0010) | Function(triggerNode) | () => document.body |
| loadData | 用于动态加载选项,无法与 `showSearch` 一起使用 | `(selectedOptions) => void` | - | | loadData | 用于动态加载选项,无法与 `showSearch` 一起使用 | `(selectedOptions) => void` | - |
| notFoundContent | 当下拉列表为空时显示的内容 | string | 'Not Found' | | notFoundContent | 当下拉列表为空时显示的内容 | string | 'Not Found' |
@ -43,7 +44,6 @@ subtitle: 级联选择
| value | 指定选中项 | string\[] | - | | value | 指定选中项 | string\[] | - |
| onChange | 选择完成后的回调 | `(value, selectedOptions) => void` | - | | onChange | 选择完成后的回调 | `(value, selectedOptions) => void` | - |
| onPopupVisibleChange | 显示/隐藏浮层的回调 | `(value) => void` | - | | onPopupVisibleChange | 显示/隐藏浮层的回调 | `(value) => void` | - |
| filedNames | 自定义 options 中 label name children 的字段 | object | `{ label: 'label', value: 'value', children: 'children' }` |
`showSearch` 为对象时,其中的字段: `showSearch` 为对象时,其中的字段:

View File

@ -42,5 +42,5 @@ Checkbox.
| Name | Description | | Name | Description |
| ---- | ----------- | | ---- | ----------- |
| focus() | get focus |
| blur() | remove focus | | blur() | remove focus |
| focus() | get focus |

View File

@ -43,5 +43,5 @@ title: Checkbox
| 名称 | 描述 | | 名称 | 描述 |
| --- | --- | | --- | --- |
| focus() | 获取焦点 |
| blur() | 移除焦点 | | blur() | 移除焦点 |
| focus() | 获取焦点 |

View File

@ -27,7 +27,7 @@ A content area which can be collapsed and expanded.
| Property | Description | Type | Default | | Property | Description | Type | Default |
| -------- | ----------- | ---- | ------- | | -------- | ----------- | ---- | ------- |
| disabled | If `true`, panel cannot be opened or closed | boolean | `false` | | disabled | If `true`, panel cannot be opened or closed | boolean | `false` |
| forceRender | Forced render of content on panel, instead of lazy rending after clicking on header | boolean | `false` |
| header | Title of the panel | string\|ReactNode | - | | header | Title of the panel | string\|ReactNode | - |
| key | Unique key identifying the panel from among its siblings | string | - | | key | Unique key identifying the panel from among its siblings | string | - |
| showArrow | If `false`, panel will not show arrow icon | boolean | `true` | | showArrow | If `false`, panel will not show arrow icon | boolean | `true` |
| forceRender | Forced render of content on panel, instead of lazy rending after clicking on header | boolean | `false` |

View File

@ -28,6 +28,6 @@ cols: 1
| 参数 | 说明 | 类型 | 默认值 | | 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- | | --- | --- | --- | --- |
| disabled | 禁用后的面板展开与否将无法通过用户交互改变 | boolean | false | | disabled | 禁用后的面板展开与否将无法通过用户交互改变 | boolean | false |
| forceRender | 被隐藏时是否渲染 DOM 结构 | boolean | false |
| header | 面板头内容 | string\|ReactNode | 无 | | header | 面板头内容 | string\|ReactNode | 无 |
| key | 对应 activeKey | string | 无 | | key | 对应 activeKey | string | 无 |
| forceRender | 被隐藏时是否渲染 DOM 结构 | boolean | false |

View File

@ -78,7 +78,7 @@ describe('DatePicker', () => {
} }
onChange = (value) => { onChange = (value) => {
let cleared = this.state.cleared; let { cleared } = this.state;
if (cleared) { if (cleared) {
value = moment(moment(value).format('YYYY-MM-DD 12:12:12')); value = moment(moment(value).format('YYYY-MM-DD 12:12:12'));
@ -93,10 +93,11 @@ describe('DatePicker', () => {
} }
render() { render() {
const { value } = this.state;
return ( return (
<DatePicker <DatePicker
showTime showTime
value={this.state.value} value={value}
format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD HH:mm:ss"
onChange={this.onChange} onChange={this.onChange}
/> />

View File

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { mount, render } from 'enzyme'; import { mount, render } from 'enzyme';
import moment from 'moment'; import moment from 'moment';
import DatePicker from '../'; import DatePicker from '..';
import { setMockDate, resetMockDate } from '../../../tests/utils'; import { setMockDate, resetMockDate } from '../../../tests/utils';
import { selectDate } from './utils'; import { selectDate } from './utils';
import focusTest from '../../../tests/shared/focusTest'; import focusTest from '../../../tests/shared/focusTest';
@ -211,8 +211,8 @@ describe('RangePicker', () => {
selectDate(wrapper, moment('2017-09-18'), 0); selectDate(wrapper, moment('2017-09-18'), 0);
selectDate(wrapper, moment('2017-10-18'), 1); selectDate(wrapper, moment('2017-10-18'), 1);
wrapper.find('.ant-calendar-picker-input').simulate('click'); wrapper.find('.ant-calendar-picker-input').simulate('click');
expect(() => expect(() => (
wrapper.find('.ant-calendar-input').at(1).simulate('change', { target: { value: '2016-01-01' } }) wrapper.find('.ant-calendar-input').at(1).simulate('change', { target: { value: '2016-01-01' } })
).not.toThrow(); )).not.toThrow();
}); });
}); });

View File

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { mount, render } from 'enzyme'; import { mount, render } from 'enzyme';
import moment from 'moment'; import moment from 'moment';
import DatePicker from '../'; import DatePicker from '..';
const { MonthPicker, WeekPicker } = DatePicker; const { MonthPicker, WeekPicker } = DatePicker;

View File

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { mount } from 'enzyme'; import { mount } from 'enzyme';
import DatePicker from '../'; import DatePicker from '..';
const { RangePicker } = DatePicker; const { RangePicker } = DatePicker;

View File

@ -54,16 +54,16 @@ The following APIs are shared by DatePicker, MonthPicker, RangePicker, WeekPicke
| dateRender | custom rendering function for date cells | function(currentDate: moment, today: moment) => React.ReactNode | - | | dateRender | custom rendering function for date cells | function(currentDate: moment, today: moment) => React.ReactNode | - |
| disabled | determine whether the DatePicker is disabled | boolean | false | | disabled | determine whether the DatePicker is disabled | boolean | false |
| disabledDate | specify the date that cannot be selected | (currentDate: moment) => boolean | - | | disabledDate | specify the date that cannot be selected | (currentDate: moment) => boolean | - |
| dropdownClassName | to customize the className of the popup calendar | string | - |
| getCalendarContainer | to set the container of the floating layer, while the default is to create a `div` element in `body` | function(trigger) | - | | getCalendarContainer | to set the container of the floating layer, while the default is to create a `div` element in `body` | function(trigger) | - |
| locale | localization configuration | object | [default](https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json) | | locale | localization configuration | object | [default](https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json) |
| mode | picker panel mode | `time|date|month|year` | 'date' |
| open | open state of picker | boolean | - | | open | open state of picker | boolean | - |
| placeholder | placeholder of date input | string\|RangePicker\[] | - | | placeholder | placeholder of date input | string\|RangePicker\[] | - |
| popupStyle | to customize the style of the popup calendar | object | {} | | popupStyle | to customize the style of the popup calendar | object | {} |
| dropdownClassName | to customize the className of the popup calendar | string | - |
| size | determine the size of the input box, the height of `large` and `small`, are 40px and 24px respectively, while default size is 32px | string | - | | size | determine the size of the input box, the height of `large` and `small`, are 40px and 24px respectively, while default size is 32px | string | - |
| style | to customize the style of the input box | object | {} | | style | to customize the style of the input box | object | {} |
| onOpenChange | a callback function, can be executed whether the popup calendar is popped up or closed | function(status) | - | | onOpenChange | a callback function, can be executed whether the popup calendar is popped up or closed | function(status) | - |
| mode | picker panel mode | `time|date|month|year` | 'date' |
| onPanelChange | callback when picker panel mode is changed | function(value, mode) | - | | onPanelChange | callback when picker panel mode is changed | function(value, mode) | - |
### Common Methods ### Common Methods
@ -116,7 +116,7 @@ The following APIs are shared by DatePicker, MonthPicker, RangePicker, WeekPicke
| defaultValue | to set default date | \[[moment](http://momentjs.com/), [moment](http://momentjs.com/)] | - | | defaultValue | to set default date | \[[moment](http://momentjs.com/), [moment](http://momentjs.com/)] | - |
| disabledTime | to specify the time that cannot be selected | function(dates: [moment, moment], partial: `'start'|'end'`) | - | | disabledTime | to specify the time that cannot be selected | function(dates: [moment, moment], partial: `'start'|'end'`) | - |
| format | to set the date format | string | "YYYY-MM-DD HH:mm:ss" | | format | to set the date format | string | "YYYY-MM-DD HH:mm:ss" |
| ranges | preseted ranges for quick selection | { \[range: string\]&#x3A; [moment](http://momentjs.com/)\[] } \| () => { \[range: string\]&#x3A; [moment](http://momentjs.com/)\[] } | - | | ranges | preseted ranges for quick selection | { \[range: string]: [moment](http://momentjs.com/)\[] } \| () => { \[range: string]: [moment](http://momentjs.com/)\[] } | - |
| renderExtraFooter | render extra footer in panel | () => React.ReactNode | - | | renderExtraFooter | render extra footer in panel | () => React.ReactNode | - |
| showTime | to provide an additional time selection | object\|boolean | [TimePicker Options](/components/time-picker/#API) | | showTime | to provide an additional time selection | object\|boolean | [TimePicker Options](/components/time-picker/#API) |
| showTime.defaultValue | to set default time of selected date, [demo](https://ant.design/components/date-picker/#components-date-picker-demo-disabled-date) | [moment](http://momentjs.com/)\[] | [moment(), moment()] | | showTime.defaultValue | to set default time of selected date, [demo](https://ant.design/components/date-picker/#components-date-picker-demo-disabled-date) | [moment](http://momentjs.com/)\[] | [moment(), moment()] |

View File

@ -55,12 +55,12 @@ import 'moment/src/locale/zh-cn';
| dateRender | 自定义日期单元格的内容 | function(currentDate: moment, today: moment) => React.ReactNode | - | | dateRender | 自定义日期单元格的内容 | function(currentDate: moment, today: moment) => React.ReactNode | - |
| disabled | 禁用 | boolean | false | | disabled | 禁用 | boolean | false |
| disabledDate | 不可选择的日期 | (currentDate: moment) => boolean | 无 | | disabledDate | 不可选择的日期 | (currentDate: moment) => boolean | 无 |
| dropdownClassName | 额外的弹出日历 className | string | - |
| getCalendarContainer | 定义浮层的容器,默认为 body 上新建 div | function(trigger) | 无 | | getCalendarContainer | 定义浮层的容器,默认为 body 上新建 div | function(trigger) | 无 |
| locale | 国际化配置 | object | [默认配置](https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json) | | locale | 国际化配置 | object | [默认配置](https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json) |
| open | 控制弹层是否展开 | boolean | - | | open | 控制弹层是否展开 | boolean | - |
| placeholder | 输入框提示文字 | string\|RangePicker\[] | - | | placeholder | 输入框提示文字 | string\|RangePicker\[] | - |
| popupStyle | 额外的弹出日历样式 | object | {} | | popupStyle | 额外的弹出日历样式 | object | {} |
| dropdownClassName | 额外的弹出日历 className | string | - |
| size | 输入框大小,`large` 高度为 40px`small` 为 24px默认是 32px | string | 无 | | size | 输入框大小,`large` 高度为 40px`small` 为 24px默认是 32px | string | 无 |
| style | 自定义输入框样式 | object | {} | | style | 自定义输入框样式 | object | {} |
| onOpenChange | 弹出日历和关闭日历的回调 | function(status) | 无 | | onOpenChange | 弹出日历和关闭日历的回调 | function(status) | 无 |
@ -79,6 +79,7 @@ import 'moment/src/locale/zh-cn';
| defaultValue | 默认日期 | [moment](http://momentjs.com/) | 无 | | defaultValue | 默认日期 | [moment](http://momentjs.com/) | 无 |
| disabledTime | 不可选择的时间 | function(date) | 无 | | disabledTime | 不可选择的时间 | function(date) | 无 |
| format | 展示的日期格式,配置参考 [moment.js](http://momentjs.com/) | string | "YYYY-MM-DD" | | format | 展示的日期格式,配置参考 [moment.js](http://momentjs.com/) | string | "YYYY-MM-DD" |
| mode | 日期面板的状态 | `time|date|month|year` | 'date' |
| renderExtraFooter | 在面板中添加额外的页脚 | () => React.ReactNode | - | | renderExtraFooter | 在面板中添加额外的页脚 | () => React.ReactNode | - |
| showTime | 增加时间选择功能 | Object\|boolean | [TimePicker Options](/components/time-picker/#API) | | showTime | 增加时间选择功能 | Object\|boolean | [TimePicker Options](/components/time-picker/#API) |
| showTime.defaultValue | 设置用户选择日期时默认的时分秒,[例子](https://ant.design/components/date-picker/#components-date-picker-demo-disabled-date) | [moment](http://momentjs.com/) | moment() | | showTime.defaultValue | 设置用户选择日期时默认的时分秒,[例子](https://ant.design/components/date-picker/#components-date-picker-demo-disabled-date) | [moment](http://momentjs.com/) | moment() |
@ -86,7 +87,6 @@ import 'moment/src/locale/zh-cn';
| value | 日期 | [moment](http://momentjs.com/) | 无 | | value | 日期 | [moment](http://momentjs.com/) | 无 |
| onChange | 时间发生变化的回调 | function(date: moment, dateString: string) | 无 | | onChange | 时间发生变化的回调 | function(date: moment, dateString: string) | 无 |
| onOk | 点击确定按钮的回调 | function() | - | | onOk | 点击确定按钮的回调 | function() | - |
| mode | 日期面板的状态 | `time|date|month|year` | 'date' |
| onPanelChange | 日期面板变化时的回调 | function(value, mode) | - | | onPanelChange | 日期面板变化时的回调 | function(value, mode) | - |
### MonthPicker ### MonthPicker
@ -116,7 +116,7 @@ import 'moment/src/locale/zh-cn';
| defaultValue | 默认日期 | [moment](http://momentjs.com/)\[] | 无 | | defaultValue | 默认日期 | [moment](http://momentjs.com/)\[] | 无 |
| disabledTime | 不可选择的时间 | function(dates: [moment, moment], partial: `'start'|'end'`) | 无 | | disabledTime | 不可选择的时间 | function(dates: [moment, moment], partial: `'start'|'end'`) | 无 |
| format | 展示的日期格式 | string | "YYYY-MM-DD HH:mm:ss" | | format | 展示的日期格式 | string | "YYYY-MM-DD HH:mm:ss" |
| ranges       | 预设时间范围快捷选择 | { \[range: string\]&#x3A; [moment](http://momentjs.com/)\[] } \| () => { \[range: string\]&#x3A; [moment](http://momentjs.com/)\[] } | 无 | | ranges       | 预设时间范围快捷选择 | { \[range: string]: [moment](http://momentjs.com/)\[] } \| () => { \[range: string]: [moment](http://momentjs.com/)\[] } | 无 |
| renderExtraFooter | 在面板中添加额外的页脚 | () => React.ReactNode | - | | renderExtraFooter | 在面板中添加额外的页脚 | () => React.ReactNode | - |
| showTime | 增加时间选择功能 | Object\|boolean | [TimePicker Options](/components/time-picker/#API) | | showTime | 增加时间选择功能 | Object\|boolean | [TimePicker Options](/components/time-picker/#API) |
| showTime.defaultValue | 设置用户选择日期时默认的时分秒,[例子](https://ant.design/components/date-picker/#components-date-picker-demo-disabled-date) | [moment](http://momentjs.com/)\[] | [moment(), moment()] | | showTime.defaultValue | 设置用户选择日期时默认的时分秒,[例子](https://ant.design/components/date-picker/#components-date-picker-demo-disabled-date) | [moment](http://momentjs.com/)\[] | [moment(), moment()] |

View File

@ -44,7 +44,7 @@
float: left; float: left;
.@{calendar-prefix-cls} { .@{calendar-prefix-cls} {
&-time-picker-inner { &-time-picker-inner {
border-right: 1.5px solid @border-color-split; border-right: 1px solid @border-color-split;
} }
} }
} }
@ -53,7 +53,7 @@
float: right; float: right;
.@{calendar-prefix-cls} { .@{calendar-prefix-cls} {
&-time-picker-inner { &-time-picker-inner {
border-left: 1.5px solid @border-color-split; border-left: 1px solid @border-color-split;
} }
} }
} }
@ -208,10 +208,7 @@
} }
&-with-ranges.@{calendar-prefix-cls}-time .@{calendar-timepicker-prefix-cls} { &-with-ranges.@{calendar-prefix-cls}-time .@{calendar-timepicker-prefix-cls} {
height: 247px; height: 233px;
&-panel {
height: 281px;
}
} }
} }

View File

@ -18,8 +18,8 @@ A divider line separates different content.
| Property | Description | Type | Default | | Property | Description | Type | Default |
| -------- | ----------- | ---- | ------- | | -------- | ----------- | ---- | ------- |
| dashed | whether line is dashed | boolean | false |
| type | direction type of divider | enum: `horizontal` `vertical` | `horizontal` |
| orientation | position of title inside divider | enum: `left` `right` `center` | `center` |
| className | className of container | string | - | | className | className of container | string | - |
| dashed | whether line is dashed | boolean | false |
| orientation | position of title inside divider | enum: `left` `right` `center` | `center` |
| style | style object of container | object | - | | style | style object of container | object | - |
| type | direction type of divider | enum: `horizontal` `vertical` | `horizontal` |

View File

@ -16,8 +16,8 @@ subtitle: 分割线
| 参数 | 说明 | 类型 | 默认值 | | 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- | | --- | --- | --- | --- |
| dashed | 是否虚线 | boolean | false |
| type | 水平还是垂直类型 | enum: `horizontal` `vertical` | `horizontal` |
| orientation | 分割线标题的位置 | enum: `left` `right` | `center` |
| className | 分割线样式类 | string | - | | className | 分割线样式类 | string | - |
| dashed | 是否虚线 | boolean | false |
| orientation | 分割线标题的位置 | enum: `left` `right` | `center` |
| style | 分割线样式对象 | object | - | | style | 分割线样式对象 | object | - |
| type | 水平还是垂直类型 | enum: `horizontal` `vertical` | `horizontal` |

View File

@ -24,7 +24,7 @@ describe('DropdownButton', () => {
const dropdownProps = wrapper.find(Dropdown).props(); const dropdownProps = wrapper.find(Dropdown).props();
Object.keys(props).forEach((key) => { Object.keys(props).forEach((key) => {
expect(dropdownProps[key]).toBe(props[key]); expect(dropdownProps[key]).toBe(props[key]); // eslint-disable-line
}); });
}); });

View File

@ -63,11 +63,13 @@ export default class Dropdown extends React.Component<DropDownProps, any> {
// menu cannot be selectable in dropdown defaultly // menu cannot be selectable in dropdown defaultly
// menu should be focusable in dropdown defaultly // menu should be focusable in dropdown defaultly
const { selectable = false, focusable = true } = overlay.props; const { selectable = false, focusable = true } = overlay.props;
const fixedModeOverlay = React.cloneElement(overlay, {
mode: 'vertical', const fixedModeOverlay = typeof overlay.type === 'string'
selectable, ? overlay : React.cloneElement(overlay, {
focusable, mode: 'vertical',
}); selectable,
focusable,
});
const triggerActions = disabled ? [] : trigger; const triggerActions = disabled ? [] : trigger;
let alignPoint; let alignPoint;

View File

@ -58,6 +58,17 @@ The following `options` are available:
| onFieldsChange | Specify a function that will be called when the value a `Form.Item` gets changed. Usage example: saving the field's value to Redux store. | Function(props, fields) | | onFieldsChange | Specify a function that will be called when the value a `Form.Item` gets changed. Usage example: saving the field's value to Redux store. | Function(props, fields) |
| onValuesChange | A handler while value of any field is changed | (props, changedValues, allValues) => void | | onValuesChange | A handler while value of any field is changed | (props, changedValues, allValues) => void |
If you want to get `ref` after `Form.create`, you can use `wrappedComponentRef` provided by `rc-form`[details can be viewed here](https://github.com/react-component/form#note-use-wrappedcomponentref-instead-of-withref-after-rc-form140).
```jsx
class CustomizedForm extends React.Component { ... }
// use wrappedComponentRef
const EnhancedForm = Form.create()(CustomizedForm);
<EnhancedForm wrappedComponentRef={(form) => this.form = form} />
this.form // => The instance of CustomizedForm
```
If the form has been decorated by `Form.create` then it has `this.props.form` property. `this.props.form` provides some APIs as follows: If the form has been decorated by `Form.create` then it has `this.props.form` property. `this.props.form` provides some APIs as follows:
> Note: Before using `getFieldsValue` `getFieldValue` `setFieldsValue` and so on, please make sure that corresponding field had been registered with `getFieldDecorator`. > Note: Before using `getFieldsValue` `getFieldValue` `setFieldsValue` and so on, please make sure that corresponding field had been registered with `getFieldDecorator`.

View File

@ -60,6 +60,17 @@ CustomizedForm = Form.create({})(CustomizedForm);
| onFieldsChange | 当 `Form.Item` 子节点的值发生改变时触发,可以把对应的值转存到 Redux store | Function(props, fields) | | onFieldsChange | 当 `Form.Item` 子节点的值发生改变时触发,可以把对应的值转存到 Redux store | Function(props, fields) |
| onValuesChange | 任一表单域的值发生改变时的回调 | (props, changedValues, allValues) => void | | onValuesChange | 任一表单域的值发生改变时的回调 | (props, changedValues, allValues) => void |
经过 `Form.create` 之后如果要拿到 `ref`,可以使用 `rc-form` 提供的 `wrappedComponentRef`[详细内容可以查看这里](https://github.com/react-component/form#note-use-wrappedcomponentref-instead-of-withref-after-rc-form140)。
```jsx
class CustomizedForm extends React.Component { ... }
// use wrappedComponentRef
const EnhancedForm = Form.create()(CustomizedForm);
<EnhancedForm wrappedComponentRef={(form) => this.form = form} />
this.form // => The instance of CustomizedForm
```
经过 `Form.create` 包装的组件将会自带 `this.props.form` 属性,`this.props.form` 提供的 API 如下: 经过 `Form.create` 包装的组件将会自带 `this.props.form` 属性,`this.props.form` 提供的 API 如下:
> 注意:使用 `getFieldsValue` `getFieldValue` `setFieldsValue` 等时,应确保对应的 field 已经用 `getFieldDecorator` 注册过了。 > 注意:使用 `getFieldsValue` `getFieldValue` `setFieldsValue` 等时,应确保对应的 field 已经用 `getFieldDecorator` 注册过了。

View File

@ -9,7 +9,7 @@ describe('Input.Search', () => {
it('should support custom button', () => { it('should support custom button', () => {
const wrapper = mount( const wrapper = mount(
<Search enterButton={<button>ok</button>} /> <Search enterButton={<button type="button">ok</button>} />
); );
expect(wrapper.render()).toMatchSnapshot(); expect(wrapper.render()).toMatchSnapshot();
}); });
@ -71,7 +71,7 @@ describe('Input.Search', () => {
it('should trigger onSearch when click search button of native', () => { it('should trigger onSearch when click search button of native', () => {
const onSearch = jest.fn(); const onSearch = jest.fn();
const wrapper = mount( const wrapper = mount(
<Search defaultValue="search text" enterButton={<button>antd button</button>} onSearch={onSearch} /> <Search defaultValue="search text" enterButton={<button type="button">antd button</button>} onSearch={onSearch} />
); );
wrapper.find('button').simulate('click'); wrapper.find('button').simulate('click');
expect(onSearch).toHaveBeenCalledTimes(1); expect(onSearch).toHaveBeenCalledTimes(1);

View File

@ -34,7 +34,9 @@ exports[`Input.Search should support custom button 1`] = `
<span <span
class="ant-input-suffix" class="ant-input-suffix"
> >
<button> <button
type="button"
>
ok ok
</button> </button>
</span> </span>

View File

@ -60,10 +60,12 @@ describe('As Form Control', () => {
it('should be reset when wrapped in form.getFieldDecorator without initialValue', () => { it('should be reset when wrapped in form.getFieldDecorator without initialValue', () => {
class Demo extends React.Component { class Demo extends React.Component {
reset = () => { reset = () => {
this.props.form.resetFields(); const { form } = this.props;
form.resetFields();
} }
render() { render() {
const { getFieldDecorator } = this.props.form; const { form: { getFieldDecorator } } = this.props;
return ( return (
<Form> <Form>
<Form.Item> <Form.Item>
@ -72,7 +74,7 @@ describe('As Form Control', () => {
<Form.Item> <Form.Item>
{getFieldDecorator('textarea')(<Input.TextArea />)} {getFieldDecorator('textarea')(<Input.TextArea />)}
</Form.Item> </Form.Item>
<button onClick={this.reset}>reset</button> <button type="button" onClick={this.reset}>reset</button>
</Form> </Form>
); );
} }

View File

@ -76,8 +76,8 @@ The wrapper.
| Property | Description | Type | Default | | Property | Description | Type | Default |
| -------- | ----------- | ---- | ------- | | -------- | ----------- | ---- | ------- |
| className | container className | string | - | | className | container className | string | - |
| style | to customize the styles | object | - |
| hasSider | whether contain Sider in children, don't have to assign it normally. Useful in ssr avoid style flickering | boolean | - | | hasSider | whether contain Sider in children, don't have to assign it normally. Useful in ssr avoid style flickering | boolean | - |
| style | to customize the styles | object | - |
> APIs of `Layout.Header` `Layout.Footer` `Layout.Content` are the same as that of `Layout`. > APIs of `Layout.Header` `Layout.Footer` `Layout.Content` are the same as that of `Layout`.
@ -95,6 +95,7 @@ The sidebar.
| defaultCollapsed | to set the initial status | boolean | false | | defaultCollapsed | to set the initial status | boolean | false |
| reverseArrow | reverse direction of arrow, for a sider that expands from the right | boolean | false | | reverseArrow | reverse direction of arrow, for a sider that expands from the right | boolean | false |
| style | to customize the styles | object | - | | style | to customize the styles | object | - |
| theme | color theme of the sidebar | string: `light` `dark` | `dark` |
| trigger | specify the customized trigger, set to null to hide the trigger | string\|ReactNode | - | | trigger | specify the customized trigger, set to null to hide the trigger | string\|ReactNode | - |
| width | width of the sidebar | number\|string | 200 | | width | width of the sidebar | number\|string | 200 |
| onCollapse | the callback function, executed by clicking the trigger or activating the responsive layout | (collapsed, type) => {} | - | | onCollapse | the callback function, executed by clicking the trigger or activating the responsive layout | (collapsed, type) => {} | - |

View File

@ -77,8 +77,8 @@ title: Layout
| 参数 | 说明 | 类型 | 默认值 | | 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- | | --- | --- | --- | --- |
| className | 容器 className | string | - | | className | 容器 className | string | - |
| style | 指定样式 | object | - |
| hasSider | 表示子元素里有 Sider一般不用指定。可用于服务端渲染时避免样式闪动 | boolean | - | | hasSider | 表示子元素里有 Sider一般不用指定。可用于服务端渲染时避免样式闪动 | boolean | - |
| style | 指定样式 | object | - |
> `Layout.Header` `Layout.Footer` `Layout.Content` API 与 `Layout` 相同 > `Layout.Header` `Layout.Footer` `Layout.Content` API 与 `Layout` 相同
@ -96,6 +96,7 @@ title: Layout
| defaultCollapsed | 是否默认收起 | boolean | false | | defaultCollapsed | 是否默认收起 | boolean | false |
| reverseArrow | 翻转折叠提示箭头的方向,当 Sider 在右边时可以使用 | boolean | false | | reverseArrow | 翻转折叠提示箭头的方向,当 Sider 在右边时可以使用 | boolean | false |
| style | 指定样式 | object | - | | style | 指定样式 | object | - |
| theme | 主题颜色 | string: `light` `dark` | `dark` |
| trigger | 自定义 trigger设置为 null 时隐藏 trigger | string\|ReactNode | - | | trigger | 自定义 trigger设置为 null 时隐藏 trigger | string\|ReactNode | - |
| width | 宽度 | number\|string | 200 | | width | 宽度 | number\|string | 200 |
| onCollapse | 展开-收起时的回调函数,有点击 trigger 以及响应式反馈两种方式可以触发 | (collapsed, type) => {} | - | | onCollapse | 展开-收起时的回调函数,有点击 trigger 以及响应式反馈两种方式可以触发 | (collapsed, type) => {} | - |

View File

@ -19,7 +19,7 @@ describe('List.pagination', () => {
pagination={pagination} pagination={pagination}
dataSource={data} dataSource={data}
renderItem={item => ( renderItem={item => (
<List.Item key={item.key} > <List.Item key={item.key}>
{item.name} {item.name}
</List.Item> </List.Item>
)} )}

View File

@ -23,8 +23,8 @@ A list can be used to display content related to a single subject. The content c
| header | List header renderer | string\|ReactNode | - | | header | List header renderer | string\|ReactNode | - |
| itemLayout | The layout of list, default is `horizontal`, If a vertical list is desired, set the itemLayout property to `vertical` | string | - | | itemLayout | The layout of list, default is `horizontal`, If a vertical list is desired, set the itemLayout property to `vertical` | string | - |
| loading | Shows a loading indicator while the contents of the list are being fetched | boolean\|[object](https://ant.design/components/spin-cn/#API) ([more](https://github.com/ant-design/ant-design/issues/8659)) | false | | loading | Shows a loading indicator while the contents of the list are being fetched | boolean\|[object](https://ant.design/components/spin-cn/#API) ([more](https://github.com/ant-design/ant-design/issues/8659)) | false |
| locale | i18n text including empty text | object | emptyText: 'No Data' <br> |
| loadMore | Shows a load more content | string\|ReactNode | - | | loadMore | Shows a load more content | string\|ReactNode | - |
| locale | i18n text including empty text | object | emptyText: 'No Data' <br> |
| pagination | Pagination [config](https://ant.design/components/pagination/), hide it by setting it to false | boolean \| object | false | | pagination | Pagination [config](https://ant.design/components/pagination/), hide it by setting it to false | boolean \| object | false |
| split | Toggles rendering of the split under the list item | boolean | true | | split | Toggles rendering of the split under the list item | boolean | true |

View File

@ -24,8 +24,8 @@ cols: 1
| header | 列表头部 | string\|ReactNode | - | | header | 列表头部 | string\|ReactNode | - |
| itemLayout | 设置 `List.Item` 布局, 设置成 `vertical` 则竖直样式显示, 默认横排 | string | - | | itemLayout | 设置 `List.Item` 布局, 设置成 `vertical` 则竖直样式显示, 默认横排 | string | - |
| loading | 当卡片内容还在加载中时,可以用 `loading` 展示一个占位 | boolean\|[object](https://ant.design/components/spin-cn/#API) ([更多](https://github.com/ant-design/ant-design/issues/8659)) | false | | loading | 当卡片内容还在加载中时,可以用 `loading` 展示一个占位 | boolean\|[object](https://ant.design/components/spin-cn/#API) ([更多](https://github.com/ant-design/ant-design/issues/8659)) | false |
| locale | 默认文案设置,目前包括空数据文案 | object | emptyText: '暂无数据' |
| loadMore | 加载更多 | string\|ReactNode | - | | loadMore | 加载更多 | string\|ReactNode | - |
| locale | 默认文案设置,目前包括空数据文案 | object | emptyText: '暂无数据' |
| pagination | 对应的 `pagination` 配置, 设置 `false` 不显示 | boolean\|object | false | | pagination | 对应的 `pagination` 配置, 设置 `false` 不显示 | boolean\|object | false |
| size | list 的尺寸 | `default` \| `middle` \| `small` | `default` | | size | list 的尺寸 | `default` \| `middle` \| `small` | `default` |
| split | 是否展示分割线 | boolean | true | | split | 是否展示分割线 | boolean | true |

View File

@ -4,7 +4,7 @@ import { mount } from 'enzyme';
import moment from 'moment'; import moment from 'moment';
import MockDate from 'mockdate'; import MockDate from 'mockdate';
import { LocaleProvider, Pagination, DatePicker, TimePicker, Calendar, import { LocaleProvider, Pagination, DatePicker, TimePicker, Calendar,
Popconfirm, Table, Modal, Select, Transfer } from '../../'; Popconfirm, Table, Modal, Select, Transfer } from '../..';
import enGB from '../en_GB'; import enGB from '../en_GB';
import frFR from '../fr_FR'; import frFR from '../fr_FR';
import nlBE from '../nl_BE'; import nlBE from '../nl_BE';
@ -113,6 +113,7 @@ describe('Locale Provider', () => {
title: 'Hello World!', title: 'Hello World!',
}); });
} }
render() { render() {
return null; return null;
} }
@ -142,8 +143,9 @@ describe('Locale Provider', () => {
} }
render() { render() {
const { locale } = this.state;
return ( return (
<LocaleProvider locale={this.state.locale}> <LocaleProvider locale={locale}>
<div> <div>
<DatePicker defaultValue={moment()} open /> <DatePicker defaultValue={moment()} open />
</div> </div>

View File

@ -103,6 +103,7 @@ describe('message', () => {
componentDidMount() { componentDidMount() {
hide = message.loading('Action in progress..', 0); hide = message.loading('Action in progress..', 0);
} }
render() { render() {
return <div>test</div>; return <div>test</div>;
} }
@ -123,6 +124,7 @@ describe('message', () => {
message.loading('Action in progress2..', 0); message.loading('Action in progress2..', 0);
setTimeout(() => message.destroy(), 1000); setTimeout(() => message.destroy(), 1000);
} }
render() { render() {
return <div>test</div>; return <div>test</div>;
} }

View File

@ -35,6 +35,7 @@ Methods for global configuration and destruction are also provided:
- `message.destroy()` - `message.destroy()`
`afterClose` can be called in then-able interface: `afterClose` can be called in then-able interface:
- `message[level](content, [duration]).then(afterClose)` - `message[level](content, [duration]).then(afterClose)`
- `message[level](content, [duration], onClose).then(afterClose)` - `message[level](content, [duration], onClose).then(afterClose)`
@ -54,5 +55,5 @@ message.config({
| -------- | ----------- | ---- | ------- | | -------- | ----------- | ---- | ------- |
| duration | time before auto-dismiss, in seconds | number | 1.5 | | duration | time before auto-dismiss, in seconds | number | 1.5 |
| getContainer | Return the mount node for Message | () => HTMLElement | () => document.body | | getContainer | Return the mount node for Message | () => HTMLElement | () => document.body |
| top | distance from top | number | 24 |
| maxCount | max message show, drop oldest if exceed limit | number | - | | maxCount | max message show, drop oldest if exceed limit | number | - |
| top | distance from top | number | 24 |

View File

@ -56,5 +56,5 @@ message.config({
| --- | --- | --- | --- | | --- | --- | --- | --- |
| duration | 默认自动关闭延时,单位秒 | number | 3 | | duration | 默认自动关闭延时,单位秒 | number | 3 |
| getContainer | 配置渲染节点的输出位置 | () => HTMLElement | () => document.body | | getContainer | 配置渲染节点的输出位置 | () => HTMLElement | () => document.body |
| top | 消息距离顶部的位置 | number | 24 |
| maxCount | 最大显示数, 超过限制时,最早的消息会被自动关闭 | number | - | | maxCount | 最大显示数, 超过限制时,最早的消息会被自动关闭 | number | - |
| top | 消息距离顶部的位置 | number | 24 |

View File

@ -9,22 +9,27 @@ class ModalTester extends React.Component {
super(props); super(props);
this.state = { visible: false }; this.state = { visible: false };
} }
componentDidMount() { componentDidMount() {
this.setState({ visible: true }); // eslint-disable-line react/no-did-mount-set-state this.setState({ visible: true }); // eslint-disable-line react/no-did-mount-set-state
} }
saveContainer = (container) => { saveContainer = (container) => {
this.container = container; this.container = container;
} }
getContainer = () => { getContainer = () => {
return this.container; return this.container;
} }
render() { render() {
const { visible } = this.state;
return ( return (
<div> <div>
<div ref={this.saveContainer} /> <div ref={this.saveContainer} />
<Modal <Modal
{...this.props} {...this.props}
visible={this.state.visible} visible={visible}
getContainer={this.getContainer} getContainer={this.getContainer}
> >
Here is content of Modal Here is content of Modal

View File

@ -65,13 +65,13 @@ The properties of the object are follows:
| className | className of container | string | - | | className | className of container | string | - |
| content | Content | string\|ReactNode | - | | content | Content | string\|ReactNode | - |
| iconType | Icon `type` of the Icon component | string | `question-circle` | | iconType | Icon `type` of the Icon component | string | `question-circle` |
| keyboard | Whether support press esc to close | Boolean | true |
| maskClosable | Whether to close the modal dialog when the mask (area outside the modal) is clicked | Boolean | `false` | | maskClosable | Whether to close the modal dialog when the mask (area outside the modal) is clicked | Boolean | `false` |
| okText | Text of the OK button | string | `OK` | | okText | Text of the OK button | string | `OK` |
| okType | Button `type` of the OK button | string | `primary` | | okType | Button `type` of the OK button | string | `primary` |
| title | Title | string\|ReactNode | - | | title | Title | string\|ReactNode | - |
| width | Width of the modal dialog | string\|number | 416 | | width | Width of the modal dialog | string\|number | 416 |
| zIndex | The `z-index` of the Modal | Number | 1000 | | zIndex | The `z-index` of the Modal | Number | 1000 |
| keyboard | Whether support press esc to close | Boolean | true |
| onCancel | Specify a function that will be called when the user clicks the Cancel button. The parameter of this function is a function whose execution should include closing the dialog. You can also just return a promise and when the promise is resolved, the modal dialog will also be closed | function | - | | onCancel | Specify a function that will be called when the user clicks the Cancel button. The parameter of this function is a function whose execution should include closing the dialog. You can also just return a promise and when the promise is resolved, the modal dialog will also be closed | function | - |
| onOk | Specify a function that will be called when the user clicks the OK button. The parameter of this function is a function whose execution should include closing the dialog. You can also just return a promise and when the promise is resolved, the modal dialog will also be closed | function | - | | onOk | Specify a function that will be called when the user clicks the OK button. The parameter of this function is a function whose execution should include closing the dialog. You can also just return a promise and when the promise is resolved, the modal dialog will also be closed | function | - |

View File

@ -25,6 +25,7 @@ title: Modal
| destroyOnClose | 关闭时销毁 Modal 里的子元素 | boolean | false | | destroyOnClose | 关闭时销毁 Modal 里的子元素 | boolean | false |
| footer | 底部内容,当不需要默认底部按钮时,可以设为 `footer={null}` | string\|ReactNode | 确定取消按钮 | | footer | 底部内容,当不需要默认底部按钮时,可以设为 `footer={null}` | string\|ReactNode | 确定取消按钮 |
| getContainer | 指定 Modal 挂载的 HTML 节点 | (instance): HTMLElement | () => document.body | | getContainer | 指定 Modal 挂载的 HTML 节点 | (instance): HTMLElement | () => document.body |
| keyboard | 是否支持键盘esc关闭 | boolean | true |
| mask | 是否展示遮罩 | Boolean | true | | mask | 是否展示遮罩 | Boolean | true |
| maskClosable | 点击蒙层是否允许关闭 | boolean | true | | maskClosable | 点击蒙层是否允许关闭 | boolean | true |
| maskStyle | 遮罩样式 | object | {} | | maskStyle | 遮罩样式 | object | {} |
@ -38,7 +39,6 @@ title: Modal
| width | 宽度 | string\|number | 520 | | width | 宽度 | string\|number | 520 |
| wrapClassName | 对话框外层容器的类名 | string | - | | wrapClassName | 对话框外层容器的类名 | string | - |
| zIndex | 设置 Modal 的 `z-index` | Number | 1000 | | zIndex | 设置 Modal 的 `z-index` | Number | 1000 |
| keyboard | 是否支持键盘esc关闭 | boolean | true |
| onCancel | 点击遮罩层或右上角叉或取消按钮的回调 | function(e) | 无 | | onCancel | 点击遮罩层或右上角叉或取消按钮的回调 | function(e) | 无 |
| onOk | 点击确定回调 | function(e) | 无 | | onOk | 点击确定回调 | function(e) | 无 |

View File

@ -26,6 +26,6 @@ If it will take a long time to complete an operation, you can use `Progress` to
| strokeWidth `(type=line)` | to set the width of the progress bar, unit: `px` | number | 10 | | strokeWidth `(type=line)` | to set the width of the progress bar, unit: `px` | number | 10 |
| strokeWidth `(type=circle)` | to set the width of the circular progress bar, unit: percentage of the canvas width | number | 6 | | strokeWidth `(type=circle)` | to set the width of the circular progress bar, unit: percentage of the canvas width | number | 6 |
| strokeColor | color of progress bar | string | - | | strokeColor | color of progress bar | string | - |
| successPercent | segmented success percent, works when `type="line"` | number | 0 |
| type | to set the type, options: `line` `circle` `dashboard` | string | `line` | | type | to set the type, options: `line` `circle` `dashboard` | string | `line` |
| width `(type=circle)` | to set the canvas width of the circular progress bar, unit: `px` | number | 132 | | width `(type=circle)` | to set the canvas width of the circular progress bar, unit: `px` | number | 132 |
| successPercent | segmented success percent, works when `type="line"` | number | 0 |

View File

@ -27,6 +27,6 @@ title: Progress
| strokeWidth `(type=line)` | 进度条线的宽度,单位 px | number | 10 | | strokeWidth `(type=line)` | 进度条线的宽度,单位 px | number | 10 |
| strokeWidth `(type=circle)` | 圆形进度条线的宽度,单位是进度条画布宽度的百分比 | number | 6 | | strokeWidth `(type=circle)` | 圆形进度条线的宽度,单位是进度条画布宽度的百分比 | number | 6 |
| strokeColor | 进度条的色彩 | string | - | | strokeColor | 进度条的色彩 | string | - |
| successPercent | 已完成的分段百分比,`type="line"` 时有效 | number | 0 |
| type | 类型,可选 `line` `circle` `dashboard` | string | line | | type | 类型,可选 `line` `circle` `dashboard` | string | line |
| width `(type=circle)` | 圆形进度条画布宽度,单位 px | number | 132 | | width `(type=circle)` | 圆形进度条画布宽度,单位 px | number | 132 |
| successPercent | 已完成的分段百分比,`type="line"` 时有效 | number | 0 |

View File

@ -42,13 +42,13 @@ Select component to select value from options.
| optionFilterProp | Which prop value of option will be used for filter if filterOption is true | string | value | | optionFilterProp | Which prop value of option will be used for filter if filterOption is true | string | value |
| optionLabelProp | Which prop value of option will render as content of select. | string | `value` for `combobox`, `children` for other modes | | optionLabelProp | Which prop value of option will render as content of select. | string | `value` for `combobox`, `children` for other modes |
| placeholder | Placeholder of select | string\|ReactNode | - | | placeholder | Placeholder of select | string\|ReactNode | - |
| showArrow | Whether to show the drop-down arrow | boolean | true |
| showSearch | Whether show search input in single mode. | boolean | false | | showSearch | Whether show search input in single mode. | boolean | false |
| showArrow | Whether to show the drop-down arrow | boolean | true |
| size | Size of Select input. `default` `large` `small` | string | default | | size | Size of Select input. `default` `large` `small` | string | default |
| tokenSeparators | Separator used to tokenize on tag/multiple mode | string\[] | | | tokenSeparators | Separator used to tokenize on tag/multiple mode | string\[] | |
| value | Current selected option. | string\|number\|string\[]\|number\[] | - | | value | Current selected option. | string\|number\|string\[]\|number\[] | - |
| onBlur | Called when blur | function | - | | onBlur | Called when blur | function | - |
| onChange | Called when select an option or input value change, or value of input is changed in combobox mode | function(value, option:Option/Array<Option\>) | - | | onChange | Called when select an option or input value change, or value of input is changed in combobox mode | function(value, option:Option/Array&lt;Option>) | - |
| onDeselect | Called when a option is deselected, the params are option's value (or key) . only called for multiple or tags, effective in multiple or tags mode only. | function(value, option:Option) | - | | onDeselect | Called when a option is deselected, the params are option's value (or key) . only called for multiple or tags, effective in multiple or tags mode only. | function(value, option:Option) | - |
| onFocus | Called when focus | function | - | | onFocus | Called when focus | function | - |
| onInputKeyDown | Called when key pressed | function | - | | onInputKeyDown | Called when key pressed | function | - |

View File

@ -44,14 +44,14 @@ title: Select
| optionFilterProp | 搜索时过滤对应的 option 属性,如设置为 children 表示对内嵌内容进行搜索 | string | value | | optionFilterProp | 搜索时过滤对应的 option 属性,如设置为 children 表示对内嵌内容进行搜索 | string | value |
| optionLabelProp | 回填到选择框的 Option 的属性值,默认是 Option 的子元素。比如在子元素需要高亮效果时,此值可以设为 `value`。 | string | `children` combobox 模式下为 `value` | | optionLabelProp | 回填到选择框的 Option 的属性值,默认是 Option 的子元素。比如在子元素需要高亮效果时,此值可以设为 `value`。 | string | `children` combobox 模式下为 `value` |
| placeholder | 选择框默认文字 | string | - | | placeholder | 选择框默认文字 | string | - |
| showArrow | 是否显示下拉小箭头 | boolean | true |
| showSearch | 使单选模式可搜索 | boolean | false | | showSearch | 使单选模式可搜索 | boolean | false |
| showArrow | 是否显示下拉小箭头 | boolean | true |
| size | 选择框大小,可选 `large` `small` | string | default | | size | 选择框大小,可选 `large` `small` | string | default |
| tags | 可以把随意输入的条目作为 tag输入项不需要与下拉选项匹配2.9 之后废弃,请使用 `mode` | boolean | false | | tags | 可以把随意输入的条目作为 tag输入项不需要与下拉选项匹配2.9 之后废弃,请使用 `mode` | boolean | false |
| tokenSeparators | 在 tags 和 multiple 模式下自动分词的分隔符 | string\[] | | | tokenSeparators | 在 tags 和 multiple 模式下自动分词的分隔符 | string\[] | |
| value | 指定当前选中的条目 | string\|string\[]\|number\|number\[] | - | | value | 指定当前选中的条目 | string\|string\[]\|number\|number\[] | - |
| onBlur | 失去焦点的时回调 | function | - | | onBlur | 失去焦点的时回调 | function | - |
| onChange | 选中 option或 input 的 value 变化combobox 模式下)时,调用此函数 | function(value, option:Option/Array<Option\>) | - | | onChange | 选中 option或 input 的 value 变化combobox 模式下)时,调用此函数 | function(value, option:Option/Array&lt;Option>) | - |
| onDeselect | 取消选中时调用,参数为选中项的 value (或 key) 值,仅在 multiple 或 tags 模式下生效 | function(valueoption:Option) | - | | onDeselect | 取消选中时调用,参数为选中项的 value (或 key) 值,仅在 multiple 或 tags 模式下生效 | function(valueoption:Option) | - |
| onFocus | 获得焦点时回调 | function | - | | onFocus | 获得焦点时回调 | function | - |
| onMouseEnter | 鼠标移入时回调 | function | - | | onMouseEnter | 鼠标移入时回调 | function | - |

View File

@ -50,20 +50,20 @@ class App extends React.Component {
<Steps current={current}> <Steps current={current}>
{steps.map(item => <Step key={item.title} title={item.title} />)} {steps.map(item => <Step key={item.title} title={item.title} />)}
</Steps> </Steps>
<div className="steps-content">{steps[this.state.current].content}</div> <div className="steps-content">{steps[current].content}</div>
<div className="steps-action"> <div className="steps-action">
{ {
this.state.current < steps.length - 1 current < steps.length - 1
&& &&
<Button type="primary" onClick={() => this.next()}>Next</Button> <Button type="primary" onClick={() => this.next()}>Next</Button>
} }
{ {
this.state.current === steps.length - 1 current === steps.length - 1
&& &&
<Button type="primary" onClick={() => message.success('Processing complete!')}>Done</Button> <Button type="primary" onClick={() => message.success('Processing complete!')}>Done</Button>
} }
{ {
this.state.current > 0 current > 0
&& &&
<Button style={{ marginLeft: 8 }} onClick={() => this.prev()}> <Button style={{ marginLeft: 8 }} onClick={() => this.prev()}>
Previous Previous

View File

@ -2,7 +2,7 @@
@import "../../style/mixins/index"; @import "../../style/mixins/index";
@steps-prefix-cls: ~"@{ant-prefix}-steps"; @steps-prefix-cls: ~"@{ant-prefix}-steps";
@process-icon-color: @processing-color; @process-icon-color: @primary-color;
@process-title-color: @heading-color; @process-title-color: @heading-color;
@process-description-color: @text-color; @process-description-color: @text-color;
@process-tail-color: @border-color-split; @process-tail-color: @border-color-split;

View File

@ -239,6 +239,7 @@ describe('Table.filter', () => {
} }
render() { render() {
const { filters } = this.state;
return ( return (
<Table dataSource={data} onChange={this.handleChange}> <Table dataSource={data} onChange={this.handleChange}>
<Column <Column
@ -249,7 +250,7 @@ describe('Table.filter', () => {
{ text: 'Jack', value: 'Jack' }, { text: 'Jack', value: 'Jack' },
{ text: 'Lucy', value: 'Lucy' }, { text: 'Lucy', value: 'Lucy' },
]} ]}
filteredValue={this.state.filters.name} filteredValue={filters.name}
onFilter={filterFn} onFilter={filterFn}
/> />
</Table> </Table>

View File

@ -306,13 +306,15 @@ describe('Table.rowSelection', () => {
state = { state = {
disableName: 'Jack', disableName: 'Jack',
}; };
render() { render() {
const { disableName } = this.state;
return ( return (
<Table <Table
columns={columns} columns={columns}
dataSource={data} dataSource={data}
rowSelection={{ rowSelection={{
getCheckboxProps: record => ({ disabled: record.name === this.state.disableName }), getCheckboxProps: record => ({ disabled: record.name === disableName }),
}} }}
/> />
); );

View File

@ -66,7 +66,7 @@ const columns = [{
| indentSize | Indent size in pixels of tree data | number | 15 | | indentSize | Indent size in pixels of tree data | number | 15 |
| loading | Loading status of table | boolean\|[object](https://ant.design/components/spin-cn/#API) ([more](https://github.com/ant-design/ant-design/issues/4544#issuecomment-271533135)) | `false` | | loading | Loading status of table | boolean\|[object](https://ant.design/components/spin-cn/#API) ([more](https://github.com/ant-design/ant-design/issues/4544#issuecomment-271533135)) | `false` |
| locale | i18n text including filter, sort, empty text, etc | object | filterConfirm: 'Ok' <br> filterReset: 'Reset' <br> emptyText: 'No Data' <br> [Default](https://github.com/ant-design/ant-design/issues/575#issuecomment-159169511) | | locale | i18n text including filter, sort, empty text, etc | object | filterConfirm: 'Ok' <br> filterReset: 'Reset' <br> emptyText: 'No Data' <br> [Default](https://github.com/ant-design/ant-design/issues/575#issuecomment-159169511) |
| pagination | Pagination [config](#pagination) or [`Pagination`] (/components/pagination/), hide it by setting it to `false` | object | | | pagination | Pagination [config](#pagination) or [`Pagination`](/components/pagination/), hide it by setting it to `false` | object | |
| rowClassName | Row's className | Function(record, index):string | - | | rowClassName | Row's className | Function(record, index):string | - |
| rowKey | Row's unique key, could be a string or function that returns a string | string\|Function(record):string | `key` | | rowKey | Row's unique key, could be a string or function that returns a string | string\|Function(record):string | `key` |
| rowSelection | Row selection [config](#rowSelection) | object | null | | rowSelection | Row selection [config](#rowSelection) | object | null |
@ -107,6 +107,7 @@ One of the Table `columns` prop for describing the table's columns, Column has t
| Property | Description | Type | Default | | Property | Description | Type | Default |
| -------- | ----------- | ---- | ------- | | -------- | ----------- | ---- | ------- |
| align | specify how content is aligned | 'left' \| 'right' \| 'center' | 'left' |
| className | className of this column | string | - | | className | className of this column | string | - |
| colSpan | Span of this column's title | number | | | colSpan | Span of this column's title | number | |
| dataIndex | Display field of the data record, could be set like `a.b.c` | string | - | | dataIndex | Display field of the data record, could be set like `a.b.c` | string | - |
@ -121,7 +122,6 @@ One of the Table `columns` prop for describing the table's columns, Column has t
| fixed | Set column to be fixed: `true`(same as left) `'left'` `'right'` | boolean\|string | `false` | | fixed | Set column to be fixed: `true`(same as left) `'left'` `'right'` | boolean\|string | `false` |
| key | Unique key of this column, you can ignore this prop if you've set a unique `dataIndex` | string | - | | key | Unique key of this column, you can ignore this prop if you've set a unique `dataIndex` | string | - |
| render | Renderer of the table cell. The return value should be a ReactNode, or an object for [colSpan/rowSpan config](#components-table-demo-colspan-rowspan) | Function(text, record, index) {} | - | | render | Renderer of the table cell. The return value should be a ReactNode, or an object for [colSpan/rowSpan config](#components-table-demo-colspan-rowspan) | Function(text, record, index) {} | - |
| align | specify how content is aligned | 'left' \| 'right' \| 'center' | 'left' |
| sorter | Sort function for local sort, see [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)'s compareFunction. If you need sort buttons only, set to `true` | Function\|boolean | - | | sorter | Sort function for local sort, see [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)'s compareFunction. If you need sort buttons only, set to `true` | Function\|boolean | - |
| sortOrder | Order of sorted values: `'ascend'` `'descend'` `false` | boolean\|string | - | | sortOrder | Order of sorted values: `'ascend'` `'descend'` `false` | boolean\|string | - |
| title | Title of this column | string\|ReactNode | - | | title | Title of this column | string\|ReactNode | - |
@ -153,11 +153,11 @@ Properties for row selection.
| Property | Description | Type | Default | | Property | Description | Type | Default |
| -------- | ----------- | ---- | ------- | | -------- | ----------- | ---- | ------- |
| columnWidth | Set the width of the selection column | string\|number | - |
| fixed | Fixed selection column on the left | boolean | - | | fixed | Fixed selection column on the left | boolean | - |
| getCheckboxProps | Get Checkbox or Radio props | Function(record) | - | | getCheckboxProps | Get Checkbox or Radio props | Function(record) | - |
| hideDefaultSelections | Remove the default `Select All` and `Select Invert` selections | boolean | `false` | | hideDefaultSelections | Remove the default `Select All` and `Select Invert` selections | boolean | `false` |
| selectedRowKeys | Controlled selected row keys | string\[] | \[] | | selectedRowKeys | Controlled selected row keys | string\[] | \[] |
| columnWidth | Set the width of the selection column | string\|number | - |
| selections | Custom selection [config](#rowSelection), only displays default selections when set to `true` | object\[]\|boolean | - | | selections | Custom selection [config](#rowSelection), only displays default selections when set to `true` | object\[]\|boolean | - |
| type | `checkbox` or `radio` | `checkbox` \| `radio` | `checkbox` | | type | `checkbox` or `radio` | `checkbox` \| `radio` | `checkbox` |
| onChange | Callback executed when selected rows change | Function(selectedRowKeys, selectedRows) | - | | onChange | Callback executed when selected rows change | Function(selectedRowKeys, selectedRows) | - |

View File

@ -81,7 +81,6 @@ const columns = [{
| onHeaderRow | 设置头部行属性 | Function(column, index) | - | | onHeaderRow | 设置头部行属性 | Function(column, index) | - |
| onRow | 设置行属性 | Function(record, index) | - | | onRow | 设置行属性 | Function(record, index) | - |
#### onRow 用法 #### onRow 用法
适用于 `onRow` `onHeaderRow` `onCell` `onHeaderCell` 适用于 `onRow` `onHeaderRow` `onCell` `onHeaderCell`
@ -109,6 +108,7 @@ const columns = [{
| 参数 | 说明 | 类型 | 默认值 | | 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- | | --- | --- | --- | --- |
| align | 设置列内容的对齐方式 | 'left' \| 'right' \| 'center' | 'left' |
| className | 列的 className | string | - | | className | 列的 className | string | - |
| colSpan | 表头列合并,设置为 0 时,不渲染 | number | | | colSpan | 表头列合并,设置为 0 时,不渲染 | number | |
| dataIndex | 列数据在数据项中对应的 key支持 `a.b.c` 的嵌套写法 | string | - | | dataIndex | 列数据在数据项中对应的 key支持 `a.b.c` 的嵌套写法 | string | - |
@ -122,7 +122,6 @@ const columns = [{
| fixed | 列是否固定,可选 `true`(等效于 left) `'left'` `'right'` | boolean\|string | false | | fixed | 列是否固定,可选 `true`(等效于 left) `'left'` `'right'` | boolean\|string | false |
| key | React 需要的 key如果已经设置了唯一的 `dataIndex`,可以忽略这个属性 | string | - | | key | React 需要的 key如果已经设置了唯一的 `dataIndex`,可以忽略这个属性 | string | - |
| render | 生成复杂数据的渲染函数,参数分别为当前行的值,当前行数据,行索引,@return里面可以设置表格[行/列合并](#components-table-demo-colspan-rowspan) | Function(text, record, index) {} | - | | render | 生成复杂数据的渲染函数,参数分别为当前行的值,当前行数据,行索引,@return里面可以设置表格[行/列合并](#components-table-demo-colspan-rowspan) | Function(text, record, index) {} | - |
| align | 设置列内容的对齐方式 | 'left' \| 'right' \| 'center' | 'left' |
| sorter | 排序函数,本地排序使用一个函数(参考 [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) 的 compareFunction),需要服务端排序可设为 true | Function\|boolean | - | | sorter | 排序函数,本地排序使用一个函数(参考 [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) 的 compareFunction),需要服务端排序可设为 true | Function\|boolean | - |
| sortOrder | 排序的受控属性,外界可用此控制列的排序,可设置为 `'ascend'` `'descend'` `false` | boolean\|string | - | | sortOrder | 排序的受控属性,外界可用此控制列的排序,可设置为 `'ascend'` `'descend'` `false` | boolean\|string | - |
| title | 列头显示文字 | string\|ReactNode | - | | title | 列头显示文字 | string\|ReactNode | - |
@ -154,11 +153,11 @@ const columns = [{
| 参数 | 说明 | 类型 | 默认值 | | 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- | | --- | --- | --- | --- |
| columnWidth | 自定义列表选择框宽度 | string\|number | - |
| fixed | 把选择框列固定在左边 | boolean | - | | fixed | 把选择框列固定在左边 | boolean | - |
| getCheckboxProps | 选择框的默认属性配置 | Function(record) | - | | getCheckboxProps | 选择框的默认属性配置 | Function(record) | - |
| hideDefaultSelections | 去掉『全选』『反选』两个默认选项 | boolean | false | | hideDefaultSelections | 去掉『全选』『反选』两个默认选项 | boolean | false |
| selectedRowKeys | 指定选中项的 key 数组,需要和 onChange 进行配合 | string\[] | \[] | | selectedRowKeys | 指定选中项的 key 数组,需要和 onChange 进行配合 | string\[] | \[] |
| columnWidth | 自定义列表选择框宽度 | string\|number | - |
| selections | 自定义选择项 [配置项](#selection), 设为 `true` 时使用默认选择项 | object\[]\|boolean | true | | selections | 自定义选择项 [配置项](#selection), 设为 `true` 时使用默认选择项 | object\[]\|boolean | true |
| type | 多选/单选,`checkbox` or `radio` | string | `checkbox` | | type | 多选/单选,`checkbox` or `radio` | string | `checkbox` |
| onChange | 选中项发生变化的时的回调 | Function(selectedRowKeys, selectedRows) | - | | onChange | 选中项发生变化的时的回调 | Function(selectedRowKeys, selectedRows) | - |

View File

@ -27,6 +27,7 @@ Ant Design has 3 types of Tabs for different situations.
| hideAdd | Hide plus icon or not. Only works while `type="editable-card"` | boolean | `false` | | hideAdd | Hide plus icon or not. Only works while `type="editable-card"` | boolean | `false` |
| size | preset tab bar size | `large` \| `default` \| `small` | `default` | | size | preset tab bar size | `large` \| `default` \| `small` | `default` |
| tabBarExtraContent | Extra content in tab bar | React.ReactNode | - | | tabBarExtraContent | Extra content in tab bar | React.ReactNode | - |
| tabBarGutter | The gap between tabs | number | - |
| tabBarStyle | Tab bar style object | object | - | | tabBarStyle | Tab bar style object | object | - |
| tabPosition | Position of tabs | `top` \| `right` \| `bottom` \| `left` | `top` | | tabPosition | Position of tabs | `top` \| `right` \| `bottom` \| `left` | `top` |
| type | Basic style of tabs | `line` \| `card` \| `editable-card` | `line` | | type | Basic style of tabs | `line` \| `card` \| `editable-card` | `line` |
@ -35,7 +36,6 @@ Ant Design has 3 types of Tabs for different situations.
| onNextClick | Callback executed when next button is clicked | Function | - | | onNextClick | Callback executed when next button is clicked | Function | - |
| onPrevClick | Callback executed when prev button is clicked | Function | - | | onPrevClick | Callback executed when prev button is clicked | Function | - |
| onTabClick | Callback executed when tab is clicked | Function | - | | onTabClick | Callback executed when tab is clicked | Function | - |
| tabBarGutter | The gap between tabs | number | - |
### Tabs.TabPane ### Tabs.TabPane

View File

@ -30,6 +30,7 @@ Ant Design 依次提供了三级选项卡,分别用于不同的场景。
| hideAdd | 是否隐藏加号图标,在 `type="editable-card"` 时有效 | boolean | false | | hideAdd | 是否隐藏加号图标,在 `type="editable-card"` 时有效 | boolean | false |
| size | 大小,提供 `large` `default``small` 三种大小 | string | 'default' | | size | 大小,提供 `large` `default``small` 三种大小 | string | 'default' |
| tabBarExtraContent | tab bar 上额外的元素 | React.ReactNode | 无 | | tabBarExtraContent | tab bar 上额外的元素 | React.ReactNode | 无 |
| tabBarGutter | tabs 之间的间隙 | number | 无 |
| tabBarStyle | tab bar 的样式对象 | object | - | | tabBarStyle | tab bar 的样式对象 | object | - |
| tabPosition | 页签位置,可选值有 `top` `right` `bottom` `left` | string | 'top' | | tabPosition | 页签位置,可选值有 `top` `right` `bottom` `left` | string | 'top' |
| type | 页签的基本样式,可选 `line`、`card` `editable-card` 类型 | string | 'line' | | type | 页签的基本样式,可选 `line`、`card` `editable-card` 类型 | string | 'line' |
@ -38,7 +39,6 @@ Ant Design 依次提供了三级选项卡,分别用于不同的场景。
| onNextClick | next 按钮被点击的回调 | Function | 无 | | onNextClick | next 按钮被点击的回调 | Function | 无 |
| onPrevClick | prev 按钮被点击的回调 | Function | 无 | | onPrevClick | prev 按钮被点击的回调 | Function | 无 |
| onTabClick | tab 被点击的回调 | Function | 无 | | onTabClick | tab 被点击的回调 | Function | 无 |
| tabBarGutter | tabs 之间的间隙 | number | 无 |
### Tabs.TabPane ### Tabs.TabPane

View File

@ -4,7 +4,9 @@ exports[`TimePicker renders addon correctly 1`] = `
<div <div
class="ant-time-picker-panel-addon" class="ant-time-picker-panel-addon"
> >
<button> <button
type="button"
>
Ok Ok
</button> </button>
</div> </div>

View File

@ -8,7 +8,7 @@ describe('TimePicker', () => {
focusTest(TimePicker); focusTest(TimePicker);
it('renders addon correctly', () => { it('renders addon correctly', () => {
const addon = () => (<button>Ok</button>); const addon = () => (<button type="button">Ok</button>);
const wrapper = mount(<TimePicker addon={addon} />); const wrapper = mount(<TimePicker addon={addon} />);
const rcTimePicker = wrapper.find(RcTimePicker); const rcTimePicker = wrapper.find(RcTimePicker);
const addonWrapper = render(rcTimePicker.props().addon()); const addonWrapper = render(rcTimePicker.props().addon());

View File

@ -39,7 +39,7 @@ import moment from 'moment';
| getPopupContainer | 定义浮层的容器,默认为 body 上新建 div | function(trigger) | 无 | | getPopupContainer | 定义浮层的容器,默认为 body 上新建 div | function(trigger) | 无 |
| hideDisabledOptions | 隐藏禁止选择的选项 | boolean | false | | hideDisabledOptions | 隐藏禁止选择的选项 | boolean | false |
| hourStep | 小时选项间隔 | number | 1 | | hourStep | 小时选项间隔 | number | 1 |
| inputReadOnly | 设置输入框为只读(避免在移动设备上打开虚拟键盘)| boolean | false | | inputReadOnly | 设置输入框为只读(避免在移动设备上打开虚拟键盘) | boolean | false |
| minuteStep | 分钟选项间隔 | number | 1 | | minuteStep | 分钟选项间隔 | number | 1 |
| open | 面板是否打开 | boolean | false | | open | 面板是否打开 | boolean | false |
| placeholder | 没有值的时候显示的内容 | string | "请选择时间" | | placeholder | 没有值的时候显示的内容 | string | "请选择时间" |

View File

@ -1,6 +1,6 @@
--- ---
order: 0 order: 0
title: title:
zh-CN: 基本用法 zh-CN: 基本用法
en-US: Basic en-US: Basic
--- ---
@ -9,7 +9,7 @@ title:
基本的时间轴。 基本的时间轴。
## en-US ## en-US
Basic timeline. Basic timeline.

View File

@ -14,7 +14,9 @@ describe('Tooltip', () => {
mouseLeaveDelay={0} mouseLeaveDelay={0}
onVisibleChange={onVisibleChange} onVisibleChange={onVisibleChange}
> >
<div id="hello">Hello world!</div> <div id="hello">
Hello world!
</div>
</Tooltip> </Tooltip>
); );
@ -60,7 +62,7 @@ describe('Tooltip', () => {
mouseLeaveDelay={0} mouseLeaveDelay={0}
onVisibleChange={onVisibleChange} onVisibleChange={onVisibleChange}
> >
<button disabled>Hello world!</button> <button type="button" disabled>Hello world!</button>
</Tooltip> </Tooltip>
); );
@ -122,7 +124,7 @@ describe('Tooltip', () => {
mouseEnterDelay={0} mouseEnterDelay={0}
mouseLeaveDelay={0} mouseLeaveDelay={0}
> >
<button disabled>Hello world!</button> <button type="button" disabled>Hello world!</button>
</Tooltip> </Tooltip>
); );
@ -143,7 +145,7 @@ describe('Tooltip', () => {
mouseLeaveDelay={0} mouseLeaveDelay={0}
placement="bottomLeft" placement="bottomLeft"
> >
<button style={{ width: triggerWidth }}> <button type="button" style={{ width: triggerWidth }}>
Hello world! Hello world!
</button> </button>
</Tooltip> </Tooltip>
@ -160,7 +162,7 @@ describe('Tooltip', () => {
placement="bottomLeft" placement="bottomLeft"
arrowPointAtCenter arrowPointAtCenter
> >
<button style={{ width: triggerWidth }}> <button type="button" style={{ width: triggerWidth }}>
Hello world! Hello world!
</button> </button>
</Tooltip> </Tooltip>

View File

@ -214,12 +214,12 @@ describe('Transfer', () => {
}); });
it('should check correctly when there is a search text', () => { it('should check correctly when there is a search text', () => {
const props = { ...listCommonProps }; const newProps = { ...listCommonProps };
delete props.targetKeys; delete newProps.targetKeys;
delete props.selectedKeys; delete newProps.selectedKeys;
const handleSelectChange = jest.fn(); const handleSelectChange = jest.fn();
const wrapper = mount( const wrapper = mount(
<Transfer {...props} showSearch onSelectChange={handleSelectChange} render={item => item.title} /> <Transfer {...newProps} showSearch onSelectChange={handleSelectChange} render={item => item.title} />
); );
wrapper.find(TransferItem).filterWhere(n => n.prop('item').key === 'b').simulate('click'); wrapper.find(TransferItem).filterWhere(n => n.prop('item').key === 'b').simulate('click');
expect(handleSelectChange).toHaveBeenLastCalledWith(['b'], []); expect(handleSelectChange).toHaveBeenLastCalledWith(['b'], []);

View File

@ -22,15 +22,15 @@ One or more elements can be selected from either column, one click on the proper
| filterOption | A function to determine whether an item should show in search result list | (inputValue, option): boolean | | | filterOption | A function to determine whether an item should show in search result list | (inputValue, option): boolean | |
| footer | A function used for rendering the footer. | (props): ReactNode | | | footer | A function used for rendering the footer. | (props): ReactNode | |
| lazy | property of [react-lazy-load](https://github.com/loktar00/react-lazy-load) for lazy rendering items. Turn off it by set to `false`. | object\|boolean | `{ height: 32, offset: 32 }` | | lazy | property of [react-lazy-load](https://github.com/loktar00/react-lazy-load) for lazy rendering items. Turn off it by set to `false`. | object\|boolean | `{ height: 32, offset: 32 }` |
| style | A custom CSS style used for rendering wrapper element. | object | |
| listStyle | A custom CSS style used for rendering the transfer columns. | object | | | listStyle | A custom CSS style used for rendering the transfer columns. | object | |
| operationStyle | A custom CSS style used for rendering the operations column. | object | |
| notFoundContent | Text to display when a column is empty. | string\|ReactNode | 'The list is empty' | | notFoundContent | Text to display when a column is empty. | string\|ReactNode | 'The list is empty' |
| operations | A set of operations that are sorted from bottom to top. | string\[] | ['>', '<'] | | operations | A set of operations that are sorted from bottom to top. | string\[] | ['>', '<'] |
| operationStyle | A custom CSS style used for rendering the operations column. | object | |
| render | The function to generate the item shown on a column. Based on an record (element of the dataSource array), this function should return a React element which is generated from that record. Also, it can return a plain object with `value` and `label`, `label` is a React element and `value` is for title | Function(record) | | | render | The function to generate the item shown on a column. Based on an record (element of the dataSource array), this function should return a React element which is generated from that record. Also, it can return a plain object with `value` and `label`, `label` is a React element and `value` is for title | Function(record) | |
| searchPlaceholder | The hint text of the search box. | string | 'Search here' | | searchPlaceholder | The hint text of the search box. | string | 'Search here' |
| selectedKeys | A set of keys of selected items. | string\[] | \[] | | selectedKeys | A set of keys of selected items. | string\[] | \[] |
| showSearch | If included, a search box is shown on each column. | boolean | false | | showSearch | If included, a search box is shown on each column. | boolean | false |
| style | A custom CSS style used for rendering wrapper element. | object | |
| targetKeys | A set of keys of elements that are listed on the right column. | string\[] | \[] | | targetKeys | A set of keys of elements that are listed on the right column. | string\[] | \[] |
| titles | A set of titles that are sorted from left to right. | string\[] | - | | titles | A set of titles that are sorted from left to right. | string\[] | - |
| onChange | A callback function that is executed when the transfer between columns is complete. | (targetKeys, direction, moveKeys): void | | | onChange | A callback function that is executed when the transfer between columns is complete. | (targetKeys, direction, moveKeys): void | |

View File

@ -22,7 +22,7 @@ class Demo extends React.Component {
value: undefined, value: undefined,
} }
onChange = (value) => { onChange = (value) => {
console.log(arguments); console.log(value);
this.setState({ value }); this.setState({ value });
} }
render() { render() {

View File

@ -50,7 +50,7 @@ class Demo extends React.Component {
value: ['0-0-0'], value: ['0-0-0'],
} }
onChange = (value) => { onChange = (value) => {
console.log('onChange ', value, arguments); console.log('onChange ', value);
this.setState({ value }); this.setState({ value });
} }
render() { render() {

View File

@ -22,7 +22,7 @@ class Demo extends React.Component {
value: undefined, value: undefined,
} }
onChange = (value) => { onChange = (value) => {
console.log(arguments); console.log(value);
this.setState({ value }); this.setState({ value });
} }
render() { render() {

View File

@ -41,7 +41,7 @@ class Demo extends React.Component {
value: undefined, value: undefined,
} }
onChange = (value) => { onChange = (value) => {
console.log(arguments); console.log(value);
this.setState({ value }); this.setState({ value });
} }
render() { render() {

View File

@ -24,6 +24,7 @@ export interface AntdTreeNodeAttribute {
disableCheckbox: boolean; disableCheckbox: boolean;
} }
export interface AntTreeNodeProps { export interface AntTreeNodeProps {
className?: string;
disabled?: boolean; disabled?: boolean;
disableCheckbox?: boolean; disableCheckbox?: boolean;
title?: string | React.ReactNode; title?: string | React.ReactNode;
@ -92,6 +93,7 @@ export interface TreeProps {
selectedKeys?: string[]; selectedKeys?: string[];
/** 默认选中的树节点 */ /** 默认选中的树节点 */
defaultSelectedKeys?: string[]; defaultSelectedKeys?: string[];
selectable?: boolean;
/** 展开/收起节点时触发 */ /** 展开/收起节点时触发 */
onExpand?: (expandedKeys: string[], info: AntTreeNodeExpandedEvent) => void | PromiseLike<any>; onExpand?: (expandedKeys: string[], info: AntTreeNodeExpandedEvent) => void | PromiseLike<any>;
/** 点击复选框触发 */ /** 点击复选框触发 */

View File

@ -61,7 +61,7 @@ class Demo extends React.Component {
selectedKeys: [], selectedKeys: [],
} }
onExpand = (expandedKeys) => { onExpand = (expandedKeys) => {
console.log('onExpand', arguments); console.log('onExpand', expandedKeys);
// if not set autoExpandParent to false, if children expanded, parent can not collapse. // if not set autoExpandParent to false, if children expanded, parent can not collapse.
// or, you can remove all expanded children keys. // or, you can remove all expanded children keys.
this.setState({ this.setState({

View File

@ -90,7 +90,7 @@ class SearchTree extends React.Component {
onChange = (e) => { onChange = (e) => {
const value = e.target.value; const value = e.target.value;
const expandedKeys = dataList.map((item) => { const expandedKeys = dataList.map((item) => {
if (item.key.indexOf(value) > -1) { if (item.title.indexOf(value) > -1) {
return getParentKey(item.key, gData); return getParentKey(item.key, gData);
} }
return null; return null;
@ -104,16 +104,16 @@ class SearchTree extends React.Component {
render() { render() {
const { searchValue, expandedKeys, autoExpandParent } = this.state; const { searchValue, expandedKeys, autoExpandParent } = this.state;
const loop = data => data.map((item) => { const loop = data => data.map((item) => {
const index = item.key.indexOf(searchValue); const index = item.title.indexOf(searchValue);
const beforeStr = item.key.substr(0, index); const beforeStr = item.title.substr(0, index);
const afterStr = item.key.substr(index + searchValue.length); const afterStr = item.title.substr(index + searchValue.length);
const title = index > -1 ? ( const title = index > -1 ? (
<span> <span>
{beforeStr} {beforeStr}
<span style={{ color: '#f50' }}>{searchValue}</span> <span style={{ color: '#f50' }}>{searchValue}</span>
{afterStr} {afterStr}
</span> </span>
) : <span>{item.key}</span>; ) : <span>{item.title}</span>;
if (item.children) { if (item.children) {
return ( return (
<TreeNode key={item.key} title={title}> <TreeNode key={item.key} title={title}>

View File

@ -17,7 +17,9 @@ exports[`Upload List handle error 1`] = `
style="display: none;" style="display: none;"
type="file" type="file"
/> />
<button> <button
type="button"
>
upload upload
</button> </button>
</span> </span>
@ -91,7 +93,9 @@ exports[`Upload List should be uploading when upload a file 1`] = `
style="display: none;" style="display: none;"
type="file" type="file"
/> />
<button> <button
type="button"
>
upload upload
</button> </button>
</span> </span>
@ -165,7 +169,9 @@ exports[`Upload List should be uploading when upload a file 2`] = `
style="display: none;" style="display: none;"
type="file" type="file"
/> />
<button> <button
type="button"
>
upload upload
</button> </button>
</span> </span>
@ -239,7 +245,9 @@ exports[`Upload List should non-image format file preview 1`] = `
style="display: none;" style="display: none;"
type="file" type="file"
/> />
<button> <button
type="button"
>
upload upload
</button> </button>
</span> </span>

View File

@ -16,6 +16,7 @@ describe('Upload', () => {
componentDidMount() { componentDidMount() {
ref = this.refs.input; ref = this.refs.input;
} }
render() { render() {
return ( return (
<Upload supportServerRender={false}> <Upload supportServerRender={false}>
@ -32,9 +33,9 @@ describe('Upload', () => {
const data = jest.fn(); const data = jest.fn();
const props = { const props = {
action: 'http://upload.com', action: 'http://upload.com',
beforeUpload: () => new Promise(resolve => beforeUpload: () => new Promise(resolve => (
setTimeout(() => resolve('success'), 100) setTimeout(() => resolve('success'), 100)
), )),
data, data,
onChange: ({ file }) => { onChange: ({ file }) => {
if (file.status !== 'uploading') { if (file.status !== 'uploading') {
@ -46,7 +47,7 @@ describe('Upload', () => {
const wrapper = mount( const wrapper = mount(
<Upload {...props}> <Upload {...props}>
<button>upload</button> <button type="button">upload</button>
</Upload> </Upload>
); );
@ -83,7 +84,7 @@ describe('Upload', () => {
const wrapper = mount( const wrapper = mount(
<Upload {...props}> <Upload {...props}>
<button>upload</button> <button type="button">upload</button>
</Upload> </Upload>
); );
@ -118,7 +119,7 @@ describe('Upload', () => {
const wrapper = mount( const wrapper = mount(
<Upload {...props}> <Upload {...props}>
<button>upload</button> <button type="button">upload</button>
</Upload> </Upload>
); );
@ -147,7 +148,7 @@ describe('Upload', () => {
const wrapper = mount( const wrapper = mount(
<Upload {...props}> <Upload {...props}>
<button>upload</button> <button type="button">upload</button>
</Upload> </Upload>
); );

View File

@ -29,7 +29,7 @@ describe('Upload List', () => {
it('should use file.thumbUrl for <img /> in priority', () => { it('should use file.thumbUrl for <img /> in priority', () => {
const wrapper = mount( const wrapper = mount(
<Upload defaultFileList={fileList} listType="picture"> <Upload defaultFileList={fileList} listType="picture">
<button>upload</button> <button type="button">upload</button>
</Upload> </Upload>
); );
fileList.forEach((file, i) => { fileList.forEach((file, i) => {
@ -57,7 +57,7 @@ describe('Upload List', () => {
}]; }];
const wrapper = mount( const wrapper = mount(
<Upload defaultFileList={list}> <Upload defaultFileList={list}>
<button>upload</button> <button type="button">upload</button>
</Upload> </Upload>
); );
expect(wrapper.find('.ant-upload-list-item').length).toBe(2); expect(wrapper.find('.ant-upload-list-item').length).toBe(2);
@ -84,7 +84,7 @@ describe('Upload List', () => {
onChange={onChange} onChange={onChange}
customRequest={successRequest} customRequest={successRequest}
> >
<button>upload</button> <button type="button">upload</button>
</Upload> </Upload>
); );
wrapper.find('input').simulate('change', { wrapper.find('input').simulate('change', {
@ -110,7 +110,7 @@ describe('Upload List', () => {
onChange={onChange} onChange={onChange}
customRequest={errorRequest} customRequest={errorRequest}
> >
<button>upload</button> <button type="button">upload</button>
</Upload> </Upload>
); );
wrapper.find('input').simulate('change', { wrapper.find('input').simulate('change', {
@ -131,7 +131,7 @@ describe('Upload List', () => {
onChange={handleChange} onChange={handleChange}
beforeUpload={() => false} beforeUpload={() => false}
> >
<button>upload</button> <button type="button">upload</button>
</Upload> </Upload>
); );
@ -152,15 +152,14 @@ describe('Upload List', () => {
let errors; let errors;
class TestForm extends React.Component { class TestForm extends React.Component {
handleSubmit = () => { handleSubmit = () => {
const { validateFields } = this.props.form; const { form: { validateFields } } = this.props;
validateFields((err) => { validateFields((err) => {
errors = err; errors = err;
}); });
} }
render() { render() {
const { getFieldDecorator } = this.props.form; const { form: { getFieldDecorator } } = this.props;
return ( return (
<Form onSubmit={this.handleSubmit}> <Form onSubmit={this.handleSubmit}>
<Form.Item> <Form.Item>
@ -183,7 +182,7 @@ describe('Upload List', () => {
<Upload <Upload
beforeUpload={() => false} beforeUpload={() => false}
> >
<button>upload</button> <button type="button">upload</button>
</Upload> </Upload>
)} )}
</Form.Item> </Form.Item>
@ -216,7 +215,7 @@ describe('Upload List', () => {
defaultFileList={fileList} defaultFileList={fileList}
onPreview={handlePreview} onPreview={handlePreview}
> >
<button>upload</button> <button type="button">upload</button>
</Upload> </Upload>
); );
wrapper.find('.anticon-eye-o').at(0).simulate('click'); wrapper.find('.anticon-eye-o').at(0).simulate('click');
@ -235,7 +234,7 @@ describe('Upload List', () => {
onRemove={handleRemove} onRemove={handleRemove}
onChange={handleChange} onChange={handleChange}
> >
<button>upload</button> <button type="button">upload</button>
</Upload> </Upload>
); );
wrapper.find('.anticon-delete').at(0).simulate('click'); wrapper.find('.anticon-delete').at(0).simulate('click');
@ -258,7 +257,7 @@ describe('Upload List', () => {
defaultFileList={newFileList} defaultFileList={newFileList}
onPreview={handlePreview} onPreview={handlePreview}
> >
<button>upload</button> <button type="button">upload</button>
</Upload> </Upload>
); );
wrapper.setState({}); wrapper.setState({});
@ -332,7 +331,7 @@ describe('Upload List', () => {
listType="picture" listType="picture"
defaultFileList={list} defaultFileList={list}
> >
<button>upload</button> <button type="button">upload</button>
</Upload> </Upload>
); );
expect(wrapper.render()).toMatchSnapshot(); expect(wrapper.render()).toMatchSnapshot();

View File

@ -1,6 +1,6 @@
{ {
"name": "antd", "name": "antd",
"version": "3.6.3", "version": "3.6.4",
"title": "Ant Design", "title": "Ant Design",
"description": "An enterprise-class UI design language and React-based implementation", "description": "An enterprise-class UI design language and React-based implementation",
"homepage": "http://ant.design/", "homepage": "http://ant.design/",
@ -92,9 +92,9 @@
"ansi-styles": "^3.2.0", "ansi-styles": "^3.2.0",
"ant-design-palettes": "^1.0.0", "ant-design-palettes": "^1.0.0",
"antd-theme-generator": "1.0.7", "antd-theme-generator": "1.0.7",
"antd-tools": "^5.1.2", "antd-tools": "^5.1.6",
"babel-cli": "^6.18.0", "babel-cli": "^6.18.0",
"babel-eslint": "^8.1.1", "babel-eslint": "8.2.3",
"babel-plugin-import": "^1.0.0", "babel-plugin-import": "^1.0.0",
"babel-plugin-transform-runtime": "^6.23.0", "babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-es2015": "^6.18.0", "babel-preset-es2015": "^6.18.0",
@ -118,7 +118,7 @@
"enzyme-adapter-react-16": "^1.0.0", "enzyme-adapter-react-16": "^1.0.0",
"enzyme-to-json": "^3.1.2", "enzyme-to-json": "^3.1.2",
"eslint": "^4.8.0", "eslint": "^4.8.0",
"eslint-config-airbnb": "latest", "eslint-config-airbnb": "^16.1.0",
"eslint-plugin-babel": "^5.0.0", "eslint-plugin-babel": "^5.0.0",
"eslint-plugin-import": "^2.2.0", "eslint-plugin-import": "^2.2.0",
"eslint-plugin-jsx-a11y": "^6.0.2", "eslint-plugin-jsx-a11y": "^6.0.2",

View File

@ -55,9 +55,9 @@ function alphabetSort(nodes) {
function sizeSort(nodes) { function sizeSort(nodes) {
return nodes.sort((...comparison) => { return nodes.sort((...comparison) => {
return asciiSort( return asciiSort(
...comparison.map(val => ...comparison.map(val => (
sizeBreakPoints.indexOf(getCellValue(val).toLowerCase()) sizeBreakPoints.indexOf(getCellValue(val).toLowerCase())
) ))
); );
}); });
} }

View File

@ -13,9 +13,9 @@ function alertBabelConfig(rules) {
if (rule.options.plugins.indexOf(replaceLib) === -1) { if (rule.options.plugins.indexOf(replaceLib) === -1) {
rule.options.plugins.push(replaceLib); rule.options.plugins.push(replaceLib);
} }
rule.options.plugins = rule.options.plugins.filter(plugin => rule.options.plugins = rule.options.plugins.filter(plugin => (
!plugin.indexOf || plugin.indexOf('babel-plugin-add-module-exports') === -1 !plugin.indexOf || plugin.indexOf('babel-plugin-add-module-exports') === -1
); ));
} else if (rule.use) { } else if (rule.use) {
alertBabelConfig(rule.use); alertBabelConfig(rule.use);
} }

View File

@ -10,8 +10,8 @@ function pickerGenerator(module) {
const tester = new RegExp(`^docs/${module}`); const tester = new RegExp(`^docs/${module}`);
return (markdownData) => { return (markdownData) => {
const { filename } = markdownData.meta; const { filename } = markdownData.meta;
if (tester.test(filename) && if (tester.test(filename)
!/\/demo$/.test(path.dirname(filename))) { && !/\/demo$/.test(path.dirname(filename))) {
return { return {
meta: markdownData.meta, meta: markdownData.meta,
}; };
@ -29,8 +29,8 @@ module.exports = {
pick: { pick: {
components(markdownData) { components(markdownData) {
const { filename } = markdownData.meta; const { filename } = markdownData.meta;
if (!/^components/.test(filename) || if (!/^components/.test(filename)
/[/\\]demo$/.test(path.dirname(filename))) return; || /[/\\]demo$/.test(path.dirname(filename))) return;
return { return {
meta: markdownData.meta, meta: markdownData.meta,

View File

@ -11,10 +11,12 @@ export default class ColorBlock extends Component {
fontWeight: index === 6 ? 'bold' : 'normal', fontWeight: index === 6 ? 'bold' : 'normal',
}; };
} }
onCopied = () => { onCopied = () => {
const { color } = this.props; const { color } = this.props;
message.success(`Copied: ${color}`); message.success(`Copied: ${color}`);
} }
render() { render() {
const { color, index } = this.props; const { color, index } = this.props;
return ( return (

View File

@ -36,24 +36,25 @@ export default class ColorPaletteTool extends Component {
} }
render() { render() {
const { primaryColor } = this.state;
return ( return (
<div className="color-palette-horizontal"> <div className="color-palette-horizontal">
<div className="color-palette-pick"> <div className="color-palette-pick">
<FormattedMessage id="app.docs.color.pick-primary" /> <FormattedMessage id="app.docs.color.pick-primary" />
</div> </div>
<div className="main-color"> <div className="main-color">
<ColorPatterns color={this.state.primaryColor} /> <ColorPatterns color={primaryColor} />
</div> </div>
<div className="color-palette-picker"> <div className="color-palette-picker">
<span style={{ display: 'inline-block', verticalAlign: 'middle' }}> <span style={{ display: 'inline-block', verticalAlign: 'middle' }}>
<ColorPicker <ColorPicker
type="chrome" type="chrome"
color={this.state.primaryColor} color={primaryColor}
onChange={this.handleChangeColor} onChange={this.handleChangeColor}
/> />
</span> </span>
<span className="color-palette-picker-value"> <span className="color-palette-picker-value">
{this.state.primaryColor} {primaryColor}
</span> </span>
{this.renderColorValidation()} {this.renderColorValidation()}
</div> </div>

View File

@ -22,34 +22,42 @@ export default class ColorPicker extends Component {
color: props.color, color: props.color,
}; };
} }
componentWillReceiveProps(nextProps) { componentWillReceiveProps(nextProps) {
this.setState({ color: nextProps.color }); this.setState({ color: nextProps.color });
} }
handleClick = () => { handleClick = () => {
this.setState({ displayColorPicker: !this.state.displayColorPicker }); const { displayColorPicker } = this.state;
this.setState({ displayColorPicker: !displayColorPicker });
}; };
handleClose = () => { handleClose = () => {
this.setState({ displayColorPicker: false }); this.setState({ displayColorPicker: false });
}; };
handleChange = (color) => { handleChange = (color) => {
const { onChange } = this.props;
this.setState({ color: color.hex }); this.setState({ color: color.hex });
this.props.onChange(color.hex, color); onChange(color.hex, color);
}; };
handleChangeComplete = (color) => { handleChangeComplete = (color) => {
const { onChangeComplete } = this.props;
this.setState({ color: color.hex }); this.setState({ color: color.hex });
this.props.onChangeComplete(color.hex); onChangeComplete(color.hex);
}; };
render() { render() {
const { small, type, position } = this.props; const { small, type, position } = this.props;
const { color, displayColorPicker } = this.state;
const Picker = pickers[type]; const Picker = pickers[type];
const styles = { const styles = {
color: { color: {
width: small ? '80px' : '120px', width: small ? '80px' : '120px',
height: small ? '16px' : '24px', height: small ? '16px' : '24px',
borderRadius: '2px', borderRadius: '2px',
background: this.state.color, background: color,
}, },
swatch: { swatch: {
padding: '4px', padding: '4px',
@ -86,13 +94,13 @@ export default class ColorPicker extends Component {
<div style={styles.color} /> <div style={styles.color} />
</div> </div>
); );
const picker = this.state.displayColorPicker ? ( const picker = displayColorPicker ? (
<div style={styles.popover}> <div style={styles.popover}>
<div style={styles.cover} onClick={this.handleClose} /> <div style={styles.cover} onClick={this.handleClose} />
<div style={styles.wrapper}> <div style={styles.wrapper}>
<Picker <Picker
{...this.props} {...this.props}
color={this.state.color} color={color}
onChange={this.handleChange} onChange={this.handleChange}
onChangeComplete={this.handleChangeComplete} onChangeComplete={this.handleChangeComplete}
/> />

View File

@ -26,10 +26,10 @@ export default class Palette extends React.Component {
}); });
this.forceUpdate(); this.forceUpdate();
} }
render() { render() {
this.colorNodes = this.colorNodes || {}; this.colorNodes = this.colorNodes || {};
const { showTitle, direction } = this.props; const { showTitle, direction, color: { name, description, english, chinese } } = this.props;
const { name, description, english, chinese } = this.props.color;
const className = direction === 'horizontal' ? 'color-palette-horizontal' : 'color-palette'; const className = direction === 'horizontal' ? 'color-palette-horizontal' : 'color-palette';
const colors = []; const colors = [];
const colorName = `${english} / ${chinese}`; const colorName = `${english} / ${chinese}`;

View File

@ -12,6 +12,7 @@ export default class Article extends React.Component {
static contextTypes = { static contextTypes = {
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
} }
componentDidMount() { componentDidMount() {
// Add ga event click // Add ga event click
this.delegation = delegate(this.node, '.resource-card', 'click', (e) => { this.delegation = delegate(this.node, '.resource-card', 'click', (e) => {
@ -21,6 +22,7 @@ export default class Article extends React.Component {
}, false); }, false);
this.componentDidUpdate(); this.componentDidUpdate();
} }
componentDidUpdate() { componentDidUpdate() {
const links = [...document.querySelectorAll('.outside-link.internal')]; const links = [...document.querySelectorAll('.outside-link.internal')];
if (links.length === 0) { if (links.length === 0) {
@ -34,12 +36,14 @@ export default class Article extends React.Component {
} }
}); });
} }
componentWillUnmount() { componentWillUnmount() {
clearTimeout(this.pingTimer); clearTimeout(this.pingTimer);
if (this.delegation) { if (this.delegation) {
this.delegation.destroy(); this.delegation.destroy();
} }
} }
getArticle(article) { getArticle(article) {
const { content } = this.props; const { content } = this.props;
const { meta } = content; const { meta } = content;
@ -64,13 +68,13 @@ export default class Article extends React.Component {
children: <Timeline>{timelineItems}</Timeline>, children: <Timeline>{timelineItems}</Timeline>,
}); });
} }
render() { render() {
const { props } = this; const { props } = this;
const { content } = props; const { content } = props;
const { meta, description } = content; const { meta, description } = content;
const { title, subtitle, filename } = meta; const { title, subtitle, filename } = meta;
const { locale } = this.context.intl; const { intl: { locale } } = this.context;
const isNotTranslated = locale === 'en-US' && typeof title === 'object'; const isNotTranslated = locale === 'en-US' && typeof title === 'object';
return ( return (
<DocumentTitle title={`${title[locale] || title} - Ant Design`}> <DocumentTitle title={`${title[locale] || title} - Ant Design`}>
@ -89,26 +93,29 @@ export default class Article extends React.Component {
<h1> <h1>
{title[locale] || title} {title[locale] || title}
{ {
!subtitle || locale === 'en-US' ? null : !subtitle || locale === 'en-US'
<span className="subtitle">{subtitle}</span> ? null
: <span className="subtitle">{subtitle}</span>
} }
<EditButton title={<FormattedMessage id="app.content.edit-page" />} filename={filename} /> <EditButton title={<FormattedMessage id="app.content.edit-page" />} filename={filename} />
</h1> </h1>
{ {
!description ? null : !description
props.utils.toReactComponent( ? null
: props.utils.toReactComponent(
['section', { className: 'markdown' }].concat(getChildren(description)) ['section', { className: 'markdown' }].concat(getChildren(description))
) )
} }
{ {
(!content.toc || content.toc.length <= 1 || meta.toc === false) ? null : (!content.toc || content.toc.length <= 1 || meta.toc === false) ? null : (
<Affix className="toc-affix" offsetTop={16}> <Affix className="toc-affix" offsetTop={16}>
{ {
props.utils.toReactComponent( props.utils.toReactComponent(
['ul', { className: 'toc' }].concat(getChildren(content.toc)) ['ul', { className: 'toc' }].concat(getChildren(content.toc))
) )
} }
</Affix> </Affix>
)
} }
{ {
this.getArticle(props.utils.toReactComponent( this.getArticle(props.utils.toReactComponent(

View File

@ -22,8 +22,9 @@ export default class ComponentDoc extends React.Component {
} }
handleExpandToggle = () => { handleExpandToggle = () => {
const { expandAll } = this.state;
this.setState({ this.setState({
expandAll: !this.state.expandAll, expandAll: !expandAll,
}); });
} }
@ -31,15 +32,15 @@ export default class ComponentDoc extends React.Component {
const { props } = this; const { props } = this;
const { doc, location } = props; const { doc, location } = props;
const { content, meta } = doc; const { content, meta } = doc;
const { locale } = this.context.intl; const { intl: { locale } } = this.context;
const demos = Object.keys(props.demos).map(key => props.demos[key]); const demos = Object.keys(props.demos).map(key => props.demos[key]);
const expand = this.state.expandAll; const { expandAll: { expand } } = this.state;
const isSingleCol = meta.cols === 1; const isSingleCol = meta.cols === 1;
const leftChildren = []; const leftChildren = [];
const rightChildren = []; const rightChildren = [];
const showedDemo = demos.some(demo => demo.meta.only) ? const showedDemo = demos.some(demo => demo.meta.only)
demos.filter(demo => demo.meta.only) : demos.filter(demo => demo.preview); ? demos.filter(demo => demo.meta.only) : demos.filter(demo => demo.preview);
showedDemo.sort((a, b) => a.meta.order - b.meta.order) showedDemo.sort((a, b) => a.meta.order - b.meta.order)
.forEach((demoData, index) => { .forEach((demoData, index) => {
const demoElem = ( const demoElem = (
@ -109,9 +110,10 @@ export default class ComponentDoc extends React.Component {
</section> </section>
<Row gutter={16}> <Row gutter={16}>
<Col span={isSingleCol ? '24' : '12'} <Col span={isSingleCol ? '24' : '12'}
className={isSingleCol ? className={
'code-boxes-col-1-1' : isSingleCol
'code-boxes-col-2-1' ? 'code-boxes-col-1-1'
: 'code-boxes-col-2-1'
} }
> >
{leftChildren} {leftChildren}

View File

@ -43,9 +43,11 @@ export default class Demo extends React.Component {
} }
shouldComponentUpdate(nextProps, nextState) { shouldComponentUpdate(nextProps, nextState) {
return (this.state.codeExpand || this.props.expand) !== (nextState.codeExpand || nextProps.expand) const { codeExpand, copied, copyTooltipVisible } = this.state;
|| this.state.copied !== nextState.copied const { expand } = this.props;
|| this.state.copyTooltipVisible !== nextState.copyTooltipVisible; return (codeExpand || expand) !== (nextState.codeExpand || nextProps.expand)
|| copied !== nextState.copied
|| copyTooltipVisible !== nextState.copyTooltipVisible;
} }
componentDidMount() { componentDidMount() {
@ -65,7 +67,8 @@ export default class Demo extends React.Component {
} }
handleCodeExpand = () => { handleCodeExpand = () => {
this.setState({ codeExpand: !this.state.codeExpand }); const { codeExpand } = this.state;
this.setState({ codeExpand: !codeExpand });
} }
saveAnchor = (anchor) => { saveAnchor = (anchor) => {
@ -102,6 +105,7 @@ export default class Demo extends React.Component {
highlightedStyle, highlightedStyle,
expand, expand,
} = props; } = props;
const { showRiddleButton, copied } = state;
if (!this.liveDemo) { if (!this.liveDemo) {
this.liveDemo = meta.iframe this.liveDemo = meta.iframe
? <BrowserFrame><iframe src={src} height={meta.iframe} title="demo" /></BrowserFrame> ? <BrowserFrame><iframe src={src} height={meta.iframe} title="demo" /></BrowserFrame>
@ -112,8 +116,7 @@ export default class Demo extends React.Component {
'code-box': true, 'code-box': true,
expand: codeExpand, expand: codeExpand,
}); });
const { intl: { locale } } = this.context;
const { locale } = this.context.intl;
const localizedTitle = meta.title[locale] || meta.title; const localizedTitle = meta.title[locale] || meta.title;
const localizeIntro = content[locale] || content; const localizeIntro = content[locale] || content;
const introChildren = props.utils const introChildren = props.utils
@ -186,9 +189,9 @@ ${state.sourceCode.replace('mountNode', 'document.getElementById(\'container\')'
<section className="code-box-demo"> <section className="code-box-demo">
{this.liveDemo} {this.liveDemo}
{ {
style ? style
<style dangerouslySetInnerHTML={{ __html: style }} /> : ? <style dangerouslySetInnerHTML={{ __html: style }} />
null : null
} }
</section> </section>
<section className="code-box-meta markdown"> <section className="code-box-meta markdown">
@ -222,7 +225,7 @@ ${state.sourceCode.replace('mountNode', 'document.getElementById(\'container\')'
> >
<div className="highlight"> <div className="highlight">
<div className="code-box-actions"> <div className="code-box-actions">
{this.state.showRiddleButton ? ( {showRiddleButton ? (
<form action="//riddle.alibaba-inc.com/riddles/define" method="POST" target="_blank"> <form action="//riddle.alibaba-inc.com/riddles/define" method="POST" target="_blank">
<input type="hidden" name="data" value={JSON.stringify(riddlePrefillConfig)} /> <input type="hidden" name="data" value={JSON.stringify(riddlePrefillConfig)} />
<Tooltip title={<FormattedMessage id="app.demo.riddle" />}> <Tooltip title={<FormattedMessage id="app.demo.riddle" />}>
@ -249,11 +252,11 @@ ${state.sourceCode.replace('mountNode', 'document.getElementById(\'container\')'
<Tooltip <Tooltip
visible={state.copyTooltipVisible} visible={state.copyTooltipVisible}
onVisibleChange={this.onCopyTooltipVisibleChange} onVisibleChange={this.onCopyTooltipVisibleChange}
title={ title={(
<FormattedMessage <FormattedMessage
id={`app.demo.${state.copied ? 'copied' : 'copy'}`} id={`app.demo.${copied ? 'copied' : 'copy'}`}
/> />
} )}
> >
<Icon <Icon
type={(state.copied && state.copyTooltipVisible) ? 'check' : 'copy'} type={(state.copied && state.copyTooltipVisible) ? 'check' : 'copy'}
@ -265,13 +268,14 @@ ${state.sourceCode.replace('mountNode', 'document.getElementById(\'container\')'
{props.utils.toReactComponent(highlightedCode)} {props.utils.toReactComponent(highlightedCode)}
</div> </div>
{ {
highlightedStyle ? highlightedStyle
<div key="style" className="highlight"> ? (
<pre> <div key="style" className="highlight">
<code className="css" dangerouslySetInnerHTML={{ __html: highlightedStyle }} /> <pre>
</pre> <code className="css" dangerouslySetInnerHTML={{ __html: highlightedStyle }} />
</div> : </pre>
null </div>
) : null
} }
</section> </section>
</section> </section>

View File

@ -12,18 +12,18 @@ const { SubMenu } = Menu;
function getActiveMenuItem(props) { function getActiveMenuItem(props) {
const { children } = props.params; const { children } = props.params;
return (children && children.replace('-cn', '')) || return (children && children.replace('-cn', ''))
props.location.pathname.replace(/(^\/|-cn$)/g, ''); || props.location.pathname.replace(/(^\/|-cn$)/g, '');
} }
function getModuleData(props) { function getModuleData(props) {
const { pathname } = props.location; const { pathname } = props.location;
const moduleName = /^\/?components/.test(pathname) ? const moduleName = /^\/?components/.test(pathname)
'components' : pathname.split('/').filter(item => item).slice(0, 2).join('/'); ? 'components' : pathname.split('/').filter(item => item).slice(0, 2).join('/');
const moduleData = moduleName === 'components' || moduleName === 'docs/react' || const moduleData = moduleName === 'components' || moduleName === 'docs/react'
moduleName === 'changelog' || moduleName === 'changelog-cn' ? || moduleName === 'changelog' || moduleName === 'changelog-cn'
[...props.picked.components, ...props.picked['docs/react'], ...props.picked.changelog] : ? [...props.picked.components, ...props.picked['docs/react'], ...props.picked.changelog]
props.picked[moduleName]; : props.picked[moduleName];
const excludedSuffix = utils.isZhCN(props.location.pathname) ? 'en-US.md' : 'zh-CN.md'; const excludedSuffix = utils.isZhCN(props.location.pathname) ? 'en-US.md' : 'zh-CN.md';
return moduleData.filter(({ meta }) => !meta.filename.endsWith(excludedSuffix)); return moduleData.filter(({ meta }) => !meta.filename.endsWith(excludedSuffix));
} }
@ -58,10 +58,11 @@ export default class MainContent extends React.Component {
} }
componentDidUpdate(prevProps) { componentDidUpdate(prevProps) {
if (!prevProps || prevProps.location.pathname !== this.props.location.pathname) { const { location } = this.props;
if (!prevProps || prevProps.location.pathname !== location.pathname) {
this.bindScroller(); this.bindScroller();
} }
if (!prevProps || (!window.location.hash && prevProps && prevProps.location.pathname !== this.props.location.pathname)) { if (!prevProps || (!window.location.hash && prevProps && prevProps.location.pathname !== location.pathname)) {
document.body.scrollTop = 0; document.body.scrollTop = 0;
document.documentElement.scrollTop = 0; document.documentElement.scrollTop = 0;
return; return;
@ -130,7 +131,7 @@ export default class MainContent extends React.Component {
} }
generateMenuItem(isTop, item) { generateMenuItem(isTop, item) {
const { locale } = this.context.intl; const { intl: { locale } } = this.context;
const key = fileNameToPath(item.filename); const key = fileNameToPath(item.filename);
const title = item.title[locale] || item.title; const title = item.title[locale] || item.title;
const text = isTop ? title : [ const text = isTop ? title : [
@ -165,10 +166,11 @@ export default class MainContent extends React.Component {
getMenuItems() { getMenuItems() {
const { themeConfig } = this.props; const { themeConfig } = this.props;
const { intl: { locale } } = this.context;
const moduleData = getModuleData(this.props); const moduleData = getModuleData(this.props);
const menuItems = utils.getMenuItems( const menuItems = utils.getMenuItems(
moduleData, moduleData,
this.context.intl.locale, locale,
themeConfig.categoryOrder, themeConfig.categoryOrder,
themeConfig.typeOrder, themeConfig.typeOrder,
); );
@ -221,6 +223,7 @@ export default class MainContent extends React.Component {
render() { render() {
const { props } = this; const { props } = this;
const { isMobile } = this.context; const { isMobile } = this.context;
const { openKeys } = this.state;
const activeMenuItem = getActiveMenuItem(props); const activeMenuItem = getActiveMenuItem(props);
const menuItems = this.getMenuItems(); const menuItems = this.getMenuItems();
const { prev, next } = this.getFooterNav(menuItems, activeMenuItem); const { prev, next } = this.getFooterNav(menuItems, activeMenuItem);
@ -233,7 +236,7 @@ export default class MainContent extends React.Component {
inlineIndent="40" inlineIndent="40"
className="aside-container menu-site" className="aside-container menu-site"
mode="inline" mode="inline"
openKeys={this.state.openKeys} openKeys={openKeys}
selectedKeys={[activeMenuItem]} selectedKeys={[activeMenuItem]}
onOpenChange={this.handleMenuOpenChange} onOpenChange={this.handleMenuOpenChange}
> >
@ -253,13 +256,12 @@ export default class MainContent extends React.Component {
<Col xxl={4} xl={5} lg={6} md={24} sm={24} xs={24} className="main-menu"> <Col xxl={4} xl={5} lg={6} md={24} sm={24} xs={24} className="main-menu">
{menuChild} {menuChild}
</Col> </Col>
) )}
}
<Col xxl={20} xl={19} lg={18} md={24} sm={24} xs={24} className={mainContainerClass}> <Col xxl={20} xl={19} lg={18} md={24} sm={24} xs={24} className={mainContainerClass}>
{ {
props.demos ? props.demos
<ComponentDoc {...props} doc={localizedPageData} demos={props.demos} /> : ? <ComponentDoc {...props} doc={localizedPageData} demos={props.demos} />
<Article {...props} content={localizedPageData} /> : <Article {...props} content={localizedPageData} />
} }
</Col> </Col>
</Row> </Row>
@ -275,14 +277,14 @@ export default class MainContent extends React.Component {
> >
<section className="prev-next-nav"> <section className="prev-next-nav">
{ {
prev ? prev
React.cloneElement(prev.props.children || prev.children[0], { className: 'prev-page' }) : ? React.cloneElement(prev.props.children || prev.children[0], { className: 'prev-page' })
null : null
} }
{ {
next ? next
React.cloneElement(next.props.children || next.children[0], { className: 'next-page' }) : ? React.cloneElement(next.props.children || next.children[0], { className: 'next-page' })
null : null
} }
</section> </section>
</Col> </Col>

View File

@ -9,16 +9,16 @@ function isChangelog(pathname) {
export default collect(async (nextProps) => { export default collect(async (nextProps) => {
const { pathname } = nextProps.location; const { pathname } = nextProps.location;
const pageDataPath = pathname.replace('-cn', '').split('/'); const pageDataPath = pathname.replace('-cn', '').split('/');
const pageData = isChangelog(pathname) ? const pageData = isChangelog(pathname)
nextProps.data.changelog.CHANGELOG : ? nextProps.data.changelog.CHANGELOG
nextProps.utils.get(nextProps.data, pageDataPath); : nextProps.utils.get(nextProps.data, pageDataPath);
if (!pageData) { if (!pageData) {
throw 404; // eslint-disable-line no-throw-literal throw 404; // eslint-disable-line no-throw-literal
} }
const locale = utils.isZhCN(pathname) ? 'zh-CN' : 'en-US'; const locale = utils.isZhCN(pathname) ? 'zh-CN' : 'en-US';
const pageDataPromise = typeof pageData === 'function' ? const pageDataPromise = typeof pageData === 'function'
pageData() : (pageData[locale] || pageData.index[locale] || pageData.index)(); ? pageData() : (pageData[locale] || pageData.index[locale] || pageData.index)();
const demosFetcher = nextProps.utils.get(nextProps.data, [...pageDataPath, 'demo']); const demosFetcher = nextProps.utils.get(nextProps.data, [...pageDataPath, 'demo']);
if (demosFetcher) { if (demosFetcher) {
const [localizedPageData, demos] = await Promise.all([pageDataPromise, demosFetcher()]); const [localizedPageData, demos] = await Promise.all([pageDataPromise, demosFetcher()]);

View File

@ -19,15 +19,18 @@ class Banner extends React.PureComponent {
static contextTypes = { static contextTypes = {
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
} }
static propTypes = { static propTypes = {
className: PropTypes.string, className: PropTypes.string,
} }
static defaultProps = { static defaultProps = {
className: 'banner', className: 'banner',
} }
render() { render() {
const { className, isMobile } = this.props; const { className, isMobile } = this.props;
const { locale } = this.context.intl; const { intl: { locale } } = this.context;
const isZhCN = locale === 'zh-CN'; const isZhCN = locale === 'zh-CN';
return ( return (
<div className="home-page-wrapper banner-wrapper" id="banner"> <div className="home-page-wrapper banner-wrapper" id="banner">

View File

@ -59,7 +59,7 @@ function TweenOneG(props) {
export default function BannerImage() { export default function BannerImage() {
return ( return (
<svg width="482px" height="500px" viewBox="0 0 482 500" > <svg width="482px" height="500px" viewBox="0 0 482 500">
<defs> <defs>
<path d="M151,55 C129.666667,62.6666667 116,74.3333333 110,90 C104,105.666667 103,118.5 107,128.5 L225.5,96 C219.833333,79 209.666667,67 195,60 C180.333333,53 165.666667,51.3333333 151,55 L137,0 L306.5,6.5 L306.5,156 L227,187.5 L61.5,191 C4.5,175 -12.6666667,147.833333 10,109.5 C32.6666667,71.1666667 75,34.6666667 137,0 L151,55 Z" id="mask" /> <path d="M151,55 C129.666667,62.6666667 116,74.3333333 110,90 C104,105.666667 103,118.5 107,128.5 L225.5,96 C219.833333,79 209.666667,67 195,60 C180.333333,53 165.666667,51.3333333 151,55 L137,0 L306.5,6.5 L306.5,156 L227,187.5 L61.5,191 C4.5,175 -12.6666667,147.833333 10,109.5 C32.6666667,71.1666667 75,34.6666667 137,0 L151,55 Z" id="mask" />
</defs> </defs>
@ -122,7 +122,7 @@ export default function BannerImage() {
</mask> </mask>
<g mask="url(#mask-2)"> <g mask="url(#mask-2)">
<TweenOneG animation={animate.track} style={{ transformOrigin: '122.7px 58px' }}> <TweenOneG animation={animate.track} style={{ transformOrigin: '122.7px 58px' }}>
<g transform="translate(-16, -52)" > <g transform="translate(-16, -52)">
<g transform="translate(16, 52)"> <g transform="translate(16, 52)">
<path d="M83.1700911,35.9320015 C63.5256194,37.9279025 44.419492,43.1766434 25.8517088,51.6782243 C14.3939956,57.7126276 7.77167019,64.8449292 7.77167019,72.4866248 C7.77167019,94.1920145 61.1993389,111.787709 127.105708,111.787709 C193.012078,111.787709 246.439746,94.1920145 246.439746,72.4866248 C246.439746,55.2822262 212.872939,40.6598106 166.13127,35.3351955" id="line-s" stroke="#0D1A26" strokeWidth="1.35" strokeLinecap="round" transform="translate(127.105708, 73.561453) rotate(-16.000000) translate(-127.105708, -73.561453) " /> <path d="M83.1700911,35.9320015 C63.5256194,37.9279025 44.419492,43.1766434 25.8517088,51.6782243 C14.3939956,57.7126276 7.77167019,64.8449292 7.77167019,72.4866248 C7.77167019,94.1920145 61.1993389,111.787709 127.105708,111.787709 C193.012078,111.787709 246.439746,94.1920145 246.439746,72.4866248 C246.439746,55.2822262 212.872939,40.6598106 166.13127,35.3351955" id="line-s" stroke="#0D1A26" strokeWidth="1.35" strokeLinecap="round" transform="translate(127.105708, 73.561453) rotate(-16.000000) translate(-127.105708, -73.561453) " />
</g> </g>
@ -134,6 +134,6 @@ export default function BannerImage() {
</g> </g>
</g> </g>
</g> </g>
</svg > </svg>
); );
} }

View File

@ -124,16 +124,19 @@ export default class Page1 extends React.PureComponent {
state = { state = {
hoverKey: null, hoverKey: null,
} }
onMouseOver = (key) => { onMouseOver = (key) => {
this.setState({ this.setState({
hoverKey: key, hoverKey: key,
}); });
} }
onMouseOut = () => { onMouseOut = () => {
this.setState({ this.setState({
hoverKey: null, hoverKey: null,
}); });
} }
getEnter = (i, e) => { getEnter = (i, e) => {
const ii = e.index; const ii = e.index;
const r = (Math.random() * 2) - 1; const r = (Math.random() * 2) - 1;
@ -153,6 +156,7 @@ export default class Page1 extends React.PureComponent {
}, },
]; ];
}; };
getSvgChild = child => child.map((item, i) => { getSvgChild = child => child.map((item, i) => {
const props = { ...item.props }; const props = { ...item.props };
if (item.type === 'g') { if (item.type === 'g') {
@ -165,18 +169,22 @@ export default class Page1 extends React.PureComponent {
}); });
} }
return ( return (
<g key={i.toString()} > <g key={i.toString()}>
{React.cloneElement(item, props)} {React.cloneElement(item, props)}
</g> </g>
); );
}); });
leave = { leave = {
opacity: 0, duration: 300, x: 100, y: 150, ease: 'easeInBack', opacity: 0, duration: 300, x: 100, y: 150, ease: 'easeInBack',
}; };
render() { render() {
const isZhCN = this.props.locale === 'zh-CN'; const { locale, isMobile } = this.props;
const { hoverKey } = this.state;
const isZhCN = locale === 'zh-CN';
const children = page1Data.map((item, i) => { const children = page1Data.map((item, i) => {
const isHover = item.nameEn === this.state.hoverKey; const isHover = item.nameEn === hoverKey;
return ( return (
<Col key={item.nameEn} md={6} xs={24}> <Col key={item.nameEn} md={6} xs={24}>
<TweenOneGroup <TweenOneGroup
@ -187,7 +195,7 @@ export default class Page1 extends React.PureComponent {
component="svg" component="svg"
resetStyleBool={false} resetStyleBool={false}
> >
{(this.props.isMobile || isHover) && this.getSvgChild(item.svgBg.props.children)} {(isMobile || isHover) && this.getSvgChild(item.svgBg.props.children)}
</TweenOneGroup> </TweenOneGroup>
<QueueAnim <QueueAnim
className="page1-block" className="page1-block"
@ -200,14 +208,14 @@ export default class Page1 extends React.PureComponent {
<div className="page1-image"> <div className="page1-image">
<img src={item.img} alt="icon" /> <img src={item.img} alt="icon" />
</div> </div>
<h3 >{isZhCN ? item.name : item.nameEn}</h3> <h3>{isZhCN ? item.name : item.nameEn}</h3>
</QueueAnim> </QueueAnim>
</Col> </Col>
); );
}); });
return ( return (
<div className="home-page-wrapper page1"> <div className="home-page-wrapper page1">
<div className="page" > <div className="page">
<h2><FormattedMessage id="app.home.design-language" /></h2> <h2><FormattedMessage id="app.home.design-language" /></h2>
<ScrollOverPack playScale="0.3"> <ScrollOverPack playScale="0.3">
<QueueAnim <QueueAnim

View File

@ -35,7 +35,7 @@ const page2Data = [
const svgBgChild = [ const svgBgChild = [
( (
<svg width="100%" height="100%" viewBox="0 0 1401 1109" stroke="none" strokeWidth="1" fill="none" fillRule="evenodd" preserveAspectRatio="xMidYMid slice" > <svg width="100%" height="100%" viewBox="0 0 1401 1109" stroke="none" strokeWidth="1" fill="none" fillRule="evenodd" preserveAspectRatio="xMidYMid slice">
<g transform="translate(-79.000000, -21.000000)"> <g transform="translate(-79.000000, -21.000000)">
<circle id="Oval-13" stroke="none" fill="#EBEDF0" fillRule="evenodd" cx="98.5" cy="98.5" r="98.5" /> <circle id="Oval-13" stroke="none" fill="#EBEDF0" fillRule="evenodd" cx="98.5" cy="98.5" r="98.5" />
<rect id="Rectangle-33" stroke="none" fill="#EBEDF0" fillRule="evenodd" transform="translate(1261.132034, 1217.132034) rotate(45.000000) translate(-1261.132034, -1217.132034) " x="1111.13203" y="1007.13203" width="300" height="300" rx="1" /> <rect id="Rectangle-33" stroke="none" fill="#EBEDF0" fillRule="evenodd" transform="translate(1261.132034, 1217.132034) rotate(45.000000) translate(-1261.132034, -1217.132034) " x="1111.13203" y="1007.13203" width="300" height="300" rx="1" />
@ -66,8 +66,8 @@ const svgBgChild = [
]; ];
const svgBgChildArray = svgBgChild.map((item, i) => { const svgBgChildArray = svgBgChild.map((item, i) => {
const { props } = item; const { props: { children } } = item;
return React.cloneElement(item, { children: svgBgToParallax(props.children, i) }); return React.cloneElement(item, { children: svgBgToParallax(children, i) });
}); });
export default function Page2({ isMobile, locale }) { export default function Page2({ isMobile, locale }) {
const isZhCN = locale === 'zh-CN'; const isZhCN = locale === 'zh-CN';
@ -109,7 +109,7 @@ export default function Page2({ isMobile, locale }) {
}); });
return ( return (
<div className="home-page-wrapper page2" id="page2"> <div className="home-page-wrapper page2" id="page2">
<div className="page" > <div className="page">
<h2><FormattedMessage id="app.home.solution" /></h2> <h2><FormattedMessage id="app.home.solution" /></h2>
<ScrollOverPack component={Row} className="page2-content" playScale="0.4"> <ScrollOverPack component={Row} className="page2-content" playScale="0.4">
<QueueAnim <QueueAnim
@ -136,10 +136,10 @@ export default function Page2({ isMobile, locale }) {
</QueueAnim> </QueueAnim>
</ScrollOverPack> </ScrollOverPack>
</div> </div>
<div className="parallax-bg bottom" > <div className="parallax-bg bottom">
{svgBgChildArray[0]} {svgBgChildArray[0]}
</div> </div>
<div className="parallax-bg top" > <div className="parallax-bg top">
{svgBgChildArray[1]} {svgBgChildArray[1]}
</div> </div>
</div> </div>

View File

@ -63,19 +63,19 @@ export default function Page3({ locale }) {
<a href={item.link} target="_black"> <a href={item.link} target="_black">
{child} {child}
</a> </a>
) )
} }
</Col> </Col>
); );
}); });
return ( return (
<div className="home-page-wrapper page3" id="page3"> <div className="home-page-wrapper page3" id="page3">
<div className="parallax-bg top" > <div className="parallax-bg top">
<svg width="1440px" height="557px" viewBox="0 0 1440 557" stroke="none" strokeWidth="1" fill="none" fillRule="evenodd" > <svg width="1440px" height="557px" viewBox="0 0 1440 557" stroke="none" strokeWidth="1" fill="none" fillRule="evenodd">
{svgChildren} {svgChildren}
</svg> </svg>
</div> </div>
<div className="page" > <div className="page">
<h2><FormattedMessage id="app.home.tool-title" /></h2> <h2><FormattedMessage id="app.home.tool-title" /></h2>
<ScrollOverPack location="page3"> <ScrollOverPack location="page3">
<QueueAnim key="queue" component={Row} type="bottom" leaveReverse> <QueueAnim key="queue" component={Row} type="bottom" leaveReverse>

View File

@ -61,11 +61,12 @@ class Home extends React.Component {
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
isMobile: PropTypes.bool.isRequired, isMobile: PropTypes.bool.isRequired,
} }
render() { render() {
const { isMobile, intl } = this.context; const { isMobile, intl } = this.context;
const childProps = { ...this.props, isMobile, locale: intl.locale }; const childProps = { ...this.props, isMobile, locale: intl.locale };
return ( return (
<DocumentTitle title={`Ant Design - ${this.props.intl.formatMessage({ id: 'app.home.slogan' })}`}> <DocumentTitle title={`Ant Design - ${intl.formatMessage({ id: 'app.home.slogan' })}`}>
<div className="main-wrapper"> <div className="main-wrapper">
<Banner {...childProps} /> <Banner {...childProps} />
<Page1 {...childProps} /> <Page1 {...childProps} />

View File

@ -6,6 +6,7 @@ export default class CopyableIcon extends React.Component {
state = { state = {
justCopied: false, justCopied: false,
}; };
onCopied = () => { onCopied = () => {
this.setState({ justCopied: true }, () => { this.setState({ justCopied: true }, () => {
setTimeout(() => { setTimeout(() => {
@ -13,12 +14,14 @@ export default class CopyableIcon extends React.Component {
}, 2000); }, 2000);
}); });
} }
render() { render() {
const { type, isNew } = this.props; const { type, isNew } = this.props;
const { justCopied } = this.state;
const text = `<Icon type="${type}" />`; const text = `<Icon type="${type}" />`;
return ( return (
<CopyToClipboard text={text} onCopy={this.onCopied}> <CopyToClipboard text={text} onCopy={this.onCopied}>
<li className={this.state.justCopied ? 'copied' : ''}> <li className={justCopied ? 'copied' : ''}>
<Icon type={type} /> <Icon type={type} />
<span className="anticon-class"> <span className="anticon-class">
<Badge dot={isNew}> <Badge dot={isNew}>

View File

@ -25,8 +25,8 @@ class Footer extends React.Component {
// 1. // 1.
// 2. // 2.
if ( if (
localStorage.getItem('antd@3.0.0-notification-sent') !== 'true' && localStorage.getItem('antd@3.0.0-notification-sent') !== 'true'
Date.now() < new Date('2017/12/20').getTime() && Date.now() < new Date('2017/12/20').getTime()
) { ) {
this.infoNewVersion(); this.infoNewVersion();
} }
@ -34,7 +34,7 @@ class Footer extends React.Component {
handleColorChange = (color) => { handleColorChange = (color) => {
const changeColor = () => { const changeColor = () => {
const { messages } = this.props.intl; const { intl: { messages } } = this.props;
window.less.modifyVars({ window.less.modifyVars({
'@primary-color': color, '@primary-color': color,
}).then(() => { }).then(() => {
@ -59,7 +59,7 @@ class Footer extends React.Component {
} }
infoNewVersion() { infoNewVersion() {
const { messages } = this.props.intl; const { intl: { messages } } = this.props;
Modal.info({ Modal.info({
title: messages['app.publish.title'], title: messages['app.publish.title'],
content: ( content: (
@ -83,6 +83,7 @@ class Footer extends React.Component {
} }
render() { render() {
const { color } = this.state;
return ( return (
<footer id="footer"> <footer id="footer">
<div className="footer-wrap"> <div className="footer-wrap">
@ -262,7 +263,7 @@ class Footer extends React.Component {
<ColorPicker <ColorPicker
type="sketch" type="sketch"
small small
color={this.state.color} color={color}
position="top" position="top"
presetColors={[ presetColors={[
'#F5222D', '#F5222D',

View File

@ -84,7 +84,7 @@ export default class Header extends React.Component {
} }
handleLangChange = () => { handleLangChange = () => {
const { pathname } = this.props.location; const { location: { pathname } } = this.props;
const currentProtocol = `${window.location.protocol}//`; const currentProtocol = `${window.location.protocol}//`;
const currentHref = window.location.href.substr(currentProtocol.length); const currentHref = window.location.href.substr(currentProtocol.length);
@ -113,7 +113,7 @@ export default class Header extends React.Component {
if (activeMenuItem === 'components' || location.pathname === 'changelog') { if (activeMenuItem === 'components' || location.pathname === 'changelog') {
activeMenuItem = 'docs/react'; activeMenuItem = 'docs/react';
} }
const { locale } = this.context.intl; const { intl: { locale } } = this.context;
const isZhCN = locale === 'zh-CN'; const isZhCN = locale === 'zh-CN';
const headerClassName = classNames({ const headerClassName = classNames({

Some files were not shown because too many files have changed in this diff Show More