react-tablize
High performance virtual table and grid components for React.
Table
Table Examples
Terse syntax
const people: Person[];
<Table rowCount={people.length}>
<TableHead>
{['Name', 'Age']}
</TableHead>
<TableBody>
{index => ([
people[index].name,
people[index].age
])}
</TableBody>
</Table>
Rows and cells syntax
const people: Person[];
<Table rowCount={people.length}>
<TableHead>
<TableCell>
Name
</TableCell>
<TableCell>
Age
</TableCell>
</TableHead>
<TableBody>
{index => (
<TableRow>
<TableCell>
{people[index].name}
</TableCell>
<TableCell>
{people[index].age}
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
Mixed syntax
const people: Person[];
<Table rowCount={people.length}>
<TableHead>
{[
<TableCell key="name">
Name
</TableCell>,
'Age'
]}
</TableHead>
<TableBody>
{index => (
<TableRow>
{[
<TableCell key="name">
{people[index].name}
</TableCell>,
people[index].age
]}
</TableRow>
)}
</TableBody>
</Table>
Columns syntax
const people: Person[];
<Table rowCount={people.length}>
<TableColumn>
<ColumnHead>Name</ColumnHead>
<ColumnBody>
{({ rowIndex }) => people[rowIndex].name}
</ColumnBody>
</TableColumn>
<TableColumn>
<ColumnHead>Age</ColumnHead>
<ColumnBody>
{({ rowIndex }) => people[rowIndex].age}
</ColumnBody>
</TableColumn>
</Table>
Table Props
Name | Type | Default | Required | Description |
---|
rowCount | number | | yes | The number of rows in the table. |
rowHeight | number | (rowIndex: number) => number | 50 | no | Row height in pixels. |
rowKey | (rowIndex: number) => React.Key | | no | React key for each row. |
overscanCount | number | 20 | no | Number of rows to render ahead. |
dir | 'rtl' | 'ltr' | 'ltr' | no | |
className | string | | no | |
style | React.CSSProperties | | no | |
placeholder | React.ReactNode | | no | What to display when there are no items. |
Grid
Grid Examples
Simple Grid
<Grid
columnCount={1000}
rowCount={10}
columnWidth={100}
rowHeight={40}
>
{cellProps => (
`${cellProps.absRowIndex}, ${cellProps.absColIndex}`
)}
</Grid>
Fixed Head and Columns
<Grid
columnCount={1000}
rowCount={10}
columnWidth={100}
rowHeight={40}
fixedHeaderHeight={50}
fixedLeftWidth={100}
>
{cellProps => {
if (cellProps.tilePosition.horizontal === 'left') {
return (
<div style={{ color: 'green' }}>
{cellProps.absColIndex}
</div>
);
}
if (cellProps.tilePosition.vertical === 'header') {
return (
<div style={{ color: 'red' }}>
{cellProps.absColIndex}
</div>
);
}
return `${cellProps.absRowIndex}, ${cellProps.absColIndex}`;
}}
</Grid>
Variable Width and Height
<Grid
columnCount={1000}
rowCount={10}
columnWidth={columnIndex => columnIndex === 0 ? 50 : 100}
rowHeight={rowIndex => rowIndex === 0 ? 80 : 40}
>
{cellProps => (
`${cellProps.absRowIndex}, ${cellProps.absColIndex}`
)}
</Grid>
Grid Cell Render Props
interface RenderCellProps {
absColIndex: number;
absRowIndex: number;
relColIndex: number;
relRowIndex: number;
tileKey: TileKey;
tilePosition: TilePosition;
height: number;
width: number;
}
enum TileKey {
HeaderLeft,
HeaderCenter,
HeaderRight,
BodyLeft,
BodyCenter,
BodyRight,
FooterLeft,
FooterCenter,
FooterRight
}
interface TilePosition {
vertical: 'header' | 'body' | 'footer';
horizontal: 'left' | 'center' | 'right';
}
Prior art and motivation
Some parts of this library are inspired by, some are a modification of, and
some are a complete ripoff of these libraries:
Thank you!
If there are so many virtual scrolling libraries out there, why do I need another one?
Well, each of these libraries implements only part of what I personally needed
so I've created a library that combines the best of all:
Library | Grid component | Fixed rows and columns | RTL | Recycling |
---|
react-window | ✔ | ✖ | ✔ | ✖ |
sticky-table | ✔ | ✔ | ✖ | ✖ |
react-virtual-grid | ✔ | ✔ | ? | ✖ |
recyclerlistview | ✖ | ? | ? | ✔ |
react-tablize | ✔ | ✔ | ✔ | ✔ |
Changelog
The changelog can be found here.