Merge branch 'master' into authors

This commit is contained in:
yiminghe 2016-03-02 21:50:18 +08:00
commit cece1ab046
62 changed files with 624 additions and 987 deletions

View File

@ -4,6 +4,18 @@
---
## 0.12.5
`2016-02-25`
- Pagination 支持 `showTotal` 属性。[#1077](https://github.com/ant-design/ant-design/pull/1077)
- Cascader 添加 `allowClear` 属性,允许隐藏清除按钮。
- 补充了一个带图标的搜索建议框的例子。[#1067](https://github.com/ant-design/ant-design/issues/1067)
- 修复 Transfer 在不支持 Object.assign 的浏览器上报错的问题。
- 修复 Cascader 在 Safari 下错位的问题。[#1066](https://github.com/ant-design/ant-design/issues/1066)
- 移除对 Button 圆角的降级方案。
- 修复了部分组件样式的小问题。
## 0.12.4
`2016-02-22`

View File

@ -10,9 +10,9 @@ An enterprise-class UI design language and React-based implementation.
## Features
- An enterprise-class graphical design language and framework for financial applications.
- An enterprise-class design language and high quality UI style.
- Rich library of UI components base on [React Component](http://react-component.github.io/badgeboard/).
- A npm + webpack + babel workflow, supporting ES2015.
- A npm + webpack + babel + dora [workflow](http://ant-tool.github.io/index.html).
## Install

View File

@ -25,11 +25,6 @@ function insertSpace(child) {
}
export default class Button extends React.Component {
componentDidMount() {
if (window && window.PIE) {
window.PIE.attach(findDOMNode(this));
}
}
handleClick(...args) {
const buttonNode = findDOMNode(this);
buttonNode.className = buttonNode.className.replace(`${prefix}clicked`, '');

View File

@ -29,17 +29,3 @@ loading | 设置按钮载入状态 | boolean | false
onClick | `click` 事件的 handler | function | `function() {}`
- `<Button>Hello world!</Button>` 最终会被渲染为 `<button>Hello world!</button>`,并且除了上表中的属性,其它属性都会直接传到 `<button></button>`
### IE8 border radius support
Ant Design 视觉上采用渐进降级的方案,在 IE8 下圆角按钮将降级为直角。
如果强烈需要圆角按钮,我们提供了 [css3pie](http://css3pie.com/) 的兼容方案。
使用时只需在 html 头部加入以下代码即可。
```html
<!--[if IE 8]>
<script src="https://t.alipayobjects.com/images/rmsweb/T1q8JiXftaXXXXXXXX.js"></script>
<![endif]-->
```

View File

@ -51,12 +51,12 @@ class AntCascader extends React.Component {
this.setState({ popupVisible: false });
}
render() {
const { prefixCls, children, placeholder, size, disabled, className } = this.props;
const { prefixCls, children, placeholder, size, disabled, className, style, allowClear } = this.props;
const sizeCls = classNames({
'ant-input-lg': size === 'large',
'ant-input-sm': size === 'small',
});
const clearIcon = this.state.value.length > 0 ?
const clearIcon = (allowClear && !disabled && this.state.value.length > 0) ?
<Icon type="cross-circle"
className={`${prefixCls}-picker-clear`}
onClick={this.clearSelection} /> : null;
@ -77,7 +77,7 @@ class AntCascader extends React.Component {
onChange={this.handleChange}>
{children ||
<span
{...this.props}
style={style}
className={pickerCls}>
<Input placeholder={placeholder}
className={`${prefixCls}-input ant-input ${sizeCls}`}
@ -105,6 +105,7 @@ AntCascader.defaultProps = {
return label.join(' / ');
},
disabled: false,
allowClear: true,
onPopupVisibleChange() {},
};

View File

@ -35,3 +35,4 @@
| placeholder | 输入框占位文本 | string | '请选择' |
| size | 输入框大小,可选 `large` `default` `small` | string | `default` |
| disabled | 禁用 | boolean | false |
| allowClear | 是否支持清除 | boolean | true |

View File

@ -34,7 +34,7 @@ export default React.createClass({
},
toggleOption(option) {
const optionIndex = this.state.value.indexOf(option);
const value = this.state.value;
const value = [...this.state.value];
if (optionIndex === - 1) {
value.push(option);
} else {

View File

@ -14,6 +14,6 @@ function onChange(value) {
}
ReactDOM.render(
<DatePicker showTime format="yyyy-MM-dd HH:mm:ss" onChange={onChange} style={{ width: 160 }} />
<DatePicker showTime format="yyyy-MM-dd HH:mm:ss" placeholder="请选择时间" onChange={onChange} style={{ width: 160 }} />
, mountNode);
````

View File

@ -10,22 +10,24 @@
import { Menu, Dropdown } from 'antd';
const DropdownButton = Dropdown.Button;
function handleButtonClick() {
console.log('click button');
}
function handleMenuClick(e) {
console.log('click', e);
}
const menu = (
<Menu>
<Menu.Item>
<a target="_blank" href="http://www.alipay.com/">第一个菜单项</a>
</Menu.Item>
<Menu.Item>
<a target="_blank" href="http://www.taobao.com/">第二个菜单项</a>
</Menu.Item>
<Menu.Item>
<a target="_blank" href="http://www.tmall.com/">第三个菜单项</a>
</Menu.Item>
<Menu onClick={handleMenuClick}>
<Menu.Item key="1">第一个菜单项</Menu.Item>
<Menu.Item key="2">第二个菜单项</Menu.Item>
<Menu.Item key="3">第三个菜单项</Menu.Item>
</Menu>
);
ReactDOM.render(
<DropdownButton overlay={menu} type="primary">
<DropdownButton onClick={handleButtonClick} overlay={menu} type="primary">
某功能按钮
</DropdownButton>
, mountNode);

View File

@ -3,32 +3,34 @@ import Button from '../button';
import Icon from '../icon';
import Dropdown from './dropdown';
const ButtonGroup = Button.Group;
const align = {
points: ['tr', 'br'],
overlay: {
adjustX: 1,
adjustY: 1,
},
offset: [0, 3],
targetOffset: [0, 0],
};
import classNames from 'classnames';
export default React.createClass({
getDefaultProps() {
return {
align,
align: {
points: ['tr', 'br'],
overlay: {
adjustX: 1,
adjustY: 1,
},
offset: [0, 4],
targetOffset: [0, 0],
},
type: 'default',
};
},
render() {
const { type, overlay, trigger, align, children, className, ...restProps } = this.props;
const cls = classNames({
'ant-dropdown-button': true,
className: !!className,
});
return (
<ButtonGroup className="ant-dropdown-button">
<Button type={this.props.type}>
{this.props.children}
</Button>
<Dropdown {...this.props}>
<Button type={this.props.type}>
<ButtonGroup {...restProps} className={cls}>
<Button type={type}>{children}</Button>
<Dropdown align={align} overlay={overlay} trigger={trigger}>
<Button type={type}>
<Icon type="down" />
</Button>
</Dropdown>

View File

@ -18,7 +18,7 @@
| 成员 | 说明 | 类型 | 默认值 |
|-------------|------------------|--------------------|--------------|
| trigger | 触发下拉的行为 | "click" or "hover" | hover |
| trigger | 触发下拉的行为 | ['click'] or ['hover'] | ['hover'] |
| overlay | 菜单节点 | [Menu](/components/menu) | 无 |

View File

@ -131,10 +131,9 @@ class FormItem extends React.Component {
renderChildren() {
const props = this.props;
const children = React.Children.map(props.children, (child) => {
if (typeof child.type === 'function' && !child.props.size) {
if (child && typeof child.type === 'function' && !child.props.size) {
return React.cloneElement(child, { size: 'large' });
}
return child;
});
return [

View File

@ -1,4 +1,4 @@
# 水平排列的表单
# 典型表单
- order: 2
@ -7,7 +7,7 @@
---
````jsx
import { Form, Input, Button, Checkbox, Radio, Row, Col } from 'antd';
import { Form, Input, Button, Checkbox, Radio, Row, Col, Tooltip, Icon } from 'antd';
const FormItem = Form.Item;
const RadioGroup = Radio.Group;
@ -19,38 +19,39 @@ let Demo = React.createClass({
render() {
const { getFieldProps } = this.props.form;
const formItemLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 14 },
};
return (
<Form horizontal onSubmit={this.handleSubmit}>
<FormItem
label="用户名:"
labelCol={{ span: 6 }}
wrapperCol={{ span: 14 }}>
{...formItemLayout}
label="用户名:">
<p className="ant-form-text" id="userName" name="userName">大眼萌 minion</p>
</FormItem>
<FormItem
label="密码:"
labelCol={{ span: 6 }}
wrapperCol={{ span: 14 }}>
{...formItemLayout}
label="密码:">
<Input type="password" {...getFieldProps('pass')} placeholder="请输入密码" />
</FormItem>
<FormItem
label="您的性别:"
labelCol={{ span: 6 }}
wrapperCol={{ span: 14 }}>
<RadioGroup {...getFieldProps('gender', { initialValue: 'female' })}>
<Radio value="male">男的</Radio>
<Radio value="female">女的</Radio>
</RadioGroup>
{...formItemLayout}
label="您的性别:">
<RadioGroup {...getFieldProps('gender', { initialValue: 'female' })}>
<Radio value="male">男的</Radio>
<Radio value="female">女的</Radio>
</RadioGroup>
</FormItem>
<FormItem
{...formItemLayout}
label="备注:"
labelCol={{ span: 6 }}
wrapperCol={{ span: 14 }}
help="随便写点什么">
<Input type="textarea" placeholder="随便写" {...getFieldProps('remark')} />
</FormItem>
<FormItem
wrapperCol={{ span: 14, offset: 6 }}>
{...formItemLayout}
label={<span>卖身华府 <Tooltip title="我为秋香"><Icon type="question-circle-o" /></Tooltip> </span>}>
<label>
<Checkbox {...getFieldProps('agreement')} />同意
</label>

View File

@ -78,94 +78,92 @@ class BasicDemo extends React.Component {
render() {
const { getFieldProps, getFieldError, isFieldValidating } = this.props.form;
const nameProps = getFieldProps('name', {
rules: [
{ required: true, min: 5, message: '用户名至少为 5 个字符' },
{ validator: this.userExists },
],
});
const emailProps = getFieldProps('email', {
validate: [{
rules: [
{ required: true },
],
trigger: 'onBlur',
}, {
rules: [
{ type: 'email', message: '请输入正确的邮箱地址' },
],
trigger: ['onBlur', 'onChange'],
}]
});
const passwdProps = getFieldProps('passwd', {
rules: [
{ required: true, whitespace: true, message: '请填写密码' },
{ validator: this.checkPass.bind(this) },
],
});
const rePasswdProps = getFieldProps('rePasswd', {
rules: [{
required: true,
whitespace: true,
message: '请再次输入密码',
}, {
validator: this.checkPass2.bind(this),
}],
});
const textareaProps = getFieldProps('textarea', {
rules: [
{ required: true, message: '真的不打算写点什么吗?' },
],
});
const formItemLayout = {
labelCol: { span: 7 },
wrapperCol: { span: 12 },
};
return (
<Form horizontal form={this.props.form}>
<FormItem
{...formItemLayout}
label="用户名:"
labelCol={{ span: 7 }}
wrapperCol={{ span: 12 }}
hasFeedback
help={isFieldValidating('name') ? '校验中...' : (getFieldError('name') || []).join(', ')}>
<Input placeholder="实时校验,输入 JasonWood 看看"
{...getFieldProps('name', {
rules: [
{ required: true, min: 5, message: '用户名至少为 5 个字符' },
{ validator: this.userExists },
],
})} />
<Input {...nameProps} placeholder="实时校验,输入 JasonWood 看看" />
</FormItem>
<FormItem
{...formItemLayout}
label="邮箱:"
labelCol={{ span: 7 }}
wrapperCol={{ span: 12 }}
hasFeedback>
<Input type="email" placeholder="onBlur 与 onChange 相结合"
{...getFieldProps('email', {
validate: [{
rules: [
{ required: true },
],
trigger: 'onBlur',
}, {
rules: [
{ type: 'email', message: '请输入正确的邮箱地址' },
],
trigger: ['onBlur', 'onChange'],
}]
})} />
<Input {...emailProps} type="email" placeholder="onBlur 与 onChange 相结合" />
</FormItem>
<FormItem
{...formItemLayout}
label="密码:"
labelCol={{ span: 7 }}
wrapperCol={{ span: 12 }}
hasFeedback>
<Input type="password" autoComplete="off"
{...getFieldProps('passwd', {
rules: [
{ required: true, whitespace: true, message: '请填写密码' },
{ validator: this.checkPass.bind(this) },
],
})}
<Input {...passwdProps} type="password" autoComplete="off"
onContextMenu={noop} onPaste={noop} onCopy={noop} onCut={noop} />
</FormItem>
<FormItem
{...formItemLayout}
label="确认密码:"
labelCol={{ span: 7 }}
wrapperCol={{ span: 12 }}
hasFeedback>
<Input type="password" autoComplete="off" placeholder="两次输入密码保持一致"
onContextMenu={noop} onPaste={noop} onCopy={noop} onCut={noop}
{...getFieldProps('rePasswd', {
rules: [{
required: true,
whitespace: true,
message: '请再次输入密码',
}, {
validator: this.checkPass2.bind(this),
}],
})} />
<Input {...rePasswdProps} type="password" autoComplete="off" placeholder="两次输入密码保持一致"
onContextMenu={noop} onPaste={noop} onCopy={noop} onCut={noop} />
</FormItem>
<FormItem
label="备注:"
labelCol={{ span: 7 }}
wrapperCol={{ span: 12 }}>
<Input type="textarea" placeholder="随便写" id="textarea" name="textarea"
{...getFieldProps('textarea', {
rules: [
{ required: true, message: '真的不打算写点什么吗?' },
],
})} />
{...formItemLayout}
label="备注:">
<Input {...textareaProps} type="textarea" placeholder="随便写" id="textarea" name="textarea" />
</FormItem>
<FormItem wrapperCol={{ span: 12, offset: 7 }} >
<Button type="primary" onClick={this.handleSubmit.bind(this)}>确定</Button>
<FormItem wrapperCol={{ span: 12, offset: 7 }}>
<Button type="primary" onClick={this.handleSubmit.bind(this)}>确定</Button>
&nbsp;&nbsp;&nbsp;
<Button type="ghost" onClick={this.handleReset.bind(this)}>重置</Button>
<Button type="ghost" onClick={this.handleReset.bind(this)}>重置</Button>
</FormItem>
</Form>
);

View File

@ -143,6 +143,10 @@ let Demo = React.createClass({
validator: this.checkPass2,
}],
});
const formItemLayout = {
labelCol: { span: 6 },
wrapperCol: { span: 18 },
};
return (
<div>
<Button type="primary" onClick={this.showModal}>修改密码</Button>
@ -151,9 +155,8 @@ let Demo = React.createClass({
<Row>
<Col span="18">
<FormItem
label="密码:"
labelCol={{ span: 6 }}
wrapperCol={{ span: 18 }}>
{...formItemLayout}
label="密码:">
<Input {...passProps} type="password"
onContextMenu={noop} onPaste={noop} onCopy={noop} onCut={noop}
autoComplete="off" id="pass" />
@ -167,9 +170,8 @@ let Demo = React.createClass({
<Row>
<Col span="18">
<FormItem
label="确认密码:"
labelCol={{ span: 6 }}
wrapperCol={{ span: 18 }}>
{...formItemLayout}
label="确认密码:">
<Input {...rePassProps} type="password"
onContextMenu={noop} onPaste={noop} onCopy={noop} onCut={noop}
autoComplete="off" id="rePass" />

View File

@ -7,13 +7,21 @@
---
````jsx
import { Select, Radio, Button, DatePicker, InputNumber, Form, Cascader } from 'antd';
import { Select, Radio, Checkbox, Button, DatePicker, InputNumber, Form, Cascader } from 'antd';
const Option = Select.Option;
const RadioGroup = Radio.Group;
const createForm = Form.create;
const FormItem = Form.Item;
let Demo = React.createClass({
componentDidMount() {
this.props.form.setFieldsValue({
eat: true,
sleep: true,
beat: true,
});
},
handleReset(e) {
e.preventDefault();
this.props.form.resetFields();
@ -57,19 +65,48 @@ let Demo = React.createClass({
}],
}];
const { getFieldProps } = this.props.form;
const selectProps = getFieldProps('select', {
rules: [
{ required: true, message: '请选择您的国籍' }
],
});
const multiSelectProps = getFieldProps('multiSelect', {
rules: [
{ required: true, message: '请选择您喜欢的颜色', type: 'array' },
]
});
const radioProps = getFieldProps('radio', {
rules: [
{ required: true, message: '请选择您的性别' }
]
});
const birthdayProps = getFieldProps('birthday', {
rules: [
{
required: true,
type: 'date',
message: '你的生日是什么呢?',
}, {
validator: this.checkBirthday,
}
]
});
const primeNumberProps = getFieldProps('primeNumber', {
rules: [{ validator: this.checkPrime }],
});
const addressProps = getFieldProps('address', {
rules: [{ required: true, type: 'array' }],
});
const formItemLayout = {
labelCol: { span: 7 },
wrapperCol: { span: 12 },
};
return (
<Form horizontal form={this.props.form}>
<FormItem
label="国籍:"
labelCol={{ span: 7 }}
wrapperCol={{ span: 12 }}>
<Select placeholder="请选择国家" style={{ width: '100%' }}
{...getFieldProps('select', {
rules: [
{ required: true, message: '请选择您的国籍' }
],
})}
>
{...formItemLayout}
label="国籍:">
<Select {...selectProps} placeholder="请选择国家" style={{ width: '100%' }}>
<Option value="china">中国</Option>
<Option value="use">美国</Option>
<Option value="japan">日本</Option>
@ -79,16 +116,9 @@ let Demo = React.createClass({
</FormItem>
<FormItem
label="喜欢的颜色:"
labelCol={{ span: 7 }}
wrapperCol={{ span: 12 }}>
<Select multiple placeholder="请选择颜色" style={{ width: '100%' }}
{...getFieldProps('multiSelect', {
rules: [
{ required: true, message: '请选择您喜欢的颜色', type: 'array' },
]
})}
>
{...formItemLayout}
label="喜欢的颜色:">
<Select {...multiSelectProps} multiple placeholder="请选择颜色" style={{ width: '100%' }}>
<Option value="red">红色</Option>
<Option value="orange">橙色</Option>
<Option value="yellow">黄色</Option>
@ -98,60 +128,44 @@ let Demo = React.createClass({
</FormItem>
<FormItem
label="性别:"
labelCol={{ span: 7 }}
wrapperCol={{ span: 12 }}>
<RadioGroup
{...getFieldProps('radio', {
rules: [
{ required: true, message: '请选择您的性别' }
]
})}
>
{...formItemLayout}
label="性别:">
<RadioGroup {...radioProps}>
<Radio value="male"></Radio>
<Radio value="female"></Radio>
</RadioGroup>
</FormItem>
<FormItem
label="生日:"
labelCol={{ span: 7 }}
wrapperCol={{ span: 12 }}>
<DatePicker
{...getFieldProps('birthday', {
rules: [
{
required: true,
type: 'date',
message: '你的生日是什么呢?',
}, {
validator: this.checkBirthday,
}
]
})}
/>
{...formItemLayout}
label="兴趣爱好:">
<Checkbox {...getFieldProps('eat', {
valuePropName: 'checked',
})} />吃饭饭 &nbsp;
<Checkbox {...getFieldProps('sleep', {
valuePropName: 'checked',
})} />睡觉觉 &nbsp;
<Checkbox {...getFieldProps('beat', {
valuePropName: 'checked',
})} />打豆豆 &nbsp;
</FormItem>
<FormItem
label="8~12间的质数"
labelCol={{ span: 7 }}
wrapperCol={{ span: 12 }}>
<InputNumber min={8} max={12}
{...getFieldProps('primeNumber', {
rules: [{ validator: this.checkPrime }],
})}
/>
{...formItemLayout}
label="生日:">
<DatePicker {...birthdayProps} />
</FormItem>
<FormItem
label="选择地址:"
labelCol={{ span: 7 }}
wrapperCol={{ span: 12 }}>
<Cascader options={address}
{...getFieldProps('address', {
rules: [{ required: true, type: 'array' }],
})}
/>
{...formItemLayout}
label="8~12间的质数">
<InputNumber {...primeNumberProps} min={8} max={12} />
</FormItem>
<FormItem
{...formItemLayout}
label="选择地址:">
<Cascader {...addressProps} options={address} />
</FormItem>
<FormItem

View File

@ -41,6 +41,8 @@
### Form
更多示例参考 [rc-form](http://react-component.github.io/form/)。
| 参数 | 说明 | 类型 | 可选值 |默认值 |
|-----------|------------------------------------------|------------|-------|--------|
| form | 经 `Form.create()` 包装过的组件会自带 `this.props.form` 属性,直接传给 Form 即可 | object | | 无 |
@ -78,8 +80,8 @@ CustomizedForm = Form.create({})(CustomizedForm);
| validateFieldsAndScroll | 与 `validateFields` 相似,但校验完后,如果校验不通过的菜单域不在可见范围内,则自动滚动进可见范围 | 参考 `validateFields` | | |
| getFieldError | 获取某个输入控件的 Error | Function(name) | | |
| isFieldValidating | 判断一个输入控件是否在校验状态 | Function(name) | | |
| resetFields | 重置一组输入控件的值与状态,如不传入参数,则重置所有组件 | Function([names: string[]]) | | | |
| getFieldProps 详见下面描述
| resetFields | 重置一组输入控件的值与状态,如不传入参数,则重置所有组件 | Function([names: string[]]) | | |
| getFieldProps 详见下面描述 | | | | |
#### this.props.form.getFieldProps(id, options)

View File

@ -120,7 +120,7 @@ const CopyableIcon = React.createClass({
});
},
render() {
const text = '&lt;Icon type="' + this.props.type + '" /&gt;';
const text = '<Icon type="' + this.props.type + '" />';
return (
<CopyToClipboard text={text} onCopy={this.onCopied}>
<li className={this.state.justCopied ? 'copied' : ''}>

View File

@ -2,12 +2,6 @@ import React from 'react';
import assign from 'object-assign';
import classNames from 'classnames';
function prefixClsFn(prefixCls, ...args) {
return args.map((s) => {
return `${prefixCls}-${s}`;
}).join(' ');
}
function ieGT9() {
if (typeof document === undefined) {
return false;
@ -44,8 +38,8 @@ Group.propTypes = {
class Input extends React.Component {
renderLabledInput(children) {
const props = this.props;
const wrapperClassName = prefixClsFn(props.prefixCls, 'input-group');
const addonClassName = prefixClsFn(wrapperClassName, 'addon');
const wrapperClassName = `${props.prefixCls}-group`;
const addonClassName = `${wrapperClassName}-addon`;
const addonBefore = props.addonBefore ? (
<span className={addonClassName}>
{props.addonBefore}
@ -59,9 +53,10 @@ class Input extends React.Component {
) : null;
const className = classNames({
[`${props.prefixCls}-input-wrapper`]: true,
[`${props.prefixCls}-wrapper`]: true,
[wrapperClassName]: (addonBefore || addonAfter),
});
return (
<span className={className}>
{addonBefore}
@ -74,16 +69,17 @@ class Input extends React.Component {
renderInput() {
const props = assign({}, this.props);
const prefixCls = props.prefixCls;
let inputClassName = prefixClsFn(prefixCls, 'input');
if (!props.type) {
return props.children;
}
switch (props.size) {
case 'small': inputClassName = prefixClsFn(prefixCls, 'input', 'input-sm'); break;
case 'large': inputClassName = prefixClsFn(prefixCls, 'input', 'input-lg'); break;
default:
}
const inputClassName = classNames({
[prefixCls]: true,
[`${prefixCls}-sm`]: props.size === 'small',
[`${prefixCls}-lg`]: props.size === 'large',
[props.className]: !!props.className,
});
let placeholder = props.placeholder;
if (placeholder && ieGT9()) {
placeholder = null;
@ -93,12 +89,8 @@ class Input extends React.Component {
}
switch (props.type) {
case 'textarea':
return (
<textarea {...props} placeholder={placeholder}
className={inputClassName} ref="input" />
);
return <textarea {...props} placeholder={placeholder} className={inputClassName} ref="input" />;
default:
inputClassName = props.className ? props.className : inputClassName;
return <input {...props} placeholder={placeholder} className={inputClassName} ref="input" />;
}
}
@ -127,7 +119,7 @@ Input.propTypes = {
Input.defaultProps = {
defaultValue: '',
disabled: false,
prefixCls: 'ant',
prefixCls: 'ant-input',
type: 'text',
};

View File

@ -1,30 +0,0 @@
# 回调函数
- order: 3
点击关闭按钮时触发回调函数。
---
````jsx
import { Button, notification } from 'antd';
const close = function () {
console.log('我被默认的关闭按钮关闭了!');
};
const openNotification = function () {
const args = {
message: '这是标题',
description: '这是提示框的文案这是提示框示框的文案这是提示是提示框的文案这是提示框的文案',
onClose: close
};
notification.open(args);
};
ReactDOM.render(
<div>
<Button type="primary" onClick={openNotification}>打开通知提醒框</Button>
</div>,
mountNode);
````

View File

@ -42,7 +42,7 @@ config 参数如下:
- `notification.config(options)`
```js
message.config({
notification.config({
top: 100
});
```

View File

@ -9,9 +9,15 @@
````jsx
import { Pagination } from 'antd';
function showTotal(total) {
return `共 ${total} 条`;
}
ReactDOM.render(<div>
<Pagination size="small" total={50} />
<br />
<Pagination size="small" total={50} showSizeChanger showQuickJumper />
<br />
<Pagination size="small" total={50} showTotal={showTotal} />
</div>, mountNode);
````

View File

@ -0,0 +1,24 @@
# 总数
- order: 9
通过设置 `showTotal` 展示总共有多少数据。
---
````jsx
import { Pagination, Select } from 'antd';
function showTotal(total) {
return `共 ${total} 条`;
}
ReactDOM.render(
<Pagination
selectComponentClass={Select}
total={80}
showTotal={showTotal}
pageSize={20} defaultCurrent={1} />,
mountNode
);
````

View File

@ -24,7 +24,8 @@
| current | 当前页数 | Number | 无 |
| defaultCurrent | 默认的当前页数 | Number | 1 |
| total | 数据总数 | Number | 0 |
| pageSize | 每页条数 | Number | 10 |
| defaultPageSize | 初始的每页条数 | Number | 10 |
| pageSize | 每页条数 | Number | |
| onChange | 页码改变的回调,参数是改变后的页码 | Function | noop |
| showSizeChanger | 是否可以改变 pageSize | Bool | false |
| pageSizeOptions | 指定每页可以显示多少条 | Array<String> | ['10', '20', '30', '40'] |
@ -32,3 +33,4 @@
| showQuickJumper | 是否可以快速跳转至某页 | Bool | false |
| size | 当为「small」时是小尺寸分页 | String | "" |
| simple | 当添加该属性时,显示为简单分页 | Object | 无 |
| showTotal | 用于显示总共有多少条数据 | Function | 无 |

View File

@ -23,5 +23,6 @@
| title | 确认框的描述 | string | 无 |
| onConfirm | 点击确认的回调 | function | 无 |
| onCancel | 卡片内容 | function | 无 |
| onVisibleChange | 显示隐藏的回调 | function(visible) | 无 |
| okText | 确认按钮文字 | String | 确定 |
| cancelText| 取消按钮文字 | String | 取消 |

View File

@ -1,4 +1,5 @@
import React from 'react';
import classNames from 'classnames';
function getCheckedValue(children) {
let value = null;
@ -76,10 +77,10 @@ export default React.createClass({
}
return radio;
});
return (
<div className={`${props.prefixCls} ${props.prefixCls}-${props.size}`}>
{children}
</div>
);
const classString = classNames({
[props.prefixCls]: true,
[`${props.prefixCls}-${props.size}`]: props.size,
});
return <div className={classString}>{children}</div>;
},
});

View File

@ -36,7 +36,7 @@ const Test = React.createClass({
style={{ width: 200 }}
onChange={this.handleChange}
filterOption={false}
searchPlaceholder="请输入账户名">
placeholder="请输入账户名">
{this.state.options}
</Select>
);

View File

@ -0,0 +1,106 @@
# 搜索框
- order: 9
带有搜索按钮的自动补全输入框。
---
````jsx
import { Input, Select, Button, Icon } from 'antd';
import jsonp from 'jsonp';
import querystring from 'querystring';
import classNames from 'classnames';
const Option = Select.Option;
let timeout;
let currentValue;
function fetch(value, callback) {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
currentValue = value;
function fake() {
const str = querystring.encode({
code: 'utf-8',
q: value,
});
jsonp(`http://suggest.taobao.com/sug?${str}`, (err, d) => {
if (currentValue === value) {
const result = d.result;
const data = [];
result.forEach((r) => {
data.push({
value: r[0],
text: r[0],
});
});
callback(data);
}
});
}
timeout = setTimeout(fake, 300);
}
const SearchInput = React.createClass({
getInitialState() {
return {
data: [],
value: '',
focus: false,
};
},
handleChange(value) {
this.setState({ value });
fetch(value, (data) => this.setState({ data }));
},
handleSubmit() {
console.log('输入框内容是: ', this.state.value);
},
handleFocusBlur(e) {
this.setState({
focus: e.target === document.activeElement,
});
},
render() {
const btnCls = classNames({
'ant-search-btn': true,
'ant-search-btn-noempty': !!this.state.value.trim(),
});
const searchCls = classNames({
'ant-search-input': true,
'ant-search-input-focus': this.state.focus,
});
return (
<Input.Group className={searchCls} style={this.props.style}>
<Select
combobox
value={this.state.value}
searchPlaceholder={this.props.placeholder}
notFoundContent=""
defaultActiveFirstOption={false}
showArrow={false}
filterOption={false}
onChange={this.handleChange}
onFocus={this.handleFocusBlur}
onBlur={this.handleFocusBlur}>
{this.state.data.map(d => <Option key={d.value}>{d.text}</Option>)}
</Select>
<div className="ant-input-group-wrap">
<Button className={btnCls} onClick={this.handleSubmit}>
<Icon type="search" />
</Button>
</div>
</Input.Group>
);
},
});
ReactDOM.render(
<SearchInput placeholder="input search text" style={{ width: 200 }} />
, mountNode);
````

View File

@ -15,14 +15,16 @@ function handleChange(value) {
}
ReactDOM.render(
<Select defaultValue="lucy" showSearch style={{ width: 200 }}
notFoundContent="找不到呐!"
searchPlaceholder="输入"
<Select showSearch
style={{ width: 200 }}
placeholder="请选择人员"
optionFilterProp="children"
notFoundContent="无法找到"
searchPlaceholder="输入关键词"
onChange={handleChange}>
<Option value="jack">jack</Option>
<Option value="lucy">lucy</Option>
<Option value="disabled" disabled>disabled</Option>
<Option value="yiminghe">yiminghe</Option>
<Option value="jack">杰克</Option>
<Option value="lucy">露西</Option>
<Option value="tom">汤姆</Option>
</Select>
, mountNode);
````

View File

@ -38,7 +38,7 @@
| searchPlaceholder | 搜索框默认文字 | string | 无 |
| notFoundContent | 当下拉列表为空时显示的内容 | string | 'Not Found' |
| dropdownMatchSelectWidth | 下拉菜单和选择器同宽 | boolean | true |
| optionFilterProp | 输入项过滤对应的 option 属性 | string | value |
| optionFilterProp | 搜索时过滤对应的 option 属性,如设置为 children 表示对内嵌内容进行搜索 | string | value |
| combobox | 输入框自动提示模式 | boolean | false |
| size | 选择框大小,可选 `large` `small` | String | default |
| showSearch | 在下拉中显示搜索框 | boolean | false |

View File

@ -1,4 +1,4 @@
# 带ICON图标的步骤条
# 带图标的步骤条
- order: 2

View File

@ -1,32 +0,0 @@
# 自定义状态
- order: 10
可以使用 `status` 定义每个步骤的状态。
---
````jsx
import { Steps } from 'antd';
const Step = Steps.Step;
const steps = [{
status: 'finish',
title: '已完成',
description: '这里是多信息的描述啊'
}, {
status: 'process',
title: '进行中',
description: '这里是多信息的耶哦耶哦哦耶哦耶'
}, {
status: 'wait',
title: '又一个待运行',
description: '描述啊描述啊'
}, {
status: 'wait',
title: '待运行',
description: '这里是多信息的描述啊'
}].map((s, i) => <Step key={i} title={s.title} description={s.description} />);
ReactDOM.render(<Steps>{steps}</Steps>, mountNode);
````

View File

@ -9,19 +9,11 @@
````jsx
import { Table } from 'antd';
function renderAction() {
return <a href="#">删除</a>;
}
function expandedRowRender(record) {
return <p>{record.description}</p>;
}
const columns = [
{ title: '姓名', dataIndex: 'name', key: 'name' },
{ title: '年龄', dataIndex: 'age', key: 'age' },
{ title: '住址', dataIndex: 'address', key: 'address' },
{ title: '操作', dataIndex: '', key: 'x', render: renderAction }
{ title: '操作', dataIndex: '', key: 'x', render: () => <a href="#">删除</a> }
];
const data = [
@ -32,7 +24,7 @@ const data = [
ReactDOM.render(
<Table columns={columns}
expandedRowRender={expandedRowRender}
expandedRowRender={record => <p>{record.description}</p>}
dataSource={data}
className="table" />
, mountNode);

View File

@ -1,4 +1,4 @@
# 滚屏分页的列
# 横向滚屏表格
- order: 16

View File

@ -38,7 +38,9 @@ let AntTable = React.createClass({
sorter: null,
radioIndex: null,
pagination: this.hasPagination() ?
objectAssign({}, defaultPagination, this.props.pagination) :
objectAssign({
size: this.props.size,
}, defaultPagination, this.props.pagination) :
{},
};
},
@ -134,19 +136,18 @@ let AntTable = React.createClass({
}
}
if (typeof column.sorter === 'function') {
sorter = function (...args) {
let result = column.sorter.apply(this, args);
if (sortOrder === 'ascend') {
return result;
} else if (sortOrder === 'descend') {
return -result;
sorter = (a, b) => {
let result = column.sorter(a, b);
if (result !== 0) {
return (sortOrder === 'descend') ? -result : result;
}
return a.index - b.index;
};
}
const newState = {
sortOrder,
sortColumn,
sorter
sorter,
};
this.setState(newState);
this.props.onChange.apply(this, this.prepareParamsArguments(
@ -373,8 +374,7 @@ let AntTable = React.createClass({
className: 'ant-table-selection-column'
};
}
if (columns[0] &&
columns[0].key === 'selection-column') {
if (columns[0] && columns[0].key === 'selection-column') {
columns[0] = selectionColumn;
} else {
columns.unshift(selectionColumn);
@ -493,9 +493,7 @@ let AntTable = React.createClass({
},
findColumn(myKey) {
return this.props.columns.filter((c) => {
return this.getColumnKey(c) === myKey;
})[0];
return this.props.columns.filter(c => this.getColumnKey(c) === myKey)[0];
},
getCurrentPageData(dataSource) {
@ -528,6 +526,10 @@ let AntTable = React.createClass({
let data = dataSource || this.props.dataSource;
//
if (state.sortOrder && state.sorter) {
data = data.slice(0);
for (let i = 0; i < data.length; i++) {
data[i].index = i;
}
data = data.sort(state.sorter);
}
//
@ -550,12 +552,12 @@ let AntTable = React.createClass({
},
render() {
let data = this.getCurrentPageData();
const data = this.getCurrentPageData();
let columns = this.renderRowSelection();
let expandIconAsCell = this.props.expandedRowRender && this.props.expandIconAsCell !== false;
let locale = objectAssign({}, defaultLocale, this.props.locale);
const expandIconAsCell = this.props.expandedRowRender && this.props.expandIconAsCell !== false;
const locale = objectAssign({}, defaultLocale, this.props.locale);
let classString = classNames({
const classString = classNames({
[`ant-table-${this.props.size}`]: true,
'ant-table-bordered': this.props.bordered,
[this.props.className]: !!this.props.className,
@ -584,7 +586,7 @@ let AntTable = React.createClass({
data={data}
columns={columns}
className={classString}
expandIconColumnIndex={columns[0].key === 'selection-column' ? 1 : 0}
expandIconColumnIndex={(columns[0] && columns[0].key === 'selection-column') ? 1 : 0}
expandIconAsCell={expandIconAsCell} />
{emptyText}
</div>
@ -592,10 +594,10 @@ let AntTable = React.createClass({
if (this.props.loading) {
// if there is no pagination or no data,
// the height of spin should decrease by half of pagination
let paginationPatchClass = (this.hasPagination() && data && data.length !== 0)
const paginationPatchClass = (this.hasPagination() && data && data.length !== 0)
? 'ant-table-with-pagination'
: 'ant-table-without-pagination';
let spinClassName = `${paginationPatchClass} ant-table-spin-holder`;
const spinClassName = `${paginationPatchClass} ant-table-spin-holder`;
table = <Spin className={spinClassName}>{table}</Spin>;
}
return (

View File

@ -1,9 +1,9 @@
# 各种类型
四种颜色的标签。
- order: 1
四种颜色的标签。
---
````jsx
@ -16,4 +16,3 @@ ReactDOM.render(<div>
<Tag closable color="red">红色</Tag>
</div>, mountNode);
````

View File

@ -11,6 +11,9 @@ import { TimePicker } from 'antd';
function onChange(time) {
console.log(time);
if (time) {
console.log(time.toLocaleTimeString('zh-CN', { hour12: false })); // Get time string
}
}
ReactDOM.render(

View File

@ -23,7 +23,7 @@ class Transfer extends Component {
splitDataSource() {
const { targetKeys, dataSource } = this.props;
let leftDataSource = Object.assign([], dataSource);
let leftDataSource = [...dataSource];
let rightDataSource = [];
if (targetKeys.length > 0) {

View File

@ -24,8 +24,9 @@ const Demo = React.createClass({
return (
<TreeSelect style={{ width: 300 }}
value={this.state.value}
dropdownMenuStyle={{ maxHeight: 400, overflow: 'auto' }}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
placeholder="请选择"
allowClear
treeDefaultExpandAll
onChange={this.onChange}>
<TreeNode value="parent 1" title="parent 1" key="0-1">

View File

@ -42,7 +42,7 @@ const Demo = React.createClass({
return (
<TreeSelect style={{ width: 300 }}
value={this.state.value}
dropdownMenuStyle={{ maxHeight: 400, overflow: 'auto' }}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
treeData={treeData}
placeholder="请选择"
treeDefaultExpandAll

View File

@ -1,27 +1,25 @@
import React from 'react';
import TreeSelect, { TreeNode } from 'rc-tree-select';
import classNames from 'classnames';
// import animation from '../common/openAnimation';
const AntTreeSelect = React.createClass({
getDefaultProps() {
return {
prefixCls: 'ant-tree-select',
prefixCls: 'ant-select',
transitionName: 'slide-up',
choiceTransitionName: 'zoom',
showSearch: false,
// openAnimation: animation,
};
},
render() {
const props = this.props;
let {
size, className, combobox, notFoundContent
size, className, combobox, notFoundContent, prefixCls
} = this.props;
const cls = classNames({
'ant-tree-select-lg': size === 'large',
'ant-tree-select-sm': size === 'small',
[`${prefixCls}-lg`]: size === 'large',
[`${prefixCls}-sm`]: size === 'small',
[className]: !!className,
});
@ -31,7 +29,7 @@ const AntTreeSelect = React.createClass({
let checkable = props.treeCheckable;
if (checkable) {
checkable = <span className={`${props.prefixCls}-tree-checkbox-inner`}></span>;
checkable = <span className={`${prefixCls}-tree-checkbox-inner`}></span>;
}
return (

View File

@ -28,6 +28,7 @@
| onSearch | 文本框值变化时回调 | function(value: String) | |
| placeholder | 选择框默认文字 | string | 无 |
| searchPlaceholder | 搜索框默认文字 | string | 无 |
| dropdownStyle | 下拉菜单的样式 | object | 无 |
| dropdownMatchSelectWidth | 下拉菜单和选择器同宽 | boolean | true |
| combobox | 输入框自动提示模式 | boolean | false |
| size | 选择框大小,可选 `large` `small` | String | default |

View File

@ -102,7 +102,7 @@ Ant Design React 支持所有的现代浏览器和 IE8+。
<style>
.code-line-highlight {
box-shadow: 0px 195px 0px rgba(255, 207, 0, 0.16);
box-shadow: 0px 184px 0px rgba(255, 207, 0, 0.16);
height: 42px;
margin-top: -42px;
position: relative;
@ -138,7 +138,7 @@ Ant Design React 支持所有的现代浏览器和 IE8+。
## 自行构建
如果想自己维护工作流,我们推荐使用 [webpack](http://webpack.github.io/) 进行构建和调试,可以参考我们所使用的 [webpack 配置](https://github.com/ant-tool/atool-build/blob/master/src/getWebpackCommonConfig.js)。
如果想自己维护工作流,我们推荐使用 [webpack](http://webpack.github.io/) 进行构建和调试。理论上你可以利用 React 生态圈中的 [各种脚手架](https://github.com/enaqx/awesome-react#boilerplates) 进行开发,如果遇到问题可参考我们所使用的 [webpack 配置](https://github.com/ant-tool/atool-build/blob/master/src/getWebpackCommonConfig.js) 进行 [定制](http://ant-tool.github.io/webpack-config.htm)。
### 改变主色系

View File

@ -1,6 +1,6 @@
{
"name": "antd",
"version": "0.12.4",
"version": "0.12.5",
"title": "Ant Design",
"description": "一个 UI 设计语言",
"homepage": "http://ant.design/",
@ -43,31 +43,31 @@
"rc-cascader": "~0.9.0",
"rc-checkbox": "~1.3.0",
"rc-collapse": "~1.4.4",
"rc-dialog": "~5.3.1",
"rc-dialog": "~5.4.0",
"rc-dropdown": "~1.4.3",
"rc-form": "~0.13.0",
"rc-form": "~0.14.0",
"rc-form-validation": "~2.5.0",
"rc-input-number": "~2.4.1",
"rc-menu": "~4.10.2",
"rc-notification": "~1.3.1",
"rc-pagination": "~1.4.0",
"rc-pagination": "~1.5.1",
"rc-progress": "~1.0.4",
"rc-queue-anim": "~0.11.2",
"rc-radio": "~2.0.0",
"rc-select": "~5.9.1",
"rc-select": "~5.10.0",
"rc-slider": "~3.3.0",
"rc-steps": "~1.4.1",
"rc-switch": "~1.3.2",
"rc-table": "~3.10.1",
"rc-table": "~3.11.1",
"rc-tabs": "~5.7.0",
"rc-time-picker": "~1.1.0",
"rc-tooltip": "~3.3.1",
"rc-tree": "~1.1.0",
"rc-tree-select": "~1.1.1",
"rc-trigger": "~1.1.1",
"rc-trigger": "~1.2.0",
"rc-upload": "~1.8.0",
"rc-util": "~3.1.2",
"react-slick": "^0.10.0",
"react-slick": "^0.11.0",
"velocity-animate": "~1.2.2",
"warning": "~2.1.0"
},
@ -98,6 +98,7 @@
"instantclick": "^3.1.0",
"jest-cli": "~0.8.0",
"json-loader": "^0.5.1",
"jsonp": "^0.2.0",
"less": "~2.6.0",
"less-loader": "^2.2.0",
"lesshint-antd": "^1.2.1",
@ -105,6 +106,7 @@
"nico-jsx": "~0.8.2",
"postcss-loader": "^0.8.0",
"pre-commit": "1.x",
"querystring": "^0.2.0",
"rc-scroll-anim": "^0.1.7",
"rc-tween-one": "^0.1.8",
"react": "0.14.x",

View File

@ -16,6 +16,8 @@ window.ReactDOM = ReactDOM;
window['object-assign'] = require('object-assign');
window['classnames'] = require('classnames');
window['reqwest'] = require('reqwest');
window['jsonp'] = require('jsonp');
window['querystring'] = require('querystring');
window['Values'] = require('values.js');
window['InstantClick'] = require('instantclick');
require('./home')();

View File

@ -415,7 +415,6 @@ footer ul li > a {
transition: all 0.3s ease;
}
.aside-container li[open=open] h4:after {
-webkit-transform: scale(0.6) rotate(180deg);
transform: scale(0.6) rotate(180deg);
@ -922,6 +921,7 @@ footer ul li > a {
margin: 0.5em 0;
padding-right: 25px;
width: 100%;
word-break: break-word;
}
.code-box .collapse {
@ -1441,9 +1441,9 @@ a.entry-link:hover .anticon-smile {
float: none;
width: 100%;
}
.preview-image-box {
padding-left: 0;
margin: 10px 0;
}
}

View File

@ -13,9 +13,6 @@
<link rel="shortcut icon" href="https://t.alipayobjects.com/images/T1QUBfXo4fXXXXXXXX.png" type="image/x-icon">
{% block styles %}{% endblock %}
<link rel="stylesheet" href="{{static_url('../dist/demo.css')}}?20160114">
<!--[if IE 8]>
<script src="https://t.alipayobjects.com/images/rmsweb/T1q8JiXftaXXXXXXXX.js"></script>
<![endif]-->
<script src="https://as.alipayobjects.com/g/component/??console-polyfill/0.2.2/index.js,es5-shim/4.1.14/es5-shim.min.js,es5-shim/4.1.14/es5-sham.min.js,html5shiv/3.7.2/html5shiv.min.js,media-match/2.0.2/media.match.min.js,jquery/1.11.3/jquery.min.js,bluebird/3.1.1/bluebird.min.js"></script>
<script>
(function() {

View File

@ -13,6 +13,10 @@
cursor: pointer;
vertical-align: middle;
&-disabled {
cursor: not-allowed;
}
&-clear {
opacity: 0;
position: absolute;
@ -93,6 +97,7 @@
}
&-menu {
display: inline-block;
vertical-align: top;
min-width: 111px;
height: 180px;
list-style: none;

View File

@ -153,7 +153,7 @@
display: block;
margin: 0 auto;
color: #666;
border-radius: 4px;
border-radius: @border-radius-sm;
width: 20px;
height: 20px;
line-height: 18px;
@ -167,6 +167,7 @@
background: tint(@primary-color, 90%);
cursor: pointer;
}
&:active {
color: #fff;
background: tint(@primary-color, 20%);

View File

@ -66,11 +66,12 @@
}
.@{calendar-prefix-cls}-input {
border: 1px solid @border-color-base;
border-radius: @border-radius-base;
border-radius: @border-radius-sm;
}
.@{calendar-prefix-cls}-input,
.@{css-prefix}time-picker-input {
padding: 1px 7px;
.input;
border-radius: @border-radius-sm;
height: @input-height-sm;
width: 96px;
}
@ -121,9 +122,11 @@
}
.@{calendar-prefix-cls}-ok-btn {
position: static;
margin: 7px 9px 9px;
height: 22px;
margin: 8px;
}
.@{calendar-prefix-cls}-today-btn {
margin: 9px;
margin: 8px 12px;
height: 22px;
}
}

View File

@ -17,7 +17,8 @@
.@{calendar-prefix-cls}-input,
.@{timepicker-prefix-cls}-input {
.input;
height: 22px;
border-radius: @border-radius-sm;
height: @input-height-sm;
width: 96px;
margin-right: 6px;
}

View File

@ -10,7 +10,6 @@
font-size: 12px;
font-weight: normal;
line-height: 1.5;
padding-top: 4px;
&-wrap {
position: relative;

View File

@ -21,9 +21,6 @@ label {
}
// Input styles
.@{css-prefix}input-wrapper {
display: block;
}
.@{css-prefix}input {
.input;
}
@ -168,14 +165,13 @@ form {
margin-right: 8px;
}
.@{calendar-prefix-cls}-picker,
.@{select-prefix-cls} {
width: 100%;
}
}
// Input combined with select
.@{css-prefix}input-group {
.@{css-prefix}input-group-wrap {
.@{select-prefix-cls}-selection {
border-bottom-left-radius: 0;
border-top-left-radius: 0;
@ -257,10 +253,6 @@ form {
vertical-align: middle;
}
.@{calendar-prefix-cls}-picker-input {
width: 100%!important;
}
.@{css-prefix}form-text {
display: inline-block;
}

View File

@ -110,7 +110,6 @@
input {
height: 32px;
line-height: 32px;
font-size: 14px;
}
.@{input-number-prefix-cls}-handler-up-inner {

View File

@ -13,6 +13,13 @@
visibility: hidden;
}
&-total-text {
float: left;
height: 30px;
line-height: 30px;
margin-right: 10px;
}
&-item {
cursor: pointer;
border-radius: @border-radius-base;
@ -222,16 +229,20 @@
width: 30px;
height: 24px;
text-align: center;
transition: border-color 0.3s ease;
&:hover {
border-color: @primary-color;
}
}
}
}
.@{pagination-prefix-cls} {
&.mini &-total-text {
height: 20px;
line-height: 20px;
}
&.mini &-item {
border: 0;

View File

@ -18,8 +18,7 @@
//** Popover arrow width
@popover-arrow-width: 4px;
//** Popover distance with trigger
@popover-distance: @popover-arrow-width + 4;
//** Popover arrow color
@popover-arrow-color: @popover-bg;
@ -55,29 +54,25 @@
&-placement-top,
&-placement-topLeft,
&-placement-topRight {
margin-top: -@popover-arrow-width;
padding-bottom: @popover-distance;
padding-bottom: @popover-arrow-width;
}
&-placement-right,
&-placement-rightTop,
&-placement-rightBottom {
margin-left: @popover-arrow-width;
padding-left: @popover-distance;
padding-left: @popover-arrow-width;
}
&-placement-bottom,
&-placement-bottomLeft,
&-placement-bottomRight {
margin-top: @popover-arrow-width;
padding-top: @popover-distance;
padding-top: @popover-arrow-width;
}
&-placement-left,
&-placement-leftTop,
&-placement-leftBottom {
margin-left: -@popover-arrow-width;
padding-right: @popover-distance;
padding-right: @popover-arrow-width;
}
&-inner {
@ -147,11 +142,9 @@
&-placement-top > &-arrow,
&-placement-topLeft > &-arrow,
&-placement-topRight > &-arrow {
left: 50%;
margin-left: -@popover-arrow-outer-width;
border-bottom-width: 0;
border-top-color: @popover-arrow-outer-color;
bottom: @popover-distance - @popover-arrow-outer-width + 1;
bottom: 0;
&:after {
content: " ";
bottom: 1px;
@ -160,19 +153,21 @@
border-top-color: @popover-arrow-color;
}
}
&-placement-top > &-arrow {
left: 50%;
margin-left: -@popover-arrow-outer-width;
}
&-placement-topLeft > &-arrow {
left: 15%;
left: 16px;
}
&-placement-topRight > &-arrow {
left: 85%;
right: 16px;
}
&-placement-right > &-arrow,
&-placement-rightTop > &-arrow,
&-placement-rightBottom > &-arrow {
top: 50%;
left: @popover-distance - @popover-arrow-outer-width + 1;
margin-top: -@popover-arrow-outer-width;
left: 0;
border-left-width: 0;
border-right-color: @popover-arrow-outer-color;
&:after {
@ -183,21 +178,23 @@
border-right-color: @popover-arrow-color;
}
}
&-placement-right > &-arrow {
top: 50%;
margin-top: -@popover-arrow-outer-width;
}
&-placement-rightTop > &-arrow {
top: 15%;
top: 12px;
}
&-placement-rightBottom > &-arrow {
top: 85%;
bottom: 12px;
}
&-placement-bottom > &-arrow,
&-placement-bottomLeft > &-arrow,
&-placement-bottomRight > &-arrow {
left: 50%;
margin-left: -@popover-arrow-outer-width;
border-top-width: 0;
border-bottom-color: @popover-arrow-outer-color;
top: @popover-distance - @popover-arrow-outer-width + 1;
top: 0;
&:after {
content: " ";
top: 1px;
@ -206,19 +203,21 @@
border-bottom-color: @popover-arrow-color;
}
}
&-placement-bottom > &-arrow {
left: 50%;
margin-left: -@popover-arrow-outer-width;
}
&-placement-bottomLeft > &-arrow {
left: 15%;
left: 16px;
}
&-placement-bottomRight > &-arrow {
left: 85%;
right: 16px;
}
&-placement-left > &-arrow,
&-placement-leftTop > &-arrow,
&-placement-leftBottom > &-arrow {
top: 50%;
right: @popover-distance - @popover-arrow-outer-width + 1;
margin-top: -@popover-arrow-outer-width;
right: 0;
border-right-width: 0;
border-left-color: @popover-arrow-outer-color;
&:after {
@ -229,11 +228,14 @@
bottom: -@popover-arrow-width;
}
}
&-placement-left > &-arrow {
top: 50%;
margin-top: -@popover-arrow-outer-width;
}
&-placement-leftTop > &-arrow {
top: 15%;
top: 12px;
}
&-placement-leftBottom > &-arrow {
top: 85%;
bottom: 12px;
}
}

View File

@ -18,6 +18,7 @@
position: relative;
line-height: 1;
vertical-align: middle;
cursor: pointer;
&:hover {
.@{radio-inner-prefix-cls} {
border-color: #bcbcbc;

View File

@ -4,6 +4,37 @@
@import "../mixins/iconfont";
.selection__clear() {
display: inline-block;
font-style: normal;
vertical-align: baseline;
text-align: center;
text-transform: none;
text-rendering: auto;
opacity: 0;
position: absolute;
right: 8px;
z-index: 1;
background: #fff;
top: 50%;
font-size: 12px;
color: #ccc;
width: 12px;
height: 12px;
margin-top: -6px;
line-height: 12px;
cursor: pointer;
transition: color 0.3s ease, opacity 0.15s ease;
&:before {
display: block;
font-family: "anticon" !important;
content: "\E631";
}
&:hover {
color: #999;
}
}
.@{select-prefix-cls} {
box-sizing: border-box;
display: inline-block;
@ -53,39 +84,13 @@
&:hover {
.hover;
}
&:active {
.active;
}
&__clear {
display: inline-block;
font-style: normal;
vertical-align: baseline;
text-align: center;
text-transform: none;
text-rendering: auto;
opacity: 0;
position: absolute;
right: 8px;
z-index: 1;
background: #fff;
top: 50%;
font-size: 12px;
color: #ccc;
width: 12px;
height: 12px;
margin-top: -6px;
line-height: 12px;
cursor: pointer;
transition: color 0.3s ease, opacity 0.15s ease;
&:before {
display: block;
font-family: "anticon" !important;
content: "\E631";
}
&:hover {
color: #999;
}
.selection__clear();
}
&:hover &__clear {
@ -147,10 +152,7 @@
.ant-select-selection__rendered {
li {
height: 24px;
.ant-select-selection__choice__content {
font-size: 14px;
line-height: 24px;
}
line-height: 24px;
}
}
}
@ -171,15 +173,7 @@
.ant-select-selection__rendered {
li {
height: 14px;
.ant-select-selection__choice__content {
line-height: 14px;
position: relative;
top: -3px;
}
.ant-select-selection__choice__remove {
position: relative;
top: -4px;
}
line-height: 14px;
}
}
}
@ -200,9 +194,13 @@
&-search__field__placeholder {
position: absolute;
top: 0;
left: 3px;
color: #aaa;
top: 50%;
left: 9px;
color: #ccc;
line-height: 20px;
height: 20px;
margin-top: -10px;
cursor: text;
}
&-search--inline {
@ -228,11 +226,6 @@
min-height: 28px;
cursor: text;
.@{select-prefix-cls}-search__field__placeholder {
top: 6px;
left: 10px;
}
.@{select-prefix-cls}-search--inline {
width: auto;
.@{select-prefix-cls}-search__field {
@ -279,7 +272,7 @@
.@{select-prefix-cls}-selection__choice__remove {
.iconfont-mixin();
color: #999;
line-height: 20px;
line-height: inherit;
cursor: pointer;
display: inline-block;
font-weight: bold;
@ -318,10 +311,6 @@
height: 100%;
float: none;
}
.@{select-prefix-cls}-search__field__placeholder {
left: 10px;
cursor: text;
}
.@{select-prefix-cls}-search__field__wrap {
width: 100%;
height: 100%;
@ -469,10 +458,6 @@
.@{select-prefix-cls}-dropdown-search {
display: block;
padding: 4px;
.@{select-prefix-cls}-search__field__placeholder {
left: 7px;
top: 5px;
}
.@{select-prefix-cls}-search__field__wrap {
width: 100%;
}
@ -489,3 +474,11 @@
}
}
}
.ant-search-input .@{select-prefix-cls} {
width: 100%;
& + .ant-input-group-wrap > button {
top: -5px;
}
}

View File

@ -65,6 +65,12 @@
background-color: transparent;
position: absolute;
text-align: center;
color: #999;
transition: color 0.3s ease;
&:hover {
color: #666;
}
&-icon {
position: relative;
@ -87,9 +93,11 @@
}
&-tab-btn-disabled {
cursor: default;
color: #ccc;
pointer-events: none;
cursor: not-allowed;
&,
&:hover {
color: #ccc;
}
}
&-tab-next {
@ -382,6 +390,7 @@
}
&&-card &-tab-inner {
padding: 7px 16px 6px;
transition: all 0.3s @ease-in-out;
}
&&-card &-tab-active {
background: #fff;
@ -399,6 +408,7 @@
color: #999;
transition: all 0.3s @ease-in-out;
.iconfont-size-under-12px(9px);
transform-origin: 100% 50%;
width: 0;
text-align: right;
vertical-align: middle;
@ -409,6 +419,11 @@
}
}
&&-card &-tab:not(&-tab-active):hover &-tab-inner {
padding-left: 8px;
padding-right: 8px;
}
&&-card &-tab-active .anticon-cross,
&&-card &-tab:hover .anticon-cross {
width: 16px;

View File

@ -17,7 +17,7 @@
//** Tooltip arrow width
@tooltip-arrow-width: 5px;
//** Tooltip distance with trigger
@tooltip-distance: @tooltip-arrow-width + 4;
@tooltip-distance: @tooltip-arrow-width - 1 + 4;
//** Tooltip arrow color
@tooltip-arrow-color: @tooltip-bg;
@ -87,85 +87,83 @@
&-placement-topLeft &-arrow,
&-placement-topRight &-arrow {
bottom: @tooltip-distance - @tooltip-arrow-width;
margin-left: -@tooltip-arrow-width;
border-width: @tooltip-arrow-width @tooltip-arrow-width 0;
border-top-color: @tooltip-arrow-color;
}
&-placement-top &-arrow {
left: 50%;
margin-left: -@tooltip-arrow-width;
}
&-placement-topLeft &-arrow {
left: 15%;
left: 16px;
}
&-placement-topRight &-arrow {
right: 15%;
right: 16px;
}
&-placement-right &-arrow,
&-placement-rightTop &-arrow,
&-placement-rightBottom &-arrow {
left: @tooltip-distance - @tooltip-arrow-width;
margin-top: -@tooltip-arrow-width;
border-width: @tooltip-arrow-width @tooltip-arrow-width @tooltip-arrow-width 0;
border-right-color: @tooltip-arrow-color;
}
&-placement-right &-arrow {
top: 50%;
margin-top: -@tooltip-arrow-width;
}
&-placement-rightTop &-arrow {
top: 15%;
margin-top: 0;
top: 8px;
}
&-placement-rightBottom &-arrow {
bottom: 15%;
bottom: 8px;
}
&-placement-left &-arrow,
&-placement-leftTop &-arrow,
&-placement-leftBottom &-arrow {
right: @tooltip-distance - @tooltip-arrow-width;
margin-top: -@tooltip-arrow-width;
border-width: @tooltip-arrow-width 0 @tooltip-arrow-width @tooltip-arrow-width;
border-left-color: @tooltip-arrow-color;
}
&-placement-left &-arrow {
top: 50%;
margin-top: -@tooltip-arrow-width;
}
&-placement-leftTop &-arrow {
top: 15%;
margin-top: 0;
top: 8px;
}
&-placement-leftBottom &-arrow {
bottom: 15%;
bottom: 8px;
}
&-placement-bottom &-arrow,
&-placement-bottomLeft &-arrow,
&-placement-bottomRight &-arrow {
top: @tooltip-distance - @tooltip-arrow-width;
margin-left: -@tooltip-arrow-width;
border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;
border-bottom-color: @tooltip-arrow-color;
}
&-placement-bottom &-arrow {
left: 50%;
margin-left: -@tooltip-arrow-width;
}
&-placement-bottomLeft &-arrow {
left: 15%;
left: 16px;
}
&-placement-bottomRight &-arrow {
right: 15%;
right: 16px;
}
}

View File

@ -1,8 +1,9 @@
@tree-select-tree-prefix-cls: ant-tree-select-tree;
.antCheckboxFn(@checkbox-prefix-cls: ant-tree-select-tree-checkbox);
@select-tree-prefix-cls: ant-select-tree;
@import "../mixins/iconfont";
.@{tree-select-tree-prefix-cls} {
.antCheckboxFn(@checkbox-prefix-cls: ant-select-tree-checkbox);
.@{select-tree-prefix-cls} {
margin: 0;
padding: 8px;
font-size: 12px;
@ -35,16 +36,16 @@
&:hover {
background-color: tint(@primary-color, 90%);
}
&.@{tree-select-tree-prefix-cls}-node-selected {
&.@{select-tree-prefix-cls}-node-selected {
background-color: tint(@primary-color, 80%);
}
}
span {
&.@{tree-select-tree-prefix-cls}-checkbox {
&.@{select-tree-prefix-cls}-checkbox {
margin: 2px 4px 0 0;
}
&.@{tree-select-tree-prefix-cls}-switcher,
&.@{tree-select-tree-prefix-cls}-iconEle {
&.@{select-tree-prefix-cls}-switcher,
&.@{select-tree-prefix-cls}-iconEle {
margin: 0;
width: 16px;
height: 16px;
@ -55,7 +56,7 @@
cursor: pointer;
outline: none;
}
&.@{tree-select-tree-prefix-cls}-icon_loading {
&.@{select-tree-prefix-cls}-icon_loading {
&:after {
content: '\e6a1';
display: inline-block;
@ -65,17 +66,17 @@
margin-top: 8px;
}
}
&.@{tree-select-tree-prefix-cls}-switcher {
&.@{tree-select-tree-prefix-cls}-roots_open,
&.@{tree-select-tree-prefix-cls}-center_open,
&.@{tree-select-tree-prefix-cls}-bottom_open,
&.@{tree-select-tree-prefix-cls}-noline_open {
&.@{select-tree-prefix-cls}-switcher {
&.@{select-tree-prefix-cls}-roots_open,
&.@{select-tree-prefix-cls}-center_open,
&.@{select-tree-prefix-cls}-bottom_open,
&.@{select-tree-prefix-cls}-noline_open {
.antTreeSwitcherIcon();
}
&.@{tree-select-tree-prefix-cls}-roots_close,
&.@{tree-select-tree-prefix-cls}-center_close,
&.@{tree-select-tree-prefix-cls}-bottom_close,
&.@{tree-select-tree-prefix-cls}-noline_close {
&.@{select-tree-prefix-cls}-roots_close,
&.@{select-tree-prefix-cls}-center_close,
&.@{select-tree-prefix-cls}-bottom_close,
&.@{select-tree-prefix-cls}-noline_close {
.antTreeSwitcherIcon();
.ie-rotate(3);
&:after {
@ -108,480 +109,3 @@
vertical-align: top;
}
}
@tree-select-prefix-cls: ant-tree-select;
@duration: .3s;
@import "../mixins/iconfont";
//mixin
.selection__clear() {
cursor: pointer;
float: right;
font-weight: bold;
}
.@{tree-select-prefix-cls} {
box-sizing: border-box;
display: inline-block;
margin: 0;
position: relative;
vertical-align: middle;
color: #666;
font-size: @font-size-base;
> ul > li > a {
padding: 0;
background-color: #fff;
}
// arrow
&-arrow {
.iconfont-mixin();
position: absolute;
top: 50%;
right: 8px;
line-height: 1;
margin-top: -5px;
.iconfont-size-under-12px(8px);
* {
display: none;
}
&:before {
content: '\e603';
transition: transform 0.2s ease;
}
}
&-selection {
outline: none;
user-select: none;
box-sizing: border-box;
display: block;
background-color: #fff;
border-radius: @border-radius-base;
border: 1px solid @border-color-base;
.transition(all .3s @ease-in-out);
&:hover {
.hover;
}
&:active {
.active;
}
}
&-disabled {
color: #ccc;
}
&-disabled &-selection {
background: #f4f4f4;
cursor: not-allowed;
&:hover,
&:active {
border-color: @border-color-base;
}
}
&-disabled &-selection--multiple &-selection__choice {
background: #e9e9e9;
color: #999;
padding-right: 10px;
&__remove {
display: none;
}
}
&-selection--single {
height: 28px;
cursor: pointer;
.@{tree-select-prefix-cls}-selection__rendered {
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
padding-left: 8px;
padding-right: 24px;
line-height: 26px;
}
.@{tree-select-prefix-cls}-selection__clear {
.selection__clear();
}
.@{tree-select-prefix-cls}-selection__placeholder {
color: #ccc;
}
}
&-lg {
.@{tree-select-prefix-cls}-selection--single {
height: 32px;
.@{tree-select-prefix-cls}-selection__rendered {
line-height: 30px;
}
}
.@{tree-select-prefix-cls}-selection--multiple {
min-height: 32px;
.@{tree-select-prefix-cls}-search__field__placeholder {
left: 10px;
margin-top: 4px;
font-size: 14px;
line-height: 24px;
height: 24px;
}
.@{tree-select-prefix-cls}-selection__rendered {
li {
height: 22px;
.@{tree-select-prefix-cls}-selection__choice__content {
font-size: 14px;
line-height: 22px;
}
}
}
}
}
&-sm {
.@{tree-select-prefix-cls}-selection {
border-radius: @border-radius-sm;
}
.@{tree-select-prefix-cls}-selection--single {
height: 22px;
.@{tree-select-prefix-cls}-selection__rendered {
line-height: 20px;
}
}
.@{tree-select-prefix-cls}-selection--multiple {
min-height: 22px;
.@{tree-select-prefix-cls}-selection__rendered {
li {
height: 14px;
.@{tree-select-prefix-cls}-selection__choice__content {
line-height: 10px;
font-size: 8px;
position: relative;
top: -3px;
}
.@{tree-select-prefix-cls}-selection__choice__remove {
position: relative;
top: -4px;
}
}
}
}
}
&-disabled &-selection__choice__remove {
color: #ccc;
cursor: default;
&:hover {
color: #ccc;
}
}
&-search__field__wrap {
display: inline-block;
position: relative;
}
&-search__field__placeholder {
position: absolute;
top: 0;
left: 3px;
color: #aaa;
}
&-search--inline {
float: left;
.@{tree-select-prefix-cls}-search__field__wrap {
width: 100%;
}
.@{tree-select-prefix-cls}-search__field {
border: 0;
font-size: 100%;
background: transparent;
outline: 0;
}
> i {
float: right;
}
}
&-selection--multiple {
min-height: 28px;
cursor: text;
.@{tree-select-prefix-cls}-search__field__placeholder {
left: 10px;
margin-top: 4px;
height: 20px;
line-height: 20px;
}
.@{tree-select-prefix-cls}-search--inline {
width: auto;
.@{tree-select-prefix-cls}-search__field {
width: 0.75em;
}
}
.@{tree-select-prefix-cls}-selection__rendered {
overflow: hidden;
text-overflow: ellipsis;
padding-left: 6px;
padding-bottom: 4px;
}
.@{tree-select-prefix-cls}-selection__clear {
.selection__clear();
margin-top: 5px;
margin-right: 10px;
}
> ul > li {
margin-top: 4px;
height: 20px;
line-height: 20px;
}
.@{tree-select-prefix-cls}-selection__choice {
background-color: #f3f3f3;
border-radius: 4px;
cursor: default;
float: left;
padding: 0 15px;
margin-right: 4px;
max-width: 99%;
position: relative;
overflow: hidden;
transition: padding @duration @ease-in-out;
padding: 0 20px 0 10px;
}
.@{tree-select-prefix-cls}-selection__choice__content {
display: inline-block;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
transition: margin @duration @ease-in-out;
}
.@{tree-select-prefix-cls}-selection__choice__remove {
.iconfont-mixin();
color: #999;
line-height: 20px;
cursor: pointer;
display: inline-block;
font-weight: bold;
transition: all 0.3s @ease-in-out;
.iconfont-size-under-12px(8px);
position: absolute;
right: 4px;
padding: 0 0 0 8px;
&:hover {
color: #404040;
}
&:before {
content: "\e62d";
}
}
}
&-open {
.@{tree-select-prefix-cls}-arrow {
.ie-rotate(2);
-ms-transform: rotate(180deg);
&:before {
.rotate(180deg);
}
}
.@{tree-select-prefix-cls}-selection {
.active();
}
}
&-combobox {
.@{tree-select-prefix-cls}-arrow {
display: none;
}
.@{tree-select-prefix-cls}-search--inline {
height: 100%;
float: none;
}
.@{tree-select-prefix-cls}-search__field__placeholder {
left: 10px;
cursor: text;
}
.@{tree-select-prefix-cls}-search__field__wrap {
width: 100%;
height: 100%;
}
.@{tree-select-prefix-cls}-search__field {
padding: 0 10px;
width: 100%;
height: 100%;
position: relative;
z-index: 1;
}
.@{tree-select-prefix-cls}-selection__rendered {
padding: 0;
height: 100%;
}
}
}
.@{tree-select-prefix-cls}-dropdown {
&.slide-up-enter.slide-up-enter-active&-placement-bottomLeft,
&.slide-up-appear.slide-up-appear-active&-placement-bottomLeft {
animation-name: antSlideUpIn;
}
&.slide-up-enter.slide-up-enter-active&-placement-topLeft,
&.slide-up-appear.slide-up-appear-active&-placement-topLeft {
animation-name: antSlideDownIn;
}
&.slide-up-leave.slide-up-leave-active&-placement-bottomLeft {
animation-name: antSlideUpOut;
}
&.slide-up-leave.slide-up-leave-active&-placement-topLeft {
animation-name: antSlideDownOut;
}
&-hidden {
display: none;
}
background-color: white;
border: 1px solid @border-color-base;
box-shadow: @box-shadow-base;
border-radius: @border-radius-base;
box-sizing: border-box;
z-index: 1070;
left: -9999px;
top: -9999px;
position: absolute;
outline: none;
overflow: hidden;
font-size: @font-size-base;
&-menu {
outline: none;
margin-bottom: 0;
padding-left: 0; // Override default ul/ol
list-style: none;
max-height: 250px;
overflow: auto;
&-item-group-list {
margin: 0;
padding: 0;
> .@{tree-select-prefix-cls}-dropdown-menu-item {
padding-left: 24px;
}
}
&-item-group-title {
color: #999;
line-height: 1.5;
padding: 8px 15px;
}
&-item {
position: relative;
display: block;
padding: 7px 15px;
font-weight: normal;
color: #666;
white-space: nowrap;
cursor: pointer;
overflow: hidden;
transition: background 0.3s ease;
&:first-child {
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
&:last-child {
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
}
&:hover,
&-active {
background-color: tint(@primary-color, 90%);
}
&-selected {
background-color: tint(@primary-color, 80%);
&:hover {
background-color: tint(@primary-color, 80%);
}
}
&-disabled {
color: #ccc;
cursor: not-allowed;
&:hover {
color: #ccc;
background-color: #fff;
cursor: not-allowed;
}
}
&-divider {
height: 1px;
margin: 1px 0;
overflow: hidden;
background-color: #e5e5e5;
line-height: 0;
}
}
}
&-container-open,
&-open {
.@{tree-select-prefix-cls}-dropdown {
display: block;
}
}
.@{tree-select-prefix-cls}-dropdown-search {
display: block;
padding: 4px;
.@{tree-select-prefix-cls}-search__field__placeholder {
left: 7px;
top: 5px;
}
.@{tree-select-prefix-cls}-search__field__wrap {
width: 100%;
}
.@{tree-select-prefix-cls}-search__field {
padding: 4px 7px;
width: 100%;
box-sizing: border-box;
border: 1px solid @border-color-base;
border-radius: 4px;
outline: none;
}
&.@{tree-select-prefix-cls}-search--hide {
display: none;
}
}
}

View File

@ -3,11 +3,20 @@ var config = require('./webpack.config');
delete config.devtool;
config.entry.demo = [config.entry.demo[0]];
config.plugins.push(new webpack.optimize.UglifyJsPlugin({
config.plugins = [config.plugins[0], new webpack.optimize.UglifyJsPlugin({
sourceMap: false,
output: {
ascii_only: true
}
}));
})];
config.module.loaders.forEach(function(loader) {
if (loader.loader === 'babel') {
// remove preset hmre
loader.query.presets = loader.query.presets.slice(0, 3);
}
return loader;
});
module.exports = config;