UNPKG

@alifd/next

Version:

A configurable component library for web built on React.

1,437 lines (1,206 loc) 49.5 kB
'use strict'; exports.__esModule = true; exports.treeNodeProps = undefined; var _objectWithoutProperties2 = require('babel-runtime/helpers/objectWithoutProperties'); var _objectWithoutProperties3 = _interopRequireDefault(_objectWithoutProperties2); var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn'); var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2); var _inherits2 = require('babel-runtime/helpers/inherits'); var _inherits3 = _interopRequireDefault(_inherits2); var _extends2 = require('babel-runtime/helpers/extends'); var _extends3 = _interopRequireDefault(_extends2); var _class, _temp; /* eslint-disable max-depth */ var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); var _lodash = require('lodash.clonedeep'); var _lodash2 = _interopRequireDefault(_lodash); var _reactLifecyclesCompat = require('react-lifecycles-compat'); var _classnames = require('classnames'); var _classnames2 = _interopRequireDefault(_classnames); var _util = require('../../util'); var _treeNode = require('./tree-node'); var _treeNode2 = _interopRequireDefault(_treeNode); var _virtualList = require('../../virtual-list'); var _virtualList2 = _interopRequireDefault(_virtualList); var _util2 = require('./util'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var bindCtx = _util.func.bindCtx, noop = _util.func.noop; var getOffset = _util.dom.getOffset; var pickOthers = _util.obj.pickOthers, pickProps = _util.obj.pickProps, isPlainObject = _util.obj.isPlainObject; var treeNodeProps = exports.treeNodeProps = ['key', 'label', 'selectable', 'checkable', 'editable', 'draggable', 'disabled', 'checkboxDisabled', 'isLeaf', 'icon']; var getExpandedKeys = function getExpandedKeys(props, willReceiveProps, _k2n, _p2n) { var expandedKeys = void 0; if (!willReceiveProps && props.defaultExpandAll) { expandedKeys = Object.keys(_k2n).filter(function (key) { var children = _k2n[key].children; return children && children.length; }); } else { expandedKeys = 'expandedKeys' in props ? props.expandedKeys : willReceiveProps ? [] : props.defaultExpandedKeys; expandedKeys = (0, _util2.normalizeToArray)(expandedKeys); if (props.autoExpandParent) { var newExpandedKeys = []; var expandedPoss = expandedKeys.reduce(function (ret, key) { var pos = _k2n[key] && _k2n[key].pos; if (pos) { ret.push(pos); newExpandedKeys.push(key); } return ret; }, []); expandedPoss.forEach(function (pos) { var nums = pos.split('-'); if (nums.length === 2) { return; } for (var i = 1; i <= nums.length - 2; i++) { var ancestorPos = nums.slice(0, i + 1).join('-'); var ancestorKey = _p2n[ancestorPos].key; if (newExpandedKeys.indexOf(ancestorKey) === -1) { newExpandedKeys.push(ancestorKey); } } }); return newExpandedKeys; } } return expandedKeys; }; var getSelectedKeys = function getSelectedKeys(props, willReceiveProps, _k2n) { var selectedKeys = 'selectedKeys' in props ? props.selectedKeys : willReceiveProps ? [] : props.defaultSelectedKeys; selectedKeys = (0, _util2.normalizeToArray)(selectedKeys); return selectedKeys.filter(function (key) { return _k2n[key]; }); }; var getIndeterminateKeys = function getIndeterminateKeys(checkedKeys, checkStrictly, _k2n, _p2n) { if (checkStrictly) { return []; } var indeterminateKeys = []; var poss = (0, _util2.filterChildKey)(checkedKeys.filter(function (key) { return !!_k2n[key]; }).filter(function (key) { return !_k2n[key].disabled && !_k2n[key].checkboxDisabled && _k2n[key].checkable !== false; }), _k2n, _p2n).map(function (key) { return _k2n[key].pos; }); poss.forEach(function (pos) { var nums = pos.split('-'); for (var i = nums.length; i > 2; i--) { var parentPos = nums.slice(0, i - 1).join('-'); var parent = _p2n[parentPos]; if (parent.disabled || parent.checkboxDisabled) break; var parentKey = parent.key; if (indeterminateKeys.indexOf(parentKey) === -1) { indeterminateKeys.push(parentKey); } } }); return indeterminateKeys; }; var getCheckedKeys = function getCheckedKeys(props, willReceiveProps, _k2n, _p2n) { var checkedKeys = props.defaultCheckedKeys; var indeterminateKeys = void 0; if ('checkedKeys' in props) { checkedKeys = props.checkedKeys; } else if (willReceiveProps) { checkedKeys = []; } var checkStrictly = props.checkStrictly; // TODO TEST if (checkStrictly) { if (isPlainObject(checkedKeys)) { var _checkedKeys = checkedKeys, checked = _checkedKeys.checked, indeterminate = _checkedKeys.indeterminate; checkedKeys = (0, _util2.normalizeToArray)(checked); indeterminateKeys = (0, _util2.normalizeToArray)(indeterminate); } else { checkedKeys = (0, _util2.normalizeToArray)(checkedKeys); } checkedKeys = checkedKeys.filter(function (key) { return !!_k2n[key]; }); } else { checkedKeys = (0, _util2.getAllCheckedKeys)(checkedKeys, _k2n, _p2n); checkedKeys = checkedKeys.filter(function (key) { return !!_k2n[key]; }); indeterminateKeys = getIndeterminateKeys(checkedKeys, props.checkStrictly, _k2n, _p2n); } return { checkedKeys: checkedKeys, indeterminateKeys: indeterminateKeys }; }; var preHandleData = function preHandleData(dataSource, props) { var k2n = {}; var p2n = {}; var keyList = []; var drill = function drill() { var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; var level = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; var prefix = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '0'; var parent = arguments[3]; return data.map(function (item, index) { // 为了兼容之前的实现 保留非法节点 if (item.illegalFlag) { return item; } var children = item.children; var pos = prefix + '-' + index; var key = item.key; item.pos = pos; item.level = level; // 判断为叶子节点 // - 指定isLeaf属性 // - loadData模式下 没有指定isLeaf为true // - 存在children元素 if (!('isLeaf' in item)) { item.isLeaf = !(children && children.length || props.loadData); } item.isLastChild = parent ? [].concat(parent.isLastChild || [], index === data.length - 1) : []; if (key === undefined || key === null) { item.key = key = pos; } keyList.push(key); !item.isLeaf && drill(children, level + 1, pos, item); k2n[key] = p2n[pos] = (0, _extends3.default)({}, item); return item; }); }; return { dataSource: drill(dataSource), k2n: k2n, p2n: p2n, keyList: keyList }; }; var preHandleChildren = function preHandleChildren(props) { var k2n = {}; var p2n = {}; var keyList = []; var loop = function loop(children) { var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '0'; var level = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1; return _react.Children.map(children, function (node, index) { if (!_react2.default.isValidElement(node)) { return; } var pos = prefix + '-' + index; var key = node.key; key = key || pos; var item = (0, _extends3.default)({}, node.props, { key: key, pos: pos, level: level }); var children = node.props.children; var hasChildren = children && _react.Children.count(children); if (!('isLeaf' in item)) { item.isLeaf = !(hasChildren || props.loadData); } keyList.push(key); if (hasChildren) { item.children = loop(children, pos, level + 1); } k2n[key] = p2n[pos] = item; return item; }); }; loop(props.children); return { k2n: k2n, p2n: p2n, keyList: keyList }; }; var getData = function getData(props) { var dataSource = props.dataSource, renderChildNodes = props.renderChildNodes, _props$children = props.children, children = _props$children === undefined ? [] : _props$children, useVirtual = props.useVirtual, immutable = props.immutable; var data = immutable ? (0, _lodash2.default)(dataSource) : dataSource; if ((renderChildNodes || useVirtual) && !('dataSource' in props)) { data = (0, _util2.convertChildren2Data)(children); } if (data) { try { return preHandleData(data, props); } catch (err) { if ((err.message || '').match('object is not extensible')) { // eslint-disable-next-line no-console console.error(err.message, 'try to set immutable to true to allow immutable dataSource'); } else { throw err; } } } else { return preHandleChildren(props); } }; /** * Tree */ var Tree = (_temp = _class = function (_Component) { (0, _inherits3.default)(Tree, _Component); function Tree(props) { (0, _classCallCheck3.default)(this, Tree); var _this = (0, _possibleConstructorReturn3.default)(this, _Component.call(this, props)); var _getData = getData(props), _getData$dataSource = _getData.dataSource, dataSource = _getData$dataSource === undefined ? [] : _getData$dataSource, k2n = _getData.k2n, p2n = _getData.p2n, keyList = _getData.keyList; var _this$props = _this.props, focusable = _this$props.focusable, autoFocus = _this$props.autoFocus, focusedKey = _this$props.focusedKey; var willReceiveProps = false; var _getCheckedKeys = getCheckedKeys(props, willReceiveProps, k2n, p2n), checkedKeys = _getCheckedKeys.checkedKeys, _getCheckedKeys$indet = _getCheckedKeys.indeterminateKeys, indeterminateKeys = _getCheckedKeys$indet === undefined ? [] : _getCheckedKeys$indet; _this.state = { _k2n: k2n, _p2n: p2n, _keyList: keyList, dataSource: dataSource, willReceiveProps: willReceiveProps, expandedKeys: getExpandedKeys(props, willReceiveProps, k2n, p2n), selectedKeys: getSelectedKeys(props, willReceiveProps, k2n, p2n), checkedKeys: checkedKeys, indeterminateKeys: indeterminateKeys }; if (focusable) { _this.tabbableKey = _this.getFirstAvaliablelChildKey('0'); } _this.state.focusedKey = 'focusedKey' in props ? focusedKey : focusable && autoFocus ? _this.tabbableKey : null; if (focusable) { _this.tabbableKey = _this.getFirstAvaliablelChildKey('0'); } bindCtx(_this, ['handleExpand', 'handleSelect', 'handleCheck', 'handleBlur']); return _this; } Tree.getDerivedStateFromProps = function getDerivedStateFromProps(props, state) { var _getData2 = getData(props), _getData2$dataSource = _getData2.dataSource, dataSource = _getData2$dataSource === undefined ? [] : _getData2$dataSource, k2n = _getData2.k2n, p2n = _getData2.p2n, keyList = _getData2.keyList; var st = {}; if (!state.willReceiveProps) { return { willReceiveProps: true, _k2n: k2n, _p2n: p2n, _keyList: keyList }; } if ('expandedKeys' in props) { st.expandedKeys = getExpandedKeys(props, state.willReceiveProps, k2n, p2n); } if ('selectedKeys' in props) { st.selectedKeys = getSelectedKeys(props, state.willReceiveProps, k2n); } if ('checkedKeys' in props) { var _getCheckedKeys2 = getCheckedKeys(props, state.willReceiveProps, k2n, p2n), checkedKeys = _getCheckedKeys2.checkedKeys; st.checkedKeys = checkedKeys; } st.indeterminateKeys = props.checkStrictly ? props.checkedKeys && props.checkedKeys.indeterminate || [] : getIndeterminateKeys(st.checkedKeys || state.checkedKeys || [], props.checkStrictly, k2n, p2n); return (0, _extends3.default)({}, st, { dataSource: dataSource, _k2n: k2n, _p2n: p2n }); }; Tree.prototype.setFocusKey = function setFocusKey() { var _state$selectedKeys = this.state.selectedKeys, selectedKeys = _state$selectedKeys === undefined ? [] : _state$selectedKeys; this.setState({ focusedKey: selectedKeys.length > 0 ? selectedKeys[0] : this.getFirstAvaliablelChildKey('0') }); }; Tree.prototype.getAvailableKey = function getAvailableKey(pos, prev) { var _this2 = this; var ps = Object.keys(this.state._p2n).filter(function (p) { return _this2.isAvailablePos(pos, p); }); if (ps.length > 1) { var index = ps.indexOf(pos); var targetIndex = void 0; if (prev) { targetIndex = index === 0 ? ps.length - 1 : index - 1; } else { targetIndex = index === ps.length - 1 ? 0 : index + 1; } return this.state._p2n[ps[targetIndex]].key; } return null; }; Tree.prototype.getFirstAvaliablelChildKey = function getFirstAvaliablelChildKey(parentPos) { var _this3 = this; var pos = Object.keys(this.state._p2n).find(function (p) { return _this3.isAvailablePos(parentPos + '-0', p); }); return pos ? this.state._p2n[pos].key : null; }; Tree.prototype.isAvailablePos = function isAvailablePos(refPos, targetPos) { var disabled = this.state._p2n[targetPos].disabled; return this.isSibling(refPos, targetPos) && !disabled; }; Tree.prototype.isSibling = function isSibling(currentPos, targetPos) { var currentNums = currentPos.split('-').slice(0, -1); var targetNums = targetPos.split('-').slice(0, -1); return currentNums.length === targetNums.length && currentNums.every(function (num, index) { return num === targetNums[index]; }); }; Tree.prototype.getParentKey = function getParentKey(pos) { return this.state._p2n[pos.slice(0, pos.length - 2)].key; }; Tree.prototype.processKey = function processKey(keys, key, add) { var index = keys.indexOf(key); if (add && index === -1) { keys.push(key); } else if (!add && index > -1) { keys.splice(index, 1); } return keys; }; /*eslint-disable max-statements*/ Tree.prototype.handleItemKeyDown = function handleItemKeyDown(key, item, e) { if ([_util.KEYCODE.UP, _util.KEYCODE.DOWN, _util.KEYCODE.RIGHT, _util.KEYCODE.LEFT, _util.KEYCODE.ENTER, _util.KEYCODE.ESC, _util.KEYCODE.SPACE].indexOf(e.keyCode) > -1) { e.preventDefault(); e.stopPropagation(); } var focusedKey = this.state.focusedKey; var node = this.state._k2n[key]; var pos = this.state._k2n[key].pos; var level = pos.split('-').length - 1; switch (e.keyCode) { case _util.KEYCODE.UP: { var avaliableKey = this.getAvailableKey(pos, true); if (avaliableKey) { focusedKey = avaliableKey; } break; } case _util.KEYCODE.DOWN: { var _avaliableKey = this.getAvailableKey(pos, false); if (_avaliableKey) { focusedKey = _avaliableKey; } break; } case _util.KEYCODE.RIGHT: { this.handleExpand(true, key, node); var _avaliableKey2 = this.getFirstAvaliablelChildKey(pos); if (_avaliableKey2) { focusedKey = _avaliableKey2; } break; } case _util.KEYCODE.LEFT: case _util.KEYCODE.ESC: { if (level === 1) { var _avaliableKey3 = this.getAvailableKey(pos, true); if (_avaliableKey3) { focusedKey = _avaliableKey3; } } else if (level > 1) { var parentKey = this.getParentKey(pos); this.handleExpand(false, parentKey, node); focusedKey = parentKey; } break; } case _util.KEYCODE.ENTER: case _util.KEYCODE.SPACE: { var checkable = 'checkable' in item.props ? item.props.checkable : this.props.checkable; var selectable = 'selectable' in item.props ? item.props.selectable : this.props.selectable; if (checkable) { this.handleCheck(!item.props.checked, key, node); } else if (selectable) { this.handleSelect(!item.props.selected, key, node, e); } break; } case _util.KEYCODE.TAB: focusedKey = null; break; default: break; } if (focusedKey !== this.state.focusedKey) { if (!('focusedKey' in this.props)) { this.setState({ focusedKey: focusedKey }); } } this.props.onItemKeyDown(focusedKey, item, e); this.props.onItemFocus(focusedKey, e); }; Tree.prototype.handleBlur = function handleBlur(e) { this.setState({ focusedKey: null }); this.props.onBlur && this.props.onBlur(e); }; Tree.prototype.handleExpand = function handleExpand(expand, key, node) { var _this4 = this; var _props = this.props, onExpand = _props.onExpand, loadData = _props.loadData; var expandedKeys = this.state.expandedKeys; // 由于setState 是异步操作,所以去掉 [...this.state.expandedKeys] this.processKey(expandedKeys, key, expand); var setExpandedState = function setExpandedState() { if (!('expandedKeys' in _this4.props)) { _this4.setState({ expandedKeys: expandedKeys }); } onExpand(expandedKeys, { expanded: expand, node: node }); }; if (expand && loadData) { return loadData(node).then(setExpandedState); } else { setExpandedState(); } }; Tree.prototype.handleSelect = function handleSelect(select, key, node, e) { var _props2 = this.props, multiple = _props2.multiple, onSelect = _props2.onSelect; var selectedKeys = [].concat(this.state.selectedKeys); if (multiple) { this.processKey(selectedKeys, key, select); } else { selectedKeys = select ? [key] : []; } if (!('selectedKeys' in this.props)) { this.setState({ selectedKeys: selectedKeys }); } onSelect(selectedKeys, { selectedNodes: this.getNodes(selectedKeys), node: node, selected: select, event: e }); }; // eslint-disable-next-line max-statements Tree.prototype.handleCheck = function handleCheck(check, key, node) { var _this5 = this; var _props3 = this.props, checkStrictly = _props3.checkStrictly, checkedStrategy = _props3.checkedStrategy, onCheck = _props3.onCheck; var _state = this.state, _k2n = _state._k2n, _p2n = _state._p2n; var checkedKeys = [].concat(this.state.checkedKeys); if (checkStrictly) { this.processKey(checkedKeys, key, check); var _newCheckedKeys = isPlainObject(this.props.checkedKeys) ? { checked: checkedKeys, indeterminate: this.state.indeterminateKeys } : checkedKeys; onCheck(_newCheckedKeys, { checkedNodes: this.getNodes(checkedKeys), checkedNodesPositions: checkedKeys.map(function (key) { if (!_k2n[key]) return null; var _k2n$key = _k2n[key], node = _k2n$key.node, pos = _k2n$key.pos; return { node: node, pos: pos }; }).filter(function (v) { return !!v; }), node: node, indeterminateKeys: this.state.indeterminateKeys, checked: check, key: key }); return; } var pos = _k2n[key].pos; (0, _util2.forEachEnableNode)(_k2n[key], function (node) { if (node.checkable === false) return; _this5.processKey(checkedKeys, node.key, check); }); var ps = Object.keys(_p2n); var currentPos = pos; var nums = pos.split('-'); for (var i = nums.length; i > 2; i--) { var parentCheck = true; var parentPos = nums.slice(0, i - 1).join('-'); if (_p2n[parentPos].disabled || _p2n[parentPos].checkboxDisabled || _p2n[parentPos].checkable === false) { currentPos = parentPos; continue; } var parentKey = _p2n[parentPos].key; var parentChecked = checkedKeys.indexOf(parentKey) > -1; if (!check && !parentChecked) { break; } for (var j = 0; j < ps.length; j++) { var p = ps[j]; var pnode = _p2n[p]; if ((0, _util2.isSiblingOrSelf)(currentPos, p) && !pnode.disabled && !pnode.checkboxDisabled) { var k = pnode.key; if (pnode.checkable === false) { // eslint-disable-next-line max-depth if (!pnode.children || pnode.children.length === 0) continue; // eslint-disable-next-line max-depth for (var m = 0; m < pnode.children.length; m++) { if (!pnode.children.every(function (child) { return (0, _util2.isNodeChecked)(child, checkedKeys); })) { parentCheck = false; break; } } } else if (checkedKeys.indexOf(k) === -1) { parentCheck = false; } if (!parentCheck) break; } } this.processKey(checkedKeys, parentKey, parentCheck); currentPos = parentPos; } var indeterminateKeys = getIndeterminateKeys(checkedKeys, checkStrictly, _k2n, _p2n); if (!('checkedKeys' in this.props)) { this.setState({ checkedKeys: checkedKeys, indeterminateKeys: indeterminateKeys }); } var newCheckedKeys = void 0; switch (checkedStrategy) { case 'parent': newCheckedKeys = (0, _util2.filterChildKey)(checkedKeys, _k2n, _p2n); break; case 'child': newCheckedKeys = (0, _util2.filterParentKey)(checkedKeys, _k2n, _p2n); break; default: newCheckedKeys = checkedKeys; break; } onCheck(newCheckedKeys, { checkedNodes: this.getNodes(newCheckedKeys), checkedNodesPositions: newCheckedKeys.map(function (key) { if (!_k2n[key]) return null; var _k2n$key2 = _k2n[key], node = _k2n$key2.node, pos = _k2n$key2.pos; return { node: node, pos: pos }; }).filter(function (v) { return !!v; }), node: node, indeterminateKeys: indeterminateKeys, checked: check, key: key }); }; Tree.prototype.getNodeProps = function getNodeProps(key) { var prefix = this.props.prefix; var _state2 = this.state, expandedKeys = _state2.expandedKeys, selectedKeys = _state2.selectedKeys, checkedKeys = _state2.checkedKeys, dragOverNodeKey = _state2.dragOverNodeKey, _k2n = _state2._k2n, indeterminateKeys = _state2.indeterminateKeys; var _k2n$key3 = _k2n[key], pos = _k2n$key3.pos, isLeaf = _k2n$key3.isLeaf, level = _k2n$key3.level; return { prefix: prefix, root: this, eventKey: key, pos: pos, isLeaf: isLeaf, level: level, expanded: expandedKeys.indexOf(key) > -1, selected: selectedKeys.indexOf(key) > -1, checked: checkedKeys.indexOf(key) > -1, indeterminate: indeterminateKeys.indexOf(key) > -1, dragOver: dragOverNodeKey === key && this.dropPosition === 0, dragOverGapTop: dragOverNodeKey === key && this.dropPosition === -1, dragOverGapBottom: dragOverNodeKey === key && this.dropPosition === 1 }; }; Tree.prototype.getNodes = function getNodes(keys) { var _this6 = this; return keys.map(function (key) { return _this6.state._k2n[key] && _this6.state._k2n[key].node; }).filter(function (v) { return !!v; }); }; Tree.prototype.handleDragStart = function handleDragStart(e, node) { var _this7 = this; var dragNodeKey = node.props.eventKey; this.dragNode = node; this.dragNodesKeys = Object.keys(this.state._k2n).filter(function (k) { return (0, _util2.isDescendantOrSelf)(_this7.state._k2n[dragNodeKey].pos, _this7.state._k2n[k].pos); }); var expandedKeys = this.processKey([].concat(this.state.expandedKeys), dragNodeKey, false); this.setState({ expandedKeys: expandedKeys }); this.props.onDragStart({ event: e, node: node, expandedKeys: expandedKeys }); }; Tree.prototype.handleDragEnter = function handleDragEnter(e, node) { var dragOverNodeKey = node.props.eventKey; this.dropPosition = this.getDropPosition(e, node); if (this.dragNode && this.dragNode.props.eventKey === dragOverNodeKey && this.dropPosition === 0) { this.setState({ dragOverNodeKey: null }); return; } var expandedKeys = this.processKey([].concat(this.state.expandedKeys), dragOverNodeKey, true); this.setState({ dragOverNodeKey: dragOverNodeKey, expandedKeys: expandedKeys }); this.props.onDragEnter({ event: e, node: node, expandedKeys: expandedKeys }); }; Tree.prototype.getDropPosition = function getDropPosition(e, node) { var labelWrapperNode = node.labelWrapperEl; var offsetTop = getOffset(labelWrapperNode).top; var offsetHeight = labelWrapperNode.offsetHeight; var pageY = e.pageY; var gapHeight = 2; if (pageY > offsetTop + offsetHeight - gapHeight) { return 1; } if (pageY < offsetTop + gapHeight) { return -1; } return 0; }; Tree.prototype.handleDragOver = function handleDragOver(e, node) { var dragOverNodeKey = node.props.eventKey; if (this.state.dragOverNodeKey !== dragOverNodeKey) { this.setState({ dragOverNodeKey: dragOverNodeKey }); } this.props.onDragOver({ event: e, node: node }); }; Tree.prototype.handleDragLeave = function handleDragLeave(e, node) { var eventKey = node.props.eventKey; var _keyList = this.state._keyList; var firstKey = _keyList[0]; var lastKey = _keyList[_keyList.length - 1]; // 只针对树的边界节点(第一个和最后一个)做处理 if (eventKey === firstKey || eventKey === lastKey) { this.setState({ dragOverNodeKey: null }); } this.props.onDragLeave({ event: e, node: node }); }; Tree.prototype.handleDragEnd = function handleDragEnd(e, node) { this.setState({ dragOverNodeKey: null }); this.props.onDragEnd({ event: e, node: node }); }; Tree.prototype.handleDrop = function handleDrop(e, node) { if (this.dragNode && (0, _util2.isDescendantOrSelf)(this.state._k2n[this.dragNode.props.eventKey].pos, this.state._k2n[node.props.eventKey].pos)) { return; } this.setState({ dragOverNodeKey: null }); var params = this.generateDropParams(node); this.props.onDrop((0, _extends3.default)({ event: e }, params)); }; Tree.prototype.canDrop = function canDrop(node) { var params = this.generateDropParams(node); return this.props.canDrop(params); }; Tree.prototype.generateDropParams = function generateDropParams(node) { return { dragNode: this.dragNode, dragNodesKeys: [].concat(this.dragNodesKeys), node: node, dropPosition: this.dropPosition }; }; Tree.prototype.filterTreeNode = function filterTreeNode(node) { return this.props.filterTreeNode.call(this, node); }; Tree.prototype.shouldNodeShow = function shouldNodeShow(nodeData) { var _state3 = this.state, expandedKeys = _state3.expandedKeys, _p2n = _state3._p2n; return !(nodeData.style && nodeData.style.display === 'none') && (0, _util2.getAllDescendantKeys)(nodeData, _p2n).every(function (k) { return expandedKeys.includes(k); }); }; Tree.prototype.renderTreeNode = function renderTreeNode(props, childNodes) { var _props4 = this.props, rtl = _props4.rtl, labelRender = _props4.labelRender; var key = props.key; var nodeProps = (0, _extends3.default)({ _key: key }, props, this.getNodeProps(key)); if (labelRender) { nodeProps.label = labelRender(pickProps(treeNodeProps, props)); } return _react2.default.createElement( _treeNode2.default, (0, _extends3.default)({ rtl: rtl, key: key }, nodeProps), childNodes ); }; Tree.prototype.renderNodeList = function renderNodeList(dataSource) { var _this8 = this; var nodeList = []; var _k2n = this.state._k2n; var drill = function drill(list) { list.forEach(function (item) { // 为了兼容之前的实现 保留非法节点 if (item.illegalFlag) { nodeList.push(item); return; } var children = item.children, nodeProps = (0, _objectWithoutProperties3.default)(item, ['children']); if (!_this8.shouldNodeShow(item)) { return; } nodeList.push(nodeProps); children && children.length && drill(children); }); }; drill(dataSource); return nodeList.map(function (nodeProps, index) { // 为了兼容之前的实现 保留非法节点 if (nodeProps.illegalFlag) { return nodeProps.node; } // aria props nodeProps.size = nodeList.length; nodeProps.posinset = index + 1; return _k2n[nodeProps.key].node = _this8.renderTreeNode(nodeProps); }); }; Tree.prototype.renderWithCustomChildNodes = function renderWithCustomChildNodes(dataSource) { var _this9 = this; var renderChildNodes = this.props.renderChildNodes; var _k2n = this.state._k2n; var drill = function drill(list) { return list.map(function (_ref, index) { var children = _ref.children, nodeProps = (0, _objectWithoutProperties3.default)(_ref, ['children']); var childNodes = void 0; if (children && children.length) { childNodes = renderChildNodes(drill(children)); } // aria props nodeProps.size = list.length; nodeProps.posinset = index + 1; return _k2n[nodeProps.key].node = _this9.renderTreeNode(nodeProps, childNodes); }); }; return drill(dataSource); }; Tree.prototype.renderByDataSource = function renderByDataSource(dataSource) { var _this10 = this; var drill = function drill(data) { var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '0'; return data.map(function (item, index) { // 为了兼容之前的实现 保留非法节点 if (item.illegalFlag) { return item.node; } var pos = prefix + '-' + index; var _item$key = item.key, key = _item$key === undefined ? pos : _item$key, children = item.children, others = (0, _objectWithoutProperties3.default)(item, ['key', 'children']); var props = (0, _extends3.default)({ size: data.length }, others, _this10.getNodeProps('' + key), { _key: key, key: key }); if (children && children.length) { props.children = drill(children, pos); } var node = _this10.renderTreeNode(props, props.children); // eslint-disable-next-line _this10.state._k2n[key].node = node; return node; }); }; return drill(dataSource); }; Tree.prototype.renderByChildren = function renderByChildren() { var _this11 = this; var rtl = this.props.rtl; var _k2n = this.state._k2n; var loop = function loop(children) { var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '0'; return _react.Children.map(children, function (child, index) { if (!_react2.default.isValidElement(child)) { return; } var pos = prefix + '-' + index; var key = child.key || pos; var props = _this11.getNodeProps('' + key); if (child.props.children) { props.children = loop(child.props.children, pos); } props._key = key; props.rtl = rtl; props.size = _react.Children.count(children); var node = (0, _react.cloneElement)(child, props); _k2n[key].node = node; return node; }); }; return loop(this.props.children); }; Tree.prototype.render = function render() { var _cx, _this12 = this; var _props5 = this.props, prefix = _props5.prefix, rtl = _props5.rtl, className = _props5.className, showLine = _props5.showLine, isNodeBlock = _props5.isNodeBlock, isLabelBlock = _props5.isLabelBlock, multiple = _props5.multiple, useVirtual = _props5.useVirtual, renderChildNodes = _props5.renderChildNodes; var dataSource = this.state.dataSource; var _pickOthers = pickOthers(Object.keys(Tree.propTypes), this.props), style = _pickOthers.style, others = (0, _objectWithoutProperties3.default)(_pickOthers, ['style']); if (rtl) { others.dir = 'rtl'; } var newClassName = (0, _classnames2.default)((_cx = {}, _cx[prefix + 'tree'] = true, _cx[prefix + 'label-block'] = isLabelBlock, _cx[prefix + 'node-block'] = isNodeBlock, _cx[prefix + 'node-indent'] = !isNodeBlock, _cx[prefix + 'show-line'] = !isNodeBlock && showLine, _cx[className] = !!className, _cx)); var treeRender = function treeRender(items, ref) { return _react2.default.createElement( 'ul', (0, _extends3.default)({ role: 'tree', ref: ref, 'aria-multiselectable': multiple, onBlur: _this12.handleBlur, className: newClassName, style: useVirtual ? null : style }, others), items ); }; var virtualTreeRender = function virtualTreeRender(dataSource) { return _react2.default.createElement( 'div', { className: prefix + 'virtual-tree-container', style: style }, _react2.default.createElement( _virtualList2.default, { itemsRenderer: function itemsRenderer(items, ref) { return treeRender(items, ref); } }, _this12.renderNodeList(dataSource) ) ); }; return useVirtual ? virtualTreeRender(dataSource) : renderChildNodes ? treeRender(this.renderWithCustomChildNodes(dataSource)) : !this.props.dataSource ? treeRender(this.renderByChildren()) : treeRender(this.renderByDataSource(dataSource)); }; return Tree; }(_react.Component), _class.propTypes = { prefix: _propTypes2.default.string, rtl: _propTypes2.default.bool, pure: _propTypes2.default.bool, className: _propTypes2.default.string, /** * 树节点 */ children: _propTypes2.default.node, /** * 数据源,该属性优先级高于 children */ dataSource: _propTypes2.default.array, /** * 是否显示树的线 */ showLine: _propTypes2.default.bool, /** * 是否支持选中节点 */ selectable: _propTypes2.default.bool, /** * (用于受控)当前选中节点 key 的数组 */ selectedKeys: _propTypes2.default.arrayOf(_propTypes2.default.string), /** * (用于非受控)默认选中节点 key 的数组 */ defaultSelectedKeys: _propTypes2.default.arrayOf(_propTypes2.default.string), /** * 选中或取消选中节点时触发的回调函数 * @param {Array} selectedKeys 选中节点key的数组 * @param {Object} extra 额外参数 * @param {Array} extra.selectedNodes 选中节点的数组 * @param {Object} extra.node 当前操作的节点 * @param {Boolean} extra.selected 当前操作是否是选中 */ onSelect: _propTypes2.default.func, /** * 是否支持多选 */ multiple: _propTypes2.default.bool, /** * 是否支持勾选节点的复选框 */ checkable: _propTypes2.default.bool, /** * (用于受控)当前勾选复选框节点 key 的数组或 `{checked: Array, indeterminate: Array}` 的对象 */ checkedKeys: _propTypes2.default.oneOfType([_propTypes2.default.arrayOf(_propTypes2.default.string), _propTypes2.default.object]), /** * (用于非受控)默认勾选复选框节点 key 的数组 */ defaultCheckedKeys: _propTypes2.default.arrayOf(_propTypes2.default.string), /** * 勾选节点复选框是否完全受控(父子节点选中状态不再关联) */ checkStrictly: _propTypes2.default.bool, /** * 定义选中时回填的方式 * @enumdesc 返回所有选中的节点, 父子节点都选中时只返回父节点, 父子节点都选中时只返回子节点 */ checkedStrategy: _propTypes2.default.oneOf(['all', 'parent', 'child']), /** * 勾选或取消勾选复选框时触发的回调函数 * @param {Array} checkedKeys 勾选复选框节点key的数组 * @param {Object} extra 额外参数 * @param {Array} extra.checkedNodes 勾选复选框节点的数组 * @param {Array} extra.checkedNodesPositions 包含有勾选复选框节点和其位置的对象的数组 * @param {Array} extra.indeterminateKeys 半选复选框节点 key 的数组 * @param {Object} extra.node 当前操作的节点 * @param {Boolean} extra.checked 当前操作是否是勾选 */ onCheck: _propTypes2.default.func, /** * (用于受控)当前展开的节点 key 的数组 */ expandedKeys: _propTypes2.default.arrayOf(_propTypes2.default.string), /** * (用于非受控)默认展开的节点 key 的数组 */ defaultExpandedKeys: _propTypes2.default.arrayOf(_propTypes2.default.string), /** * 是否默认展开所有节点 */ defaultExpandAll: _propTypes2.default.bool, /** * 是否自动展开父节点,建议受控时设置为false */ autoExpandParent: _propTypes2.default.bool, /** * 展开或收起节点时触发的回调函数 * @param {Array} expandedKeys 展开的节点key的数组 * @param {Object} extra 额外参数 * @param {Object} extra.node 当前操作的节点 * @param {Boolean} extra.expanded 当前操作是否是展开 */ onExpand: _propTypes2.default.func, /** * 是否支持编辑节点内容 */ editable: _propTypes2.default.bool, /** * 编辑节点内容完成时触发的回调函数 * @param {String} key 编辑节点的 key * @param {String} label 编辑节点完成时节点的文本 * @param {Object} node 当前编辑的节点 */ onEditFinish: _propTypes2.default.func, /** * 是否支持拖拽节点 */ draggable: _propTypes2.default.bool, /** * 开始拖拽节点时触发的回调函数 * @param {Object} info 拖拽信息 * @param {Object} info.event 事件对象 * @param {Object} info.node 拖拽的节点 */ onDragStart: _propTypes2.default.func, /** * 拖拽节点进入目标节点时触发的回调函数 * @param {Object} info 拖拽信息 * @param {Object} info.event 事件对象 * @param {Object} info.node 目标节点 * @param {Array} info.expandedKeys 当前展开的节点key的数组 */ onDragEnter: _propTypes2.default.func, /** * 拖拽节点在目标节点上移动的时候触发的回调函数 * @param {Object} info 拖拽信息 * @param {Object} info.event 事件对象 * @param {Object} info.node 目标节点 */ onDragOver: _propTypes2.default.func, /** * 拖拽节点离开目标节点时触发的回调函数 * @param {Object} info 拖拽信息 * @param {Object} info.event 事件对象 * @param {Object} info.node 目标节点 */ onDragLeave: _propTypes2.default.func, /** * 拖拽节点拖拽结束时触发的回调函数 * @param {Object} info 拖拽信息 * @param {Object} info.event 事件对象 * @param {Object} info.node 目标节点 */ onDragEnd: _propTypes2.default.func, /** * 拖拽节点放入目标节点内或前后触发的回调函数 * @param {Object} info 拖拽信息 * @param {Object} info.event 事件对象 * @param {Object} info.node 目标节点 * @param {Object} info.dragNode 拖拽的节点 * @param {Array} info.dragNodesKeys 拖拽的节点和其子节点 key 的数组 * @param {Number} info.dropPosition 放置位置,-1代表当前节点前,0代表当前节点里,1代表当前节点后 */ onDrop: _propTypes2.default.func, /** * 节点是否可被作为拖拽的目标节点 * @param {Object} info 拖拽信息 * @param {Object} info.node 目标节点 * @param {Object} info.dragNode 拖拽的节点 * @param {Array} info.dragNodesKeys 拖拽的节点和其子节点 key 的数组 * @param {Number} info.dropPosition 放置位置,-1代表当前节点前,0代表当前节点里,1代表当前节点后 * @return {Boolean} 是否可以被当作目标节点 */ canDrop: _propTypes2.default.func, /** * 异步加载数据的函数 * @param {Object} node 被点击展开的节点 */ loadData: _propTypes2.default.func, /** * 按需筛选高亮节点 * @param {Object} node 待筛选的节点 * @return {Boolean} 是否被筛选中 */ filterTreeNode: _propTypes2.default.func, /** * 右键点击节点时触发的回调函数 * @param {Object} info 信息对象 * @param {Object} info.event 事件对象 * @param {Object} info.node 点击的节点 */ onRightClick: _propTypes2.default.func, /** * 设置节点是否占满剩余空间,一般用于统一在各节点右侧添加元素(借助 flex 实现,暂时只支持 ie10+) */ isLabelBlock: _propTypes2.default.bool, /** * 设置节点是否占满一行 */ isNodeBlock: _propTypes2.default.oneOfType([_propTypes2.default.bool, _propTypes2.default.object]), /** * 是否开启展开收起动画 */ animation: _propTypes2.default.bool, /** * 当前获得焦点的子菜单或菜单项 key 值 */ focusedKey: _propTypes2.default.string, /** * 渲染子节点 * @param {Array<ReactNode>} nodes 所有的子节点 * @return {ReactNode} 返回节点 */ renderChildNodes: _propTypes2.default.func, focusable: _propTypes2.default.bool, autoFocus: _propTypes2.default.bool, onItemFocus: _propTypes2.default.func, onBlur: _propTypes2.default.func, onItemKeyDown: _propTypes2.default.func, /** * 自定义渲染单个子节点 * @param {Object} node 节点数据 * @return {ReactNode} 返回节点 * @version 1.25 */ labelRender: _propTypes2.default.func, /** * 是否开启虚拟滚动 */ useVirtual: _propTypes2.default.bool, /** * 是否是不可变数据 * @version 1.23 */ immutable: _propTypes2.default.bool }, _class.defaultProps = { prefix: 'next-', rtl: false, pure: false, showLine: false, selectable: true, editable: false, multiple: false, checkable: false, checkStrictly: false, checkedStrategy: 'all', draggable: false, autoExpandParent: true, defaultExpandAll: false, defaultExpandedKeys: [], defaultCheckedKeys: [], defaultSelectedKeys: [], onExpand: noop, onCheck: noop, onSelect: noop, onDragStart: noop, onDragEnter: noop, onDragOver: noop, onDragLeave: noop, onDragEnd: noop, onDrop: noop, canDrop: function canDrop() { return true; }, onEditFinish: noop, onRightClick: noop, isLabelBlock: false, isNodeBlock: false, animation: true, focusable: true, autoFocus: false, onItemFocus: noop, onItemKeyDown: noop, useVirtual: false, immutable: false }, _temp); Tree.displayName = 'Tree'; exports.default = (0, _reactLifecyclesCompat.polyfill)(Tree);