react-vtree
Version:
React component for efficiently rendering large tree structures
158 lines (130 loc) • 4.87 kB
JavaScript
import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized";
import _inheritsLoose from "@babel/runtime/helpers/inheritsLoose";
import _extends from "@babel/runtime/helpers/extends";
/* eslint-disable react/no-unused-state,@typescript-eslint/consistent-type-assertions */
import React, { PureComponent } from 'react';
// eslint-disable-next-line @typescript-eslint/naming-convention,@typescript-eslint/prefer-readonly-parameter-types
export var Row = function Row(_ref) {
var index = _ref.index,
_ref$data = _ref.data,
Node = _ref$data.component,
treeData = _ref$data.treeData,
order = _ref$data.order,
records = _ref$data.records,
style = _ref.style,
isScrolling = _ref.isScrolling;
return /*#__PURE__*/React.createElement(Node, Object.assign({}, records[order[index]], {
style: style,
isScrolling: isScrolling,
treeData: treeData
}));
};
export var createTreeComputer = function createTreeComputer(_ref2) {
var createRecord = _ref2.createRecord,
shouldUpdateRecords = _ref2.shouldUpdateRecords,
updateRecord = _ref2.updateRecord,
updateRecordOnNewData = _ref2.updateRecordOnNewData;
return function (_ref3, state, options) {
var _options$refreshNodes;
var treeWalker = _ref3.treeWalker;
if (options === void 0) {
options = {};
}
var order = [];
var records = _extends({}, state.records);
var iter = treeWalker((_options$refreshNodes = options.refreshNodes) != null ? _options$refreshNodes : false); // Here we are updating all records to the provided openness state described
// in UpdateOptions. It should be done before the tree re-calculation
// because tree walker omits closed nodes while update is required for all
// of them.
if (shouldUpdateRecords(options)) {
for (var id in records) {
updateRecord(records[id], id, options);
}
}
var isPreviousOpened = false; // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition,no-constant-condition
while (true) {
var _iter$next = iter.next(isPreviousOpened),
done = _iter$next.done,
value = _iter$next.value;
if (done || !value) {
break;
}
var _id = void 0;
if (typeof value === 'string' || typeof value === 'symbol') {
_id = value;
} else {
_id = value.id;
var _record = records[_id];
if (!_record) {
records[_id] = createRecord(value, options, state);
} else {
_record.data = value;
updateRecordOnNewData(_record, options);
}
}
if (records[_id]) {
order.push(_id);
isPreviousOpened = records[_id].isOpen;
} else if (process.env.NODE_ENV === 'development') {
// eslint-disable-next-line no-console
console.error("No record with id " + String(_id) + " found.");
}
}
return {
order: order,
records: records
};
};
};
var Tree = /*#__PURE__*/function (_PureComponent) {
_inheritsLoose(Tree, _PureComponent);
Tree.getDerivedStateFromProps = function getDerivedStateFromProps(props, state) {
var component = props.children,
treeData = props.itemData,
treeWalker = props.treeWalker;
var computeTree = state.computeTree,
order = state.order,
oldTreeWalker = state.treeWalker;
return _extends({
component: component,
treeData: treeData,
treeWalker: treeWalker
}, treeWalker !== oldTreeWalker || !order ? computeTree(props, state, {
refreshNodes: true
}) : null);
};
function Tree(props, context) {
var _this;
_this = _PureComponent.call(this, props, context) || this;
_this.list = /*#__PURE__*/React.createRef();
_this.state = {
component: props.children,
recomputeTree: _this.recomputeTree.bind(_assertThisInitialized(_this)),
records: {}
};
return _this;
}
var _proto = Tree.prototype;
_proto.recomputeTree = function recomputeTree(options) {
var _this2 = this;
return new Promise(function (resolve) {
_this2.setState(function (prevState) {
return prevState.computeTree(_this2.props, prevState, options);
}, resolve);
});
};
_proto.scrollTo = function scrollTo(scrollOffset) {
var _this$list$current;
(_this$list$current = this.list.current) == null ? void 0 : _this$list$current.scrollTo(scrollOffset);
};
_proto.scrollToItem = function scrollToItem(id, align) {
var _this$list$current2;
// eslint-disable-next-line react/destructuring-assignment
(_this$list$current2 = this.list.current) == null ? void 0 : _this$list$current2.scrollToItem(this.state.order.indexOf(id), align);
};
return Tree;
}(PureComponent);
Tree.defaultProps = {
rowComponent: Row
};
export default Tree;