Merge from "master"

This commit is contained in:
afc163 2017-02-26 18:45:16 +08:00
commit 376806dab8
169 changed files with 2103 additions and 2670 deletions

View File

@ -36,7 +36,6 @@ const eslintrc = {
'consistent-return': 0, 'consistent-return': 0,
'no-redeclare': 0, 'no-redeclare': 0,
'react/require-extension': 0, 'react/require-extension': 0,
'react/jsx-indent': 0,
'jsx-a11y/no-static-element-interactions': 0, 'jsx-a11y/no-static-element-interactions': 0,
'jsx-a11y/anchor-has-content': 0, 'jsx-a11y/anchor-has-content': 0,
'react/no-danger': 0, 'react/no-danger': 0,
@ -57,7 +56,6 @@ if (process.env.RUN_ENV === 'DEMO') {
'eol-last': 0, 'eol-last': 0,
'prefer-rest-params': 0, 'prefer-rest-params': 0,
'react/no-multi-comp': 0, 'react/no-multi-comp': 0,
'react/prefer-es6-class': 0,
'jsx-a11y/href-no-hash': 0, 'jsx-a11y/href-no-hash': 0,
'import/newline-after-import': 0, 'import/newline-after-import': 0,
}); });

View File

@ -1,12 +1,12 @@
<!-- Issue Template --> <!-- Issue Template -->
<!-- <!--
antd 的用法咨询,建议通过以下渠道,官方 issues 目前没有足够精力提供此类咨询服务 亲爱的中文用户请注意
1. [Stack Overflow](http://stackoverflow.com/questions/tagged/antd) 1. 官方 issue 用于报告 bug 和讨论需求。用法咨询类问题建议到 https://segmentfault.com/t/antd 上提问,目前社区没有足够精力提供此类服务,感谢您的理解。
2. [Segment Fault](https://segmentfault.com/t/antd)(中文) 2. 建议使用英文进行提问,这样你的问题可以被更多的人阅读和回答。如果表达上较复杂,英文标题加中文描述也是可选的方案。
3. 报告 BUG 时请务必按照下列格式书写并尽可能提供源代码、复现步骤、复现演示、GIF 演示等。我们和你一样都希望尽快解决问题,请不要浪费时间在互相追问上。
如果是报告 bug请按照下列格式书写并务必提供复现步骤否则恕难解决感谢您的支持。 4. 如果需要粘贴源码,尽量避免截图并注意代码格式。关于如何在 Markdown 中书写代码可以参考https://segmentfault.com/markdown
--> -->
#### Environment(required) #### Environment(required)

View File

@ -498,9 +498,11 @@ timeline: true
> 建议从 `1.x` 升级时,直接升级到 `2.x` 的最新版本。 > 建议从 `1.x` 升级时,直接升级到 `2.x` 的最新版本。
此版本有部分不兼容的改动,升级时确保修改相应的使用代码。 > 建议在升级 antd 的过程中,每做完一次合理的修改并 review 和测试之后,就 git commit 一次,这样在误操作时能随时回滚到之前的版本
* 时间类组件的 `value``defaultValue` 不再支持 `String/Date` 类型,请使用 [moment](http://momentjs.com/)。 此版本有部分不兼容的改动,升级时确保修改相应的使用代码。另外由于人肉查找代码中的废弃用法过于低效,所以我们提供了 [antd-migration-helper](https://github.com/ant-design/antd-migration-helper) 用于扫描代码中的废弃用法。
* 时间类组件的 `value``defaultValue` 不再支持 `String/Date` 类型,请使用 [moment](http://momentjs.com/)。需要对代码进行如下修改,可人手修改也可用我们提供的 [codemod](https://github.com/ant-design/antd-codemod#time-related-value-to-moment) 脚本自动修改类似用法,但注意脚本不能覆盖所有情况,所以在运行脚本后仍然需要 review 和测试。
```diff ```diff
- <TimePicker defaultValue="12:08:23" /> - <TimePicker defaultValue="12:08:23" />
+ <TimePicker defaultValue={moment('12:08:23', 'HH:mm:ss')} /> + <TimePicker defaultValue={moment('12:08:23', 'HH:mm:ss')} />
@ -511,9 +513,16 @@ timeline: true
- <Calendar defaultValue={new Date('2010-10-10')} /> - <Calendar defaultValue={new Date('2010-10-10')} />
+ <Calendar defaultValue={moment('2010-10-10', 'YYYY-MM-DD')} /> + <Calendar defaultValue={moment('2010-10-10', 'YYYY-MM-DD')} />
``` ```
* 时间类组件的 `onChange``onPanelChange` 及其他回调函数中为 `Date/GregorianCalendar` 类型的参数,均修改为 moment 类型,两者 API 有所不同,但功能基本一致,请对照 [moment 的 API 文档](http://momentjs.com/docs/) 和 [gregorian-calendar 的文档](https://github.com/yiminghe/gregorian-calendar) 进行修改。你也可以参考这个 [commit](https://github.com/ant-design/ant-design/commit/4026221d451b246956983bb42140142d4a48b7d7) 来进行修改。 * 时间类组件的 `onChange``onPanelChange` 及其他回调函数中为 `Date/GregorianCalendar` 类型的参数,均修改为 moment 类型,两者 API 有所不同,但功能基本一致,请对照 [moment 的 API 文档](http://momentjs.com/docs/) 和 [gregorian-calendar 的文档](https://github.com/yiminghe/gregorian-calendar) 进行修改。
1. 也可以参考这个 [commit](https://github.com/ant-design/ant-design/commit/4026221d451b246956983bb42140142d4a48b7d7) 来进行修改。
由于 `JSON.stringify(date: moment)` 返回的值会丢失时区设置,所以要先使用 `.format` 把日期转成字符串,相关 issue 见 [#3082](https://github.com/ant-design/ant-design/issues/3082) 1. 也可用我们提供的 [codemod](https://github.com/ant-design/antd-codemod#gergoriancalendar-to-moment) 脚本自动修改类似用法,但注意脚本不能覆盖所有情况,所以在运行脚本后仍然需要 review 和测试。
```diff
function disabledDate(date) {
- console.log(date.getTime());
+ console.log(date.valueOf());
}
```
* 由于 `JSON.stringify(date: moment)` 返回的值会丢失时区设置,所以在提交前要先使用 `.format` 把日期转成字符串,相关 issue 见 [#3082](https://github.com/ant-design/ant-design/issues/3082)
```js ```js
handleSubmit() { handleSubmit() {
const values = this.props.form.getFieldsValue(); const values = this.props.form.getFieldsValue();
@ -522,9 +531,17 @@ timeline: true
// 发送 data 到服务器 // 发送 data 到服务器
} }
``` ```
* 时间类组件与表单校验一起使用时,`type: 'date'` 改为 `type: 'object'` * 时间类组件与表单校验一起使用时,`type: 'date'` 改为 `type: 'object'`
* 时间类组件的 `format` 属性也发生了变化,从 [gregorian-calendar-format 的格式](https://github.com/yiminghe/gregorian-calendar-format#api) 变化为与 [moment 的格式](http://momentjs.com/docs/#/parsing/string-format/),例如原来的 `yyyy-MM-dd` 将变为 `YYYY-MM-DD` ```diff
getFieldDecorator('time', {
rules: [{
required: true,
- type: 'date',
+ type: 'object',
}],
})(...)
```
* 时间类组件的 `format` 属性也发生了变化,从 [gregorian-calendar-format 的格式](https://github.com/yiminghe/gregorian-calendar-format#api) 变化为与 [moment 的格式](http://momentjs.com/docs/#/parsing/string-format/),例如原来的 `yyyy-MM-dd` 将变为 `YYYY-MM-DD`。可人手修改也可用我们提供的 [codemod](https://github.com/ant-design/antd-codemod#time-related-value-to-moment) 脚本自动修改类似用法,但注意脚本不能覆盖所有情况,所以在运行脚本后仍然需要 review 和测试。
* Breadcrumb 移除 `linkRender``nameRender`,请使用 `itemRender` * Breadcrumb 移除 `linkRender``nameRender`,请使用 `itemRender`
* Menu 移除 `onClose` `onOpen`,请使用 `onOpenChange`。API 差异较大,请先研究 [demo](http://beta.ant.design/components/menu/#components-menu-demo-sider-current)。 * Menu 移除 `onClose` `onOpen`,请使用 `onOpenChange`。API 差异较大,请先研究 [demo](http://beta.ant.design/components/menu/#components-menu-demo-sider-current)。
* Table 移除列分页功能,请使用 [固定列](http://ant.design/components/table/#components-table-demo-fixed-columns)。 * Table 移除列分页功能,请使用 [固定列](http://ant.design/components/table/#components-table-demo-fixed-columns)。
@ -532,7 +549,7 @@ timeline: true
以下变化升级后旧代码仍然能正常运行,但是控制台会出现警告提示,建议按提示进行修改。 以下变化升级后旧代码仍然能正常运行,但是控制台会出现警告提示,建议按提示进行修改。
* Form 废弃 `getFieldProps`,请使用 `getFieldDecorator` * Form 废弃 `getFieldProps`,请使用 `getFieldDecorator`。可人手修改也可用我们提供的 [codemod](https://github.com/ant-design/antd-codemod#getfieldprops-to-getfielddecorator) 脚本自动修改类似用法,但注意脚本不能覆盖所有情况,所以在运行脚本后仍然需要 review 和测试。
```diff ```diff
- <Input placeholder="text" {...getFieldProps('userName', { ... })} /> - <Input placeholder="text" {...getFieldProps('userName', { ... })} />
@ -552,6 +569,8 @@ timeline: true
} }
``` ```
最后,由于时间类组件修改比较复杂,可能还需要深入业务逻辑,所以在项目比较赶的情况下,可以考虑使用 [antd-adapter](https://github.com/ant-design/antd-adapter) 适配为 `antd@1.x` 里面的用法,但不建议。
### 2.x Bug 修复 ### 2.x Bug 修复
* 修复 Dropdown.Button `disabled` 属性无效的问题。[#3070](https://github.com/ant-design/ant-design/issues/3070) * 修复 Dropdown.Button `disabled` 属性无效的问题。[#3070](https://github.com/ant-design/ant-design/issues/3070)

View File

@ -28,7 +28,7 @@ An enterprise-class UI design language and React-based implementation.
## Let's build a better antd together [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) ## Let's build a better antd together [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)
`antd` is an open source project, improvements are welcomed. If you are interested in contributing to `antd`, you can watch this repository, join in [discussion](https://github.com/ant-design/ant-design/issues?q=is%3Aopen+is%3Aissue+label%3ADiscussion), or try to implement some [features which have been accepted](https://github.com/ant-design/ant-design/issues?q=is%3Aopen+is%3Aissue+label%3A%22PR+welcome%22). `antd` is an open source project, improvements are welcomed. If you are interested in contributing to `antd`, you can watch this repository, join in [discussion](https://github.com/ant-design/ant-design/issues?q=is%3Aopen+is%3Aissue+label%3ADiscussion), or try to implement some [features which have been accepted](https://github.com/ant-design/ant-design/issues?q=is%3Aopen+is%3Aissue+label%3A%22PR+welcome%22). Actually, there are [many ways](https://opensource.guide/how-to-contribute/) to contribute.
## Install ## Install

View File

@ -1,4 +1,5 @@
import cssAnimation from 'css-animation'; import cssAnimation from 'css-animation';
import getRequestAnimationFrame from './getRequestAnimationFrame';
function animate(node, show, done) { function animate(node, show, done) {
let height; let height;
@ -6,16 +7,22 @@ function animate(node, show, done) {
start() { start() {
if (!show) { if (!show) {
node.style.height = `${node.offsetHeight}px`; node.style.height = `${node.offsetHeight}px`;
node.style.opacity = 1;
} else { } else {
height = node.offsetHeight; height = node.offsetHeight;
node.style.height = 0; node.style.height = 0;
node.style.opacity = 0;
} }
}, },
active() { active() {
node.style.height = `${show ? height : 0}px`; getRequestAnimationFrame()(() => {
node.style.height = `${show ? height : 0}px`;
node.style.opacity = show ? 1 : 0;
});
}, },
end() { end() {
node.style.height = ''; node.style.height = '';
node.style.opacity = '';
done(); done();
}, },
}); });

View File

@ -29,6 +29,8 @@ function getOffset(element: HTMLElement, target) {
scrollTop - clientTop, scrollTop - clientTop,
left: elemRect.left - targetRect.left + left: elemRect.left - targetRect.left +
scrollLeft - clientLeft, scrollLeft - clientLeft,
width: elemRect.width,
height: elemRect.height,
}; };
} }
@ -138,14 +140,15 @@ export default class Affix extends React.Component<AffixProps, any> {
(targetNode as Window).innerHeight || (targetNode as HTMLElement).clientHeight; (targetNode as Window).innerHeight || (targetNode as HTMLElement).clientHeight;
if (scrollTop > elemOffset.top - offsetTop && offsetMode.top) { if (scrollTop > elemOffset.top - offsetTop && offsetMode.top) {
// Fixed Top // Fixed Top
const width = elemOffset.width;
this.setAffixStyle(e, { this.setAffixStyle(e, {
position: 'fixed', position: 'fixed',
top: targetRect.top + offsetTop, top: targetRect.top + offsetTop,
left: targetRect.left + elemOffset.left, left: targetRect.left + elemOffset.left,
width: affixNode.offsetWidth, width,
}); });
this.setPlaceholderStyle({ this.setPlaceholderStyle({
width: affixNode.offsetWidth, width,
height: affixNode.offsetHeight, height: affixNode.offsetHeight,
}); });
} else if ( } else if (
@ -154,14 +157,15 @@ export default class Affix extends React.Component<AffixProps, any> {
) { ) {
// Fixed Bottom // Fixed Bottom
const targetBottomOffet = targetNode === window ? 0 : (window.innerHeight - targetRect.bottom); const targetBottomOffet = targetNode === window ? 0 : (window.innerHeight - targetRect.bottom);
const width = elemOffset.width;
this.setAffixStyle(e, { this.setAffixStyle(e, {
position: 'fixed', position: 'fixed',
bottom: targetBottomOffet + offsetBottom, bottom: targetBottomOffet + offsetBottom,
left: targetRect.left + elemOffset.left, left: targetRect.left + elemOffset.left,
width: affixNode.offsetWidth, width,
}); });
this.setPlaceholderStyle({ this.setPlaceholderStyle({
width: affixNode.offsetWidth, width,
height: affixNode.offsetHeight, height: affixNode.offsetHeight,
}); });
} else { } else {
@ -222,7 +226,7 @@ export default class Affix extends React.Component<AffixProps, any> {
[this.props.prefixCls || 'ant-affix']: this.state.affixStyle, [this.props.prefixCls || 'ant-affix']: this.state.affixStyle,
}); });
const props = omit(this.props, ['prefixCls', 'offsetTop', 'offsetBottom', 'target']); const props = omit(this.props, ['prefixCls', 'offsetTop', 'offsetBottom', 'target', 'onChange']);
const placeholderStyle = { ...this.state.placeholderStyle, ...this.props.style }; const placeholderStyle = { ...this.state.placeholderStyle, ...this.props.style };
return ( return (
<div {...props} style={placeholderStyle}> <div {...props} style={placeholderStyle}>

View File

@ -128,11 +128,12 @@ ReactDOM.render(<Complete />, mountNode);
} }
.global-search.ant-select-auto-complete .ant-input-preSuffix-wrapper .ant-input-suffix { .global-search.ant-select-auto-complete .ant-input-preSuffix-wrapper .ant-input-suffix {
right: 1px; right: 0;
} }
.global-search.ant-select-auto-complete .ant-input-preSuffix-wrapper .ant-input-suffix button { .global-search.ant-select-auto-complete .ant-input-preSuffix-wrapper .ant-input-suffix button {
border-radius: 3px; padding-top: 5px;
padding-bottom: 6px;
border-top-left-radius: 0; border-top-left-radius: 0;
border-bottom-left-radius: 0; border-bottom-left-radius: 0;
} }

View File

@ -27,7 +27,8 @@ const dataSource = ['12345', '23456', '34567'];
| onChange | Called when select an option or input value change, or value of input is changed | function(value, label) | - | | onChange | Called when select an option or input value change, or value of input is changed | function(value, label) | - |
| 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) | - |
| disabled | Whether disabled select | boolean | false | | disabled | Whether disabled select | boolean | false |
| defaultActiveFirstOption | Whether active first option by default | boolean | true |
| placeholder | placeholder of input | string | - | | placeholder | placeholder of input | string | - |
| children (for dataSource) | Data source for autocomplet | React.ReactElement<OptionProps> / Array<React.ReactElement<OptionProps>> | - | | children (for dataSource) | Data source for autocomplet | React.ReactElement<OptionProps> / Array<React.ReactElement<OptionProps>> | - |
| children (for customize input element) | customize input element | HTMLInputElement / HTMLTextAreaElement / React.ReactElement<InputProps> | `<Input />` | | children (for customize input element) | customize input element | HTMLInputElement / HTMLTextAreaElement / React.ReactElement<InputProps> | `<Input />` |
| filterOption | If true, filter options by input, if function, filter options against it. The function will receive two arguments, `inputValue` and `option`, if the function returns `true`, the option will be included in the filtered set; Otherwise, it will be excluded. | boolean or function(inputValue, option) | true | | filterOption | If true, filter options by input, if function, filter options against it. The function will receive two arguments, `inputValue` and `option`, if the function returns `true`, the option will be included in the filtered set; Otherwise, it will be excluded. | boolean or function(inputValue, option) | true |

View File

@ -28,6 +28,7 @@ const dataSource = ['12345', '23456', '34567'];
| onChange | 选中 option或 input 的 value 变化时,调用此函数 | function(value) | 无 | | onChange | 选中 option或 input 的 value 变化时,调用此函数 | function(value) | 无 |
| onSelect | 被选中时调用,参数为选中项的 value 值 | function(value, option) | 无 | | onSelect | 被选中时调用,参数为选中项的 value 值 | function(value, option) | 无 |
| disabled | 是否禁用 | boolean | false | | disabled | 是否禁用 | boolean | false |
| defaultActiveFirstOption | 是否默认高亮第一个选项。 | boolean | true
| placeholder | 输入框提示 | string | - | | placeholder | 输入框提示 | string | - |
| children (自动完成的数据源) | 自动完成的数据源 | React.ReactElement<OptionProps> / Array<React.ReactElement<OptionProps>> | - | | children (自动完成的数据源) | 自动完成的数据源 | React.ReactElement<OptionProps> / Array<React.ReactElement<OptionProps>> | - |
| children (自定义输入框) | 自定义输入框 | HTMLInputElement / HTMLTextAreaElement / React.ReactElement<InputProps> | `<Input />` | | children (自定义输入框) | 自定义输入框 | HTMLInputElement / HTMLTextAreaElement / React.ReactElement<InputProps> | `<Input />` |

View File

@ -88,8 +88,11 @@ export default class Breadcrumb extends React.Component<BreadcrumbProps, any> {
}); });
} else if (children) { } else if (children) {
crumbs = React.Children.map(children, (element: any, index) => { crumbs = React.Children.map(children, (element: any, index) => {
if (!element) {
return element;
}
warning( warning(
element && element.type.__ANT_BREADCRUMB_ITEM, element.type && element.type.__ANT_BREADCRUMB_ITEM,
'Breadcrumb only accetps Breadcrumb.Item as it\'s children' 'Breadcrumb only accetps Breadcrumb.Item as it\'s children'
); );
return cloneElement(element, { return cloneElement(element, {

View File

@ -1,6 +1,7 @@
import React from 'react'; import React from 'react';
import { mount } from 'enzyme'; import { mount, render } from 'enzyme';
import Breadcrumb from '../Breadcrumb'; import { renderToJson } from 'enzyme-to-json';
import Breadcrumb from '../index';
describe('Breadcrumb', () => { describe('Breadcrumb', () => {
it('warns on non-Breadcrumb.Item children', () => { it('warns on non-Breadcrumb.Item children', () => {
@ -18,4 +19,18 @@ describe('Breadcrumb', () => {
'Breadcrumb only accetps Breadcrumb.Item as it\'s children' 'Breadcrumb only accetps Breadcrumb.Item as it\'s children'
); );
}); });
// https://github.com/ant-design/ant-design/issues/5015
it('should allow Breadcrumb.Item is null or undefined', () => {
const wrapper = render(
<Breadcrumb>
{null}
<Breadcrumb.Item>Home</Breadcrumb.Item>
{undefined}
</Breadcrumb>
);
// eslint-disable-next-line
expect(console.error.calls).toBe(undefined);
expect(renderToJson(wrapper)).toMatchSnapshot();
});
}); });

View File

@ -0,0 +1,15 @@
exports[`Breadcrumb should allow Breadcrumb.Item is null or undefined 1`] = `
<div
class="ant-breadcrumb">
<span>
<span
class="ant-breadcrumb-link">
Home
</span>
<span
class="ant-breadcrumb-separator">
/
</span>
</span>
</div>
`;

View File

@ -1,6 +1,6 @@
--- ---
order: 0 order: 0
title: title:
zh-CN: 基本 zh-CN: 基本
en-US: Basic Usage en-US: Basic Usage
--- ---

View File

@ -351,6 +351,13 @@ exports[`test renders ./components/button/demo/loading.md correctly 1`] = `
Click me! Click me!
</span> </span>
</button> </button>
<button
class="ant-btn ant-btn-primary"
type="button">
<span>
Won\'t show loading
</span>
</button>
<br /> <br />
<button <button
class="ant-btn ant-btn-circle ant-btn-loading" class="ant-btn ant-btn-circle ant-btn-loading"

View File

@ -2,6 +2,7 @@ import React from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { findDOMNode } from 'react-dom'; import { findDOMNode } from 'react-dom';
import Icon from '../icon'; import Icon from '../icon';
import omit from 'omit.js';
const rxTwoCNChar = /^[\u4e00-\u9fa5]{2}$/; const rxTwoCNChar = /^[\u4e00-\u9fa5]{2}$/;
const isTwoCNChar = rxTwoCNChar.test.bind(rxTwoCNChar); const isTwoCNChar = rxTwoCNChar.test.bind(rxTwoCNChar);
@ -67,6 +68,29 @@ export default class Button extends React.Component<ButtonProps, any> {
timeout: any; timeout: any;
clickedTimeout: any; clickedTimeout: any;
delayTimeout: number;
constructor(props) {
super(props);
this.state = {
loading: props.loading,
};
}
componentWillReceiveProps(nextProps) {
const currentLoading = this.props.loading;
const loading = nextProps.loading;
if (currentLoading) {
clearTimeout(this.delayTimeout);
}
if (loading) {
this.delayTimeout = setTimeout(() => this.setState({ loading }), 200);
} else {
this.setState({ loading });
}
}
componentWillUnmount() { componentWillUnmount() {
if (this.clickedTimeout) { if (this.clickedTimeout) {
@ -75,6 +99,9 @@ export default class Button extends React.Component<ButtonProps, any> {
if (this.timeout) { if (this.timeout) {
clearTimeout(this.timeout); clearTimeout(this.timeout);
} }
if (this.delayTimeout) {
clearTimeout(this.delayTimeout);
}
} }
clearButton = (button) => { clearButton = (button) => {
@ -105,9 +132,10 @@ export default class Button extends React.Component<ButtonProps, any> {
render() { render() {
const { const {
type, shape, size = '', className, htmlType, children, icon, loading, prefixCls, ghost, ...others, type, shape, size = '', className, htmlType, children, icon, prefixCls, ghost, ...others,
} = this.props; } = this.props;
const { loading } = this.state;
// large => lg // large => lg
// small => sm // small => sm
const sizeCls = ({ const sizeCls = ({
@ -130,7 +158,7 @@ export default class Button extends React.Component<ButtonProps, any> {
return ( return (
<button <button
{...others} {...omit(others, ['loading'])}
type={htmlType || 'button'} type={htmlType || 'button'}
className={classes} className={classes}
onMouseUp={this.handleMouseUp} onMouseUp={this.handleMouseUp}

View File

@ -20,6 +20,7 @@ class App extends React.Component {
state = { state = {
loading: false, loading: false,
iconLoading: false, iconLoading: false,
delayLoading: false,
} }
enterLoading = () => { enterLoading = () => {
@ -29,6 +30,15 @@ class App extends React.Component {
enterIconLoading = () => { enterIconLoading = () => {
this.setState({ iconLoading: true }); this.setState({ iconLoading: true });
} }
delayLoading = () => {
this.setState({
delayLoading: true,
});
setTimeout(() => this.setState({
delayLoading: false,
}), 150);
}
render() { render() {
return ( return (
@ -46,6 +56,9 @@ class App extends React.Component {
<Button type="primary" icon="poweroff" loading={this.state.iconLoading} onClick={this.enterIconLoading}> <Button type="primary" icon="poweroff" loading={this.state.iconLoading} onClick={this.enterIconLoading}>
Click me! Click me!
</Button> </Button>
<Button type="primary" loading={this.state.delayLoading} onClick={this.delayLoading}>
Won&apos;t show loading
</Button>
<br /> <br />
<Button shape="circle" loading /> <Button shape="circle" loading />
<Button type="primary" shape="circle" loading /> <Button type="primary" shape="circle" loading />

View File

@ -125,9 +125,9 @@
bottom: -1px; bottom: -1px;
right: -1px; right: -1px;
border-radius: inherit; border-radius: inherit;
border: 1.5px solid @primary-color; border: 0 solid @primary-color;
opacity: 0.4; opacity: 0.4;
animation: buttonEffect 0.4s ease-in-out forwards; animation: buttonEffect .4s;
display: block; display: block;
} }
@ -153,5 +153,6 @@
left: -6px; left: -6px;
bottom: -6px; bottom: -6px;
right: -6px; right: -6px;
border-width: 6px;
} }
} }

View File

@ -1569,790 +1569,6 @@ exports[`test renders ./components/calendar/demo/card.md correctly 1`] = `
</div> </div>
`; `;
exports[`test renders ./components/calendar/demo/locale.md correctly 1`] = `
<div
class=" ant-fullcalendar-fullscreen">
<div
class="ant-fullcalendar-header">
<div
class="ant-fullcalendar-year-select ant-select ant-select-enabled">
<div
aria-autocomplete="list"
aria-expanded="false"
aria-haspopup="true"
class="ant-select-selection
ant-select-selection--single"
role="combobox"
tabindex="0">
<div
class="ant-select-selection__rendered">
<div
class="ant-select-selection-selected-value"
style="display:block;opacity:1;"
title="2016">
2016
</div>
</div>
<span
class="ant-select-arrow"
style="user-select:none;-webkit-user-select:none;"
unselectable="unselectable">
<b />
</span>
</div>
</div>
<div
class="ant-fullcalendar-month-select ant-select ant-select-enabled">
<div
aria-autocomplete="list"
aria-expanded="false"
aria-haspopup="true"
class="ant-select-selection
ant-select-selection--single"
role="combobox"
tabindex="0">
<div
class="ant-select-selection__rendered">
<div
class="ant-select-selection-selected-value"
style="display:block;opacity:1;"
title="Nov">
Nov
</div>
</div>
<span
class="ant-select-arrow"
style="user-select:none;-webkit-user-select:none;"
unselectable="unselectable">
<b />
</span>
</div>
</div>
<div
class="ant-radio-group ant-radio-group-default">
<label
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked">
<span
class="ant-radio-button ant-radio-button-checked ant-radio-button ant-radio-button-checked ant-radio-button-checked-1">
<span
class="ant-radio-button-inner" />
<input
checked=""
class="ant-radio-button-input"
type="radio" />
</span>
<span>
Month
</span>
</label>
<label
class="ant-radio-button-wrapper">
<span
class="ant-radio-button">
<span
class="ant-radio-button-inner" />
<input
class="ant-radio-button-input"
type="radio" />
</span>
<span>
Year
</span>
</label>
</div>
</div>
<div
class="ant-fullcalendar ant-fullcalendar-full ant-fullcalendar-fullscreen"
tabindex="0">
<div
class="ant-fullcalendar-calendar-body">
<table
cellspacing="0"
class="ant-fullcalendar-table"
role="grid">
<thead>
<tr
role="row">
<th
class="ant-fullcalendar-column-header"
role="columnheader"
title="Sun">
<span
class="ant-fullcalendar-column-header-inner">
Su
</span>
</th>
<th
class="ant-fullcalendar-column-header"
role="columnheader"
title="Mon">
<span
class="ant-fullcalendar-column-header-inner">
Mo
</span>
</th>
<th
class="ant-fullcalendar-column-header"
role="columnheader"
title="Tue">
<span
class="ant-fullcalendar-column-header-inner">
Tu
</span>
</th>
<th
class="ant-fullcalendar-column-header"
role="columnheader"
title="Wed">
<span
class="ant-fullcalendar-column-header-inner">
We
</span>
</th>
<th
class="ant-fullcalendar-column-header"
role="columnheader"
title="Thu">
<span
class="ant-fullcalendar-column-header-inner">
Th
</span>
</th>
<th
class="ant-fullcalendar-column-header"
role="columnheader"
title="Fri">
<span
class="ant-fullcalendar-column-header-inner">
Fr
</span>
</th>
<th
class="ant-fullcalendar-column-header"
role="columnheader"
title="Sat">
<span
class="ant-fullcalendar-column-header-inner">
Sa
</span>
</th>
</tr>
</thead>
<tbody
class="ant-fullcalendar-tbody">
<tr
role="row">
<td
class="ant-fullcalendar-cell ant-fullcalendar-last-month-cell"
role="gridcell"
title="2016-10-30">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
30
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell ant-fullcalendar-last-month-cell"
role="gridcell"
title="2016-10-31">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
31
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-1">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
01
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-2">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
02
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-3">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
03
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-4">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
04
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-5">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
05
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
</tr>
<tr
role="row">
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-6">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
06
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-7">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
07
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-8">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
08
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-9">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
09
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-10">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
10
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-11">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
11
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-12">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
12
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
</tr>
<tr
role="row">
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-13">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
13
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-14">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
14
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-15">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
15
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-16">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
16
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-17">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
17
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-18">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
18
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-19">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
19
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
</tr>
<tr
role="row">
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-20">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
20
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-21">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
21
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell ant-fullcalendar-today ant-fullcalendar-selected-day"
role="gridcell"
title="2016-11-22">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
22
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-23">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
23
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-24">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
24
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-25">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
25
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-26">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
26
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
</tr>
<tr
role="row">
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-27">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
27
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-28">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
28
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-29">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
29
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell"
role="gridcell"
title="2016-11-30">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
30
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell ant-fullcalendar-next-month-btn-day"
role="gridcell"
title="2016-12-1">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
01
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell ant-fullcalendar-next-month-btn-day"
role="gridcell"
title="2016-12-2">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
02
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell ant-fullcalendar-next-month-btn-day"
role="gridcell"
title="2016-12-3">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
03
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
</tr>
<tr
role="row">
<td
class="ant-fullcalendar-cell ant-fullcalendar-next-month-btn-day"
role="gridcell"
title="2016-12-4">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
04
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell ant-fullcalendar-next-month-btn-day"
role="gridcell"
title="2016-12-5">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
05
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell ant-fullcalendar-next-month-btn-day"
role="gridcell"
title="2016-12-6">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
06
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell ant-fullcalendar-next-month-btn-day"
role="gridcell"
title="2016-12-7">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
07
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell ant-fullcalendar-next-month-btn-day"
role="gridcell"
title="2016-12-8">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
08
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell ant-fullcalendar-next-month-btn-day"
role="gridcell"
title="2016-12-9">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
09
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
<td
class="ant-fullcalendar-cell ant-fullcalendar-next-month-btn-day"
role="gridcell"
title="2016-12-10">
<div
class="ant-fullcalendar-date">
<div
class="ant-fullcalendar-value">
10
</div>
<div
class="ant-fullcalendar-content" />
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
`;
exports[`test renders ./components/calendar/demo/notice-calendar.md correctly 1`] = ` exports[`test renders ./components/calendar/demo/notice-calendar.md correctly 1`] = `
<div <div
class=" ant-fullcalendar-fullscreen"> class=" ant-fullcalendar-fullscreen">

View File

@ -1,30 +0,0 @@
---
order: 3
title:
zh-CN: 国际化
en-US: locale
---
## zh-CN
通过 `locale` 配置语言, 默认支持 en_US, zh_CN
## en-US
To set the language. en_US, zh_CN are supported by default.
````jsx
import { Calendar } from 'antd';
import enUS from 'antd/lib/calendar/locale/en_US';
import moment from 'moment';
// It's recommended to set moment locale globally, otherwise, you need to set it by `value` or `defaultValue`
// moment.locale('en');
function onPanelChange(value, mode) {
console.log(value, mode);
}
ReactDOM.render(
<Calendar defaultValue={moment().locale('en')} onPanelChange={onPanelChange} locale={enUS} />
, mountNode);
````

View File

@ -13,7 +13,15 @@ When data is in the form of date, such as schedule, timetable, prices calendar,
## API ## API
```html **Note:** Part of locale of Calendar is read from value. So, please set the locale of moment correctly.
```jsx
import moment from 'moment';
// It's recommended to set locale in entry file globaly.
import 'moment/locale/zh-cn';
moment.locale('zh-cn');
<Calendar <Calendar
dateCellRender={dateCellRender} dateCellRender={dateCellRender}
monthCellRender={monthCellRender} monthCellRender={monthCellRender}

View File

@ -15,7 +15,15 @@ title: Calendar
## API ## API
```html **注意:**Calendar 部分 locale 是从 value 中读取,所以请先正确设置 moment 的 locale。
```jsx
import moment from 'moment';
// 推荐在入口文件全局设置 locale
import 'moment/locale/zh-cn';
moment.locale('zh-cn');
<Calendar <Calendar
dateCellRender={dateCellRender} dateCellRender={dateCellRender}
monthCellRender={monthCellRender} monthCellRender={monthCellRender}

View File

@ -1,6 +1,8 @@
// matchMedia polyfill for // matchMedia polyfill for
// https://github.com/WickyNilliams/enquire.js/issues/82 // https://github.com/WickyNilliams/enquire.js/issues/82
import assign from 'object-assign'; import assign from 'object-assign';
import debounce from 'lodash.debounce';
if (typeof window !== 'undefined') { if (typeof window !== 'undefined') {
const matchMediaPolyfill = function matchMediaPolyfill(mediaQuery: string): MediaQueryList { const matchMediaPolyfill = function matchMediaPolyfill(mediaQuery: string): MediaQueryList {
return { return {
@ -48,6 +50,41 @@ export default class Carousel extends React.Component<CarouselProps, any> {
draggable: false, draggable: false,
}; };
refs: {
slick: any,
};
constructor() {
super();
this.onWindowResized = debounce(this.onWindowResized, 500, {
leading: false,
});
}
componentDidMount() {
const { autoplay } = this.props;
if (autoplay) {
window.addEventListener('resize', this.onWindowResized);
}
}
componentWillUnmount() {
const { autoplay } = this.props;
if (autoplay) {
window.removeEventListener('resize', this.onWindowResized);
(this.onWindowResized as any).cancel();
}
}
onWindowResized = () => {
// Fix https://github.com/ant-design/ant-design/issues/2550
const { slick } = this.refs;
const { autoplay } = this.props;
if (autoplay && slick && slick.innerSlider && slick.innerSlider.autoPlay) {
slick.innerSlider.autoPlay();
}
}
render() { render() {
let props = assign({}, this.props); let props = assign({}, this.props);

View File

@ -0,0 +1,179 @@
exports[`Cascader can be selected 1`] = `
<div>
<div
class="ant-cascader-menus ant-cascader-menus-placement-bottomLeft ">
<div>
<ul
class="ant-cascader-menu">
<li
class="ant-cascader-menu-item ant-cascader-menu-item-expand ant-cascader-menu-item-active"
title="Zhejiang">
Zhejiang
</li>
<li
class="ant-cascader-menu-item ant-cascader-menu-item-expand"
title="Jiangsu">
Jiangsu
</li>
</ul>
<ul
class="ant-cascader-menu">
<li
class="ant-cascader-menu-item ant-cascader-menu-item-expand"
title="Hangzhou">
Hangzhou
</li>
</ul>
</div>
</div>
</div>
`;
exports[`Cascader can be selected 2`] = `
<div>
<div
class="ant-cascader-menus ant-cascader-menus-placement-bottomLeft ">
<div>
<ul
class="ant-cascader-menu">
<li
class="ant-cascader-menu-item ant-cascader-menu-item-expand ant-cascader-menu-item-active"
title="Zhejiang">
Zhejiang
</li>
<li
class="ant-cascader-menu-item ant-cascader-menu-item-expand"
title="Jiangsu">
Jiangsu
</li>
</ul>
<ul
class="ant-cascader-menu">
<li
class="ant-cascader-menu-item ant-cascader-menu-item-expand ant-cascader-menu-item-active"
title="Hangzhou">
Hangzhou
</li>
</ul>
<ul
class="ant-cascader-menu">
<li
class="ant-cascader-menu-item"
title="West Lake">
West Lake
</li>
</ul>
</div>
</div>
</div>
`;
exports[`Cascader can be selected 3`] = `
<div>
<div
class="ant-cascader-menus ant-cascader-menus-placement-bottomLeft ant-cascader-menus-hidden">
<div>
<ul
class="ant-cascader-menu">
<li
class="ant-cascader-menu-item ant-cascader-menu-item-expand ant-cascader-menu-item-active"
title="Zhejiang">
Zhejiang
</li>
<li
class="ant-cascader-menu-item ant-cascader-menu-item-expand"
title="Jiangsu">
Jiangsu
</li>
</ul>
<ul
class="ant-cascader-menu">
<li
class="ant-cascader-menu-item ant-cascader-menu-item-expand ant-cascader-menu-item-active"
title="Hangzhou">
Hangzhou
</li>
</ul>
<ul
class="ant-cascader-menu">
<li
class="ant-cascader-menu-item ant-cascader-menu-item-active"
title="West Lake">
West Lake
</li>
</ul>
</div>
</div>
</div>
`;
exports[`Cascader popup correctly when panel is hidden 1`] = `
<div>
<div
class="ant-cascader-menus ant-cascader-menus-empty ant-cascader-menus-placement-bottomLeft ant-cascader-menus-hidden">
<div />
</div>
</div>
`;
exports[`Cascader popup correctly when panel is open 1`] = `
<div>
<div
class="ant-cascader-menus ant-cascader-menus-placement-bottomLeft ">
<div>
<ul
class="ant-cascader-menu">
<li
class="ant-cascader-menu-item ant-cascader-menu-item-expand"
title="Zhejiang">
Zhejiang
</li>
<li
class="ant-cascader-menu-item ant-cascader-menu-item-expand"
title="Jiangsu">
Jiangsu
</li>
</ul>
</div>
</div>
</div>
`;
exports[`Cascader popup correctly with defaultValue 1`] = `
<div>
<div
class="ant-cascader-menus ant-cascader-menus-placement-bottomLeft ">
<div>
<ul
class="ant-cascader-menu">
<li
class="ant-cascader-menu-item ant-cascader-menu-item-expand ant-cascader-menu-item-active"
title="Zhejiang">
Zhejiang
</li>
<li
class="ant-cascader-menu-item ant-cascader-menu-item-expand"
title="Jiangsu">
Jiangsu
</li>
</ul>
<ul
class="ant-cascader-menu">
<li
class="ant-cascader-menu-item ant-cascader-menu-item-expand ant-cascader-menu-item-active"
title="Hangzhou">
Hangzhou
</li>
</ul>
<ul
class="ant-cascader-menu">
<li
class="ant-cascader-menu-item"
title="West Lake">
West Lake
</li>
</ul>
</div>
</div>
</div>
`;

View File

@ -0,0 +1,71 @@
import React from 'react';
import { render, mount } from 'enzyme';
import { renderToJson } from 'enzyme-to-json';
import Cascader from '..';
const options = [{
value: 'zhejiang',
label: 'Zhejiang',
children: [{
value: 'hangzhou',
label: 'Hangzhou',
children: [{
value: 'xihu',
label: 'West Lake',
}],
}],
}, {
value: 'jiangsu',
label: 'Jiangsu',
children: [{
value: 'nanjing',
label: 'Nanjing',
children: [{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
}],
}],
}];
describe('Cascader', () => {
it('popup correctly when panel is hidden', () => {
const wrapper = mount(
<Cascader options={options} />
);
expect(renderToJson(render(wrapper.find('Trigger').node.getComponent()))).toMatchSnapshot();
});
it('popup correctly when panel is open', () => {
const wrapper = mount(
<Cascader options={options} />
);
wrapper.find('input').simulate('click');
expect(renderToJson(render(wrapper.find('Trigger').node.getComponent()))).toMatchSnapshot();
});
it('popup correctly with defaultValue', () => {
const wrapper = mount(
<Cascader options={options} defaultValue={['zhejiang', 'hangzhou']} />
);
wrapper.find('input').simulate('click');
expect(renderToJson(render(wrapper.find('Trigger').node.getComponent()))).toMatchSnapshot();
});
it('can be selected', () => {
const wrapper = mount(<Cascader options={options} />);
wrapper.find('input').simulate('click');
let popupWrapper = mount(wrapper.find('Trigger').node.getComponent());
popupWrapper.find('.ant-cascader-menu').at(0).find('.ant-cascader-menu-item').at(0)
.simulate('click');
expect(renderToJson(render(wrapper.find('Trigger').node.getComponent()))).toMatchSnapshot();
popupWrapper = mount(wrapper.find('Trigger').node.getComponent());
popupWrapper.find('.ant-cascader-menu').at(1).find('.ant-cascader-menu-item').at(0)
.simulate('click');
expect(renderToJson(render(wrapper.find('Trigger').node.getComponent()))).toMatchSnapshot();
popupWrapper = mount(wrapper.find('Trigger').node.getComponent());
popupWrapper.find('.ant-cascader-menu').at(2).find('.ant-cascader-menu-item').at(0)
.simulate('click');
expect(renderToJson(render(wrapper.find('Trigger').node.getComponent()))).toMatchSnapshot();
});
});

View File

@ -24,7 +24,7 @@
position: relative; position: relative;
top: 0; top: 0;
left: 0; left: 0;
display: inline-block; display: block;
width: 14px; width: 14px;
height: 14px; height: 14px;
border: @border-width-base @border-style-base @border-color-base; border: @border-width-base @border-style-base @border-color-base;
@ -133,6 +133,7 @@
.@{checkbox-prefix-cls} + span { .@{checkbox-prefix-cls} + span {
padding-left: 8px; padding-left: 8px;
padding-right: 8px; padding-right: 8px;
vertical-align: middle;
} }
.@{checkbox-prefix-cls}-group { .@{checkbox-prefix-cls}-group {

View File

@ -1,6 +1,7 @@
import React from 'react'; import React from 'react';
import RcCollapse from 'rc-collapse'; import RcCollapse from 'rc-collapse';
import classNames from 'classnames'; import classNames from 'classnames';
import animation from '../_util/openAnimation';
export interface CollapseProps { export interface CollapseProps {
activeKey?: Array<string> | string; activeKey?: Array<string> | string;
@ -30,6 +31,7 @@ export default class Collapse extends React.Component<CollapseProps, any> {
static defaultProps = { static defaultProps = {
prefixCls: 'ant-collapse', prefixCls: 'ant-collapse',
bordered: true, bordered: true,
openAnimation: { ...animation, appear() {} },
}; };
render() { render() {

View File

@ -1,6 +1,7 @@
import React from 'react'; import React from 'react';
import CalendarLocale from 'rc-calendar/lib/locale/zh_CN'; import CalendarLocale from 'rc-calendar/lib/locale/zh_CN';
import RcCalendar from 'rc-calendar'; import RcCalendar from 'rc-calendar';
import warning from 'warning';
export default class Calendar extends React.Component<any, any> { export default class Calendar extends React.Component<any, any> {
static defaultProps = { static defaultProps = {
@ -9,6 +10,7 @@ export default class Calendar extends React.Component<any, any> {
}; };
render() { render() {
warning(false, 'DatePicker.Calendar is deprecated, use Calendar instead.');
return <RcCalendar {...this.props} />; return <RcCalendar {...this.props} />;
} }
} }

View File

@ -210,24 +210,6 @@ exports[`test renders ./components/date-picker/demo/format.md correctly 1`] = `
</div> </div>
`; `;
exports[`test renders ./components/date-picker/demo/locale.md correctly 1`] = `
<span
class="ant-calendar-picker"
style="width:154px;">
<span>
<input
class="ant-calendar-picker-input ant-input"
placeholder="Select date"
readonly=""
value="2016-11-22" />
<i
class="anticon anticon-cross-circle ant-calendar-picker-clear" />
<span
class="ant-calendar-picker-icon" />
</span>
</span>
`;
exports[`test renders ./components/date-picker/demo/presetted-ranges.md correctly 1`] = ` exports[`test renders ./components/date-picker/demo/presetted-ranges.md correctly 1`] = `
<div> <div>
<span <span

View File

@ -1,14 +1,3 @@
import { render } from 'enzyme';
import { renderToJson } from 'enzyme-to-json';
import MockDate from 'mockdate';
import demoTest from '../../../tests/shared/demoTest'; import demoTest from '../../../tests/shared/demoTest';
demoTest('date-picker', { skip: ['locale.md'] }); demoTest('date-picker', { skip: ['locale.md'] });
test('renders ./components/date-picker/demo/locale.md correctly', () => {
MockDate.set(new Date('2016-11-22').getTime());
const LocaleDemo = require('../demo/locale'); // eslint-disable-line global-require
const wrapper = render(LocaleDemo);
expect(renderToJson(wrapper)).toMatchSnapshot();
MockDate.reset();
});

View File

@ -1,44 +0,0 @@
---
order: 7
title:
zh-CN: 国际化
en-US: Locale
---
## zh-CN
通过 `locale` 设置语言, 默认支持 `en_US``zh_CN`。
moment 会自动使用当前时区,如果需要使用别的时区,则需要自行设置,设置方法请参考示例代码中的注释。
## en-US
Use locale to set the language. `en_US`, `zh_CN` are supported by default.
moment will use your time zone automatically. If you want to set other time zone, please set it by yourself.
````jsx
import { DatePicker } from 'antd';
import enUS from 'antd/lib/date-picker/locale/en_US';
import moment from 'moment-timezone/moment-timezone';
// It's recommended to set moment locale and time zone globally in entry file,
// otherwise, you need to set it by `value` or `defaultValue`.
// moment.locale('en');
// The following data is copied from https://github.com/moment/moment-timezone/blob/develop/data/packed/latest.json
// moment.tz.add('Europe/London|GMT BST BDST|0 -10 -20|0101010101010101010101010101010101010101010101010121212121210101210101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-2axa0 Rc0 1fA0 14M0 1fc0 1g00 1co0 1dc0 1co0 1oo0 1400 1dc0 19A0 1io0 1io0 WM0 1o00 14o0 1o00 17c0 1io0 17c0 1fA0 1a00 1lc0 17c0 1io0 17c0 1fA0 1a00 1io0 17c0 1io0 17c0 1fA0 1cM0 1io0 17c0 1fA0 1a00 1io0 17c0 1io0 17c0 1fA0 1a00 1io0 1qM0 Dc0 2Rz0 Dc0 1zc0 Oo0 1zc0 Rc0 1wo0 17c0 1iM0 FA0 xB0 1fA0 1a00 14o0 bb0 LA0 xB0 Rc0 1wo0 11A0 1o00 17c0 1fA0 1a00 1fA0 1cM0 1fA0 1a00 17c0 1fA0 1a00 1io0 17c0 1lc0 17c0 1fA0 1a00 1io0 17c0 1io0 17c0 1fA0 1a00 1a00 1qM0 WM0 1qM0 11A0 1o00 WM0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1tA0 IM0 90o0 U00 1tA0 U00 1tA0 U00 1tA0 U00 1tA0 WM0 1qM0 WM0 1qM0 WM0 1tA0 U00 1tA0 U00 1tA0 11z0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 14o0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|10e6');
// moment.tz.setDefault('Europe/London')
const log = console.log.bind(console);
ReactDOM.render(
<DatePicker
defaultValue={moment().locale('en').utcOffset(0)}
locale={enUS}
showTime
onChange={log}
/>
, mountNode);
````

View File

@ -59,6 +59,7 @@ The following APIs are shared by DatePicker, MonthPicker, RangePicker.
| 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) |
| showToday | whether to show "Today" button | boolean | true | | showToday | whether to show "Today" button | boolean | true |
| disabledTime | to specify the time that cannot be selected | function(date) | - | | disabledTime | to specify the time that cannot be selected | function(date) | - |
| onOk | callback when click ok button | function() | - |
### MonthPicker ### MonthPicker

View File

@ -22,6 +22,7 @@ export interface PickerProps {
getCalendarContainer?: (trigger: any) => React.ReactNode; getCalendarContainer?: (trigger: any) => React.ReactNode;
open?: boolean; open?: boolean;
onOpenChange?: (status: boolean) => void; onOpenChange?: (status: boolean) => void;
disabledDate?: (current: moment.Moment) => boolean;
} }
export interface SinglePickerProps { export interface SinglePickerProps {
@ -36,14 +37,17 @@ export interface DatePickerProps extends PickerProps, SinglePickerProps {
showToday?: boolean; showToday?: boolean;
open?: boolean; open?: boolean;
toggleOpen?: (e: {open: boolean}) => void; toggleOpen?: (e: {open: boolean}) => void;
disabledDate?: (current: moment.Moment) => boolean; disabledTime?: (current: moment.Moment) => {
disabledHours?: () => [number, number],
disabledMinutes?: () => [number, number],
disabledSeconds?: () => [number, number],
};
onOpenChange?: (status: boolean) => void; onOpenChange?: (status: boolean) => void;
placeholder?: string; placeholder?: string;
} }
const DatePicker = wrapPicker(createPicker(RcCalendar)) as React.ClassicComponentClass<DatePickerProps>; const DatePicker = wrapPicker(createPicker(RcCalendar)) as React.ClassicComponentClass<DatePickerProps>;
export interface MonthPickerProps extends PickerProps, SinglePickerProps { export interface MonthPickerProps extends PickerProps, SinglePickerProps {
disabledDate?: (current: moment.Moment) => boolean;
placeholder?: string; placeholder?: string;
} }
const MonthPicker = wrapPicker(createPicker(MonthCalendar), 'YYYY-MM'); const MonthPicker = wrapPicker(createPicker(MonthCalendar), 'YYYY-MM');
@ -57,6 +61,12 @@ export interface RangePickerProps extends PickerProps {
ranges?: { ranges?: {
[range: string]: moment.Moment[], [range: string]: moment.Moment[],
}; };
placeholder?: [string, string];
disabledTime?: (current: moment.Moment, type: string) => {
disabledHours?: () => [number, number],
disabledMinutes?: () => [number, number],
disabledSeconds?: () => [number, number],
};
} }
assign(DatePicker, { assign(DatePicker, {

View File

@ -48,6 +48,7 @@ moment.locale('zh-cn');
| open | 控制弹层是否展开 | boolean | - | | open | 控制弹层是否展开 | boolean | - |
| onOpenChange | 弹出日历和关闭日历的回调 | function(status) | 无 | | onOpenChange | 弹出日历和关闭日历的回调 | function(status) | 无 |
| placeholder | 输入框提示文字 | string\|RangePicker[] | - | | placeholder | 输入框提示文字 | string\|RangePicker[] | - |
| onOk | 点击确定按钮的回调 | function() | - |
### DatePicker ### DatePicker

View File

@ -191,7 +191,7 @@
&-combobox { &-combobox {
display: inline-block; display: inline-block;
height: 100%; height: 100%;
background-color: white; background-color: @component-background;
border-top: @border-width-base @border-style-base @border-color-split; border-top: @border-width-base @border-style-base @border-color-split;
} }
&-select { &-select {

View File

@ -68,6 +68,12 @@
transition: all .3s; transition: all .3s;
} }
&-selected,
&-selected > a {
color: @primary-color;
background-color: @primary-1;
}
&:hover { &:hover {
background-color: @primary-1; background-color: @primary-1;
} }

View File

@ -213,27 +213,30 @@ export default class FormItem extends React.Component<FormItemProps, any> {
} }
renderLabel() { renderLabel() {
const props = this.props; const { label, labelCol, prefixCls, colon, id } = this.props;
const context = this.context; const context = this.context;
const labelCol = props.labelCol;
const required = this.isRequired(); const required = this.isRequired();
const className = classNames({ const className = classNames({
[`${props.prefixCls}-item-required`]: required, [`${prefixCls}-item-required`]: required,
}); });
let label = props.label; let labelChildren = label;
// Keep label is original where there should have no colon // Keep label is original where there should have no colon
const haveColon = props.colon && !context.vertical; const haveColon = colon && !context.vertical;
// Remove duplicated user input colon // Remove duplicated user input colon
if (haveColon && typeof label === 'string' && (label as string).trim() !== '') { if (haveColon && typeof label === 'string' && (label as string).trim() !== '') {
label = (props.label as string).replace(/[|:]\s*$/, ''); labelChildren = (label as string).replace(/[|:]\s*$/, '');
} }
return props.label ? ( return label ? (
<Col {...labelCol} key="label" className={`${props.prefixCls}-item-label`}> <Col {...labelCol} key="label" className={`${prefixCls}-item-label`}>
<label htmlFor={props.id || this.getId()} className={className}> <label
{label} htmlFor={id || this.getId()}
className={className}
title={typeof label === 'string' ? label : ''}
>
{labelChildren}
</label> </label>
</Col> </Col>
) : null; ) : null;

View File

@ -14,7 +14,8 @@ exports[`test renders ./components/form/demo/advanced-search.md correctly 1`] =
class="ant-col-5 ant-form-item-label"> class="ant-col-5 ant-form-item-label">
<label <label
class="" class=""
for="field-0"> for="field-0"
title="Field 0">
Field 0 Field 0
</label> </label>
</div> </div>
@ -42,7 +43,8 @@ exports[`test renders ./components/form/demo/advanced-search.md correctly 1`] =
class="ant-col-5 ant-form-item-label"> class="ant-col-5 ant-form-item-label">
<label <label
class="" class=""
for="field-1"> for="field-1"
title="Field 1">
Field 1 Field 1
</label> </label>
</div> </div>
@ -70,7 +72,8 @@ exports[`test renders ./components/form/demo/advanced-search.md correctly 1`] =
class="ant-col-5 ant-form-item-label"> class="ant-col-5 ant-form-item-label">
<label <label
class="" class=""
for="field-2"> for="field-2"
title="Field 2">
Field 2 Field 2
</label> </label>
</div> </div>
@ -98,7 +101,8 @@ exports[`test renders ./components/form/demo/advanced-search.md correctly 1`] =
class="ant-col-5 ant-form-item-label"> class="ant-col-5 ant-form-item-label">
<label <label
class="" class=""
for="field-3"> for="field-3"
title="Field 3">
Field 3 Field 3
</label> </label>
</div> </div>
@ -126,7 +130,8 @@ exports[`test renders ./components/form/demo/advanced-search.md correctly 1`] =
class="ant-col-5 ant-form-item-label"> class="ant-col-5 ant-form-item-label">
<label <label
class="" class=""
for="field-4"> for="field-4"
title="Field 4">
Field 4 Field 4
</label> </label>
</div> </div>
@ -154,7 +159,8 @@ exports[`test renders ./components/form/demo/advanced-search.md correctly 1`] =
class="ant-col-5 ant-form-item-label"> class="ant-col-5 ant-form-item-label">
<label <label
class="" class=""
for="field-5"> for="field-5"
title="Field 5">
Field 5 Field 5
</label> </label>
</div> </div>
@ -219,7 +225,8 @@ exports[`test renders ./components/form/demo/coordinated.md correctly 1`] = `
class="ant-col-4 ant-form-item-label"> class="ant-col-4 ant-form-item-label">
<label <label
class="ant-form-item-required" class="ant-form-item-required"
for="note"> for="note"
title="Note">
Note Note
</label> </label>
</div> </div>
@ -242,7 +249,8 @@ exports[`test renders ./components/form/demo/coordinated.md correctly 1`] = `
class="ant-col-4 ant-form-item-label"> class="ant-col-4 ant-form-item-label">
<label <label
class="ant-form-item-required" class="ant-form-item-required"
for="gender"> for="gender"
title="Gender">
Gender Gender
</label> </label>
</div> </div>
@ -308,7 +316,8 @@ exports[`test renders ./components/form/demo/customized-form-controls.md correct
class="ant-form-item-label"> class="ant-form-item-label">
<label <label
class="" class=""
for="price"> for="price"
title="Price">
Price Price
</label> </label>
</div> </div>
@ -436,7 +445,8 @@ exports[`test renders ./components/form/demo/global-state.md correctly 1`] = `
class="ant-form-item-label"> class="ant-form-item-label">
<label <label
class="ant-form-item-required" class="ant-form-item-required"
for="username"> for="username"
title="Username">
Username Username
</label> </label>
</div> </div>
@ -544,7 +554,8 @@ exports[`test renders ./components/form/demo/layout.md correctly 1`] = `
<div <div
class="ant-col-4 ant-form-item-label"> class="ant-col-4 ant-form-item-label">
<label <label
class=""> class=""
title="Form Layout">
Form Layout Form Layout
</label> </label>
</div> </div>
@ -606,7 +617,8 @@ exports[`test renders ./components/form/demo/layout.md correctly 1`] = `
<div <div
class="ant-col-4 ant-form-item-label"> class="ant-col-4 ant-form-item-label">
<label <label
class=""> class=""
title="Field A">
Field A Field A
</label> </label>
</div> </div>
@ -626,7 +638,8 @@ exports[`test renders ./components/form/demo/layout.md correctly 1`] = `
<div <div
class="ant-col-4 ant-form-item-label"> class="ant-col-4 ant-form-item-label">
<label <label
class=""> class=""
title="Field B">
Field B Field B
</label> </label>
</div> </div>
@ -763,7 +776,8 @@ exports[`test renders ./components/form/demo/register.md correctly 1`] = `
class="ant-col-6 ant-form-item-label"> class="ant-col-6 ant-form-item-label">
<label <label
class="ant-form-item-required" class="ant-form-item-required"
for="email"> for="email"
title="E-mail">
E-mail E-mail
</label> </label>
</div> </div>
@ -786,7 +800,8 @@ exports[`test renders ./components/form/demo/register.md correctly 1`] = `
class="ant-col-6 ant-form-item-label"> class="ant-col-6 ant-form-item-label">
<label <label
class="ant-form-item-required" class="ant-form-item-required"
for="password"> for="password"
title="Password">
Password Password
</label> </label>
</div> </div>
@ -809,7 +824,8 @@ exports[`test renders ./components/form/demo/register.md correctly 1`] = `
class="ant-col-6 ant-form-item-label"> class="ant-col-6 ant-form-item-label">
<label <label
class="ant-form-item-required" class="ant-form-item-required"
for="confirm"> for="confirm"
title="Confirm Password">
Confirm Password Confirm Password
</label> </label>
</div> </div>
@ -832,7 +848,8 @@ exports[`test renders ./components/form/demo/register.md correctly 1`] = `
class="ant-col-6 ant-form-item-label"> class="ant-col-6 ant-form-item-label">
<label <label
class="ant-form-item-required" class="ant-form-item-required"
for="nickname"> for="nickname"
title="">
<span> <span>
Nickname  Nickname 
<i <i
@ -859,7 +876,8 @@ exports[`test renders ./components/form/demo/register.md correctly 1`] = `
class="ant-col-6 ant-form-item-label"> class="ant-col-6 ant-form-item-label">
<label <label
class="ant-form-item-required" class="ant-form-item-required"
for="residence"> for="residence"
title="Habitual Residence">
Habitual Residence Habitual Residence
</label> </label>
</div> </div>
@ -896,7 +914,8 @@ exports[`test renders ./components/form/demo/register.md correctly 1`] = `
class="ant-col-6 ant-form-item-label"> class="ant-col-6 ant-form-item-label">
<label <label
class="ant-form-item-required" class="ant-form-item-required"
for="phone"> for="phone"
title="Phone Number">
Phone Number Phone Number
</label> </label>
</div> </div>
@ -952,7 +971,8 @@ exports[`test renders ./components/form/demo/register.md correctly 1`] = `
class="ant-col-6 ant-form-item-label"> class="ant-col-6 ant-form-item-label">
<label <label
class="ant-form-item-required" class="ant-form-item-required"
for="captcha"> for="captcha"
title="Captcha">
Captcha Captcha
</label> </label>
</div> </div>
@ -1047,7 +1067,8 @@ exports[`test renders ./components/form/demo/time-related-controls.md correctly
class="ant-col-8 ant-form-item-label"> class="ant-col-8 ant-form-item-label">
<label <label
class="ant-form-item-required" class="ant-form-item-required"
for="date-picker"> for="date-picker"
title="DatePicker">
DatePicker DatePicker
</label> </label>
</div> </div>
@ -1076,7 +1097,8 @@ exports[`test renders ./components/form/demo/time-related-controls.md correctly
class="ant-col-8 ant-form-item-label"> class="ant-col-8 ant-form-item-label">
<label <label
class="ant-form-item-required" class="ant-form-item-required"
for="date-time-picker"> for="date-time-picker"
title="DatePicker[showTime]">
DatePicker[showTime] DatePicker[showTime]
</label> </label>
</div> </div>
@ -1106,7 +1128,8 @@ exports[`test renders ./components/form/demo/time-related-controls.md correctly
class="ant-col-8 ant-form-item-label"> class="ant-col-8 ant-form-item-label">
<label <label
class="ant-form-item-required" class="ant-form-item-required"
for="month-picker"> for="month-picker"
title="MonthPicker">
MonthPicker MonthPicker
</label> </label>
</div> </div>
@ -1135,7 +1158,8 @@ exports[`test renders ./components/form/demo/time-related-controls.md correctly
class="ant-col-8 ant-form-item-label"> class="ant-col-8 ant-form-item-label">
<label <label
class="ant-form-item-required" class="ant-form-item-required"
for="range-picker"> for="range-picker"
title="RangePicker">
RangePicker RangePicker
</label> </label>
</div> </div>
@ -1174,7 +1198,8 @@ exports[`test renders ./components/form/demo/time-related-controls.md correctly
class="ant-col-8 ant-form-item-label"> class="ant-col-8 ant-form-item-label">
<label <label
class="ant-form-item-required" class="ant-form-item-required"
for="range-time-picker"> for="range-time-picker"
title="RangePicker[showTime]">
RangePicker[showTime] RangePicker[showTime]
</label> </label>
</div> </div>
@ -1214,7 +1239,8 @@ exports[`test renders ./components/form/demo/time-related-controls.md correctly
class="ant-col-8 ant-form-item-label"> class="ant-col-8 ant-form-item-label">
<label <label
class="ant-form-item-required" class="ant-form-item-required"
for="time-picker"> for="time-picker"
title="TimePicker">
TimePicker TimePicker
</label> </label>
</div> </div>
@ -1263,7 +1289,8 @@ exports[`test renders ./components/form/demo/validate-other.md correctly 1`] = `
<div <div
class="ant-col-6 ant-form-item-label"> class="ant-col-6 ant-form-item-label">
<label <label
class=""> class=""
title="Nation">
Nation Nation
</label> </label>
</div> </div>
@ -1284,7 +1311,8 @@ exports[`test renders ./components/form/demo/validate-other.md correctly 1`] = `
class="ant-col-6 ant-form-item-label"> class="ant-col-6 ant-form-item-label">
<label <label
class="ant-form-item-required" class="ant-form-item-required"
for="select"> for="select"
title="Select">
Select Select
</label> </label>
</div> </div>
@ -1328,7 +1356,8 @@ exports[`test renders ./components/form/demo/validate-other.md correctly 1`] = `
class="ant-col-6 ant-form-item-label"> class="ant-col-6 ant-form-item-label">
<label <label
class="ant-form-item-required" class="ant-form-item-required"
for="select-multiple"> for="select-multiple"
title="Select[multiple]">
Select[multiple] Select[multiple]
</label> </label>
</div> </div>
@ -1378,7 +1407,8 @@ exports[`test renders ./components/form/demo/validate-other.md correctly 1`] = `
class="ant-col-6 ant-form-item-label"> class="ant-col-6 ant-form-item-label">
<label <label
class="" class=""
for="input-number"> for="input-number"
title="InputNumber">
InputNumber InputNumber
</label> </label>
</div> </div>
@ -1428,7 +1458,8 @@ exports[`test renders ./components/form/demo/validate-other.md correctly 1`] = `
class="ant-col-6 ant-form-item-label"> class="ant-col-6 ant-form-item-label">
<label <label
class="" class=""
for="switch"> for="switch"
title="Switch">
Switch Switch
</label> </label>
</div> </div>
@ -1453,7 +1484,8 @@ exports[`test renders ./components/form/demo/validate-other.md correctly 1`] = `
class="ant-col-6 ant-form-item-label"> class="ant-col-6 ant-form-item-label">
<label <label
class="" class=""
for="slider"> for="slider"
title="Slider">
Slider Slider
</label> </label>
</div> </div>
@ -1535,7 +1567,8 @@ exports[`test renders ./components/form/demo/validate-other.md correctly 1`] = `
class="ant-col-6 ant-form-item-label"> class="ant-col-6 ant-form-item-label">
<label <label
class="" class=""
for="radio-group"> for="radio-group"
title="Radio.Group">
Radio.Group Radio.Group
</label> </label>
</div> </div>
@ -1597,7 +1630,8 @@ exports[`test renders ./components/form/demo/validate-other.md correctly 1`] = `
class="ant-col-6 ant-form-item-label"> class="ant-col-6 ant-form-item-label">
<label <label
class="" class=""
for="radio-button"> for="radio-button"
title="Radio.Button">
Radio.Button Radio.Button
</label> </label>
</div> </div>
@ -1659,7 +1693,8 @@ exports[`test renders ./components/form/demo/validate-other.md correctly 1`] = `
class="ant-col-6 ant-form-item-label"> class="ant-col-6 ant-form-item-label">
<label <label
class="" class=""
for="upload"> for="upload"
title="Upload">
Upload Upload
</label> </label>
</div> </div>
@ -1709,7 +1744,8 @@ exports[`test renders ./components/form/demo/validate-static.md correctly 1`] =
<div <div
class="ant-col-5 ant-form-item-label"> class="ant-col-5 ant-form-item-label">
<label <label
class=""> class=""
title="Fail">
Fail Fail
</label> </label>
</div> </div>
@ -1734,7 +1770,8 @@ exports[`test renders ./components/form/demo/validate-static.md correctly 1`] =
<div <div
class="ant-col-5 ant-form-item-label"> class="ant-col-5 ant-form-item-label">
<label <label
class=""> class=""
title="Warning">
Warning Warning
</label> </label>
</div> </div>
@ -1755,7 +1792,8 @@ exports[`test renders ./components/form/demo/validate-static.md correctly 1`] =
<div <div
class="ant-col-5 ant-form-item-label"> class="ant-col-5 ant-form-item-label">
<label <label
class=""> class=""
title="Validating">
Validating Validating
</label> </label>
</div> </div>
@ -1780,7 +1818,8 @@ exports[`test renders ./components/form/demo/validate-static.md correctly 1`] =
<div <div
class="ant-col-5 ant-form-item-label"> class="ant-col-5 ant-form-item-label">
<label <label
class=""> class=""
title="Success">
Success Success
</label> </label>
</div> </div>
@ -1801,7 +1840,8 @@ exports[`test renders ./components/form/demo/validate-static.md correctly 1`] =
<div <div
class="ant-col-5 ant-form-item-label"> class="ant-col-5 ant-form-item-label">
<label <label
class=""> class=""
title="Warning">
Warning Warning
</label> </label>
</div> </div>
@ -1822,7 +1862,8 @@ exports[`test renders ./components/form/demo/validate-static.md correctly 1`] =
<div <div
class="ant-col-5 ant-form-item-label"> class="ant-col-5 ant-form-item-label">
<label <label
class=""> class=""
title="Fail">
Fail Fail
</label> </label>
</div> </div>
@ -1847,7 +1888,8 @@ exports[`test renders ./components/form/demo/validate-static.md correctly 1`] =
<div <div
class="ant-col-5 ant-form-item-label"> class="ant-col-5 ant-form-item-label">
<label <label
class=""> class=""
title="inline">
inline inline
</label> </label>
</div> </div>
@ -1930,7 +1972,8 @@ exports[`test renders ./components/form/demo/without-form-create.md correctly 1`
<div <div
class="ant-col-7 ant-form-item-label"> class="ant-col-7 ant-form-item-label">
<label <label
class=""> class=""
title="Prime between 8 & 12">
Prime between 8 & 12 Prime between 8 & 12
</label> </label>
</div> </div>

View File

@ -72,7 +72,7 @@ class TimeRelatedForm extends React.Component {
{...formItemLayout} {...formItemLayout}
label="DatePicker[showTime]" label="DatePicker[showTime]"
> >
{getFieldDecorator('date-time-picker', config)( {getFieldDecorator('date-time-picker', config)(
<DatePicker showTime format="YYYY-MM-DD HH:mm:ss" /> <DatePicker showTime format="YYYY-MM-DD HH:mm:ss" />
)} )}
</FormItem> </FormItem>
@ -80,7 +80,7 @@ class TimeRelatedForm extends React.Component {
{...formItemLayout} {...formItemLayout}
label="MonthPicker" label="MonthPicker"
> >
{getFieldDecorator('month-picker', config)( {getFieldDecorator('month-picker', config)(
<MonthPicker /> <MonthPicker />
)} )}
</FormItem> </FormItem>
@ -88,7 +88,7 @@ class TimeRelatedForm extends React.Component {
{...formItemLayout} {...formItemLayout}
label="RangePicker" label="RangePicker"
> >
{getFieldDecorator('range-picker', rangeConfig)( {getFieldDecorator('range-picker', rangeConfig)(
<RangePicker /> <RangePicker />
)} )}
</FormItem> </FormItem>
@ -96,7 +96,7 @@ class TimeRelatedForm extends React.Component {
{...formItemLayout} {...formItemLayout}
label="RangePicker[showTime]" label="RangePicker[showTime]"
> >
{getFieldDecorator('range-time-picker', rangeConfig)( {getFieldDecorator('range-time-picker', rangeConfig)(
<RangePicker showTime format="YYYY-MM-DD HH:mm:ss" /> <RangePicker showTime format="YYYY-MM-DD HH:mm:ss" />
)} )}
</FormItem> </FormItem>
@ -104,7 +104,7 @@ class TimeRelatedForm extends React.Component {
{...formItemLayout} {...formItemLayout}
label="TimePicker" label="TimePicker"
> >
{getFieldDecorator('time-picker', config)( {getFieldDecorator('time-picker', config)(
<TimePicker /> <TimePicker />
)} )}
</FormItem> </FormItem>

View File

@ -249,15 +249,14 @@ form {
// Form layout // Form layout
//== Vertical Form //== Vertical Form
.@{form-prefix-cls}-vertical { .@{form-prefix-cls}-vertical .@{form-prefix-cls}-item-label,
.@{form-prefix-cls}-item-label { .@{ant-prefix}-col-24.@{form-prefix-cls}-item-label { // when labelCol is 24, it is a vertical form
padding: 0 0 8px; padding: 0 0 8px;
display: block; display: block;
text-align: left; text-align: left;
label:after { label:after {
content: ''; content: '';
}
} }
} }

View File

@ -104,8 +104,10 @@ Ant Design layout component if it can not meet your needs, you can use the excel
| offset | the number of cells to the left of the grid spacing, no cell in grid spacing | number | 0 | | offset | the number of cells to the left of the grid spacing, no cell in grid spacing | number | 0 |
| push | the number of cells that raster move to the right | number | 0 | | push | the number of cells that raster move to the right | number | 0 |
| pull | the number of cells that raster move to the left | number | 0 | | pull | the number of cells that raster move to the left | number | 0 |
| xs | `<768px`, could be a `span` value or a object contain above props | number\|object | - | | xs | `<768px` and also default setting, could be a `span` value or a object contain above props | number\|object | - |
| sm | `≥768px`, could be a `span` value or a object contain above props | number\|object | - | | sm | `≥768px`, could be a `span` value or a object contain above props | number\|object | - |
| md | `≥992px`, could be a `span` value or a object contain above props | number\|object | - | | md | `≥992px`, could be a `span` value or a object contain above props | number\|object | - |
| lg | `≥1200px`, could be a `span` value or a object contain above props | number\|object | - | | lg | `≥1200px`, could be a `span` value or a object contain above props | number\|object | - |
| xl | `≥1600px`, could be a `span` value or a object contain above props | number\|object | - | | xl | `≥1600px`, could be a `span` value or a object contain above props | number\|object | - |
The breakpoints of responsive grid follow [BootStrap 3 media queries rules](http://getbootstrap.com/css/#grid-media-queries)(not contain `occasionally part`).

View File

@ -108,3 +108,5 @@ Ant Design 的布局组件若不能满足你的需求,你也可以直接使用
| md | `≥992px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number\|object | - | | md | `≥992px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number\|object | - |
| lg | `≥1200px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number\|object | - | | lg | `≥1200px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number\|object | - |
| xl | `≥1600px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number\|object | - | | xl | `≥1600px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number\|object | - |
响应式栅格的断点遵循了 [BootStrap 3 的规则](http://getbootstrap.com/css/#grid-media-queries)(不包含链接里 `occasionally` 的部分)。

View File

@ -16,17 +16,15 @@ Click the button to toggle between available and disabled states.
````jsx ````jsx
import { InputNumber, Button } from 'antd'; import { InputNumber, Button } from 'antd';
const Test = React.createClass({ class App extends React.Component {
getInitialState() { state = {
return { disabled: true,
disabled: true, };
}; toggle = () => {
},
toggle() {
this.setState({ this.setState({
disabled: !this.state.disabled, disabled: !this.state.disabled,
}); });
}, }
render() { render() {
return ( return (
<div> <div>
@ -36,8 +34,8 @@ const Test = React.createClass({
</div> </div>
</div> </div>
); );
}, }
}); }
ReactDOM.render(<Test />, mountNode); ReactDOM.render(<App />, mountNode);
```` ````

View File

@ -19,6 +19,6 @@ When a numeric value needs to be provided.
| value | current value | number | | | value | current value | number | |
| step | The number to which the current value is increased or decreased. It can be an integer or decimal. | number\|string | 1 | | step | The number to which the current value is increased or decreased. It can be an integer or decimal. | number\|string | 1 |
| defaultValue | initial value | number | | | defaultValue | initial value | number | |
| onChange | The callback triggered when the value is changed. | Function(value) | | | onChange | The callback triggered when the value is changed. | Function(value: number | string) | |
| disabled | disable the input | boolean | false | | disabled | disable the input | boolean | false |
| size | width of input box | string | none | | size | width of input box | string | none |

View File

@ -22,6 +22,6 @@ title: InputNumber
| value | 当前值 | number | | | value | 当前值 | number | |
| step | 每次改变步数,可以为小数 | number\|string | 1 | | step | 每次改变步数,可以为小数 | number\|string | 1 |
| defaultValue | 初始值 | number | | | defaultValue | 初始值 | number | |
| onChange | 变化回调 | Function(value) | | | onChange | 变化回调 | Function(value: number | string) | |
| disabled | 禁用 | boolean | false | | disabled | 禁用 | boolean | false |
| size | 输入框大小 | string | 无 | | size | 输入框大小 | string | 无 |

View File

@ -11,7 +11,7 @@ title:
## en-US ## en-US
Basic usage example Basic usage example.
````jsx ````jsx
import { Input } from 'antd'; import { Input } from 'antd';

View File

@ -17,3 +17,10 @@
.@{ant-prefix}-input-preSuffix-wrapper { .@{ant-prefix}-input-preSuffix-wrapper {
.input-preSuffix-wrapper(~"@{ant-prefix}-input"); .input-preSuffix-wrapper(~"@{ant-prefix}-input");
} }
// chrome only hack, fix https://github.com/ant-design/ant-design/issues/4987
@media all and (-webkit-min-device-pixel-ratio: 0) and (min-resolution: .001dpcm) {
input.@{ant-prefix}-input {
line-height: inherit;
}
}

View File

@ -69,7 +69,7 @@ exports[`test renders ./components/layout/demo/basic.md correctly 1`] = `
Sider Sider
</div> </div>
<div <div
class="ant-layout-content"> class="ant-layout">
<div <div
class="ant-layout-header"> class="ant-layout-header">
Header Header

View File

@ -18,40 +18,40 @@ import { Layout } from 'antd';
const { Header, Footer, Sider, Content } = Layout; const { Header, Footer, Sider, Content } = Layout;
ReactDOM.render( ReactDOM.render(
<div> <div>
<Layout>
<Header>Header</Header>
<Content>Content</Content>
<Footer>Footer</Footer>
</Layout>
<Layout>
<Header>Header</Header>
<Layout> <Layout>
<Sider>Sider</Sider>
<Content>Content</Content>
</Layout>
<Footer>Footer</Footer>
</Layout>
<Layout>
<Header>Header</Header>
<Layout>
<Content>Content</Content>
<Sider>Sider</Sider>
</Layout>
<Footer>Footer</Footer>
</Layout>
<Layout>
<Sider>Sider</Sider>
<Content>
<Header>Header</Header> <Header>Header</Header>
<Content>Content</Content> <Content>Content</Content>
<Footer>Footer</Footer> <Footer>Footer</Footer>
</Content> </Layout>
</Layout>
</div> <Layout>
<Header>Header</Header>
<Layout>
<Sider>Sider</Sider>
<Content>Content</Content>
</Layout>
<Footer>Footer</Footer>
</Layout>
<Layout>
<Header>Header</Header>
<Layout>
<Content>Content</Content>
<Sider>Sider</Sider>
</Layout>
<Footer>Footer</Footer>
</Layout>
<Layout>
<Sider>Sider</Sider>
<Layout>
<Header>Header</Header>
<Content>Content</Content>
<Footer>Footer</Footer>
</Layout>
</Layout>
</div>
, mountNode); , mountNode);
```` ````

View File

@ -96,6 +96,7 @@ ReactDOM.render(<SiderDemo />, mountNode);
#components-layout-demo-side .ant-layout-sider-collapsed .anticon { #components-layout-demo-side .ant-layout-sider-collapsed .anticon {
font-size: 16px; font-size: 16px;
margin-left: 8px;
} }
#components-layout-demo-side .ant-layout-sider-collapsed .nav-text { #components-layout-demo-side .ant-layout-sider-collapsed .nav-text {
@ -104,5 +105,5 @@ ReactDOM.render(<SiderDemo />, mountNode);
#components-layout-demo-side .ant-layout-sider-collapsed .ant-menu-submenu-vertical > .ant-menu-submenu-title:after { #components-layout-demo-side .ant-layout-sider-collapsed .ant-menu-submenu-vertical > .ant-menu-submenu-title:after {
display: none; display: none;
} }
```` ````

View File

@ -9,11 +9,11 @@ When you are handling the overall layout of a page, this component might be help
## Overview ## Overview
- `Layout`: The layout wrapper, in which `Header` `Sider` `Content` `Footer` or `Layout` itself can be nested. - `Layout`: The layout wrapper, in which `Header` `Sider` `Content` `Footer` or `Layout` itself can be nested, and can be placed in any parent container.
- `Header`: The top layout with default style. - `Header`: The top layout with default style, in which any element can be nested, and must be placed in `Layout`.
- `Sider`: The sidebar with default style and basic functions. - `Sider`: The sidebar with default style and basic functions, in which any element can be nested, and must be placed in `Layout`.
- `Content`: The content layout with default style. - `Content`: The content layout with default style, in which any element can be nested, and must be placed in `Layout`.
- `Footer`: The bottom layout with default style. - `Footer`: The bottom layout with default style, in which any element can be nested, and must be placed in `Layout`.
> Base on `flex layout`, please pay attention to the [compatibility](http://caniuse.com/#search=flex). > Base on `flex layout`, please pay attention to the [compatibility](http://caniuse.com/#search=flex).

View File

@ -10,11 +10,11 @@ title: Layout
## 概述 ## 概述
- `Layout`:布局容器,其下可嵌套 `Header` `Sider` `Content` `Footer``Layout` 本身。 - `Layout`:布局容器,其下可嵌套 `Header` `Sider` `Content` `Footer``Layout` 本身,可以放在任何父容器中
- `Header`:顶部布局,自带默认样式。 - `Header`:顶部布局,自带默认样式,其下可嵌套任何元素,只能放在 `Layout`
- `Sider`:侧边栏,自带默认样式及基本功能。 - `Sider`:侧边栏,自带默认样式及基本功能,其下可嵌套任何元素,只能放在 `Layout`
- `Content`:内容部分,自带默认样式。 - `Content`:内容部分,自带默认样式,其下可嵌套任何元素,只能放在 `Layout`
- `Footer`:底部布局,自带默认样式。 - `Footer`:底部布局,自带默认样式,其下可嵌套任何元素,只能放在 `Layout`
> 注意:采用 flex 布局实现,请注意[浏览器兼容性](http://caniuse.com/#search=flex)问题。 > 注意:采用 flex 布局实现,请注意[浏览器兼容性](http://caniuse.com/#search=flex)问题。

View File

@ -36,18 +36,16 @@ const columns = [{
dataIndex: 'age', dataIndex: 'age',
}]; }];
const Page = React.createClass({ class Page extends React.Component {
getInitialState() { state = {
return { visible: false,
visible: false, }
}; showModal = () => {
},
showModal() {
this.setState({ visible: true }); this.setState({ visible: true });
}, }
hideModal() { hideModal = () => {
this.setState({ visible: false }); this.setState({ visible: false });
}, }
render() { render() {
const info = () => { const info = () => {
Modal.info({ Modal.info({
@ -102,16 +100,17 @@ const Page = React.createClass({
</Modal> </Modal>
</div> </div>
); );
}, }
}); }
const App = React.createClass({ class App extends React.Component {
getInitialState() { constructor() {
return { super();
this.state = {
locale: enUS, locale: enUS,
}; };
}, }
changeLocale(e) { changeLocale = (e) => {
const localeValue = e.target.value; const localeValue = e.target.value;
this.setState({ locale: localeValue }); this.setState({ locale: localeValue });
if (!localeValue) { if (!localeValue) {
@ -119,7 +118,7 @@ const App = React.createClass({
} else { } else {
moment.locale('en'); moment.locale('en');
} }
}, }
render() { render() {
return ( return (
<div> <div>
@ -133,8 +132,8 @@ const App = React.createClass({
<LocaleProvider locale={this.state.locale}><Page /></LocaleProvider> <LocaleProvider locale={this.state.locale}><Page /></LocaleProvider>
</div> </div>
); );
}, }
}); }
ReactDOM.render(<App />, mountNode); ReactDOM.render(<App />, mountNode);
```` ````

View File

@ -17,13 +17,11 @@ Wrap your app with `LocaleProvider`, and apply the corresponding language packag
import { Pagination, LocaleProvider } from 'antd'; import { Pagination, LocaleProvider } from 'antd';
import enUS from 'antd/lib/locale-provider/en_US'; import enUS from 'antd/lib/locale-provider/en_US';
function App() { const App = () => (
return ( <div>
<div> <Pagination defaultCurrent={1} total={50} showSizeChanger />
<Pagination defaultCurrent={1} total={50} showSizeChanger /> </div>
</div> );
);
}
ReactDOM.render( ReactDOM.render(
<LocaleProvider locale={enUS}> <LocaleProvider locale={enUS}>

View File

@ -1,6 +1,6 @@
--- ---
order: 1 order: 1
title: title:
zh-CN: 异步加载 zh-CN: 异步加载
en-US: Asynchronous loading en-US: Asynchronous loading
--- ---
@ -17,19 +17,18 @@ async
import { Mention } from 'antd'; import { Mention } from 'antd';
const users = ['afc163', 'benjycui', 'yiminghe', 'jljsj33', 'dqaria', 'RaoHai']; const users = ['afc163', 'benjycui', 'yiminghe', 'jljsj33', 'dqaria', 'RaoHai'];
const AsyncMention = React.createClass({
getInitialState() { class AsyncMention extends React.Component {
return { state = {
suggestions: [], suggestions: [],
loading: false, loading: false,
}; }
}, fetchSuggestions = (value, callback) => {
fetchSuggestions(value, callback) {
setTimeout(() => { setTimeout(() => {
callback(users.filter(item => item.indexOf(value) !== -1)); callback(users.filter(item => item.indexOf(value) !== -1));
}, 500); }, 500);
}, }
onSearchChange(value) { onSearchChange = (value) => {
this.fetchSuggestions(value, (suggestions) => { this.fetchSuggestions(value, (suggestions) => {
this.setState({ this.setState({
suggestions, suggestions,
@ -39,7 +38,7 @@ const AsyncMention = React.createClass({
this.setState({ this.setState({
loading: true, loading: true,
}); });
}, }
render() { render() {
const { suggestions, loading } = this.state; const { suggestions, loading } = this.state;
return ( return (
@ -50,11 +49,8 @@ const AsyncMention = React.createClass({
onSearchChange={this.onSearchChange} onSearchChange={this.onSearchChange}
/> />
); );
}, }
}); }
ReactDOM.render( ReactDOM.render(<AsyncMention />, mountNode);
<AsyncMention />,
mountNode
);
```` ````

View File

@ -1,6 +1,6 @@
--- ---
order: 3 order: 3
title: title:
zh-CN: 头像 zh-CN: 头像
en-US: Icon Image en-US: Icon Image
--- ---
@ -26,18 +26,15 @@ const webFrameworks = [
{ name: 'Flask', type: 'Python', icon: 'https://zos.alipayobjects.com/rmsportal/xaypBUijfnpAlXE.png' }, { name: 'Flask', type: 'Python', icon: 'https://zos.alipayobjects.com/rmsportal/xaypBUijfnpAlXE.png' },
]; ];
const CustomNavMention = React.createClass({ class CustomNavMention extends React.Component {
getInitialState() { state = {
return { suggestions: [],
suggestions: [], }
}; onSearchChange = (value) => {
},
onSearchChange(value) {
const searchValue = value.toLowerCase(); const searchValue = value.toLowerCase();
const filtered = webFrameworks.filter(item => const filtered = webFrameworks.filter(item =>
item.name.toLowerCase().indexOf(searchValue) !== -1 item.name.toLowerCase().indexOf(searchValue) !== -1
); );
const suggestions = filtered.map(suggestion => const suggestions = filtered.map(suggestion =>
<Nav value={suggestion.name} data={suggestion} disabled={suggestion.disabled}> <Nav value={suggestion.name} data={suggestion} disabled={suggestion.disabled}>
<span> <span>
@ -45,10 +42,8 @@ const CustomNavMention = React.createClass({
{suggestion.name} - {suggestion.type} {suggestion.name} - {suggestion.type}
</span> </span>
</Nav>); </Nav>);
this.setState({ this.setState({ suggestions });
suggestions, }
});
},
render() { render() {
const { suggestions } = this.state; const { suggestions } = this.state;
return ( return (
@ -58,11 +53,8 @@ const CustomNavMention = React.createClass({
onSearchChange={this.onSearchChange} onSearchChange={this.onSearchChange}
/> />
); );
}, }
}); }
ReactDOM.render( ReactDOM.render(<CustomNavMention />, mountNode);
<CustomNavMention />,
mountNode
);
```` ````

View File

@ -17,25 +17,25 @@ Controlled mode.
import { Mention } from 'antd'; import { Mention } from 'antd';
const { toEditorState } = Mention; const { toEditorState } = Mention;
const App = React.createClass({ class App extends React.Component {
getInitialState() { state = {
return { value: toEditorState('@afc163'),
value: toEditorState('@afc163'), }
}; handleChange = (editorState) => {
},
handleChange(editorState) {
this.setState({ this.setState({
value: editorState, value: editorState,
}); });
}, }
render() { render() {
return (<Mention return (
suggestions={['afc163', 'benjycui', 'yiminghe', 'RaoHai', '中文', 'にほんご']} <Mention
value={this.state.value} suggestions={['afc163', 'benjycui', 'yiminghe', 'RaoHai', '中文', 'にほんご']}
onChange={this.handleChange} value={this.state.value}
/>); onChange={this.handleChange}
}, />
}); );
}
}
ReactDOM.render(<App />, mountNode); ReactDOM.render(<App />, mountNode);
```` ````

View File

@ -7,28 +7,26 @@ title:
## zh-CN ## zh-CN
受控模式,例如配合 Form 使用 受控模式,例如配合 Form 使用
## en-US ## en-US
Controlled mode, for example, to work with `Form` . Controlled mode, for example, to work with `Form`.
````jsx ````jsx
import { Mention, Form, Button } from 'antd'; import { Mention, Form, Button } from 'antd';
const { toEditorState, getMentions } = Mention; const { toEditorState, getMentions } = Mention;
const FormItem = Form.Item; const FormItem = Form.Item;
let App = React.createClass({ class App extends React.Component {
getInitialState() { state = {
return { initValue: toEditorState('@afc163'),
initValue: toEditorState('@afc163'), }
}; handleReset = (e) => {
},
handleReset(e) {
e.preventDefault(); e.preventDefault();
this.props.form.resetFields(); this.props.form.resetFields();
}, }
handleSubmit(e) { handleSubmit = (e) => {
e.preventDefault(); e.preventDefault();
this.props.form.validateFields((errors, values) => { this.props.form.validateFields((errors, values) => {
if (errors) { if (errors) {
@ -38,8 +36,8 @@ let App = React.createClass({
console.log('Submit!!!'); console.log('Submit!!!');
console.log(values); console.log(values);
}); });
}, }
checkMention(rule, value, callback) { checkMention = (rule, value, callback) => {
const { getFieldValue } = this.props.form; const { getFieldValue } = this.props.form;
const mentions = getMentions(getFieldValue('mention')); const mentions = getMentions(getFieldValue('mention'));
if (mentions.length < 2) { if (mentions.length < 2) {
@ -47,7 +45,7 @@ let App = React.createClass({
} else { } else {
callback(); callback();
} }
}, }
render() { render() {
const { getFieldDecorator, getFieldValue } = this.props.form; const { getFieldDecorator, getFieldValue } = this.props.form;
console.log('>> render', getFieldValue('mention') === this.state.initValue); console.log('>> render', getFieldValue('mention') === this.state.initValue);
@ -77,10 +75,10 @@ let App = React.createClass({
</FormItem> </FormItem>
</Form> </Form>
); );
}, }
}); }
App = Form.create()(App); const FormDemo = Form.create()(App);
ReactDOM.render(<App />, mountNode); ReactDOM.render(<FormDemo />, mountNode);
```` ````

View File

@ -1,6 +1,6 @@
--- ---
order: 2 order: 2
title: title:
zh-CN: 自定义建议 zh-CN: 自定义建议
en-US: Customize Suggestion en-US: Customize Suggestion
--- ---
@ -30,23 +30,22 @@ const webFrameworks = [
function onSelect(suggestion, data) { function onSelect(suggestion, data) {
console.log('onSelect', suggestion, data); console.log('onSelect', suggestion, data);
} }
const CustomNavMention = React.createClass({
getInitialState() { class CustomNavMention extends React.Component {
return { state = {
suggestions: [], suggestions: [],
}; }
}, onSearchChange = (value) => {
onSearchChange(value) {
const searchValue = value.toLowerCase(); const searchValue = value.toLowerCase();
const filtered = webFrameworks.filter(item => const filtered = webFrameworks.filter(item =>
item.name.toLowerCase().indexOf(searchValue) !== -1 item.name.toLowerCase().indexOf(searchValue) !== -1
); );
const suggestions = filtered.map(suggestion => const suggestions = filtered.map(suggestion =>
<Nav value={suggestion.name} data={suggestion}> <Nav value={suggestion.name} data={suggestion}>
<span>{suggestion.name} - {suggestion.type} </span> <span>{suggestion.name} - {suggestion.type}</span>
</Nav>); </Nav>);
this.setState({ suggestions }); this.setState({ suggestions });
}, }
render() { render() {
const { suggestions } = this.state; const { suggestions } = this.state;
return ( return (
@ -58,11 +57,8 @@ const CustomNavMention = React.createClass({
onSelect={onSelect} onSelect={onSelect}
/> />
); );
}, }
}); }
ReactDOM.render( ReactDOM.render(<CustomNavMention />, mountNode);
<CustomNavMention />,
mountNode
);
```` ````

View File

@ -25,23 +25,28 @@ function onSelect(suggestion) {
console.log('onSelect', suggestion); console.log('onSelect', suggestion);
} }
const PopoverContainer = React.createClass({ class PopoverContainer extends React.Component {
getSuggestionContainer() { getSuggestionContainer = () => {
return this.popover.getPopupDomNode(); return this.popover.getPopupDomNode();
}, }
render() { render() {
const mention = (<Mention const mention = (
style={{ width: '100%', height: 100 }} <Mention
onChange={onChange} style={{ width: '100%', height: 100 }}
defaultValue={toEditorState('@afc163')} onChange={onChange}
suggestions={['afc163', 'benjycui', 'yiminghe', 'RaoHai', '中文', 'にほんご']} defaultValue={toEditorState('@afc163')}
onSelect={onSelect} suggestions={['afc163', 'benjycui', 'yiminghe', 'RaoHai', '中文', 'にほんご']}
getSuggestionContainer={this.getSuggestionContainer} onSelect={onSelect}
/>); getSuggestionContainer={this.getSuggestionContainer}
return (<Popover trigger="click" content={mention} title="Title" ref={popover => this.popover = popover}> />
<Button type="primary">Click Me</Button> );
</Popover>); return (
}, <Popover trigger="click" content={mention} title="Title" ref={popover => this.popover = popover}>
}); <Button type="primary">Click Me</Button>
</Popover>
);
}
}
ReactDOM.render(<PopoverContainer />, mountNode); ReactDOM.render(<PopoverContainer />, mountNode);
```` ````

View File

@ -18,18 +18,16 @@ import { Menu, Icon } from 'antd';
const SubMenu = Menu.SubMenu; const SubMenu = Menu.SubMenu;
const MenuItemGroup = Menu.ItemGroup; const MenuItemGroup = Menu.ItemGroup;
const App = React.createClass({ class App extends React.Component {
getInitialState() { state = {
return { current: 'mail',
current: 'mail', }
}; handleClick = (e) => {
},
handleClick(e) {
console.log('click ', e); console.log('click ', e);
this.setState({ this.setState({
current: e.key, current: e.key,
}); });
}, }
render() { render() {
return ( return (
<Menu <Menu
@ -58,8 +56,8 @@ const App = React.createClass({
</Menu.Item> </Menu.Item>
</Menu> </Menu>
); );
}, }
}); }
ReactDOM.render(<App />, mountNode); ReactDOM.render(<App />, mountNode);
```` ````

View File

@ -21,18 +21,16 @@ Click the menu and you will see that all the other menus gets collapsed to keep
import { Menu, Icon } from 'antd'; import { Menu, Icon } from 'antd';
const SubMenu = Menu.SubMenu; const SubMenu = Menu.SubMenu;
const Sider = React.createClass({ class Sider extends React.Component {
getInitialState() { state = {
return { current: '1',
current: '1', openKeys: [],
openKeys: [], }
}; handleClick = (e) => {
},
handleClick(e) {
console.log('Clicked: ', e); console.log('Clicked: ', e);
this.setState({ current: e.key }); this.setState({ current: e.key });
}, }
onOpenChange(openKeys) { onOpenChange = (openKeys) => {
const state = this.state; const state = this.state;
const latestOpenKey = openKeys.find(key => !(state.openKeys.indexOf(key) > -1)); const latestOpenKey = openKeys.find(key => !(state.openKeys.indexOf(key) > -1));
const latestCloseKey = state.openKeys.find(key => !(openKeys.indexOf(key) > -1)); const latestCloseKey = state.openKeys.find(key => !(openKeys.indexOf(key) > -1));
@ -45,13 +43,13 @@ const Sider = React.createClass({
nextOpenKeys = this.getAncestorKeys(latestCloseKey); nextOpenKeys = this.getAncestorKeys(latestCloseKey);
} }
this.setState({ openKeys: nextOpenKeys }); this.setState({ openKeys: nextOpenKeys });
}, }
getAncestorKeys(key) { getAncestorKeys = (key) => {
const map = { const map = {
sub3: ['sub2'], sub3: ['sub2'],
}; };
return map[key] || []; return map[key] || [];
}, }
render() { render() {
return ( return (
<Menu <Menu
@ -84,7 +82,8 @@ const Sider = React.createClass({
</SubMenu> </SubMenu>
</Menu> </Menu>
); );
}, }
}); }
ReactDOM.render(<Sider />, mountNode); ReactDOM.render(<Sider />, mountNode);
```` ````

View File

@ -18,10 +18,10 @@ import { Menu, Icon } from 'antd';
const SubMenu = Menu.SubMenu; const SubMenu = Menu.SubMenu;
const MenuItemGroup = Menu.ItemGroup; const MenuItemGroup = Menu.ItemGroup;
const Sider = React.createClass({ class Sider extends React.Component {
handleClick(e) { handleClick = (e) => {
console.log('click ', e); console.log('click ', e);
}, }
render() { render() {
return ( return (
<Menu <Menu
@ -57,8 +57,8 @@ const Sider = React.createClass({
</SubMenu> </SubMenu>
</Menu> </Menu>
); );
}, }
}); }
ReactDOM.render(<Sider />, mountNode); ReactDOM.render(<Sider />, mountNode);
```` ````

View File

@ -18,17 +18,15 @@ import { Menu, Icon, Switch } from 'antd';
const SubMenu = Menu.SubMenu; const SubMenu = Menu.SubMenu;
const MenuItemGroup = Menu.ItemGroup; const MenuItemGroup = Menu.ItemGroup;
const Sider = React.createClass({ class Sider extends React.Component {
getInitialState() { state = {
return { mode: 'inline',
mode: 'inline', }
}; changeMode = (value) => {
},
changeMode(value) {
this.setState({ this.setState({
mode: value ? 'vertical' : 'inline', mode: value ? 'vertical' : 'inline',
}); });
}, }
render() { render() {
return ( return (
<div> <div>
@ -67,8 +65,8 @@ const Sider = React.createClass({
</Menu> </Menu>
</div> </div>
); );
}, }
}); }
ReactDOM.render(<Sider />, mountNode); ReactDOM.render(<Sider />, mountNode);
```` ````

View File

@ -17,24 +17,22 @@ There are two built-in themes: 'light' and 'dark'. The default value is 'light'.
import { Menu, Icon, Switch } from 'antd'; import { Menu, Icon, Switch } from 'antd';
const SubMenu = Menu.SubMenu; const SubMenu = Menu.SubMenu;
const Sider = React.createClass({ class Sider extends React.Component {
getInitialState() { state = {
return { theme: 'dark',
theme: 'dark', current: '1',
current: '1', }
}; changeTheme = (value) => {
},
changeTheme(value) {
this.setState({ this.setState({
theme: value ? 'dark' : 'light', theme: value ? 'dark' : 'light',
}); });
}, }
handleClick(e) { handleClick = (e) => {
console.log('click ', e); console.log('click ', e);
this.setState({ this.setState({
current: e.key, current: e.key,
}); });
}, }
render() { render() {
return ( return (
<div> <div>
@ -77,7 +75,8 @@ const Sider = React.createClass({
</Menu> </Menu>
</div> </div>
); );
}, }
}); }
ReactDOM.render(<Sider />, mountNode); ReactDOM.render(<Sider />, mountNode);
```` ````

View File

@ -75,12 +75,16 @@
&-item:hover, &-item:hover,
&-item-active, &-item-active,
&-submenu-open, &:not(&-inline) &-submenu-open,
&-submenu-active, &-submenu-active,
&-submenu-title:hover { &-submenu-title:hover {
color: @primary-color; color: @primary-color;
} }
&:not(&-inline) &-submenu-open {
z-index: @zindex-dropdown;
}
&-horizontal &-item, &-horizontal &-item,
&-horizontal &-submenu { &-horizontal &-submenu {
margin-top: -1px; margin-top: -1px;
@ -395,7 +399,7 @@
&-dark &-item:hover, &-dark &-item:hover,
&-dark &-item-active, &-dark &-item-active,
&-dark &-submenu-active, &-dark &-submenu-active,
&-dark &-submenu-open, &-dark:not(&-inline) &-submenu-open,
&-dark &-submenu-selected, &-dark &-submenu-selected,
&-dark &-submenu:hover, &-dark &-submenu:hover,
&-dark &-submenu-title:hover { &-dark &-submenu-title:hover {

View File

@ -55,13 +55,14 @@
&-notice.move-up-leave.move-up-leave-active { &-notice.move-up-leave.move-up-leave-active {
animation-name: MessageMoveOut; animation-name: MessageMoveOut;
overflow: hidden; overflow: hidden;
animation-duration: .3s;
} }
} }
@keyframes MessageMoveOut { @keyframes MessageMoveOut {
0% { 0% {
opacity: 1; opacity: 1;
max-height: 60px; max-height: 150px;
padding: 8px; padding: 8px;
} }
100% { 100% {

View File

@ -17,7 +17,7 @@ export interface ModalProps {
/** 是否显示右上角的关闭按钮*/ /** 是否显示右上角的关闭按钮*/
closable?: boolean; closable?: boolean;
/** 点击确定回调*/ /** 点击确定回调*/
onOk?: () => void; onOk?: (e: React.MouseEvent<any>) => void;
/** 点击模态框右上角叉、取消按钮、Props.maskClosable 值为 true 时的遮罩层或键盘按下 Esc 时的回调*/ /** 点击模态框右上角叉、取消按钮、Props.maskClosable 值为 true 时的遮罩层或键盘按下 Esc 时的回调*/
onCancel?: (e: React.MouseEvent<any>) => void; onCancel?: (e: React.MouseEvent<any>) => void;
afterClose?: () => void; afterClose?: () => void;
@ -89,10 +89,10 @@ export default class Modal extends React.Component<ModalProps, any> {
} }
} }
handleOk = () => { handleOk = (e) => {
const onOk = this.props.onOk; const onOk = this.props.onOk;
if (onOk) { if (onOk) {
onOk(); onOk(e);
} }
} }

View File

@ -1,6 +1,6 @@
--- ---
order: 1 order: 1
title: title:
zh-CN: 异步关闭 zh-CN: 异步关闭
en-US: Asynchronously close en-US: Asynchronously close
--- ---
@ -17,19 +17,17 @@ you can use this pattern when you submit a form.
````jsx ````jsx
import { Modal, Button } from 'antd'; import { Modal, Button } from 'antd';
const Test = React.createClass({ class App extends React.Component {
getInitialState() { state = {
return { ModalText: 'Content of the modal dialog',
ModalText: 'Content of the modal dialog', visible: false,
visible: false, }
}; showModal = () => {
},
showModal() {
this.setState({ this.setState({
visible: true, visible: true,
}); });
}, }
handleOk() { handleOk = () => {
this.setState({ this.setState({
ModalText: 'The modal dialog will be closed after two seconds', ModalText: 'The modal dialog will be closed after two seconds',
confirmLoading: true, confirmLoading: true,
@ -40,13 +38,13 @@ const Test = React.createClass({
confirmLoading: false, confirmLoading: false,
}); });
}, 2000); }, 2000);
}, }
handleCancel() { handleCancel = () => {
console.log('Clicked cancel button'); console.log('Clicked cancel button');
this.setState({ this.setState({
visible: false, visible: false,
}); });
}, }
render() { render() {
return ( return (
<div> <div>
@ -61,8 +59,8 @@ const Test = React.createClass({
</Modal> </Modal>
</div> </div>
); );
}, }
}); }
ReactDOM.render(<Test />, mountNode); ReactDOM.render(<App />, mountNode);
```` ````

View File

@ -16,27 +16,25 @@ Basic modal dialog.
````jsx ````jsx
import { Modal, Button } from 'antd'; import { Modal, Button } from 'antd';
const App = React.createClass({ class App extends React.Component {
getInitialState() { state = { visible: false }
return { visible: false }; showModal = () => {
},
showModal() {
this.setState({ this.setState({
visible: true, visible: true,
}); });
}, }
handleOk() { handleOk = (e) => {
console.log('Clicked OK');
this.setState({
visible: false,
});
},
handleCancel(e) {
console.log(e); console.log(e);
this.setState({ this.setState({
visible: false, visible: false,
}); });
}, }
handleCancel = (e) => {
console.log(e);
this.setState({
visible: false,
});
}
render() { render() {
return ( return (
<div> <div>
@ -50,8 +48,8 @@ const App = React.createClass({
</Modal> </Modal>
</div> </div>
); );
}, }
}); }
ReactDOM.render(<App />, mountNode); ReactDOM.render(<App />, mountNode);
```` ````

View File

@ -22,27 +22,25 @@ You could set `footer` to `null` if you don't need default footer buttons.
````jsx ````jsx
import { Modal, Button } from 'antd'; import { Modal, Button } from 'antd';
const Test = React.createClass({ class App extends React.Component {
getInitialState() { state = {
return { loading: false,
loading: false, visible: false,
visible: false, }
}; showModal = () => {
},
showModal() {
this.setState({ this.setState({
visible: true, visible: true,
}); });
}, }
handleOk() { handleOk = () => {
this.setState({ loading: true }); this.setState({ loading: true });
setTimeout(() => { setTimeout(() => {
this.setState({ loading: false, visible: false }); this.setState({ loading: false, visible: false });
}, 3000); }, 3000);
}, }
handleCancel() { handleCancel = () => {
this.setState({ visible: false }); this.setState({ visible: false });
}, }
render() { render() {
return ( return (
<div> <div>
@ -69,8 +67,8 @@ const Test = React.createClass({
</Modal> </Modal>
</div> </div>
); );
}, }
}); }
ReactDOM.render(<Test />, mountNode); ReactDOM.render(<App />, mountNode);
```` ````

View File

@ -1,6 +1,6 @@
--- ---
order: 6 order: 6
title: title:
zh-CN: 国际化 zh-CN: 国际化
en-US: Internationalization en-US: Internationalization
--- ---
@ -16,25 +16,23 @@ To customize the text of the buttons, you need to set `okText` and `cancelText`
````jsx ````jsx
import { Modal, Button } from 'antd'; import { Modal, Button } from 'antd';
const LocalizedModal = React.createClass({ class LocalizedModal extends React.Component {
getInitialState() { state = { visible: false }
return { visible: false }; showModal = () => {
},
showModal() {
this.setState({ this.setState({
visible: true, visible: true,
}); });
}, }
handleOk() { handleOk = () => {
this.setState({ this.setState({
visible: false, visible: false,
}); });
}, }
handleCancel() { handleCancel = () => {
this.setState({ this.setState({
visible: false, visible: false,
}); });
}, }
render() { render() {
return ( return (
<div> <div>
@ -49,8 +47,8 @@ const LocalizedModal = React.createClass({
</Modal> </Modal>
</div> </div>
); );
}, }
}); }
function confirm() { function confirm() {
Modal.confirm({ Modal.confirm({
@ -67,4 +65,3 @@ ReactDOM.render(<div>
<Button onClick={confirm}>confirm</Button> <Button onClick={confirm}>confirm</Button>
</div>, mountNode); </div>, mountNode);
```` ````

View File

@ -17,19 +17,17 @@ set position of modal dialog.
````jsx ````jsx
import { Modal, Button } from 'antd'; import { Modal, Button } from 'antd';
const App = React.createClass({ class App extends React.Component {
getInitialState() { state = {
return { modal1Visible: false,
modal1Visible: false, modal2Visible: false,
modal2Visible: false, }
};
},
setModal1Visible(modal1Visible) { setModal1Visible(modal1Visible) {
this.setState({ modal1Visible }); this.setState({ modal1Visible });
}, }
setModal2Visible(modal2Visible) { setModal2Visible(modal2Visible) {
this.setState({ modal2Visible }); this.setState({ modal2Visible });
}, }
render() { render() {
return ( return (
<div> <div>
@ -60,8 +58,8 @@ const App = React.createClass({
</Modal> </Modal>
</div> </div>
); );
}, }
}); }
ReactDOM.render(<App />, mountNode); ReactDOM.render(<App />, mountNode);
```` ````

View File

@ -22,7 +22,7 @@ and so on.
| confirmLoading | Determine whether to apply loading visual effect for OK button or not | boolean | no | | confirmLoading | Determine whether to apply loading visual effect for OK button or not | boolean | no |
| title | The modal dialog's title | string\|ReactNode | no | | title | The modal dialog's title | string\|ReactNode | no |
| closable | Determine whether a close (x) button is visible on top right of the modal dialog or not | boolean | true | | closable | Determine whether a close (x) button is visible on top right of the modal dialog or not | boolean | true |
| onOk | Specify a function that will be called when a user clicked OK button | function | no | | onOk | Specify a function that will be called when a user clicked OK button | function(e) | no |
| onCancel | Specify a function that will be called when a user clicked mask, close button on top right or cancel button | function(e) | no | | onCancel | Specify a function that will be called when a user clicked mask, close button on top right or cancel button | function(e) | no |
| width | Width of a modal dialog | string\|number | 520 | | width | Width of a modal dialog | string\|number | 520 |
| footer | Footer content, set as `footer={null}` when you don't need default buttons | string\|ReactNode | OK and cancel button | | footer | Footer content, set as `footer={null}` when you don't need default buttons | string\|ReactNode | OK and cancel button |

View File

@ -21,7 +21,7 @@ title: Modal
| confirmLoading | 确定按钮 loading | boolean | 无 | | confirmLoading | 确定按钮 loading | boolean | 无 |
| title | 标题 | string\|ReactNode | 无 | | title | 标题 | string\|ReactNode | 无 |
| closable | 是否显示右上角的关闭按钮 | boolean | true | | closable | 是否显示右上角的关闭按钮 | boolean | true |
| onOk | 点击确定回调 | function | 无 | | onOk | 点击确定回调 | function(e) | 无 |
| onCancel | 点击遮罩层或右上角叉或取消按钮的回调 | function(e) | 无 | | onCancel | 点击遮罩层或右上角叉或取消按钮的回调 | function(e) | 无 |
| width | 宽度 | string\|number | 520 | | width | 宽度 | string\|number | 520 |
| footer | 底部内容,当不需要默认底部按钮时,可以设为 `footer={null}` | string\|ReactNode | 确定取消按钮 | | footer | 底部内容,当不需要默认底部按钮时,可以设为 `footer={null}` | string\|ReactNode | 确定取消按钮 |

View File

@ -16,22 +16,20 @@ Controlled page number.
````jsx ````jsx
import { Pagination } from 'antd'; import { Pagination } from 'antd';
const Container = React.createClass({ class App extends React.Component {
getInitialState() { state = {
return { current: 3,
current: 3, }
}; onChange = (page) => {
},
onChange(page) {
console.log(page); console.log(page);
this.setState({ this.setState({
current: page, current: page,
}); });
}, }
render() { render() {
return <Pagination current={this.state.current} onChange={this.onChange} total={50} />; return <Pagination current={this.state.current} onChange={this.onChange} total={50} />;
}, }
}); }
ReactDOM.render(<Container />, mountNode); ReactDOM.render(<App />, mountNode);
```` ````

View File

@ -17,20 +17,20 @@ You can show the total number of data by setting `showTotal`.
import { Pagination } from 'antd'; import { Pagination } from 'antd';
ReactDOM.render( ReactDOM.render(
<div> <div>
<Pagination <Pagination
total={85} total={85}
showTotal={total => `Total ${total} items`} showTotal={total => `Total ${total} items`}
pageSize={20} pageSize={20}
defaultCurrent={1} defaultCurrent={1}
/> />
<br /> <br />
<Pagination <Pagination
total={85} total={85}
showTotal={(total, range) => `${range[0]}-${range[1]} of ${total} items`} showTotal={(total, range) => `${range[0]}-${range[1]} of ${total} items`}
pageSize={20} pageSize={20}
defaultCurrent={1} defaultCurrent={1}
/> />
</div> </div>
, mountNode); , mountNode);
```` ````

View File

@ -16,11 +16,13 @@ The basic example.
````jsx ````jsx
import { Popconfirm, message } from 'antd'; import { Popconfirm, message } from 'antd';
function confirm() { function confirm(e) {
console.log(e);
message.success('Click on Yes'); message.success('Click on Yes');
} }
function cancel() { function cancel(e) {
console.log(e);
message.error('Click on No'); message.error('Click on No');
} }

View File

@ -16,25 +16,23 @@ Make it pop up under some conditions.
````jsx ````jsx
import { Popconfirm, Switch, message } from 'antd'; import { Popconfirm, Switch, message } from 'antd';
const App = React.createClass({ class App extends React.Component {
getInitialState() { state = {
return { visible: false,
visible: false, condition: true, // Whether meet the condition, if not show popconfirm.
condition: true, // Whether meet the condition, if not show popconfirm. }
}; changeCondition = (value) => {
},
changeCondition(value) {
this.setState({ condition: value }); this.setState({ condition: value });
}, }
confirm() { confirm = () => {
this.setState({ visible: false }); this.setState({ visible: false });
message.success('Next step.'); message.success('Next step.');
}, }
cancel() { cancel = () => {
this.setState({ visible: false }); this.setState({ visible: false });
message.error('Click on cancel.'); message.error('Click on cancel.');
}, }
handleVisibleChange(visible) { handleVisibleChange = (visible) => {
if (!visible) { if (!visible) {
this.setState({ visible }); this.setState({ visible });
return; return;
@ -46,7 +44,7 @@ const App = React.createClass({
} else { } else {
this.setState({ visible }); // show the popconfirm this.setState({ visible }); // show the popconfirm
} }
}, }
render() { render() {
return ( return (
<div> <div>
@ -63,8 +61,8 @@ const App = React.createClass({
Whether directly execute<Switch defaultChecked onChange={this.changeCondition} /> Whether directly execute<Switch defaultChecked onChange={this.changeCondition} />
</div> </div>
); );
}, }
}); }
ReactDOM.render(<App />, mountNode); ReactDOM.render(<App />, mountNode);
```` ````

View File

@ -17,8 +17,8 @@ The difference with `confirm` is more lightweight than the static popped full-sc
| Param | Description | Type | Default value | | Param | Description | Type | Default value |
|-----------|------------------------------------------|---------------|--------| |-----------|------------------------------------------|---------------|--------|
| title | title of the confirmation box | string\|ReactNode | none | | title | title of the confirmation box | string\|ReactNode | none |
| onConfirm | callback of confirmation | function | none | | onConfirm | callback of confirmation | function(e) | none |
| onCancel | callback of cancel | function | none | | onCancel | callback of cancel | function(e) | none |
| okText | text of the confirmation button | string | Confirm | | okText | text of the confirmation button | string | Confirm |
| cancelText| text of the cancel button | string | Cancel | | cancelText| text of the cancel button | string | Cancel |

View File

@ -6,8 +6,8 @@ import Button from '../button';
export interface PopconfirmProps extends AbstractTooltipProps { export interface PopconfirmProps extends AbstractTooltipProps {
title: React.ReactNode; title: React.ReactNode;
onConfirm?: () => void; onConfirm?: (e: React.MouseEvent<any>) => void;
onCancel?: () => void; onCancel?: (e: React.MouseEvent<any>) => void;
okText?: React.ReactNode; okText?: React.ReactNode;
cancelText?: React.ReactNode; cancelText?: React.ReactNode;
} }
@ -46,21 +46,21 @@ export default class Popconfirm extends React.Component<PopconfirmProps, any> {
} }
} }
confirm = () => { confirm = (e) => {
this.setVisible(false); this.setVisible(false);
const onConfirm = this.props.onConfirm; const onConfirm = this.props.onConfirm;
if (onConfirm) { if (onConfirm) {
onConfirm.call(this); onConfirm.call(this, e);
} }
} }
cancel = () => { cancel = (e) => {
this.setVisible(false); this.setVisible(false);
const onCancel = this.props.onCancel; const onCancel = this.props.onCancel;
if (onCancel) { if (onCancel) {
onCancel.call(this); onCancel.call(this, e);
} }
} }

View File

@ -18,8 +18,8 @@ title: Popconfirm
| 参数 | 说明 | 类型 | 默认值 | | 参数 | 说明 | 类型 | 默认值 |
|-----------|------------------------------------------|---------------|--------| |-----------|------------------------------------------|---------------|--------|
| title | 确认框的描述 | string\|ReactNode | 无 | | title | 确认框的描述 | string\|ReactNode | 无 |
| onConfirm | 点击确认的回调 | function | 无 | | onConfirm | 点击确认的回调 | function(e) | 无 |
| onCancel | 点击取消的回调 | function | 无 | | onCancel | 点击取消的回调 | function(e) | 无 |
| okText | 确认按钮文字 | string | 确定 | | okText | 确认按钮文字 | string | 确定 |
| cancelText| 取消按钮文字 | string | 取消 | | cancelText| 取消按钮文字 | string | 取消 |

View File

@ -1,2 +1,5 @@
import '../../style/index.less'; import '../../style/index.less';
// style dependencies
import '../../popover/style'; import '../../popover/style';
import '../../button/style';

View File

@ -16,20 +16,18 @@ Use `visible` prop to control the display of the card.
````jsx ````jsx
import { Popover, Button } from 'antd'; import { Popover, Button } from 'antd';
const App = React.createClass({ class App extends React.Component {
getInitialState() { state = {
return { visible: false,
visible: false, }
}; hide = () => {
},
hide() {
this.setState({ this.setState({
visible: false, visible: false,
}); });
}, }
handleVisibleChange(visible) { handleVisibleChange = (visible) => {
this.setState({ visible }); this.setState({ visible });
}, }
render() { render() {
return ( return (
<Popover <Popover
@ -42,8 +40,8 @@ const App = React.createClass({
<Button type="primary">Click me</Button> <Button type="primary">Click me</Button>
</Popover> </Popover>
); );
}, }
}); }
ReactDOM.render(<App />, mountNode); ReactDOM.render(<App />, mountNode);
```` ````

View File

@ -6,10 +6,10 @@ exports[`test renders ./components/progress/demo/circle.md correctly 1`] = `
class="ant-progress-inner" class="ant-progress-inner"
style="width:132px;height:132px;font-size:27.12px;"> style="width:132px;height:132px;font-size:27.12px;">
<svg <svg
class="rc-progress-circle " class="ant-progress-circle "
viewbox="0 0 100 100"> viewbox="0 0 100 100">
<path <path
class="rc-progress-circle-trail" class="ant-progress-circle-trail"
d="M 50,50 m 0,-47 d="M 50,50 m 0,-47
a 47,47 0 1 1 0,94 a 47,47 0 1 1 0,94
a 47,47 0 1 1 0,-94" a 47,47 0 1 1 0,-94"
@ -17,7 +17,7 @@ exports[`test renders ./components/progress/demo/circle.md correctly 1`] = `
stroke="#f3f3f3" stroke="#f3f3f3"
stroke-width="6" /> stroke-width="6" />
<path <path
class="rc-progress-circle-path" class="ant-progress-circle-path"
d="M 50,50 m 0,-47 d="M 50,50 m 0,-47
a 47,47 0 1 1 0,94 a 47,47 0 1 1 0,94
a 47,47 0 1 1 0,-94" a 47,47 0 1 1 0,-94"
@ -39,10 +39,10 @@ exports[`test renders ./components/progress/demo/circle.md correctly 1`] = `
class="ant-progress-inner" class="ant-progress-inner"
style="width:132px;height:132px;font-size:27.12px;"> style="width:132px;height:132px;font-size:27.12px;">
<svg <svg
class="rc-progress-circle " class="ant-progress-circle "
viewbox="0 0 100 100"> viewbox="0 0 100 100">
<path <path
class="rc-progress-circle-trail" class="ant-progress-circle-trail"
d="M 50,50 m 0,-47 d="M 50,50 m 0,-47
a 47,47 0 1 1 0,94 a 47,47 0 1 1 0,94
a 47,47 0 1 1 0,-94" a 47,47 0 1 1 0,-94"
@ -50,7 +50,7 @@ exports[`test renders ./components/progress/demo/circle.md correctly 1`] = `
stroke="#f3f3f3" stroke="#f3f3f3"
stroke-width="6" /> stroke-width="6" />
<path <path
class="rc-progress-circle-path" class="ant-progress-circle-path"
d="M 50,50 m 0,-47 d="M 50,50 m 0,-47
a 47,47 0 1 1 0,94 a 47,47 0 1 1 0,94
a 47,47 0 1 1 0,-94" a 47,47 0 1 1 0,-94"
@ -73,10 +73,10 @@ exports[`test renders ./components/progress/demo/circle.md correctly 1`] = `
class="ant-progress-inner" class="ant-progress-inner"
style="width:132px;height:132px;font-size:27.12px;"> style="width:132px;height:132px;font-size:27.12px;">
<svg <svg
class="rc-progress-circle " class="ant-progress-circle "
viewbox="0 0 100 100"> viewbox="0 0 100 100">
<path <path
class="rc-progress-circle-trail" class="ant-progress-circle-trail"
d="M 50,50 m 0,-47 d="M 50,50 m 0,-47
a 47,47 0 1 1 0,94 a 47,47 0 1 1 0,94
a 47,47 0 1 1 0,-94" a 47,47 0 1 1 0,-94"
@ -84,7 +84,7 @@ exports[`test renders ./components/progress/demo/circle.md correctly 1`] = `
stroke="#f3f3f3" stroke="#f3f3f3"
stroke-width="6" /> stroke-width="6" />
<path <path
class="rc-progress-circle-path" class="ant-progress-circle-path"
d="M 50,50 m 0,-47 d="M 50,50 m 0,-47
a 47,47 0 1 1 0,94 a 47,47 0 1 1 0,94
a 47,47 0 1 1 0,-94" a 47,47 0 1 1 0,-94"
@ -112,10 +112,10 @@ exports[`test renders ./components/progress/demo/circle-dynamic.md correctly 1`]
class="ant-progress-inner" class="ant-progress-inner"
style="width:132px;height:132px;font-size:27.12px;"> style="width:132px;height:132px;font-size:27.12px;">
<svg <svg
class="rc-progress-circle " class="ant-progress-circle "
viewbox="0 0 100 100"> viewbox="0 0 100 100">
<path <path
class="rc-progress-circle-trail" class="ant-progress-circle-trail"
d="M 50,50 m 0,-47 d="M 50,50 m 0,-47
a 47,47 0 1 1 0,94 a 47,47 0 1 1 0,94
a 47,47 0 1 1 0,-94" a 47,47 0 1 1 0,-94"
@ -123,7 +123,7 @@ exports[`test renders ./components/progress/demo/circle-dynamic.md correctly 1`]
stroke="#f3f3f3" stroke="#f3f3f3"
stroke-width="6" /> stroke-width="6" />
<path <path
class="rc-progress-circle-path" class="ant-progress-circle-path"
d="M 50,50 m 0,-47 d="M 50,50 m 0,-47
a 47,47 0 1 1 0,94 a 47,47 0 1 1 0,94
a 47,47 0 1 1 0,-94" a 47,47 0 1 1 0,-94"
@ -165,10 +165,10 @@ exports[`test renders ./components/progress/demo/circle-mini.md correctly 1`] =
class="ant-progress-inner" class="ant-progress-inner"
style="width:80px;height:80px;font-size:18.8px;"> style="width:80px;height:80px;font-size:18.8px;">
<svg <svg
class="rc-progress-circle " class="ant-progress-circle "
viewbox="0 0 100 100"> viewbox="0 0 100 100">
<path <path
class="rc-progress-circle-trail" class="ant-progress-circle-trail"
d="M 50,50 m 0,-47 d="M 50,50 m 0,-47
a 47,47 0 1 1 0,94 a 47,47 0 1 1 0,94
a 47,47 0 1 1 0,-94" a 47,47 0 1 1 0,-94"
@ -176,7 +176,7 @@ exports[`test renders ./components/progress/demo/circle-mini.md correctly 1`] =
stroke="#f3f3f3" stroke="#f3f3f3"
stroke-width="6" /> stroke-width="6" />
<path <path
class="rc-progress-circle-path" class="ant-progress-circle-path"
d="M 50,50 m 0,-47 d="M 50,50 m 0,-47
a 47,47 0 1 1 0,94 a 47,47 0 1 1 0,94
a 47,47 0 1 1 0,-94" a 47,47 0 1 1 0,-94"
@ -198,10 +198,10 @@ exports[`test renders ./components/progress/demo/circle-mini.md correctly 1`] =
class="ant-progress-inner" class="ant-progress-inner"
style="width:80px;height:80px;font-size:18.8px;"> style="width:80px;height:80px;font-size:18.8px;">
<svg <svg
class="rc-progress-circle " class="ant-progress-circle "
viewbox="0 0 100 100"> viewbox="0 0 100 100">
<path <path
class="rc-progress-circle-trail" class="ant-progress-circle-trail"
d="M 50,50 m 0,-47 d="M 50,50 m 0,-47
a 47,47 0 1 1 0,94 a 47,47 0 1 1 0,94
a 47,47 0 1 1 0,-94" a 47,47 0 1 1 0,-94"
@ -209,7 +209,7 @@ exports[`test renders ./components/progress/demo/circle-mini.md correctly 1`] =
stroke="#f3f3f3" stroke="#f3f3f3"
stroke-width="6" /> stroke-width="6" />
<path <path
class="rc-progress-circle-path" class="ant-progress-circle-path"
d="M 50,50 m 0,-47 d="M 50,50 m 0,-47
a 47,47 0 1 1 0,94 a 47,47 0 1 1 0,94
a 47,47 0 1 1 0,-94" a 47,47 0 1 1 0,-94"
@ -232,10 +232,10 @@ exports[`test renders ./components/progress/demo/circle-mini.md correctly 1`] =
class="ant-progress-inner" class="ant-progress-inner"
style="width:80px;height:80px;font-size:18.8px;"> style="width:80px;height:80px;font-size:18.8px;">
<svg <svg
class="rc-progress-circle " class="ant-progress-circle "
viewbox="0 0 100 100"> viewbox="0 0 100 100">
<path <path
class="rc-progress-circle-trail" class="ant-progress-circle-trail"
d="M 50,50 m 0,-47 d="M 50,50 m 0,-47
a 47,47 0 1 1 0,94 a 47,47 0 1 1 0,94
a 47,47 0 1 1 0,-94" a 47,47 0 1 1 0,-94"
@ -243,7 +243,7 @@ exports[`test renders ./components/progress/demo/circle-mini.md correctly 1`] =
stroke="#f3f3f3" stroke="#f3f3f3"
stroke-width="6" /> stroke-width="6" />
<path <path
class="rc-progress-circle-path" class="ant-progress-circle-path"
d="M 50,50 m 0,-47 d="M 50,50 m 0,-47
a 47,47 0 1 1 0,94 a 47,47 0 1 1 0,94
a 47,47 0 1 1 0,-94" a 47,47 0 1 1 0,-94"
@ -309,10 +309,10 @@ exports[`test renders ./components/progress/demo/format.md correctly 1`] = `
class="ant-progress-inner" class="ant-progress-inner"
style="width:132px;height:132px;font-size:27.12px;"> style="width:132px;height:132px;font-size:27.12px;">
<svg <svg
class="rc-progress-circle " class="ant-progress-circle "
viewbox="0 0 100 100"> viewbox="0 0 100 100">
<path <path
class="rc-progress-circle-trail" class="ant-progress-circle-trail"
d="M 50,50 m 0,-47 d="M 50,50 m 0,-47
a 47,47 0 1 1 0,94 a 47,47 0 1 1 0,94
a 47,47 0 1 1 0,-94" a 47,47 0 1 1 0,-94"
@ -320,7 +320,7 @@ exports[`test renders ./components/progress/demo/format.md correctly 1`] = `
stroke="#f3f3f3" stroke="#f3f3f3"
stroke-width="6" /> stroke-width="6" />
<path <path
class="rc-progress-circle-path" class="ant-progress-circle-path"
d="M 50,50 m 0,-47 d="M 50,50 m 0,-47
a 47,47 0 1 1 0,94 a 47,47 0 1 1 0,94
a 47,47 0 1 1 0,-94" a 47,47 0 1 1 0,-94"
@ -342,10 +342,10 @@ exports[`test renders ./components/progress/demo/format.md correctly 1`] = `
class="ant-progress-inner" class="ant-progress-inner"
style="width:132px;height:132px;font-size:27.12px;"> style="width:132px;height:132px;font-size:27.12px;">
<svg <svg
class="rc-progress-circle " class="ant-progress-circle "
viewbox="0 0 100 100"> viewbox="0 0 100 100">
<path <path
class="rc-progress-circle-trail" class="ant-progress-circle-trail"
d="M 50,50 m 0,-47 d="M 50,50 m 0,-47
a 47,47 0 1 1 0,94 a 47,47 0 1 1 0,94
a 47,47 0 1 1 0,-94" a 47,47 0 1 1 0,-94"
@ -353,7 +353,7 @@ exports[`test renders ./components/progress/demo/format.md correctly 1`] = `
stroke="#f3f3f3" stroke="#f3f3f3"
stroke-width="6" /> stroke-width="6" />
<path <path
class="rc-progress-circle-path" class="ant-progress-circle-path"
d="M 50,50 m 0,-47 d="M 50,50 m 0,-47
a 47,47 0 1 1 0,94 a 47,47 0 1 1 0,94
a 47,47 0 1 1 0,-94" a 47,47 0 1 1 0,-94"

View File

@ -17,26 +17,24 @@ A dynamic progress bar is better.
import { Progress, Button } from 'antd'; import { Progress, Button } from 'antd';
const ButtonGroup = Button.Group; const ButtonGroup = Button.Group;
const MyProgress = React.createClass({ class App extends React.Component {
getInitialState() { state = {
return { percent: 0,
percent: 0, }
}; increase = () => {
},
increase() {
let percent = this.state.percent + 10; let percent = this.state.percent + 10;
if (percent > 100) { if (percent > 100) {
percent = 100; percent = 100;
} }
this.setState({ percent }); this.setState({ percent });
}, }
decline() { decline = () => {
let percent = this.state.percent - 10; let percent = this.state.percent - 10;
if (percent < 0) { if (percent < 0) {
percent = 0; percent = 0;
} }
this.setState({ percent }); this.setState({ percent });
}, }
render() { render() {
return ( return (
<div> <div>
@ -47,8 +45,8 @@ const MyProgress = React.createClass({
</ButtonGroup> </ButtonGroup>
</div> </div>
); );
}, }
}); }
ReactDOM.render(<MyProgress />, mountNode); ReactDOM.render(<App />, mountNode);
```` ````

View File

@ -22,5 +22,5 @@ ReactDOM.render(
<Progress type="circle" percent={70} width={80} status="exception" /> <Progress type="circle" percent={70} width={80} status="exception" />
<Progress type="circle" percent={100} width={80} /> <Progress type="circle" percent={100} width={80} />
</div> </div>
, mountNode); , mountNode);
```` ````

View File

@ -22,7 +22,7 @@ ReactDOM.render(
<Progress type="circle" percent={70} status="exception" /> <Progress type="circle" percent={70} status="exception" />
<Progress type="circle" percent={100} /> <Progress type="circle" percent={100} />
</div> </div>
, mountNode); , mountNode);
```` ````
<style> <style>

View File

@ -17,26 +17,24 @@ A dynamic progress bar is better.
import { Progress, Button } from 'antd'; import { Progress, Button } from 'antd';
const ButtonGroup = Button.Group; const ButtonGroup = Button.Group;
const MyProgress = React.createClass({ class App extends React.Component {
getInitialState() { state = {
return { percent: 0,
percent: 0, }
}; increase = () => {
},
increase() {
let percent = this.state.percent + 10; let percent = this.state.percent + 10;
if (percent > 100) { if (percent > 100) {
percent = 100; percent = 100;
} }
this.setState({ percent }); this.setState({ percent });
}, }
decline() { decline = () => {
let percent = this.state.percent - 10; let percent = this.state.percent - 10;
if (percent < 0) { if (percent < 0) {
percent = 0; percent = 0;
} }
this.setState({ percent }); this.setState({ percent });
}, }
render() { render() {
return ( return (
<div> <div>
@ -47,8 +45,8 @@ const MyProgress = React.createClass({
</ButtonGroup> </ButtonGroup>
</div> </div>
); );
}, }
}); }
ReactDOM.render(<MyProgress />, mountNode); ReactDOM.render(<App />, mountNode);
```` ````

View File

@ -25,8 +25,8 @@ ReactDOM.render(
```` ````
<style> <style>
.ant-progress-circle, div.ant-progress-circle,
.ant-progress-line { div.ant-progress-line {
margin-right: 8px; margin-right: 8px;
margin-bottom: 8px; margin-bottom: 8px;
} }

View File

@ -102,6 +102,7 @@ export default class Progress extends React.Component<ProgressProps, any> {
trailWidth={circleWidth} trailWidth={circleWidth}
strokeColor={statusColorMap[progressStatus]} strokeColor={statusColorMap[progressStatus]}
trailColor={trailColor} trailColor={trailColor}
prefixCls={prefixCls}
/> />
{progressInfo} {progressInfo}
</div> </div>

View File

@ -26,11 +26,19 @@
&-inner { &-inner {
display: inline-block; display: inline-block;
width: 100%; width: 100%;
background-color: #f3f3f3; background-color: @background-color-base;
border-radius: 100px; border-radius: 100px;
vertical-align: middle; vertical-align: middle;
} }
&-circle-trail {
stroke: @background-color-base;
}
&-circle-path {
stroke: @process-default-color;
}
&-bg { &-bg {
border-radius: 100px; border-radius: 100px;
background-color: @process-default-color; background-color: @process-default-color;
@ -75,6 +83,9 @@
.@{progress-prefix-cls}-text { .@{progress-prefix-cls}-text {
color: @error-color; color: @error-color;
} }
.@{progress-prefix-cls}-circle-path {
stroke: @error-color;
}
} }
&-status-success { &-status-success {
@ -84,6 +95,9 @@
.@{progress-prefix-cls}-text { .@{progress-prefix-cls}-text {
color: @success-color; color: @success-color;
} }
.@{progress-prefix-cls}-circle-path {
stroke: @success-color;
}
} }
&-circle &-inner { &-circle &-inner {

View File

@ -18,4 +18,3 @@ import { Radio } from 'antd';
ReactDOM.render(<Radio>Radio</Radio>, mountNode); ReactDOM.render(<Radio>Radio</Radio>, mountNode);
``` ```
2

View File

@ -16,17 +16,15 @@ Radio unavailable.
```jsx ```jsx
import { Radio, Button } from 'antd'; import { Radio, Button } from 'antd';
const App = React.createClass({ class App extends React.Component {
getInitialState() { state = {
return { disabled: true,
disabled: true, }
}; toggleDisabled = () => {
},
toggleDisabled() {
this.setState({ this.setState({
disabled: !this.state.disabled, disabled: !this.state.disabled,
}); });
}, }
render() { render() {
return ( return (
<div> <div>
@ -40,8 +38,8 @@ const App = React.createClass({
</div> </div>
</div> </div>
); );
}, }
}); }
ReactDOM.render(<App />, mountNode); ReactDOM.render(<App />, mountNode);
``` ```

View File

@ -3,7 +3,7 @@ order: 3
title: title:
zh-CN: 按钮样式 zh-CN: 按钮样式
en-US: radio style en-US: radio style
------------------ ---
## zh-CN ## zh-CN

View File

@ -3,7 +3,7 @@ order: 2
title: title:
zh-CN: RadioGroup 垂直 zh-CN: RadioGroup 垂直
en-US: Vertical RadioGroup en-US: Vertical RadioGroup
-------------------------- ---
## zh-CN ## zh-CN
@ -17,18 +17,16 @@ Vertical RadioGroup, with more radios.
import { Radio, Input } from 'antd'; import { Radio, Input } from 'antd';
const RadioGroup = Radio.Group; const RadioGroup = Radio.Group;
const App = React.createClass({ class App extends React.Component {
getInitialState() { state = {
return { value: 1,
value: 1, }
}; onChange = (e) => {
},
onChange(e) {
console.log('radio checked', e.target.value); console.log('radio checked', e.target.value);
this.setState({ this.setState({
value: e.target.value, value: e.target.value,
}); });
}, }
render() { render() {
const radioStyle = { const radioStyle = {
display: 'block', display: 'block',
@ -46,8 +44,8 @@ const App = React.createClass({
</Radio> </Radio>
</RadioGroup> </RadioGroup>
); );
}, }
}); }
ReactDOM.render(<App />, mountNode); ReactDOM.render(<App />, mountNode);
``` ```

View File

@ -3,7 +3,7 @@ order: 1
title: title:
zh-CN: RadioGroup 组合 zh-CN: RadioGroup 组合
en-US: RadioGroup group en-US: RadioGroup group
----------------------- ---
## zh-CN ## zh-CN
@ -17,18 +17,16 @@ A set of mutually exclusive Radio with the use of
import { Radio } from 'antd'; import { Radio } from 'antd';
const RadioGroup = Radio.Group; const RadioGroup = Radio.Group;
const App = React.createClass({ class App extends React.Component {
getInitialState() { state = {
return { value: 1,
value: 1, }
}; onChange = (e) => {
},
onChange(e) {
console.log('radio checked', e.target.value); console.log('radio checked', e.target.value);
this.setState({ this.setState({
value: e.target.value, value: e.target.value,
}); });
}, }
render() { render() {
return ( return (
<RadioGroup onChange={this.onChange} value={this.state.value}> <RadioGroup onChange={this.onChange} value={this.state.value}>
@ -38,8 +36,8 @@ const App = React.createClass({
<Radio value={4}>D</Radio> <Radio value={4}>D</Radio>
</RadioGroup> </RadioGroup>
); );
}, }
}); }
ReactDOM.render(<App />, mountNode); ReactDOM.render(<App />, mountNode);
``` ```

View File

@ -3,7 +3,7 @@ order: 5
title: title:
zh-CN: 大小 zh-CN: 大小
en-US: Size en-US: Size
----------- ---
## zh-CN ## zh-CN

View File

@ -57,7 +57,7 @@
position: relative; position: relative;
top: 0; top: 0;
left: 0; left: 0;
display: inline-block; display: block;
width: 14px; width: 14px;
height: 14px; height: 14px;
border-width: 1px; border-width: 1px;
@ -110,6 +110,7 @@
span.@{radio-prefix-cls} + * { span.@{radio-prefix-cls} + * {
padding-left: 8px; padding-left: 8px;
padding-right: 8px; padding-right: 8px;
vertical-align: middle;
} }
.@{radio-prefix-cls}-button-wrapper { .@{radio-prefix-cls}-button-wrapper {

View File

@ -16,16 +16,14 @@ Add copywriting in rate components.
````jsx ````jsx
import { Rate } from 'antd'; import { Rate } from 'antd';
const Rater = React.createClass({ class Rater extends React.Component {
getInitialState() { state = {
return { value: 3,
value: 3, count: null,
count: null, }
}; handleChange = (value) => {
},
handleChange(value) {
this.setState({ value }); this.setState({ value });
}, }
render() { render() {
const { value } = this.state; const { value } = this.state;
return ( return (
@ -34,8 +32,8 @@ const Rater = React.createClass({
{value && <span className="ant-rate-text">{value} stars</span>} {value && <span className="ant-rate-text">{value} stars</span>}
</span> </span>
); );
}, }
}); }
ReactDOM.render(<Rater />, mountNode); ReactDOM.render(<Rater />, mountNode);
```` ````

View File

@ -22,13 +22,11 @@ Using the [AutoComplete](/components/auto-complete/) component is strongly recom
import { Select } from 'antd'; import { Select } from 'antd';
const Option = Select.Option; const Option = Select.Option;
const Test = React.createClass({ class App extends React.Component {
getInitialState() { state = {
return { options: [],
options: [], }
}; handleChange = (value) => {
},
handleChange(value) {
let options; let options;
if (!value || value.indexOf('@') >= 0) { if (!value || value.indexOf('@') >= 0) {
options = []; options = [];
@ -39,7 +37,7 @@ const Test = React.createClass({
}); });
} }
this.setState({ options }); this.setState({ options });
}, }
render() { render() {
// filterOption needs to be falseas the value is dynamically generated // filterOption needs to be falseas the value is dynamically generated
return ( return (
@ -52,8 +50,8 @@ const Test = React.createClass({
{this.state.options} {this.state.options}
</Select> </Select>
); );
}, }
}); }
ReactDOM.render(<Test />, mountNode); ReactDOM.render(<App />, mountNode);
```` ````

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