add: 自定义icon

This commit is contained in:
wh 2017-10-18 10:59:51 +08:00
parent a0815f0107
commit 531e81063b
6 changed files with 167 additions and 42 deletions

62
demo/demolist/Demo6.js Normal file
View File

@ -0,0 +1,62 @@
/**
*
* @title Tree基本使用事例自定义图标
* @description 添加openIconcloseIcon属性
*
*/
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

View File

@ -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

View File

@ -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;

View File

@ -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:"";
}
}

View File

@ -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;