mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-10 04:30:25 +02:00
debounce table loader
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import { useMergedRef } from '@mantine/hooks';
|
import { useMergedRef } from '@mantine/hooks';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
|
import debounce from 'lodash/debounce';
|
||||||
import { AnimatePresence } from 'motion/react';
|
import { AnimatePresence } from 'motion/react';
|
||||||
import { useOverlayScrollbars } from 'overlayscrollbars-react';
|
import { useOverlayScrollbars } from 'overlayscrollbars-react';
|
||||||
import React, {
|
import React, {
|
||||||
@@ -14,7 +15,7 @@ import React, {
|
|||||||
useRef,
|
useRef,
|
||||||
useState,
|
useState,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import { type CellComponentProps, Grid, type GridProps } from 'react-window-v2';
|
import { type CellComponentProps, Grid } from 'react-window-v2';
|
||||||
|
|
||||||
import styles from './item-table-list.module.css';
|
import styles from './item-table-list.module.css';
|
||||||
|
|
||||||
@@ -46,7 +47,7 @@ interface VirtualizedTableGridProps {
|
|||||||
internalState: ItemListStateActions;
|
internalState: ItemListStateActions;
|
||||||
itemType: LibraryItem;
|
itemType: LibraryItem;
|
||||||
mergedRowRef: React.Ref<HTMLDivElement>;
|
mergedRowRef: React.Ref<HTMLDivElement>;
|
||||||
onCellsRendered?: GridProps<TableItemProps>['onCellsRendered'];
|
onRangeChanged?: ItemTableListProps['onRangeChanged'];
|
||||||
onRowClick?: (item: any, event: React.MouseEvent<HTMLDivElement>) => void;
|
onRowClick?: (item: any, event: React.MouseEvent<HTMLDivElement>) => void;
|
||||||
parsedColumns: ReturnType<typeof parseTableColumns>;
|
parsedColumns: ReturnType<typeof parseTableColumns>;
|
||||||
pinnedLeftColumnCount: number;
|
pinnedLeftColumnCount: number;
|
||||||
@@ -80,7 +81,7 @@ const VirtualizedTableGrid = React.memo(
|
|||||||
internalState,
|
internalState,
|
||||||
itemType,
|
itemType,
|
||||||
mergedRowRef,
|
mergedRowRef,
|
||||||
onCellsRendered,
|
onRangeChanged,
|
||||||
onRowClick,
|
onRowClick,
|
||||||
parsedColumns,
|
parsedColumns,
|
||||||
pinnedLeftColumnCount,
|
pinnedLeftColumnCount,
|
||||||
@@ -200,6 +201,23 @@ const VirtualizedTableGrid = React.memo(
|
|||||||
[pinnedLeftColumnCount, pinnedRowCount, CellComponent],
|
[pinnedLeftColumnCount, pinnedRowCount, CellComponent],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const debouncedOnCellsRendered = useMemo(() => {
|
||||||
|
return debounce(
|
||||||
|
(items: {
|
||||||
|
columnStartIndex: number;
|
||||||
|
columnStopIndex: number;
|
||||||
|
rowStartIndex: number;
|
||||||
|
rowStopIndex: number;
|
||||||
|
}) => {
|
||||||
|
onRangeChanged?.({
|
||||||
|
startIndex: items.rowStartIndex,
|
||||||
|
stopIndex: items.rowStopIndex,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
45,
|
||||||
|
);
|
||||||
|
}, [onRangeChanged]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.itemTableContainer}>
|
<div className={styles.itemTableContainer}>
|
||||||
<div
|
<div
|
||||||
@@ -294,7 +312,7 @@ const VirtualizedTableGrid = React.memo(
|
|||||||
columnWidth={(index) => {
|
columnWidth={(index) => {
|
||||||
return columnWidth(index + pinnedLeftColumnCount);
|
return columnWidth(index + pinnedLeftColumnCount);
|
||||||
}}
|
}}
|
||||||
onCellsRendered={onCellsRendered}
|
onCellsRendered={debouncedOnCellsRendered}
|
||||||
rowCount={totalRowCount}
|
rowCount={totalRowCount}
|
||||||
rowHeight={(index, cellProps) => {
|
rowHeight={(index, cellProps) => {
|
||||||
return getRowHeight(index + pinnedRowCount, cellProps);
|
return getRowHeight(index + pinnedRowCount, cellProps);
|
||||||
@@ -419,14 +437,8 @@ interface ItemTableListProps {
|
|||||||
type: 'index' | 'offset';
|
type: 'index' | 'offset';
|
||||||
};
|
};
|
||||||
itemType: LibraryItem;
|
itemType: LibraryItem;
|
||||||
onCellsRendered?: GridProps<TableItemProps>['onCellsRendered'];
|
onRangeChanged?: (range: { startIndex: number; stopIndex: number }) => void;
|
||||||
onEndReached?: (index: number, internalState: ItemListStateActions) => void;
|
|
||||||
onRangeChanged?: (
|
|
||||||
range: { endIndex: number; startIndex: number },
|
|
||||||
internalState: ItemListStateActions,
|
|
||||||
) => void;
|
|
||||||
onScrollEnd?: (offset: number, internalState: ItemListStateActions) => void;
|
onScrollEnd?: (offset: number, internalState: ItemListStateActions) => void;
|
||||||
onStartReached?: (index: number, internalState: ItemListStateActions) => void;
|
|
||||||
ref?: Ref<ItemListHandle>;
|
ref?: Ref<ItemListHandle>;
|
||||||
rowHeight?: ((index: number, cellProps: TableItemProps) => number) | number;
|
rowHeight?: ((index: number, cellProps: TableItemProps) => number) | number;
|
||||||
size?: 'compact' | 'default' | 'large';
|
size?: 'compact' | 'default' | 'large';
|
||||||
@@ -448,11 +460,8 @@ export const ItemTableList = ({
|
|||||||
headerHeight = 40,
|
headerHeight = 40,
|
||||||
initialTop,
|
initialTop,
|
||||||
itemType,
|
itemType,
|
||||||
onCellsRendered,
|
|
||||||
onEndReached,
|
|
||||||
onRangeChanged,
|
onRangeChanged,
|
||||||
onScrollEnd,
|
onScrollEnd,
|
||||||
onStartReached,
|
|
||||||
ref,
|
ref,
|
||||||
rowHeight,
|
rowHeight,
|
||||||
size = 'default',
|
size = 'default',
|
||||||
@@ -950,10 +959,10 @@ export const ItemTableList = ({
|
|||||||
if (lastIndex !== -1 && currentIndex !== -1) {
|
if (lastIndex !== -1 && currentIndex !== -1) {
|
||||||
// Create range selection
|
// Create range selection
|
||||||
const startIndex = Math.min(lastIndex, currentIndex);
|
const startIndex = Math.min(lastIndex, currentIndex);
|
||||||
const endIndex = Math.max(lastIndex, currentIndex);
|
const stopIndex = Math.max(lastIndex, currentIndex);
|
||||||
|
|
||||||
const rangeItems: ItemListItem[] = [];
|
const rangeItems: ItemListItem[] = [];
|
||||||
for (let i = startIndex; i <= endIndex; i++) {
|
for (let i = startIndex; i <= stopIndex; i++) {
|
||||||
const rangeItem = data[i];
|
const rangeItem = data[i];
|
||||||
if (
|
if (
|
||||||
rangeItem &&
|
rangeItem &&
|
||||||
@@ -1015,59 +1024,6 @@ export const ItemTableList = ({
|
|||||||
[data, enableSelection, internalState, itemType],
|
[data, enableSelection, internalState, itemType],
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleOnCellsRendered = useCallback(
|
|
||||||
(cells: {
|
|
||||||
columnStartIndex: number;
|
|
||||||
columnStopIndex: number;
|
|
||||||
rowStartIndex: number;
|
|
||||||
rowStopIndex: number;
|
|
||||||
}) => {
|
|
||||||
onRangeChanged?.(
|
|
||||||
{
|
|
||||||
endIndex: cells.rowStopIndex,
|
|
||||||
startIndex: cells.rowStartIndex,
|
|
||||||
},
|
|
||||||
internalState,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (onStartReached || onEndReached) {
|
|
||||||
if (cells.rowStartIndex === 0) {
|
|
||||||
onStartReached?.(0, handleRef.current ?? (undefined as any));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cells.rowStopIndex + 10 >= totalItemCount) {
|
|
||||||
onEndReached?.(totalItemCount, handleRef.current ?? (undefined as any));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (onCellsRendered) {
|
|
||||||
return ({ columnStartIndex, columnStopIndex, rowStartIndex, rowStopIndex }) => {
|
|
||||||
return onCellsRendered!(
|
|
||||||
{
|
|
||||||
columnStartIndex: columnStartIndex + pinnedLeftColumnCount,
|
|
||||||
columnStopIndex: columnStopIndex + pinnedLeftColumnCount,
|
|
||||||
rowStartIndex: rowStartIndex + pinnedRowCount,
|
|
||||||
rowStopIndex: rowStopIndex + pinnedRowCount,
|
|
||||||
},
|
|
||||||
cells,
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return undefined;
|
|
||||||
},
|
|
||||||
[
|
|
||||||
onCellsRendered,
|
|
||||||
onEndReached,
|
|
||||||
onRangeChanged,
|
|
||||||
onStartReached,
|
|
||||||
pinnedLeftColumnCount,
|
|
||||||
pinnedRowCount,
|
|
||||||
totalItemCount,
|
|
||||||
internalState,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
const isInitialScrollPositionSet = useRef<boolean>(false);
|
const isInitialScrollPositionSet = useRef<boolean>(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -1134,7 +1090,7 @@ export const ItemTableList = ({
|
|||||||
internalState={internalState}
|
internalState={internalState}
|
||||||
itemType={itemType}
|
itemType={itemType}
|
||||||
mergedRowRef={mergedRowRef}
|
mergedRowRef={mergedRowRef}
|
||||||
onCellsRendered={handleOnCellsRendered}
|
onRangeChanged={onRangeChanged}
|
||||||
onRowClick={handleRowClick}
|
onRowClick={handleRowClick}
|
||||||
parsedColumns={parsedColumns}
|
parsedColumns={parsedColumns}
|
||||||
pinnedLeftColumnCount={pinnedLeftColumnCount}
|
pinnedLeftColumnCount={pinnedLeftColumnCount}
|
||||||
|
|||||||
Reference in New Issue
Block a user