add: 自定义icon
This commit is contained in:
parent
a0815f0107
commit
531e81063b
|
@ -0,0 +1,62 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @title Tree基本使用事例自定义图标
|
||||||
|
* @description 添加openIcon、closeIcon属性
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
import React, {
|
||||||
|
Component
|
||||||
|
} from 'react';
|
||||||
|
import Tree from '../../src';
|
||||||
|
|
||||||
|
const TreeNode = Tree.TreeNode;
|
||||||
|
|
||||||
|
const defaultProps = {
|
||||||
|
keys: ['0-0-0', '0-0-1']
|
||||||
|
}
|
||||||
|
console.log(Tree);
|
||||||
|
class Demo1 extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
const keys = this.props.keys;
|
||||||
|
this.state = {
|
||||||
|
defaultExpandedKeys: keys,
|
||||||
|
defaultSelectedKeys: keys,
|
||||||
|
defaultCheckedKeys: keys,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
onSelect(info) {
|
||||||
|
console.log('selected', info);
|
||||||
|
}
|
||||||
|
onCheck(info) {
|
||||||
|
console.log('onCheck', info);
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
|
||||||
|
<Tree className="myCls" checkable openIcon="uf-minus" closeIcon="uf-plus"
|
||||||
|
defaultExpandedKeys={this.state.defaultExpandedKeys}
|
||||||
|
defaultSelectedKeys={this.state.defaultSelectedKeys}
|
||||||
|
defaultCheckedKeys={this.state.defaultCheckedKeys}
|
||||||
|
onSelect={this.onSelect} onCheck={this.onCheck}
|
||||||
|
>
|
||||||
|
<TreeNode title="parent 1" key="0-0">
|
||||||
|
<TreeNode title="parent 1-0" key="0-0-0" disabled>
|
||||||
|
<TreeNode title="leaf" key="0-0-0-0" disableCheckbox />
|
||||||
|
<TreeNode title="leaf" key="0-0-0-1" />
|
||||||
|
</TreeNode>
|
||||||
|
<TreeNode title="parent 1-1" key="0-0-1">
|
||||||
|
<TreeNode title={<span style={{ color: '#08c' }}>sss</span>} key="0-0-1-0" />
|
||||||
|
</TreeNode>
|
||||||
|
</TreeNode>
|
||||||
|
</Tree>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Demo1.defaultProps = defaultProps;
|
||||||
|
|
||||||
|
|
||||||
|
export default Demo1;
|
File diff suppressed because one or more lines are too long
|
@ -18,13 +18,15 @@
|
||||||
|checkStrictly|精细的检查每个节点|bool|false
|
|checkStrictly|精细的检查每个节点|bool|false
|
||||||
|defaultSelectedKeys|指定选中的节点key|String[]|[]
|
|defaultSelectedKeys|指定选中的节点key|String[]|[]
|
||||||
|selectedKeys|指定选中的节点keys(controlled)|String[]|-
|
|selectedKeys|指定选中的节点keys(controlled)|String[]|-
|
||||||
|
|openIcon|自定义展开节点图标的名称[参考这里](http://bee.tinper.org/bee-icon)String[]|-
|
||||||
|
|closeIcon|自定义关闭节点图标的名称[参考这里](http://bee.tinper.org/bee-icon)String[]|-
|
||||||
|onExpand|当打开或关闭树节点触发的方法|function(expandedKeys, {expanded: bool, node})|-
|
|onExpand|当打开或关闭树节点触发的方法|function(expandedKeys, {expanded: bool, node})|-
|
||||||
|onCheck|当选择事件发生触发的方法|function(checkedKeys, e:{checked: bool, checkedNodes, node, event})|-
|
|onCheck|当选择事件发生触发的方法|function(checkedKeys, e:{checked: bool, checkedNodes, node, event})|-
|
||||||
|onSelect|当用户选择树节点触发的回调函数|function(selectedKeys, e:{selected: bool, selectedNodes, node, event})|-
|
|onSelect|当用户选择树节点触发的回调函数|function(selectedKeys, e:{selected: bool, selectedNodes, node, event})|-
|
||||||
|filterTreeNode|过滤树节点的方法(highlight),当返回true,相关联的节点会高亮|function(node)|-
|
|filterTreeNode|过滤树节点的方法(highlight),当返回true,相关联的节点会高亮|function(node)|-
|
||||||
|loadData|异步加载数据|function(node)|-
|
|loadData|异步加载数据|function(node)|-
|
||||||
|onRightClick|当用户点击右键触发的回调函数|function({event,node})|-
|
|onRightClick|当用户点击右键触发的回调函数|function({event,node})|-
|
||||||
|draggable|树是否可拖拽(IE>8| bool|false
|
|draggable|树是否可拖拽(IE>8| bool|false
|
||||||
|onDragStart|当树节点刚开始拖拽所触发的放方法|function({event,node})|-
|
|onDragStart|当树节点刚开始拖拽所触发的放方法|function({event,node})|-
|
||||||
|onDragEnter|当拖拽进入触发的方法|function({event,node,expandedKeys})|-
|
|onDragEnter|当拖拽进入触发的方法|function({event,node,expandedKeys})|-
|
||||||
|onDragOver|当拖拽经过触发的方法|function({event,node})|-
|
|onDragOver|当拖拽经过触发的方法|function({event,node})|-
|
||||||
|
@ -37,6 +39,6 @@
|
||||||
|:---|:-----|:----|:------|
|
|:---|:-----|:----|:------|
|
||||||
|disabled|节点是否不可用|bool|false
|
|disabled|节点是否不可用|bool|false
|
||||||
|disableCheckbox|节点的checkbox是否不可用|bool|false
|
|disableCheckbox|节点的checkbox是否不可用|bool|false
|
||||||
|title|名称标题|String/element |--
|
|title|名称标题|String/element |--
|
||||||
|key|节点key,和(default)ExpandedKeys / (default)CheckedKeys / (default)SelectedKeys一起用,必须是唯一的|String|-
|
|key|节点key,和(default)ExpandedKeys / (default)CheckedKeys / (default)SelectedKeys一起用,必须是唯一的|String|-
|
||||||
|isLeaf|是否是叶子节点|bool|false
|
|isLeaf|是否是叶子节点|bool|false
|
||||||
|
|
69
src/Tree.js
69
src/Tree.js
|
@ -1,15 +1,21 @@
|
||||||
/* eslint no-console:0 */
|
/* eslint no-console:0 */
|
||||||
import React, { PropTypes } from 'react';
|
import React, {
|
||||||
|
PropTypes
|
||||||
|
} from 'react';
|
||||||
import assign from 'object-assign';
|
import assign from 'object-assign';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import {
|
import {
|
||||||
loopAllChildren, isInclude, getOffset,
|
loopAllChildren,
|
||||||
filterParentPosition, handleCheckState, getCheck,
|
isInclude,
|
||||||
getStrictlyValue, arraysEqual,
|
getOffset,
|
||||||
|
filterParentPosition,
|
||||||
|
handleCheckState,
|
||||||
|
getCheck,
|
||||||
|
getStrictlyValue,
|
||||||
|
arraysEqual,
|
||||||
} from './util';
|
} from './util';
|
||||||
|
|
||||||
function noop() {
|
function noop() {}
|
||||||
}
|
|
||||||
|
|
||||||
class Tree extends React.Component {
|
class Tree extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -114,11 +120,17 @@ class Tree extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
onDragOver(e, treeNode) {
|
onDragOver(e, treeNode) {
|
||||||
this.props.onDragOver({ event: e, node: treeNode });
|
this.props.onDragOver({
|
||||||
|
event: e,
|
||||||
|
node: treeNode
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onDragLeave(e, treeNode) {
|
onDragLeave(e, treeNode) {
|
||||||
this.props.onDragLeave({ event: e, node: treeNode });
|
this.props.onDragLeave({
|
||||||
|
event: e,
|
||||||
|
node: treeNode
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onDrop(e, treeNode) {
|
onDrop(e, treeNode) {
|
||||||
|
@ -156,7 +168,10 @@ class Tree extends React.Component {
|
||||||
this.setState({
|
this.setState({
|
||||||
dragOverNodeKey: '',
|
dragOverNodeKey: '',
|
||||||
});
|
});
|
||||||
this.props.onDragEnd({ event: e, node: treeNode });
|
this.props.onDragEnd({
|
||||||
|
event: e,
|
||||||
|
node: treeNode
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onExpand(treeNode) {
|
onExpand(treeNode) {
|
||||||
|
@ -170,15 +185,22 @@ class Tree extends React.Component {
|
||||||
expandedKeys.splice(index, 1);
|
expandedKeys.splice(index, 1);
|
||||||
}
|
}
|
||||||
if (!controlled) {
|
if (!controlled) {
|
||||||
this.setState({ expandedKeys });
|
this.setState({
|
||||||
|
expandedKeys
|
||||||
|
});
|
||||||
}
|
}
|
||||||
this.props.onExpand(expandedKeys, { node: treeNode, expanded });
|
this.props.onExpand(expandedKeys, {
|
||||||
|
node: treeNode,
|
||||||
|
expanded
|
||||||
|
});
|
||||||
|
|
||||||
// after data loaded, need set new expandedKeys
|
// after data loaded, need set new expandedKeys
|
||||||
if (expanded && this.props.loadData) {
|
if (expanded && this.props.loadData) {
|
||||||
return this.props.loadData(treeNode).then(() => {
|
return this.props.loadData(treeNode).then(() => {
|
||||||
if (!controlled) {
|
if (!controlled) {
|
||||||
this.setState({ expandedKeys });
|
this.setState({
|
||||||
|
expandedKeys
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -284,11 +306,17 @@ class Tree extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
onMouseEnter(e, treeNode) {
|
onMouseEnter(e, treeNode) {
|
||||||
this.props.onMouseEnter({ event: e, node: treeNode });
|
this.props.onMouseEnter({
|
||||||
|
event: e,
|
||||||
|
node: treeNode
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onMouseLeave(e, treeNode) {
|
onMouseLeave(e, treeNode) {
|
||||||
this.props.onMouseLeave({ event: e, node: treeNode });
|
this.props.onMouseLeave({
|
||||||
|
event: e,
|
||||||
|
node: treeNode
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onContextMenu(e, treeNode) {
|
onContextMenu(e, treeNode) {
|
||||||
|
@ -309,7 +337,10 @@ class Tree extends React.Component {
|
||||||
this.setState({
|
this.setState({
|
||||||
selectedKeys,
|
selectedKeys,
|
||||||
});
|
});
|
||||||
this.props.onRightClick({ event: e, node: treeNode });
|
this.props.onRightClick({
|
||||||
|
event: e,
|
||||||
|
node: treeNode
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// all keyboard events callbacks run from here at first
|
// all keyboard events callbacks run from here at first
|
||||||
|
@ -336,9 +367,7 @@ class Tree extends React.Component {
|
||||||
filterExpandedKeys.push(newKey);
|
filterExpandedKeys.push(newKey);
|
||||||
} else if (props.autoExpandParent) {
|
} else if (props.autoExpandParent) {
|
||||||
expandedPositionArr.forEach(p => {
|
expandedPositionArr.forEach(p => {
|
||||||
if ((p.split('-').length > pos.split('-').length
|
if ((p.split('-').length > pos.split('-').length && isInclude(pos.split('-'), p.split('-')) || pos === p) && filterExpandedKeys.indexOf(newKey) === -1) {
|
||||||
&& isInclude(pos.split('-'), p.split('-')) || pos === p)
|
|
||||||
&& filterExpandedKeys.indexOf(newKey) === -1) {
|
|
||||||
filterExpandedKeys.push(newKey);
|
filterExpandedKeys.push(newKey);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -477,6 +506,8 @@ class Tree extends React.Component {
|
||||||
openTransitionName: this.getOpenTransitionName(),
|
openTransitionName: this.getOpenTransitionName(),
|
||||||
openAnimation: props.openAnimation,
|
openAnimation: props.openAnimation,
|
||||||
filterTreeNode: this.filterTreeNode.bind(this),
|
filterTreeNode: this.filterTreeNode.bind(this),
|
||||||
|
openIcon: props.openIcon,
|
||||||
|
closeIcon: props.closeIcon
|
||||||
};
|
};
|
||||||
if (props.checkable) {
|
if (props.checkable) {
|
||||||
cloneProps.checkable = props.checkable;
|
cloneProps.checkable = props.checkable;
|
||||||
|
@ -638,4 +669,4 @@ Tree.defaultProps = {
|
||||||
onDragEnd: noop,
|
onDragEnd: noop,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Tree;
|
export default Tree;
|
|
@ -318,3 +318,14 @@
|
||||||
-webkit-transition: height 0.2s cubic-bezier(0.215, 0.61, 0.355, 1);
|
-webkit-transition: height 0.2s cubic-bezier(0.215, 0.61, 0.355, 1);
|
||||||
transition: height 0.2s cubic-bezier(0.215, 0.61, 0.355, 1);
|
transition: height 0.2s cubic-bezier(0.215, 0.61, 0.355, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义switcher图标
|
||||||
|
*/
|
||||||
|
|
||||||
|
.u-tree li span.u-tree-switcher.uf {
|
||||||
|
font-size: 14px;
|
||||||
|
&:after{
|
||||||
|
content:"";
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,12 @@
|
||||||
import React, { PropTypes } from 'react';
|
import React, {
|
||||||
|
PropTypes
|
||||||
|
} from 'react';
|
||||||
import assign from 'object-assign';
|
import assign from 'object-assign';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import Animate from 'bee-animate';
|
import Animate from 'bee-animate';
|
||||||
import { browser } from './util';
|
import {
|
||||||
|
browser
|
||||||
|
} from './util';
|
||||||
|
|
||||||
const browserUa = typeof window !== 'undefined' ? browser(window.navigator) : '';
|
const browserUa = typeof window !== 'undefined' ? browser(window.navigator) : '';
|
||||||
const ieOrEdge = /.*(IE|Edge).+/.test(browserUa);
|
const ieOrEdge = /.*(IE|Edge).+/.test(browserUa);
|
||||||
|
@ -36,17 +40,17 @@ class TreeNode extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
if (!this.props.root._treeNodeInstances) {
|
if (!this.props.root._treeNodeInstances) {
|
||||||
this.props.root._treeNodeInstances = [];
|
this.props.root._treeNodeInstances = [];
|
||||||
|
}
|
||||||
|
this.props.root._treeNodeInstances.push(this);
|
||||||
}
|
}
|
||||||
this.props.root._treeNodeInstances.push(this);
|
// shouldComponentUpdate(nextProps) {
|
||||||
}
|
// if (!nextProps.expanded) {
|
||||||
// shouldComponentUpdate(nextProps) {
|
// return false;
|
||||||
// if (!nextProps.expanded) {
|
// }
|
||||||
// return false;
|
// return true;
|
||||||
// }
|
// }
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
onCheck() {
|
onCheck() {
|
||||||
this.props.root.onCheck(this);
|
this.props.root.onCheck(this);
|
||||||
|
@ -128,7 +132,9 @@ class TreeNode extends React.Component {
|
||||||
const callbackPromise = this.props.root.onExpand(this);
|
const callbackPromise = this.props.root.onExpand(this);
|
||||||
if (callbackPromise && typeof callbackPromise === 'object') {
|
if (callbackPromise && typeof callbackPromise === 'object') {
|
||||||
const setLoading = (dataLoading) => {
|
const setLoading = (dataLoading) => {
|
||||||
this.setState({ dataLoading });
|
this.setState({
|
||||||
|
dataLoading
|
||||||
|
});
|
||||||
};
|
};
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
callbackPromise.then(() => {
|
callbackPromise.then(() => {
|
||||||
|
@ -145,6 +151,7 @@ class TreeNode extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderSwitcher(props, expandedState) {
|
renderSwitcher(props, expandedState) {
|
||||||
|
let stateIcon;
|
||||||
const prefixCls = props.prefixCls;
|
const prefixCls = props.prefixCls;
|
||||||
const switcherCls = {
|
const switcherCls = {
|
||||||
[`${prefixCls}-switcher`]: true,
|
[`${prefixCls}-switcher`]: true,
|
||||||
|
@ -157,6 +164,15 @@ class TreeNode extends React.Component {
|
||||||
switcherCls[`${prefixCls}-center_${expandedState}`] = !props.last;
|
switcherCls[`${prefixCls}-center_${expandedState}`] = !props.last;
|
||||||
switcherCls[`${prefixCls}-bottom_${expandedState}`] = props.last;
|
switcherCls[`${prefixCls}-bottom_${expandedState}`] = props.last;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (expandedState === 'open' && props.openIcon) {
|
||||||
|
stateIcon = `uf ${props.openIcon}`;
|
||||||
|
}
|
||||||
|
if (expandedState === 'close' && props.closeIcon) {
|
||||||
|
stateIcon = [`uf ${props.closeIcon}`];
|
||||||
|
}
|
||||||
|
switcherCls[stateIcon] = stateIcon;
|
||||||
|
|
||||||
if (props.disabled) {
|
if (props.disabled) {
|
||||||
switcherCls[`${prefixCls}-switcher-disabled`] = true;
|
switcherCls[`${prefixCls}-switcher-disabled`] = true;
|
||||||
return <span className={classNames(switcherCls)}></span>;
|
return <span className={classNames(switcherCls)}></span>;
|
||||||
|
@ -200,10 +216,10 @@ class TreeNode extends React.Component {
|
||||||
let newChildren = children;
|
let newChildren = children;
|
||||||
if (children &&
|
if (children &&
|
||||||
(children.type === TreeNode ||
|
(children.type === TreeNode ||
|
||||||
Array.isArray(children) &&
|
Array.isArray(children) &&
|
||||||
children.every((item) => {
|
children.every((item) => {
|
||||||
return item.type === TreeNode;
|
return item.type === TreeNode;
|
||||||
}))) {
|
}))) {
|
||||||
const cls = {
|
const cls = {
|
||||||
[`${props.prefixCls}-child-tree`]: true,
|
[`${props.prefixCls}-child-tree`]: true,
|
||||||
[`${props.prefixCls}-child-tree-open`]: props.expanded,
|
[`${props.prefixCls}-child-tree-open`]: props.expanded,
|
||||||
|
@ -246,6 +262,8 @@ class TreeNode extends React.Component {
|
||||||
let canRenderSwitcher = true;
|
let canRenderSwitcher = true;
|
||||||
const content = props.title;
|
const content = props.title;
|
||||||
let newChildren = this.renderChildren(props);
|
let newChildren = this.renderChildren(props);
|
||||||
|
let openIconCls = false,
|
||||||
|
closeIconCls = false;
|
||||||
if (!newChildren || newChildren === props.children) {
|
if (!newChildren || newChildren === props.children) {
|
||||||
// content = newChildren;
|
// content = newChildren;
|
||||||
newChildren = null;
|
newChildren = null;
|
||||||
|
@ -262,9 +280,8 @@ class TreeNode extends React.Component {
|
||||||
const iconEleCls = {
|
const iconEleCls = {
|
||||||
[`${prefixCls}-iconEle`]: true,
|
[`${prefixCls}-iconEle`]: true,
|
||||||
[`${prefixCls}-icon_loading`]: this.state.dataLoading,
|
[`${prefixCls}-icon_loading`]: this.state.dataLoading,
|
||||||
[`${prefixCls}-icon__${iconState}`]: true,
|
[`${prefixCls}-icon__${iconState}`]: true
|
||||||
};
|
};
|
||||||
|
|
||||||
const selectHandle = () => {
|
const selectHandle = () => {
|
||||||
const icon = (props.showIcon || props.loadData && this.state.dataLoading) ?
|
const icon = (props.showIcon || props.loadData && this.state.dataLoading) ?
|
||||||
<span className={classNames(iconEleCls)}></span> : null;
|
<span className={classNames(iconEleCls)}></span> : null;
|
||||||
|
@ -374,10 +391,12 @@ TreeNode.propTypes = {
|
||||||
isLeaf: PropTypes.bool,
|
isLeaf: PropTypes.bool,
|
||||||
root: PropTypes.object,
|
root: PropTypes.object,
|
||||||
onSelect: PropTypes.func,
|
onSelect: PropTypes.func,
|
||||||
|
openIcon: PropTypes.string,
|
||||||
|
closeIcon: PropTypes.string
|
||||||
};
|
};
|
||||||
|
|
||||||
TreeNode.defaultProps = {
|
TreeNode.defaultProps = {
|
||||||
title: defaultTitle,
|
title: defaultTitle,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default TreeNode;
|
export default TreeNode;
|
Loading…
Reference in New Issue