mirror of
https://github.com/ant-design/ant-design.git
synced 2024-12-26 01:42:30 +08:00
Merge remote-tracking branch 'ant-design/master'
This commit is contained in:
commit
6dae3aebf1
@ -28,7 +28,9 @@ const eslintrc = {
|
||||
'react/sort-comp': 0,
|
||||
'react/prop-types': 0,
|
||||
'react/jsx-first-prop-new-line': 0,
|
||||
"react/jsx-filename-extension": [1, { extensions: ['.js', '.jsx', '.md'] }],
|
||||
'import/no-unresolved': 0,
|
||||
'import/no-extraneous-dependencies': 0,
|
||||
'no-param-reassign': 0,
|
||||
'no-return-assign': 0,
|
||||
'max-len': 0,
|
||||
@ -50,6 +52,8 @@ if (process.env.RUN_ENV === 'DEMO') {
|
||||
'prefer-rest-params': 0,
|
||||
'react/no-multi-comp': 0,
|
||||
'react/prefer-es6-class': 0,
|
||||
'jsx-a11y/href-no-hash': 0,
|
||||
'import/newline-after-import': 0,
|
||||
});
|
||||
}
|
||||
|
||||
|
13
CHANGELOG.md
13
CHANGELOG.md
@ -9,11 +9,22 @@ timeline: true
|
||||
|
||||
---
|
||||
|
||||
## 1.10.0
|
||||
|
||||
`2016-08-20`
|
||||
|
||||
- Affix 和 BackTop 新增 `target` 属性,支持指定滚动容器。[#2718](https://github.com/ant-design/ant-design/issues/2718)
|
||||
- 文档页面加上编辑按钮,方便社区贡献。[#2325](https://github.com/ant-design/ant-design/issues/2325)
|
||||
- 升级 rc-cascader 依赖,修复一个 `loadData` 属性和表单结合使用的问题。[#2767](https://github.com/ant-design/ant-design/issues/2767)
|
||||
- 修复 `editable-card` 类型的 Tabs 没有关闭图标的问题。[#2747](https://github.com/ant-design/ant-design/issues/2747)
|
||||
- Menu 修正默认 `z-index`。[#2762](https://github.com/ant-design/ant-design/issues/2762)
|
||||
- 修正 Select 组件在 IE 下的一些样式问题。[#2741](https://github.com/ant-design/ant-design/issues/2741)
|
||||
|
||||
## 1.9.1
|
||||
|
||||
`2016-08-16`
|
||||
|
||||
- 修复 Tabs 的 `type="editable-card"` 模式,activeKey 错误的问题。[#2725](https://github.com/ant-design/ant-design/issues/2725)
|
||||
- 修复 `editable-card` 类型的 Tabs 设置 `activeKey` 无效的问题。[#2725](https://github.com/ant-design/ant-design/issues/2725)
|
||||
- 修复一个 Table 的样式兼容性问题。[#2723](https://github.com/ant-design/ant-design/issues/2723)
|
||||
- 更新 axure 部件库。[#2714](https://github.com/ant-design/ant-design/issues/2714)
|
||||
|
||||
|
29
components/affix/demo/target.md
Normal file
29
components/affix/demo/target.md
Normal file
@ -0,0 +1,29 @@
|
||||
---
|
||||
order: 4
|
||||
title: 参考对象
|
||||
---
|
||||
|
||||
用 `target` 设置 `Affix` 需要监听其滚动事件的元素,默认为 `window`。
|
||||
|
||||
````jsx
|
||||
import { Affix, Button } from 'antd';
|
||||
|
||||
const Demo = () => {
|
||||
return (
|
||||
<div style={{ height: 100, overflow: 'hidden' }}>
|
||||
<div style={{ height: '100%', overflowY: 'scroll' }} id="affix-target">
|
||||
<div style={{ height: 300, backgroundImage: 'url(https://zos.alipayobjects.com/rmsportal/RmjwQiJorKyobvI.jpg)' }}>
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<Affix target={() => document.getElementById('affix-target')} offsetTop={20}>
|
||||
<Button type="primary">固定在容器顶部</Button>
|
||||
</Affix>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
ReactDOM.render(<Demo />, mountNode);
|
||||
````
|
@ -6,32 +6,42 @@ import warning from 'warning';
|
||||
import assign from 'object-assign';
|
||||
import shallowequal from 'shallowequal';
|
||||
|
||||
function getScroll(w, top?: boolean) {
|
||||
let ret = w[`page${top ? 'Y' : 'X'}Offset`];
|
||||
const method = `scroll${top ? 'Top' : 'Left'}`;
|
||||
if (typeof ret !== 'number') {
|
||||
const d = w.document;
|
||||
function getScroll(target, top) {
|
||||
const prop = top ? 'pageYOffset' : 'pageXOffset';
|
||||
const method = top ? 'scrollTop' : 'scrollLeft';
|
||||
const isWindow = target === window;
|
||||
|
||||
let ret = isWindow ? target[prop] : target[method];
|
||||
// ie6,7,8 standard mode
|
||||
ret = d.documentElement[method];
|
||||
if (typeof ret !== 'number') {
|
||||
// quirks mode
|
||||
ret = d.body[method];
|
||||
}
|
||||
if (isWindow && typeof ret !== 'number') {
|
||||
ret = window.document.documentElement[method];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
function getOffset(element) {
|
||||
const rect = element.getBoundingClientRect();
|
||||
const body = document.body;
|
||||
const clientTop = element.clientTop || body.clientTop || 0;
|
||||
const clientLeft = element.clientLeft || body.clientLeft || 0;
|
||||
const scrollTop = getScroll(window, true);
|
||||
const scrollLeft = getScroll(window);
|
||||
function getTargetRect(target): any {
|
||||
return target !== window ?
|
||||
target.getBoundingClientRect() :
|
||||
{ top: 0, left: 0, bottom: 0 };
|
||||
}
|
||||
|
||||
function getOffset(element, target) {
|
||||
const elemRect = element.getBoundingClientRect();
|
||||
const targetRect = getTargetRect(target);
|
||||
|
||||
const scrollTop = getScroll(target, true);
|
||||
const scrollLeft = getScroll(target, false);
|
||||
|
||||
const docElem = window.document.body;
|
||||
const clientTop = docElem.clientTop || 0;
|
||||
const clientLeft = docElem.clientLeft || 0;
|
||||
|
||||
return {
|
||||
top: rect.top + scrollTop - clientTop,
|
||||
left: rect.left + scrollLeft - clientLeft,
|
||||
top: elemRect.top - targetRect.top +
|
||||
scrollTop - clientTop,
|
||||
left: elemRect.left - targetRect.left +
|
||||
scrollLeft - clientLeft,
|
||||
};
|
||||
}
|
||||
|
||||
@ -45,15 +55,20 @@ export interface AffixProps {
|
||||
offsetBottom?: number;
|
||||
style?: React.CSSProperties;
|
||||
onChange?: (affixed?: boolean) => any;
|
||||
target?: () => Window | HTMLElement;
|
||||
}
|
||||
|
||||
export default class Affix extends React.Component<AffixProps, any> {
|
||||
static propTypes = {
|
||||
offsetTop: React.PropTypes.number,
|
||||
offsetBottom: React.PropTypes.number,
|
||||
target: React.PropTypes.func,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
target() {
|
||||
return window;
|
||||
},
|
||||
onChange() {},
|
||||
};
|
||||
|
||||
@ -73,8 +88,10 @@ export default class Affix extends React.Component<AffixProps, any> {
|
||||
}
|
||||
|
||||
setAffixStyle(e, affixStyle) {
|
||||
const { onChange, target } = this.props;
|
||||
const originalAffixStyle = this.state.affixStyle;
|
||||
if (e.type === 'scroll' && originalAffixStyle && affixStyle) {
|
||||
const isWindow = target() === window;
|
||||
if (e.type === 'scroll' && originalAffixStyle && affixStyle && isWindow) {
|
||||
return;
|
||||
}
|
||||
if (shallowequal(affixStyle, originalAffixStyle)) {
|
||||
@ -84,7 +101,7 @@ export default class Affix extends React.Component<AffixProps, any> {
|
||||
const affixed = !!this.state.affixStyle;
|
||||
if ((affixStyle && !originalAffixStyle) ||
|
||||
(!affixStyle && originalAffixStyle)) {
|
||||
this.props.onChange(affixed);
|
||||
onChange(affixed);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -100,24 +117,25 @@ export default class Affix extends React.Component<AffixProps, any> {
|
||||
this.setState({ placeholderStyle });
|
||||
}
|
||||
|
||||
handleScroll = (e) => {
|
||||
let { offsetTop, offsetBottom, offset } = this.props;
|
||||
updatePosition = (e) => {
|
||||
let { offsetTop, offsetBottom, offset, target } = this.props;
|
||||
const targetNode = target();
|
||||
|
||||
// Backwards support
|
||||
offsetTop = offsetTop || offset;
|
||||
const scrollTop = getScroll(window, true);
|
||||
const scrollTop = getScroll(targetNode, true);
|
||||
const affixNode = ReactDOM.findDOMNode(this) as HTMLElement;
|
||||
const fixedNode = ReactDOM.findDOMNode(this.refs.fixedNode) as HTMLElement;
|
||||
const elemOffset = getOffset(affixNode);
|
||||
const elemOffset = getOffset(affixNode, targetNode);
|
||||
const elemSize = {
|
||||
width: fixedNode.offsetWidth,
|
||||
height: fixedNode.offsetHeight,
|
||||
width: this.refs.fixedNode.offsetWidth,
|
||||
height: this.refs.fixedNode.offsetHeight,
|
||||
};
|
||||
|
||||
const offsetMode = {
|
||||
top: null as boolean,
|
||||
bottom: null as boolean,
|
||||
};
|
||||
// Default to `offsetTop=0`.
|
||||
if (typeof offsetTop !== 'number' && typeof offsetBottom !== 'number') {
|
||||
offsetMode.top = true;
|
||||
offsetTop = 0;
|
||||
@ -126,25 +144,31 @@ export default class Affix extends React.Component<AffixProps, any> {
|
||||
offsetMode.bottom = typeof offsetBottom === 'number';
|
||||
}
|
||||
|
||||
const targetRect = getTargetRect(targetNode);
|
||||
const targetInnerHeight =
|
||||
(targetNode as Window).innerHeight || (targetNode as HTMLElement).clientHeight;
|
||||
if (scrollTop > elemOffset.top - offsetTop && offsetMode.top) {
|
||||
// Fixed Top
|
||||
this.setAffixStyle(e, {
|
||||
position: 'fixed',
|
||||
top: offsetTop,
|
||||
left: elemOffset.left,
|
||||
top: targetRect.top + offsetTop,
|
||||
left: targetRect.left + elemOffset.left,
|
||||
width: affixNode.offsetWidth,
|
||||
});
|
||||
this.setPlaceholderStyle(e, {
|
||||
width: affixNode.offsetWidth,
|
||||
height: affixNode.offsetHeight,
|
||||
});
|
||||
} else if (scrollTop < elemOffset.top + elemSize.height + offsetBottom - window.innerHeight &&
|
||||
offsetMode.bottom) {
|
||||
} else if (
|
||||
scrollTop < elemOffset.top + elemSize.height + offsetBottom - targetInnerHeight &&
|
||||
offsetMode.bottom
|
||||
) {
|
||||
// Fixed Bottom
|
||||
const targetBottomOffet = targetNode === window ? 0 : (window.innerHeight - targetRect.bottom);
|
||||
this.setAffixStyle(e, {
|
||||
position: 'fixed',
|
||||
bottom: offsetBottom,
|
||||
left: elemOffset.left,
|
||||
bottom: targetBottomOffet + offsetBottom,
|
||||
left: targetRect.left + elemOffset.left,
|
||||
width: affixNode.offsetWidth,
|
||||
});
|
||||
this.setPlaceholderStyle(e, {
|
||||
@ -159,17 +183,37 @@ export default class Affix extends React.Component<AffixProps, any> {
|
||||
|
||||
componentDidMount() {
|
||||
warning(!('offset' in this.props), '`offset` prop of Affix is deprecated, use `offsetTop` instead.');
|
||||
this.scrollEvent = addEventListener(window, 'scroll', this.handleScroll);
|
||||
this.resizeEvent = addEventListener(window, 'resize', this.handleScroll);
|
||||
|
||||
const target = this.props.target;
|
||||
this.setTargetEventListeners(target);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (this.props.target !== nextProps.target) {
|
||||
this.clearScrollEventListeners();
|
||||
this.setTargetEventListeners(nextProps.target);
|
||||
|
||||
// Mock Event object.
|
||||
this.updatePosition({});
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.scrollEvent) {
|
||||
this.scrollEvent.remove();
|
||||
this.clearScrollEventListeners();
|
||||
}
|
||||
if (this.resizeEvent) {
|
||||
this.resizeEvent.remove();
|
||||
|
||||
setTargetEventListeners(getTarget) {
|
||||
const target = getTarget();
|
||||
this.scrollEvent = addEventListener(target, 'scroll', this.updatePosition);
|
||||
this.resizeEvent = addEventListener(target, 'resize', this.updatePosition);
|
||||
}
|
||||
|
||||
clearScrollEventListeners() {
|
||||
['scrollEvent', 'resizeEvent'].forEach((name) => {
|
||||
if (this[name]) {
|
||||
this[name].remove();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
@ -180,6 +224,7 @@ export default class Affix extends React.Component<AffixProps, any> {
|
||||
const props = assign({}, this.props);
|
||||
delete props.offsetTop;
|
||||
delete props.offsetBottom;
|
||||
delete props.target;
|
||||
|
||||
return (
|
||||
<div {...props} style={this.state.placeholderStyle}>
|
||||
|
@ -20,4 +20,5 @@ english: Affix
|
||||
|-------------|----------------|--------------------|--------------|
|
||||
| offsetTop | 距离窗口顶部达到指定偏移量后触发 | Number | |
|
||||
| offsetBottom | 距离窗口底部达到指定偏移量后触发 | Number | |
|
||||
| target | 设置 `Affix` 需要监听其滚动事件的元素,值为一个返回对应 DOM 元素的函数 | Function | () => window |
|
||||
| onChange | 固定状态改变时触发的回调函数 | Function(affixed) | 无 |
|
||||
|
@ -16,6 +16,7 @@ Items in dataSource could be an `AutoComplete.Option`.
|
||||
|
||||
````jsx
|
||||
import { AutoComplete } from 'antd';
|
||||
|
||||
const Option = AutoComplete.Option;
|
||||
|
||||
const Complete = React.createClass({
|
||||
|
@ -3,7 +3,7 @@ import Select, { Option, OptGroup } from '../select';
|
||||
import classNames from 'classnames';
|
||||
|
||||
export interface AutoCompleteProps {
|
||||
size?: string;
|
||||
size?: 'large' | 'small' | 'default';
|
||||
className?: string;
|
||||
notFoundContent?: Element;
|
||||
dataSource: Array<any>;
|
||||
|
@ -5,24 +5,28 @@ import addEventListener from 'rc-util/lib/Dom/addEventListener';
|
||||
import classNames from 'classnames';
|
||||
import omit from 'object.omit';
|
||||
|
||||
function getScroll(w, top) {
|
||||
let ret = w[`page${top ? 'Y' : 'X'}Offset`];
|
||||
const method = `scroll${top ? 'Top' : 'Left'}`;
|
||||
if (typeof ret !== 'number') {
|
||||
const d = w.document;
|
||||
function getScroll(target, top) {
|
||||
if (typeof window === 'undefined') {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const prop = top ? 'pageYOffset' : 'pageXOffset';
|
||||
const method = top ? 'scrollTop' : 'scrollLeft';
|
||||
const isWindow = target === window;
|
||||
|
||||
let ret = isWindow ? target[prop] : target[method];
|
||||
// ie6,7,8 standard mode
|
||||
ret = d.documentElement[method];
|
||||
if (typeof ret !== 'number') {
|
||||
// quirks mode
|
||||
ret = d.body[method];
|
||||
}
|
||||
if (isWindow && typeof ret !== 'number') {
|
||||
ret = window.document.documentElement[method];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
interface BackTopProps {
|
||||
visibilityHeight?: number;
|
||||
onClick?: (event) => void;
|
||||
target?: () => HTMLElement | Window;
|
||||
prefixCls?: string;
|
||||
className?: string;
|
||||
}
|
||||
@ -31,6 +35,9 @@ export default class BackTop extends React.Component<BackTopProps, any> {
|
||||
static defaultProps = {
|
||||
onClick() {},
|
||||
visibilityHeight: 400,
|
||||
target() {
|
||||
return window;
|
||||
},
|
||||
prefixCls: 'ant-back-top',
|
||||
};
|
||||
|
||||
@ -38,9 +45,9 @@ export default class BackTop extends React.Component<BackTopProps, any> {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const scrollTop = getScroll(window, true);
|
||||
const scrollTop = getScroll(props.target(), true);
|
||||
this.state = {
|
||||
visible: scrollTop > this.props.visibilityHeight,
|
||||
visible: scrollTop > props.visibilityHeight,
|
||||
};
|
||||
}
|
||||
|
||||
@ -53,19 +60,25 @@ export default class BackTop extends React.Component<BackTopProps, any> {
|
||||
}
|
||||
|
||||
setScrollTop(value) {
|
||||
const targetNode = this.props.target();
|
||||
if (targetNode === window) {
|
||||
document.body.scrollTop = value;
|
||||
document.documentElement.scrollTop = value;
|
||||
} else {
|
||||
(targetNode as HTMLElement).scrollTop = value;
|
||||
}
|
||||
}
|
||||
|
||||
handleScroll = () => {
|
||||
const scrollTop = getScroll(window, true);
|
||||
const { visibilityHeight, target } = this.props;
|
||||
const scrollTop = getScroll(target(), true);
|
||||
this.setState({
|
||||
visible: scrollTop > this.props.visibilityHeight,
|
||||
visible: scrollTop > visibilityHeight,
|
||||
});
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.scrollEvent = addEventListener(window, 'scroll', this.handleScroll);
|
||||
this.scrollEvent = addEventListener(this.props.target(), 'scroll', this.handleScroll);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
@ -18,10 +18,10 @@ import { Badge } from 'antd';
|
||||
|
||||
ReactDOM.render(<div>
|
||||
<Badge count={99}>
|
||||
<a href="#" className="head-example"></a>
|
||||
<a href="#" className="head-example" />
|
||||
</Badge>
|
||||
<Badge count={200}>
|
||||
<a href="#" className="head-example"></a>
|
||||
<a href="#" className="head-example" />
|
||||
</Badge>
|
||||
</div>, mountNode);
|
||||
````
|
||||
|
@ -18,7 +18,7 @@ import { Badge } from 'antd';
|
||||
|
||||
ReactDOM.render(
|
||||
<Badge count={5}>
|
||||
<a href="#" className="head-example"></a>
|
||||
<a href="#" className="head-example" />
|
||||
</Badge>
|
||||
, mountNode);
|
||||
````
|
||||
|
@ -44,10 +44,10 @@ const Test = React.createClass({
|
||||
return (
|
||||
<div>
|
||||
<Badge count={this.state.count}>
|
||||
<a href="#" className="head-example"></a>
|
||||
<a href="#" className="head-example" />
|
||||
</Badge>
|
||||
<Badge dot={this.state.show}>
|
||||
<a href="#" className="head-example"></a>
|
||||
<a href="#" className="head-example" />
|
||||
</Badge>
|
||||
<div style={{ marginTop: 10 }}>
|
||||
<ButtonGroup>
|
||||
|
@ -19,7 +19,7 @@ import { Badge } from 'antd';
|
||||
ReactDOM.render(
|
||||
<a href="#">
|
||||
<Badge count={5}>
|
||||
<span className="head-example"></span>
|
||||
<span className="head-example" />
|
||||
</Badge>
|
||||
</a>
|
||||
, mountNode);
|
||||
|
@ -18,10 +18,10 @@ import { Badge } from 'antd';
|
||||
|
||||
ReactDOM.render(<div>
|
||||
<Badge count={99} overflowCount={10}>
|
||||
<a href="#" className="head-example"></a>
|
||||
<a href="#" className="head-example" />
|
||||
</Badge>
|
||||
<Badge count={1000} overflowCount={999}>
|
||||
<a href="#" className="head-example"></a>
|
||||
<a href="#" className="head-example" />
|
||||
</Badge>
|
||||
</div>, mountNode);
|
||||
````
|
||||
|
36
components/badge/demo/status.md
Normal file
36
components/badge/demo/status.md
Normal file
@ -0,0 +1,36 @@
|
||||
---
|
||||
order: 7
|
||||
title:
|
||||
zh-CN: 状态点
|
||||
en-US: Status
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
用于表示状态的小圆点。
|
||||
|
||||
## en-US
|
||||
|
||||
Standalone badge with status.
|
||||
|
||||
````jsx
|
||||
import { Badge } from 'antd';
|
||||
|
||||
ReactDOM.render(
|
||||
<div>
|
||||
<div>Status: </div>
|
||||
<Badge status="success" />
|
||||
<Badge status="error" />
|
||||
<Badge status="default" />
|
||||
<Badge status="processing" />
|
||||
<Badge status="warning" />
|
||||
<br />
|
||||
<Badge status="success" text="Success" /><br />
|
||||
<Badge status="error" text="Error" /><br />
|
||||
<Badge status="default" text="Default" /><br />
|
||||
<Badge status="processing" text="Processing" /><br />
|
||||
<Badge status="warning" text="Warning" />
|
||||
</div>,
|
||||
mountNode
|
||||
);
|
||||
````
|
@ -14,7 +14,7 @@ Badge normally appears in proximity to notification or head picture with eye-cat
|
||||
|
||||
```jsx
|
||||
<Badge count={5}>
|
||||
<a href="#" className="head-example"></a>
|
||||
<a href="#" className="head-example" />
|
||||
</Badge>
|
||||
```
|
||||
|
||||
@ -28,3 +28,5 @@ Badge normally appears in proximity to notification or head picture with eye-cat
|
||||
| count | Number to show in badge | Number | |
|
||||
| overflowCount | Max count to show | Number | 99 |
|
||||
| dot | whether to show red dot without number | Boolean | false |
|
||||
| status | Set Badge as a status dot | Enum{ 'success', 'processing, 'default', 'error', 'warning' } | '' |
|
||||
| text | If `status` is set, `text` is to set the text of status dot | String | '' |
|
||||
|
@ -13,6 +13,8 @@ interface BadgeProps {
|
||||
style?: React.CSSProperties;
|
||||
prefixCls?: string;
|
||||
className?: string;
|
||||
status?: 'success' | 'processing' | 'default' | 'error' | 'warning';
|
||||
text?: string;
|
||||
}
|
||||
|
||||
export default class Badge extends React.Component<BadgeProps, any> {
|
||||
@ -21,6 +23,7 @@ export default class Badge extends React.Component<BadgeProps, any> {
|
||||
count: null,
|
||||
dot: false,
|
||||
overflowCount: 99,
|
||||
// status: 'default',
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
@ -33,18 +36,25 @@ export default class Badge extends React.Component<BadgeProps, any> {
|
||||
};
|
||||
|
||||
render() {
|
||||
let { count, prefixCls, overflowCount, className, style, children, dot } = this.props;
|
||||
let { count, prefixCls, overflowCount, className, style, children, dot, status, text } = this.props;
|
||||
const isDot = dot || status;
|
||||
|
||||
count = count > overflowCount ? `${overflowCount}+` : count;
|
||||
|
||||
// dot mode don't need count
|
||||
if (dot) {
|
||||
if (isDot) {
|
||||
count = '';
|
||||
}
|
||||
|
||||
// null undefined "" "0" 0
|
||||
const hidden = (!count || count === '0') && !dot;
|
||||
const scrollNumberCls = prefixCls + (dot ? '-dot' : '-count');
|
||||
const hidden = (!count || count === '0') && !isDot;
|
||||
const scrollNumberCls = classNames({
|
||||
[`${prefixCls}-dot`]: isDot,
|
||||
[`${prefixCls}-count`]: !isDot,
|
||||
[`${prefixCls}-status`]: status,
|
||||
[`${prefixCls}-status-${status}`]: status,
|
||||
[`${prefixCls}-status-with-text`]: text,
|
||||
});
|
||||
const badgeCls = classNames({
|
||||
[className]: !!className,
|
||||
[prefixCls]: true,
|
||||
@ -70,6 +80,10 @@ export default class Badge extends React.Component<BadgeProps, any> {
|
||||
/>
|
||||
}
|
||||
</Animate>
|
||||
{
|
||||
hidden || !text ? null :
|
||||
<span className={`${prefixCls}-status-text`}>{text}</span>
|
||||
}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ english: Badge
|
||||
|
||||
```jsx
|
||||
<Badge count={5}>
|
||||
<a href="#" className="head-example"></a>
|
||||
<a href="#" className="head-example" />
|
||||
</Badge>
|
||||
```
|
||||
|
||||
@ -28,4 +28,6 @@ english: Badge
|
||||
|----------------|----------------------------------|------------|---------|--------|
|
||||
| count | 展示的数字,大于 overflowCount 时显示为 `${overflowCount}+`,为 0 时隐藏 | Number | | |
|
||||
| overflowCount | 展示封顶的数字值 | Number | | 99 |
|
||||
| dot | 不展示数字,只有一个小红点 | boolean | | false |
|
||||
| dot | 不展示数字,只有一个小红点 | Boolean | | false |
|
||||
| status | 设置 Badge 为状态点 | Enum | 'success'、'processing'、'default'、'error'、'warning' | '' |
|
||||
| text | 在设置了 `status` 的前提下有效,设置状态点的文本 | String | | '' |
|
||||
|
@ -47,6 +47,38 @@
|
||||
box-shadow: 0 0 0 1px #fff;
|
||||
}
|
||||
|
||||
&-status {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
|
||||
&-success {
|
||||
background-color: @success-color;
|
||||
}
|
||||
&-processing {
|
||||
background-color: @primary-color;
|
||||
animation: antStatusProcessing 1.2s infinite ease-in-out;
|
||||
}
|
||||
&-default {
|
||||
background-color: @normal-color;
|
||||
}
|
||||
&-error {
|
||||
background-color: @error-color;
|
||||
}
|
||||
&-warning {
|
||||
background-color: @warning-color;
|
||||
}
|
||||
|
||||
&-with-text {
|
||||
top: 5px;
|
||||
}
|
||||
|
||||
&-text {
|
||||
color: @text-color;
|
||||
font-size: @font-size-base;
|
||||
margin-left: 8px; // 8 - (6 / 2) === 5
|
||||
}
|
||||
}
|
||||
|
||||
&-zoom-appear,
|
||||
&-zoom-enter {
|
||||
animation: antZoomBadgeIn .3s @ease-out-back;
|
||||
@ -66,6 +98,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes antStatusProcessing {
|
||||
0%,
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
a & {
|
||||
&-count:hover {
|
||||
background: tint(@error-color, 20%);
|
||||
|
@ -35,6 +35,7 @@ interface ButtonProps {
|
||||
shape?: ButtonShape;
|
||||
size?: ButtonSize;
|
||||
onClick?: React.FormEventHandler;
|
||||
onMouseUp?: React.FormEventHandler;
|
||||
loading?: boolean;
|
||||
disabled?: boolean;
|
||||
style?: React.CSSProperties;
|
||||
|
@ -7,7 +7,19 @@ const Option = Select.Option;
|
||||
|
||||
function noop() {}
|
||||
|
||||
export default class Header extends React.Component {
|
||||
export interface HeaderProps {
|
||||
prefixCls?: string;
|
||||
locale?: any;
|
||||
fullscreen?: boolean;
|
||||
yearSelectOffset?: number;
|
||||
yearSelectTotal?: number;
|
||||
type?: string;
|
||||
onValueChange?: (value) => void;
|
||||
onTypeChange?: (type: string) => void;
|
||||
value: any;
|
||||
}
|
||||
|
||||
export default class Header extends React.Component<HeaderProps, any> {
|
||||
static defaultProps = {
|
||||
prefixCls: `${PREFIX_CLS}-header`,
|
||||
yearSelectOffset: 10,
|
||||
|
@ -16,7 +16,27 @@ function zerofixed(v) {
|
||||
return `${v}`;
|
||||
}
|
||||
|
||||
export default class Calendar extends React.Component {
|
||||
interface CalendarContext {
|
||||
antLocale?: {
|
||||
Calendar?: any
|
||||
};
|
||||
}
|
||||
|
||||
export interface CalendarProps {
|
||||
prefixCls?: string;
|
||||
className?: string;
|
||||
value?: Date;
|
||||
defaultValue?: Date;
|
||||
mode?: 'month' | 'year';
|
||||
fullscreen?: boolean;
|
||||
dateCellRender?: (date) => React.ReactNode;
|
||||
monthCellRender?: (month) => React.ReactNode;
|
||||
locale?: any;
|
||||
style?: React.CSSProperties;
|
||||
onPanelChange?: (date: Date, mode: string) => void;
|
||||
}
|
||||
|
||||
export default class Calendar extends React.Component<CalendarProps, any> {
|
||||
static defaultProps = {
|
||||
monthCellRender: noop,
|
||||
dateCellRender: noop,
|
||||
@ -43,6 +63,8 @@ export default class Calendar extends React.Component {
|
||||
antLocale: PropTypes.object,
|
||||
};
|
||||
|
||||
context: CalendarContext;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
|
@ -1 +1,2 @@
|
||||
module.exports = require('../../date-picker/locale/en_US');
|
||||
import en_US from '../../date-picker/locale/en_US';
|
||||
export default en_US;
|
||||
|
@ -1 +1,2 @@
|
||||
module.exports = require('../../date-picker/locale/ru_RU');
|
||||
import ru_RU from '../../date-picker/locale/ru_RU';
|
||||
export default ru_RU;
|
||||
|
@ -1 +1,2 @@
|
||||
module.exports = require('../../date-picker/locale/zh_CN');
|
||||
import zh_CN from '../../date-picker/locale/zh_CN';
|
||||
export default zh_CN;
|
||||
|
@ -2,8 +2,9 @@
|
||||
// https://github.com/WickyNilliams/enquire.js/issues/82
|
||||
import assign from 'object-assign';
|
||||
if (typeof window !== 'undefined') {
|
||||
const matchMediaPolyfill = function matchMediaPolyfill() {
|
||||
const matchMediaPolyfill = function matchMediaPolyfill(mediaQuery: string): MediaQueryList {
|
||||
return {
|
||||
media: mediaQuery,
|
||||
matches: false,
|
||||
addListener() {
|
||||
},
|
||||
@ -23,7 +24,7 @@ export interface CarouselProps {
|
||||
/** 动画效果函数,可取 scrollx, fade */
|
||||
effect?: CarouselEffect;
|
||||
/** 是否显示面板指示点 */
|
||||
dots?: SlickCarouselboolean;
|
||||
dots?: boolean;
|
||||
/** 垂直显示 */
|
||||
vertical?: boolean;
|
||||
/** 是否自动切换 */
|
||||
|
@ -59,12 +59,13 @@ export default class CheckboxGroup extends React.Component<CheckboxGroupProps, C
|
||||
}
|
||||
getOptions() {
|
||||
const { options } = this.props;
|
||||
return options.map(option => {
|
||||
// https://github.com/Microsoft/TypeScript/issues/7960
|
||||
return (options as Array<any>).map(option => {
|
||||
if (typeof option === 'string') {
|
||||
return {
|
||||
label: option,
|
||||
value: option,
|
||||
};
|
||||
} as CheckboxOptionType;
|
||||
}
|
||||
return option;
|
||||
});
|
||||
|
@ -2,7 +2,7 @@ import * as React from 'react';
|
||||
import CalendarLocale from 'rc-calendar/lib/locale/zh_CN';
|
||||
import RcCalendar from 'rc-calendar';
|
||||
|
||||
export default class Calendar extends React.Component {
|
||||
export default class Calendar extends React.Component<any, any> {
|
||||
static defaultProps = {
|
||||
locale: CalendarLocale,
|
||||
prefixCls: 'ant-calendar',
|
||||
|
@ -5,7 +5,7 @@ import RcDatePicker from 'rc-calendar/lib/Picker';
|
||||
import classNames from 'classnames';
|
||||
import Icon from '../icon';
|
||||
|
||||
export default class RangePicker extends React.Component {
|
||||
export default class RangePicker extends React.Component<any, any> {
|
||||
static defaultProps = {
|
||||
defaultValue: [],
|
||||
};
|
||||
@ -74,7 +74,7 @@ export default class RangePicker extends React.Component {
|
||||
let pickerChangeHandler = {
|
||||
onChange: this.handleChange,
|
||||
};
|
||||
let calendarHandler = {
|
||||
let calendarHandler: Object = {
|
||||
onOk: this.handleChange,
|
||||
};
|
||||
if (props.timePicker) {
|
||||
|
@ -6,6 +6,11 @@ import classNames from 'classnames';
|
||||
import assign from 'object-assign';
|
||||
import Icon from '../icon';
|
||||
|
||||
export interface PickerProps {
|
||||
parseDateFromValue?: Function;
|
||||
value?: string | Date;
|
||||
}
|
||||
|
||||
export default function createPicker(TheCalendar) {
|
||||
// use class typescript error
|
||||
const CalenderWrapper = React.createClass({
|
||||
@ -16,7 +21,7 @@ export default function createPicker(TheCalendar) {
|
||||
};
|
||||
},
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
componentWillReceiveProps(nextProps: PickerProps) {
|
||||
if ('value' in nextProps) {
|
||||
this.setState({
|
||||
value: nextProps.parseDateFromValue(nextProps.value),
|
||||
@ -60,10 +65,10 @@ export default function createPicker(TheCalendar) {
|
||||
});
|
||||
|
||||
// 需要选择时间时,点击 ok 时才触发 onChange
|
||||
let pickerChangeHandler = {
|
||||
let pickerChangeHandler: Object = {
|
||||
onChange: this.handleChange,
|
||||
};
|
||||
let calendarHandler = {
|
||||
let calendarHandler: Object = {
|
||||
onOk: this.handleChange,
|
||||
// fix https://github.com/ant-design/ant-design/issues/1902
|
||||
onSelect: (value, cause) => {
|
||||
@ -95,7 +100,7 @@ export default function createPicker(TheCalendar) {
|
||||
);
|
||||
|
||||
// default width for showTime
|
||||
const pickerStyle = {};
|
||||
const pickerStyle = { width: undefined };
|
||||
if (props.showTime) {
|
||||
pickerStyle.width = 180;
|
||||
}
|
||||
|
@ -7,11 +7,11 @@ title:
|
||||
|
||||
## zh-CN
|
||||
|
||||
通过 `locale` 配置时区、语言等, 默认支持 `en_US`,`zh_CN`。
|
||||
通过 `locale` 配置时区、语言等, 默认支持 `en_US`,`zh_CN`。不同版本带有不同的时区配置,如果所在时区与默认配置不同,需要自行设置。上面的 demo 就是在东八区使用 en_US 版本的例子。
|
||||
|
||||
## en-US
|
||||
|
||||
Use locale to set the properties like time zone, language and etc. en_US, zh_CN are supported by default.
|
||||
Use locale to set the properties like time zone, language and etc. `en_US`, `zh_CN` are supported by default. There are different time zone configuration in different versions, you must set it by yourself if your time zone does not match the default setting. The example above is to show how to use the `en_US` version at GMT+8 time zone.
|
||||
|
||||
|
||||
````jsx
|
||||
@ -19,7 +19,7 @@ import { DatePicker } from 'antd';
|
||||
import enUS from 'antd/lib/date-picker/locale/en_US';
|
||||
|
||||
const customLocale = {
|
||||
timezoneOffset: 0 * 60,
|
||||
timezoneOffset: 8 * 60,
|
||||
firstDayOfWeek: 0,
|
||||
minimalDaysInFirstWeek: 1,
|
||||
};
|
||||
|
@ -1,15 +1,49 @@
|
||||
import * as React from 'react';
|
||||
import assign from 'object-assign';
|
||||
import RcCalendar from 'rc-calendar';
|
||||
import MonthCalendar from 'rc-calendar/lib/MonthCalendar';
|
||||
import createPicker from './createPicker';
|
||||
import wrapPicker from './wrapPicker';
|
||||
import RangePicker from './RangePicker';
|
||||
import Calendar from './Calendar';
|
||||
import { TimePickerProps } from '../time-picker';
|
||||
|
||||
const DatePicker = wrapPicker(createPicker(RcCalendar));
|
||||
const MonthPicker = wrapPicker(createPicker(MonthCalendar), 'yyyy-MM');
|
||||
interface PickerProps {
|
||||
format?: string;
|
||||
disabled?: boolean;
|
||||
style?: React.CSSProperties;
|
||||
popupStyle?: React.CSSProperties;
|
||||
locale?: any;
|
||||
size?: 'large' | 'small' | 'default';
|
||||
getCalendarContainer?: (trigger) => React.ReactNode;
|
||||
}
|
||||
|
||||
DatePicker.Calendar = Calendar;
|
||||
DatePicker.RangePicker = wrapPicker(RangePicker);
|
||||
DatePicker.MonthPicker = MonthPicker;
|
||||
interface SinglePickerProps {
|
||||
value?: string | Date;
|
||||
defaultValue?: string | Date;
|
||||
onChange?: (date: Date, dateString: string) => void;
|
||||
}
|
||||
|
||||
export interface DatePickerProps extends PickerProps, SinglePickerProps {
|
||||
showTime?: TimePickerProps;
|
||||
}
|
||||
const DatePicker = wrapPicker(createPicker(RcCalendar)) as React.ClassicComponentClass<DatePickerProps>;
|
||||
|
||||
export interface MonthPickerProps extends PickerProps, SinglePickerProps {
|
||||
}
|
||||
const MonthPicker = wrapPicker(createPicker(MonthCalendar), 'yyyy-MM') as React.ClassicComponentClass<MonthPickerProps>;
|
||||
|
||||
export interface RangePickerProps extends PickerProps {
|
||||
value?: [string | Date, string | Date];
|
||||
defaultValue?: [string | Date, string | Date];
|
||||
onChange?: (dates: [Date, Date], dateStrings: [String, String]) => void;
|
||||
showTime?: TimePickerProps;
|
||||
}
|
||||
|
||||
assign(DatePicker, {
|
||||
RangePicker: wrapPicker(RangePicker) as React.ClassicComponentClass<RangePickerProps>,
|
||||
Calendar,
|
||||
MonthPicker,
|
||||
});
|
||||
|
||||
export default DatePicker;
|
||||
|
@ -7,7 +7,7 @@ import classNames from 'classnames';
|
||||
import defaultLocale from './locale/zh_CN';
|
||||
import assign from 'object-assign';
|
||||
|
||||
export default function wrapPicker(Picker, defaultFormat) {
|
||||
export default function wrapPicker(Picker, defaultFormat?) {
|
||||
const PickerWrapper = React.createClass({
|
||||
getDefaultProps() {
|
||||
return {
|
||||
@ -46,7 +46,7 @@ export default function wrapPicker(Picker, defaultFormat) {
|
||||
|
||||
getFormatter() {
|
||||
const format = this.props.format;
|
||||
const formatter = new DateTimeFormat(format, this.getLocale().lang.format);
|
||||
const formatter = new DateTimeFormat(format as string, this.getLocale().lang.format);
|
||||
return formatter;
|
||||
},
|
||||
|
||||
|
@ -19,13 +19,13 @@ import { Menu, Dropdown, Icon } from 'antd';
|
||||
const menu = (
|
||||
<Menu>
|
||||
<Menu.Item>
|
||||
<a target="_blank" href="http://www.alipay.com/">第一个菜单项</a>
|
||||
<a target="_blank" rel="noopener noreferrer" href="http://www.alipay.com/">第一个菜单项</a>
|
||||
</Menu.Item>
|
||||
<Menu.Item>
|
||||
<a target="_blank" href="http://www.taobao.com/">第二个菜单项</a>
|
||||
<a target="_blank" rel="noopener noreferrer" href="http://www.taobao.com/">第二个菜单项</a>
|
||||
</Menu.Item>
|
||||
<Menu.Item>
|
||||
<a target="_blank" href="http://www.tmall.com/">第三个菜单项</a>
|
||||
<a target="_blank" rel="noopener noreferrer" href="http://www.tmall.com/">第三个菜单项</a>
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
|
@ -19,10 +19,10 @@ import { Menu, Dropdown, Icon } from 'antd';
|
||||
const menu = (
|
||||
<Menu>
|
||||
<Menu.Item key="0">
|
||||
<a target="_blank" href="http://www.alipay.com/">第一个菜单项</a>
|
||||
<a target="_blank" rel="noopener noreferrer" href="http://www.alipay.com/">第一个菜单项</a>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="1">
|
||||
<a target="_blank" href="http://www.taobao.com/">第二个菜单项</a>
|
||||
<a target="_blank" rel="noopener noreferrer" href="http://www.taobao.com/">第二个菜单项</a>
|
||||
</Menu.Item>
|
||||
<Menu.Divider />
|
||||
<Menu.Item key="3" disabled>第三个菜单项(不可用)</Menu.Item>
|
||||
|
@ -5,7 +5,18 @@ import Dropdown from './dropdown';
|
||||
const ButtonGroup = Button.Group;
|
||||
import classNames from 'classnames';
|
||||
import splitObject from '../_util/splitObject';
|
||||
export default class DropdownButton extends React.Component {
|
||||
|
||||
export interface DropdownButtonProps {
|
||||
type?: 'primary' | 'ghost' | 'dash';
|
||||
onClick?: React.FormEventHandler;
|
||||
trigger?: 'click' | 'hover';
|
||||
overlay: React.ReactNode;
|
||||
visible?: boolean;
|
||||
onVisibleChange?: (visible: boolean) => void;
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
|
||||
export default class DropdownButton extends React.Component<DropdownButtonProps, any> {
|
||||
static defaultProps = {
|
||||
align: {
|
||||
points: ['tr', 'br'],
|
||||
|
@ -2,13 +2,16 @@ import * as React from 'react';
|
||||
import RcDropdown from 'rc-dropdown';
|
||||
|
||||
export interface DropDownProps {
|
||||
trigger: string[];
|
||||
trigger?: Array<'click' | 'hover'>;
|
||||
overlay: React.ReactNode;
|
||||
visible: boolean;
|
||||
onVisibleChange: (visible: boolean) => void;
|
||||
style?: React.CSSProperties;
|
||||
onVisibleChange?: (visible: boolean) => void;
|
||||
visible?: boolean;
|
||||
align?: Object;
|
||||
}
|
||||
|
||||
export default class Dropdown extends React.Component<DropDownProps, any> {
|
||||
static Button: React.ReactNode;
|
||||
static defaultProps = {
|
||||
transitionName: 'slide-up',
|
||||
prefixCls: 'ant-dropdown',
|
||||
|
@ -31,9 +31,9 @@ english: Dropdown
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|-------------|------------------|--------------------|--------------|
|
||||
| type | 按钮类型,和 [Button](/components/button) 一致 | String | 'default' |
|
||||
| onClick | 点击左侧按钮的回调,和 [Button](/components/button) 一致 | Function | - |
|
||||
| type | 按钮类型,和 [Button](/components/button/) 一致 | String | 'default' |
|
||||
| onClick | 点击左侧按钮的回调,和 [Button](/components/button/) 一致 | Function | - |
|
||||
| trigger | 触发下拉的行为 | ['click'] or ['hover'] | ['hover'] |
|
||||
| overlay | 菜单 | [Menu](/components/menu) | - |
|
||||
| overlay | 菜单 | [Menu](/components/menu/) | - |
|
||||
| visible | 菜单是否显示 | Boolean | - |
|
||||
| onVisibleChange | 菜单显示状态改变时调用,参数为 { visible } | Function | - |
|
||||
|
@ -1,10 +1,83 @@
|
||||
import * as React from 'react';
|
||||
import { PropTypes } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
||||
import omit from 'object.omit';
|
||||
import warning from 'warning';
|
||||
import assign from 'object-assign';
|
||||
import FormItem from './FormItem';
|
||||
import createDOMForm from 'rc-form/lib/createDOMForm';
|
||||
import { FIELD_META_PROP } from './constants';
|
||||
|
||||
export default class Form extends React.Component {
|
||||
export interface FormCreateOption {
|
||||
onFieldsChange?: (props: any, fields: Array<any>) => void;
|
||||
mapPropsToFields?: (props: any) => void;
|
||||
}
|
||||
|
||||
export interface FormProps {
|
||||
horizontal?: boolean;
|
||||
inline?: boolean;
|
||||
vertical?: boolean;
|
||||
form?: Object;
|
||||
onSubmit?: React.FormEventHandler;
|
||||
style?: React.CSSProperties;
|
||||
className?: string;
|
||||
prefixCls?: string;
|
||||
}
|
||||
|
||||
// function create
|
||||
export type WrappedFormUtils = {
|
||||
/** 获取一组输入控件的值,如不传入参数,则获取全部组件的值 */
|
||||
getFieldsValue(fieldNames?: Array<string>): Object;
|
||||
/** 获取一个输入控件的值*/
|
||||
getFieldValue(fieldName: string): any;
|
||||
/** 设置一组输入控件的值*/
|
||||
setFieldsValue(obj: Object): void;
|
||||
/** 设置一组输入控件的值*/
|
||||
setFields(obj: Object): void;
|
||||
/** 校验并获取一组输入域的值与 Error */
|
||||
validateFields(fieldNames?: Array<string>, options?: Object, callback?: (erros: any, values: any) => void): any;
|
||||
/** 与 `validateFields` 相似,但校验完后,如果校验不通过的菜单域不在可见范围内,则自动滚动进可见范围 */
|
||||
validateFieldsAndScroll(
|
||||
fieldNames?: Array<string>,
|
||||
options?: Object,
|
||||
callback?: (erros: any, values: any) => void
|
||||
): void;
|
||||
/** 获取某个输入控件的 Error */
|
||||
getFieldError(name: string): Object[];
|
||||
/** 判断一个输入控件是否在校验状态*/
|
||||
isFieldValidating(name: string): boolean;
|
||||
/** 重置一组输入控件的值与状态,如不传入参数,则重置所有组件 */
|
||||
resetFields(names?: Array<string>): void;
|
||||
|
||||
getFieldProps(id: string, options: {
|
||||
/** 子节点的值的属性,如 Checkbox 的是 'checked' */
|
||||
valuePropName?: string;
|
||||
/** 子节点的初始值,类型、可选值均由子节点决定 */
|
||||
initialValue?: any;
|
||||
/** 收集子节点的值的时机 */
|
||||
trigger?: string;
|
||||
/** 校验子节点值的时机 */
|
||||
validateTrigger?: string;
|
||||
/** 校验规则,参见 [async-validator](https://github.com/yiminghe/async-validator) */
|
||||
rules?: Array<any>;
|
||||
/** 必填输入控件唯一标志 */
|
||||
id?: string;
|
||||
}): Array<any>;
|
||||
}
|
||||
|
||||
export interface FormComponentProps {
|
||||
form: WrappedFormUtils;
|
||||
}
|
||||
|
||||
class FormComponent extends React.Component<FormComponentProps, {}> {
|
||||
}
|
||||
|
||||
export interface ComponentDecorator {
|
||||
<T extends (typeof FormComponent)>(component: T): T;
|
||||
}
|
||||
|
||||
export default class Form extends React.Component<FormProps, any> {
|
||||
static defaultProps = {
|
||||
prefixCls: 'ant-form',
|
||||
onSubmit(e) {
|
||||
@ -21,6 +94,33 @@ export default class Form extends React.Component {
|
||||
onSubmit: React.PropTypes.func,
|
||||
};
|
||||
|
||||
static Item = FormItem;
|
||||
|
||||
static create = (options?: FormCreateOption): ComponentDecorator => {
|
||||
const formWrapper = createDOMForm(assign({}, options, {
|
||||
fieldNameProp: 'id',
|
||||
fieldMetaProp: FIELD_META_PROP,
|
||||
}));
|
||||
|
||||
/* eslint-disable react/prefer-es6-class */
|
||||
return (Component) => formWrapper(React.createClass({
|
||||
propTypes: {
|
||||
form: PropTypes.object.isRequired,
|
||||
},
|
||||
childContextTypes: {
|
||||
form: PropTypes.object.isRequired,
|
||||
},
|
||||
getChildContext() {
|
||||
return {
|
||||
form: this.props.form,
|
||||
};
|
||||
},
|
||||
render() {
|
||||
return <Component {...this.props} />;
|
||||
},
|
||||
}));
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
|
@ -3,9 +3,35 @@ import classNames from 'classnames';
|
||||
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
||||
import Row from '../row';
|
||||
import Col from '../col';
|
||||
import { WrappedFormUtils } from './Form';
|
||||
import { FIELD_META_PROP } from './constants';
|
||||
|
||||
export default class FormItem extends React.Component {
|
||||
export interface FormItemLabelColOption {
|
||||
span: number;
|
||||
offset: number;
|
||||
}
|
||||
|
||||
export interface FormItemProps {
|
||||
prefixCls?: string;
|
||||
id?: string;
|
||||
label?: string;
|
||||
labelCol?: FormItemLabelColOption;
|
||||
wrapperCol?: FormItemLabelColOption;
|
||||
help?: React.ReactNode;
|
||||
extra?: string;
|
||||
validateStatus?: 'success' | 'warning' | 'error' | 'validating';
|
||||
hasFeedback?: boolean;
|
||||
className?: string;
|
||||
required?: boolean;
|
||||
style?: React.CSSProperties;
|
||||
colon?: boolean;
|
||||
}
|
||||
|
||||
export interface FormItemContext {
|
||||
form: WrappedFormUtils;
|
||||
}
|
||||
|
||||
export default class FormItem extends React.Component<FormItemProps, any> {
|
||||
static defaultProps = {
|
||||
hasFeedback: false,
|
||||
prefixCls: 'ant-form',
|
||||
@ -14,7 +40,7 @@ export default class FormItem extends React.Component {
|
||||
|
||||
static propTypes = {
|
||||
prefixCls: React.PropTypes.string,
|
||||
label: React.PropTypes.node,
|
||||
label: React.PropTypes.string,
|
||||
labelCol: React.PropTypes.object,
|
||||
help: React.PropTypes.oneOfType([React.PropTypes.node, React.PropTypes.bool]),
|
||||
validateStatus: React.PropTypes.oneOf(['', 'success', 'warning', 'error', 'validating']),
|
||||
@ -30,6 +56,8 @@ export default class FormItem extends React.Component {
|
||||
form: React.PropTypes.object,
|
||||
};
|
||||
|
||||
context: FormItemContext;
|
||||
|
||||
shouldComponentUpdate(...args) {
|
||||
return PureRenderMixin.shouldComponentUpdate.apply(this, args);
|
||||
}
|
||||
@ -46,14 +74,14 @@ export default class FormItem extends React.Component {
|
||||
|
||||
getOnlyControl() {
|
||||
const children = React.Children.toArray(this.props.children);
|
||||
const child = children.filter((c) => {
|
||||
const child = children.filter((c: React.ReactElement<any>) => {
|
||||
return c.props && FIELD_META_PROP in c.props;
|
||||
})[0];
|
||||
return child !== undefined ? child : null;
|
||||
}
|
||||
|
||||
getChildProp(prop) {
|
||||
const child = this.getOnlyControl();
|
||||
const child = this.getOnlyControl() as React.ReactElement<any>;
|
||||
return child && child.props && child.props[prop];
|
||||
}
|
||||
|
||||
@ -173,7 +201,7 @@ export default class FormItem extends React.Component {
|
||||
|
||||
renderChildren() {
|
||||
const props = this.props;
|
||||
const children = React.Children.map(props.children, (child) => {
|
||||
const children = React.Children.map(props.children, (child: React.ReactElement<any>) => {
|
||||
if (child && typeof child.type === 'function' && !child.props.size) {
|
||||
return React.cloneElement(child, { size: 'large' });
|
||||
}
|
||||
|
@ -1,22 +0,0 @@
|
||||
import assign from 'object-assign';
|
||||
const ValueMixin = {
|
||||
setValue(field, e) {
|
||||
let v = e;
|
||||
const target = e && e.target;
|
||||
if (target) {
|
||||
if ((`${target.nodeName}`).toLowerCase() === 'input' &&
|
||||
target.type === 'checkbox') {
|
||||
v = target.checked;
|
||||
} else {
|
||||
v = e.target.value;
|
||||
}
|
||||
}
|
||||
const newFormData = {};
|
||||
newFormData[field] = v;
|
||||
this.setState({
|
||||
formData: assign({}, this.state.formData, newFormData),
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export default ValueMixin;
|
@ -31,7 +31,7 @@ let BasicDemo = React.createClass({
|
||||
handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
this.props.form.validateFields((errors, values) => {
|
||||
if (!!errors) {
|
||||
if (errors) {
|
||||
console.log('Errors in form!!!');
|
||||
return;
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ let Demo = React.createClass({
|
||||
|
||||
handleSubmit() {
|
||||
this.props.form.validateFields((errors, values) => {
|
||||
if (!!errors) {
|
||||
if (errors) {
|
||||
console.log('Errors in form!!!');
|
||||
return;
|
||||
}
|
||||
@ -60,17 +60,14 @@ let Demo = React.createClass({
|
||||
} else {
|
||||
strength = 'H';
|
||||
}
|
||||
if (type === 'pass') {
|
||||
this.setState({ passBarShow: true, passStrength: strength });
|
||||
this.setState({
|
||||
[`${type}BarShow`]: true,
|
||||
[`${type}Strength`]: strength,
|
||||
});
|
||||
} else {
|
||||
this.setState({ rePassBarShow: true, rePassStrength: strength });
|
||||
}
|
||||
} else {
|
||||
if (type === 'pass') {
|
||||
this.setState({ passBarShow: false });
|
||||
} else {
|
||||
this.setState({ rePassBarShow: false });
|
||||
}
|
||||
this.setState({
|
||||
[`${type}BarShow`]: false,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
@ -113,9 +110,9 @@ let Demo = React.createClass({
|
||||
return (
|
||||
<div>
|
||||
<ul className={classSet}>
|
||||
<li className="ant-pwd-strength-item ant-pwd-strength-item-1"></li>
|
||||
<li className="ant-pwd-strength-item ant-pwd-strength-item-2"></li>
|
||||
<li className="ant-pwd-strength-item ant-pwd-strength-item-3"></li>
|
||||
<li className="ant-pwd-strength-item ant-pwd-strength-item-1" />
|
||||
<li className="ant-pwd-strength-item ant-pwd-strength-item-2" />
|
||||
<li className="ant-pwd-strength-item ant-pwd-strength-item-3" />
|
||||
<span className="ant-form-text">
|
||||
{level[strength]}
|
||||
</span>
|
||||
|
@ -37,7 +37,7 @@ let Demo = React.createClass({
|
||||
handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
this.props.form.validateFieldsAndScroll((errors, values) => {
|
||||
if (!!errors) {
|
||||
if (errors) {
|
||||
console.log('Errors in form!!!');
|
||||
return;
|
||||
}
|
||||
|
@ -101,7 +101,8 @@ The return value of `getFieldProps` contains `id`、`value`(or any other props `
|
||||
|
||||
### Form.Item
|
||||
|
||||
> If Form.Item has multiple children, `help`, `required`, and `validateStatus` can't be generated automatically.
|
||||
> * If Form.Item has multiple children, `help`, `required`, and `validateStatus` can't be generated automatically.
|
||||
> * Form controls must be child of Form.Item, otherwise, you need to set `help`, `required` and `validateStatus` by yourself.
|
||||
|
||||
| Property | Description | Type | Optional | Default Value |
|
||||
|-----------|------------------------------------------|-----------|-------|--------|
|
||||
|
@ -1,40 +1,3 @@
|
||||
import React, { PropTypes } from 'react';
|
||||
import createDOMForm from 'rc-form/lib/createDOMForm';
|
||||
import Form from './Form';
|
||||
import FormItem from './FormItem';
|
||||
import ValueMixin from './ValueMixin';
|
||||
import assign from 'object-assign';
|
||||
import { FIELD_META_PROP } from './constants';
|
||||
|
||||
Form.create = (o = {}) => {
|
||||
const options = assign({}, o, {
|
||||
fieldNameProp: 'id',
|
||||
fieldMetaProp: FIELD_META_PROP,
|
||||
});
|
||||
const formWrapper = createDOMForm(options);
|
||||
|
||||
/* eslint-disable react/prefer-es6-class */
|
||||
return (Component) => formWrapper(React.createClass({
|
||||
propTypes: {
|
||||
form: PropTypes.object.isRequired,
|
||||
},
|
||||
childContextTypes: {
|
||||
form: PropTypes.object.isRequired,
|
||||
},
|
||||
getChildContext() {
|
||||
return {
|
||||
form: this.props.form,
|
||||
};
|
||||
},
|
||||
render() {
|
||||
return <Component {...this.props} />;
|
||||
},
|
||||
}));
|
||||
};
|
||||
|
||||
Form.Item = FormItem;
|
||||
|
||||
// @Deprecated
|
||||
Form.ValueMixin = ValueMixin;
|
||||
|
||||
export default Form;
|
||||
|
@ -103,7 +103,8 @@ CustomizedForm = Form.create({})(CustomizedForm);
|
||||
|
||||
### Form.Item
|
||||
|
||||
> 一个 Form.Item 建议只放一个 child,有多个 child 时,`help` `required` `validateStatus` 无法自动生成。
|
||||
> * 一个 Form.Item 建议只放一个 child,有多个 child 时,`help` `required` `validateStatus` 无法自动生成。
|
||||
> * 只有当表单域为 Form.Item 的子元素时,才会自动生成 `help` `required` `validateStatus`,其它情况请自行设置。
|
||||
|
||||
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|
||||
|-----------|------------------------------------------|-----------|-------|--------|
|
||||
|
125
components/icon/index.en-US.md
Normal file
125
components/icon/index.en-US.md
Normal file
@ -0,0 +1,125 @@
|
||||
---
|
||||
category: Components
|
||||
chinese: 图标
|
||||
type: Basic
|
||||
english: Icon
|
||||
toc: false
|
||||
---
|
||||
|
||||
Meaningful vector graphics.
|
||||
|
||||
## Icons naming convention
|
||||
|
||||
We provide semantic name for every icon, and naming rules are as follows:
|
||||
|
||||
- Scanning line icon has the similar name with its solid one,but it's distinguished by `-o`, for example, `question-circle`(a full circle) and `question-circle-o`(an empty circle);
|
||||
|
||||
- Naming sequence:`[icon's name]-[shape, optional]-[Scanning line or not]-[direction, optional]`.
|
||||
|
||||
## How to use
|
||||
|
||||
Use tag <Icon /> to create an icon and set its type in the type prop, for example:
|
||||
|
||||
```html
|
||||
<Icon type="link" />
|
||||
```
|
||||
|
||||
Finally, it will be rendered as follow:
|
||||
|
||||
```html
|
||||
<i class="anticon anticon-${type}"></i>
|
||||
```
|
||||
|
||||
## Local deployment of icons font
|
||||
|
||||
By default, icon components uses [iconfont.cn](http://iconfont.cn), publicly available repository of a huge set of icons. In case you need to use a locally deployed version of the icon font, you can refer to [this example](https://github.com/ant-design/antd-init/tree/master/examples/local-iconfont)。
|
||||
|
||||
## List of icons
|
||||
|
||||
> Click the icon and copy the code。
|
||||
|
||||
### 一. Directional Icons
|
||||
|
||||
```__react
|
||||
import IconSet from 'site/theme/template/IconSet';
|
||||
const icons1 = ['step-backward', 'step-forward', 'fast-backward', 'fast-forward', 'shrink', 'arrow-salt', 'down', 'up', 'left', 'right', 'caret-down', 'caret-up', 'caret-left', 'caret-right', 'caret-circle-right', 'caret-circle-left', 'caret-circle-o-right', 'caret-circle-o-left', 'circle-right', 'circle-left', 'circle-o-right', 'circle-o-left', 'double-right', 'double-left', 'verticle-right', 'verticle-left', 'forward', 'backward', 'rollback', 'enter', 'retweet', 'swap', 'swap-left', 'swap-right', 'arrow-right', 'arrow-up', 'arrow-down', 'arrow-left', 'play-circle', 'play-circle-o', 'circle-up', 'circle-down', 'circle-o-up', 'circle-o-down', 'caret-circle-o-up', 'caret-circle-o-down', 'caret-circle-up', 'caret-circle-down'];
|
||||
|
||||
ReactDOM.render(<IconSet className="icons" icons={icons1} key="icons1" />, mountNode);
|
||||
```
|
||||
|
||||
### 二. Suggested Icons
|
||||
|
||||
```__react
|
||||
const icons2 = ['question', 'question-circle-o', 'question-circle', 'plus', 'plus-circle-o', 'plus-circle', 'pause', 'pause-circle-o', 'pause-circle', 'minus', 'minus-circle-o', 'minus-circle', 'plus-square', 'minus-square', 'info', 'info-circle-o', 'info-circle', 'exclamation', 'exclamation-circle-o', 'exclamation-circle', 'cross', 'cross-circle-o', 'cross-circle', 'check', 'check-circle-o', 'check-circle', 'clock-circle-o', 'clock-circle'];
|
||||
|
||||
ReactDOM.render(<IconSet className="icons" icons={icons2} key="icons2" />, mountNode);
|
||||
```
|
||||
|
||||
### 三. Universal Icons
|
||||
|
||||
```__react
|
||||
const icons3 = ['lock', 'unlock', 'android', 'apple', 'area-chart', 'bar-chart', 'bars', 'book', 'calendar', 'cloud', 'cloud-download', 'code', 'copy', 'credit-card', 'delete', 'desktop', 'download', 'edit', 'ellipsis', 'file', 'file-text', 'file-unknown', 'file-pdf','file-excel', 'file-jpg', 'file-ppt', 'folder', 'folder-open', 'github', 'hdd', 'frown', 'meh', 'inbox', 'laptop', 'appstore-o', 'appstore', 'line-chart', 'link', 'logout', 'mail', 'menu-fold', 'menu-unfold', 'mobile', 'notification', 'paper-clip', 'picture', 'pie-chart', 'poweroff', 'reload', 'search', 'setting', 'share-alt', 'shopping-cart', 'smile', 'tablet', 'tag', 'tags', 'to-top', 'upload', 'user', 'video-camera', 'windows', 'ie', 'chrome', 'home', 'loading', 'smile-circle', 'meh-circle', 'frown-circle', 'tags-o', 'tag-o', 'cloud-upload-o', 'cloud-download-o', 'cloud-upload', 'cloud-o', 'star-o', 'star', 'heart-o', 'heart', 'environment', 'environment-o', 'eye', 'eye-o', 'camera', 'camera-o', 'aliwangwang', 'aliwangwang-o', 'save', 'team', 'solution', 'phone', 'filter', 'exception', 'export', 'customerservice', 'qrcode', 'scan', 'like', 'dislike', 'message', 'pay-circle', 'pay-circle-o', 'calculator', 'pushpin', 'pushpin-o'];
|
||||
|
||||
ReactDOM.render(<IconSet className="icons" icons={icons3} key="icons3" />, mountNode);
|
||||
```
|
||||
|
||||
|
||||
<style>
|
||||
.markdown .icons {
|
||||
width: 100%;
|
||||
}
|
||||
ul.anticons-list {
|
||||
margin: 20px 0;
|
||||
list-style: none;
|
||||
overflow: hidden;
|
||||
}
|
||||
ul.anticons-list li {
|
||||
float: left;
|
||||
margin: 6px 6px 6px 0;
|
||||
width: 145px;
|
||||
text-align: center;
|
||||
list-style: none;
|
||||
cursor: pointer;
|
||||
height: 100px;
|
||||
color: #5C6B77;
|
||||
transition: all 0.2s ease;
|
||||
position: relative;
|
||||
padding-top: 10px;
|
||||
}
|
||||
ul.anticons-list li:hover {
|
||||
background-color: #4BB8FF;
|
||||
color: #fff;
|
||||
border-radius: 4px;
|
||||
}
|
||||
ul.anticons-list li.copied:hover {
|
||||
color: rgba(255,255,255,0.2);
|
||||
}
|
||||
ul.anticons-list li:after {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
content: "Copied!";
|
||||
text-align: center;
|
||||
line-height: 110px;
|
||||
color: #fff;
|
||||
transition: all 0.3s cubic-bezier(0.18, 0.89, 0.32, 1.28);
|
||||
opacity: 0;
|
||||
}
|
||||
ul.anticons-list li.copied:after {
|
||||
opacity: 1;
|
||||
top: 0;
|
||||
}
|
||||
.anticon {
|
||||
font-size: 26px;
|
||||
margin: 12px 0 16px;
|
||||
}
|
||||
.anticon-class {
|
||||
display: block;
|
||||
text-align: center;
|
||||
transform: scale(0.83);
|
||||
font-family: Consolas;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
@ -1,6 +1,13 @@
|
||||
import * as React from 'react';
|
||||
|
||||
export default props => {
|
||||
export interface IconProps {
|
||||
type: string;
|
||||
className?: string;
|
||||
title?: string;
|
||||
onClick?: (e) => void;
|
||||
}
|
||||
|
||||
export default (props: IconProps) => {
|
||||
const { type, className = '' } = props;
|
||||
return <i {...props} className={`${className} anticon anticon-${type}`.trim()} />;
|
||||
};
|
||||
|
@ -1,10 +1,18 @@
|
||||
---
|
||||
order: 0
|
||||
title: 基本
|
||||
title:
|
||||
zh-CN: 基本
|
||||
en-US: Basic
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
数字输入框。
|
||||
|
||||
## en-US
|
||||
|
||||
Numeric-only input box.
|
||||
|
||||
````jsx
|
||||
import { InputNumber } from 'antd';
|
||||
|
||||
|
@ -1,10 +1,18 @@
|
||||
---
|
||||
order: 3
|
||||
title: 小数
|
||||
title:
|
||||
zh-CN: 小数
|
||||
en-US: Decimals
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
和原生的数字输入框一样,value 的精度由 step 的小数位数决定。
|
||||
|
||||
## en-US
|
||||
|
||||
A numeric-only input box whose values can be increased or decreased using a decimal step. The number of decimals (also known as precision) is determined by the step prop.
|
||||
|
||||
````jsx
|
||||
import { InputNumber } from 'antd';
|
||||
|
||||
|
@ -1,10 +1,18 @@
|
||||
---
|
||||
order: 2
|
||||
title: 不可用
|
||||
title:
|
||||
zh-CN: 不可用
|
||||
en-US: Disabled
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
点击按钮切换可用状态。
|
||||
|
||||
## en-US
|
||||
|
||||
Click the button to toggle between available and disabled states.
|
||||
|
||||
````jsx
|
||||
import { InputNumber, Button } from 'antd';
|
||||
|
||||
|
@ -1,10 +1,18 @@
|
||||
---
|
||||
order: 1
|
||||
title: 三种大小
|
||||
title:
|
||||
zh-CN: 三种大小
|
||||
en-US: Sizes
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
三种大小的数字输入框,当 size 分别为 `large` 和 `small` 时,输入框高度为 `32px` 和 `22px` ,默认高度为 `28px`
|
||||
|
||||
## en-US
|
||||
|
||||
There are three sizes available to a numeric input box. By default, the size is `28px`. The two additional sizes are `large` and `small` which means `32px` and `22px`, respectively.
|
||||
|
||||
````jsx
|
||||
import { InputNumber } from 'antd';
|
||||
|
||||
|
25
components/input-number/index.en-US.md
Normal file
25
components/input-number/index.en-US.md
Normal file
@ -0,0 +1,25 @@
|
||||
---
|
||||
category: Components
|
||||
chinese: 数字输入框
|
||||
type: Form Controls
|
||||
english: InputNumber
|
||||
---
|
||||
|
||||
Enter a number within certain range with the mouse or keyboard.
|
||||
|
||||
## When to use
|
||||
|
||||
When a numeric value needs to be provided.
|
||||
|
||||
## API
|
||||
|
||||
| property | description | type | default |
|
||||
|-------------|----------------|--------------------|--------------|
|
||||
| min | min value | Number | -Infinity |
|
||||
| max | max vale | Number | Infinity |
|
||||
| value | current value | Number | |
|
||||
| step | The number to which the current value is increased or decreased. It can be an integer or decimal. | Number or String | 1 |
|
||||
| defaultValue | initial value | Number | |
|
||||
| onChange | The callback triggered when the value is changed. | Function | |
|
||||
| disabled | disable the input | Boolean | false |
|
||||
| size | width of input box | String | none |
|
@ -3,7 +3,19 @@ import classNames from 'classnames';
|
||||
import RcInputNumber from 'rc-input-number';
|
||||
import splitObject from '../_util/splitObject';
|
||||
|
||||
export default class InputNumber extends React.Component {
|
||||
export interface InputNumberProps {
|
||||
prefixCls?: string;
|
||||
min?: number;
|
||||
max?: number;
|
||||
value?: number;
|
||||
step?: number | string;
|
||||
defaultValue?: number;
|
||||
onChange?: (value: number) => void;
|
||||
disabled?: boolean;
|
||||
size?: 'large' | 'small' | 'default';
|
||||
}
|
||||
|
||||
export default class InputNumber extends React.Component<InputNumberProps, any> {
|
||||
static defaultProps = {
|
||||
prefixCls: 'ant-input-number',
|
||||
step: 1,
|
||||
|
@ -1,7 +1,14 @@
|
||||
import * as React from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
export default function Group(props) {
|
||||
export interface GroupProps {
|
||||
className?: string;
|
||||
size?: 'large' | 'small' | 'default';
|
||||
children?: any;
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
|
||||
const Group: React.StatelessComponent<GroupProps> = (props) => {
|
||||
const className = classNames({
|
||||
'ant-input-group': true,
|
||||
'ant-input-group-lg': props.size === 'large',
|
||||
@ -13,8 +20,10 @@ export default function Group(props) {
|
||||
{props.children}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
Group.propTypes = {
|
||||
children: React.PropTypes.any,
|
||||
};
|
||||
|
||||
export default Group;
|
||||
|
@ -27,7 +27,32 @@ function clearNextFrameAction(nextFrameId) {
|
||||
}
|
||||
}
|
||||
|
||||
export default class Input extends Component {
|
||||
interface AutoSizeType {
|
||||
minRows?: number;
|
||||
maxRows?: number;
|
||||
};
|
||||
|
||||
export interface InputProps {
|
||||
prefixCls?: string;
|
||||
className?: string;
|
||||
type: string;
|
||||
id?: number | string;
|
||||
value?: any;
|
||||
defaultValue?: any;
|
||||
placeholder?: string;
|
||||
size?: 'large' | 'default' | 'small';
|
||||
disabled?: boolean;
|
||||
readOnly?: boolean;
|
||||
addonBefore?: React.ReactNode;
|
||||
addonAfter?: React.ReactNode;
|
||||
onPressEnter?: React.FormEventHandler;
|
||||
onKeyDown?: React.FormEventHandler;
|
||||
onChange?: React.FormEventHandler;
|
||||
autosize?: boolean | AutoSizeType;
|
||||
}
|
||||
|
||||
export default class Input extends Component<InputProps, any> {
|
||||
static Group: any;
|
||||
static defaultProps = {
|
||||
defaultValue: '',
|
||||
disabled: false,
|
||||
@ -58,6 +83,12 @@ export default class Input extends Component {
|
||||
onKeyDown: PropTypes.func,
|
||||
};
|
||||
|
||||
nextFrameActionId: number;
|
||||
refs: {
|
||||
[key: string]: any;
|
||||
input: any;
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
@ -98,8 +129,8 @@ export default class Input extends Component {
|
||||
if (type !== 'textarea' || !autosize || !this.refs.input) {
|
||||
return;
|
||||
}
|
||||
const minRows = autosize ? autosize.minRows : null;
|
||||
const maxRows = autosize ? autosize.maxRows : null;
|
||||
const minRows = autosize ? (autosize as AutoSizeType).minRows : null;
|
||||
const maxRows = autosize ? (autosize as AutoSizeType).maxRows : null;
|
||||
const textareaStyles = calculateNodeHeight(this.refs.input, false, minRows, maxRows);
|
||||
this.setState({ textareaStyles });
|
||||
}
|
||||
|
@ -1,10 +1,18 @@
|
||||
---
|
||||
order: 2
|
||||
title: 前置/后置标签
|
||||
title:
|
||||
zh-CN: 前置/后置标签
|
||||
en-US: Pre / Post tab
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
用于配置一些固定组合。
|
||||
|
||||
## en-US
|
||||
|
||||
Using pre & post tabs example.
|
||||
|
||||
````jsx
|
||||
import { Input, Select } from 'antd';
|
||||
const Option = Select.Option;
|
||||
|
@ -1,18 +1,28 @@
|
||||
---
|
||||
order: 6
|
||||
title: 适应文本高度的文本域
|
||||
title:
|
||||
zh-CN: 适应文本高度的文本域
|
||||
en-US: Autosizing the height to fit the content
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
`autosize` 属性适用于 `textarea` 节点,并且只有高度会自动变化。另外 `autosize` 可以设定为一个对象,指定最小行数和最大行数。
|
||||
|
||||
## en-US
|
||||
|
||||
`autosize` prop for a `textarea` type of `Input` makes the height to automatically adjust based on the content.
|
||||
An options object can be provided to `autosize` to specify the minimum and maximum number of lines the textarea will automatically adjust.
|
||||
|
||||
|
||||
````jsx
|
||||
import { Input } from 'antd';
|
||||
|
||||
ReactDOM.render(
|
||||
<div>
|
||||
<Input type="textarea" placeholder="自适应内容高度" autosize />
|
||||
<Input type="textarea" placeholder="Autosize height based on content lines" autosize />
|
||||
<div style={{ margin: '24px 0' }} />
|
||||
<Input type="textarea" placeholder="有最大高度和最小高度" autosize={{ minRows: 2, maxRows: 6 }} />
|
||||
<Input type="textarea" placeholder="Autosize height with minimum and maximum number of lines" autosize={{ minRows: 2, maxRows: 6 }} />
|
||||
</div>
|
||||
, mountNode);
|
||||
````
|
||||
|
@ -1,10 +1,18 @@
|
||||
---
|
||||
order: 0
|
||||
title: 基本使用
|
||||
title:
|
||||
zh-CN: 基本使用
|
||||
en-US: Basic usage
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
基本使用。
|
||||
|
||||
## en-US
|
||||
|
||||
Basic usage example
|
||||
|
||||
````jsx
|
||||
import { Input } from 'antd';
|
||||
|
||||
|
@ -1,10 +1,18 @@
|
||||
---
|
||||
order: 3
|
||||
title: 输入框组合
|
||||
title:
|
||||
zh-CN: 输入框组合
|
||||
en-US: Input Group
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
输入框的组合展现。
|
||||
|
||||
## en-US
|
||||
|
||||
Input.Group example
|
||||
|
||||
````jsx
|
||||
import { Input, Col } from 'antd';
|
||||
const InputGroup = Input.Group;
|
||||
|
@ -1,10 +1,18 @@
|
||||
---
|
||||
order: 4
|
||||
title: 搜索框
|
||||
title:
|
||||
zh-CN: 搜索框
|
||||
en-US: Search box
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
带有搜索按钮的输入框。
|
||||
|
||||
## en-US
|
||||
|
||||
Example of creating a search box by grouping a standard input with a search button.
|
||||
|
||||
````jsx
|
||||
import { Input, Button } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
|
@ -1,20 +1,30 @@
|
||||
---
|
||||
order: 1
|
||||
title: 三种大小
|
||||
title:
|
||||
zh-CN: 三种大小
|
||||
en-US: Three sizes of Input
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
我们为 `<Input />` 输入框定义了三种尺寸(大、默认、小),高度分别为 `32px`、`28px` 和 `22px`。
|
||||
|
||||
注意: 在表单里面,我们只使用大尺寸的输入框。
|
||||
|
||||
## en-US
|
||||
|
||||
There are three sizes of an Input box: `large` (32px)、`default` (28px) and `small` (22px).
|
||||
|
||||
Note: Inside of forms, only the large size is used.
|
||||
|
||||
````jsx
|
||||
import { Input } from 'antd';
|
||||
|
||||
ReactDOM.render(
|
||||
<div className="example-input">
|
||||
<Input size="large" placeholder="大尺寸" />
|
||||
<Input placeholder="默认尺寸" />
|
||||
<Input size="small" placeholder="小尺寸" />
|
||||
<Input size="large" placeholder="large size" />
|
||||
<Input placeholder="default size" />
|
||||
<Input size="small" placeholder="small size" />
|
||||
</div>
|
||||
, mountNode);
|
||||
````
|
||||
|
@ -1,10 +1,18 @@
|
||||
---
|
||||
order: 5
|
||||
title: 文本域
|
||||
title:
|
||||
zh-CN: 文本域
|
||||
en-US: Textarea
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
用于多行输入,指定 `type` 为一个特殊的 `textarea`。
|
||||
|
||||
## en-US
|
||||
|
||||
For multi-line user input cases, an input whose `type` prop has the value of `"textarea"` can be used.
|
||||
|
||||
````jsx
|
||||
import { Input } from 'antd';
|
||||
|
||||
|
47
components/input/index.en-US.md
Normal file
47
components/input/index.en-US.md
Normal file
@ -0,0 +1,47 @@
|
||||
---
|
||||
category: Components
|
||||
chinese: 输入框
|
||||
type: Form Controls
|
||||
english: Input
|
||||
---
|
||||
|
||||
A basic widget for getting the user input is a text field.
|
||||
Keyboard and mouse can be used for providing or changing data.
|
||||
|
||||
## When to Use
|
||||
|
||||
- A user input in a form field is needed.
|
||||
- A search input is required.
|
||||
|
||||
## API
|
||||
|
||||
### Input
|
||||
|
||||
| Property | Description | Type | Available Values | Default |
|
||||
|----------------|-----------------------|----------|------------------|---------------|
|
||||
| type | The type of input. For a multi-line input, the 'textarea' value can be used. | string | 'text' or 'textarea' | 'text' |
|
||||
| id | The identifier. | number or string | | |
|
||||
| value | The content value. | any | | |
|
||||
| defaultValue | The initial value. | any | | |
|
||||
| size | The size of the input box. The implicit value is 'default'. Note: in the context of a form, the 'large' size is used. | string | {'large','default','small'} | 'default' |
|
||||
| disabled | Tell if the input is disabled. | bool | | false |
|
||||
| addonBefore | The label text displayed before (on the left side of) the input field. | node | | |
|
||||
| addonAfter | The label text displayed after (on the right side of) the input field. | node | | |
|
||||
| onPressEnter | The callback function that is triggered when pressing Enter key. | function(e) | | |
|
||||
| autosize | Height autosize feature, available when type="textarea". | bool or object | `true` or `{ minRows: 2, maxRows: 6 }` | false |
|
||||
|
||||
> When `Input` is used in a `Form.Item` context, if the `Form.Item` has the `id` and `options` props defined
|
||||
then `value`, `defaultValue`, and `id` props are automatically set.
|
||||
|
||||
#### Input.Group
|
||||
|
||||
| Property | Description | Type | Available Values | Default |
|
||||
|-----------|----------------------------------|--------|-----------------------------|-----------|
|
||||
| size | The size of `Input.Group` specifies the size of the included `Input` fields. | string | {'large','default','small'} | 'default' |
|
||||
|
||||
```html
|
||||
<Input.Group className={string}>
|
||||
<Input />
|
||||
<Input />
|
||||
</Input.Group>
|
||||
```
|
@ -1,17 +1,39 @@
|
||||
import { PropTypes } from 'react';
|
||||
import * as React from 'react';
|
||||
import { PropTypes } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import assign from 'object-assign';
|
||||
const stringOrNumber = PropTypes.oneOfType([PropTypes.string, PropTypes.number]);
|
||||
const objectOrNumber = PropTypes.oneOfType([PropTypes.object, PropTypes.number]);
|
||||
import splitObject from '../_util/splitObject';
|
||||
|
||||
export default function Col(props) {
|
||||
const stringOrNumber = PropTypes.oneOfType([PropTypes.string, PropTypes.number]);
|
||||
const objectOrNumber = PropTypes.oneOfType([PropTypes.object, PropTypes.number]);
|
||||
|
||||
interface ColSize {
|
||||
span?: number;
|
||||
order?: number;
|
||||
offset?: number;
|
||||
push?: number;
|
||||
pull?: number;
|
||||
}
|
||||
|
||||
export interface ColProps {
|
||||
className?: string;
|
||||
span?: number;
|
||||
order?: number;
|
||||
offset?: number;
|
||||
push?: number;
|
||||
pull?: number;
|
||||
xs?: ColSize;
|
||||
sm?: ColSize;
|
||||
md?: ColSize;
|
||||
lg?: ColSize;
|
||||
}
|
||||
|
||||
const Col: React.StatelessComponent<ColProps> = (props) => {
|
||||
const [{ span, order, offset, push, pull, className, children }, others] = splitObject(props,
|
||||
['span', 'order', 'offset', 'push', 'pull', 'className', 'children']);
|
||||
let sizeClassObj = {};
|
||||
['xs', 'sm', 'md', 'lg'].forEach(size => {
|
||||
let sizeProps = {};
|
||||
let sizeProps: ColSize = {};
|
||||
if (typeof props[size] === 'number') {
|
||||
sizeProps.span = props[size];
|
||||
} else if (typeof props[size] === 'object') {
|
||||
@ -38,7 +60,7 @@ export default function Col(props) {
|
||||
}, sizeClassObj));
|
||||
|
||||
return <div {...others} className={classes}>{children}</div>;
|
||||
}
|
||||
};
|
||||
|
||||
Col.propTypes = {
|
||||
span: stringOrNumber,
|
||||
@ -53,3 +75,5 @@ Col.propTypes = {
|
||||
md: objectOrNumber,
|
||||
lg: objectOrNumber,
|
||||
};
|
||||
|
||||
export default Col;
|
||||
|
@ -92,8 +92,8 @@ Ant Design layout component if it can not meet your needs, you can use the excel
|
||||
|------------|-----------------|--------------------|-------------|
|
||||
| gutter | grid spacing | number | 0 |
|
||||
| type | layout mode, the optional `flex`, effective modern browser | string | |
|
||||
| align | the vertical alignment of the layout of flex: `top`` middle` `bottom` | string | `top` |
|
||||
| justify | horizontal arrangement of the layout of flex: `start`` end` `center`` space-around` `space-between` | string | `start` |
|
||||
| align | the vertical alignment of the layout of flex: `top` ` middle` `bottom` | string | `top` |
|
||||
| justify | horizontal arrangement of the layout of flex: `start` ` end` `center` ` space-around` `space-between` | string | `start` |
|
||||
|
||||
### Col
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
category: Components
|
||||
chinese: 布局
|
||||
chinese: 栅格
|
||||
type: Basic
|
||||
cols: 1
|
||||
english: Layout
|
||||
|
@ -1,8 +1,19 @@
|
||||
import React, { Children, cloneElement } from 'react';
|
||||
import * as React from 'react';
|
||||
import { Children, cloneElement } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import assign from 'object-assign';
|
||||
import splitObject from '../_util/splitObject';
|
||||
export default class Row extends React.Component {
|
||||
|
||||
export interface RowProps {
|
||||
className?: string;
|
||||
gutter?: number;
|
||||
type?: 'flex';
|
||||
align?: 'top' | 'middle' | 'bottom';
|
||||
justify?: 'start' | 'end' | 'center' | 'space-around' | 'space-between';
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
|
||||
export default class Row extends React.Component<RowProps, any> {
|
||||
static defaultProps = {
|
||||
gutter: 0,
|
||||
};
|
||||
@ -28,7 +39,7 @@ export default class Row extends React.Component {
|
||||
marginLeft: gutter / -2,
|
||||
marginRight: gutter / -2,
|
||||
}, style) : style;
|
||||
const cols = Children.map(children, col => {
|
||||
const cols = Children.map(children, (col: React.ReactElement<any>) => {
|
||||
if (!col) {
|
||||
return null;
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ title:
|
||||
|
||||
## zh-CN
|
||||
|
||||
此处列出 Ant Design 中需要国际化支持的组件,你可以在演示里切换语言。
|
||||
此处列出 Ant Design 中需要国际化支持的组件,你可以在演示里切换语言。涉及时间的组件请注意时区设置 [DatePicker](/components/date-picker/#components-date-picker-demo-locale)。
|
||||
|
||||
## en-US
|
||||
|
||||
@ -32,6 +32,12 @@ const columns = [{
|
||||
dataIndex: 'age',
|
||||
}];
|
||||
|
||||
const customLocale = {
|
||||
timezoneOffset: 8 * 60,
|
||||
firstDayOfWeek: 1,
|
||||
minimalDaysInFirstWeek: 1,
|
||||
};
|
||||
|
||||
const Page = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
@ -112,6 +118,10 @@ const App = React.createClass({
|
||||
this.setState({ locale: e.target.value });
|
||||
},
|
||||
render() {
|
||||
const locale = { ...this.state.locale };
|
||||
if (locale.DatePicker) {
|
||||
locale.DatePicker = { ...locale.DatePicker, ...customLocale };
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<div className="change-locale">
|
||||
@ -121,7 +131,7 @@ const App = React.createClass({
|
||||
<Radio.Button key="cn">中文</Radio.Button>
|
||||
</Radio.Group>
|
||||
</div>
|
||||
<LocaleProvider locale={this.state.locale}><Page /></LocaleProvider>
|
||||
<LocaleProvider locale={locale}><Page /></LocaleProvider>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
@ -29,7 +29,7 @@ let App = React.createClass({
|
||||
handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
this.props.form.validateFields((errors, values) => {
|
||||
if (!!errors) {
|
||||
if (errors) {
|
||||
console.log('Errors in form!!!');
|
||||
return;
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ const App = React.createClass({
|
||||
</MenuItemGroup>
|
||||
</SubMenu>
|
||||
<Menu.Item key="alipay">
|
||||
<a href="http://www.alipay.com/" target="_blank">导航四 - 链接</a>
|
||||
<a href="http://www.alipay.com/" target="_blank" rel="noopener noreferrer">导航四 - 链接</a>
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
|
@ -89,6 +89,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
&-horizontal,
|
||||
&-inline,
|
||||
&-vertical {
|
||||
z-index: auto;
|
||||
}
|
||||
|
||||
&-inline,
|
||||
&-vertical {
|
||||
border-right: 1px solid @border-color-split;
|
||||
|
@ -7,7 +7,12 @@ import classNames from 'classnames';
|
||||
import { getConfirmLocale } from './locale';
|
||||
import assign from 'object-assign';
|
||||
|
||||
class ActionButton extends React.Component {
|
||||
export interface ActionButtonProps {
|
||||
type: 'primary' | 'ghost' | 'dashed';
|
||||
actionFn: Function;
|
||||
closeModal: Function;
|
||||
}
|
||||
class ActionButton extends React.Component<ActionButtonProps, any> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
|
@ -45,9 +45,11 @@ const Test = React.createClass({
|
||||
<Button type="primary" onClick={this.showModal}>
|
||||
Open modal dialog
|
||||
</Button>
|
||||
<Modal ref="modal"
|
||||
<Modal
|
||||
visible={this.state.visible}
|
||||
title="Title" onOk={this.handleOk} onCancel={this.handleCancel}
|
||||
title="Title"
|
||||
onOk={this.handleOk}
|
||||
onCancel={this.handleCancel}
|
||||
footer={[
|
||||
<Button key="back" type="ghost" size="large" onClick={this.handleCancel}>Return</Button>,
|
||||
<Button key="submit" type="primary" size="large" loading={this.state.loading} onClick={this.handleOk}>
|
||||
|
@ -57,7 +57,7 @@ export default class Pagination extends React.Component<PaginationProps, any> {
|
||||
|
||||
render() {
|
||||
let className = this.props.className;
|
||||
let selectComponentClass = Select;
|
||||
let selectComponentClass = Select as React.ReactNode;
|
||||
|
||||
let locale;
|
||||
if (this.context.antLocale && this.context.antLocale.Pagination) {
|
||||
|
@ -1 +1,2 @@
|
||||
module.exports = require('rc-pagination/lib/locale/en_US');
|
||||
import en_US from 'rc-pagination/lib/locale/en_US';
|
||||
export default en_US;
|
||||
|
@ -1 +1,2 @@
|
||||
module.exports = require('rc-pagination/lib/locale/zh_CN');
|
||||
import zh_CN from 'rc-pagination/lib/locale/zh_CN';
|
||||
export default zh_CN;
|
||||
|
@ -1,56 +0,0 @@
|
||||
---
|
||||
order: 1
|
||||
title: 进场和离场
|
||||
---
|
||||
|
||||
同时支持进场和离场动画。
|
||||
|
||||
````jsx
|
||||
import { QueueAnim, Button } from 'antd';
|
||||
|
||||
const Test = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
show: true,
|
||||
};
|
||||
},
|
||||
onClick() {
|
||||
this.setState({
|
||||
show: !this.state.show,
|
||||
});
|
||||
},
|
||||
render() {
|
||||
const list = this.state.show ? [
|
||||
<div className="demo-kp" key="a">
|
||||
<ul>
|
||||
<li></li>
|
||||
<li></li>
|
||||
<li></li>
|
||||
</ul>
|
||||
</div>,
|
||||
<div className="demo-listBox" key="b">
|
||||
<div className="demo-list">
|
||||
<div className="title"></div>
|
||||
<ul>
|
||||
<li></li>
|
||||
<li></li>
|
||||
<li></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>,
|
||||
] : null;
|
||||
return (
|
||||
<div>
|
||||
<p className="buttons">
|
||||
<Button type="primary" onClick={this.onClick}>切换</Button>
|
||||
</p>
|
||||
<QueueAnim className="demo-content">
|
||||
{list}
|
||||
</QueueAnim>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
ReactDOM.render(<Test />, mountNode);
|
||||
````
|
@ -1,67 +0,0 @@
|
||||
---
|
||||
order: 5
|
||||
title: 添加与删除
|
||||
---
|
||||
|
||||
场景里有增加或删除条目时也会触发动画。
|
||||
|
||||
````jsx
|
||||
import { QueueAnim, Button } from 'antd';
|
||||
|
||||
const Test = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
show: true,
|
||||
items: [
|
||||
<li key="0"></li>,
|
||||
<li key="1"></li>,
|
||||
<li key="2"></li>,
|
||||
],
|
||||
};
|
||||
},
|
||||
onClick() {
|
||||
this.setState({
|
||||
show: !this.state.show,
|
||||
});
|
||||
},
|
||||
onAdd() {
|
||||
const items = this.state.items;
|
||||
items.push(<li key={Date.now()}></li>);
|
||||
this.setState({
|
||||
show: true,
|
||||
items,
|
||||
});
|
||||
},
|
||||
onRemove() {
|
||||
const items = this.state.items;
|
||||
items.splice(items.length - 1, 1);
|
||||
this.setState({
|
||||
show: true,
|
||||
items,
|
||||
});
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<p className="buttons">
|
||||
<Button type="primary" onClick={this.onClick}>切换</Button>
|
||||
<Button onClick={this.onAdd} style={{ marginLeft: 10 }}>添加</Button>
|
||||
<Button onClick={this.onRemove} style={{ marginLeft: 10 }}>删除</Button>
|
||||
</p>
|
||||
<div className="demo-content">
|
||||
<div className="demo-listBox" key="b">
|
||||
<div className="demo-list">
|
||||
<div className="title"></div>
|
||||
<QueueAnim component="ul" type={['right', 'left']}>
|
||||
{this.state.show ? this.state.items : null}
|
||||
</QueueAnim>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
ReactDOM.render(<Test />, mountNode);
|
||||
````
|
@ -1,61 +0,0 @@
|
||||
---
|
||||
order: 3
|
||||
title: 自定义动画进出场
|
||||
---
|
||||
|
||||
通过 `animConfig` 来自定义动画进出场。
|
||||
|
||||
````jsx
|
||||
import { QueueAnim, Button } from 'antd';
|
||||
|
||||
const Test = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
show: true,
|
||||
};
|
||||
},
|
||||
onClick() {
|
||||
this.setState({
|
||||
show: !this.state.show,
|
||||
});
|
||||
},
|
||||
render() {
|
||||
const list = this.state.show ? [
|
||||
<div className="demo-kp" key="a">
|
||||
<ul>
|
||||
<li></li>
|
||||
<li></li>
|
||||
<li></li>
|
||||
</ul>
|
||||
</div>,
|
||||
<div className="demo-listBox" key="b">
|
||||
<div className="demo-list">
|
||||
<div className="title"></div>
|
||||
<ul>
|
||||
<li></li>
|
||||
<li></li>
|
||||
<li></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>,
|
||||
] : null;
|
||||
return (
|
||||
<div>
|
||||
<p className="buttons">
|
||||
<Button type="primary" onClick={this.onClick}>切换</Button>
|
||||
</p>
|
||||
<QueueAnim className="demo-content"
|
||||
animConfig={[
|
||||
{ opacity: [1, 0], translateY: [0, 50] },
|
||||
{ opacity: [1, 0], translateY: [0, -50] },
|
||||
]}
|
||||
>
|
||||
{list}
|
||||
</QueueAnim>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
ReactDOM.render(<Test />, mountNode);
|
||||
````
|
@ -1,60 +0,0 @@
|
||||
---
|
||||
order: 2
|
||||
title: 进场和离场
|
||||
---
|
||||
|
||||
通过把属性设置一个数组来分别表示进出场的效果,`type`、`animConfig`、`delay`、`duration`、`interval`、`ease` 等属性均支持配置为数组。
|
||||
|
||||
````jsx
|
||||
import { QueueAnim, Button } from 'antd';
|
||||
|
||||
const Test = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
show: true,
|
||||
};
|
||||
},
|
||||
onClick() {
|
||||
this.setState({
|
||||
show: !this.state.show,
|
||||
});
|
||||
},
|
||||
render() {
|
||||
const list = this.state.show ? [
|
||||
<div className="demo-kp" key="a">
|
||||
<ul>
|
||||
<li></li>
|
||||
<li></li>
|
||||
<li></li>
|
||||
</ul>
|
||||
</div>,
|
||||
<div className="demo-listBox" key="b">
|
||||
<div className="demo-list">
|
||||
<div className="title"></div>
|
||||
<ul>
|
||||
<li></li>
|
||||
<li></li>
|
||||
<li></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>,
|
||||
] : null;
|
||||
return (
|
||||
<div>
|
||||
<p className="buttons">
|
||||
<Button type="primary" onClick={this.onClick}>切换</Button>
|
||||
</p>
|
||||
<QueueAnim className="demo-content"
|
||||
key="demo"
|
||||
type={['right', 'left']}
|
||||
ease={['easeOutQuart', 'easeInOutQuart']}
|
||||
>
|
||||
{list}
|
||||
</QueueAnim>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
ReactDOM.render(<Test />, mountNode);
|
||||
````
|
@ -1,64 +0,0 @@
|
||||
---
|
||||
order: 4
|
||||
title: 表单动画进出场
|
||||
---
|
||||
|
||||
表单组合的进场与出场动画。
|
||||
|
||||
````jsx
|
||||
import { QueueAnim, Button, Radio, Input, Form, Row, Col } from 'antd';
|
||||
const FormItem = Form.Item;
|
||||
const RadioGroup = Radio.Group;
|
||||
|
||||
const Test = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
show: true,
|
||||
};
|
||||
},
|
||||
onClick() {
|
||||
this.setState({
|
||||
show: !this.state.show,
|
||||
});
|
||||
},
|
||||
render() {
|
||||
const formItemLayout = {
|
||||
labelCol: { span: 6 },
|
||||
wrapperCol: { span: 14 },
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
<p className="buttons">
|
||||
<Button type="primary" onClick={this.onClick}>切换</Button>
|
||||
</p>
|
||||
<QueueAnim component={Form} className="ant-form ant-form-horizontal" type="bottom" leaveReverse>
|
||||
{this.state.show ? [
|
||||
<FormItem key="item1" {...formItemLayout} label="用户名:">
|
||||
<p className="ant-form-text">大眼萌 minion</p>
|
||||
</FormItem>,
|
||||
<FormItem key="item2" {...formItemLayout} label="密码:">
|
||||
<Input type="password" placeholder="请输入密码" />
|
||||
</FormItem>,
|
||||
<FormItem key="item3" {...formItemLayout} label="您的性别:">
|
||||
<RadioGroup>
|
||||
<Radio value="male">男的</Radio>
|
||||
<Radio value="female">女的</Radio>
|
||||
</RadioGroup>
|
||||
</FormItem>,
|
||||
<FormItem key="item4" {...formItemLayout} label="备注:">
|
||||
<Input type="textarea" placeholder="随便写" />
|
||||
</FormItem>,
|
||||
<Row key="submit">
|
||||
<Col span="16" offset="6">
|
||||
<Button type="primary" htmlType="submit">确定</Button>
|
||||
</Col>
|
||||
</Row>,
|
||||
] : null}
|
||||
</QueueAnim>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
ReactDOM.render(<Test />, mountNode);
|
||||
````
|
@ -1,76 +0,0 @@
|
||||
---
|
||||
order: 6
|
||||
title: 一个复杂些的例子
|
||||
---
|
||||
|
||||
模拟一个完整的页面。
|
||||
|
||||
````jsx
|
||||
import { QueueAnim, Button } from 'antd';
|
||||
|
||||
const Test = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
show: true,
|
||||
};
|
||||
},
|
||||
onClick() {
|
||||
this.setState({
|
||||
show: !this.state.show,
|
||||
});
|
||||
},
|
||||
render() {
|
||||
const page = this.state.show ? [
|
||||
<div className="demo-header" key="header">
|
||||
<div className="logo">
|
||||
<img alt="logo" width="30" src="https://t.alipayobjects.com/images/rmsweb/T1B9hfXcdvXXXXXXXX.svg" />
|
||||
<span>logo</span>
|
||||
</div>
|
||||
<QueueAnim component="ul">
|
||||
<li key="0"></li>
|
||||
<li key="1"></li>
|
||||
<li key="2"></li>
|
||||
<li key="3"></li>
|
||||
<li key="4"></li>
|
||||
</QueueAnim>
|
||||
</div>,
|
||||
<QueueAnim className="demo-content" key="content" delay={300}>
|
||||
<div className="demo-title" key="title">我是标题</div>
|
||||
<div className="demo-kp" key="b">
|
||||
<QueueAnim component="ul">
|
||||
<li key="0"></li>
|
||||
<li key="1"></li>
|
||||
<li key="2"></li>
|
||||
</QueueAnim>
|
||||
</div>
|
||||
<div className="demo-title" key="title2">我是标题</div>
|
||||
<div className="demo-listBox">
|
||||
<QueueAnim className="demo-list" delay={500}>
|
||||
<div className="title" key="title3"></div>
|
||||
<QueueAnim component="ul" type="bottom" key="li">
|
||||
<li key="0"></li>
|
||||
<li key="1"></li>
|
||||
<li key="2"></li>
|
||||
<li key="3"></li>
|
||||
<li key="4"></li>
|
||||
</QueueAnim>
|
||||
</QueueAnim>
|
||||
</div>
|
||||
</QueueAnim>,
|
||||
<QueueAnim delay={1000} type="bottom" key="footerBox">
|
||||
<div className="demo-footer" key="footer"></div>
|
||||
</QueueAnim>,
|
||||
] : null;
|
||||
return (
|
||||
<div>
|
||||
<p className="buttons">
|
||||
<Button type="primary" onClick={this.onClick}>切换</Button>
|
||||
</p>
|
||||
<QueueAnim type={['right', 'left']}>{page}</QueueAnim>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
ReactDOM.render(<Test />, mountNode);
|
||||
````
|
@ -1,140 +0,0 @@
|
||||
---
|
||||
order: 7
|
||||
iframe: true
|
||||
title: Router 默认进出场
|
||||
---
|
||||
|
||||
router 组合的进场与出场动画。
|
||||
|
||||
````jsx
|
||||
const ReactRouter = require('react-router');
|
||||
let { Router, Route, Link, hashHistory } = ReactRouter;
|
||||
import { QueueAnim, Menu } from 'antd';
|
||||
|
||||
function App(props) {
|
||||
const key = props.location.pathname;
|
||||
const keys = key.replace('/', '') ? [key.replace('/', '')] : ['home'];
|
||||
return (
|
||||
<div>
|
||||
<Menu style={{ marginBottom: 10 }} mode="horizontal" selectedKeys={keys}>
|
||||
<Menu.Item key="home">
|
||||
<Link to="/">首页</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="page1">
|
||||
<Link to="/page1">Page 1</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="page2">
|
||||
<Link to="/page2">Page 2</Link>
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
<QueueAnim type={['right', 'left']} className="demo-router-wrap">
|
||||
{React.cloneElement(props.children || <Home />, { key })}
|
||||
</QueueAnim>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Home() {
|
||||
return (
|
||||
<div className="demo-router-child">
|
||||
<QueueAnim className="demo-content">
|
||||
<div className="demo-kp" key="a">
|
||||
<QueueAnim component="ul">
|
||||
<li key="0"></li>
|
||||
<li key="1"></li>
|
||||
<li key="2"></li>
|
||||
</QueueAnim>
|
||||
</div>
|
||||
<div className="demo-kp" key="b">
|
||||
<QueueAnim component="ul">
|
||||
<li key="0"></li>
|
||||
<li key="1"></li>
|
||||
<li key="2"></li>
|
||||
</QueueAnim>
|
||||
</div>
|
||||
<div className="demo-kp" key="c">
|
||||
<QueueAnim component="ul">
|
||||
<li key="0"></li>
|
||||
<li key="1"></li>
|
||||
<li key="2"></li>
|
||||
</QueueAnim>
|
||||
</div>
|
||||
</QueueAnim>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Page1() {
|
||||
return (
|
||||
<div className="demo-router-child">
|
||||
<QueueAnim className="demo-content">
|
||||
<div className="demo-kp" key="b">
|
||||
<QueueAnim component="ul">
|
||||
<li key="0"></li>
|
||||
<li key="1"></li>
|
||||
<li key="2"></li>
|
||||
</QueueAnim>
|
||||
</div>
|
||||
<div className="demo-listBox">
|
||||
<QueueAnim className="demo-list" delay={200}>
|
||||
<div className="title" key="title3"></div>
|
||||
<QueueAnim component="ul" animConfig={{ opacity: [1, 0], translateY: [0, 30], scale: [1, 0.9] }} key="ul">
|
||||
<li key="0"></li>
|
||||
<li key="1"></li>
|
||||
<li key="2"></li>
|
||||
</QueueAnim>
|
||||
</QueueAnim>
|
||||
</div>
|
||||
</QueueAnim>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Page2() {
|
||||
return (
|
||||
<div className="demo-router-child">
|
||||
<div className="demo-content">
|
||||
<div className="demo-listBox">
|
||||
<QueueAnim className="demo-list">
|
||||
<div className="title" key="title3"></div>
|
||||
<QueueAnim component="ul" animConfig={{ opacity: [1, 0], translateY: [0, 30], scale: [1, 0.9] }} key="li">
|
||||
<li key="0"></li>
|
||||
<li key="1"></li>
|
||||
<li key="2"></li>
|
||||
<li key="3"></li>
|
||||
<li key="4"></li>
|
||||
<li key="5"></li>
|
||||
</QueueAnim>
|
||||
</QueueAnim>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
ReactDOM.render((
|
||||
<Router history={hashHistory}>
|
||||
<Route path="/" component={App} ignoreScrollBehavior>
|
||||
<Route path="page1" component={Page1} />
|
||||
<Route path="page2" component={Page2} />
|
||||
</Route>
|
||||
</Router>
|
||||
), mountNode);
|
||||
````
|
||||
|
||||
````css
|
||||
#components-queue-anim-demo-router iframe {
|
||||
height: 260px;
|
||||
}
|
||||
#components-queue-anim-demo-router .demo-router-wrap {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
margin: auto;
|
||||
height:200px;
|
||||
overflow: hidden;
|
||||
}
|
||||
#components-queue-anim-demo-router .queue-anim-leaving {
|
||||
position: absolute;
|
||||
width:100%;
|
||||
}
|
||||
````
|
@ -1,33 +0,0 @@
|
||||
---
|
||||
order: 0
|
||||
title: 默认
|
||||
---
|
||||
|
||||
最简单的进场例子。
|
||||
|
||||
````jsx
|
||||
import { QueueAnim } from 'antd';
|
||||
|
||||
ReactDOM.render(
|
||||
<QueueAnim delay={500} style={{ height: 150 }}>
|
||||
<div key="a">依次进场</div>
|
||||
<div key="b">依次进场</div>
|
||||
<div key="c">依次进场</div>
|
||||
<div key="d">依次进场</div>
|
||||
<div key="e">依次进场</div>
|
||||
<div key="f">依次进场</div>
|
||||
</QueueAnim>
|
||||
, mountNode);
|
||||
````
|
||||
|
||||
````css
|
||||
.code-box-demo > div {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.code-box-demo .buttons {
|
||||
text-align: center;
|
||||
margin: 0 auto;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
````
|
@ -1,48 +0,0 @@
|
||||
---
|
||||
category: Components
|
||||
chinese: 进出场动画
|
||||
type: Other
|
||||
english: QueueAnim
|
||||
---
|
||||
|
||||
通过简单的配置对一组元素添加串行的进场动画效果。
|
||||
|
||||
## 何时使用
|
||||
|
||||
- 从内容A到内容B的转变过程时能有效的吸引用户注意力,突出视觉中心,提高整体视觉效果。
|
||||
- 小的信息元素排布或块状较多的情况下,根据一定的路径层次依次进场,区分维度层级,来凸显量级,使页面转场更加流畅和舒适,提高整体视觉效果和产品的质感。
|
||||
- 特别适合首页和需要视觉展示效果的宣传页,以及单页应用的切换页面动效。
|
||||
|
||||
|
||||
## API
|
||||
|
||||
> 此组件 `antd@1.0.0+` 后标记为废弃,您可以直接使用 `import QueueAnim from 'rc-queue-anim'` 来代替,相关文档也已移到 [ant-motioin](http://motion.ant.design/components/queue-anim)。
|
||||
|
||||
> [ant-motioin](http://motion.ant.design/) 是一个动效设计语言,欢迎关注。
|
||||
|
||||
元素依次进场。
|
||||
|
||||
```html
|
||||
<QueueAnim>
|
||||
<div key='demo1'>依次进场</div>
|
||||
<div key='demo2'>依次进场</div>
|
||||
<div key='demo3'>依次进场</div>
|
||||
<div key='demo4'>依次进场</div>
|
||||
</QueueAnim>
|
||||
```
|
||||
|
||||
> 每个子标签必须带 key,如果未设置 key 将不执行动画。
|
||||
|
||||
|参数 |类型 |默认 |详细 |
|
||||
|------------|----------------|---------|----------------|
|
||||
| type | string / array | `right` | 动画内置参数 <br/> `left` `right` `top` `bottom` `scale` `scaleBig` `scaleX` `scaleY`|
|
||||
| animConfig | object / array | null | 配置动画参数 <br/> 如 `{opacity:[1, 0],translateY:[0, -30]}` 具体参考 [velocity](http://julian.com/research/velocity) 的写法|
|
||||
| delay | number / array | 0 | 整个动画的延时,以毫秒为单位 |
|
||||
| duration | number / array | 500 | 每个动画的时间,以毫秒为单位 |
|
||||
| interval | number / array | 100 | 每个动画的间隔时间,以毫秒为单位 |
|
||||
| leaveReverse | boolean | false | 出场时是否倒放,从最后一个 dom 开始往上播放 |
|
||||
| ease | string / array | `easeOutQuart` | 动画的缓动函数,[查看详细](http://julian.com/research/velocity/#easing) |
|
||||
| animatingClassName | array | `['queue-anim-entering', 'queue-anim-leaving']` | 进出场动画进行中的类名 |
|
||||
| component | string | `div` | QueueAnim 替换的标签名 |
|
||||
|
||||
> 当以上数据类型为 Array 时,`['left', 'top']` 第一个为进场动画属性, 第二个为离场属性。
|
@ -1,14 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import RcQueueAnim from 'rc-queue-anim';
|
||||
import warning from 'warning';
|
||||
|
||||
export default class QueueAnim extends React.Component {
|
||||
componentDidMount() {
|
||||
warning(false, '`QueueAnim` is deprecated, ' +
|
||||
'you can import QueueAnim from \'rc-queue-anim\' directly.' +
|
||||
'The Demo will be moved to http://motion.ant.design/component/queue-anim');
|
||||
}
|
||||
render() {
|
||||
return <RcQueueAnim {...this.props} />;
|
||||
}
|
||||
}
|
@ -4,4 +4,5 @@ import Button from './radioButton';
|
||||
|
||||
Radio.Button = Button;
|
||||
Radio.Group = Group;
|
||||
export { Button, Group };
|
||||
export default Radio;
|
||||
|
@ -31,6 +31,9 @@ export interface SelectProps {
|
||||
defaultActiveFirstOption?: boolean;
|
||||
labelInValue?: boolean;
|
||||
getPopupContainer?: (triggerNode: React.ReactNode) => React.ReactNode;
|
||||
style?: React.CSSProperties;
|
||||
dropdownMenuStyle?: React.CSSProperties;
|
||||
onChange?: (value) => void;
|
||||
}
|
||||
|
||||
export interface SelectContext {
|
||||
@ -39,6 +42,8 @@ export interface SelectContext {
|
||||
};
|
||||
}
|
||||
|
||||
export { Option, OptGroup }
|
||||
|
||||
export default class Select extends React.Component<SelectProps, any> {
|
||||
static Option = Option;
|
||||
static OptGroup = OptGroup;
|
||||
|
@ -152,16 +152,16 @@
|
||||
}
|
||||
|
||||
&-lg {
|
||||
.ant-select-selection--single {
|
||||
.@{select-prefix-cls}-selection--single {
|
||||
height: 32px;
|
||||
.ant-select-selection__rendered {
|
||||
.@{select-prefix-cls}-selection__rendered {
|
||||
line-height: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-select-selection--multiple {
|
||||
.@{select-prefix-cls}-selection--multiple {
|
||||
min-height: 32px;
|
||||
.ant-select-selection__rendered {
|
||||
.@{select-prefix-cls}-selection__rendered {
|
||||
li {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
@ -171,18 +171,18 @@
|
||||
}
|
||||
|
||||
&-sm {
|
||||
.ant-select-selection {
|
||||
.@{select-prefix-cls}-selection {
|
||||
border-radius: @border-radius-sm;
|
||||
}
|
||||
.ant-select-selection--single {
|
||||
.@{select-prefix-cls}-selection--single {
|
||||
height: 22px;
|
||||
.ant-select-selection__rendered {
|
||||
.@{select-prefix-cls}-selection__rendered {
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
.ant-select-selection--multiple {
|
||||
.@{select-prefix-cls}-selection--multiple {
|
||||
min-height: 22px;
|
||||
.ant-select-selection__rendered {
|
||||
.@{select-prefix-cls}-selection__rendered {
|
||||
li {
|
||||
height: 14px;
|
||||
line-height: 14px;
|
||||
@ -223,14 +223,17 @@
|
||||
&-search--inline {
|
||||
float: left;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.@{select-prefix-cls}-search__field__wrap {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.@{select-prefix-cls}-search__field {
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
height: 100%;
|
||||
background: transparent;
|
||||
outline: 0;
|
||||
border-radius: @border-radius-base;
|
||||
@ -361,6 +364,9 @@
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
> ul {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ export default class Spin extends React.Component<SpinProps, any> {
|
||||
const spinElement = (
|
||||
<div {...divProps} className={spinClassName}>
|
||||
<span className={`${prefixCls}-dot`} />
|
||||
<div className={`${prefixCls}-text`}>{tip || '加载中...'}</div>
|
||||
{tip ? <div className={`${prefixCls}-text`}>{tip}</div> : null}
|
||||
</div>
|
||||
);
|
||||
|
||||
|
@ -106,11 +106,6 @@
|
||||
.square(@spin-dot-size-lg);
|
||||
}
|
||||
|
||||
&-text,
|
||||
&&-show-text &-dot {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&&-show-text &-text {
|
||||
display: block;
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ Let's generate 3~6 steps randomly, and proceed to a random step.
|
||||
````jsx
|
||||
import { Steps, Button } from 'antd';
|
||||
const Step = Steps.Step;
|
||||
const array = Array.apply(null, Array(Math.floor(Math.random() * 3) + 3));
|
||||
const array = [...Array(Math.floor(Math.random() * 3) + 3)];
|
||||
const steps = array.map((item, i) => ({
|
||||
title: `步骤${i + 1}`,
|
||||
}));
|
||||
|
@ -4,6 +4,7 @@
|
||||
@success-color : #87d068;
|
||||
@error-color : #f50;
|
||||
@warning-color : #fa0;
|
||||
@normal-color : #d9d9d9;
|
||||
|
||||
// ------ Base & Require ------
|
||||
@body-background : #fff;
|
||||
|
@ -96,6 +96,7 @@ interface TableContext {
|
||||
export default class Table extends React.Component<TableProps, any> {
|
||||
static propTypes = {
|
||||
dataSource: React.PropTypes.array,
|
||||
columns: React.PropTypes.array.isRequired,
|
||||
prefixCls: React.PropTypes.string,
|
||||
useFixedHeader: React.PropTypes.bool,
|
||||
rowSelection: React.PropTypes.object,
|
||||
@ -311,11 +312,11 @@ export default class Table extends React.Component<TableProps, any> {
|
||||
return;
|
||||
}
|
||||
return (a, b) => {
|
||||
let result = sortColumn.sorter(a, b);
|
||||
const result = sortColumn.sorter(a, b);
|
||||
if (result !== 0) {
|
||||
return (sortOrder === 'descend') ? -result : result;
|
||||
}
|
||||
return a.indexForSort - b.indexForSort;
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
|
||||
@ -774,9 +775,6 @@ export default class Table extends React.Component<TableProps, any> {
|
||||
let data = this.props.dataSource || [];
|
||||
// 优化本地排序
|
||||
data = data.slice(0);
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
data[i] = assign({}, data[i], { indexForSort: i });
|
||||
}
|
||||
const sorterFn = this.getSorterFn();
|
||||
if (sorterFn) {
|
||||
data = data.sort(sorterFn);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user