Tree.js 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124
  1. "use strict";
  2. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  3. Object.defineProperty(exports, "__esModule", {
  4. value: true
  5. });
  6. exports.default = void 0;
  7. var _vue = require("vue");
  8. var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
  9. var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
  10. var _contextTypes = require("./contextTypes");
  11. var _util = require("./util");
  12. var _treeUtil = require("./utils/treeUtil");
  13. var _NodeList = _interopRequireWildcard(require("./NodeList"));
  14. var _conductUtil = require("./utils/conductUtil");
  15. var _DropIndicator = _interopRequireDefault(require("./DropIndicator"));
  16. var _initDefaultProps = _interopRequireDefault(require("../_util/props-util/initDefaultProps"));
  17. var _props = require("./props");
  18. var _warning = require("../vc-util/warning");
  19. var _KeyCode = _interopRequireDefault(require("../_util/KeyCode"));
  20. var _classNames = _interopRequireDefault(require("../_util/classNames"));
  21. var _pickAttrs = _interopRequireDefault(require("../_util/pickAttrs"));
  22. var _useMaxLevel = _interopRequireDefault(require("./useMaxLevel"));
  23. function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
  24. function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
  25. const MAX_RETRY_TIMES = 10;
  26. var _default = exports.default = (0, _vue.defineComponent)({
  27. compatConfig: {
  28. MODE: 3
  29. },
  30. name: 'Tree',
  31. inheritAttrs: false,
  32. props: (0, _initDefaultProps.default)((0, _props.treeProps)(), {
  33. prefixCls: 'vc-tree',
  34. showLine: false,
  35. showIcon: true,
  36. selectable: true,
  37. multiple: false,
  38. checkable: false,
  39. disabled: false,
  40. checkStrictly: false,
  41. draggable: false,
  42. expandAction: false,
  43. defaultExpandParent: true,
  44. autoExpandParent: false,
  45. defaultExpandAll: false,
  46. defaultExpandedKeys: [],
  47. defaultCheckedKeys: [],
  48. defaultSelectedKeys: [],
  49. dropIndicatorRender: _DropIndicator.default,
  50. allowDrop: () => true
  51. }),
  52. setup(props, _ref) {
  53. let {
  54. attrs,
  55. slots,
  56. expose
  57. } = _ref;
  58. const destroyed = (0, _vue.shallowRef)(false);
  59. let delayedDragEnterLogic = {};
  60. const indent = (0, _vue.shallowRef)();
  61. const selectedKeys = (0, _vue.shallowRef)([]);
  62. const checkedKeys = (0, _vue.shallowRef)([]);
  63. const halfCheckedKeys = (0, _vue.shallowRef)([]);
  64. const loadedKeys = (0, _vue.shallowRef)([]);
  65. const loadingKeys = (0, _vue.shallowRef)([]);
  66. const expandedKeys = (0, _vue.shallowRef)([]);
  67. const loadingRetryTimes = {};
  68. const dragState = (0, _vue.reactive)({
  69. draggingNodeKey: null,
  70. dragChildrenKeys: [],
  71. // dropTargetKey is the key of abstract-drop-node
  72. // the abstract-drop-node is the real drop node when drag and drop
  73. // not the DOM drag over node
  74. dropTargetKey: null,
  75. dropPosition: null,
  76. dropContainerKey: null,
  77. dropLevelOffset: null,
  78. dropTargetPos: null,
  79. dropAllowed: true,
  80. // the abstract-drag-over-node
  81. // if mouse is on the bottom of top dom node or no the top of the bottom dom node
  82. // abstract-drag-over-node is the top node
  83. dragOverNodeKey: null
  84. });
  85. const treeData = (0, _vue.shallowRef)([]);
  86. (0, _vue.watch)([() => props.treeData, () => props.children], () => {
  87. treeData.value = props.treeData !== undefined ? props.treeData.slice() : (0, _treeUtil.convertTreeToData)((0, _vue.toRaw)(props.children));
  88. }, {
  89. immediate: true,
  90. deep: true
  91. });
  92. const keyEntities = (0, _vue.shallowRef)({});
  93. const focused = (0, _vue.shallowRef)(false);
  94. const activeKey = (0, _vue.shallowRef)(null);
  95. const listChanging = (0, _vue.shallowRef)(false);
  96. const fieldNames = (0, _vue.computed)(() => (0, _treeUtil.fillFieldNames)(props.fieldNames));
  97. const listRef = (0, _vue.shallowRef)();
  98. let dragStartMousePosition = null;
  99. let dragNode = null;
  100. let currentMouseOverDroppableNodeKey = null;
  101. const treeNodeRequiredProps = (0, _vue.computed)(() => {
  102. return {
  103. expandedKeysSet: expandedKeysSet.value,
  104. selectedKeysSet: selectedKeysSet.value,
  105. loadedKeysSet: loadedKeysSet.value,
  106. loadingKeysSet: loadingKeysSet.value,
  107. checkedKeysSet: checkedKeysSet.value,
  108. halfCheckedKeysSet: halfCheckedKeysSet.value,
  109. dragOverNodeKey: dragState.dragOverNodeKey,
  110. dropPosition: dragState.dropPosition,
  111. keyEntities: keyEntities.value
  112. };
  113. });
  114. const expandedKeysSet = (0, _vue.computed)(() => {
  115. return new Set(expandedKeys.value);
  116. });
  117. const selectedKeysSet = (0, _vue.computed)(() => {
  118. return new Set(selectedKeys.value);
  119. });
  120. const loadedKeysSet = (0, _vue.computed)(() => {
  121. return new Set(loadedKeys.value);
  122. });
  123. const loadingKeysSet = (0, _vue.computed)(() => {
  124. return new Set(loadingKeys.value);
  125. });
  126. const checkedKeysSet = (0, _vue.computed)(() => {
  127. return new Set(checkedKeys.value);
  128. });
  129. const halfCheckedKeysSet = (0, _vue.computed)(() => {
  130. return new Set(halfCheckedKeys.value);
  131. });
  132. (0, _vue.watchEffect)(() => {
  133. if (treeData.value) {
  134. const entitiesMap = (0, _treeUtil.convertDataToEntities)(treeData.value, {
  135. fieldNames: fieldNames.value
  136. });
  137. keyEntities.value = (0, _extends2.default)({
  138. [_NodeList.MOTION_KEY]: _NodeList.MotionEntity
  139. }, entitiesMap.keyEntities);
  140. }
  141. });
  142. let init = false; // 处理 defaultXxxx api, 仅仅首次有效
  143. (0, _vue.watch)([() => props.expandedKeys, () => props.autoExpandParent, keyEntities],
  144. // eslint-disable-next-line @typescript-eslint/no-unused-vars
  145. (_ref2, _ref3) => {
  146. let [_newKeys, newAutoExpandParent] = _ref2;
  147. let [_oldKeys, oldAutoExpandParent] = _ref3;
  148. let keys = expandedKeys.value;
  149. // ================ expandedKeys =================
  150. if (props.expandedKeys !== undefined || init && newAutoExpandParent !== oldAutoExpandParent) {
  151. keys = props.autoExpandParent || !init && props.defaultExpandParent ? (0, _util.conductExpandParent)(props.expandedKeys, keyEntities.value) : props.expandedKeys;
  152. } else if (!init && props.defaultExpandAll) {
  153. const cloneKeyEntities = (0, _extends2.default)({}, keyEntities.value);
  154. delete cloneKeyEntities[_NodeList.MOTION_KEY];
  155. keys = Object.keys(cloneKeyEntities).map(key => cloneKeyEntities[key].key);
  156. } else if (!init && props.defaultExpandedKeys) {
  157. keys = props.autoExpandParent || props.defaultExpandParent ? (0, _util.conductExpandParent)(props.defaultExpandedKeys, keyEntities.value) : props.defaultExpandedKeys;
  158. }
  159. if (keys) {
  160. expandedKeys.value = keys;
  161. }
  162. init = true;
  163. }, {
  164. immediate: true
  165. });
  166. // ================ flattenNodes =================
  167. const flattenNodes = (0, _vue.shallowRef)([]);
  168. (0, _vue.watchEffect)(() => {
  169. flattenNodes.value = (0, _treeUtil.flattenTreeData)(treeData.value, expandedKeys.value, fieldNames.value);
  170. });
  171. // ================ selectedKeys =================
  172. (0, _vue.watchEffect)(() => {
  173. if (props.selectable) {
  174. if (props.selectedKeys !== undefined) {
  175. selectedKeys.value = (0, _util.calcSelectedKeys)(props.selectedKeys, props);
  176. } else if (!init && props.defaultSelectedKeys) {
  177. selectedKeys.value = (0, _util.calcSelectedKeys)(props.defaultSelectedKeys, props);
  178. }
  179. }
  180. });
  181. const {
  182. maxLevel,
  183. levelEntities
  184. } = (0, _useMaxLevel.default)(keyEntities);
  185. // ================= checkedKeys =================
  186. (0, _vue.watchEffect)(() => {
  187. if (props.checkable) {
  188. let checkedKeyEntity;
  189. if (props.checkedKeys !== undefined) {
  190. checkedKeyEntity = (0, _util.parseCheckedKeys)(props.checkedKeys) || {};
  191. } else if (!init && props.defaultCheckedKeys) {
  192. checkedKeyEntity = (0, _util.parseCheckedKeys)(props.defaultCheckedKeys) || {};
  193. } else if (treeData.value) {
  194. // If `treeData` changed, we also need check it
  195. checkedKeyEntity = (0, _util.parseCheckedKeys)(props.checkedKeys) || {
  196. checkedKeys: checkedKeys.value,
  197. halfCheckedKeys: halfCheckedKeys.value
  198. };
  199. }
  200. if (checkedKeyEntity) {
  201. let {
  202. checkedKeys: newCheckedKeys = [],
  203. halfCheckedKeys: newHalfCheckedKeys = []
  204. } = checkedKeyEntity;
  205. if (!props.checkStrictly) {
  206. const conductKeys = (0, _conductUtil.conductCheck)(newCheckedKeys, true, keyEntities.value, maxLevel.value, levelEntities.value);
  207. ({
  208. checkedKeys: newCheckedKeys,
  209. halfCheckedKeys: newHalfCheckedKeys
  210. } = conductKeys);
  211. }
  212. checkedKeys.value = newCheckedKeys;
  213. halfCheckedKeys.value = newHalfCheckedKeys;
  214. }
  215. }
  216. });
  217. // ================= loadedKeys ==================
  218. (0, _vue.watchEffect)(() => {
  219. if (props.loadedKeys) {
  220. loadedKeys.value = props.loadedKeys;
  221. }
  222. });
  223. const resetDragState = () => {
  224. (0, _extends2.default)(dragState, {
  225. dragOverNodeKey: null,
  226. dropPosition: null,
  227. dropLevelOffset: null,
  228. dropTargetKey: null,
  229. dropContainerKey: null,
  230. dropTargetPos: null,
  231. dropAllowed: false
  232. });
  233. };
  234. const scrollTo = scroll => {
  235. listRef.value.scrollTo(scroll);
  236. };
  237. (0, _vue.watch)(() => props.activeKey, () => {
  238. if (props.activeKey !== undefined) {
  239. activeKey.value = props.activeKey;
  240. }
  241. }, {
  242. immediate: true
  243. });
  244. (0, _vue.watch)(activeKey, val => {
  245. (0, _vue.nextTick)(() => {
  246. if (val !== null) {
  247. scrollTo({
  248. key: val
  249. });
  250. }
  251. });
  252. }, {
  253. immediate: true,
  254. flush: 'post'
  255. });
  256. // =========================== Expanded ===========================
  257. /** Set uncontrolled `expandedKeys`. This will also auto update `flattenNodes`. */
  258. const setExpandedKeys = keys => {
  259. if (props.expandedKeys === undefined) {
  260. expandedKeys.value = keys;
  261. }
  262. };
  263. const cleanDragState = () => {
  264. if (dragState.draggingNodeKey !== null) {
  265. (0, _extends2.default)(dragState, {
  266. draggingNodeKey: null,
  267. dropPosition: null,
  268. dropContainerKey: null,
  269. dropTargetKey: null,
  270. dropLevelOffset: null,
  271. dropAllowed: true,
  272. dragOverNodeKey: null
  273. });
  274. }
  275. dragStartMousePosition = null;
  276. currentMouseOverDroppableNodeKey = null;
  277. };
  278. // if onNodeDragEnd is called, onWindowDragEnd won't be called since stopPropagation() is called
  279. const onNodeDragEnd = (event, node) => {
  280. const {
  281. onDragend
  282. } = props;
  283. dragState.dragOverNodeKey = null;
  284. cleanDragState();
  285. onDragend === null || onDragend === void 0 ? void 0 : onDragend({
  286. event,
  287. node: node.eventData
  288. });
  289. dragNode = null;
  290. };
  291. // since stopPropagation() is called in treeNode
  292. // if onWindowDrag is called, whice means state is keeped, drag state should be cleared
  293. const onWindowDragEnd = event => {
  294. onNodeDragEnd(event, null, true);
  295. window.removeEventListener('dragend', onWindowDragEnd);
  296. };
  297. const onNodeDragStart = (event, node) => {
  298. const {
  299. onDragstart
  300. } = props;
  301. const {
  302. eventKey,
  303. eventData
  304. } = node;
  305. dragNode = node;
  306. dragStartMousePosition = {
  307. x: event.clientX,
  308. y: event.clientY
  309. };
  310. const newExpandedKeys = (0, _util.arrDel)(expandedKeys.value, eventKey);
  311. dragState.draggingNodeKey = eventKey;
  312. dragState.dragChildrenKeys = (0, _util.getDragChildrenKeys)(eventKey, keyEntities.value);
  313. indent.value = listRef.value.getIndentWidth();
  314. setExpandedKeys(newExpandedKeys);
  315. window.addEventListener('dragend', onWindowDragEnd);
  316. if (onDragstart) {
  317. onDragstart({
  318. event,
  319. node: eventData
  320. });
  321. }
  322. };
  323. /**
  324. * [Legacy] Select handler is smaller than node,
  325. * so that this will trigger when drag enter node or select handler.
  326. * This is a little tricky if customize css without padding.
  327. * Better for use mouse move event to refresh drag state.
  328. * But let's just keep it to avoid event trigger logic change.
  329. */
  330. const onNodeDragEnter = (event, node) => {
  331. const {
  332. onDragenter,
  333. onExpand,
  334. allowDrop,
  335. direction
  336. } = props;
  337. const {
  338. pos,
  339. eventKey
  340. } = node;
  341. // record the key of node which is latest entered, used in dragleave event.
  342. if (currentMouseOverDroppableNodeKey !== eventKey) {
  343. currentMouseOverDroppableNodeKey = eventKey;
  344. }
  345. if (!dragNode) {
  346. resetDragState();
  347. return;
  348. }
  349. const {
  350. dropPosition,
  351. dropLevelOffset,
  352. dropTargetKey,
  353. dropContainerKey,
  354. dropTargetPos,
  355. dropAllowed,
  356. dragOverNodeKey
  357. } = (0, _util.calcDropPosition)(event, dragNode, node, indent.value, dragStartMousePosition, allowDrop, flattenNodes.value, keyEntities.value, expandedKeysSet.value, direction);
  358. if (
  359. // don't allow drop inside its children
  360. dragState.dragChildrenKeys.indexOf(dropTargetKey) !== -1 ||
  361. // don't allow drop when drop is not allowed caculated by calcDropPosition
  362. !dropAllowed) {
  363. resetDragState();
  364. return;
  365. }
  366. // Side effect for delay drag
  367. if (!delayedDragEnterLogic) {
  368. delayedDragEnterLogic = {};
  369. }
  370. Object.keys(delayedDragEnterLogic).forEach(key => {
  371. clearTimeout(delayedDragEnterLogic[key]);
  372. });
  373. if (dragNode.eventKey !== node.eventKey) {
  374. // hoist expand logic here
  375. // since if logic is on the bottom
  376. // it will be blocked by abstract dragover node check
  377. // => if you dragenter from top, you mouse will still be consider as in the top node
  378. delayedDragEnterLogic[pos] = window.setTimeout(() => {
  379. if (dragState.draggingNodeKey === null) return;
  380. let newExpandedKeys = expandedKeys.value.slice();
  381. const entity = keyEntities.value[node.eventKey];
  382. if (entity && (entity.children || []).length) {
  383. newExpandedKeys = (0, _util.arrAdd)(expandedKeys.value, node.eventKey);
  384. }
  385. setExpandedKeys(newExpandedKeys);
  386. if (onExpand) {
  387. onExpand(newExpandedKeys, {
  388. node: node.eventData,
  389. expanded: true,
  390. nativeEvent: event
  391. });
  392. }
  393. }, 800);
  394. }
  395. // Skip if drag node is self
  396. if (dragNode.eventKey === dropTargetKey && dropLevelOffset === 0) {
  397. resetDragState();
  398. return;
  399. }
  400. // Update drag over node and drag state
  401. (0, _extends2.default)(dragState, {
  402. dragOverNodeKey,
  403. dropPosition,
  404. dropLevelOffset,
  405. dropTargetKey,
  406. dropContainerKey,
  407. dropTargetPos,
  408. dropAllowed
  409. });
  410. if (onDragenter) {
  411. onDragenter({
  412. event,
  413. node: node.eventData,
  414. expandedKeys: expandedKeys.value
  415. });
  416. }
  417. };
  418. const onNodeDragOver = (event, node) => {
  419. const {
  420. onDragover,
  421. allowDrop,
  422. direction
  423. } = props;
  424. if (!dragNode) {
  425. return;
  426. }
  427. const {
  428. dropPosition,
  429. dropLevelOffset,
  430. dropTargetKey,
  431. dropContainerKey,
  432. dropAllowed,
  433. dropTargetPos,
  434. dragOverNodeKey
  435. } = (0, _util.calcDropPosition)(event, dragNode, node, indent.value, dragStartMousePosition, allowDrop, flattenNodes.value, keyEntities.value, expandedKeysSet.value, direction);
  436. if (dragState.dragChildrenKeys.indexOf(dropTargetKey) !== -1 || !dropAllowed) {
  437. // don't allow drop inside its children
  438. // don't allow drop when drop is not allowed caculated by calcDropPosition
  439. return;
  440. }
  441. // Update drag position
  442. if (dragNode.eventKey === dropTargetKey && dropLevelOffset === 0) {
  443. if (!(dragState.dropPosition === null && dragState.dropLevelOffset === null && dragState.dropTargetKey === null && dragState.dropContainerKey === null && dragState.dropTargetPos === null && dragState.dropAllowed === false && dragState.dragOverNodeKey === null)) {
  444. resetDragState();
  445. }
  446. } else if (!(dropPosition === dragState.dropPosition && dropLevelOffset === dragState.dropLevelOffset && dropTargetKey === dragState.dropTargetKey && dropContainerKey === dragState.dropContainerKey && dropTargetPos === dragState.dropTargetPos && dropAllowed === dragState.dropAllowed && dragOverNodeKey === dragState.dragOverNodeKey)) {
  447. (0, _extends2.default)(dragState, {
  448. dropPosition,
  449. dropLevelOffset,
  450. dropTargetKey,
  451. dropContainerKey,
  452. dropTargetPos,
  453. dropAllowed,
  454. dragOverNodeKey
  455. });
  456. }
  457. if (onDragover) {
  458. onDragover({
  459. event,
  460. node: node.eventData
  461. });
  462. }
  463. };
  464. const onNodeDragLeave = (event, node) => {
  465. // if it is outside the droppable area
  466. // currentMouseOverDroppableNodeKey will be updated in dragenter event when into another droppable receiver.
  467. if (currentMouseOverDroppableNodeKey === node.eventKey && !event.currentTarget.contains(event.relatedTarget)) {
  468. resetDragState();
  469. currentMouseOverDroppableNodeKey = null;
  470. }
  471. const {
  472. onDragleave
  473. } = props;
  474. if (onDragleave) {
  475. onDragleave({
  476. event,
  477. node: node.eventData
  478. });
  479. }
  480. };
  481. const onNodeDrop = function (event, _node) {
  482. let outsideTree = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
  483. var _a;
  484. const {
  485. dragChildrenKeys,
  486. dropPosition,
  487. dropTargetKey,
  488. dropTargetPos,
  489. dropAllowed
  490. } = dragState;
  491. if (!dropAllowed) return;
  492. const {
  493. onDrop
  494. } = props;
  495. dragState.dragOverNodeKey = null;
  496. cleanDragState();
  497. if (dropTargetKey === null) return;
  498. const abstractDropNodeProps = (0, _extends2.default)((0, _extends2.default)({}, (0, _treeUtil.getTreeNodeProps)(dropTargetKey, (0, _vue.toRaw)(treeNodeRequiredProps.value))), {
  499. active: ((_a = activeItem.value) === null || _a === void 0 ? void 0 : _a.key) === dropTargetKey,
  500. data: keyEntities.value[dropTargetKey].node
  501. });
  502. const dropToChild = dragChildrenKeys.indexOf(dropTargetKey) !== -1;
  503. (0, _warning.warning)(!dropToChild, "Can not drop to dragNode's children node. Maybe this is a bug of ant-design-vue. Please report an issue.");
  504. const posArr = (0, _util.posToArr)(dropTargetPos);
  505. const dropResult = {
  506. event,
  507. node: (0, _treeUtil.convertNodePropsToEventData)(abstractDropNodeProps),
  508. dragNode: dragNode ? dragNode.eventData : null,
  509. dragNodesKeys: [dragNode.eventKey].concat(dragChildrenKeys),
  510. dropToGap: dropPosition !== 0,
  511. dropPosition: dropPosition + Number(posArr[posArr.length - 1])
  512. };
  513. if (!outsideTree) {
  514. onDrop === null || onDrop === void 0 ? void 0 : onDrop(dropResult);
  515. }
  516. dragNode = null;
  517. };
  518. const triggerExpandActionExpand = (e, treeNode) => {
  519. const {
  520. expanded,
  521. key
  522. } = treeNode;
  523. const node = flattenNodes.value.filter(nodeItem => nodeItem.key === key)[0];
  524. const eventNode = (0, _treeUtil.convertNodePropsToEventData)((0, _extends2.default)((0, _extends2.default)({}, (0, _treeUtil.getTreeNodeProps)(key, treeNodeRequiredProps.value)), {
  525. data: node.data
  526. }));
  527. setExpandedKeys(expanded ? (0, _util.arrDel)(expandedKeys.value, key) : (0, _util.arrAdd)(expandedKeys.value, key));
  528. onNodeExpand(e, eventNode);
  529. };
  530. const onNodeClick = (e, treeNode) => {
  531. const {
  532. onClick,
  533. expandAction
  534. } = props;
  535. if (expandAction === 'click') {
  536. triggerExpandActionExpand(e, treeNode);
  537. }
  538. if (onClick) {
  539. onClick(e, treeNode);
  540. }
  541. };
  542. const onNodeDoubleClick = (e, treeNode) => {
  543. const {
  544. onDblclick,
  545. expandAction
  546. } = props;
  547. if (expandAction === 'doubleclick' || expandAction === 'dblclick') {
  548. triggerExpandActionExpand(e, treeNode);
  549. }
  550. if (onDblclick) {
  551. onDblclick(e, treeNode);
  552. }
  553. };
  554. const onNodeSelect = (e, treeNode) => {
  555. let newSelectedKeys = selectedKeys.value;
  556. const {
  557. onSelect,
  558. multiple
  559. } = props;
  560. const {
  561. selected
  562. } = treeNode;
  563. const key = treeNode[fieldNames.value.key];
  564. const targetSelected = !selected;
  565. // Update selected keys
  566. if (!targetSelected) {
  567. newSelectedKeys = (0, _util.arrDel)(newSelectedKeys, key);
  568. } else if (!multiple) {
  569. newSelectedKeys = [key];
  570. } else {
  571. newSelectedKeys = (0, _util.arrAdd)(newSelectedKeys, key);
  572. }
  573. // [Legacy] Not found related usage in doc or upper libs
  574. const keyEntitiesValue = keyEntities.value;
  575. const selectedNodes = newSelectedKeys.map(selectedKey => {
  576. const entity = keyEntitiesValue[selectedKey];
  577. if (!entity) return null;
  578. return entity.node;
  579. }).filter(node => node);
  580. if (props.selectedKeys === undefined) {
  581. selectedKeys.value = newSelectedKeys;
  582. }
  583. if (onSelect) {
  584. onSelect(newSelectedKeys, {
  585. event: 'select',
  586. selected: targetSelected,
  587. node: treeNode,
  588. selectedNodes,
  589. nativeEvent: e
  590. });
  591. }
  592. };
  593. const onNodeCheck = (e, treeNode, checked) => {
  594. const {
  595. checkStrictly,
  596. onCheck
  597. } = props;
  598. const key = treeNode[fieldNames.value.key];
  599. // Prepare trigger arguments
  600. let checkedObj;
  601. const eventObj = {
  602. event: 'check',
  603. node: treeNode,
  604. checked,
  605. nativeEvent: e
  606. };
  607. const keyEntitiesValue = keyEntities.value;
  608. if (checkStrictly) {
  609. const newCheckedKeys = checked ? (0, _util.arrAdd)(checkedKeys.value, key) : (0, _util.arrDel)(checkedKeys.value, key);
  610. const newHalfCheckedKeys = (0, _util.arrDel)(halfCheckedKeys.value, key);
  611. checkedObj = {
  612. checked: newCheckedKeys,
  613. halfChecked: newHalfCheckedKeys
  614. };
  615. eventObj.checkedNodes = newCheckedKeys.map(checkedKey => keyEntitiesValue[checkedKey]).filter(entity => entity).map(entity => entity.node);
  616. if (props.checkedKeys === undefined) {
  617. checkedKeys.value = newCheckedKeys;
  618. }
  619. } else {
  620. // Always fill first
  621. let {
  622. checkedKeys: newCheckedKeys,
  623. halfCheckedKeys: newHalfCheckedKeys
  624. } = (0, _conductUtil.conductCheck)([...checkedKeys.value, key], true, keyEntitiesValue, maxLevel.value, levelEntities.value);
  625. // If remove, we do it again to correction
  626. if (!checked) {
  627. const keySet = new Set(newCheckedKeys);
  628. keySet.delete(key);
  629. ({
  630. checkedKeys: newCheckedKeys,
  631. halfCheckedKeys: newHalfCheckedKeys
  632. } = (0, _conductUtil.conductCheck)(Array.from(keySet), {
  633. checked: false,
  634. halfCheckedKeys: newHalfCheckedKeys
  635. }, keyEntitiesValue, maxLevel.value, levelEntities.value));
  636. }
  637. checkedObj = newCheckedKeys;
  638. // [Legacy] This is used for vc-tree-select`
  639. eventObj.checkedNodes = [];
  640. eventObj.checkedNodesPositions = [];
  641. eventObj.halfCheckedKeys = newHalfCheckedKeys;
  642. newCheckedKeys.forEach(checkedKey => {
  643. const entity = keyEntitiesValue[checkedKey];
  644. if (!entity) return;
  645. const {
  646. node,
  647. pos
  648. } = entity;
  649. eventObj.checkedNodes.push(node);
  650. eventObj.checkedNodesPositions.push({
  651. node,
  652. pos
  653. });
  654. });
  655. if (props.checkedKeys === undefined) {
  656. checkedKeys.value = newCheckedKeys;
  657. halfCheckedKeys.value = newHalfCheckedKeys;
  658. }
  659. }
  660. if (onCheck) {
  661. onCheck(checkedObj, eventObj);
  662. }
  663. };
  664. const onNodeLoad = treeNode => {
  665. const key = treeNode[fieldNames.value.key];
  666. const loadPromise = new Promise((resolve, reject) => {
  667. // We need to get the latest state of loading/loaded keys
  668. const {
  669. loadData,
  670. onLoad
  671. } = props;
  672. if (!loadData || loadedKeysSet.value.has(key) || loadingKeysSet.value.has(key)) {
  673. return null;
  674. }
  675. // Process load data
  676. const promise = loadData(treeNode);
  677. promise.then(() => {
  678. const newLoadedKeys = (0, _util.arrAdd)(loadedKeys.value, key);
  679. const newLoadingKeys = (0, _util.arrDel)(loadingKeys.value, key);
  680. // onLoad should trigger before internal setState to avoid `loadData` trigger twice.
  681. // https://github.com/ant-design/ant-design/issues/12464
  682. if (onLoad) {
  683. onLoad(newLoadedKeys, {
  684. event: 'load',
  685. node: treeNode
  686. });
  687. }
  688. if (props.loadedKeys === undefined) {
  689. loadedKeys.value = newLoadedKeys;
  690. }
  691. loadingKeys.value = newLoadingKeys;
  692. resolve();
  693. }).catch(e => {
  694. const newLoadingKeys = (0, _util.arrDel)(loadingKeys.value, key);
  695. loadingKeys.value = newLoadingKeys;
  696. // If exceed max retry times, we give up retry
  697. loadingRetryTimes[key] = (loadingRetryTimes[key] || 0) + 1;
  698. if (loadingRetryTimes[key] >= MAX_RETRY_TIMES) {
  699. (0, _warning.warning)(false, 'Retry for `loadData` many times but still failed. No more retry.');
  700. const newLoadedKeys = (0, _util.arrAdd)(loadedKeys.value, key);
  701. if (props.loadedKeys === undefined) {
  702. loadedKeys.value = newLoadedKeys;
  703. }
  704. resolve();
  705. }
  706. reject(e);
  707. });
  708. loadingKeys.value = (0, _util.arrAdd)(loadingKeys.value, key);
  709. });
  710. // Not care warning if we ignore this
  711. loadPromise.catch(() => {});
  712. return loadPromise;
  713. };
  714. const onNodeMouseEnter = (event, node) => {
  715. const {
  716. onMouseenter
  717. } = props;
  718. if (onMouseenter) {
  719. onMouseenter({
  720. event,
  721. node
  722. });
  723. }
  724. };
  725. const onNodeMouseLeave = (event, node) => {
  726. const {
  727. onMouseleave
  728. } = props;
  729. if (onMouseleave) {
  730. onMouseleave({
  731. event,
  732. node
  733. });
  734. }
  735. };
  736. const onNodeContextMenu = (event, node) => {
  737. const {
  738. onRightClick
  739. } = props;
  740. if (onRightClick) {
  741. event.preventDefault();
  742. onRightClick({
  743. event,
  744. node
  745. });
  746. }
  747. };
  748. const onFocus = e => {
  749. const {
  750. onFocus
  751. } = props;
  752. focused.value = true;
  753. if (onFocus) {
  754. onFocus(e);
  755. }
  756. };
  757. const onBlur = e => {
  758. const {
  759. onBlur
  760. } = props;
  761. focused.value = false;
  762. onActiveChange(null);
  763. if (onBlur) {
  764. onBlur(e);
  765. }
  766. };
  767. const onNodeExpand = (e, treeNode) => {
  768. let newExpandedKeys = expandedKeys.value;
  769. const {
  770. onExpand,
  771. loadData
  772. } = props;
  773. const {
  774. expanded
  775. } = treeNode;
  776. const key = treeNode[fieldNames.value.key];
  777. // Do nothing when motion is in progress
  778. if (listChanging.value) {
  779. return;
  780. }
  781. // Update selected keys
  782. const index = newExpandedKeys.indexOf(key);
  783. const targetExpanded = !expanded;
  784. (0, _warning.warning)(expanded && index !== -1 || !expanded && index === -1, 'Expand state not sync with index check');
  785. if (targetExpanded) {
  786. newExpandedKeys = (0, _util.arrAdd)(newExpandedKeys, key);
  787. } else {
  788. newExpandedKeys = (0, _util.arrDel)(newExpandedKeys, key);
  789. }
  790. setExpandedKeys(newExpandedKeys);
  791. if (onExpand) {
  792. onExpand(newExpandedKeys, {
  793. node: treeNode,
  794. expanded: targetExpanded,
  795. nativeEvent: e
  796. });
  797. }
  798. // Async Load data
  799. if (targetExpanded && loadData) {
  800. const loadPromise = onNodeLoad(treeNode);
  801. if (loadPromise) {
  802. loadPromise.then(() => {
  803. // [Legacy] Refresh logic
  804. // const newFlattenTreeData = flattenTreeData(
  805. // treeData.value,
  806. // newExpandedKeys,
  807. // fieldNames.value,
  808. // );
  809. // flattenNodes.value = newFlattenTreeData;
  810. }).catch(e => {
  811. const expandedKeysToRestore = (0, _util.arrDel)(expandedKeys.value, key);
  812. setExpandedKeys(expandedKeysToRestore);
  813. Promise.reject(e);
  814. });
  815. }
  816. }
  817. };
  818. const onListChangeStart = () => {
  819. listChanging.value = true;
  820. };
  821. const onListChangeEnd = () => {
  822. setTimeout(() => {
  823. listChanging.value = false;
  824. });
  825. };
  826. // =========================== Keyboard ===========================
  827. const onActiveChange = newActiveKey => {
  828. const {
  829. onActiveChange
  830. } = props;
  831. if (activeKey.value === newActiveKey) {
  832. return;
  833. }
  834. if (props.activeKey !== undefined) {
  835. activeKey.value = newActiveKey;
  836. }
  837. if (newActiveKey !== null) {
  838. scrollTo({
  839. key: newActiveKey
  840. });
  841. }
  842. if (onActiveChange) {
  843. onActiveChange(newActiveKey);
  844. }
  845. };
  846. const activeItem = (0, _vue.computed)(() => {
  847. if (activeKey.value === null) {
  848. return null;
  849. }
  850. return flattenNodes.value.find(_ref4 => {
  851. let {
  852. key
  853. } = _ref4;
  854. return key === activeKey.value;
  855. }) || null;
  856. });
  857. const offsetActiveKey = offset => {
  858. let index = flattenNodes.value.findIndex(_ref5 => {
  859. let {
  860. key
  861. } = _ref5;
  862. return key === activeKey.value;
  863. });
  864. // Align with index
  865. if (index === -1 && offset < 0) {
  866. index = flattenNodes.value.length;
  867. }
  868. index = (index + offset + flattenNodes.value.length) % flattenNodes.value.length;
  869. const item = flattenNodes.value[index];
  870. if (item) {
  871. const {
  872. key
  873. } = item;
  874. onActiveChange(key);
  875. } else {
  876. onActiveChange(null);
  877. }
  878. };
  879. const activeItemEventNode = (0, _vue.computed)(() => {
  880. return (0, _treeUtil.convertNodePropsToEventData)((0, _extends2.default)((0, _extends2.default)({}, (0, _treeUtil.getTreeNodeProps)(activeKey.value, treeNodeRequiredProps.value)), {
  881. data: activeItem.value.data,
  882. active: true
  883. }));
  884. });
  885. const onKeydown = event => {
  886. const {
  887. onKeydown,
  888. checkable,
  889. selectable
  890. } = props;
  891. // >>>>>>>>>> Direction
  892. switch (event.which) {
  893. case _KeyCode.default.UP:
  894. {
  895. offsetActiveKey(-1);
  896. event.preventDefault();
  897. break;
  898. }
  899. case _KeyCode.default.DOWN:
  900. {
  901. offsetActiveKey(1);
  902. event.preventDefault();
  903. break;
  904. }
  905. }
  906. // >>>>>>>>>> Expand & Selection
  907. const item = activeItem.value;
  908. if (item && item.data) {
  909. const expandable = item.data.isLeaf === false || !!(item.data.children || []).length;
  910. const eventNode = activeItemEventNode.value;
  911. switch (event.which) {
  912. // >>> Expand
  913. case _KeyCode.default.LEFT:
  914. {
  915. // Collapse if possible
  916. if (expandable && expandedKeysSet.value.has(activeKey.value)) {
  917. onNodeExpand({}, eventNode);
  918. } else if (item.parent) {
  919. onActiveChange(item.parent.key);
  920. }
  921. event.preventDefault();
  922. break;
  923. }
  924. case _KeyCode.default.RIGHT:
  925. {
  926. // Expand if possible
  927. if (expandable && !expandedKeysSet.value.has(activeKey.value)) {
  928. onNodeExpand({}, eventNode);
  929. } else if (item.children && item.children.length) {
  930. onActiveChange(item.children[0].key);
  931. }
  932. event.preventDefault();
  933. break;
  934. }
  935. // Selection
  936. case _KeyCode.default.ENTER:
  937. case _KeyCode.default.SPACE:
  938. {
  939. if (checkable && !eventNode.disabled && eventNode.checkable !== false && !eventNode.disableCheckbox) {
  940. onNodeCheck({}, eventNode, !checkedKeysSet.value.has(activeKey.value));
  941. } else if (!checkable && selectable && !eventNode.disabled && eventNode.selectable !== false) {
  942. onNodeSelect({}, eventNode);
  943. }
  944. break;
  945. }
  946. }
  947. }
  948. if (onKeydown) {
  949. onKeydown(event);
  950. }
  951. };
  952. expose({
  953. onNodeExpand,
  954. scrollTo,
  955. onKeydown,
  956. selectedKeys: (0, _vue.computed)(() => selectedKeys.value),
  957. checkedKeys: (0, _vue.computed)(() => checkedKeys.value),
  958. halfCheckedKeys: (0, _vue.computed)(() => halfCheckedKeys.value),
  959. loadedKeys: (0, _vue.computed)(() => loadedKeys.value),
  960. loadingKeys: (0, _vue.computed)(() => loadingKeys.value),
  961. expandedKeys: (0, _vue.computed)(() => expandedKeys.value)
  962. });
  963. (0, _vue.onUnmounted)(() => {
  964. window.removeEventListener('dragend', onWindowDragEnd);
  965. destroyed.value = true;
  966. });
  967. (0, _contextTypes.useProvideKeysState)({
  968. expandedKeys,
  969. selectedKeys,
  970. loadedKeys,
  971. loadingKeys,
  972. checkedKeys,
  973. halfCheckedKeys,
  974. expandedKeysSet,
  975. selectedKeysSet,
  976. loadedKeysSet,
  977. loadingKeysSet,
  978. checkedKeysSet,
  979. halfCheckedKeysSet,
  980. flattenNodes
  981. });
  982. return () => {
  983. const {
  984. // focused,
  985. // flattenNodes,
  986. // keyEntities,
  987. draggingNodeKey,
  988. // activeKey,
  989. dropLevelOffset,
  990. dropContainerKey,
  991. dropTargetKey,
  992. dropPosition,
  993. dragOverNodeKey
  994. // indent,
  995. } = dragState;
  996. const {
  997. prefixCls,
  998. showLine,
  999. focusable,
  1000. tabindex = 0,
  1001. selectable,
  1002. showIcon,
  1003. icon = slots.icon,
  1004. switcherIcon,
  1005. draggable,
  1006. checkable,
  1007. checkStrictly,
  1008. disabled,
  1009. motion,
  1010. loadData,
  1011. filterTreeNode,
  1012. height,
  1013. itemHeight,
  1014. virtual,
  1015. dropIndicatorRender,
  1016. onContextmenu,
  1017. onScroll,
  1018. direction,
  1019. rootClassName,
  1020. rootStyle
  1021. } = props;
  1022. const {
  1023. class: className,
  1024. style
  1025. } = attrs;
  1026. const domProps = (0, _pickAttrs.default)((0, _extends2.default)((0, _extends2.default)({}, props), attrs), {
  1027. aria: true,
  1028. data: true
  1029. });
  1030. // It's better move to hooks but we just simply keep here
  1031. let draggableConfig;
  1032. if (draggable) {
  1033. if (typeof draggable === 'object') {
  1034. draggableConfig = draggable;
  1035. } else if (typeof draggable === 'function') {
  1036. draggableConfig = {
  1037. nodeDraggable: draggable
  1038. };
  1039. } else {
  1040. draggableConfig = {};
  1041. }
  1042. } else {
  1043. draggableConfig = false;
  1044. }
  1045. return (0, _vue.createVNode)(_contextTypes.TreeContext, {
  1046. "value": {
  1047. prefixCls,
  1048. selectable,
  1049. showIcon,
  1050. icon,
  1051. switcherIcon,
  1052. draggable: draggableConfig,
  1053. draggingNodeKey,
  1054. checkable,
  1055. customCheckable: slots.checkable,
  1056. checkStrictly,
  1057. disabled,
  1058. keyEntities: keyEntities.value,
  1059. dropLevelOffset,
  1060. dropContainerKey,
  1061. dropTargetKey,
  1062. dropPosition,
  1063. dragOverNodeKey,
  1064. dragging: draggingNodeKey !== null,
  1065. indent: indent.value,
  1066. direction,
  1067. dropIndicatorRender,
  1068. loadData,
  1069. filterTreeNode,
  1070. onNodeClick,
  1071. onNodeDoubleClick,
  1072. onNodeExpand,
  1073. onNodeSelect,
  1074. onNodeCheck,
  1075. onNodeLoad,
  1076. onNodeMouseEnter,
  1077. onNodeMouseLeave,
  1078. onNodeContextMenu,
  1079. onNodeDragStart,
  1080. onNodeDragEnter,
  1081. onNodeDragOver,
  1082. onNodeDragLeave,
  1083. onNodeDragEnd,
  1084. onNodeDrop,
  1085. slots
  1086. }
  1087. }, {
  1088. default: () => [(0, _vue.createVNode)("div", {
  1089. "role": "tree",
  1090. "class": (0, _classNames.default)(prefixCls, className, rootClassName, {
  1091. [`${prefixCls}-show-line`]: showLine,
  1092. [`${prefixCls}-focused`]: focused.value,
  1093. [`${prefixCls}-active-focused`]: activeKey.value !== null
  1094. }),
  1095. "style": rootStyle
  1096. }, [(0, _vue.createVNode)(_NodeList.default, (0, _objectSpread2.default)({
  1097. "ref": listRef,
  1098. "prefixCls": prefixCls,
  1099. "style": style,
  1100. "disabled": disabled,
  1101. "selectable": selectable,
  1102. "checkable": !!checkable,
  1103. "motion": motion,
  1104. "height": height,
  1105. "itemHeight": itemHeight,
  1106. "virtual": virtual,
  1107. "focusable": focusable,
  1108. "focused": focused.value,
  1109. "tabindex": tabindex,
  1110. "activeItem": activeItem.value,
  1111. "onFocus": onFocus,
  1112. "onBlur": onBlur,
  1113. "onKeydown": onKeydown,
  1114. "onActiveChange": onActiveChange,
  1115. "onListChangeStart": onListChangeStart,
  1116. "onListChangeEnd": onListChangeEnd,
  1117. "onContextmenu": onContextmenu,
  1118. "onScroll": onScroll
  1119. }, domProps), null)])]
  1120. });
  1121. };
  1122. }
  1123. });