NodeList.js 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. import _objectDestructuringEmpty from "@babel/runtime/helpers/esm/objectDestructuringEmpty";
  2. import _extends from "@babel/runtime/helpers/esm/extends";
  3. import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
  4. import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
  5. import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
  6. var _excluded = ["prefixCls", "selectable", "checkable", "disabled", "motion", "height", "itemHeight", "virtual", "focusable", "activeItem", "focused", "tabindex", "onKeydown", "onFocus", "onBlur", "onListChangeStart", "onListChangeEnd"];
  7. import { resolveDirective as _resolveDirective, createVNode as _createVNode, Fragment as _Fragment } from "vue";
  8. /**
  9. * Handle virtual list of the TreeNodes.
  10. */
  11. import { computed, defineComponent, ref, shallowRef, watch } from 'vue';
  12. import VirtualList from '../vc-virtual-list';
  13. import omit from '../_util/omit';
  14. import { useInjectKeysState, useInjectTreeContext } from './contextTypes';
  15. import MotionTreeNode from './MotionTreeNode';
  16. import { nodeListProps } from './props';
  17. import { findExpandedKeys, getExpandRange } from './utils/diffUtil';
  18. import { getKey } from './utils/treeUtil';
  19. var HIDDEN_STYLE = {
  20. width: 0,
  21. height: 0,
  22. display: 'flex',
  23. overflow: 'hidden',
  24. opacity: 0,
  25. border: 0,
  26. padding: 0,
  27. margin: 0
  28. };
  29. var noop = function noop() {};
  30. export var MOTION_KEY = "RC_TREE_MOTION_".concat(Math.random());
  31. var MotionNode = {
  32. key: MOTION_KEY
  33. };
  34. export var MotionEntity = {
  35. key: MOTION_KEY,
  36. level: 0,
  37. index: 0,
  38. pos: '0',
  39. node: MotionNode,
  40. nodes: [MotionNode]
  41. };
  42. var MotionFlattenData = {
  43. parent: null,
  44. children: [],
  45. pos: MotionEntity.pos,
  46. data: MotionNode,
  47. title: null,
  48. key: MOTION_KEY,
  49. /** Hold empty list here since we do not use it */
  50. isStart: [],
  51. isEnd: []
  52. };
  53. /**
  54. * We only need get visible content items to play the animation.
  55. */
  56. export function getMinimumRangeTransitionRange(list, virtual, height, itemHeight) {
  57. if (virtual === false || !height) {
  58. return list;
  59. }
  60. return list.slice(0, Math.ceil(height / itemHeight) + 1);
  61. }
  62. function itemKey(item) {
  63. var key = item.key,
  64. pos = item.pos;
  65. return getKey(key, pos);
  66. }
  67. function getAccessibilityPath(item) {
  68. var path = String(item.key);
  69. var current = item;
  70. while (current.parent) {
  71. current = current.parent;
  72. path = "".concat(current.key, " > ").concat(path);
  73. }
  74. return path;
  75. }
  76. export default defineComponent({
  77. compatConfig: {
  78. MODE: 3
  79. },
  80. name: 'NodeList',
  81. inheritAttrs: false,
  82. props: nodeListProps,
  83. setup: function setup(props, _ref) {
  84. var expose = _ref.expose,
  85. attrs = _ref.attrs;
  86. // =============================== Ref ================================
  87. var listRef = ref();
  88. var indentMeasurerRef = ref();
  89. var _useInjectKeysState = useInjectKeysState(),
  90. expandedKeys = _useInjectKeysState.expandedKeys,
  91. flattenNodes = _useInjectKeysState.flattenNodes;
  92. expose({
  93. scrollTo: function scrollTo(scroll) {
  94. listRef.value.scrollTo(scroll);
  95. },
  96. getIndentWidth: function getIndentWidth() {
  97. return indentMeasurerRef.value.offsetWidth;
  98. }
  99. });
  100. // ============================== Motion ==============================
  101. var transitionData = shallowRef(flattenNodes.value);
  102. var transitionRange = shallowRef([]);
  103. var motionType = ref(null);
  104. function onMotionEnd() {
  105. transitionData.value = flattenNodes.value;
  106. transitionRange.value = [];
  107. motionType.value = null;
  108. props.onListChangeEnd();
  109. }
  110. var context = useInjectTreeContext();
  111. watch([function () {
  112. return expandedKeys.value.slice();
  113. }, flattenNodes], function (_ref2, _ref3) {
  114. var _ref4 = _slicedToArray(_ref2, 2),
  115. expandedKeys = _ref4[0],
  116. data = _ref4[1];
  117. var _ref5 = _slicedToArray(_ref3, 2),
  118. prevExpandedKeys = _ref5[0],
  119. prevData = _ref5[1];
  120. var diffExpanded = findExpandedKeys(prevExpandedKeys, expandedKeys);
  121. if (diffExpanded.key !== null) {
  122. var virtual = props.virtual,
  123. height = props.height,
  124. itemHeight = props.itemHeight;
  125. if (diffExpanded.add) {
  126. var keyIndex = prevData.findIndex(function (_ref6) {
  127. var key = _ref6.key;
  128. return key === diffExpanded.key;
  129. });
  130. var rangeNodes = getMinimumRangeTransitionRange(getExpandRange(prevData, data, diffExpanded.key), virtual, height, itemHeight);
  131. var newTransitionData = prevData.slice();
  132. newTransitionData.splice(keyIndex + 1, 0, MotionFlattenData);
  133. transitionData.value = newTransitionData;
  134. transitionRange.value = rangeNodes;
  135. motionType.value = 'show';
  136. } else {
  137. var _keyIndex = data.findIndex(function (_ref7) {
  138. var key = _ref7.key;
  139. return key === diffExpanded.key;
  140. });
  141. var _rangeNodes = getMinimumRangeTransitionRange(getExpandRange(data, prevData, diffExpanded.key), virtual, height, itemHeight);
  142. var _newTransitionData = data.slice();
  143. _newTransitionData.splice(_keyIndex + 1, 0, MotionFlattenData);
  144. transitionData.value = _newTransitionData;
  145. transitionRange.value = _rangeNodes;
  146. motionType.value = 'hide';
  147. }
  148. } else if (prevData !== data) {
  149. transitionData.value = data;
  150. }
  151. });
  152. // We should clean up motion if is changed by dragging
  153. watch(function () {
  154. return context.value.dragging;
  155. }, function (dragging) {
  156. if (!dragging) {
  157. onMotionEnd();
  158. }
  159. });
  160. var mergedData = computed(function () {
  161. return props.motion === undefined ? transitionData.value : flattenNodes.value;
  162. });
  163. var onActiveChange = function onActiveChange() {
  164. props.onActiveChange(null);
  165. };
  166. return function () {
  167. var _props$attrs = _objectSpread(_objectSpread({}, props), attrs),
  168. prefixCls = _props$attrs.prefixCls,
  169. selectable = _props$attrs.selectable,
  170. checkable = _props$attrs.checkable,
  171. disabled = _props$attrs.disabled,
  172. motion = _props$attrs.motion,
  173. height = _props$attrs.height,
  174. itemHeight = _props$attrs.itemHeight,
  175. virtual = _props$attrs.virtual,
  176. focusable = _props$attrs.focusable,
  177. activeItem = _props$attrs.activeItem,
  178. focused = _props$attrs.focused,
  179. tabindex = _props$attrs.tabindex,
  180. onKeydown = _props$attrs.onKeydown,
  181. onFocus = _props$attrs.onFocus,
  182. onBlur = _props$attrs.onBlur,
  183. onListChangeStart = _props$attrs.onListChangeStart,
  184. onListChangeEnd = _props$attrs.onListChangeEnd,
  185. domProps = _objectWithoutProperties(_props$attrs, _excluded);
  186. return _createVNode(_Fragment, null, [focused && activeItem && _createVNode("span", {
  187. "style": HIDDEN_STYLE,
  188. "aria-live": "assertive"
  189. }, [getAccessibilityPath(activeItem)]), _createVNode("div", null, [_createVNode("input", {
  190. "style": HIDDEN_STYLE,
  191. "disabled": focusable === false || disabled,
  192. "tabindex": focusable !== false ? tabindex : null,
  193. "onKeydown": onKeydown,
  194. "onFocus": onFocus,
  195. "onBlur": onBlur,
  196. "value": "",
  197. "onChange": noop,
  198. "aria-label": "for screen reader"
  199. }, null)]), _createVNode("div", {
  200. "class": "".concat(prefixCls, "-treenode"),
  201. "aria-hidden": true,
  202. "style": {
  203. position: 'absolute',
  204. pointerEvents: 'none',
  205. visibility: 'hidden',
  206. height: 0,
  207. overflow: 'hidden'
  208. }
  209. }, [_createVNode("div", {
  210. "class": "".concat(prefixCls, "-indent")
  211. }, [_createVNode("div", {
  212. "ref": indentMeasurerRef,
  213. "class": "".concat(prefixCls, "-indent-unit")
  214. }, null)])]), _createVNode(VirtualList, _objectSpread(_objectSpread({}, omit(domProps, ['onActiveChange'])), {}, {
  215. "data": mergedData.value,
  216. "itemKey": itemKey,
  217. "height": height,
  218. "fullHeight": false,
  219. "virtual": virtual,
  220. "itemHeight": itemHeight,
  221. "prefixCls": "".concat(prefixCls, "-list"),
  222. "ref": listRef,
  223. "onVisibleChange": function onVisibleChange(originList, fullList) {
  224. var originSet = new Set(originList);
  225. var restList = fullList.filter(function (item) {
  226. return !originSet.has(item);
  227. });
  228. // Motion node is not render. Skip motion
  229. if (restList.some(function (item) {
  230. return itemKey(item) === MOTION_KEY;
  231. })) {
  232. onMotionEnd();
  233. }
  234. }
  235. }), {
  236. default: function _default(treeNode) {
  237. var pos = treeNode.pos,
  238. restProps = _extends({}, (_objectDestructuringEmpty(treeNode.data), treeNode.data)),
  239. title = treeNode.title,
  240. key = treeNode.key,
  241. isStart = treeNode.isStart,
  242. isEnd = treeNode.isEnd;
  243. var mergedKey = getKey(key, pos);
  244. delete restProps.key;
  245. delete restProps.children;
  246. return _createVNode(MotionTreeNode, _objectSpread(_objectSpread({}, restProps), {}, {
  247. "eventKey": mergedKey,
  248. "title": title,
  249. "active": !!activeItem && key === activeItem.key,
  250. "data": treeNode.data,
  251. "isStart": isStart,
  252. "isEnd": isEnd,
  253. "motion": motion,
  254. "motionNodes": key === MOTION_KEY ? transitionRange.value : null,
  255. "motionType": motionType.value,
  256. "onMotionStart": onListChangeStart,
  257. "onMotionEnd": onMotionEnd,
  258. "onMousemove": onActiveChange
  259. }), null);
  260. }
  261. })]);
  262. };
  263. }
  264. });