UNPKG

react-vtree

Version:

React component for efficiently rendering large tree structures

104 lines (90 loc) 2.86 kB
import React from 'react'; import { VariableSizeList } from 'react-window'; import Tree, { createTreeComputer } from './Tree'; import { shouldUpdateRecords, updateRecord, updateRecordOnNewData } from './utils'; const computeTree = createTreeComputer({ createRecord: (data, { opennessState }, { recomputeTree, resetAfterId }) => { var _opennessState; const record = { data, height: data.defaultHeight, isOpen: (_opennessState = opennessState == null ? void 0 : opennessState[data.id]) != null ? _opennessState : data.isOpenByDefault, resize(height, shouldForceUpdate) { record.height = height; resetAfterId(record.data.id, shouldForceUpdate); }, toggle() { record.isOpen = !record.isOpen; return recomputeTree({ refreshNodes: record.isOpen, useDefaultHeight: true }); } }; return record; }, shouldUpdateRecords: options => { var _options$useDefaultHe; return shouldUpdateRecords(options) || ((_options$useDefaultHe = options.useDefaultHeight) != null ? _options$useDefaultHe : false); }, updateRecord: (record, recordId, options) => { if (options.useDefaultHeight) { record.height = record.data.defaultHeight; } updateRecord(record, recordId, options); }, updateRecordOnNewData: (record, options) => { updateRecordOnNewData(record, options); if (options.useDefaultHeight) { record.height = record.data.defaultHeight; } } }); export class VariableSizeTree extends Tree { constructor(props, context) { super(props, context); this.getItemSize = this.getItemSize.bind(this); this.state = { ...this.state, computeTree, resetAfterId: this.resetAfterId.bind(this) }; } resetAfterId(id, shouldForceUpdate = false) { var _this$list$current; (_this$list$current = this.list.current) == null ? void 0 : _this$list$current.resetAfterIndex(this.state.order.indexOf(id), shouldForceUpdate); } recomputeTree(options) { return super.recomputeTree(options).then(() => { var _this$list$current2; (_this$list$current2 = this.list.current) == null ? void 0 : _this$list$current2.resetAfterIndex(0, true); }); } render() { const { children, itemSize, rowComponent, treeWalker, ...rest } = this.props; return /*#__PURE__*/React.createElement(VariableSizeList, Object.assign({}, rest, { itemCount: this.state.order.length, itemData: this.state // eslint-disable-next-line @typescript-eslint/unbound-method , itemSize: itemSize != null ? itemSize : this.getItemSize, ref: this.list }), rowComponent); } getItemSize(index) { const { order, records } = this.state; return records[order[index]].height; } }