极简数据表

table · minimal · 灵感来源:GOV.UK table / USWDS usa-table

表头不用大写小字,一条分隔线就够分层

组件复现清单
组件类型材质数浏览量更新
玻璃按钮按钮31 2842026-10-24
玻璃输入框输入39632026-10-30
玻璃抽屉抽屉312 4072026-10-31
极简通知通知3772026-10-19
拟态骨架屏骨架352026-10-12

复用卡

Data Table · 极简数据表 · 表格 / Minimal

规格 · 术语提示词(给 AI 用)

做一个 Data Table(极简数据表):
- 同一份 props(caption / columns / rows / className)
- 平底 + 发丝线,零模糊零 inset;表头用正文小号,不用大写小字
- 悬停换底色不换阴影——极简没有"按下去"这回事
- 对齐、滚动与只读边界同玻璃数据表
用这些 CSS 变量:--color-bg --color-divider --color-surface --color-text --color-text-muted
灵感参考:GOV.UK table / USWDS usa-table

参数(CSS 变量)

--color-bg --color-divider --color-surface --color-text --color-text-muted

必缺状态

悬停 / 焦点

整页场景

(尚未接进整页场景)

安装(一条链接)

参考(本站可核对)

调研笔记

极简数据表

  • 材质签名:平底 + 发丝线,零模糊零 inset;分层只靠一条表头线与留白
  • 表头不用大写小字——那是玻璃那支的手法;这里用正文小号 + muted 色
  • 悬停换底色(--color-bg),不换阴影:极简没有"按下去"这回事
  • 只读第一版:没有排序、筛选、选择、固定列。要加就一项一项放行,每加一项都要回答"键盘怎么走"
  • 空表不渲染:没有数据时换成空态组件,别留一排表头
  • 结构与对齐口径见 页面模式 · 表格
  • 嵌进面板时用 framed=false:只留滚动容器,材质底不重复画
  • 窄屏不硬压列:整表有 34rem 下限,再窄就横向滚动(顺序见页面模式 §3)

实现

table/minimal
import { type ReactNode } from 'react';

export interface TableColumn {
  key: string;
  header: string;
  /** end = 数字列:表头与数值一起右对齐(GOV / Polaris 同一条) */
  align?: 'start' | 'end';
  /** 列宽只写 Tailwind 宽度类,不写 px 字面量 */
  width?: string;
}

export interface TableRow {
  id: string;
  cells: Record<string, ReactNode>;
}

interface Props {
  caption: string;
  columns: TableColumn[];
  rows: TableRow[];
  /** false = 只留滚动容器,材质底交给外层面板(嵌在卡片里时不再套一层卡) */
  framed?: boolean;
  className?: string;
}

/** 极简数据表:材质签名 = 平底 + 发丝线,表头不用大写小字,靠留白与一条分隔线分层 */
export function MinimalTable({ caption, columns, rows, framed = true, className = '' }: Props) {
  return (
    <div
      role="region"
      aria-label={caption}
      tabIndex={0}
      className={`overflow-x-auto outline-offset-2 ${framed ? 'rounded-md bg-[var(--color-surface)]' : ''} ${className}`}
    >
      <table className="w-full min-w-[34rem] border-collapse text-sm">
        <caption className="sr-only">{caption}</caption>
        <thead>
          <tr className="border-b border-[var(--color-divider)]">
            {columns.map((c) => (
              <th
                key={c.key}
                scope="col"
                className={`
                  px-4 py-3 text-xs font-medium text-[var(--color-text-muted)] whitespace-nowrap
                  ${c.align === 'end' ? 'text-right' : 'text-left'}
                  ${c.width ?? ''}
                `}
              >
                {c.header}
              </th>
            ))}
          </tr>
        </thead>
        <tbody>
          {rows.map((row) => (
            <tr
              key={row.id}
              className="border-b border-[var(--color-divider)] last:border-b-0 transition-colors hover:bg-[var(--color-bg)]"
            >
              {columns.map((c, i) =>
                i === 0 ? (
                  <th
                    key={c.key}
                    scope="row"
                    className="px-4 py-3 text-left font-medium text-[var(--color-text)] break-words"
                  >
                    {row.cells[c.key]}
                  </th>
                ) : (
                  <td
                    key={c.key}
                    className={`
                      px-4 py-3 text-[var(--color-text-muted)] break-words
                      ${c.align === 'end' ? 'text-right tabular-nums whitespace-nowrap' : ''}
                    `}
                  >
                    {row.cells[c.key]}
                  </td>
                ),
              )}
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

元信息

标识
table/minimal
状态
done
最后提交
2026-11-01
风格轴
minimal
依赖 token
--color-bg --color-divider --color-surface --color-text --color-text-muted
在工作台打开 源码与 notes 都在 src/components/table/minimal/