Initial logs with datasource / datatable setup

Summary:
First rudementary setup of DataTable component that follows a data source. Initially used react-virtuose library, but it performed really badly by doing expensive layout shifts and having troublesome scroll handling. Switched to react-virtual library, which is a bit more level, but much more efficient, and the source code is actually understandable :)

Features:
- hook up to window events of datasource
- high and low prio rendering, based on where the change is happening (should be optimized further)
- sticky scrolling support
- initial column configuration (custom rendering, styling, columns etc will follow in next diffs)

Reviewed By: nikoant

Differential Revision: D26175665

fbshipit-source-id: 224be13b1b32d35e7e01c1dc4198811e2af31102
This commit is contained in:
Michel Weststrate
2021-03-16 14:54:53 -07:00
committed by Facebook GitHub Bot
parent 5b76a0c717
commit 86ad413669
8 changed files with 440 additions and 3 deletions

View File

@@ -70,9 +70,10 @@ type OutputChange =
newCount: number;
};
// TODO: remove class, export interface instead
export class DataSource<
T,
KEY extends keyof T,
KEY extends keyof T = any,
KEY_TYPE extends string | number | never = ExtractKeyType<T, KEY>
> {
private nextId = 0;
@@ -267,6 +268,9 @@ export class DataSource<
setOutputChangeListener(
listener: typeof DataSource['prototype']['outputChangeListener'],
) {
if (this.outputChangeListener && listener) {
console.warn('outputChangeListener already set');
}
this.outputChangeListener = listener;
}
@@ -303,11 +307,14 @@ export class DataSource<
* The clear operation removes any records stored, but will keep the current view preferences such as sorting and filtering
*/
clear() {
this.windowStart = 0;
this.windowEnd = 0;
this._records = [];
this._recordsById = new Map();
this.idToIndex = new Map();
this.dataUpdateQueue = [];
this.output = [];
this.notifyReset(0);
}
/**
@@ -372,6 +379,13 @@ export class DataSource<
});
}
notifyReset(count: number) {
this.outputChangeListener?.({
type: 'reset',
newCount: count,
});
}
processEvents() {
const events = this.dataUpdateQueue.splice(0);
events.forEach(this.processEvent);