Skip to content

Commit d4ec83c

Browse files
committed
docs: rewrite overview section
1 parent 0e56a4d commit d4ec83c

4 files changed

Lines changed: 546 additions & 86 deletions

File tree

docs/config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@
7474
{
7575
"label": "vanilla",
7676
"children": [
77-
{ "label": "Vanilla JS (No Framework)", "to": "vanilla" }
77+
{ "label": "Quick Start", "to": "framework/vanilla/quick-start" }
7878
]
7979
}
8080
]
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
---
2+
title: Quick Start
3+
---
4+
5+
TanStack Table is a headless table library. It manages your table's state and logic (sorting, filtering, pagination, selection, and more) while you keep 100% control over the markup and styles. The `@tanstack/table-core` package gives you the framework-agnostic core directly, so you provide the rendering and subscribe to table state changes yourself. This page gets you from install to a rendering vanilla table, then shows how to layer on your first feature.
6+
7+
## Installation
8+
9+
TanStack Table v9 is currently published under the `beta` tag:
10+
11+
```bash
12+
npm install @tanstack/table-core@beta
13+
```
14+
15+
## Your First Table
16+
17+
The TypeScript module below is complete. Use it with an HTML page that contains `<div id="app"></div>` and you will see a working table.
18+
19+
```ts
20+
import {
21+
constructTable,
22+
tableFeatures,
23+
type ColumnDef,
24+
} from '@tanstack/table-core'
25+
import { FlexRender } from '@tanstack/table-core/flex-render'
26+
import { storeReactivityBindings } from '@tanstack/table-core/store-reactivity-bindings'
27+
28+
// 1. Define the shape of your data
29+
type Person = {
30+
firstName: string
31+
lastName: string
32+
age: number
33+
}
34+
35+
// 2. Give your data a stable reference
36+
const data: Array<Person> = [
37+
{ firstName: 'tanner', lastName: 'linsley', age: 24 },
38+
{ firstName: 'tandy', lastName: 'miller', age: 40 },
39+
{ firstName: 'joe', lastName: 'dirte', age: 45 },
40+
]
41+
42+
// 3. New in v9: declare which features this table uses
43+
const features = tableFeatures({
44+
coreReactivityFeature: storeReactivityBindings(),
45+
})
46+
47+
// 4. Define your columns. Renderers return values or HTML strings.
48+
const columns: Array<ColumnDef<typeof features, Person>> = [
49+
{
50+
accessorKey: 'firstName', // accessorKey shorthand
51+
header: 'First Name',
52+
cell: (info) => info.getValue(),
53+
},
54+
{
55+
accessorFn: (row) => row.lastName, // accessorFn alternative with a custom id
56+
id: 'lastName',
57+
header: () => '<span>Last Name</span>',
58+
cell: (info) => `<i>${info.getValue<string>()}</i>`,
59+
},
60+
{
61+
accessorKey: 'age',
62+
header: () => 'Age',
63+
},
64+
]
65+
66+
// 5. Create the table instance
67+
const table = constructTable({
68+
features,
69+
columns,
70+
data,
71+
})
72+
73+
const app = document.getElementById('app')
74+
75+
if (!app) {
76+
throw new Error('Missing #app element')
77+
}
78+
79+
// 6. Render markup from the table instance APIs
80+
const renderTable = () => {
81+
const tableElement = document.createElement('table')
82+
const thead = document.createElement('thead')
83+
const tbody = document.createElement('tbody')
84+
85+
table.getHeaderGroups().forEach((headerGroup) => {
86+
const tr = document.createElement('tr')
87+
88+
headerGroup.headers.forEach((header) => {
89+
const th = document.createElement('th')
90+
th.innerHTML = header.isPlaceholder
91+
? ''
92+
: String(FlexRender({ header }) ?? '')
93+
tr.appendChild(th)
94+
})
95+
96+
thead.appendChild(tr)
97+
})
98+
99+
table.getRowModel().rows.forEach((row) => {
100+
const tr = document.createElement('tr')
101+
102+
row.getAllCells().forEach((cell) => {
103+
const td = document.createElement('td')
104+
td.innerHTML = String(FlexRender({ cell }) ?? '')
105+
tr.appendChild(td)
106+
})
107+
108+
tbody.appendChild(tr)
109+
})
110+
111+
tableElement.appendChild(thead)
112+
tableElement.appendChild(tbody)
113+
114+
app.replaceChildren(tableElement)
115+
}
116+
117+
table.store.subscribe(() => renderTable())
118+
renderTable()
119+
```
120+
121+
A few things to note:
122+
123+
- `tableFeatures({...})` declares which optional features the table uses. Registering only what you need keeps bundles small and gives TypeScript accurate types for the table instance.
124+
- The core row model is always included automatically. Feature row models (sorting, filtering, pagination) are registered as slots directly on the `tableFeatures({...})` call when you need them.
125+
- Vanilla usage must provide `coreReactivityFeature: storeReactivityBindings()` because there is no framework adapter to wire the core TanStack Store atoms into a rendering system for you.
126+
- `FlexRender` renders the `header`, `cell`, and `footer` definitions from your columns. In vanilla usage, renderers commonly return strings or HTML strings that you place into the DOM.
127+
- Subscribe to `table.store` when your UI should redraw after table state changes.
128+
129+
See the full [Basic example](./examples/basic) for a runnable version with more columns and a footer.
130+
131+
## Add a Feature: Sorting
132+
133+
Features are opt-in in v9. To make columns sortable, register `rowSortingFeature` and the `sortedRowModel` factory in `tableFeatures`, then wire the header click handler.
134+
135+
```ts
136+
import {
137+
constructTable,
138+
createSortedRowModel,
139+
rowSortingFeature,
140+
sortFns,
141+
tableFeatures,
142+
} from '@tanstack/table-core'
143+
import { storeReactivityBindings } from '@tanstack/table-core/store-reactivity-bindings'
144+
145+
const features = tableFeatures({
146+
coreReactivityFeature: storeReactivityBindings(),
147+
rowSortingFeature, // enables sorting APIs and state
148+
sortedRowModel: createSortedRowModel(), // client-side sorting
149+
sortFns,
150+
})
151+
152+
// columns and data unchanged from above
153+
154+
const table = constructTable({
155+
features,
156+
columns,
157+
data,
158+
})
159+
```
160+
161+
```ts
162+
// In renderTable, replace the header rendering with sortable header markup.
163+
table.getHeaderGroups().forEach((headerGroup) => {
164+
const tr = document.createElement('tr')
165+
166+
headerGroup.headers.forEach((header) => {
167+
const th = document.createElement('th')
168+
const button = document.createElement('button')
169+
170+
button.type = 'button'
171+
button.disabled = !header.column.getCanSort()
172+
button.innerHTML = header.isPlaceholder
173+
? ''
174+
: String(FlexRender({ header }) ?? '')
175+
button.innerHTML +=
176+
{
177+
asc: ' 🔼',
178+
desc: ' 🔽',
179+
}[header.column.getIsSorted() as string] ?? ''
180+
button.addEventListener('click', (event) => {
181+
header.column.getToggleSortingHandler()?.(event)
182+
})
183+
184+
th.appendChild(button)
185+
tr.appendChild(th)
186+
})
187+
188+
thead.appendChild(tr)
189+
})
190+
```
191+
192+
Clicking a header now toggles between ascending, descending, and unsorted. Every other feature follows this same pattern: register the feature and its row model factory (if it has one) in `tableFeatures`, then use the APIs it adds to the table, columns, and rows. See the [Sorting example](./examples/sorting) for custom sort functions, multi-sorting, and per-column options.
193+
194+
## Where to Go Next
195+
196+
**Table state.** In v9, table state is backed by TanStack Store atoms. When you use `@tanstack/table-core` directly, you decide when to read state, subscribe to state, and redraw your UI. You usually do not need to manage state yourself: set `initialState` for starting values and call feature APIs like `table.setSorting(...)` or `table.nextPage()`. When your app should own a state slice, or you want fine-grained subscriptions, read the [Table State Guide](./guide/table-state). It is the foundational guide for vanilla usage.
197+
198+
**Feature examples.** Browse runnable vanilla examples such as [Pagination](./examples/pagination) and [Sorting](./examples/sorting) to see complete DOM rendering setups.
199+
200+
**Core guides.** The framework-agnostic guides cover the main table objects: [Data](../../guide/data), [Column Definitions](../../guide/column-defs), [Table Instance](../../guide/tables), [Rows](../../guide/rows), [Cells](../../guide/cells), and [Header Groups](../../guide/header-groups).

0 commit comments

Comments
 (0)