mcpField
D
data-table-filters

data-table-filters

github.com/openstatushq开发2.3k478 次安装4 周前更新
代码仓库

关于 data-table-filters

这是一个 shadcn 注册表,提供可组合模块,用于构建支持筛选、排序、无限滚动和虚拟化的数据表。开发者可按需逐步添加功能,包括模式推断和服务端集成。

主要功能

  1. 01可组合的数据表模块
  2. 02内置 4 种筛选类型
  3. 03无限滚动与虚拟化
  4. 04根据 JSON 推断模式
  5. 05URL 与客户端状态适配器
  6. 06可选 AI 与 MCP 模块

适用场景

  1. 01构建带筛选和无限滚动的日志查看器
  2. 02从 JSON 数据推断表格列与筛选器
  3. 03将数据表连接到 Drizzle ORM 或 React Query
  4. 04添加自然语言筛选或 MCP 端点

MCP 相关

可选的 data-table-mcp 模块提供无状态且兼容无服务器环境的 MCP 服务端点,供 AI Agent 使用。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/openstatushq/data-table-filters --skill data-table-filters

安装后在 Claude Code 中输入/data-table-filters确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
ai-filters.md
auto-infer.md
component-catalog.md
drizzle-integration.md
fetch-layer.md
mcp-server.md
schema-api.md
store-adapters.md
scripts/
detect-stack.sh

详细介绍

数据表筛选器

一个 shadcn 注册表,用于构建支持无限滚动和虚拟化的可筛选、可排序数据表。先从核心模块开始,再通过可选模块扩展命令面板、单元格渲染器、工作表面板、存储适配器、模式生成、Drizzle ORM 辅助工具和 React Query 集成。

前置要求。 适用于任一 shadcn 库:CLI 默认库、Base UI(npx shadcn@latest init -d)或 Radix(npx shadcn@latest init -b radix -p lyra)。每次注册表更改和每晚运行时,CI 都会将其安装到两者中并进行类型检查。

注册表模块

使用 npx shadcn@latest add @data-table-filters/<block> 安装任意模块。CLI 会处理依赖项、路径重写和 CSS 变量注入。

模块安装新增内容
data-table@data-table-filters/data-table核心功能:表格引擎、存储、4 种筛选器类型、内存适配器(63 个文件)
data-table-filter-command@data-table-filters/data-table-filter-command带历史记录和键盘快捷键的命令面板
data-table-cell@data-table-filters/data-table-cell12 种单元格渲染器(文本、代码、数字、条形图、热力图、仪表盘、徽章、布尔值、星级、状态码、级别指示器、时间戳)
data-table-sheet@data-table-filters/data-table-sheet行详情侧边面板(自动安装单元格)
data-table-nuqs@data-table-filters/data-table-nuqsnuqs URL 状态适配器
data-table-zustand@data-table-filters/data-table-zustandzustand 状态适配器
data-table-schema@data-table-filters/data-table-schema声明式架构系统,包含 col.* 工厂函数
data-table-drizzle@data-table-filters/data-table-drizzleDrizzle ORM 服务端辅助工具(自动安装架构)
data-table-query@data-table-filters/data-table-queryReact Query 无限查询集成
data-table-filter-command-ai@data-table-filters/data-table-filter-command-aiAI 驱动的自然语言 → 筛选器推断(与提供方无关)
data-table-mcp@data-table-filters/data-table-mcp面向 AI Agent 的 MCP 服务端点(无状态,兼容无服务器环境)
data-table-actions@data-table-filters/data-table-actions根据服务端元数据呈现行操作和批量操作(需要 drizzle)
data-table-remote@data-table-filters/data-table-remote由端点清单驱动的无头表格——架构、功能和行标识
data-table-chart@data-table-filters/data-table-chart表格上的时间线图表:按级别堆叠分桶,拖动即可缩放时间筛选器
data-table-example-infinite@data-table-filters/data-table-example-infinite开箱即用的 /example 路由:架构、模拟 API、带 URL 状态的无限表格

模块可从 shadcn 注册表目录按名称安装;也可以使用 JSON 格式 https://data-table.openstatus.dev/r/<block>.json。

