A high-performance virtual scrolling table component for React, supporting Pivot Table, Group Table, and Detail Table modes. Capable of handling large datasets efficiently using `react-window`.
npm install @yester/virtual-tableA high-performance virtual scrolling table component for React, supporting Pivot Table, Group Table, and Detail Table modes. Capable of handling large datasets efficiently using react-window.
- š High Performance: Renders thousands of rows smoothly using virtual scrolling.
- š Pivot Table: Supports multi-dimensional data analysis with row/column grouping and aggregation.
- š Group Table: Supports row grouping with expandable/collapsible rows.
- š Detail Table: Standard list view for detailed data.
- š Sortable: Supports sorting on multiple fields.
- šØ Customizable: Flexible styling and cell rendering.
- š¦ Lightweight: No heavy dependencies (lodash removed, icons extracted).
``bash`
pnpm add virtual-tableor
npm install virtual-tableor
yarn add virtual-table
`tsx
import React from 'react';
import { VirtualTable } from 'virtual-table';
import 'virtual-table/dist/style.css'; // Import styles
const App = () => {
const data = [
{ province: 'Zhejiang', city: 'Hangzhou', type: 'Furniture', amount: 10 },
// ... more data
];
const params = {
data,
meta: [],
sortParams: [],
fields: {
rows: [{ field: 'province', title: 'Province', width: 150 }],
columns: [{ field: 'type', title: 'Type', width: 120 }],
values: [{ field: 'amount', title: 'Amount', calculateType: 'sum', width: 100 }]
}
};
return (
Modes
$3
Configure rows, columns, and values in fields.`tsx
const pivotFields = {
rows: [
{ field: 'province', title: 'Province', width: 120, total: { enabled: true, label: 'Total' } },
{ field: 'city', title: 'City', width: 120 }
],
columns: [
{ field: 'type', title: 'Type', width: 120 }
],
values: [
{ field: 'amount', title: 'Amount', calculateType: 'sum', width: 100 }
]
};
`$3
Configure rows and values, leave columns empty.`tsx
const groupFields = {
rows: [
{ field: 'province', title: 'Province', width: 120 },
{ field: 'city', title: 'City', width: 120 }
],
columns: [],
values: [
{ field: 'amount', title: 'Amount', calculateType: 'sum', width: 100 }
]
};
`$3
Configure only values as a flat list of columns.`tsx
const detailFields = {
rows: [],
columns: [],
values: [
{ field: 'province', title: 'Province', width: 120 },
{ field: 'city', title: 'City', width: 120 },
{ field: 'amount', title: 'Amount', width: 100 }
]
};
`API
$3
| Property | Type | Description |
|Data |
any[] | Source data array |
| fields | PivotFields | Configuration for rows, columns, and values |
| meta | any[] | Meta information (optional) |
| sortParams | SortParam[] | Sorting configuration |
| scroll | { x?: number \| string; y?: number \| string } | Scroll configuration. y is required for virtual scrolling height |
| className | string | Custom CSS class |
| style | React.CSSProperties | Custom styles |$3
`typescript
interface PivotFields {
rows: DimensionNode[]; // Row dimensions
columns: DimensionNode[]; // Column dimensions
values: MetricNode[]; // Value fields (metrics)
}
`$3
#### DimensionNode (Rows & Columns)
| Property | Type | Description |
|----------|------|-------------|
|
field | string | Data field key |
| title | string | Column header title |
| width | number \| string | Column width |
| total | { enabled: boolean; label?: string } | Subtotal configuration |
| collapsed | boolean | Whether the dimension is collapsed by default |
| sort | { enabled: boolean; type: 'asc' \| 'desc' } | Sort configuration |#### MetricNode (Values)
| Property | Type | Description |
|----------|------|-------------|
|
field | string | Data field key or unique key for expression |
| title | string | Header title |
| width | number \| string | Column width |
| calculateType | 'sum' \| 'avg' \| 'count' \| 'min' \| 'max' \| 'd_count' \| 'expr' | Aggregation type |
| expression | string | Expression for calculation (e.g. '{amount} * {price}') |
| formatter | (val: any, record: any) => ReactNode | Cell content formatter |
| emptyReplace | string | Replacement for empty values |
| hidden | boolean | Whether to hide this metric column |Advanced Usage
$3
You can define a new metric based on other metrics using
calculateType: 'expr' and expression. Variables in {} refer to other metric fields.`tsx
values: [
{ field: 'amount', title: 'Amount', calculateType: 'sum' },
{ field: 'price', title: 'Price', calculateType: 'avg' },
{
field: 'total_value',
title: 'Total Value',
calculateType: 'expr',
expression: '{amount} * {price}'
}
]
`$3
Use
formatter to customize cell rendering, such as adding currency symbols or returning React components.`tsx
values: [
{
field: 'price',
title: 'Price',
formatter: (val) => Ā„{val}
}
]
`$3
Simply add multiple dimensions to
columns in PivotFields to create nested headers.`tsx
columns: [
{ field: 'year', title: 'Year', width: 100 }, // Top level
{ field: 'quarter', title: 'Quarter', width: 100 } // Sub level
]
`$3
Set
collapsed: true on a row dimension to collapse it by default.`tsx
rows: [
{ field: 'province', title: 'Province', collapsed: true }
]
`Development
`bash
Install dependencies
pnpm installRun dev server
pnpm devBuild library
pnpm buildRun tests
pnpm testRelease (Test -> Build -> Publish)
pnpm release
``MIT