DirectoryTree.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. "use client";
  2. import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
  3. var __rest = this && this.__rest || function (s, e) {
  4. var t = {};
  5. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
  6. if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
  7. if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
  8. }
  9. return t;
  10. };
  11. import * as React from 'react';
  12. import FileOutlined from "@ant-design/icons/es/icons/FileOutlined";
  13. import FolderOpenOutlined from "@ant-design/icons/es/icons/FolderOpenOutlined";
  14. import FolderOutlined from "@ant-design/icons/es/icons/FolderOutlined";
  15. import classNames from 'classnames';
  16. import { conductExpandParent } from "rc-tree/es/util";
  17. import { convertDataToEntities, convertTreeToData } from "rc-tree/es/utils/treeUtil";
  18. import { ConfigContext } from '../config-provider';
  19. import Tree from './Tree';
  20. import { calcRangeKeys, convertDirectoryKeysToNodes } from './utils/dictUtil';
  21. function getIcon(props) {
  22. const {
  23. isLeaf,
  24. expanded
  25. } = props;
  26. if (isLeaf) {
  27. return /*#__PURE__*/React.createElement(FileOutlined, null);
  28. }
  29. return expanded ? /*#__PURE__*/React.createElement(FolderOpenOutlined, null) : /*#__PURE__*/React.createElement(FolderOutlined, null);
  30. }
  31. function getTreeData({
  32. treeData,
  33. children
  34. }) {
  35. return treeData || convertTreeToData(children);
  36. }
  37. const DirectoryTree = (_a, ref) => {
  38. var {
  39. defaultExpandAll,
  40. defaultExpandParent,
  41. defaultExpandedKeys
  42. } = _a,
  43. props = __rest(_a, ["defaultExpandAll", "defaultExpandParent", "defaultExpandedKeys"]);
  44. // Shift click usage
  45. const lastSelectedKey = React.useRef(null);
  46. const cachedSelectedKeys = React.useRef(null);
  47. const getInitExpandedKeys = () => {
  48. const {
  49. keyEntities
  50. } = convertDataToEntities(getTreeData(props));
  51. let initExpandedKeys;
  52. // Expanded keys
  53. if (defaultExpandAll) {
  54. initExpandedKeys = Object.keys(keyEntities);
  55. } else if (defaultExpandParent) {
  56. initExpandedKeys = conductExpandParent(props.expandedKeys || defaultExpandedKeys || [], keyEntities);
  57. } else {
  58. initExpandedKeys = props.expandedKeys || defaultExpandedKeys || [];
  59. }
  60. return initExpandedKeys;
  61. };
  62. const [selectedKeys, setSelectedKeys] = React.useState(props.selectedKeys || props.defaultSelectedKeys || []);
  63. const [expandedKeys, setExpandedKeys] = React.useState(() => getInitExpandedKeys());
  64. React.useEffect(() => {
  65. if ('selectedKeys' in props) {
  66. setSelectedKeys(props.selectedKeys);
  67. }
  68. }, [props.selectedKeys]);
  69. React.useEffect(() => {
  70. if ('expandedKeys' in props) {
  71. setExpandedKeys(props.expandedKeys);
  72. }
  73. }, [props.expandedKeys]);
  74. const onExpand = (keys, info) => {
  75. var _a;
  76. if (!('expandedKeys' in props)) {
  77. setExpandedKeys(keys);
  78. }
  79. // Call origin function
  80. return (_a = props.onExpand) === null || _a === void 0 ? void 0 : _a.call(props, keys, info);
  81. };
  82. const onSelect = (keys, event) => {
  83. var _a;
  84. const {
  85. multiple,
  86. fieldNames
  87. } = props;
  88. const {
  89. node,
  90. nativeEvent
  91. } = event;
  92. const {
  93. key = ''
  94. } = node;
  95. const treeData = getTreeData(props);
  96. // const newState: DirectoryTreeState = {};
  97. // We need wrap this event since some value is not same
  98. const newEvent = Object.assign(Object.assign({}, event), {
  99. selected: true
  100. });
  101. // Windows / Mac single pick
  102. const ctrlPick = (nativeEvent === null || nativeEvent === void 0 ? void 0 : nativeEvent.ctrlKey) || (nativeEvent === null || nativeEvent === void 0 ? void 0 : nativeEvent.metaKey);
  103. const shiftPick = nativeEvent === null || nativeEvent === void 0 ? void 0 : nativeEvent.shiftKey;
  104. // Generate new selected keys
  105. let newSelectedKeys;
  106. if (multiple && ctrlPick) {
  107. // Control click
  108. newSelectedKeys = keys;
  109. lastSelectedKey.current = key;
  110. cachedSelectedKeys.current = newSelectedKeys;
  111. newEvent.selectedNodes = convertDirectoryKeysToNodes(treeData, newSelectedKeys, fieldNames);
  112. } else if (multiple && shiftPick) {
  113. // Shift click
  114. newSelectedKeys = Array.from(new Set([].concat(_toConsumableArray(cachedSelectedKeys.current || []), _toConsumableArray(calcRangeKeys({
  115. treeData,
  116. expandedKeys,
  117. startKey: key,
  118. endKey: lastSelectedKey.current,
  119. fieldNames
  120. })))));
  121. newEvent.selectedNodes = convertDirectoryKeysToNodes(treeData, newSelectedKeys, fieldNames);
  122. } else {
  123. // Single click
  124. newSelectedKeys = [key];
  125. lastSelectedKey.current = key;
  126. cachedSelectedKeys.current = newSelectedKeys;
  127. newEvent.selectedNodes = convertDirectoryKeysToNodes(treeData, newSelectedKeys, fieldNames);
  128. }
  129. (_a = props.onSelect) === null || _a === void 0 ? void 0 : _a.call(props, newSelectedKeys, newEvent);
  130. if (!('selectedKeys' in props)) {
  131. setSelectedKeys(newSelectedKeys);
  132. }
  133. };
  134. const {
  135. getPrefixCls,
  136. direction
  137. } = React.useContext(ConfigContext);
  138. const {
  139. prefixCls: customizePrefixCls,
  140. className,
  141. showIcon = true,
  142. expandAction = 'click'
  143. } = props,
  144. otherProps = __rest(props, ["prefixCls", "className", "showIcon", "expandAction"]);
  145. const prefixCls = getPrefixCls('tree', customizePrefixCls);
  146. const connectClassName = classNames(`${prefixCls}-directory`, {
  147. [`${prefixCls}-directory-rtl`]: direction === 'rtl'
  148. }, className);
  149. return /*#__PURE__*/React.createElement(Tree, Object.assign({
  150. icon: getIcon,
  151. ref: ref,
  152. blockNode: true
  153. }, otherProps, {
  154. showIcon: showIcon,
  155. expandAction: expandAction,
  156. prefixCls: prefixCls,
  157. className: connectClassName,
  158. expandedKeys: expandedKeys,
  159. selectedKeys: selectedKeys,
  160. onSelect: onSelect,
  161. onExpand: onExpand
  162. }));
  163. };
  164. const ForwardDirectoryTree = /*#__PURE__*/React.forwardRef(DirectoryTree);
  165. if (process.env.NODE_ENV !== 'production') {
  166. ForwardDirectoryTree.displayName = 'DirectoryTree';
  167. }
  168. export default ForwardDirectoryTree;