快速开始

  1. 运行 scripts/detect-stack.sh 检测用户的项目设置。它会报告项目使用的组件库——两者均可。如果输出 shadcn/ui: not initialized,请先运行 npx shadcn@latest init -d 初始化(Radix 用户可运行 init -b radix -p lyra),然后继续。还没有项目?运行 pnpm dlx shadcn@latest init @data-table-filters/data-table-example-infinite --name logs-viewer --template next -p lyra,即可创建一个初始化了 shadcn 的 Next.js 应用,并安装好可用的 /example 路由(包含时间线图表、筛选器、无限滚动和行详情面板)以及它所需的所有区块(使用 Radix 时,在 -p lyra 前添加 -b radix)。需要 pnpm(npm i -g pnpm);如果更喜欢使用 npm,npx 和 npm run dev 的用法也一样。然后运行 cd logs-viewer,启动开发服务器,打开 http://localhost:3000/example,并编辑 app/example/table-schema.ts——或者继续步骤 2,为自己的表格进行配置。
  2. 安装核心包和架构:npx shadcn@latest add @data-table-filters/data-table @data-table-filters/data-table-schema
  3. 搭建一个最简可用的表格(见下文);如果数据结构未知,则渲染 <DataTableAuto data={rows} />
  4. 根据需要添加其他区块

Next.js? 请将 data-table-filters 仓库用作参考——这是一个完整的 Next.js 应用,已接入所有区块。

最简可用表格(内存适配器)

注意: DataTableInfinite 内部会渲染 DataTableProvider,后者已使用 ControlsProvider 和 DataTableStoreSync 包装子元素。无需单独添加它们。你唯一需要的包装器是 DataTableStoreProvider(用于 BYOS 适配器)。

"use client";
import { DataTableInfinite } from "@/components/data-table/data-table-infinite";
import type { DataTableFilterField } from "@/components/data-table/types";
import { useMemoryAdapter } from "@/lib/store/adapters/memory";
import { DataTableStoreProvider } from "@/lib/store/provider/DataTableStoreProvider";
import type { ColumnDef } from "@tanstack/react-table";

const columns: ColumnDef<YourData>[] = [
  /* user's columns */
];
const filterFields: DataTableFilterField<YourData>[] = [
  /* user's filters */
];

export function MyTable({ data }: { data: YourData[] }) {
  const adapter = useMemoryAdapter(/* schema definition */);
  return (
    <DataTableStoreProvider adapter={adapter}>
      <DataTableInfinite
        columns={columns}
        data={data}
        filterFields={filterFields}
      />
    </DataTableStoreProvider>
  );
}

接入扩展区块

通过 npx shadcn@latest add 安装区块后,将其接入表格。

命令面板 → commandSlot
<DataTableInfinite
  commandSlot={<DataTableFilterCommand schema={schema} tableId="my-table" />}
/>
Sheet 详情面板 → sheetSlot
<DataTableInfinite
  sheetSlot={
    <DataTableSheetDetails title="Details">{content}</DataTableSheetDetails>
  }
/>
浮动栏(批量操作)→ floatingBarSlot

将 col.select() 添加到架构中,以启用带复选框的多行选择。使用 DataTableFloatingBar 包装操作——它会从上下文读取选择状态(与 sheetSlot 使用的 DataTableSheetDetails 模式相同)。

// In table-schema.tsx
export const tableSchema = createTableSchema({
  select: col.select().size(37),
  // ... other columns
});

// In client.tsx
import { DataTableFloatingBar } from "@/components/data-table/data-table-floating-bar";

<DataTableInfinite
  floatingBarSlot={
    <DataTableFloatingBar>
      {({ rows }) => (
        <Button variant="outline" size="sm" onClick={() => console.log(rows)}>
          Export ({rows.length})
        </Button>
      )}
    </DataTableFloatingBar>
  }
/>;
行操作 → data-table-actions

安装:npx shadcn@latest add @data-table-filters/data-table-actions(需要 drizzle 区块)。

在服务端与 Drizzle 处理程序相邻的位置一次性声明操作。列表端点会公开这些操作(meta.actions),并为每行标注适用的操作 ID(_actions);UI 根据该 JSON 进行渲染,不会获知操作的具体作用。

// app/<table>/api/actions.ts
export const actionHandler = createActionHandler({
  db,
  table,
  filters,
  columnMapping, // same as createDrizzleHandler, plus the id column
  idColumn: "uuid",
  basePath: "/<table>/api/actions",
  actions: {
    acknowledge: {
      label: "Acknowledge",
      scope: ["row", "bulk", "filter"],
      when: { level: ["error"] }, // filter values — evaluated in JS for _actions, compiled to SQL as the WHERE guard
      handler: async (ctx, tx) =>
        (
          await tx
            .update(table)
            .set({ level: "warning" })
            .where(ctx.where)
            .returning()
        ).length,
    },
  },
});

