docs-i18n 0.8.0 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/template/app/utils/content-loader.ts +4 -0
- package/template/app/utils/docs.server.ts +7 -0
- package/template/content/blog/en/announcing-query-v5.md +110 -0
- package/template/content/blog/en/hello-world.md +26 -0
- package/template/content/blog/en/i18n-best-practices.md +57 -0
- package/template/content/blog/en/react-query-vs-swr.md +100 -0
- package/template/content/blog/en/state-management-2024.md +143 -0
- package/template/content/blog/en/tanstack-router-1.0.md +121 -0
- package/template/content/blog/ja/announcing-query-v5.md +110 -0
- package/template/content/blog/ja/hello-world.md +26 -0
- package/template/content/blog/zh-hans/announcing-query-v5.md +93 -0
- package/template/content/blog/zh-hans/hello-world.md +26 -0
- package/template/content/docs-i18n/docs.config.json +25 -0
- package/template/content/docs-i18n/en/admin.md +143 -0
- package/template/content/docs-i18n/en/architecture.md +222 -0
- package/template/content/docs-i18n/en/cli.md +324 -0
- package/template/content/docs-i18n/en/configuration.md +331 -0
- package/template/content/docs-i18n/en/deployment.md +209 -0
- package/template/content/docs-i18n/en/getting-started.md +168 -0
- package/template/content/docs.config.json +25 -0
- package/template/content/en/admin.md +151 -0
- package/template/content/en/architecture.md +222 -0
- package/template/content/en/cli.md +269 -0
- package/template/content/en/configuration.md +331 -0
- package/template/content/en/deployment.md +209 -0
- package/template/content/en/getting-started.md +168 -0
- package/template/content/form/docs.config.json +18 -0
- package/template/content/form/en/guides/validation.md +175 -0
- package/template/content/form/en/installation.md +63 -0
- package/template/content/form/en/overview.md +71 -0
- package/template/content/form/en/quick-start.md +121 -0
- package/template/content/form/ja/installation.md +63 -0
- package/template/content/form/ja/overview.md +71 -0
- package/template/content/form/zh-hans/installation.md +63 -0
- package/template/content/form/zh-hans/overview.md +71 -0
- package/template/content/query/docs.config.json +32 -0
- package/template/content/query/en/guides/mutations.md +126 -0
- package/template/content/query/en/guides/pagination.md +98 -0
- package/template/content/query/en/guides/queries.md +120 -0
- package/template/content/query/en/installation.md +78 -0
- package/template/content/query/en/overview.md +72 -0
- package/template/content/query/en/quick-start.md +108 -0
- package/template/content/query/ja/installation.md +78 -0
- package/template/content/query/ja/overview.md +72 -0
- package/template/content/query/zh-hans/guides/mutations.md +126 -0
- package/template/content/query/zh-hans/guides/pagination.md +98 -0
- package/template/content/query/zh-hans/guides/queries.md +120 -0
- package/template/content/query/zh-hans/installation.md +95 -0
- package/template/content/query/zh-hans/overview.md +72 -0
- package/template/content/query/zh-hans/quick-start.md +108 -0
- package/template/content/router/docs.config.json +18 -0
- package/template/content/router/en/guides/routing-concepts.md +131 -0
- package/template/content/router/en/installation.md +57 -0
- package/template/content/router/en/overview.md +74 -0
- package/template/content/router/en/quick-start.md +88 -0
- package/template/content/router/ja/installation.md +57 -0
- package/template/content/router/ja/overview.md +78 -0
- package/template/content/router/zh-hans/guides/routing-concepts.md +131 -0
- package/template/content/router/zh-hans/installation.md +57 -0
- package/template/content/router/zh-hans/overview.md +81 -0
- package/template/content/router/zh-hans/quick-start.md +88 -0
- package/template/content/table/docs.config.json +18 -0
- package/template/content/table/en/guides/column-definitions.md +135 -0
- package/template/content/table/en/installation.md +56 -0
- package/template/content/table/en/overview.md +79 -0
- package/template/content/table/en/quick-start.md +112 -0
- package/template/content/table/ja/installation.md +56 -0
- package/template/content/table/ja/overview.md +79 -0
- package/template/content/table/zh-hans/installation.md +56 -0
- package/template/content/table/zh-hans/overview.md +79 -0
- package/template/content/virtual/docs.config.json +18 -0
- package/template/content/virtual/en/guides/dynamic-sizing.md +129 -0
- package/template/content/virtual/en/installation.md +57 -0
- package/template/content/virtual/en/overview.md +74 -0
- package/template/content/virtual/en/quick-start.md +114 -0
- package/template/content/virtual/ja/installation.md +57 -0
- package/template/content/virtual/ja/overview.md +74 -0
- package/template/content/virtual/zh-hans/installation.md +57 -0
- package/template/content/virtual/zh-hans/overview.md +74 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 路由概念
|
|
3
|
+
description: 了解 TanStack Router 的核心路由概念
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 路由概念
|
|
7
|
+
|
|
8
|
+
TanStack Router 建立在几个核心概念之上,使其功能强大且灵活。理解这些概念将帮助您构建更好的应用。
|
|
9
|
+
|
|
10
|
+
## 路由树
|
|
11
|
+
|
|
12
|
+
TanStack Router 使用路由树来定义应用的结构。路由可以嵌套以创建布局和层级结构:
|
|
13
|
+
|
|
14
|
+
```tsx
|
|
15
|
+
import { createRootRoute, createRoute, createRouter } from '@tanstack/react-router'
|
|
16
|
+
|
|
17
|
+
const rootRoute = createRootRoute({
|
|
18
|
+
component: RootLayout,
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
const indexRoute = createRoute({
|
|
22
|
+
getParentRoute: () => rootRoute,
|
|
23
|
+
path: '/',
|
|
24
|
+
component: HomePage,
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
const aboutRoute = createRoute({
|
|
28
|
+
getParentRoute: () => rootRoute,
|
|
29
|
+
path: '/about',
|
|
30
|
+
component: AboutPage,
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
const routeTree = rootRoute.addChildren([indexRoute, aboutRoute])
|
|
34
|
+
|
|
35
|
+
const router = createRouter({ routeTree })
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## 基于文件的路由
|
|
39
|
+
|
|
40
|
+
对于大多数应用,TanStack Router 通过插件支持基于文件的路由。您的文件结构即是路由结构:
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
app/
|
|
44
|
+
routes/
|
|
45
|
+
__root.tsx → 根布局
|
|
46
|
+
index.tsx → /
|
|
47
|
+
about.tsx → /about
|
|
48
|
+
posts.tsx → /posts(布局)
|
|
49
|
+
posts.index.tsx → /posts/
|
|
50
|
+
posts.$postId.tsx → /posts/:postId
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
> [!NOTE]
|
|
54
|
+
> 基于文件的路由由 `@tanstack/router-plugin` 包驱动,它在构建时自动生成路由树。
|
|
55
|
+
|
|
56
|
+
## 搜索参数
|
|
57
|
+
|
|
58
|
+
TanStack Router 将搜索参数视为一等公民,提供完整的类型安全:
|
|
59
|
+
|
|
60
|
+
```tsx
|
|
61
|
+
const productsRoute = createRoute({
|
|
62
|
+
getParentRoute: () => rootRoute,
|
|
63
|
+
path: '/products',
|
|
64
|
+
validateSearch: (search: Record<string, unknown>) => {
|
|
65
|
+
return {
|
|
66
|
+
page: Number(search.page) || 1,
|
|
67
|
+
filter: (search.filter as string) || '',
|
|
68
|
+
sort: (search.sort as 'asc' | 'desc') || 'asc',
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
component: ProductsPage,
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
function ProductsPage() {
|
|
75
|
+
const { page, filter, sort } = productsRoute.useSearch()
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<div>
|
|
79
|
+
<p>页码:{page},筛选:{filter},排序:{sort}</p>
|
|
80
|
+
</div>
|
|
81
|
+
)
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## 数据加载
|
|
86
|
+
|
|
87
|
+
路由可以定义在渲染前获取数据的加载器:
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
const postRoute = createRoute({
|
|
91
|
+
getParentRoute: () => postsRoute,
|
|
92
|
+
path: '$postId',
|
|
93
|
+
loader: async ({ params }) => {
|
|
94
|
+
const post = await fetchPost(params.postId)
|
|
95
|
+
return { post }
|
|
96
|
+
},
|
|
97
|
+
component: PostPage,
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
function PostPage() {
|
|
101
|
+
const { post } = postRoute.useLoaderData()
|
|
102
|
+
return <article>{post.title}</article>
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
| 功能 | 描述 |
|
|
107
|
+
|---|---|
|
|
108
|
+
| 路由树 | 具有父子关系的层级路由定义 |
|
|
109
|
+
| 基于文件的路由 | 从文件系统自动生成路由 |
|
|
110
|
+
| 搜索参数 | 带验证的类型安全 URL 搜索参数 |
|
|
111
|
+
| 数据加载 | 在路由渲染前预取数据 |
|
|
112
|
+
| 等待状态 | 导航期间的内置加载指示器 |
|
|
113
|
+
| 错误边界 | 按路由的错误处理 |
|
|
114
|
+
|
|
115
|
+
## 路径参数
|
|
116
|
+
|
|
117
|
+
路径中的动态段以 `$` 为前缀:
|
|
118
|
+
|
|
119
|
+
```tsx
|
|
120
|
+
// 单个参数
|
|
121
|
+
'/posts/$postId'
|
|
122
|
+
|
|
123
|
+
// 多个参数
|
|
124
|
+
'/users/$userId/posts/$postId'
|
|
125
|
+
|
|
126
|
+
// 通配符/全匹配
|
|
127
|
+
'/files/$'
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
> [!WARNING]
|
|
131
|
+
> 与其他路由器不同,TanStack Router 不使用 `:` 作为动态段前缀。始终使用 `$` 作为前缀。
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 安装
|
|
3
|
+
description: 如何在项目中安装 TanStack Router
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 安装
|
|
7
|
+
|
|
8
|
+
## 安装依赖包
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install @tanstack/react-router
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pnpm add @tanstack/react-router
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
yarn add @tanstack/react-router
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
bun add @tanstack/react-router
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Vite 插件(推荐)
|
|
27
|
+
|
|
28
|
+
为了获得最佳的基于文件路由和自动路由生成体验,请安装 Vite 插件:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install -D @tanstack/router-plugin
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
然后将其添加到 `vite.config.ts` 中:
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
import { defineConfig } from 'vite'
|
|
38
|
+
import react from '@vitejs/plugin-react'
|
|
39
|
+
import { TanStackRouterVite } from '@tanstack/router-plugin/vite'
|
|
40
|
+
|
|
41
|
+
export default defineConfig({
|
|
42
|
+
plugins: [TanStackRouterVite(), react()],
|
|
43
|
+
})
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## 开发工具
|
|
47
|
+
|
|
48
|
+
安装开发工具用于路由调试:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npm install @tanstack/router-devtools
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## 环境要求
|
|
55
|
+
|
|
56
|
+
- React 18+
|
|
57
|
+
- TypeScript 5.0+(强烈推荐)
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: TanStack Router 概述
|
|
3
|
+
description: 为 React 应用打造的类型安全路由库
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# TanStack Router
|
|
7
|
+
|
|
8
|
+
TanStack Router 是一个为 React 应用设计的全类型安全路由库。它将路由提升为一等公民,提供从导航到搜索参数的端到端类型安全。
|
|
9
|
+
|
|
10
|
+
## 为什么选择 TanStack Router?
|
|
11
|
+
|
|
12
|
+
传统的 React 路由库在类型安全方面存在不足。路由路径是字符串,参数是 `any` 类型,搜索参数完全未经验证。TanStack Router 从根本上解决了这些问题。
|
|
13
|
+
|
|
14
|
+
## 核心特性
|
|
15
|
+
|
|
16
|
+
- **100% 类型安全** — 链接、导航、参数和搜索参数都经过完整的类型检查
|
|
17
|
+
- **一等搜索参数** — URL 搜索参数经过验证和类型化,如同路径参数一样
|
|
18
|
+
- **内置数据加载** — 路由级别的数据预取,支持 stale-while-revalidate
|
|
19
|
+
- **文件路由** — 通过文件系统结构自动生成类型安全的路由树
|
|
20
|
+
- **嵌套布局** — 路由可嵌套以创建共享布局
|
|
21
|
+
- **代码分割** — 开箱即用的按路由代码分割
|
|
22
|
+
|
|
23
|
+
## 快速示例
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
import {
|
|
27
|
+
createRootRoute,
|
|
28
|
+
createRoute,
|
|
29
|
+
createRouter,
|
|
30
|
+
Link,
|
|
31
|
+
Outlet,
|
|
32
|
+
} from '@tanstack/react-router'
|
|
33
|
+
|
|
34
|
+
// 定义根路由
|
|
35
|
+
const rootRoute = createRootRoute({
|
|
36
|
+
component: () => (
|
|
37
|
+
<div>
|
|
38
|
+
<nav>
|
|
39
|
+
<Link to="/">首页</Link>
|
|
40
|
+
<Link to="/about">关于</Link>
|
|
41
|
+
</nav>
|
|
42
|
+
<Outlet />
|
|
43
|
+
</div>
|
|
44
|
+
),
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
// 定义子路由
|
|
48
|
+
const indexRoute = createRoute({
|
|
49
|
+
getParentRoute: () => rootRoute,
|
|
50
|
+
path: '/',
|
|
51
|
+
component: () => <h1>欢迎来到首页</h1>,
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
const aboutRoute = createRoute({
|
|
55
|
+
getParentRoute: () => rootRoute,
|
|
56
|
+
path: '/about',
|
|
57
|
+
component: () => <h1>关于我们</h1>,
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
// 构建路由树
|
|
61
|
+
const routeTree = rootRoute.addChildren([indexRoute, aboutRoute])
|
|
62
|
+
const router = createRouter({ routeTree })
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## 与 TanStack Query 配合使用
|
|
66
|
+
|
|
67
|
+
TanStack Router 与 TanStack Query 完美配合。在路由的 `loader` 中使用 Query 来预取数据:
|
|
68
|
+
|
|
69
|
+
```tsx
|
|
70
|
+
const userRoute = createRoute({
|
|
71
|
+
path: '/users/$userId',
|
|
72
|
+
loader: ({ params, context }) =>
|
|
73
|
+
context.queryClient.ensureQueryData({
|
|
74
|
+
queryKey: ['user', params.userId],
|
|
75
|
+
queryFn: () => fetchUser(params.userId),
|
|
76
|
+
}),
|
|
77
|
+
})
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
> [!NOTE]
|
|
81
|
+
> TanStack Router 可以独立使用,也可以与 TanStack Start 结合使用以获得完整的全栈框架体验。
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 快速开始
|
|
3
|
+
description: 几分钟内上手 TanStack Router
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 快速开始
|
|
7
|
+
|
|
8
|
+
## 基于文件的路由
|
|
9
|
+
|
|
10
|
+
最简单的入门方式是使用基于文件的路由。创建您的路由目录:
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
src/
|
|
14
|
+
routes/
|
|
15
|
+
__root.tsx
|
|
16
|
+
index.tsx
|
|
17
|
+
about.tsx
|
|
18
|
+
posts/
|
|
19
|
+
index.tsx
|
|
20
|
+
$postId.tsx
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### 根路由
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
// src/routes/__root.tsx
|
|
27
|
+
import { createRootRoute, Link, Outlet } from '@tanstack/react-router'
|
|
28
|
+
|
|
29
|
+
export const Route = createRootRoute({
|
|
30
|
+
component: () => (
|
|
31
|
+
<>
|
|
32
|
+
<nav>
|
|
33
|
+
<Link to="/">首页</Link>
|
|
34
|
+
<Link to="/about">关于</Link>
|
|
35
|
+
<Link to="/posts">文章</Link>
|
|
36
|
+
</nav>
|
|
37
|
+
<Outlet />
|
|
38
|
+
</>
|
|
39
|
+
),
|
|
40
|
+
})
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 索引路由
|
|
44
|
+
|
|
45
|
+
```tsx
|
|
46
|
+
// src/routes/index.tsx
|
|
47
|
+
import { createFileRoute } from '@tanstack/react-router'
|
|
48
|
+
|
|
49
|
+
export const Route = createFileRoute('/')({
|
|
50
|
+
component: () => <div>欢迎回来!</div>,
|
|
51
|
+
})
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 动态路由
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
// src/routes/posts/$postId.tsx
|
|
58
|
+
import { createFileRoute } from '@tanstack/react-router'
|
|
59
|
+
|
|
60
|
+
export const Route = createFileRoute('/posts/$postId')({
|
|
61
|
+
loader: async ({ params }) => {
|
|
62
|
+
return fetchPost(params.postId)
|
|
63
|
+
},
|
|
64
|
+
component: PostPage,
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
function PostPage() {
|
|
68
|
+
const post = Route.useLoaderData()
|
|
69
|
+
return <div>{post.title}</div>
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## 数据加载
|
|
74
|
+
|
|
75
|
+
TanStack Router 支持带缓存的路由级数据加载:
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
export const Route = createFileRoute('/posts')({
|
|
79
|
+
loader: async () => {
|
|
80
|
+
const posts = await fetch('/api/posts').then((r) => r.json())
|
|
81
|
+
return { posts }
|
|
82
|
+
},
|
|
83
|
+
component: PostsPage,
|
|
84
|
+
})
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
> [!NOTE]
|
|
88
|
+
> 嵌套路由的路由加载器会并行运行,确保最快的数据加载速度。
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"sections": [
|
|
3
|
+
{
|
|
4
|
+
"label": "Getting Started",
|
|
5
|
+
"children": [
|
|
6
|
+
{ "label": "Overview", "to": "overview" },
|
|
7
|
+
{ "label": "Installation", "to": "installation" },
|
|
8
|
+
{ "label": "Quick Start", "to": "quick-start" }
|
|
9
|
+
]
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"label": "Guides",
|
|
13
|
+
"children": [
|
|
14
|
+
{ "label": "Column Definitions", "to": "guides/column-definitions" }
|
|
15
|
+
]
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Column Definitions
|
|
3
|
+
description: Learn how to define and configure columns in TanStack Table
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Column Definitions
|
|
7
|
+
|
|
8
|
+
Column definitions are the single most important part of building a table. They are responsible for defining the data model, how data is displayed, and what features each column supports.
|
|
9
|
+
|
|
10
|
+
## Column Definition Types
|
|
11
|
+
|
|
12
|
+
TanStack Table supports three types of column definitions:
|
|
13
|
+
|
|
14
|
+
| Type | Purpose | Has data accessor? |
|
|
15
|
+
|---|---|---|
|
|
16
|
+
| **Accessor Columns** | Display data from your data model | Yes |
|
|
17
|
+
| **Display Columns** | Render arbitrary UI (e.g., action buttons) | No |
|
|
18
|
+
| **Group Columns** | Group other columns under a shared header | No |
|
|
19
|
+
|
|
20
|
+
## Accessor Columns
|
|
21
|
+
|
|
22
|
+
Accessor columns are the most common type. They map directly to a field in your data:
|
|
23
|
+
|
|
24
|
+
```tsx
|
|
25
|
+
import { createColumnHelper } from '@tanstack/react-table'
|
|
26
|
+
|
|
27
|
+
type Person = {
|
|
28
|
+
firstName: string
|
|
29
|
+
lastName: string
|
|
30
|
+
age: number
|
|
31
|
+
email: string
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const columnHelper = createColumnHelper<Person>()
|
|
35
|
+
|
|
36
|
+
const columns = [
|
|
37
|
+
columnHelper.accessor('firstName', {
|
|
38
|
+
header: 'First Name',
|
|
39
|
+
cell: (info) => info.getValue(),
|
|
40
|
+
}),
|
|
41
|
+
columnHelper.accessor('lastName', {
|
|
42
|
+
header: 'Last Name',
|
|
43
|
+
}),
|
|
44
|
+
columnHelper.accessor('age', {
|
|
45
|
+
header: 'Age',
|
|
46
|
+
cell: (info) => <span className="font-mono">{info.getValue()}</span>,
|
|
47
|
+
}),
|
|
48
|
+
columnHelper.accessor('email', {
|
|
49
|
+
header: 'Email',
|
|
50
|
+
cell: (info) => (
|
|
51
|
+
<a href={`mailto:${info.getValue()}`} className="text-blue-600 underline">
|
|
52
|
+
{info.getValue()}
|
|
53
|
+
</a>
|
|
54
|
+
),
|
|
55
|
+
}),
|
|
56
|
+
]
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Display Columns
|
|
60
|
+
|
|
61
|
+
Display columns do not have a data accessor and are useful for rendering UI elements like action buttons or row selection checkboxes:
|
|
62
|
+
|
|
63
|
+
```tsx
|
|
64
|
+
const columns = [
|
|
65
|
+
columnHelper.display({
|
|
66
|
+
id: 'select',
|
|
67
|
+
header: ({ table }) => (
|
|
68
|
+
<input
|
|
69
|
+
type="checkbox"
|
|
70
|
+
checked={table.getIsAllRowsSelected()}
|
|
71
|
+
onChange={table.getToggleAllRowsSelectedHandler()}
|
|
72
|
+
/>
|
|
73
|
+
),
|
|
74
|
+
cell: ({ row }) => (
|
|
75
|
+
<input
|
|
76
|
+
type="checkbox"
|
|
77
|
+
checked={row.getIsSelected()}
|
|
78
|
+
onChange={row.getToggleSelectedHandler()}
|
|
79
|
+
/>
|
|
80
|
+
),
|
|
81
|
+
}),
|
|
82
|
+
// ... accessor columns
|
|
83
|
+
columnHelper.display({
|
|
84
|
+
id: 'actions',
|
|
85
|
+
header: 'Actions',
|
|
86
|
+
cell: ({ row }) => (
|
|
87
|
+
<button onClick={() => handleEdit(row.original)}>Edit</button>
|
|
88
|
+
),
|
|
89
|
+
}),
|
|
90
|
+
]
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Column Sizing
|
|
94
|
+
|
|
95
|
+
You can control column widths through the column definition:
|
|
96
|
+
|
|
97
|
+
```tsx
|
|
98
|
+
columnHelper.accessor('firstName', {
|
|
99
|
+
header: 'First Name',
|
|
100
|
+
size: 200, // default column size
|
|
101
|
+
minSize: 100, // minimum column size
|
|
102
|
+
maxSize: 300, // maximum column size
|
|
103
|
+
})
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
> [!NOTE]
|
|
107
|
+
> Column sizes are specified in pixels. The table will attempt to respect these sizes but may adjust them based on available space and other column constraints.
|
|
108
|
+
|
|
109
|
+
## Header Groups
|
|
110
|
+
|
|
111
|
+
Group columns allow you to create multi-level headers:
|
|
112
|
+
|
|
113
|
+
```tsx
|
|
114
|
+
const columns = [
|
|
115
|
+
columnHelper.group({
|
|
116
|
+
id: 'name',
|
|
117
|
+
header: 'Name',
|
|
118
|
+
columns: [
|
|
119
|
+
columnHelper.accessor('firstName', { header: 'First' }),
|
|
120
|
+
columnHelper.accessor('lastName', { header: 'Last' }),
|
|
121
|
+
],
|
|
122
|
+
}),
|
|
123
|
+
columnHelper.group({
|
|
124
|
+
id: 'info',
|
|
125
|
+
header: 'Info',
|
|
126
|
+
columns: [
|
|
127
|
+
columnHelper.accessor('age', { header: 'Age' }),
|
|
128
|
+
columnHelper.accessor('email', { header: 'Email' }),
|
|
129
|
+
],
|
|
130
|
+
}),
|
|
131
|
+
]
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
> [!WARNING]
|
|
135
|
+
> When using group columns, make sure each group has a unique `id`. The `id` is required because group columns do not have an accessor to derive an ID from.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Installation
|
|
3
|
+
description: How to install TanStack Table in your project
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Installation
|
|
7
|
+
|
|
8
|
+
## React
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install @tanstack/react-table
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pnpm add @tanstack/react-table
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
yarn add @tanstack/react-table
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
bun add @tanstack/react-table
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Vue
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install @tanstack/vue-table
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Solid
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install @tanstack/solid-table
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Svelte
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm install @tanstack/svelte-table
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Requirements
|
|
45
|
+
|
|
46
|
+
- TypeScript 4.7+ (recommended)
|
|
47
|
+
- React 18+ / Vue 3+ / Solid 1.6+ / Svelte 4+
|
|
48
|
+
|
|
49
|
+
## Adapter Pattern
|
|
50
|
+
|
|
51
|
+
TanStack Table uses an adapter pattern. The core logic lives in `@tanstack/table-core`, while framework-specific packages provide thin wrappers:
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
// The core is included automatically — you don't need to install it separately
|
|
55
|
+
import { getCoreRowModel } from '@tanstack/react-table'
|
|
56
|
+
```
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: TanStack Table Overview
|
|
3
|
+
description: Headless UI for building powerful tables and datagrids
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# TanStack Table
|
|
7
|
+
|
|
8
|
+
TanStack Table is a headless UI library for building powerful tables and datagrids for TS/JS, React, Vue, Solid, and Svelte.
|
|
9
|
+
|
|
10
|
+
## What is "Headless" UI?
|
|
11
|
+
|
|
12
|
+
Headless UI is a term for libraries and utilities that provide the logic, state, processing, and API for UI elements and interactions, but do not provide markup, styles, or pre-built implementations.
|
|
13
|
+
|
|
14
|
+
## Features
|
|
15
|
+
|
|
16
|
+
- **Framework Agnostic** — Core logic works with React, Vue, Solid, Svelte, and vanilla JS
|
|
17
|
+
- **Sorting** — Multi-column sorting with customizable sort functions
|
|
18
|
+
- **Filtering** — Column and global filtering with custom filter functions
|
|
19
|
+
- **Pagination** — Client-side and server-side pagination
|
|
20
|
+
- **Row Selection** — Single and multi-row selection
|
|
21
|
+
- **Column Ordering & Pinning** — Reorder and pin columns
|
|
22
|
+
- **Column Sizing** — Resizable columns
|
|
23
|
+
- **Virtualization** — Virtual scrolling for large datasets (via TanStack Virtual)
|
|
24
|
+
- **Grouping & Aggregation** — Group rows and aggregate data
|
|
25
|
+
|
|
26
|
+
## Basic Example
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
import { createColumnHelper, useReactTable, getCoreRowModel } from '@tanstack/react-table'
|
|
30
|
+
|
|
31
|
+
type Person = {
|
|
32
|
+
firstName: string
|
|
33
|
+
lastName: string
|
|
34
|
+
age: number
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const columnHelper = createColumnHelper<Person>()
|
|
38
|
+
|
|
39
|
+
const columns = [
|
|
40
|
+
columnHelper.accessor('firstName', { header: 'First Name' }),
|
|
41
|
+
columnHelper.accessor('lastName', { header: 'Last Name' }),
|
|
42
|
+
columnHelper.accessor('age', { header: 'Age' }),
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
function MyTable({ data }: { data: Person[] }) {
|
|
46
|
+
const table = useReactTable({
|
|
47
|
+
data,
|
|
48
|
+
columns,
|
|
49
|
+
getCoreRowModel: getCoreRowModel(),
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
<table>
|
|
54
|
+
<thead>
|
|
55
|
+
{table.getHeaderGroups().map((headerGroup) => (
|
|
56
|
+
<tr key={headerGroup.id}>
|
|
57
|
+
{headerGroup.headers.map((header) => (
|
|
58
|
+
<th key={header.id}>
|
|
59
|
+
{flexRender(header.column.columnDef.header, header.getContext())}
|
|
60
|
+
</th>
|
|
61
|
+
))}
|
|
62
|
+
</tr>
|
|
63
|
+
))}
|
|
64
|
+
</thead>
|
|
65
|
+
<tbody>
|
|
66
|
+
{table.getRowModel().rows.map((row) => (
|
|
67
|
+
<tr key={row.id}>
|
|
68
|
+
{row.getVisibleCells().map((cell) => (
|
|
69
|
+
<td key={cell.id}>
|
|
70
|
+
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
|
71
|
+
</td>
|
|
72
|
+
))}
|
|
73
|
+
</tr>
|
|
74
|
+
))}
|
|
75
|
+
</tbody>
|
|
76
|
+
</table>
|
|
77
|
+
)
|
|
78
|
+
}
|
|
79
|
+
```
|