Split DataSource & DataSourceView
Summary: This diff is primarily cosmetic, just pushing code around to make the API more intuitive. Most importantly, DataSource was split into DataSource and DataSourceView classes, the latter being accessible through `datasource.view`. The benefit of this is two fold: 1. Conceptually it is much clearer now which operations operate on the _source_ records, and which ones on the derived _view_. 2. This will make it easier in the future to support multiple views to be based on a single data source. This refactoring also nicely found 2 cases where datasource logic and view logic were mixed. The only semantic change in this diff is that both DataSource and DataSourceView are now iterable, so that one can do a `for (const record of ds)` / `for (const record of ds.view)` Reviewed By: nikoant Differential Revision: D26976838 fbshipit-source-id: 3726e92b3c6ee3417dc66cbbe6e288797eecf70e
This commit is contained in:
committed by
Facebook GitHub Bot
parent
d73f6578a7
commit
602152665b
@@ -96,7 +96,7 @@ export const DataSourceRenderer: <T extends object, C>(
|
||||
const parentRef = React.useRef<null | HTMLDivElement>(null);
|
||||
|
||||
const virtualizer = useVirtual({
|
||||
size: dataSource.output.length,
|
||||
size: dataSource.view.size,
|
||||
parentRef,
|
||||
useObserver: _testHeight
|
||||
? () => ({height: _testHeight, width: 1000})
|
||||
@@ -148,7 +148,7 @@ export const DataSourceRenderer: <T extends object, C>(
|
||||
}
|
||||
}
|
||||
|
||||
dataSource.setOutputChangeListener((event) => {
|
||||
dataSource.view.setListener((event) => {
|
||||
switch (event.type) {
|
||||
case 'reset':
|
||||
rerender(UpdatePrio.HIGH, true);
|
||||
@@ -171,7 +171,7 @@ export const DataSourceRenderer: <T extends object, C>(
|
||||
|
||||
return () => {
|
||||
unmounted = true;
|
||||
dataSource.setOutputChangeListener(undefined);
|
||||
dataSource.view.setListener(undefined);
|
||||
};
|
||||
},
|
||||
[dataSource, setForceUpdate, useFixedRowHeight, _testHeight],
|
||||
@@ -185,15 +185,15 @@ export const DataSourceRenderer: <T extends object, C>(
|
||||
useLayoutEffect(function updateWindow() {
|
||||
const start = virtualizer.virtualItems[0]?.index ?? 0;
|
||||
const end = start + virtualizer.virtualItems.length;
|
||||
if (start !== dataSource.windowStart && !followOutput.current) {
|
||||
if (start !== dataSource.view.windowStart && !followOutput.current) {
|
||||
onRangeChange?.(
|
||||
start,
|
||||
end,
|
||||
dataSource.output.length,
|
||||
dataSource.view.size,
|
||||
parentRef.current?.scrollTop ?? 0,
|
||||
);
|
||||
}
|
||||
dataSource.setWindow(start, end);
|
||||
dataSource.view.setWindow(start, end);
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -223,7 +223,7 @@ export const DataSourceRenderer: <T extends object, C>(
|
||||
useLayoutEffect(function scrollToEnd() {
|
||||
if (followOutput.current) {
|
||||
virtualizer.scrollToIndex(
|
||||
dataSource.output.length - 1,
|
||||
dataSource.view.size - 1,
|
||||
/* smooth is not typed by react-virtual, but passed on to the DOM as it should*/
|
||||
{
|
||||
align: 'end',
|
||||
@@ -255,7 +255,7 @@ export const DataSourceRenderer: <T extends object, C>(
|
||||
onKeyDown={onKeyDown}
|
||||
tabIndex={0}>
|
||||
{virtualizer.virtualItems.map((virtualRow) => {
|
||||
const entry = dataSource.getEntry(virtualRow.index);
|
||||
const value = dataSource.view.get(virtualRow.index);
|
||||
// the position properties always change, so they are not part of the TableRow to avoid invalidating the memoized render always.
|
||||
// Also all row containers are renderd as part of same component to have 'less react' framework code in between*/}
|
||||
return (
|
||||
@@ -270,7 +270,7 @@ export const DataSourceRenderer: <T extends object, C>(
|
||||
transform: `translateY(${virtualRow.start}px)`,
|
||||
}}
|
||||
ref={useFixedRowHeight ? undefined : virtualRow.measureRef}>
|
||||
{itemRenderer(entry.value, virtualRow.index, context)}
|
||||
{itemRenderer(value, virtualRow.index, context)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -197,7 +197,7 @@ export function DataTable<T extends object>(
|
||||
(e: React.KeyboardEvent<any>) => {
|
||||
let handled = true;
|
||||
const shiftPressed = e.shiftKey;
|
||||
const outputSize = dataSource.output.length;
|
||||
const outputSize = dataSource.view.size;
|
||||
const windowSize = virtualizerRef.current!.virtualItems.length;
|
||||
switch (e.key) {
|
||||
case 'ArrowUp':
|
||||
@@ -244,7 +244,7 @@ export function DataTable<T extends object>(
|
||||
|
||||
useEffect(
|
||||
function updateFilter() {
|
||||
dataSource.setFilter(
|
||||
dataSource.view.setFilter(
|
||||
computeDataTableFilter(state.searchValue, state.columns),
|
||||
);
|
||||
},
|
||||
@@ -257,11 +257,11 @@ export function DataTable<T extends object>(
|
||||
useEffect(
|
||||
function updateSorting() {
|
||||
if (state.sorting === undefined) {
|
||||
dataSource.setSortBy(undefined);
|
||||
dataSource.setReversed(false);
|
||||
dataSource.view.setSortBy(undefined);
|
||||
dataSource.view.setReversed(false);
|
||||
} else {
|
||||
dataSource.setSortBy(state.sorting.key);
|
||||
dataSource.setReversed(state.sorting.direction === 'desc');
|
||||
dataSource.view.setSortBy(state.sorting.key);
|
||||
dataSource.view.setReversed(state.sorting.direction === 'desc');
|
||||
}
|
||||
},
|
||||
[dataSource, state.sorting],
|
||||
@@ -342,7 +342,7 @@ export function DataTable<T extends object>(
|
||||
savePreferences(stateRef.current, lastOffset.current);
|
||||
// if the component unmounts, we reset the SFRW pipeline to
|
||||
// avoid wasting resources in the background
|
||||
dataSource.reset();
|
||||
dataSource.view.reset();
|
||||
// clean ref
|
||||
if (props.tableManagerRef) {
|
||||
(props.tableManagerRef as MutableRefObject<any>).current = undefined;
|
||||
|
||||
@@ -342,7 +342,7 @@ export function getSelectedItem<T>(
|
||||
): T | undefined {
|
||||
return selection.current < 0
|
||||
? undefined
|
||||
: dataSource.getItem(selection.current);
|
||||
: dataSource.view.get(selection.current);
|
||||
}
|
||||
|
||||
export function getSelectedItems<T>(
|
||||
@@ -351,7 +351,7 @@ export function getSelectedItems<T>(
|
||||
): T[] {
|
||||
return [...selection.items]
|
||||
.sort()
|
||||
.map((i) => dataSource.getItem(i))
|
||||
.map((i) => dataSource.view.get(i))
|
||||
.filter(Boolean) as any[];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user