.cursor/skills/data-table/SKILL.md
Build data tables with filtering, sorting, pagination, and URL state management using diceui DataTable components. Use when creating admin tables, list views, or any data-heavy UI that needs server-side pagination and filtering.
npx skillsauth add jiahao-jayden/vibe-any-tanstack data-tableInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
基于 diceui/data-table 的数据表格组件,已集成 nuqs URL 状态管理和 TanStack Router。
@/shared/components/common/data-table/ # 组件目录
@/shared/components/common/data-table/data-table-config.ts # 配置
@/shared/hooks/use-data-table.ts # hook
@/shared/types/data-table.ts # 类型
@/shared/lib/data-table.ts # 工具函数
@/shared/lib/parsers.ts # URL 解析器
import { DataTable, DataTableToolbar, DataTableSkeleton, DataTableColumnHeader } from "@/shared/components/common/data-table"
import { useDataTable } from "@/shared/hooks/use-data-table"
import { parseAsInteger, parseAsString, useQueryState } from "nuqs"
function MyTablePage() {
// 1. URL 状态管理(参数名需与 useDataTable 默认 queryKeys 一致:page, perPage, sort, 以及列 id 作为 filter 键)
const [page] = useQueryState("page", parseAsInteger.withDefault(1))
const [perPage] = useQueryState("perPage", parseAsInteger.withDefault(10))
const [name] = useQueryState("name", parseAsString) // 列 id 为 "name" 时,filter 键为 "name"
// 2. 数据获取
const { data, isLoading } = useQuery({
queryKey: ["items", page, perPage, name],
queryFn: () => fetchItems({ page, perPage, search: name }),
})
// 3. 定义列
const columns: ColumnDef<Item>[] = useMemo(() => [
{
id: "name",
accessorKey: "name",
header: ({ column }) => <DataTableColumnHeader column={column} label="Name" />,
cell: ({ row }) => row.original.name,
meta: {
label: "Name",
placeholder: "Search...",
variant: "text",
},
enableColumnFilter: true,
},
], [])
// 4. 初始化表格
const { table } = useDataTable({
data: data?.items ?? [],
columns,
pageCount: data?.totalPages ?? -1,
initialState: {
sorting: [{ id: "createdAt", desc: true }],
pagination: { pageIndex: 0, pageSize: 10 },
},
getRowId: (row) => row.id,
})
// 5. 渲染
if (isLoading) {
return <DataTableSkeleton columnCount={5} rowCount={10} filterCount={2} />
}
return (
<DataTable table={table}>
<DataTableToolbar table={table} />
</DataTable>
)
}
| Variant | 用途 | meta 配置 |
|---------|------|-----------|
| text | 文本搜索 | placeholder |
| number | 数字过滤 | unit |
| range | 范围滑块 | range: [min, max] |
| date | 日期选择 | - |
| dateRange | 日期范围 | - |
| select | 单选下拉 | options |
| multiSelect | 多选下拉 | options |
// 文本过滤
{
id: "name",
accessorKey: "name",
header: ({ column }) => <DataTableColumnHeader column={column} label="Name" />,
meta: { label: "Name", variant: "text", placeholder: "Search...", icon: User },
enableColumnFilter: true,
}
// 选择过滤
{
id: "status",
accessorKey: "status",
header: () => "Status",
meta: {
label: "Status",
variant: "select",
options: [
{ label: "Active", value: "active" },
{ label: "Inactive", value: "inactive" },
],
},
enableColumnFilter: true,
enableSorting: false,
}
// 日期列
{
id: "createdAt",
accessorKey: "createdAt",
header: ({ column }) => <DataTableColumnHeader column={column} label="Created" />,
cell: ({ row }) => new Date(row.original.createdAt).toLocaleDateString(),
}
// 操作列
{
id: "actions",
header: "",
enableSorting: false,
enableHiding: false,
cell: ({ row }) => <Button onClick={() => handleView(row.original.id)}>View</Button>,
}
| 组件 | 用途 |
|------|------|
| DataTable | 主表格组件 |
| DataTableToolbar | 标准工具栏(过滤 + 视图选项) |
| DataTableColumnHeader | 列头(支持排序) |
| DataTablePagination | 分页控件 |
| DataTableViewOptions | 列可见性控制 |
| DataTableSkeleton | 加载骨架屏 |
| DataTableFacetedFilter | 分面过滤器 |
| DataTableDateFilter | 日期过滤器 |
| DataTableSliderFilter | 滑块范围过滤器 |
参考现有实现:
src/routes/{-$locale}/_main/admin/users.tsx - 用户管理表格src/routes/{-$locale}/_main/admin/orders.tsx - 订单管理表格page, perPage, sort, 以及列 id 作为 filter 键。API 调用时用 useQueryState 读取相同参数。若 API 需要不同参数名(如 sortBy/sortOrder),可通过 queryKeys 自定义useDataTable 已配置 manualPagination, manualSorting, manualFilteringdata.length === 0 && !hasFilters 时显示空状态,有过滤时显示表格(可能是过滤结果为空)DataTableSkeleton 组件,传入 columnCount, rowCount, filterCount详细的 API 文档请查看 reference.md,包含:
useDataTable hook 完整参数development
Full-stack development guide for the VibeAny project. Covers creating pages, API routes, database tables, admin panels, landing page sections, i18n content, and server functions. Use when building any new feature, page, API endpoint, or modifying the landing page in this TanStack Start + React + Drizzle + Intlayer codebase.
development
使用 Remotion 框架以编程方式创建视频。Remotion 让你用 React 组件定义视频内容,支持动画、字幕、音乐可视化等。 触发词: - "用代码做视频"、"编程视频"、"React 视频" - "Remotion"、"remotion" - "/remotion-video" 适用场景: - 程序化视频:(1) 批量生成 (2) 数据驱动(如年度总结)(3) 音乐可视化 (4) 自动字幕 - 教程讲解视频:(5) 技术概念可视化(如 CNN、算法)(6) 分层递进讲解 (7) AI 配音教程 - 3D 视频:(8) 产品展示/模型动画 (9) 卡通角色讲解 (10) 3D 数据可视化 (11) Logo 动画
development
Create new AI chat interface components for the ai-elements library following established composable patterns, shadcn/ui integration, and Vercel AI SDK conventions. Use when creating new components in packages/elements/src or when the user asks to add a new component to ai-elements.
development
Maintainer-only workflow for handling GitHub Secret Scanning alerts on OpenClaw. Use when Codex needs to triage, redact, clean up, and resolve secret leakage found in issue comments, issue bodies, PR comments, or other GitHub content.