bee-tree/build/Tree.js

671 lines
23 KiB
JavaScript

'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _objectAssign = require('object-assign');
var _objectAssign2 = _interopRequireDefault(_objectAssign);
var _classnames = require('classnames');
var _classnames2 = _interopRequireDefault(_classnames);
var _util = require('./util');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _defaults(obj, defaults) { var keys = Object.getOwnPropertyNames(defaults); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = Object.getOwnPropertyDescriptor(defaults, key); if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } } return obj; }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : _defaults(subClass, superClass); } /* eslint no-console:0 */
function noop() {}
var Tree = function (_React$Component) {
_inherits(Tree, _React$Component);
function Tree(props) {
_classCallCheck(this, Tree);
var _this = _possibleConstructorReturn(this, _React$Component.call(this, props));
['onKeyDown', 'onCheck'].forEach(function (m) {
_this[m] = _this[m].bind(_this);
});
_this.contextmenuKeys = [];
_this.checkedKeysChange = true;
_this.state = {
expandedKeys: _this.getDefaultExpandedKeys(props),
checkedKeys: _this.getDefaultCheckedKeys(props),
selectedKeys: _this.getDefaultSelectedKeys(props),
dragNodesKeys: '',
dragOverNodeKey: '',
dropNodeKey: ''
};
return _this;
}
Tree.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) {
var expandedKeys = this.getDefaultExpandedKeys(nextProps, true);
var checkedKeys = this.getDefaultCheckedKeys(nextProps, true);
var selectedKeys = this.getDefaultSelectedKeys(nextProps, true);
var st = {};
if (expandedKeys) {
st.expandedKeys = expandedKeys;
}
if (checkedKeys) {
if (nextProps.checkedKeys === this.props.checkedKeys) {
this.checkedKeysChange = false;
} else {
this.checkedKeysChange = true;
}
st.checkedKeys = checkedKeys;
}
if (selectedKeys) {
st.selectedKeys = selectedKeys;
}
this.setState(st);
};
Tree.prototype.onDragStart = function onDragStart(e, treeNode) {
this.dragNode = treeNode;
this.dragNodesKeys = this.getDragNodes(treeNode);
var st = {
dragNodesKeys: this.dragNodesKeys
};
var expandedKeys = this.getExpandedKeys(treeNode, false);
if (expandedKeys) {
// Controlled expand, save and then reset
this.getRawExpandedKeys();
st.expandedKeys = expandedKeys;
}
this.setState(st);
this.props.onDragStart({
event: e,
node: treeNode
});
this._dropTrigger = false;
};
Tree.prototype.onDragEnterGap = function onDragEnterGap(e, treeNode) {
var offsetTop = (0, _util.getOffset)(treeNode.refs.selectHandle).top;
var offsetHeight = treeNode.refs.selectHandle.offsetHeight;
var pageY = e.pageY;
var gapHeight = 2;
if (pageY > offsetTop + offsetHeight - gapHeight) {
this.dropPosition = 1;
return 1;
}
if (pageY < offsetTop + gapHeight) {
this.dropPosition = -1;
return -1;
}
this.dropPosition = 0;
return 0;
};
Tree.prototype.onDragEnter = function onDragEnter(e, treeNode) {
var enterGap = this.onDragEnterGap(e, treeNode);
if (this.dragNode.props.eventKey === treeNode.props.eventKey && enterGap === 0) {
this.setState({
dragOverNodeKey: ''
});
return;
}
var st = {
dragOverNodeKey: treeNode.props.eventKey
};
var expandedKeys = this.getExpandedKeys(treeNode, true);
if (expandedKeys) {
this.getRawExpandedKeys();
st.expandedKeys = expandedKeys;
}
this.setState(st);
this.props.onDragEnter({
event: e,
node: treeNode,
expandedKeys: expandedKeys && [].concat(_toConsumableArray(expandedKeys)) || [].concat(_toConsumableArray(this.state.expandedKeys))
});
};
Tree.prototype.onDragOver = function onDragOver(e, treeNode) {
this.props.onDragOver({ event: e, node: treeNode });
};
Tree.prototype.onDragLeave = function onDragLeave(e, treeNode) {
this.props.onDragLeave({ event: e, node: treeNode });
};
Tree.prototype.onDrop = function onDrop(e, treeNode) {
var key = treeNode.props.eventKey;
this.setState({
dragOverNodeKey: '',
dropNodeKey: key
});
if (this.dragNodesKeys.indexOf(key) > -1) {
if (console.warn) {
console.warn('can not drop to dragNode(include it\'s children node)');
}
return false;
}
var posArr = treeNode.props.pos.split('-');
var res = {
event: e,
node: treeNode,
dragNode: this.dragNode,
dragNodesKeys: [].concat(_toConsumableArray(this.dragNodesKeys)),
dropPosition: this.dropPosition + Number(posArr[posArr.length - 1])
};
if (this.dropPosition !== 0) {
res.dropToGap = true;
}
if ('expandedKeys' in this.props) {
res.rawExpandedKeys = [].concat(_toConsumableArray(this._rawExpandedKeys)) || [].concat(_toConsumableArray(this.state.expandedKeys));
}
this.props.onDrop(res);
this._dropTrigger = true;
};
Tree.prototype.onDragEnd = function onDragEnd(e, treeNode) {
this.setState({
dragOverNodeKey: ''
});
this.props.onDragEnd({ event: e, node: treeNode });
};
Tree.prototype.onExpand = function onExpand(treeNode) {
var _this2 = this;
var expanded = !treeNode.props.expanded;
var controlled = 'expandedKeys' in this.props;
var expandedKeys = [].concat(_toConsumableArray(this.state.expandedKeys));
var index = expandedKeys.indexOf(treeNode.props.eventKey);
if (expanded && index === -1) {
expandedKeys.push(treeNode.props.eventKey);
} else if (!expanded && index > -1) {
expandedKeys.splice(index, 1);
}
if (!controlled) {
this.setState({ expandedKeys: expandedKeys });
}
this.props.onExpand(expandedKeys, { node: treeNode, expanded: expanded });
// after data loaded, need set new expandedKeys
if (expanded && this.props.loadData) {
return this.props.loadData(treeNode).then(function () {
if (!controlled) {
_this2.setState({ expandedKeys: expandedKeys });
}
});
}
};
Tree.prototype.onCheck = function onCheck(treeNode) {
var _this3 = this;
var checked = !treeNode.props.checked;
if (treeNode.props.halfChecked) {
checked = true;
}
var key = treeNode.props.eventKey;
var checkedKeys = [].concat(_toConsumableArray(this.state.checkedKeys));
var index = checkedKeys.indexOf(key);
var newSt = {
event: 'check',
node: treeNode,
checked: checked
};
if (this.props.checkStrictly && 'checkedKeys' in this.props) {
if (checked && index === -1) {
checkedKeys.push(key);
}
if (!checked && index > -1) {
checkedKeys.splice(index, 1);
}
newSt.checkedNodes = [];
(0, _util.loopAllChildren)(this.props.children, function (item, ind, pos, keyOrPos) {
if (checkedKeys.indexOf(keyOrPos) !== -1) {
newSt.checkedNodes.push(item);
}
});
this.props.onCheck((0, _util.getStrictlyValue)(checkedKeys, this.props.checkedKeys.halfChecked), newSt);
} else {
if (checked && index === -1) {
this.treeNodesStates[treeNode.props.pos].checked = true;
var checkedPositions = [];
Object.keys(this.treeNodesStates).forEach(function (i) {
if (_this3.treeNodesStates[i].checked) {
checkedPositions.push(i);
}
});
(0, _util.handleCheckState)(this.treeNodesStates, (0, _util.filterParentPosition)(checkedPositions), true);
}
if (!checked) {
this.treeNodesStates[treeNode.props.pos].checked = false;
this.treeNodesStates[treeNode.props.pos].halfChecked = false;
(0, _util.handleCheckState)(this.treeNodesStates, [treeNode.props.pos], false);
}
var checkKeys = (0, _util.getCheck)(this.treeNodesStates);
newSt.checkedNodes = checkKeys.checkedNodes;
newSt.checkedNodesPositions = checkKeys.checkedNodesPositions;
newSt.halfCheckedKeys = checkKeys.halfCheckedKeys;
this.checkKeys = checkKeys;
this._checkedKeys = checkedKeys = checkKeys.checkedKeys;
if (!('checkedKeys' in this.props)) {
this.setState({
checkedKeys: checkedKeys
});
}
this.props.onCheck(checkedKeys, newSt);
}
};
Tree.prototype.onSelect = function onSelect(treeNode) {
var props = this.props;
var selectedKeys = [].concat(_toConsumableArray(this.state.selectedKeys));
var eventKey = treeNode.props.eventKey;
var index = selectedKeys.indexOf(eventKey);
var selected = void 0;
if (index !== -1) {
selected = false;
selectedKeys.splice(index, 1);
} else {
selected = true;
if (!props.multiple) {
selectedKeys.length = 0;
}
selectedKeys.push(eventKey);
}
var selectedNodes = [];
if (selectedKeys.length) {
(0, _util.loopAllChildren)(this.props.children, function (item) {
if (selectedKeys.indexOf(item.key) !== -1) {
selectedNodes.push(item);
}
});
}
var newSt = {
event: 'select',
node: treeNode,
selected: selected,
selectedNodes: selectedNodes
};
if (!('selectedKeys' in this.props)) {
this.setState({
selectedKeys: selectedKeys
});
}
props.onSelect(selectedKeys, newSt);
};
Tree.prototype.onMouseEnter = function onMouseEnter(e, treeNode) {
this.props.onMouseEnter({ event: e, node: treeNode });
};
Tree.prototype.onMouseLeave = function onMouseLeave(e, treeNode) {
this.props.onMouseLeave({ event: e, node: treeNode });
};
Tree.prototype.onContextMenu = function onContextMenu(e, treeNode) {
var selectedKeys = [].concat(_toConsumableArray(this.state.selectedKeys));
var eventKey = treeNode.props.eventKey;
if (this.contextmenuKeys.indexOf(eventKey) === -1) {
this.contextmenuKeys.push(eventKey);
}
this.contextmenuKeys.forEach(function (key) {
var index = selectedKeys.indexOf(key);
if (index !== -1) {
selectedKeys.splice(index, 1);
}
});
if (selectedKeys.indexOf(eventKey) === -1) {
selectedKeys.push(eventKey);
}
this.setState({
selectedKeys: selectedKeys
});
this.props.onRightClick({ event: e, node: treeNode });
};
// all keyboard events callbacks run from here at first
Tree.prototype.onKeyDown = function onKeyDown(e) {
e.preventDefault();
};
Tree.prototype.getFilterExpandedKeys = function getFilterExpandedKeys(props, expandKeyProp, expandAll) {
var keys = props[expandKeyProp];
if (!expandAll && !props.autoExpandParent) {
return keys || [];
}
var expandedPositionArr = [];
if (props.autoExpandParent) {
(0, _util.loopAllChildren)(props.children, function (item, index, pos, newKey) {
if (keys.indexOf(newKey) > -1) {
expandedPositionArr.push(pos);
}
});
}
var filterExpandedKeys = [];
(0, _util.loopAllChildren)(props.children, function (item, index, pos, newKey) {
if (expandAll) {
filterExpandedKeys.push(newKey);
} else if (props.autoExpandParent) {
expandedPositionArr.forEach(function (p) {
if ((p.split('-').length > pos.split('-').length && (0, _util.isInclude)(pos.split('-'), p.split('-')) || pos === p) && filterExpandedKeys.indexOf(newKey) === -1) {
filterExpandedKeys.push(newKey);
}
});
}
});
return filterExpandedKeys.length ? filterExpandedKeys : keys;
};
Tree.prototype.getDefaultExpandedKeys = function getDefaultExpandedKeys(props, willReceiveProps) {
var expandedKeys = willReceiveProps ? undefined : this.getFilterExpandedKeys(props, 'defaultExpandedKeys', props.defaultExpandedKeys.length ? false : props.defaultExpandAll);
if ('expandedKeys' in props) {
expandedKeys = (props.autoExpandParent ? this.getFilterExpandedKeys(props, 'expandedKeys', false) : props.expandedKeys) || [];
}
return expandedKeys;
};
Tree.prototype.getDefaultCheckedKeys = function getDefaultCheckedKeys(props, willReceiveProps) {
var checkedKeys = willReceiveProps ? undefined : props.defaultCheckedKeys;
if ('checkedKeys' in props) {
checkedKeys = props.checkedKeys || [];
if (props.checkStrictly) {
if (props.checkedKeys.checked) {
checkedKeys = props.checkedKeys.checked;
} else if (!Array.isArray(props.checkedKeys)) {
checkedKeys = [];
}
}
}
return checkedKeys;
};
Tree.prototype.getDefaultSelectedKeys = function getDefaultSelectedKeys(props, willReceiveProps) {
var getKeys = function getKeys(keys) {
if (props.multiple) {
return [].concat(_toConsumableArray(keys));
}
if (keys.length) {
return [keys[0]];
}
return keys;
};
var selectedKeys = willReceiveProps ? undefined : getKeys(props.defaultSelectedKeys);
if ('selectedKeys' in props) {
selectedKeys = getKeys(props.selectedKeys);
}
return selectedKeys;
};
Tree.prototype.getRawExpandedKeys = function getRawExpandedKeys() {
if (!this._rawExpandedKeys && 'expandedKeys' in this.props) {
this._rawExpandedKeys = [].concat(_toConsumableArray(this.state.expandedKeys));
}
};
Tree.prototype.getOpenTransitionName = function getOpenTransitionName() {
var props = this.props;
var transitionName = props.openTransitionName;
var animationName = props.openAnimation;
if (!transitionName && typeof animationName === 'string') {
transitionName = props.prefixCls + '-open-' + animationName;
}
return transitionName;
};
Tree.prototype.getDragNodes = function getDragNodes(treeNode) {
var dragNodesKeys = [];
var tPArr = treeNode.props.pos.split('-');
(0, _util.loopAllChildren)(this.props.children, function (item, index, pos, newKey) {
var pArr = pos.split('-');
if (treeNode.props.pos === pos || tPArr.length < pArr.length && (0, _util.isInclude)(tPArr, pArr)) {
dragNodesKeys.push(newKey);
}
});
return dragNodesKeys;
};
Tree.prototype.getExpandedKeys = function getExpandedKeys(treeNode, expand) {
var key = treeNode.props.eventKey;
var expandedKeys = this.state.expandedKeys;
var expandedIndex = expandedKeys.indexOf(key);
var exKeys = void 0;
if (expandedIndex > -1 && !expand) {
exKeys = [].concat(_toConsumableArray(expandedKeys));
exKeys.splice(expandedIndex, 1);
return exKeys;
}
if (expand && expandedKeys.indexOf(key) === -1) {
return expandedKeys.concat([key]);
}
};
Tree.prototype.filterTreeNode = function filterTreeNode(treeNode) {
var filterTreeNode = this.props.filterTreeNode;
if (typeof filterTreeNode !== 'function' || treeNode.props.disabled) {
return false;
}
return filterTreeNode.call(this, treeNode);
};
Tree.prototype.renderTreeNode = function renderTreeNode(child, index) {
var level = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
var pos = level + '-' + index;
var key = child.key || pos;
var state = this.state;
var props = this.props;
// prefer to child's own selectable property if passed
var selectable = props.selectable;
if (child.props.hasOwnProperty('selectable')) {
selectable = child.props.selectable;
}
var cloneProps = {
ref: 'treeNode-' + key,
root: this,
eventKey: key,
pos: pos,
selectable: selectable,
loadData: props.loadData,
onMouseEnter: props.onMouseEnter,
onMouseLeave: props.onMouseLeave,
onRightClick: props.onRightClick,
prefixCls: props.prefixCls,
showLine: props.showLine,
showIcon: props.showIcon,
draggable: props.draggable,
dragOver: state.dragOverNodeKey === key && this.dropPosition === 0,
dragOverGapTop: state.dragOverNodeKey === key && this.dropPosition === -1,
dragOverGapBottom: state.dragOverNodeKey === key && this.dropPosition === 1,
_dropTrigger: this._dropTrigger,
expanded: state.expandedKeys.indexOf(key) !== -1,
selected: state.selectedKeys.indexOf(key) !== -1,
openTransitionName: this.getOpenTransitionName(),
openAnimation: props.openAnimation,
filterTreeNode: this.filterTreeNode.bind(this)
};
if (props.checkable) {
cloneProps.checkable = props.checkable;
if (props.checkStrictly) {
if (state.checkedKeys) {
cloneProps.checked = state.checkedKeys.indexOf(key) !== -1 || false;
}
if (props.checkedKeys.halfChecked) {
cloneProps.halfChecked = props.checkedKeys.halfChecked.indexOf(key) !== -1 || false;
} else {
cloneProps.halfChecked = false;
}
} else {
if (this.checkedKeys) {
cloneProps.checked = this.checkedKeys.indexOf(key) !== -1 || false;
}
cloneProps.halfChecked = this.halfCheckedKeys.indexOf(key) !== -1;
}
}
if (this.treeNodesStates && this.treeNodesStates[pos]) {
(0, _objectAssign2["default"])(cloneProps, this.treeNodesStates[pos].siblingPosition);
}
return _react2["default"].cloneElement(child, cloneProps);
};
Tree.prototype.render = function render() {
var _this4 = this;
var props = this.props;
var domProps = {
className: (0, _classnames2["default"])(props.className, props.prefixCls),
role: 'tree-node'
};
if (props.focusable) {
domProps.tabIndex = '0';
domProps.onKeyDown = this.onKeyDown;
}
var getTreeNodesStates = function getTreeNodesStates() {
_this4.treeNodesStates = {};
(0, _util.loopAllChildren)(props.children, function (item, index, pos, keyOrPos, siblingPosition) {
_this4.treeNodesStates[pos] = {
siblingPosition: siblingPosition
};
});
};
if (props.showLine && !props.checkable) {
getTreeNodesStates();
}
if (props.checkable && (this.checkedKeysChange || props.loadData)) {
if (props.checkStrictly) {
getTreeNodesStates();
} else if (props._treeNodesStates) {
this.treeNodesStates = props._treeNodesStates.treeNodesStates;
this.halfCheckedKeys = props._treeNodesStates.halfCheckedKeys;
this.checkedKeys = props._treeNodesStates.checkedKeys;
} else {
var checkedKeys = this.state.checkedKeys;
var checkKeys = void 0;
if (!props.loadData && this.checkKeys && this._checkedKeys && (0, _util.arraysEqual)(this._checkedKeys, checkedKeys)) {
// if checkedKeys the same as _checkedKeys from onCheck, use _checkedKeys.
checkKeys = this.checkKeys;
} else {
var checkedPositions = [];
this.treeNodesStates = {};
(0, _util.loopAllChildren)(props.children, function (item, index, pos, keyOrPos, siblingPosition) {
_this4.treeNodesStates[pos] = {
node: item,
key: keyOrPos,
checked: false,
halfChecked: false,
siblingPosition: siblingPosition
};
if (checkedKeys.indexOf(keyOrPos) !== -1) {
_this4.treeNodesStates[pos].checked = true;
checkedPositions.push(pos);
}
});
// if the parent node's key exists, it all children node will be checked
(0, _util.handleCheckState)(this.treeNodesStates, (0, _util.filterParentPosition)(checkedPositions), true);
checkKeys = (0, _util.getCheck)(this.treeNodesStates);
}
this.halfCheckedKeys = checkKeys.halfCheckedKeys;
this.checkedKeys = checkKeys.checkedKeys;
}
}
return _react2["default"].createElement(
'ul',
_extends({}, domProps, { unselectable: true, ref: 'tree' }),
_react2["default"].Children.map(props.children, this.renderTreeNode, this)
);
};
return Tree;
}(_react2["default"].Component);
Tree.propTypes = {
prefixCls: _react.PropTypes.string,
children: _react.PropTypes.any,
showLine: _react.PropTypes.bool,
showIcon: _react.PropTypes.bool,
selectable: _react.PropTypes.bool,
multiple: _react.PropTypes.bool,
checkable: _react.PropTypes.oneOfType([_react.PropTypes.bool, _react.PropTypes.node]),
_treeNodesStates: _react.PropTypes.object,
checkStrictly: _react.PropTypes.bool,
draggable: _react.PropTypes.bool,
autoExpandParent: _react.PropTypes.bool,
defaultExpandAll: _react.PropTypes.bool,
defaultExpandedKeys: _react.PropTypes.arrayOf(_react.PropTypes.string),
expandedKeys: _react.PropTypes.arrayOf(_react.PropTypes.string),
defaultCheckedKeys: _react.PropTypes.arrayOf(_react.PropTypes.string),
checkedKeys: _react.PropTypes.oneOfType([_react.PropTypes.arrayOf(_react.PropTypes.string), _react.PropTypes.object]),
defaultSelectedKeys: _react.PropTypes.arrayOf(_react.PropTypes.string),
selectedKeys: _react.PropTypes.arrayOf(_react.PropTypes.string),
onExpand: _react.PropTypes.func,
onCheck: _react.PropTypes.func,
onSelect: _react.PropTypes.func,
loadData: _react.PropTypes.func,
onMouseEnter: _react.PropTypes.func,
onMouseLeave: _react.PropTypes.func,
onRightClick: _react.PropTypes.func,
onDragStart: _react.PropTypes.func,
onDragEnter: _react.PropTypes.func,
onDragOver: _react.PropTypes.func,
onDragLeave: _react.PropTypes.func,
onDrop: _react.PropTypes.func,
onDragEnd: _react.PropTypes.func,
filterTreeNode: _react.PropTypes.func,
openTransitionName: _react.PropTypes.string,
openAnimation: _react.PropTypes.oneOfType([_react.PropTypes.string, _react.PropTypes.object])
};
Tree.defaultProps = {
prefixCls: 'rc-tree',
showLine: false,
showIcon: true,
selectable: true,
multiple: false,
checkable: false,
checkStrictly: false,
draggable: false,
autoExpandParent: true,
defaultExpandAll: false,
defaultExpandedKeys: [],
defaultCheckedKeys: [],
defaultSelectedKeys: [],
onExpand: noop,
onCheck: noop,
onSelect: noop,
onDragStart: noop,
onDragEnter: noop,
onDragOver: noop,
onDragLeave: noop,
onDrop: noop,
onDragEnd: noop
};
exports["default"] = Tree;
module.exports = exports['default'];