UNPKG

choerodon-ui

Version:

An enterprise-class UI design language and React-based implementation

560 lines (467 loc) 21.5 kB
import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _extends from "@babel/runtime/helpers/extends"; import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties"; import _objectSpread from "@babel/runtime/helpers/objectSpread2"; import _typeof from "@babel/runtime/helpers/typeof"; import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import _createSuper from "@babel/runtime/helpers/createSuper"; var _excluded = ["eventKey", "className", "style", "dragOver", "dragOverGapTop", "dragOverGapBottom", "isLeaf", "isStart", "isEnd", "expanded", "selected", "checked", "halfChecked", "loading", "domRef", "active", "data", "onMouseMove", "context"]; import * as React from 'react'; import classNames from 'classnames'; import Icon from '../../icon'; import { TreeContext } from './contextTypes'; import { getDataAndAria } from './util'; import Indent from './Indent'; import { convertNodePropsToEventData } from './utils/treeUtil'; import { stopEvent } from '../../_util/EventManager'; import Ripple from '../../ripple'; var ICON_OPEN = 'open'; var ICON_CLOSE = 'close'; var defaultTitle = '---'; var InternalTreeNode = /*#__PURE__*/function (_React$Component) { _inherits(InternalTreeNode, _React$Component); var _super = _createSuper(InternalTreeNode); function InternalTreeNode() { var _this; _classCallCheck(this, InternalTreeNode); _this = _super.apply(this, arguments); _this.state = { dragNodeHighlight: false }; _this.onSelectorClick = function (e) { // Click trigger before select/check operation var context = _this.props.context; var onNodeClick = context.onNodeClick; onNodeClick(e, convertNodePropsToEventData(_this.props)); if (_this.isSelectable()) { _this.onSelect(e); } else { _this.onCheck(e); } }; _this.onSelectorDoubleClick = function (e) { var context = _this.props.context; var onNodeDoubleClick = context.onNodeDoubleClick; onNodeDoubleClick(e, convertNodePropsToEventData(_this.props)); }; _this.onSelect = function (e) { if (_this.isDisabled()) return; var context = _this.props.context; var onNodeSelect = context.onNodeSelect; e.preventDefault(); onNodeSelect(e, convertNodePropsToEventData(_this.props)); }; _this.onCheck = function (e) { if (_this.isDisabled()) return; var disableCheckbox = _this.props.disableCheckbox; if (!_this.isCheckable() || disableCheckbox) return; var _this$props = _this.props, checked = _this$props.checked, context = _this$props.context; var onNodeCheck = context.onNodeCheck; stopEvent(e); var targetChecked = !checked; onNodeCheck(e, convertNodePropsToEventData(_this.props), targetChecked); }; _this.onMouseEnter = function (e) { var context = _this.props.context; var onNodeMouseEnter = context.onNodeMouseEnter; onNodeMouseEnter(e, convertNodePropsToEventData(_this.props)); }; _this.onMouseLeave = function (e) { var context = _this.props.context; var onNodeMouseLeave = context.onNodeMouseLeave; onNodeMouseLeave(e, convertNodePropsToEventData(_this.props)); }; _this.onContextMenu = function (e) { var context = _this.props.context; var onNodeContextMenu = context.onNodeContextMenu; onNodeContextMenu(e, convertNodePropsToEventData(_this.props)); }; _this.onDragStart = function (e) { var context = _this.props.context; var onNodeDragStart = context.onNodeDragStart; e.stopPropagation(); _this.setState({ dragNodeHighlight: true }); onNodeDragStart(e, _assertThisInitialized(_this)); try { // ie throw error // firefox-need-it e.dataTransfer.setData('text/plain', ''); } catch (error) {// empty } }; _this.onDragEnter = function (e) { var context = _this.props.context; var onNodeDragEnter = context.onNodeDragEnter; e.preventDefault(); e.stopPropagation(); onNodeDragEnter(e, _assertThisInitialized(_this)); }; _this.onDragOver = function (e) { var context = _this.props.context; var onNodeDragOver = context.onNodeDragOver; e.preventDefault(); e.stopPropagation(); onNodeDragOver(e, _assertThisInitialized(_this)); }; _this.onDragLeave = function (e) { var context = _this.props.context; var onNodeDragLeave = context.onNodeDragLeave; e.stopPropagation(); onNodeDragLeave(e, _assertThisInitialized(_this)); }; _this.onDragEnd = function (e) { var context = _this.props.context; var onNodeDragEnd = context.onNodeDragEnd; e.stopPropagation(); _this.setState({ dragNodeHighlight: false }); onNodeDragEnd(e, _assertThisInitialized(_this)); }; _this.onDrop = function (e) { var context = _this.props.context; var onNodeDrop = context.onNodeDrop; e.preventDefault(); e.stopPropagation(); _this.setState({ dragNodeHighlight: false }); onNodeDrop(e, _assertThisInitialized(_this)); }; // Disabled item still can be switch _this.onExpand = function (e) { stopEvent(e); var _this$props2 = _this.props, loading = _this$props2.loading, context = _this$props2.context; var onNodeExpand = context.onNodeExpand; if (loading) return; onNodeExpand(e, convertNodePropsToEventData(_this.props)); }; // Drag usage _this.setSelectHandle = function (node) { _this.selectHandle = node; }; _this.getNodeState = function () { var expanded = _this.props.expanded; if (_this.isLeaf()) { return null; } return expanded ? ICON_OPEN : ICON_CLOSE; }; _this.hasChildren = function () { var _this$props3 = _this.props, eventKey = _this$props3.eventKey, context = _this$props3.context; var keyEntities = context.keyEntities; var _ref = keyEntities[eventKey] || {}, children = _ref.children; return !!(children || []).length; }; _this.isLeaf = function () { var _this$props4 = _this.props, isLeaf = _this$props4.isLeaf, loaded = _this$props4.loaded, context = _this$props4.context; var loadData = context.loadData; var hasChildren = _this.hasChildren(); if (isLeaf === false) { return false; } return isLeaf || !loadData && !hasChildren || loadData && loaded && !hasChildren; }; _this.isDisabled = function () { var _this$props5 = _this.props, disabled = _this$props5.disabled, context = _this$props5.context; var treeDisabled = context.disabled; return !!(treeDisabled || disabled); }; _this.isCheckable = function () { var _this$props6 = _this.props, checkable = _this$props6.checkable, context = _this$props6.context; var treeCheckable = context.checkable; // Return false if tree or treeNode is not checkable if (!treeCheckable || checkable === false) return false; return treeCheckable; }; // Load data to avoid default expanded tree without data _this.syncLoadData = function (props) { var expanded = props.expanded, loading = props.loading, loaded = props.loaded, context = props.context; var loadData = context.loadData, onNodeLoad = context.onNodeLoad; if (loading) return; // read from state to avoid loadData at same time if (loadData && expanded && !_this.isLeaf()) { // We needn't reload data when has children in sync logic // It's only needed in node expanded if (!_this.hasChildren() && !loaded) { onNodeLoad(convertNodePropsToEventData(_this.props)); } } }; _this.getMergedDraggable = function (draggable, data) { if (typeof draggable === 'function') { return draggable(data); } if (_typeof(draggable) === 'object') { var _draggable$nodeDragga = draggable.nodeDraggable, nodeDraggable = _draggable$nodeDragga === void 0 ? false : _draggable$nodeDragga; return typeof nodeDraggable === 'function' ? nodeDraggable(data) : nodeDraggable; } return draggable; }; // renderDraggableIcon _this.renderDraggableIcon = function () { var context = _this.props.context; var prefixCls = context.prefixCls, draggable = context.draggable; if (_typeof(draggable) === 'object') { var _draggable$icon = draggable.icon, icon = _draggable$icon === void 0 ? false : _draggable$icon; if (icon) { return /*#__PURE__*/React.createElement("span", { className: "".concat(prefixCls, "-draggable-icon") }, /*#__PURE__*/React.isValidElement(icon) ? icon : /*#__PURE__*/React.createElement(Icon, { type: "baseline-drag_indicator" })); } return null; } }; // Switcher _this.renderSwitcher = function () { var _this$props7 = _this.props, expanded = _this$props7.expanded, switcherIconFromProps = _this$props7.switcherIcon, context = _this$props7.context; var prefixCls = context.prefixCls, switcherIconFromCtx = context.switcherIcon; var switcherIcon = switcherIconFromProps || switcherIconFromCtx; if (_this.isLeaf()) { return /*#__PURE__*/React.createElement("span", { className: classNames("".concat(prefixCls, "-switcher"), "".concat(prefixCls, "-switcher-noop")) }, typeof switcherIcon === 'function' ? switcherIcon(_objectSpread(_objectSpread({}, _this.props), {}, { isLeaf: true })) : switcherIcon); } var switcherCls = classNames("".concat(prefixCls, "-switcher"), "".concat(prefixCls, "-switcher_").concat(expanded ? ICON_OPEN : ICON_CLOSE)); return /*#__PURE__*/React.createElement("span", { onClick: _this.onExpand, className: switcherCls }, typeof switcherIcon === 'function' ? switcherIcon(_objectSpread(_objectSpread({}, _this.props), {}, { isLeaf: false })) : switcherIcon); }; // Checkbox _this.renderCheckbox = function () { var _this$props8 = _this.props, checked = _this$props8.checked, halfChecked = _this$props8.halfChecked, disableCheckbox = _this$props8.disableCheckbox, context = _this$props8.context; var prefixCls = context.prefixCls; var disabled = _this.isDisabled(); var checkable = _this.isCheckable(); if (!checkable) return null; // [Legacy] Custom element should be separate with `checkable` in future var $custom = typeof checkable !== 'boolean' ? checkable : null; return /*#__PURE__*/React.createElement("span", { className: classNames("".concat(prefixCls, "-checkbox"), checked && "".concat(prefixCls, "-checkbox-checked"), !checked && halfChecked && "".concat(prefixCls, "-checkbox-indeterminate"), (disabled || disableCheckbox) && "".concat(prefixCls, "-checkbox-disabled")), onClick: _this.onCheck }, $custom); }; _this.renderIcon = function () { var _this$props9 = _this.props, loading = _this$props9.loading, context = _this$props9.context; var prefixCls = context.prefixCls; return /*#__PURE__*/React.createElement("span", { className: classNames("".concat(prefixCls, "-iconEle"), "".concat(prefixCls, "-icon__").concat(_this.getNodeState() || 'docu'), loading && "".concat(prefixCls, "-icon_loading")) }); }; // Icon + Title _this.renderSelector = function () { var dragNodeHighlight = _this.state.dragNodeHighlight; var _this$props10 = _this.props, title = _this$props10.title, selected = _this$props10.selected, icon = _this$props10.icon, loading = _this$props10.loading, data = _this$props10.data, context = _this$props10.context; var prefixCls = context.prefixCls, showIcon = context.showIcon, treeIcon = context.icon, draggable = context.draggable, loadData = context.loadData, titleRender = context.titleRender; var disabled = _this.isDisabled(); var mergedDraggable = _this.getMergedDraggable(draggable, data); var wrapClass = "".concat(prefixCls, "-node-content-wrapper"); // Icon - Still show loading icon when loading without showIcon var $icon; if (showIcon) { var currentIcon = icon || treeIcon; $icon = currentIcon ? /*#__PURE__*/React.createElement("span", { className: classNames("".concat(prefixCls, "-iconEle"), "".concat(prefixCls, "-icon__customize")) }, typeof currentIcon === 'function' ? currentIcon(_this.props) : currentIcon) : _this.renderIcon(); } else if (loadData && loading) { $icon = _this.renderIcon(); } // Title var titleNode; if (typeof title === 'function') { titleNode = title(data); } else if (titleRender) { titleNode = titleRender(data); } else { titleNode = title; } var $title = /*#__PURE__*/React.createElement("span", { className: "".concat(prefixCls, "-title") }, titleNode); return /*#__PURE__*/React.createElement("span", { ref: _this.setSelectHandle, title: typeof title === 'string' ? title : '', className: classNames("".concat(wrapClass), "".concat(wrapClass, "-").concat(_this.getNodeState() || 'normal'), !disabled && (selected || dragNodeHighlight) && "".concat(prefixCls, "-node-selected"), !disabled && mergedDraggable && 'draggable'), draggable: !disabled && mergedDraggable || undefined, "aria-grabbed": !disabled && mergedDraggable || undefined, onMouseEnter: _this.onMouseEnter, onMouseLeave: _this.onMouseLeave, onContextMenu: _this.onContextMenu, onDragStart: mergedDraggable ? _this.onDragStart : undefined }, $icon, $title); }; _this.renderDropIndicator = function () { var _this$props11 = _this.props, disabled = _this$props11.disabled, eventKey = _this$props11.eventKey, context = _this$props11.context; var draggable = context.draggable, dropLevelOffset = context.dropLevelOffset, dropPosition = context.dropPosition, prefixCls = context.prefixCls, indent = context.indent, dropIndicatorRender = context.dropIndicatorRender, dragOverNodeKey = context.dragOverNodeKey, direction = context.direction; var isDraggable = draggable; if (_typeof(draggable) === 'object') { var _draggable$nodeDragga2 = draggable.nodeDraggable, nodeDraggable = _draggable$nodeDragga2 === void 0 ? false : _draggable$nodeDragga2; isDraggable = nodeDraggable; } var mergedDraggable = isDraggable !== false; // allowDrop is calculated in Tree.tsx, there is no need for calc it here var showIndicator = !disabled && mergedDraggable && dragOverNodeKey === eventKey; return showIndicator && dropIndicatorRender ? dropIndicatorRender({ dropPosition: dropPosition, dropLevelOffset: dropLevelOffset, indent: indent, prefixCls: prefixCls, direction: direction }) : null; }; return _this; } // Isomorphic needn't load data in server side _createClass(InternalTreeNode, [{ key: "componentDidMount", value: function componentDidMount() { this.syncLoadData(this.props); } }, { key: "componentDidUpdate", value: function componentDidUpdate() { this.syncLoadData(this.props); } }, { key: "isSelectable", value: function isSelectable() { var _this$props12 = this.props, selectable = _this$props12.selectable, context = _this$props12.context; var treeSelectable = context.selectable; // Ignore when selectable is undefined or null if (typeof selectable === 'boolean') { return selectable; } return treeSelectable; } }, { key: "render", value: function render() { var _classNames; var _this$props13 = this.props, eventKey = _this$props13.eventKey, className = _this$props13.className, style = _this$props13.style, dragOver = _this$props13.dragOver, dragOverGapTop = _this$props13.dragOverGapTop, dragOverGapBottom = _this$props13.dragOverGapBottom, isLeaf = _this$props13.isLeaf, _this$props13$isStart = _this$props13.isStart, isStart = _this$props13$isStart === void 0 ? [] : _this$props13$isStart, _this$props13$isEnd = _this$props13.isEnd, isEnd = _this$props13$isEnd === void 0 ? [] : _this$props13$isEnd, expanded = _this$props13.expanded, selected = _this$props13.selected, checked = _this$props13.checked, halfChecked = _this$props13.halfChecked, loading = _this$props13.loading, domRef = _this$props13.domRef, active = _this$props13.active, data = _this$props13.data, onMouseMove = _this$props13.onMouseMove, context = _this$props13.context, otherProps = _objectWithoutProperties(_this$props13, _excluded); var prefixCls = context.prefixCls, filterTreeNode = context.filterTreeNode, draggable = context.draggable, keyEntities = context.keyEntities, dropContainerKey = context.dropContainerKey, dropTargetKey = context.dropTargetKey, ripple = context.ripple; var disabled = this.isDisabled(); var dataOrAriaAttributeProps = getDataAndAria(otherProps); var _ref2 = keyEntities[eventKey] || {}, level = _ref2.level; var isEndNode = isEnd[isEnd.length - 1]; var mergedDraggable = this.getMergedDraggable(draggable, data); return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Ripple, { disabled: disabled || !ripple }, /*#__PURE__*/React.createElement("div", _extends({ ref: domRef, className: classNames(className, "".concat(prefixCls, "-treenode"), (_classNames = {}, _defineProperty(_classNames, "".concat(prefixCls, "-treenode-disabled"), disabled), _defineProperty(_classNames, "".concat(prefixCls, "-treenode-switcher-").concat(expanded ? 'open' : 'close'), !isLeaf), _defineProperty(_classNames, "".concat(prefixCls, "-treenode-checkbox-checked"), checked), _defineProperty(_classNames, "".concat(prefixCls, "-treenode-checkbox-indeterminate"), halfChecked), _defineProperty(_classNames, "".concat(prefixCls, "-treenode-selected"), selected), _defineProperty(_classNames, "".concat(prefixCls, "-treenode-loading"), loading), _defineProperty(_classNames, "".concat(prefixCls, "-treenode-active"), active), _defineProperty(_classNames, "".concat(prefixCls, "-treenode-leaf-last"), isEndNode), _defineProperty(_classNames, 'drop-target', dropTargetKey === eventKey), _defineProperty(_classNames, 'drop-container', dropContainerKey === eventKey), _defineProperty(_classNames, 'drag-over', !disabled && dragOver), _defineProperty(_classNames, 'drag-over-gap-top', !disabled && dragOverGapTop), _defineProperty(_classNames, 'drag-over-gap-bottom', !disabled && dragOverGapBottom), _defineProperty(_classNames, 'filter-node', filterTreeNode && filterTreeNode(convertNodePropsToEventData(this.props))), _classNames)), style: style, onClick: this.onSelectorClick, onDoubleClick: this.onSelectorDoubleClick, onDragEnter: mergedDraggable ? this.onDragEnter : undefined, onDragOver: mergedDraggable ? this.onDragOver : undefined, onDragLeave: mergedDraggable ? this.onDragLeave : undefined, onDrop: mergedDraggable ? this.onDrop : undefined, onDragEnd: mergedDraggable ? this.onDragEnd : undefined, onMouseMove: onMouseMove }, dataOrAriaAttributeProps), /*#__PURE__*/React.createElement(Indent, { prefixCls: prefixCls, level: level, isStart: isStart, isEnd: isEnd }), this.renderDraggableIcon(), this.renderSwitcher(), this.renderCheckbox(), this.renderSelector())), this.renderDropIndicator()); } }]); return InternalTreeNode; }(React.Component); var ContextTreeNode = function ContextTreeNode(props) { return /*#__PURE__*/React.createElement(TreeContext.Consumer, null, function (context) { return /*#__PURE__*/React.createElement(InternalTreeNode, _extends({}, props, { context: context })); }); }; ContextTreeNode.displayName = 'TreeNode'; ContextTreeNode.defaultProps = { // eslint-disable-next-line react/default-props-match-prop-types title: defaultTitle }; ContextTreeNode.isTreeNode = 1; export { InternalTreeNode }; export default ContextTreeNode; //# sourceMappingURL=TreeNode.js.map