Introduce range finder
Summary: Show a hint during scrolling of the relative offset the user is looking at. This is based on the current virtualisation window, so not 100% accurate, but probably still provides the right signal to the user. See the bottom right of the recording Reviewed By: nikoant Differential Revision: D26450261 fbshipit-source-id: 206a860024e346c6b872edc3fc7919019046a6d7
This commit is contained in:
committed by
Facebook GitHub Bot
parent
1ce665ceaf
commit
8aabce477b
@@ -91,8 +91,8 @@ export class DataSource<
|
|||||||
|
|
||||||
private dataUpdateQueue: DataEvent<T>[] = [];
|
private dataUpdateQueue: DataEvent<T>[] = [];
|
||||||
|
|
||||||
private windowStart = 0;
|
windowStart = 0;
|
||||||
private windowEnd = 0;
|
windowEnd = 0;
|
||||||
|
|
||||||
private outputChangeListener?: (change: OutputChange) => void;
|
private outputChangeListener?: (change: OutputChange) => void;
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ type DataSourceProps<T extends object, C> = {
|
|||||||
defaultRowHeight: number;
|
defaultRowHeight: number;
|
||||||
onKeyDown?: React.KeyboardEventHandler<HTMLDivElement>;
|
onKeyDown?: React.KeyboardEventHandler<HTMLDivElement>;
|
||||||
virtualizerRef?: MutableRefObject<DataSourceVirtualizer | undefined>;
|
virtualizerRef?: MutableRefObject<DataSourceVirtualizer | undefined>;
|
||||||
|
onRangeChange?(start: number, end: number, total: number): void;
|
||||||
_testHeight?: number; // exposed for unit testing only
|
_testHeight?: number; // exposed for unit testing only
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -73,6 +74,7 @@ export const DataSourceRenderer: <T extends object, C>(
|
|||||||
autoScroll,
|
autoScroll,
|
||||||
onKeyDown,
|
onKeyDown,
|
||||||
virtualizerRef,
|
virtualizerRef,
|
||||||
|
onRangeChange,
|
||||||
_testHeight,
|
_testHeight,
|
||||||
}: DataSourceProps<any, any>) {
|
}: DataSourceProps<any, any>) {
|
||||||
/**
|
/**
|
||||||
@@ -176,6 +178,9 @@ export const DataSourceRenderer: <T extends object, C>(
|
|||||||
useLayoutEffect(function updateWindow() {
|
useLayoutEffect(function updateWindow() {
|
||||||
const start = virtualizer.virtualItems[0]?.index ?? 0;
|
const start = virtualizer.virtualItems[0]?.index ?? 0;
|
||||||
const end = start + virtualizer.virtualItems.length;
|
const end = start + virtualizer.virtualItems.length;
|
||||||
|
if (start !== dataSource.windowStart && !followOutput.current) {
|
||||||
|
onRangeChange?.(start, end, dataSource.output.length);
|
||||||
|
}
|
||||||
dataSource.setWindow(start, end);
|
dataSource.setWindow(start, end);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import React, {
|
|||||||
useLayoutEffect,
|
useLayoutEffect,
|
||||||
useMemo,
|
useMemo,
|
||||||
useRef,
|
useRef,
|
||||||
|
useState,
|
||||||
RefObject,
|
RefObject,
|
||||||
MutableRefObject,
|
MutableRefObject,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
@@ -23,6 +24,8 @@ import {Percentage} from '../utils/widthUtils';
|
|||||||
import {DataSourceRenderer, DataSourceVirtualizer} from './DataSourceRenderer';
|
import {DataSourceRenderer, DataSourceVirtualizer} from './DataSourceRenderer';
|
||||||
import {useDataTableManager, TableManager} from './useDataTableManager';
|
import {useDataTableManager, TableManager} from './useDataTableManager';
|
||||||
import {TableSearch} from './TableSearch';
|
import {TableSearch} from './TableSearch';
|
||||||
|
import styled from '@emotion/styled';
|
||||||
|
import {theme} from '../theme';
|
||||||
|
|
||||||
interface DataTableProps<T = any> {
|
interface DataTableProps<T = any> {
|
||||||
columns: DataTableColumn<T>[];
|
columns: DataTableColumn<T>[];
|
||||||
@@ -161,7 +164,24 @@ export function DataTable<T extends object>(props: DataTableProps<T>) {
|
|||||||
[selection],
|
[selection],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/** Range finder */
|
||||||
|
const [range, setRange] = useState('');
|
||||||
|
const hideRange = useRef<NodeJS.Timeout>();
|
||||||
|
|
||||||
|
const onRangeChange = useCallback(
|
||||||
|
(start: number, end: number, total: number) => {
|
||||||
|
// TODO: figure out if we don't trigger this callback to often hurting perf
|
||||||
|
setRange(`${start} - ${end} / ${total}`);
|
||||||
|
clearTimeout(hideRange.current!);
|
||||||
|
hideRange.current = setTimeout(() => {
|
||||||
|
setRange('');
|
||||||
|
}, 1000);
|
||||||
|
},
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<Layout.Container grow>
|
||||||
<Layout.Top>
|
<Layout.Top>
|
||||||
<Layout.Container>
|
<Layout.Container>
|
||||||
<TableSearch
|
<TableSearch
|
||||||
@@ -187,8 +207,21 @@ export function DataTable<T extends object>(props: DataTableProps<T>) {
|
|||||||
itemRenderer={itemRenderer}
|
itemRenderer={itemRenderer}
|
||||||
onKeyDown={onKeyDown}
|
onKeyDown={onKeyDown}
|
||||||
virtualizerRef={virtualizerRef}
|
virtualizerRef={virtualizerRef}
|
||||||
|
onRangeChange={onRangeChange}
|
||||||
_testHeight={props._testHeight}
|
_testHeight={props._testHeight}
|
||||||
/>
|
/>
|
||||||
</Layout.Top>
|
</Layout.Top>
|
||||||
|
{range && <RangeFinder>{range}</RangeFinder>}
|
||||||
|
</Layout.Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const RangeFinder = styled.div({
|
||||||
|
backgroundColor: theme.backgroundWash,
|
||||||
|
position: 'absolute',
|
||||||
|
right: 40,
|
||||||
|
bottom: 20,
|
||||||
|
padding: '4px 8px',
|
||||||
|
color: theme.textColorSecondary,
|
||||||
|
fontSize: '0.8em',
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user