mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-24 02:59:58 +08:00
Add cascade
This commit is contained in:
parent
564c425ad7
commit
20ce55933e
43
components/cascader/demo/basic.md
Normal file
43
components/cascader/demo/basic.md
Normal file
@ -0,0 +1,43 @@
|
||||
# 基本
|
||||
|
||||
- order: 0
|
||||
|
||||
省市级联。
|
||||
|
||||
---
|
||||
|
||||
````jsx
|
||||
import { Cascader } from 'antd';
|
||||
|
||||
const options = [{
|
||||
value: 'zhejiang',
|
||||
label: '浙江',
|
||||
children: [{
|
||||
value: 'hangzhou',
|
||||
label: '杭州',
|
||||
children: [{
|
||||
value: 'xihu',
|
||||
label: '西湖',
|
||||
}],
|
||||
}],
|
||||
}, {
|
||||
value: 'jiangsu',
|
||||
label: '江苏',
|
||||
children: [{
|
||||
value: 'nanjing',
|
||||
label: '南京',
|
||||
children: [{
|
||||
value: 'zhonghuamen',
|
||||
label: '中华门',
|
||||
}],
|
||||
}],
|
||||
}];
|
||||
|
||||
function onChange(value) {
|
||||
console.log(value);
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
<Cascader options={options} onChange={onChange} />
|
||||
, mountNode);
|
||||
````
|
53
components/cascader/demo/custom-trigger.md
Normal file
53
components/cascader/demo/custom-trigger.md
Normal file
@ -0,0 +1,53 @@
|
||||
# 可以自定义显示
|
||||
|
||||
- order: 1
|
||||
|
||||
切换按钮和结果分开。
|
||||
|
||||
---
|
||||
|
||||
````jsx
|
||||
import { Cascader } from 'antd';
|
||||
|
||||
const options = [{
|
||||
value: 'zhejiang',
|
||||
label: '浙江',
|
||||
children: [{
|
||||
value: 'hangzhou',
|
||||
label: '杭州',
|
||||
}],
|
||||
}, {
|
||||
value: 'jiangsu',
|
||||
label: '江苏',
|
||||
children: [{
|
||||
value: 'nanjing',
|
||||
label: '南京',
|
||||
}],
|
||||
}];
|
||||
|
||||
const CitySwitcher = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
text: '未选择',
|
||||
};
|
||||
},
|
||||
onChange(value, selectedOptions) {
|
||||
this.setState({
|
||||
text: selectedOptions.map(o => o.label).join(', '),
|
||||
});
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<span>
|
||||
{this.state.text}
|
||||
|
||||
<Cascader options={options} onChange={this.onChange}>
|
||||
<a href="#">切换城市</a>
|
||||
</Cascader>
|
||||
</span>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
ReactDOM.render(<CitySwitcher />, mountNode);
|
||||
````
|
49
components/cascader/demo/hover.md
Normal file
49
components/cascader/demo/hover.md
Normal file
@ -0,0 +1,49 @@
|
||||
# 移入展开
|
||||
|
||||
- order: 2
|
||||
|
||||
通过移入展开下级菜单,点击完成选择。
|
||||
|
||||
---
|
||||
|
||||
````jsx
|
||||
import { Cascader } from 'antd';
|
||||
|
||||
const options = [{
|
||||
value: 'zhejiang',
|
||||
label: '浙江',
|
||||
children: [{
|
||||
value: 'hangzhou',
|
||||
label: '杭州',
|
||||
children: [{
|
||||
value: 'xihu',
|
||||
label: '西湖',
|
||||
}],
|
||||
}],
|
||||
}, {
|
||||
value: 'jiangsu',
|
||||
label: '江苏',
|
||||
children: [{
|
||||
value: 'nanjing',
|
||||
label: '南京',
|
||||
children: [{
|
||||
value: 'zhonghuamen',
|
||||
label: '中华门',
|
||||
}],
|
||||
}],
|
||||
}];
|
||||
|
||||
function onChange(value) {
|
||||
console.log(value);
|
||||
}
|
||||
|
||||
// 只展示最后一项
|
||||
function displayRender(label) {
|
||||
return label[label.length - 1];
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
<Cascader options={options} expandTrigger="hover"
|
||||
displayRender={displayRender} onChange={onChange} />
|
||||
, mountNode);
|
||||
````
|
53
components/cascader/index.jsx
Normal file
53
components/cascader/index.jsx
Normal file
@ -0,0 +1,53 @@
|
||||
import React from 'react';
|
||||
import Cascader from 'rc-cascader';
|
||||
import Input from '../input';
|
||||
import arrayTreeFilter from 'array-tree-filter';
|
||||
|
||||
class AntCascader extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
value: [],
|
||||
};
|
||||
[
|
||||
'handleChange',
|
||||
'getLabel',
|
||||
].forEach((method) => this[method] = this[method].bind(this));
|
||||
}
|
||||
handleChange(value, selectedOptions) {
|
||||
this.setState({ value });
|
||||
this.props.onChange(value, selectedOptions);
|
||||
}
|
||||
getLabel() {
|
||||
const { options, displayRender } = this.props;
|
||||
const label = arrayTreeFilter(options, (o, level) => o.value === this.state.value[level])
|
||||
.map(o => o.label);
|
||||
return displayRender(label);
|
||||
}
|
||||
render() {
|
||||
const { prefixCls, children, placeholder, style } = this.props;
|
||||
return (
|
||||
<Cascader {...this.props} onChange={this.handleChange}>
|
||||
{children ||
|
||||
<Input placeholder={placeholder}
|
||||
className={`${prefixCls}-input ant-input`}
|
||||
style={style}
|
||||
value={this.getLabel()}
|
||||
readOnly />}
|
||||
</Cascader>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
AntCascader.defaultProps = {
|
||||
prefixCls: 'ant-cascader',
|
||||
placeholder: '请选择',
|
||||
transitionName: 'slide-up',
|
||||
onChange() {},
|
||||
options: [],
|
||||
displayRender(label) {
|
||||
return label.join(' / ');
|
||||
},
|
||||
};
|
||||
|
||||
export default AntCascader;
|
15
components/cascader/index.md
Normal file
15
components/cascader/index.md
Normal file
@ -0,0 +1,15 @@
|
||||
# Cascader
|
||||
|
||||
- category: Components
|
||||
- chinese: 级联选择
|
||||
- type: 表单
|
||||
|
||||
---
|
||||
|
||||
级联选择框。
|
||||
|
||||
## 何时使用
|
||||
|
||||
|
||||
## API
|
||||
|
1
index.js
1
index.js
@ -43,6 +43,7 @@ const antd = {
|
||||
Calendar: require('./components/calendar'),
|
||||
TimePicker: require('./components/time-picker'),
|
||||
Transfer: require('./components/transfer'),
|
||||
Cascader: require('./components/cascader'),
|
||||
};
|
||||
|
||||
antd.version = require('./package.json').version;
|
||||
|
@ -32,6 +32,7 @@
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"array-tree-filter": "~1.0.0",
|
||||
"classnames": "~2.2.0",
|
||||
"css-animation": "1.1.x",
|
||||
"gregorian-calendar": "~4.1.0",
|
||||
@ -39,6 +40,7 @@
|
||||
"object-assign": "~4.0.1",
|
||||
"rc-animate": "~2.0.2",
|
||||
"rc-calendar": "~5.2.0",
|
||||
"rc-cascader": "~0.3.0",
|
||||
"rc-checkbox": "~1.1.1",
|
||||
"rc-collapse": "~1.4.4",
|
||||
"rc-dialog": "~5.2.2",
|
||||
|
80
style/components/cascader.less
Normal file
80
style/components/cascader.less
Normal file
@ -0,0 +1,80 @@
|
||||
.ant-cascader {
|
||||
font-size: @font-size-base;
|
||||
&-input {
|
||||
width: 172px;
|
||||
display: block;
|
||||
}
|
||||
&-menus {
|
||||
font-size: 12px;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
position: absolute;
|
||||
border: 1px solid @border-color-base;
|
||||
border-radius: @border-radius-base;
|
||||
box-shadow: @box-shadow-base;
|
||||
&-hidden {
|
||||
display: none;
|
||||
}
|
||||
&.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;
|
||||
}
|
||||
}
|
||||
&-menu {
|
||||
float: left;
|
||||
width: 111px;
|
||||
height: 180px;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border-right: 1px solid @border-color-split;
|
||||
&:last-child {
|
||||
border-right-color: transparent;
|
||||
margin-right: -1px;
|
||||
}
|
||||
}
|
||||
&-menu-item {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
padding: 0 16px;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
transition: all 0.3s ease;
|
||||
&:hover {
|
||||
background: tint(@primary-color, 90%);
|
||||
}
|
||||
&-active {
|
||||
background: tint(@primary-color, 80%);
|
||||
&:hover {
|
||||
background: tint(@primary-color, 80%);
|
||||
}
|
||||
}
|
||||
&-expand {
|
||||
position: relative;
|
||||
&:after {
|
||||
content: '\e600';
|
||||
font-family: 'anticon';
|
||||
.iconfont-size-under-12px(8px);
|
||||
color: #999;
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
line-height: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -38,3 +38,4 @@
|
||||
@import "calendar";
|
||||
@import "timepicker";
|
||||
@import "transfer";
|
||||
@import "cascader";
|
||||
|
Loading…
Reference in New Issue
Block a user