|
|
@@ -1,105 +0,0 @@
|
|
|
-import React, { useState, useEffect, useRef } from 'react'
|
|
|
-import { VariableSizeGrid as Grid } from 'react-window'
|
|
|
-import ResizeObserver from 'rc-resize-observer'
|
|
|
-import classNames from 'classnames'
|
|
|
-import { Table } from 'antd'
|
|
|
-import type { TableProps } from 'antd'
|
|
|
-
|
|
|
-function VirtualTable<RecordType extends Record<string, unknown>>(props: TableProps<RecordType>) {
|
|
|
- const { columns, scroll } = props
|
|
|
- const [state, setState] = useState({
|
|
|
- tableWidth: 0,
|
|
|
- current: 1
|
|
|
- })
|
|
|
- const widthColumnCount = columns.filter(({ width }) => !width).length
|
|
|
- const mergedColumns = columns.map(column => {
|
|
|
- if (column.width) {
|
|
|
- return column
|
|
|
- }
|
|
|
-
|
|
|
- return { ...column, width: Math.floor(state.tableWidth / widthColumnCount) }
|
|
|
- })
|
|
|
- const gridRef = useRef()
|
|
|
- const [connectObject] = useState(() => {
|
|
|
- const obj = {}
|
|
|
- Object.defineProperty(obj, 'scrollLeft', {
|
|
|
- get: () => null,
|
|
|
- set: scrollLeft => {
|
|
|
- if (gridRef.current) {
|
|
|
- gridRef.current.scrollTo({
|
|
|
- scrollLeft
|
|
|
- })
|
|
|
- }
|
|
|
- }
|
|
|
- })
|
|
|
- return obj
|
|
|
- })
|
|
|
-
|
|
|
- const resetVirtualGrid = () => {
|
|
|
- gridRef.current?.resetAfterIndices({
|
|
|
- columnIndex: 0,
|
|
|
- shouldForceUpdate: true
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- useEffect(() => resetVirtualGrid, [state.tableWidth])
|
|
|
-
|
|
|
- const renderVirtualList = (rawData, { scrollbarSize, ref, onScroll }) => {
|
|
|
- // eslint-disable-next-line no-param-reassign
|
|
|
- ref.current = connectObject
|
|
|
- const totalHeight = rawData.length * 54
|
|
|
- return (
|
|
|
- <Grid
|
|
|
- ref={gridRef}
|
|
|
- className="virtual-grid"
|
|
|
- columnCount={mergedColumns.length}
|
|
|
- columnWidth={index => {
|
|
|
- const { width } = mergedColumns[index]
|
|
|
- return totalHeight > scroll.y && index === mergedColumns.length - 1
|
|
|
- ? width - scrollbarSize - 1
|
|
|
- : width
|
|
|
- }}
|
|
|
- height={scroll.y}
|
|
|
- rowCount={rawData.length}
|
|
|
- rowHeight={() => 54}
|
|
|
- width={state.tableWidth}
|
|
|
- onScroll={({ scrollLeft }) => {
|
|
|
- onScroll({
|
|
|
- scrollLeft
|
|
|
- })
|
|
|
- }}
|
|
|
- >
|
|
|
- {({ columnIndex, rowIndex, style }) => (
|
|
|
- <div
|
|
|
- className={classNames('virtual-table-cell', {
|
|
|
- 'virtual-table-cell-last': columnIndex === mergedColumns.length - 1
|
|
|
- })}
|
|
|
- style={style}
|
|
|
- >
|
|
|
- {rawData[rowIndex][mergedColumns[columnIndex].dataIndex]}
|
|
|
- </div>
|
|
|
- )}
|
|
|
- </Grid>
|
|
|
- )
|
|
|
- }
|
|
|
-
|
|
|
- return (
|
|
|
- <ResizeObserver
|
|
|
- onResize={({ width }) => {
|
|
|
- setState({ ...state, tableWidth: width })
|
|
|
- }}
|
|
|
- >
|
|
|
- <Table
|
|
|
- {...props}
|
|
|
- className="virtual-table"
|
|
|
- columns={mergedColumns}
|
|
|
- pagination={false}
|
|
|
- components={{
|
|
|
- body: renderVirtualList
|
|
|
- }}
|
|
|
- />
|
|
|
- </ResizeObserver>
|
|
|
- )
|
|
|
-} // Usage
|
|
|
-
|
|
|
-export default VirtualTable
|