diff --git a/.eslintrc b/.eslintrc
index 18c1180eee..780aa12746 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -12,6 +12,7 @@
"experimentalObjectRestSpread": true
},
"plugins": [
+ "markdown",
"react",
"babel"
],
@@ -30,9 +31,7 @@
"no-undef": 2,
"no-unused-vars": [2, { "vars": "all", "args": "none" }],
"babel/object-shorthand": 0,
- "react/jsx-boolean-value": 0,
"react/jsx-no-duplicate-props": 2,
- "react/prop-types": [2, { "ignore": [ "children", "className", "style" ] }],
"react/sort-comp": 0,
"react/wrap-multilines": 0,
"react/no-multi-comp": 0,
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 845c0ffc59..846de7331a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,30 @@
---
+## 0.10.2 `2015-11-25`
+
+- Slider 新增 `tipFormatter` 用于格式化 Tooltip 的内容。
+- 优化 Badge 动画效果。
+- 修复以下问题:
+ - 文本域的表单校验无法重置。
+ - 设置 Upload 的 `multiple` 为 `true` 时,未显示每个文件的上传进度。
+ - Breadcrumb 配合 Router 的时候如果没有 `breadcrumbName` 会抛错。
+ - InputNumber 同时设置 `size` `className` 时会有冲突。
+
+
+## 0.10.1 `2015-11-20`
+
+- 修改内部组件的引用结构,方便工具优化。[#566](https://github.com/ant-design/ant-design/pull/566)
+ - 移除了演示中没有使用过的 `antd.ButtonGroup`,依然用 `const ButtonGroup = Button.Group` 来使用。
+ - Form 和 Input 目录分离,`import { Form, Input } from 'ant/lib/form'` 的引用方式被废弃。
+
+ 现在可以 `import Form from 'ant/lib/form'` 和 `import Input from 'ant/lib/input'`。
+
+ 原有的 `import { Form, Input } from 'antd'` 则不受影响。
+
+- 修复 Datepicker 的 `style` 和 `calendarStyle` 属性失效的问题,并将 `calendarStyle` 更名为 `popupStyle`。
+
+
## 0.10.0 `2015-11-20`
- 全面兼容 `react@0.14.x`。
@@ -31,7 +55,7 @@
#### 组件变更
- Table
- - 支持单选。[演示](/components/table/#demo-row-selection-radio-props)
+ - 支持单选。[演示](http://ant.design/components/table/#demo-row-selection-radio-props)
- 选择模式支持默认选中和不可用效果。[演示](/components/table/#demo-row-selection-props)
- 列支持了 `colSpan` 和 `rowSpan` 配置。[演示](/components/table/#demo-colspan-rowspan)
- 新增 `loading` 属性。
@@ -70,7 +94,7 @@
> 备注:
>
> - [计划和推进 issue](https://github.com/ant-design/ant-design/issues/276)
-> - [0.10 升级指南](/docs/upgrade-to-0.10)
+> - [0.10 升级指南](http://ant.design/docs/upgrade-to-0.10)
## 0.9.3 ~ 0.9.5 `2015-11-04`
diff --git a/components/affix/index.jsx b/components/affix/index.jsx
index 32e3cf939b..eaa9c11bcd 100644
--- a/components/affix/index.jsx
+++ b/components/affix/index.jsx
@@ -1,6 +1,7 @@
import React from 'react';
import ReactDOM from 'react-dom';
import rcUtil from 'rc-util';
+import classNames from 'classnames';
function getScroll(w, top) {
let ret = w['page' + (top ? 'Y' : 'X') + 'Offset'];
@@ -89,7 +90,7 @@ let Affix = React.createClass({
},
render() {
- const className = rcUtil.classSet({
+ const className = classNames({
[this.props.className]: this.props.className,
'ant-affix': this.state.affix
});
diff --git a/components/alert/demo/close-type.md b/components/alert/demo/close-type.md
index 29d62f7705..5f52f8788d 100644
--- a/components/alert/demo/close-type.md
+++ b/components/alert/demo/close-type.md
@@ -8,7 +8,7 @@
````jsx
import { Alert } from 'antd';
-const link = 不再提醒;
+const link = 不再提醒;
ReactDOM.render(
diff --git a/components/alert/index.jsx b/components/alert/index.jsx
index e29dcf300f..1e20bf8726 100644
--- a/components/alert/index.jsx
+++ b/components/alert/index.jsx
@@ -16,6 +16,7 @@ export default React.createClass({
};
},
handleClose(e) {
+ e.preventDefault();
let dom = ReactDOM.findDOMNode(this);
dom.style.height = dom.offsetHeight + 'px';
// Magic code
diff --git a/components/badge/ScrollNumber.jsx b/components/badge/ScrollNumber.jsx
new file mode 100644
index 0000000000..ffb482a09f
--- /dev/null
+++ b/components/badge/ScrollNumber.jsx
@@ -0,0 +1,135 @@
+import React, { createElement } from 'react';
+import assign from 'object-assign';
+
+function getNumberArray(num) {
+ return num ?
+ num.toString().split('').reverse().map(i => Number(i)) : [];
+}
+
+class AntScrollNumber extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ animateStarted: true,
+ count: props.count
+ };
+ }
+
+ getPositionByNum(num, i) {
+ if (this.state.animateStarted) {
+ return 10 + num;
+ }
+ const currentDigit = getNumberArray(this.state.count)[i];
+ const lastDigit = getNumberArray(this.lastCount)[i];
+ // 同方向则在同一侧切换数字
+ if (this.state.count > this.lastCount) {
+ if (currentDigit >= lastDigit) {
+ return 10 + num;
+ } else {
+ return 20 + num;
+ }
+ } else {
+ if (currentDigit <= lastDigit) {
+ return 10 + num;
+ } else {
+ return num;
+ }
+ }
+ }
+
+ componentWillReceiveProps(nextProps) {
+ if ('count' in nextProps && nextProps.count) {
+ if (this.lastCount === this.state.count) {
+ return;
+ }
+ this.lastCount = this.state.count;
+ // 复原数字初始位置
+ this.setState({
+ animateStarted: true,
+ }, () => {
+ // 等待数字位置复原完毕
+ // 开始设置完整的数字
+ setTimeout(() => {
+ this.setState({
+ animateStarted: false,
+ count: nextProps.count,
+ }, () => {
+ this.props.onAnimated();
+ });
+ }, 5);
+ });
+ }
+ }
+
+ renderNumberList() {
+ const childrenToReturn = [];
+ for (let i = 0; i < 30; i++) {
+ childrenToReturn.push(
{i % 10}
);
+ }
+ return childrenToReturn;
+ }
+
+ renderCurrentNumber(num, i) {
+ const position = this.getPositionByNum(num, i);
+ const height = this.props.height;
+ const removeTransition = this.state.animateStarted ||
+ (getNumberArray(this.lastCount)[i] === undefined);
+ return createElement('span', {
+ className: `${this.props.prefixCls}-only`,
+ style: {
+ transition: removeTransition && 'none',
+ transform: 'translate3d(0, ' + (-position * height) + 'px, 0)',
+ height: height,
+ },
+ key: i,
+ }, this.renderNumberList());
+ }
+
+ renderNumberElement() {
+ const state = this.state;
+ if (!state.count || isNaN(state.count)) {
+ return state.count;
+ }
+ return getNumberArray(state.count)
+ .map((num, i) => this.renderCurrentNumber(num, i)).reverse();
+ }
+
+ render() {
+ const props = assign({}, this.props, {
+ className: `${this.props.prefixCls} ${this.props.className}`
+ });
+ if (typeof document !== 'undefined' && typeof window !== 'undefined') {
+ return createElement(
+ this.props.component,
+ props,
+ this.renderNumberElement()
+ );
+ } else {
+ return createElement(
+ this.props.component,
+ props,
+ props.count
+ );
+ }
+ }
+}
+
+AntScrollNumber.defaultProps = {
+ prefixCls: 'ant-scroll-number',
+ count: null,
+ component: 'sup',
+ onAnimated: function() {},
+ height: 20
+};
+
+AntScrollNumber.propTypes = {
+ count: React.PropTypes.oneOfType([
+ React.PropTypes.string,
+ React.PropTypes.number
+ ]),
+ component: React.PropTypes.string,
+ onAnimated: React.PropTypes.func,
+ height: React.PropTypes.number,
+};
+
+export default AntScrollNumber;
diff --git a/components/badge/demo/change.md b/components/badge/demo/change.md
index 4ce034bdab..59b7b9878e 100644
--- a/components/badge/demo/change.md
+++ b/components/badge/demo/change.md
@@ -33,7 +33,7 @@ const Test = React.createClass({
show: !this.state.show
});
},
- onNumberClick(){
+ onNumberClick() {
const count = this.state.count;
this.setState({
count: count ? 0 : 5
@@ -45,9 +45,15 @@ const Test = React.createClass({
- 一个链接
+
+
+
-
-
;
}
diff --git a/components/badge/demo/dot.md b/components/badge/demo/dot.md
index bb380924b4..22c26a6154 100644
--- a/components/badge/demo/dot.md
+++ b/components/badge/demo/dot.md
@@ -10,10 +10,10 @@
import { Badge, Icon } from 'antd';
ReactDOM.render(, document.getElementById('components-badge-demo-dot'));
diff --git a/components/badge/index.jsx b/components/badge/index.jsx
index 5c1f659d54..3aaa743053 100644
--- a/components/badge/index.jsx
+++ b/components/badge/index.jsx
@@ -1,5 +1,6 @@
import React from 'react';
import Animate from 'rc-animate';
+import ScrollNumber from './ScrollNumber';
class AntBadge extends React.Component {
constructor(props) {
@@ -27,12 +28,10 @@ class AntBadge extends React.Component {
+ transitionAppear>
{
hidden ? null :
-
- {count}
-
+
}
@@ -43,7 +42,7 @@ class AntBadge extends React.Component {
AntBadge.defaultProps = {
prefixCls: 'ant-badge',
count: null,
- dot: false
+ dot: false,
};
AntBadge.propTypes = {
@@ -51,7 +50,7 @@ AntBadge.propTypes = {
React.PropTypes.string,
React.PropTypes.number
]),
- dot: React.PropTypes.bool
+ dot: React.PropTypes.bool,
};
export default AntBadge;
diff --git a/components/breadcrumb/index.jsx b/components/breadcrumb/index.jsx
index 48d4442d05..546b39b5e8 100644
--- a/components/breadcrumb/index.jsx
+++ b/components/breadcrumb/index.jsx
@@ -30,6 +30,9 @@ let Breadcrumb = React.createClass({
if (routes && routes.length > 0 && ReactRouter) {
let Link = ReactRouter.Link;
crumbs = routes.map(function(route, i) {
+ if (!route.breadcrumbName) {
+ return null;
+ }
let name = route.breadcrumbName.replace(/\:(.*)/g, function(replacement, key) {
return params[key] || replacement;
});
diff --git a/components/button/button-group.jsx b/components/button/button-group.jsx
index 4fa7390a3a..082ee4d577 100644
--- a/components/button/button-group.jsx
+++ b/components/button/button-group.jsx
@@ -1,5 +1,5 @@
import React from 'react';
-import rcUtil from 'rc-util';
+import classNames from 'classnames';
const prefix = 'ant-btn-group-';
@@ -14,7 +14,7 @@ export default class ButtonGroup extends React.Component {
'small': 'sm'
})[size] || '';
- const classes = rcUtil.classSet({
+ const classes = classNames({
'ant-btn-group': true,
[prefix + sizeCls]: sizeCls,
[className]: className
diff --git a/components/button/button.jsx b/components/button/button.jsx
index 2e7247678d..c9760872b6 100644
--- a/components/button/button.jsx
+++ b/components/button/button.jsx
@@ -1,5 +1,5 @@
import React from 'react';
-import rcUtil from 'rc-util';
+import classNames from 'classnames';
import { findDOMNode } from 'react-dom';
const rxTwoCNChar = /^[\u4e00-\u9fa5]{2,2}$/;
@@ -41,7 +41,7 @@ export default class Button extends React.Component {
'small': 'sm'
})[size] || '';
- const classes = rcUtil.classSet({
+ const classes = classNames({
'ant-btn': true,
[prefix + type]: type,
[prefix + shape]: shape,
diff --git a/components/button/demo/basic.md b/components/button/demo/basic.md
index cb36d3b224..5a558ed963 100644
--- a/components/button/demo/basic.md
+++ b/components/button/demo/basic.md
@@ -18,7 +18,7 @@ ReactDOM.render(
,
-document.getElementById('components-button-demo-basic'))
+document.getElementById('components-button-demo-basic'));
````
+
diff --git a/components/tree/demo/checkbox.md b/components/tree/demo/checkbox.md
index 76c82e9438..1015859dfb 100644
--- a/components/tree/demo/checkbox.md
+++ b/components/tree/demo/checkbox.md
@@ -15,7 +15,7 @@ function handleCheck(info) {
}
ReactDOM.render(
-
+
diff --git a/components/tree/demo/dynamic.md b/components/tree/demo/dynamic.md
index a85694093e..e877bc1d43 100644
--- a/components/tree/demo/dynamic.md
+++ b/components/tree/demo/dynamic.md
@@ -10,22 +10,23 @@
import { Tree } from 'antd';
const TreeNode = Tree.TreeNode;
-const asyncTree = [
- {name: "pNode 01", key: "0-0"},
-];
+const asyncTree = [{
+ name: 'pNode 01',
+ key: '0-0'
+}];
const generateTreeNodes = () => {
- const arr = [
- {name: "伯约", key: "0-0-0"},
- ];
- return arr;
-}
+ return [{
+ name: '伯约',
+ key: '0-0-0'
+ }];
+};
const TreeDemo = React.createClass({
timeout(duration = 0) {
return new Promise((resolve, reject) => {
- setTimeout(resolve.bind(this), duration);
- })
+ setTimeout(resolve.bind(this), duration);
+ });
},
getInitialState() {
return {
@@ -62,19 +63,19 @@ const TreeDemo = React.createClass({
if (item.children) {
return {loop(item.children)};
} else {
- return ;
+ return ;
}
- })
+ });
};
const parseTreeNode = data => loop(data);
let treeNodes = parseTreeNode(this.state.treeData);
return (
-
- {treeNodes}
-
- )
+
+ {treeNodes}
+
+ );
}
-})
+});
ReactDOM.render(, document.getElementById('components-tree-demo-dynamic'));
````
diff --git a/components/tree/demo/special.md b/components/tree/demo/special.md
index cd9e2d606e..d6892c7b2b 100644
--- a/components/tree/demo/special.md
+++ b/components/tree/demo/special.md
@@ -19,45 +19,45 @@ class TreeDemo extends React.Component {
this.state = {
checkedKeys: [],
selectedKeys: []
- }
+ };
}
handleClick() {
this.setState({
checkedKeys: ['p11'],
selectedKeys: ['p21', 'p11']
- })
+ });
}
handleCheck(info) {
console.log('check: ', info);
this.setState({
checkedKeys: ['p21'],
selectedKeys: ['p1', 'p21']
- })
+ });
}
handleSelect(info) {
console.log('selected: ', info);
this.setState({
checkedKeys: ['p21'],
selectedKeys: ['p21']
- })
+ });
}
render() {
return (
-
-
-
-
-
- test
- sss}/>
-
-
+
+
+
+
+
+ test
+ sss}/>
+
-
-
+
+
+
);
}
diff --git a/components/upload/demo/fileList.md b/components/upload/demo/fileList.md
index a89fc35667..f2651a7fe4 100644
--- a/components/upload/demo/fileList.md
+++ b/components/upload/demo/fileList.md
@@ -15,17 +15,15 @@
````jsx
import { Upload, Button, Icon } from 'antd';
-const fileList = [{
- uid: -1,
- name: 'xxx.png',
- status: 'done',
- url: 'http://www.baidu.com/xxx.png'
-}];
-
const MyUpload = React.createClass({
getInitialState() {
return {
- fileList: fileList
+ fileList: [{
+ uid: -1,
+ name: 'xxx.png',
+ status: 'done',
+ url: 'http://www.baidu.com/xxx.png'
+ }]
};
},
handleChange(info) {
@@ -52,9 +50,7 @@ const MyUpload = React.createClass({
return true;
});
- this.setState({
- fileList: fileList
- });
+ this.setState({ fileList });
},
render() {
const props = {
diff --git a/components/upload/index.jsx b/components/upload/index.jsx
index 0a68b40053..554545bba5 100644
--- a/components/upload/index.jsx
+++ b/components/upload/index.jsx
@@ -62,7 +62,7 @@ const AntUpload = React.createClass({
f.status = 'uploading';
return f;
});
- nextFileList = nextFileList.concat(file);
+ nextFileList = nextFileList.concat(targetItem);
} else {
targetItem = fileToObject(file);
targetItem.status = 'uploading';
diff --git a/components/validation/demo/basic.md b/components/validation/demo/basic.md
index 61dfceb436..01d671b9ee 100644
--- a/components/validation/demo/basic.md
+++ b/components/validation/demo/basic.md
@@ -147,7 +147,7 @@ const Demo = React.createClass({
wrapperCol={{span: 12}}
validateStatus={this.renderValidateStyle('name')}
hasFeedback
- help={status.name.isValidating ? "正在校验中.." : status.name.errors ? status.name.errors.join(',') : null}
+ help={status.name.isValidating ? '正在校验中..' : (status.name.errors && status.name.errors.join(','))}
required>
@@ -164,7 +164,7 @@ const Demo = React.createClass({
help={status.email.errors ? status.email.errors.join(',') : null}
required>
-
+
diff --git a/components/validation/demo/customize.md b/components/validation/demo/customize.md
index 07518ee45b..3eb88a5414 100644
--- a/components/validation/demo/customize.md
+++ b/components/validation/demo/customize.md
@@ -9,20 +9,11 @@
---
````jsx
-import {Validation, Button, Form, Input, Row, Col} from 'antd';
+import { Validation, Button, Form, Input, Row, Col } from 'antd';
+import classNames from 'classnames';
const Validator = Validation.Validator;
const FormItem = Form.Item;
-function cx(classNames) {
- if (typeof classNames === 'object') {
- return Object.keys(classNames).filter(function(className) {
- return classNames[className];
- }).join(' ');
- } else {
- return Array.prototype.join.call(arguments, ' ');
- }
-}
-
function noop() {
return false;
}
@@ -49,7 +40,7 @@ const Demo = React.createClass({
handleSubmit(e) {
e.preventDefault();
- var validation = this.refs.validation;
+ const validation = this.refs.validation;
validation.validate((valid) => {
if (!valid) {
console.log('error in form');
@@ -71,7 +62,7 @@ const Demo = React.createClass({
const formData = this.state.formData;
const status = this.state.status;
- const classes = cx({
+ const classes = classNames({
'error': status[item].errors,
'validating': status[item].isValidating,
'success': formData[item] && !status[item].errors && !status[item].isValidating
@@ -91,9 +82,17 @@ const Demo = React.createClass({
} else {
strength = 'H';
}
- type === 'pass' ? this.setState({ passBarShow: true, passStrength: strength }) : this.setState({ rePassBarShow: true, rePassStrength: strength });
+ if (type === 'pass') {
+ this.setState({ passBarShow: true, passStrength: strength });
+ } else {
+ this.setState({ rePassBarShow: true, rePassStrength: strength });
+ }
} else {
- type === 'pass' ? this.setState({ passBarShow: false }) : this.setState({ rePassBarShow: false });
+ if (type === 'pass') {
+ this.setState({ passBarShow: false });
+ } else {
+ this.setState({ rePassBarShow: false });
+ }
}
},
@@ -119,7 +118,7 @@ const Demo = React.createClass({
renderPassStrengthBar(type) {
const strength = type === 'pass' ? this.state.passStrength : this.state.rePassStrength;
- const classSet = cx({
+ const classSet = classNames({
'ant-pwd-strength': true,
'ant-pwd-strength-low': strength === 'L',
'ant-pwd-strength-medium': strength === 'M',
@@ -132,16 +131,16 @@ const Demo = React.createClass({
};
return (
-
-
-
-
-
-
- {level[strength]}
-
-
-
+
+
+
+
+
+
+ {level[strength]}
+
+
+
);
},
diff --git a/components/validation/demo/other-items.md b/components/validation/demo/other-items.md
index 05db498411..852c15b1cf 100644
--- a/components/validation/demo/other-items.md
+++ b/components/validation/demo/other-items.md
@@ -25,10 +25,6 @@ function cx(classNames) {
}
}
-function noop() {
- return false;
-}
-
const Demo = React.createClass({
mixins: [Validation.FieldMixin],
@@ -45,7 +41,7 @@ const Demo = React.createClass({
select: undefined,
multiSelect: undefined,
radio: undefined,
- birthday: undefined,
+ birthday: null,
primeNumber: 9
}
};
@@ -119,7 +115,7 @@ const Demo = React.createClass({
help={status.select.errors ? status.select.errors.join(',') : null}
required>
-