import React from 'react'; import Hook from '../../hook'; import { DataColumnExtra, TableContext, TableMessages } from '../types/table.type'; import { DataRow } from '../types/body.type'; import { DataTableBody } from './body'; import { TableBodyRowHeight } from './style'; interface DataColumn extends DataColumnExtra { sticky?: number, } export interface DataTableBodyVirtualizedProps { tableRef: any, context: TableContext, messages: TableMessages, selectable: boolean, onDataChange: (column: DataColumn, row: DataRow, value: any) => void } export const DataTableBodyVirtualized: React.FC = ({ tableRef, context, messages, selectable, onDataChange }) => { const status = React.useRef({ scroll: 0, hold: false }) const [virtualization, setVirtualization] = React.useState({ from: 0, to: 0 }); React.useLayoutEffect(() => { tableRef.current.scrollTop = status.current.scroll; status.current.hold = false; }) Hook.useScrollPosition(tableRef, ({ current }) => { if (!status.current.hold) { const scroll = current.y; const viewportRows = Math.ceil(current.h / TableBodyRowHeight); const viewportHeight = viewportRows * TableBodyRowHeight; const rowsBuffered = Math.max(2, viewportRows); const p = Math.ceil(scroll / TableBodyRowHeight) * TableBodyRowHeight; const f = Math.floor(p / TableBodyRowHeight) - rowsBuffered; const t = Math.ceil((p + viewportHeight) / TableBodyRowHeight) + rowsBuffered; const r = f < 0 ? -f : 0; const from = Math.max(0, f); const to = Math.min(t + r, 1000); status.current.scroll = scroll; tableRef.current.scrollTop = status.current.scroll; if (virtualization.from !== from || virtualization.to !== to) { status.current.hold = true; setVirtualization({ from, to }); } } }, 100) return ( ) }