v1.1.8
This commit is contained in:
@@ -6,7 +6,7 @@ import Label from '../label';
|
||||
import General from '../plugin/general';
|
||||
import Custom from '../plugin/custom';
|
||||
import Tree from '../plugin/tree';
|
||||
// import Cascader from '../plugin/cascader';
|
||||
import Cascader from '../plugin/cascader';
|
||||
|
||||
/**
|
||||
* 框架渲染类, 渲染基础的外边框 + 属性变化监听
|
||||
@@ -384,8 +384,7 @@ class Framework extends Component{
|
||||
const bodyProps = { ...config, data, dataObj, flatData, sels, ck: this.itemClick.bind(this), show, onReset: this.onReset.bind(this) }
|
||||
|
||||
//渲染组件
|
||||
// let Body = content ? <Custom { ...bodyProps } /> : tree.show ? <Tree { ...bodyProps } /> : config.cascader.show ? <Cascader { ...bodyProps } /> : <General { ...bodyProps } />;
|
||||
let Body = content ? <Custom { ...bodyProps } /> : tree.show ? <Tree { ...bodyProps } /> : <General { ...bodyProps } />;
|
||||
let Body = content ? <Custom { ...bodyProps } /> : tree.show ? <Tree { ...bodyProps } /> : config.cascader.show ? <Cascader { ...bodyProps } /> : <General { ...bodyProps } />;
|
||||
|
||||
return (
|
||||
<xm-select { ...xmSelectProps } >
|
||||
|
||||
@@ -16,17 +16,30 @@ class Cascader extends Component{
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
optionClick(item, selected, disabled, index, e){
|
||||
|
||||
console.log(item, index);
|
||||
|
||||
this.props.ck(item, selected, disabled);
|
||||
|
||||
let expand = this.state.expand.slice(0, index + 1);
|
||||
expand[index] = item[this.props.prop.value];
|
||||
|
||||
this.setState({ expand });
|
||||
optionClick(item, selected, disabled, type, index, e){
|
||||
if(type === 'line'){
|
||||
if(disabled){
|
||||
return ;
|
||||
}
|
||||
//加载中的不需要进行处理
|
||||
if(item.__node.loading === true){
|
||||
return;
|
||||
}
|
||||
|
||||
const { cascader, prop, sels } = this.props;
|
||||
|
||||
//不是父节点的不需要处理
|
||||
if(!cascader.lazy && !item[prop.optgroup]){
|
||||
this.props.ck(item, selected, disabled);
|
||||
return
|
||||
}
|
||||
|
||||
let expand = this.state.expand.slice(0, index + 1);
|
||||
expand[index] = item[this.props.prop.value];
|
||||
this.setState({ expand });
|
||||
}else if(type === 'checkbox'){
|
||||
this.props.ck(item, selected, disabled);
|
||||
}
|
||||
//阻止父组件上的事件冒泡
|
||||
this.blockClick(e);
|
||||
}
|
||||
@@ -47,7 +60,7 @@ class Cascader extends Component{
|
||||
let { name, value, disabled, children } = prop;
|
||||
const showIcon = config.model.icon != 'hidden';
|
||||
|
||||
const renderItem = (item, indent, index) => {
|
||||
const renderItem = (item, indent, index, checked) => {
|
||||
//是否被选中
|
||||
let selected = !!sels.find(sel => sel[value] == item[value]);
|
||||
//是否禁用
|
||||
@@ -55,8 +68,11 @@ class Cascader extends Component{
|
||||
// 是否半选
|
||||
let half = item.__node.half === true;
|
||||
|
||||
selected = selected || half || item.__node.selected
|
||||
dis = dis || item.__node.disabled;
|
||||
//是否遵义严格父子结构
|
||||
if(cascader.strict){
|
||||
selected = selected || half || item.__node.selected
|
||||
dis = dis || item.__node.disabled;
|
||||
}
|
||||
|
||||
const iconStyle = selected ? {
|
||||
color: theme.color,
|
||||
@@ -67,8 +83,19 @@ class Cascader extends Component{
|
||||
|
||||
const itemStyle = { backgroundColor: 'transparent' }
|
||||
const className = ['xm-option', (dis ? ' disabled' : ''), (selected ? ' selected' : ''), (showIcon ? 'show-icon' : 'hide-icon') ].join(' ');
|
||||
const iconClass = ['xm-option-icon xm-iconfont', radio ? 'xm-icon-danx' : half ? 'xm-icon-banxuan' : 'xm-icon-duox'].join(' ');
|
||||
const iconClass = ['xm-option-icon xm-iconfont', radio ? 'xm-icon-danx' : cascader.strict && half ? 'xm-icon-banxuan' : 'xm-icon-duox'].join(' ');
|
||||
|
||||
if(item[value] === this.state.val){
|
||||
itemStyle.backgroundColor = theme.hover
|
||||
}
|
||||
|
||||
const contentStyle = {}, checkedStyle = {};
|
||||
if(checked){
|
||||
contentStyle.color = theme.color
|
||||
contentStyle.fontWeight = 700
|
||||
checkedStyle.color = theme.color
|
||||
}
|
||||
let checkedClass = 'xm-right-arrow';
|
||||
|
||||
//处理鼠标选择的背景色
|
||||
const hoverChange = e => {
|
||||
@@ -83,31 +110,30 @@ class Cascader extends Component{
|
||||
|
||||
return (
|
||||
<div class={ className } style={ itemStyle } value={ item[value] } onClick={
|
||||
this.optionClick.bind(this, item, selected, dis, index)
|
||||
this.optionClick.bind(this, item, selected, dis, 'line', index)
|
||||
} onMouseEnter={ hoverChange } onMouseLeave={ hoverChange }>
|
||||
{ showIcon && <i class={ iconClass } style={ iconStyle } ></i> }
|
||||
<div class='xm-option-content' dangerouslySetInnerHTML={{ __html: template({ data, item, arr: sels, name: item[name], value: item[value] }) }}></div>
|
||||
{ showIcon && <i class={ iconClass } style={ iconStyle } onClick={ this.optionClick.bind(this, item, selected, dis, 'checkbox', index) }></i> }
|
||||
<div class='xm-option-content' style={ contentStyle } dangerouslySetInnerHTML={{ __html: template({ data, item, arr: sels, name: item[name], value: item[value] }) }}></div>
|
||||
{ item[children] && <div class={ checkedClass } style={ checkedStyle }></div> }
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
let boxArr = [];
|
||||
const renderGroup = (item, indent, index) => {
|
||||
|
||||
const child = item[children];
|
||||
indent = indent + cascader.indent + 6
|
||||
|
||||
indent = cascader.indent + 10
|
||||
|
||||
return (
|
||||
<div class="xm-cascader">
|
||||
{ renderItem(item, indent, index) }
|
||||
{ child && this.state.expand[index] === item[value] &&
|
||||
<div class="xm-cascader-box" index={ index % 4 } style={{ left: indent + 'px' }}>{ child.map(c => renderGroup(c, indent, index + 1)) }</div>
|
||||
}
|
||||
const checked = child && this.state.expand[index] === item[value];
|
||||
checked && boxArr.push(
|
||||
<div class="xm-cascader-box" index={ index % 4 } style={{ left: indent + 'px', width: cascader.indent + 'px'}}>
|
||||
<div class="xm-cascader-scroll">{ child.map(c => renderGroup(c, indent, index + 1)) }</div>
|
||||
</div>
|
||||
)
|
||||
return renderItem(item, indent, index, checked)
|
||||
}
|
||||
|
||||
let arr = data.map(item => renderGroup(item, 0, 0)).filter(a => a);
|
||||
let arr = data.map(item => renderGroup(item, 2, 0)).concat(boxArr).filter(a => a);
|
||||
// let safetyArr = deepMerge([], arr);
|
||||
// let safetySels = deepMerge([], sels);
|
||||
|
||||
@@ -116,7 +142,7 @@ class Cascader extends Component{
|
||||
}
|
||||
|
||||
return (
|
||||
<div onClick={ this.blockClick } class="xm-body-cascader">
|
||||
<div onClick={ this.blockClick } class="xm-body-cascader" style={{ width: cascader.indent + 'px', height: config.height }}>
|
||||
{ arr }
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -194,7 +194,7 @@ class General extends Component{
|
||||
}
|
||||
|
||||
//组件将要接收新属性
|
||||
componentWillReceiveProps(props){
|
||||
componentWillReceiveProps(props){
|
||||
if(this.props.show != props.show){
|
||||
if(!props.show){
|
||||
//清空输入框的值
|
||||
|
||||
@@ -237,7 +237,7 @@ class Tree extends Component{
|
||||
}
|
||||
const className = ['xm-option', (dis ? ' disabled' : ''), (selected ? ' selected' : ''), (showIcon ? 'show-icon' : 'hide-icon') ].join(' ');
|
||||
const iconClass = ['xm-option-icon xm-iconfont', radio ? 'xm-icon-danx' : tree.strict && half ? 'xm-icon-banxuan' : 'xm-icon-duox'].join(' ');
|
||||
const treeIconClass = ['xm-tree-icon', expand ? 'expand':'', item[children] && (item[children].length > 0 || (tree.lazy && item.__node.loading !== false)) ? 'visible':'hidden'].join(' ');
|
||||
const treeIconClass = ['xm-tree-icon', expand ? 'expand':'', item[children] && (item[children].length > 0 || (tree.lazy && item.__node.loading !== false)) ? 'xm-visible':'xm-hidden'].join(' ');
|
||||
|
||||
const iconArray = [];
|
||||
if(tree.showFolderIcon){
|
||||
@@ -284,7 +284,7 @@ class Tree extends Component{
|
||||
child.length === 0 && (expand = false)
|
||||
return (
|
||||
<div class="xm-tree">
|
||||
{ tree.showFolderIcon && tree.showLine && expand && child.length > 1 && <i class='left-line left-line-group' style={ {left: indent + 3 + 'px'} }></i> }
|
||||
{ tree.showFolderIcon && tree.showLine && expand && child.length > 0 && <i class='left-line left-line-group' style={ {left: indent + 3 + 'px'} }></i> }
|
||||
{ renderItem(item, indent, child.length === 0 && (!tree.lazy || tree.lazy && item.__node.loading === false) ? 0 : expand) }
|
||||
{ expand && <div class="xm-tree-box">{ child.map(c => renderGroup(c, indent)) }</div> }
|
||||
</div>
|
||||
@@ -311,7 +311,7 @@ class Tree extends Component{
|
||||
|
||||
//工具条操作
|
||||
function flat(list, array){
|
||||
array.forEach(item => item[optgroup] ? flat(list, item[children]) : list.push(item))
|
||||
array.forEach(item => item[optgroup] ? (!tree.strict && list.push(item), flat(list, item[children])) : list.push(item))
|
||||
}
|
||||
const toolbar = (
|
||||
<div class='xm-toolbar'>
|
||||
|
||||
@@ -107,7 +107,9 @@ export default function (lan = 'zn') {
|
||||
//是否展示级联
|
||||
show: false,
|
||||
//间距
|
||||
indent: 200,
|
||||
indent: 100,
|
||||
//是否严格遵守父子模式
|
||||
strict: true,
|
||||
},
|
||||
//自定义属性名称
|
||||
prop: {
|
||||
|
||||
@@ -401,7 +401,7 @@ xm-select{
|
||||
margin-left: -2px;
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
&.visible{
|
||||
&.xm-visible{
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
@@ -429,36 +429,57 @@ xm-select{
|
||||
|
||||
.xm-cascader{
|
||||
// position: relative;
|
||||
|
||||
&-box{
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
padding: 5px 0;
|
||||
border: @border;
|
||||
background-color: #fff;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, .12);
|
||||
margin: -1px;
|
||||
|
||||
&::before{
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border: 6px solid transparent;
|
||||
border-right-color: @defaultBorderColor;
|
||||
top: 10px;
|
||||
left: -12px;
|
||||
}
|
||||
&::after{
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border: 6px solid transparent;
|
||||
border-right-color: #fff;
|
||||
top: 10px;
|
||||
left: -11px;
|
||||
}
|
||||
}
|
||||
&-scroll{
|
||||
height: 100%;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
padding: 5px 0;
|
||||
|
||||
}
|
||||
&-box[index="0"]{
|
||||
background-color: #F5F5F5;
|
||||
}
|
||||
&-box[index="1"]{
|
||||
background-color: #FAFAFA;
|
||||
}
|
||||
&-box[index="2"]{
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
&-box[index="3"]{
|
||||
background-color: #EFEFEF;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
&.cascader{
|
||||
background-color: #EFEFEF;
|
||||
width: unset;
|
||||
min-width: unset;
|
||||
.xm-option-content{
|
||||
padding-left: 8px;
|
||||
}
|
||||
.disabled .xm-right-arrow{
|
||||
color: #C2C2C2 !important;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.xm-input{
|
||||
@@ -533,6 +554,19 @@ xm-select{
|
||||
cursor: initial;
|
||||
}
|
||||
|
||||
.xm-right-arrow{
|
||||
position: absolute;
|
||||
color: #666;
|
||||
right: 5px;
|
||||
top: -1px;
|
||||
font-weight: 700;
|
||||
transform: scale(0.6, 1);
|
||||
|
||||
&::after{
|
||||
content: '>';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//不同尺寸下的数据调整
|
||||
@@ -573,7 +607,7 @@ xm-select{
|
||||
.left-line-group{
|
||||
height: calc(100% - @size);
|
||||
}
|
||||
.xm-tree-icon.hidden+.top-line{
|
||||
.xm-tree-icon.xm-hidden+.top-line{
|
||||
top: @size / 2 - 1px;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user