react-table base on @tanstack/react-table and shadcn
A powerful and customizable React table component built on top of @tanstack/react-table, featuring sticky headers, columns, and advanced data table functionality.
``bash`
npm install @ginv/react-table @tanstack/react-tableor
yarn add @ginv/react-table @tanstack/react-tableor
pnpm add @ginv/react-table @tanstack/react-table
Follow these steps to implement a basic data table:
1. Wrap your table with TableProvider componentDataTableToolbar
2. Define columns with field configurations, sorting, and visibility options
3. Configure pagination with page size and total count
4. Add filtering using component
5. Enable row selection for batch operations
6. Configure scrolling with sticky headers and columns
`typescript
import type { ColumnPinningState, SortingState, VisibilityState } from '@tanstack/react-table'
import { TableCell, TableRow } from '@/components/ui/table'
import {
DataTablePagination,
DataTableToolbar,
getPinnedColumnCellClassName,
getPinnedColumnStyle,
TableProvider,
} from '@ginv/react-table'
interface ColumnMeta {
className?: string
tdClassName?: string
thClassName?: string
}
interface ScheduleTableProps {
data: ScheduleListResponse
loading?: boolean
}
export function ScheduleTable({ data, loading = false }: ScheduleTableProps) {
const { content, totalElements: total } = data
const { currentRow } = useSchedules()
// Configure row selection state based on current row
const rowSelection = useMemo(
() =>
currentRow !== null
? { [String(currentRow.id)]: true }
: {},
[currentRow],
)
const [sorting, setSorting] = useState
const [columnVisibility, setColumnVisibility] = useState
const [columnPinning] = useState
left: ['name'],
right: ['actions'],
})
// User options for filtering
const [userOptionsList, setUserOptionsList] = useState<{ label: string, value: number }[]>([])
// Manage URL query string state
const {
globalFilter,
onGlobalFilterChange,
columnFilters,
onColumnFiltersChange,
pagination,
onPaginationChange,
ensurePageInRange,
} = useTableUrlStateWithNuqs({
pagination: { defaultPage: 1, defaultPageSize: 10 },
globalFilter: { enabled: true, key: 'filter' },
columnFilters: [
{ columnId: 'type', searchKey: 'type', type: 'array' },
{ columnId: 'runState', searchKey: 'runState', type: 'array' },
{
columnId: 'commitBy',
searchKey: 'commitBy',
type: 'array',
},
],
})
// Calculate total page count (server-side pagination)
const pageCount = Math.ceil(total / pagination.pageSize)
const table = useReactTable({
data: content,
columns,
state: {
sorting,
columnVisibility,
rowSelection,
columnFilters,
globalFilter,
pagination,
columnPinning,
},
enableRowSelection: true,
onSortingChange: setSorting,
onColumnVisibilityChange: setColumnVisibility,
getCoreRowModel: getCoreRowModel(),
manualPagination: true,
manualFiltering: true,
pageCount,
getSortedRowModel: getSortedRowModel(),
getFacetedRowModel: getFacetedRowModel(),
onPaginationChange,
onGlobalFilterChange,
onColumnFiltersChange,
getRowId: row => String(row.id),
})
useEffect(() => {
ensurePageInRange(pageCount)
}, [pageCount, ensurePageInRange])
useEffect(() => {
const loadUserOptions = async () => {
try {
const options = await fetchUserOptions({ workspaceId: 1 })
setUserOptionsList(options)
}
catch (error) {
console.error('Failed to fetch user options:', error)
setUserOptionsList([])
}
}
loadUserOptions()
}, [])
return (
API Reference
$3
The main wrapper component for the data table.
Props:
| Prop | Type | Description |
|------|------|-------------|
|
table | Table | TanStack table instance |
| loading | boolean | Show loading state |
| renderWrapper | boolean | Wrap table with scroll area |
| scrollArea | object | Scroll area configuration |
| children | (row: Row | Render function for table rows |$3
Toolbar component with search and filter functionality.
Props:
| Prop | Type | Description |
|------|------|-------------|
|
table | Table | TanStack table instance |
| searchPlaceholder | string | Search input placeholder text |
| filters | FilterConfig[] | Array of filter configurations |$3
Pagination component with page size selector.
Props:
| Prop | Type | Description |
|------|------|-------------|
|
table | Table | TanStack table instance |
| className | string | Additional CSS classes |$3
-
getPinnedColumnStyle(pinned: ColumnPinningPosition): Returns inline styles for pinned columns
- getPinnedColumnCellClassName(pinned: ColumnPinningPosition)`: Returns className for pinned column cellsMIT
Contributions are welcome! Please feel free to submit a Pull Request.