123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 |
- import _extends from "@babel/runtime/helpers/esm/extends";
- import _objectDestructuringEmpty from "@babel/runtime/helpers/esm/objectDestructuringEmpty";
- import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
- import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
- var _excluded = ["prefixCls", "data", "selectable", "checkable", "expandedKeys", "selectedKeys", "checkedKeys", "loadedKeys", "loadingKeys", "halfCheckedKeys", "keyEntities", "disabled", "dragging", "dragOverNodeKey", "dropPosition", "motion", "height", "itemHeight", "virtual", "scrollWidth", "focusable", "activeItem", "focused", "tabIndex", "onKeyDown", "onFocus", "onBlur", "onActiveChange", "onListChangeStart", "onListChangeEnd"];
- /**
- * Handle virtual list of the TreeNodes.
- */
- import useLayoutEffect from "rc-util/es/hooks/useLayoutEffect";
- import VirtualList from 'rc-virtual-list';
- import * as React from 'react';
- import MotionTreeNode from "./MotionTreeNode";
- import { findExpandedKeys, getExpandRange } from "./utils/diffUtil";
- import { getKey, getTreeNodeProps } from "./utils/treeUtil";
- var HIDDEN_STYLE = {
- width: 0,
- height: 0,
- display: 'flex',
- overflow: 'hidden',
- opacity: 0,
- border: 0,
- padding: 0,
- margin: 0
- };
- var noop = function noop() {};
- export var MOTION_KEY = "RC_TREE_MOTION_".concat(Math.random());
- var MotionNode = {
- key: MOTION_KEY
- };
- export var MotionEntity = {
- key: MOTION_KEY,
- level: 0,
- index: 0,
- pos: '0',
- node: MotionNode,
- nodes: [MotionNode]
- };
- var MotionFlattenData = {
- parent: null,
- children: [],
- pos: MotionEntity.pos,
- data: MotionNode,
- title: null,
- key: MOTION_KEY,
- /** Hold empty list here since we do not use it */
- isStart: [],
- isEnd: []
- };
- /**
- * We only need get visible content items to play the animation.
- */
- export function getMinimumRangeTransitionRange(list, virtual, height, itemHeight) {
- if (virtual === false || !height) {
- return list;
- }
- return list.slice(0, Math.ceil(height / itemHeight) + 1);
- }
- function itemKey(item) {
- var key = item.key,
- pos = item.pos;
- return getKey(key, pos);
- }
- function getAccessibilityPath(item) {
- var path = String(item.data.key);
- var current = item;
- while (current.parent) {
- current = current.parent;
- path = "".concat(current.data.key, " > ").concat(path);
- }
- return path;
- }
- var NodeList = /*#__PURE__*/React.forwardRef(function (props, ref) {
- var prefixCls = props.prefixCls,
- data = props.data,
- selectable = props.selectable,
- checkable = props.checkable,
- expandedKeys = props.expandedKeys,
- selectedKeys = props.selectedKeys,
- checkedKeys = props.checkedKeys,
- loadedKeys = props.loadedKeys,
- loadingKeys = props.loadingKeys,
- halfCheckedKeys = props.halfCheckedKeys,
- keyEntities = props.keyEntities,
- disabled = props.disabled,
- dragging = props.dragging,
- dragOverNodeKey = props.dragOverNodeKey,
- dropPosition = props.dropPosition,
- motion = props.motion,
- height = props.height,
- itemHeight = props.itemHeight,
- virtual = props.virtual,
- scrollWidth = props.scrollWidth,
- focusable = props.focusable,
- activeItem = props.activeItem,
- focused = props.focused,
- tabIndex = props.tabIndex,
- onKeyDown = props.onKeyDown,
- onFocus = props.onFocus,
- onBlur = props.onBlur,
- onActiveChange = props.onActiveChange,
- onListChangeStart = props.onListChangeStart,
- onListChangeEnd = props.onListChangeEnd,
- domProps = _objectWithoutProperties(props, _excluded);
- // =============================== Ref ================================
- var listRef = React.useRef(null);
- var indentMeasurerRef = React.useRef(null);
- React.useImperativeHandle(ref, function () {
- return {
- scrollTo: function scrollTo(scroll) {
- listRef.current.scrollTo(scroll);
- },
- getIndentWidth: function getIndentWidth() {
- return indentMeasurerRef.current.offsetWidth;
- }
- };
- });
- // ============================== Motion ==============================
- var _React$useState = React.useState(expandedKeys),
- _React$useState2 = _slicedToArray(_React$useState, 2),
- prevExpandedKeys = _React$useState2[0],
- setPrevExpandedKeys = _React$useState2[1];
- var _React$useState3 = React.useState(data),
- _React$useState4 = _slicedToArray(_React$useState3, 2),
- prevData = _React$useState4[0],
- setPrevData = _React$useState4[1];
- var _React$useState5 = React.useState(data),
- _React$useState6 = _slicedToArray(_React$useState5, 2),
- transitionData = _React$useState6[0],
- setTransitionData = _React$useState6[1];
- var _React$useState7 = React.useState([]),
- _React$useState8 = _slicedToArray(_React$useState7, 2),
- transitionRange = _React$useState8[0],
- setTransitionRange = _React$useState8[1];
- var _React$useState9 = React.useState(null),
- _React$useState10 = _slicedToArray(_React$useState9, 2),
- motionType = _React$useState10[0],
- setMotionType = _React$useState10[1];
- // When motion end but data change, this will makes data back to previous one
- var dataRef = React.useRef(data);
- dataRef.current = data;
- function onMotionEnd() {
- var latestData = dataRef.current;
- setPrevData(latestData);
- setTransitionData(latestData);
- setTransitionRange([]);
- setMotionType(null);
- onListChangeEnd();
- }
- // Do animation if expanded keys changed
- // layoutEffect here to avoid blink of node removing
- useLayoutEffect(function () {
- setPrevExpandedKeys(expandedKeys);
- var diffExpanded = findExpandedKeys(prevExpandedKeys, expandedKeys);
- if (diffExpanded.key !== null) {
- if (diffExpanded.add) {
- var keyIndex = prevData.findIndex(function (_ref) {
- var key = _ref.key;
- return key === diffExpanded.key;
- });
- var rangeNodes = getMinimumRangeTransitionRange(getExpandRange(prevData, data, diffExpanded.key), virtual, height, itemHeight);
- var newTransitionData = prevData.slice();
- newTransitionData.splice(keyIndex + 1, 0, MotionFlattenData);
- setTransitionData(newTransitionData);
- setTransitionRange(rangeNodes);
- setMotionType('show');
- } else {
- var _keyIndex = data.findIndex(function (_ref2) {
- var key = _ref2.key;
- return key === diffExpanded.key;
- });
- var _rangeNodes = getMinimumRangeTransitionRange(getExpandRange(data, prevData, diffExpanded.key), virtual, height, itemHeight);
- var _newTransitionData = data.slice();
- _newTransitionData.splice(_keyIndex + 1, 0, MotionFlattenData);
- setTransitionData(_newTransitionData);
- setTransitionRange(_rangeNodes);
- setMotionType('hide');
- }
- } else if (prevData !== data) {
- // If whole data changed, we just refresh the list
- setPrevData(data);
- setTransitionData(data);
- }
- }, [expandedKeys, data]);
- // We should clean up motion if is changed by dragging
- React.useEffect(function () {
- if (!dragging) {
- onMotionEnd();
- }
- }, [dragging]);
- var mergedData = motion ? transitionData : data;
- var treeNodeRequiredProps = {
- expandedKeys: expandedKeys,
- selectedKeys: selectedKeys,
- loadedKeys: loadedKeys,
- loadingKeys: loadingKeys,
- checkedKeys: checkedKeys,
- halfCheckedKeys: halfCheckedKeys,
- dragOverNodeKey: dragOverNodeKey,
- dropPosition: dropPosition,
- keyEntities: keyEntities
- };
- return /*#__PURE__*/React.createElement(React.Fragment, null, focused && activeItem && /*#__PURE__*/React.createElement("span", {
- style: HIDDEN_STYLE,
- "aria-live": "assertive"
- }, getAccessibilityPath(activeItem)), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("input", {
- style: HIDDEN_STYLE,
- disabled: focusable === false || disabled,
- tabIndex: focusable !== false ? tabIndex : null,
- onKeyDown: onKeyDown,
- onFocus: onFocus,
- onBlur: onBlur,
- value: "",
- onChange: noop,
- "aria-label": "for screen reader"
- })), /*#__PURE__*/React.createElement("div", {
- className: "".concat(prefixCls, "-treenode"),
- "aria-hidden": true,
- style: {
- position: 'absolute',
- pointerEvents: 'none',
- visibility: 'hidden',
- height: 0,
- overflow: 'hidden',
- border: 0,
- padding: 0
- }
- }, /*#__PURE__*/React.createElement("div", {
- className: "".concat(prefixCls, "-indent")
- }, /*#__PURE__*/React.createElement("div", {
- ref: indentMeasurerRef,
- className: "".concat(prefixCls, "-indent-unit")
- }))), /*#__PURE__*/React.createElement(VirtualList, _extends({}, domProps, {
- data: mergedData,
- itemKey: itemKey,
- height: height,
- fullHeight: false,
- virtual: virtual,
- itemHeight: itemHeight,
- scrollWidth: scrollWidth,
- prefixCls: "".concat(prefixCls, "-list"),
- ref: listRef,
- role: "tree",
- onVisibleChange: function onVisibleChange(originList) {
- // The best match is using `fullList` - `originList` = `restList`
- // and check the `restList` to see if has the MOTION_KEY node
- // but this will cause performance issue for long list compare
- // we just check `originList` and repeat trigger `onMotionEnd`
- if (originList.every(function (item) {
- return itemKey(item) !== MOTION_KEY;
- })) {
- onMotionEnd();
- }
- }
- }), function (treeNode) {
- var pos = treeNode.pos,
- restProps = Object.assign({}, (_objectDestructuringEmpty(treeNode.data), treeNode.data)),
- title = treeNode.title,
- key = treeNode.key,
- isStart = treeNode.isStart,
- isEnd = treeNode.isEnd;
- var mergedKey = getKey(key, pos);
- delete restProps.key;
- delete restProps.children;
- var treeNodeProps = getTreeNodeProps(mergedKey, treeNodeRequiredProps);
- return /*#__PURE__*/React.createElement(MotionTreeNode, _extends({}, restProps, treeNodeProps, {
- title: title,
- active: !!activeItem && key === activeItem.key,
- pos: pos,
- data: treeNode.data,
- isStart: isStart,
- isEnd: isEnd,
- motion: motion,
- motionNodes: key === MOTION_KEY ? transitionRange : null,
- motionType: motionType,
- onMotionStart: onListChangeStart,
- onMotionEnd: onMotionEnd,
- treeNodeRequiredProps: treeNodeRequiredProps,
- onMouseMove: function onMouseMove() {
- onActiveChange(null);
- }
- }));
- }));
- });
- if (process.env.NODE_ENV !== 'production') {
- NodeList.displayName = 'NodeList';
- }
- export default NodeList;
|