// GET route: data = actionHandler.annotate(result.data); meta.actions = actionHandler.descriptors
// POST app/<table>/api/actions/[id]/route.ts: actionHandler.execute(id, await req.json(), { actor })
// client.tsx
<DataTableActionsProvider
  actions={meta?.actions}
  getRowId={(r) => r.uuid}
  queryKeyPrefix="<prefix>"
>
  <DataTableInfinite
    columns={[...generateColumns(schema), createActionsColumn()]}
    floatingBarSlot={
      <DataTableFloatingBar>
        {({ rows }) => <DataTableActionsBar rows={rows} />}
      </DataTableFloatingBar>
    }
  />
</DataTableActionsProvider>

_actions 仅供参考;处理程序的 ctx.where(ID ∩ when)才是判定依据,因此 applied 可能少于发送的 ID。操作会加入队列(切换状态),而不会立即执行。结果会以 sonner toast 提示——在布局中挂载一次 <Toaster />(npx shadcn@latest add sonner)。

单元格渲染器 → 列定义
import { DataTableCellBadge } from "@/components/data-table/data-table-cell";
// Use in columnDef.cell
自定义筛选器类型 → FILTER_COMPONENTS

核心包已包含全部 4 种筛选器类型。添加自定义类型:

import { FILTER_COMPONENTS } from "@/components/data-table/data-table-filter-controls";
FILTER_COMPONENTS.myCustom = MyCustomFilterComponent;
AI 命令面板 → commandSlot

需要一个用于流式传输 AI 结果的 API 路由。参见 references/ai-filters.md。

<DataTableInfinite
  commandSlot={
    <DataTableFilterAICommand
      schema={filterSchema.definition}
      tableSchema={tableSchema.definition}
      api="/api/ai-filters"
      tableId="my-table"
    />
  }
/>
所有插槽属性

DataTableInfinite 接受:commandSlot、sheetSlot、toolbarActions、chartSlot、footerSlot、floatingBarSlot。

完整接入详情请参见 references/component-catalog.md。

存储适配器配置

  • memory(默认)——临时存储,零配置。适用于原型开发、嵌入式组件和构建器。
  • nuqs——URL 状态。支持分享链接和将筛选器加入书签。需要进行框架配置。
  • zustand——客户端状态。适用于已有 zustand 应用及复杂应用状态。

安装适配器区块并替换为相应的提供程序。参见 references/store-adapters.md。

架构生成

安装:npx shadcn@latest add @data-table-filters/data-table-schema

将数据模型映射到 createTableSchema + col.*:

  • string → col.string().filterable("input")

  • number → col.number().filterable("slider", { min, max })

  • boolean → col.boolean().filterable("checkbox")

  • Date → col.timestamp().filterable("timerange")

  • enum → col.enum(values).filterable("checkbox")

  • select → col.select()(复选框行选择,而非可筛选项)

预设:col.presets.logLevel()、.httpStatus()、.duration()、.timestamp()、.traceId()、.pathname()、.httpMethod()。

参见 references/schema-api.md。

自动推断(从 JSON 零配置生成)

对于没有预定义架构的原始 JSON 数据,可使用 DataTableAuto,或使用较底层的 inferSchemaFromJSON + createTableSchema.fromJSON 流程。此功能会根据数据自动生成列、筛选器、表单字段和列可见性。

DataTableAuto 组件

即插即用组件——传入 JSON 数据,即可获得功能齐全的表格:

import { DataTableAuto } from "@/components/data-table/data-table-auto";
import data from "./data.json";

export default function Page() {
  return <DataTableAuto data={data} />;
}

开箱即用地包含命令面板和表单详情面板。查看此仓库中的 /auto 路由,了解可运行的示例。

底层 API
import { inferSchemaFromJSON } from "@/lib/table-schema/infer";
import { createTableSchema } from "@/lib/table-schema";

const schemaJson = inferSchemaFromJSON(data);
const { definition } = createTableSchema.fromJSON(schemaJson);

有关推断规则、智能增强和自定义方式,请参见 references/auto-infer.md。

服务端集成

安装:npx shadcn@latest add @data-table-filters/data-table-drizzle

