Table Docs
Basic Examples
Feature Examples
- Kitchen Sink (All Features)
- Cell Spanning
- Column Filters
- Column Filters (Faceted)
- Bucketed Faceted Filters
- Fuzzy Search Filters
- Column Ordering
- Column Pinning
- Column Pinning (Split)
- Sticky Column Pinning
- Column Sizing
- Column Resizing
- Performant Column Resizing
- Column Visibility
- Expanding
- Expanding Sub Components
- Grouping
- Aggregation
- Grouped Aggregation
- Pagination
- Row Pinning
- Row Selection
- Sorting
Specialized Examples
Octane Example: Basic Use App Table
import { createRoot, useState } from 'octane'
import { createTableHook } from '@tanstack/octane-table'
import './index.css'
// This example uses the new `createTableHook` method to create a re-usable table hook factory instead of independently using the standalone `useTable` hook and `createColumnHelper` method. You can choose to use either way.
// 1. Define what the shape of your data will be for each row
type Person = {
firstName: string
lastName: string
age: number
visits: number
status: string
progress: number
}
// 2. Create some dummy data with a stable reference (this could be an API response stored in useState or similar)
const defaultData: Array<Person> = [
{ firstName: 'tanner', lastName: 'linsley', age: 24, visits: 100, status: 'In Relationship', progress: 50 },
{ firstName: 'tandy', lastName: 'miller', age: 40, visits: 40, status: 'Single', progress: 80 },
{ firstName: 'joe', lastName: 'dirte', age: 45, visits: 20, status: 'Complicated', progress: 10 },
{ firstName: 'kevin', lastName: 'vandy', age: 28, visits: 100, status: 'Single', progress: 70 },
]
function CellValue() @{
const cell = useCellContext()
<span data-registered-cell="true">{String(cell.renderValue())}</span>
}
function HeaderValue() @{
const header = useHeaderContext()
<span data-registered-header="true">{String(header.column.id)}</span>
}
// 3. New in V9! Tell the table which features and row models we want to use. In this case, this will be a basic table with no additional features
const {
useAppTable,
createAppColumnHelper,
useCellContext,
useHeaderContext,
} = createTableHook({
features: {},
debugTable: true,
cellComponents: { CellValue },
headerComponents: { HeaderValue },
})
// 4. Create a helper object to help define our columns
const columnHelper = createAppColumnHelper<Person>()
// 5. Define the columns for your table with a stable reference (in this case, defined statically outside of an Octane component)
const columns = columnHelper.columns([
columnHelper.accessor('firstName', { header: 'First Name', footer: (info) => info.column.id }),
columnHelper.accessor((row) => row.lastName, { id: 'lastName', header: 'Last Name', footer: (info) => info.column.id }),
columnHelper.accessor((row) => Number(row.age), { id: 'age', header: 'Age', footer: (info) => info.column.id }),
columnHelper.accessor('visits', { header: 'Visits', footer: (info) => info.column.id }),
columnHelper.accessor('status', { header: 'Status', footer: (info) => info.column.id }),
columnHelper.accessor('progress', { header: 'Profile Progress', footer: (info) => info.column.id }),
])
function App() @{
// 6. Store data with a stable reference
const [data] = useState(() => [...defaultData])
// 7. Create the table instance with the required columns and data.
// Features and row models are already defined in the createTableHook call above.
const table = useAppTable(
{
debugTable: true,
columns,
data,
// add additional table options here or in the createTableHook call above
},
(state) => state, // default selector
)
// 8. Render your table markup from the table instance APIs
<table.AppTable>
<div className="demo-root">
<table>
<thead>
@for (const headerGroup of table.getHeaderGroups(); key headerGroup.id) {
<tr>
@for (const header of headerGroup.headers; key header.id) {
<table.AppHeader header={header}>
{(appHeader) => <th>
{header.isPlaceholder ? null : <appHeader.FlexRender />}
<appHeader.HeaderValue />
</th>}
</table.AppHeader>
}
</tr>
}
</thead>
<tbody>
@for (const row of table.getRowModel().rows; key row.id) {
<tr>
@for (const cell of row.getAllCells(); key cell.id) {
<table.AppCell cell={cell}>
{(appCell) => <td>
<appCell.CellValue />
</td>}
</table.AppCell>
}
</tr>
}
</tbody>
<tfoot>
@for (const footerGroup of table.getFooterGroups(); key footerGroup.id) {
<tr>
@for (const header of footerGroup.headers; key header.id) {
<table.AppFooter header={header}>
{(appFooter) => <th><appFooter.FlexRender /></th>}
</table.AppFooter>
}
</tr>
}
</tfoot>
</table>
</div>
</table.AppTable>
}
const rootElement = document.getElementById('root')
if (!rootElement) throw new Error('Failed to find the root element')
createRoot(rootElement).render(App)