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 windowStart = 0;
|
||||
private windowEnd = 0;
|
||||
windowStart = 0;
|
||||
windowEnd = 0;
|
||||
|
||||
private outputChangeListener?: (change: OutputChange) => void;
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ type DataSourceProps<T extends object, C> = {
|
||||
defaultRowHeight: number;
|
||||
onKeyDown?: React.KeyboardEventHandler<HTMLDivElement>;
|
||||
virtualizerRef?: MutableRefObject<DataSourceVirtualizer | undefined>;
|
||||
onRangeChange?(start: number, end: number, total: number): void;
|
||||
_testHeight?: number; // exposed for unit testing only
|
||||
};
|
||||
|
||||
@@ -73,6 +74,7 @@ export const DataSourceRenderer: <T extends object, C>(
|
||||
autoScroll,
|
||||
onKeyDown,
|
||||
virtualizerRef,
|
||||
onRangeChange,
|
||||
_testHeight,
|
||||
}: DataSourceProps<any, any>) {
|
||||
/**
|
||||
@@ -176,6 +178,9 @@ 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) {
|
||||
onRangeChange?.(start, end, dataSource.output.length);
|
||||
}
|
||||
dataSource.setWindow(start, end);
|
||||
});
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import React, {
|
||||
useLayoutEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
RefObject,
|
||||
MutableRefObject,
|
||||
} from 'react';
|
||||
@@ -23,6 +24,8 @@ import {Percentage} from '../utils/widthUtils';
|
||||
import {DataSourceRenderer, DataSourceVirtualizer} from './DataSourceRenderer';
|
||||
import {useDataTableManager, TableManager} from './useDataTableManager';
|
||||
import {TableSearch} from './TableSearch';
|
||||
import styled from '@emotion/styled';
|
||||
import {theme} from '../theme';
|
||||
|
||||
interface DataTableProps<T = any> {
|
||||
columns: DataTableColumn<T>[];
|
||||
@@ -161,34 +164,64 @@ export function DataTable<T extends object>(props: DataTableProps<T>) {
|
||||
[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 (
|
||||
<Layout.Top>
|
||||
<Layout.Container>
|
||||
<TableSearch
|
||||
onSearch={tableManager.setSearchValue}
|
||||
extraActions={props.extraActions}
|
||||
<Layout.Container grow>
|
||||
<Layout.Top>
|
||||
<Layout.Container>
|
||||
<TableSearch
|
||||
onSearch={tableManager.setSearchValue}
|
||||
extraActions={props.extraActions}
|
||||
/>
|
||||
<TableHead
|
||||
columns={tableManager.columns}
|
||||
visibleColumns={tableManager.visibleColumns}
|
||||
onColumnResize={tableManager.resizeColumn}
|
||||
onReset={tableManager.reset}
|
||||
onColumnToggleVisibility={tableManager.toggleColumnVisibility}
|
||||
sorting={tableManager.sorting}
|
||||
onColumnSort={tableManager.sortColumn}
|
||||
/>
|
||||
</Layout.Container>
|
||||
<DataSourceRenderer<T, RenderContext<T>>
|
||||
dataSource={dataSource}
|
||||
autoScroll={props.autoScroll}
|
||||
useFixedRowHeight={!usesWrapping}
|
||||
defaultRowHeight={DEFAULT_ROW_HEIGHT}
|
||||
context={renderingConfig}
|
||||
itemRenderer={itemRenderer}
|
||||
onKeyDown={onKeyDown}
|
||||
virtualizerRef={virtualizerRef}
|
||||
onRangeChange={onRangeChange}
|
||||
_testHeight={props._testHeight}
|
||||
/>
|
||||
<TableHead
|
||||
columns={tableManager.columns}
|
||||
visibleColumns={tableManager.visibleColumns}
|
||||
onColumnResize={tableManager.resizeColumn}
|
||||
onReset={tableManager.reset}
|
||||
onColumnToggleVisibility={tableManager.toggleColumnVisibility}
|
||||
sorting={tableManager.sorting}
|
||||
onColumnSort={tableManager.sortColumn}
|
||||
/>
|
||||
</Layout.Container>
|
||||
<DataSourceRenderer<T, RenderContext<T>>
|
||||
dataSource={dataSource}
|
||||
autoScroll={props.autoScroll}
|
||||
useFixedRowHeight={!usesWrapping}
|
||||
defaultRowHeight={DEFAULT_ROW_HEIGHT}
|
||||
context={renderingConfig}
|
||||
itemRenderer={itemRenderer}
|
||||
onKeyDown={onKeyDown}
|
||||
virtualizerRef={virtualizerRef}
|
||||
_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