使用 createDrizzleHandler({ db, table, columnMapping, cursorColumn, schema }) 构建路由处理程序。

对于非 Drizzle ORM:实现响应结构 { data, facets, totalRowCount, filterRowCount, nextCursor, prevCursor }。

参见 references/drizzle-integration.md。

获取层

安装:npx shadcn@latest add @data-table-filters/data-table-query

配置 createDataTableQueryOptions({ queryKeyPrefix, apiEndpoint, searchParamsSerializer })。

默认使用同源 fetch 和 SuperJSON 请求体。对于其他 API,可传入 transport(baseUrl、作为同步/异步函数的 headers、credentials、parseResponse)以及一种 pagination 策略——timestampCursorPagination()(默认,双向)、opaqueCursorPagination() 或 offsetPagination({ size })。schemaJsonParser(schema) 会将时间戳列从普通 ISO 字符串还原,因此端点无需采用 SuperJSON。对于非 2xx 响应或无法解析的请求体,会抛出 DataTableFetchError,其中包含 status、url 和请求体片段。

参见 references/fetch-layer.md。

无头表格(指向某个端点)

安装:npx shadcn@latest add @data-table-filters/data-table-remote

适用于数据和端点由其他地方管理,且应用中无需编写逐列代码的表格。

服务端——发布描述表格的清单:

// app/<table>/api/schema/route.ts
const handler = createTableManifestHandler(
  createTableManifest({
    schema: tableSchema,
    primaryKey: "uuid", // the column that identifies a row on the wire
    rowLabel: "{method} {pathname}", // template over column keys, for a11y
    capabilities: { facets: true, totalRowCount: true, chart: true },
    defaults: { sort: { id: "date", desc: true }, size: 40 },
  }),
);
export const GET = (request: Request) => handler(request);

如果清单依赖请求(例如按租户区分列、根据权限显示操作),请传入函数而非值。响应会附带 ETag,因此重新验证时会返回 304。

客户端:

<DataTableRemote
  manifestEndpoint="/logs/api/schema" // data endpoint defaults to this minus /schema
  searchParamsSerializer={searchParamsSerializer}
  initialManifest={snapshot} // optional — skips the round trip before first paint
  transport={{ headers: async () => ({ authorization: await token() }) }}
  renderers={{ pathname: { cell: (v) => <PathnameCell value={String(v)} /> } }}
/>

要点:

  • 功能默认关闭。 仅声明端点已实现的功能;表格会相应降级(客户端分面、计数为空、无实时按钮、无图表),而非渲染空内容。
  • 渲染器不会序列化。 命名显示项(badge、bar、status-code……)会作为数据传递;其余情况使用 applyRenderers / renderers 属性。描述符保持不变,因此架构仍可往返转换。
  • 清单不可信。 列和操作均有数量上限;操作的 href 仅限页面来源,除非通过 allowedActionOrigins 将其他来源列入允许列表。
  • 使用快照避免往返请求。 pullManifestModule(url) 会写入一个带类型的模块;将其作为 initialManifest 传入。运行时仍会重新验证。
  • 使用 runEndpointConformance({ url, manifest }) 和 formatConformanceReport 验证端点。

故障排除

  • 缺少 CSS 变量:Core 会注入 --color-success/warning/error/info。请检查 CSS 中是否应用了 cssVars。
  • 导入路径不匹配:shadcn CLI 会根据 components.json 中的别名重写 @/ 路径。
  • nuqs:静默失败或崩溃:需要完成两个设置步骤——在根布局中添加 <NuqsAdapter>,并在表格组件外层添加 <Suspense>。请参阅 references/store-adapters.md。
  • nuqs:加载时未应用 URL 中的筛选条件:将服务器解析后的搜索参数作为 initialState 传递给 nuqs 适配器。请参阅 references/store-adapters.md 中的 SSR Hydration 部分。
  • nuqs:空字符串导致出现幽灵筛选条件:使用 field.string()(默认值为 null),而不是 field.string().default("")。
  • Sheet 下拉菜单缺失:SheetField.type 必须与筛选器类型匹配(不能是 "readonly"),才能显示筛选器下拉菜单。使用 generateSheetFields() 可根据筛选器配置自动生成。
  • 筛选器未渲染:请确认筛选器类型字符串与 FILTER_COMPONENTS 的键匹配。
  • Tailwind v4:Registry 面向 v4。类名语法与 v3 不同。

评论

支持 Markdown