acud
Version:
acg react 组件库
416 lines • 15.7 kB
JavaScript
import _extends from "@babel/runtime/helpers/esm/extends";
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import React, { useCallback, useMemo, useState, useEffect } from 'react';
import classNames from 'classnames';
import update from 'immutability-helper';
import OutlinedDrag from "acud-icon/es/icons/OutlinedDrag";
import OutlinedEdit from "acud-icon/es/icons/OutlinedEdit";
import OutlinedDelete from "acud-icon/es/icons/OutlinedDelete";
import OutlinedPlus from "acud-icon/es/icons/OutlinedPlus";
import RcTree, { TreeNode } from 'rc-tree';
import Input from '../input';
import Popover from '../popover';
import { getParentKey, editNode, saveNode, deleteNode, changeNode, addNode } from './utils/nodeHelper';
import { renderSwitcherIcon } from './utils/iconHelper';
import { dropIndicatorRender } from './utils/dragHelper';
import { ConfigContext } from '../config-provider';
import PopoverComponent from './PopoverComponent';
var DataChangeType;
(function (DataChangeType) {
DataChangeType["SAVE"] = "save";
DataChangeType["EDITINPUTCHANGE"] = "editInputChange";
DataChangeType["DELETE"] = "delete";
DataChangeType["ADD"] = "add";
DataChangeType["DROP"] = "drop";
})(DataChangeType || (DataChangeType = {}));
var UtilType;
(function (UtilType) {
UtilType["Add"] = "Add";
UtilType["Edit"] = "Edit";
UtilType["Delete"] = "Delete";
})(UtilType || (UtilType = {}));
;
var generateList = function generateList(data) {
var dataList = [];
var _helper = function helper(data) {
for (var i = 0; i < data.length; i++) {
var node = data[i];
var key = node.key;
dataList.push({
key: key,
title: key
});
if (node.children) {
_helper(node.children);
}
}
};
_helper(data);
return dataList;
};
var handleClickAndDbClick = function handleClickAndDbClick(clickFunc, dbClickFunc, time) {
var count = 0;
return function () {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
count++;
setTimeout(function () {
if (count === 1) {
clickFunc.apply(void 0, args);
} else if (count === 2) {
dbClickFunc.apply(void 0, args);
}
;
count = 0;
}, time);
};
};
var isSearchTitle = function isSearchTitle(title) {
return typeof title === 'string' || typeof title === 'number';
};
var isUtilType = function isUtilType(val) {
return typeof val === 'string' && val in UtilType;
};
var DEFAULT_POPOVER_UTIL = [{
text: '新建节点',
onClick: UtilType.Add
}, {
text: '编辑节点',
onClick: UtilType.Edit
}, {
text: '删除节点',
onClick: UtilType.Delete
}];
var Tree = /*#__PURE__*/React.forwardRef(function (props, ref) {
var _props$selectable = props.selectable,
selectable = _props$selectable === void 0 ? true : _props$selectable,
searchable = props.searchable,
searchPlaceholder = props.searchPlaceholder,
_props$checkable = props.checkable,
checkable = _props$checkable === void 0 ? false : _props$checkable,
editable = props.editable,
editInputProps = props.editInputProps,
draggable = props.draggable,
showIconUtil = props.showIconUtil,
showPopoverUtil = props.showPopoverUtil,
_props$customPopoverU = props.customPopoverUtil,
customPopoverUtil = _props$customPopoverU === void 0 ? DEFAULT_POPOVER_UTIL : _props$customPopoverU,
customizePrefixCls = props.prefixCls,
className = props.className,
showLine = props.showLine,
_switcherIcon = props.switcherIcon,
onDataChange = props.onDataChange,
treeDataOrigin = props.treeData,
defaultExpandedKeys = props.defaultExpandedKeys,
expandedKeysInProps = props.expandedKeys,
titleEllipsis = props.titleEllipsis,
popoverZIndex = props.popoverZIndex;
var _useState = useState(expandedKeysInProps || defaultExpandedKeys || []),
_useState2 = _slicedToArray(_useState, 2),
expandedKeys = _useState2[0],
setExpandedKeys = _useState2[1];
var _useState3 = useState(true),
_useState4 = _slicedToArray(_useState3, 2),
autoExpandParent = _useState4[0],
setAutoExpandParent = _useState4[1];
var _useState5 = useState([]),
_useState6 = _slicedToArray(_useState5, 2),
treeData = _useState6[0],
setTreeData = _useState6[1];
var _useState7 = useState(),
_useState8 = _slicedToArray(_useState7, 2),
searchText = _useState8[0],
setSearchText = _useState8[1];
var _useState9 = useState(false),
_useState0 = _slicedToArray(_useState9, 2),
searchFound = _useState0[0],
setSearchFound = _useState0[1];
var treeRef = /*#__PURE__*/React.createRef();
React.useImperativeHandle(ref, function () {
return treeRef.current;
});
var dataList = useMemo(function () {
return generateList(treeData);
}, [treeData]);
var draggableConfig = useMemo(function () {
if (!draggable) {
return false;
}
return {
icon: /*#__PURE__*/React.createElement(OutlinedDrag, null)
};
}, [draggable]);
var onExpand = function onExpand(expandedKeysValue, info) {
var _a;
setExpandedKeys(expandedKeysValue);
setAutoExpandParent(false);
return (_a = props.onExpand) === null || _a === void 0 ? void 0 : _a.call(props, expandedKeysValue, info);
};
var onClick = function onClick(event, node) {
var _a;
if (node.children && !selectable) {
treeRef.current.onNodeExpand(event, node);
}
(_a = props.onClick) === null || _a === void 0 ? void 0 : _a.call(props, event, node);
};
var onSearchInputChange = function onSearchInputChange(event) {
var value = event.target.value;
var found = false;
var expandedKeys = dataList.map(function (item) {
if (isSearchTitle(item.title) && item.title.indexOf(value) > -1) {
found = true;
return getParentKey(item.key, treeData);
}
return null;
}).filter(function (item, i, self) {
return item && self.indexOf(item) === i;
});
setExpandedKeys(expandedKeys);
setSearchText(value);
setAutoExpandParent(true);
setSearchFound(found);
};
var onEditInputChange = useCallback(function (e, node) {
setTreeData(function (treeData) {
var newTreeData = changeNode(node, {
title: e.target.value
}, treeData);
onDataChange === null || onDataChange === void 0 ? void 0 : onDataChange(newTreeData, node, DataChangeType.EDITINPUTCHANGE);
return newTreeData;
});
}, [onDataChange]);
var onQuickEdit = function onQuickEdit(_, node) {
if (editable) {
setTreeData(editNode(node, treeData));
}
};
var onSave = useCallback(function (node) {
setTreeData(function (treeData) {
var newTreeData = saveNode(node, treeData);
onDataChange === null || onDataChange === void 0 ? void 0 : onDataChange(newTreeData, node, DataChangeType.SAVE);
return newTreeData;
});
}, [onDataChange]);
var onDelete = useCallback(function (node) {
setTreeData(function (treeData) {
var newTreeData = deleteNode(node, treeData).filter(function (item) {
return item !== null;
});
onDataChange === null || onDataChange === void 0 ? void 0 : onDataChange(newTreeData, node, DataChangeType.DELETE);
return newTreeData;
});
}, [onDataChange]);
var onAdd = useCallback(function (node) {
setTreeData(function (treeData) {
var newTreeData = addNode(node, treeData);
onDataChange === null || onDataChange === void 0 ? void 0 : onDataChange(newTreeData, node, DataChangeType.ADD);
return newTreeData;
});
setExpandedKeys(function (expandedKeys) {
return _toConsumableArray(new Set([].concat(_toConsumableArray(expandedKeys), [node.key])));
});
}, [onDataChange]);
var onDrop = function onDrop(info) {
var _a, _b;
var dropKey = info.node.key;
var dragKey = info.dragNode.key;
var dropPos = info.node.pos.split('-');
var dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]);
var _loop = function loop(data, key, callback) {
for (var i = 0; i < data.length; i++) {
if (data[i].key === key) {
return callback(data[i], i, data);
}
var children = data[i].children;
if (children) {
_loop(children, key, callback);
}
}
};
var data = _toConsumableArray(treeData);
// Find dragObject
var dragObj = data[0];
_loop(data, dragKey, function (item, index, arr) {
arr.splice(index, 1);
dragObj = item;
});
if (dropPosition === 0) {
// Drop on the content
_loop(data, dropKey, function (item) {
item.children = item.children || [];
item.children.unshift(dragObj);
});
} else {
var ar = data;
var i = 0;
_loop(data, dropKey, function (_, index, arr) {
ar = arr;
i = index;
});
if (dropPosition === -1) {
ar.splice(i, 0, dragObj);
} else {
ar.splice(i + 1, 0, dragObj);
}
}
setTreeData(data);
(_a = props.onDataChange) === null || _a === void 0 ? void 0 : _a.call(props, data, info.node, DataChangeType.DROP);
(_b = props.onDrop) === null || _b === void 0 ? void 0 : _b.call(props, info);
};
var handleClick = handleClickAndDbClick(onClick, onQuickEdit, 200);
var _React$useContext = React.useContext(ConfigContext),
getPrefixCls = _React$useContext.getPrefixCls;
var prefixCls = getPrefixCls('tree', customizePrefixCls);
var formatTreeData = useCallback(function (data) {
if (Array.isArray(data)) {
var res = [];
for (var i = 0; i < data.length; i++) {
res[i] = formatTreeData(data[i]);
}
return res;
}
var newItem;
var renderTitle;
if (data.isEditable && isSearchTitle(data.title)) {
renderTitle = /*#__PURE__*/React.createElement("div", {
className: "".concat(prefixCls, "-edit-input")
}, /*#__PURE__*/React.createElement(Input, _extends({}, editInputProps, {
value: data.title,
onChange: function onChange(e) {
return onEditInputChange(e, data);
},
onBlur: function onBlur() {
return onSave(data);
},
size: 'small',
autoFocus: true
})));
} else {
var title = data.title;
if (isSearchTitle(title) && searchText) {
var index = title.indexOf(searchText);
var beforeStr = title.substr(0, index);
var afterStr = title.substr(index + searchText.length);
title = index > -1 ? /*#__PURE__*/React.createElement("span", null, beforeStr, /*#__PURE__*/React.createElement("span", {
className: "".concat(prefixCls, "-node-highlighttext")
}, searchText), afterStr) : /*#__PURE__*/React.createElement("span", null, title);
}
var handleAdd = function handleAdd() {
return onAdd(data);
};
var handleEdit = function handleEdit() {
setTreeData(function (treeData) {
return editNode(data, treeData);
});
};
var handleDelete = function handleDelete() {
return onDelete(data);
};
var onClickMap = {
Add: handleAdd,
Edit: handleEdit,
Delete: handleDelete
};
var customPopoverUtilArray = Array.isArray(customPopoverUtil) ? customPopoverUtil : customPopoverUtil(data);
var popoverContent = customPopoverUtilArray.map(function (item) {
var liProps = _extends(_extends({
key: item.key || item.text
}, !item.disabled && {
onClick: isUtilType(item.onClick) ? onClickMap[item.onClick] : function () {
return item.onClick(data, treeData);
}
}), item.disabled && {
className: "".concat(prefixCls, "-popover-util-li-disabled")
});
return /*#__PURE__*/React.createElement("li", liProps, item.text);
});
var titleContent = /*#__PURE__*/React.createElement("span", {
className: "".concat(prefixCls, "-title-titleContent")
}, title);
renderTitle = /*#__PURE__*/React.createElement("span", {
className: "".concat(prefixCls, "-title-titleWithOps")
}, titleEllipsis ? /*#__PURE__*/React.createElement(Popover, {
zIndex: popoverZIndex === undefined ? 1051 : popoverZIndex,
content: title
}, titleContent) : titleContent, showIconUtil && editable && /*#__PURE__*/React.createElement("span", {
className: "".concat(prefixCls, "-icon-util")
}, /*#__PURE__*/React.createElement(OutlinedPlus, {
onClick: handleAdd
}), /*#__PURE__*/React.createElement(OutlinedEdit, {
onClick: handleEdit
}), /*#__PURE__*/React.createElement(OutlinedDelete, {
onClick: handleDelete
})), (showPopoverUtil && editable || customPopoverUtil !== DEFAULT_POPOVER_UTIL) && /*#__PURE__*/React.createElement("span", {
className: "".concat(prefixCls, "-icon-util")
}, /*#__PURE__*/React.createElement(PopoverComponent, {
prefixCls: prefixCls,
popoverZIndex: popoverZIndex,
popoverContent: popoverContent
})));
}
newItem = update(data, {
$merge: {
title: renderTitle
}
});
if (data.children) {
newItem = update(newItem, {
$merge: {
children: formatTreeData(data.children)
}
});
}
return newItem;
}, [editable, onDelete, onSave, onAdd, onEditInputChange, showIconUtil, showPopoverUtil, searchText, prefixCls, customPopoverUtil, titleEllipsis, popoverZIndex]);
var formatedTreeData = useMemo(function () {
return formatTreeData(treeData);
}, [treeData, formatTreeData]);
var classes = classNames(prefixCls, className, titleEllipsis ? "".concat(prefixCls, "-with-title-ellipsis") : '');
// 兼容不传treeData数据直接传treeNode子组件的场景
var newProps = _extends({}, props);
if (treeDataOrigin) {
newProps.treeData = formatedTreeData;
}
// expandedKeys和defaultExpandAll冲突需动态赋值
if (props && props.defaultExpandAll) {
if (expandedKeys.length) {
newProps.expandedKeys = expandedKeys;
}
} else {
newProps.expandedKeys = expandedKeys;
}
useEffect(function () {
if (Array.isArray(treeDataOrigin)) {
setTreeData(treeDataOrigin);
}
}, [treeDataOrigin]);
useEffect(function () {
Array.isArray(expandedKeysInProps) && setExpandedKeys(expandedKeysInProps);
}, [expandedKeysInProps]);
return /*#__PURE__*/React.createElement(React.Fragment, null, searchable && /*#__PURE__*/React.createElement(Input, {
placeholder: searchPlaceholder,
className: "".concat(prefixCls, "-search-input"),
onChange: onSearchInputChange
}), searchText && !searchFound ? "\u672A\u627E\u5230\u4E0E".concat(searchText, "\u76F8\u5173\u7684\u7ED3\u679C") : (!treeDataOrigin || !!formatedTreeData.length) && /*#__PURE__*/React.createElement(RcTree, _extends({
ref: treeRef
}, newProps, {
className: classes,
prefixCls: prefixCls,
onClick: handleClick,
onExpand: onExpand,
onDrop: onDrop,
checkable: checkable ? /*#__PURE__*/React.createElement("span", {
className: "".concat(prefixCls, "-checkbox-inner")
}) : checkable,
autoExpandParent: autoExpandParent,
switcherIcon: function switcherIcon(nodeProps) {
return renderSwitcherIcon(prefixCls, _switcherIcon, showLine, nodeProps);
},
dropIndicatorRender: dropIndicatorRender,
draggable: draggableConfig
})));
});
Tree.TreeNode = TreeNode;
export default Tree;