Table 表格
成行成列的结构化数据:需要按列比较、排序或批量选择时用。只有两三个字段的条目用 List 更轻。
基本用法
传列定义和数据。第一列自动加粗作为行的主信息;numeric 的列右对齐并用等宽数字。指针移上去时,一块共享的浅灰底跟着在行之间滑动。
| 城市 | 状态 | |||
|---|---|---|---|---|
| 林小满 | 设计 | 上海 | 128 | 在线 |
| 周屿 | 前端 | 杭州 | 342 | 在线 |
| Ada Chen | 产品 | 深圳 | 17 | 离开 |
| 宋知远 | 后端 | 北京 | 276 | 离线 |
| 何田田 | 测试 | 成都 | 64 | 在线 |
排序
给列加 sortable 后表头变成按钮,点击在 升序 → 降序 → 不排序 之间循环。默认按 accessor(或 row[key])的值比较,数字、日期、字符串各有合理的顺序;也可以传 compare 自定义。服务端排序时加 manualSort,组件只发事件不动数据。
| 城市 | 状态 | |||
|---|---|---|---|---|
| 周屿 | 前端 | 杭州 | 342 | 在线 |
| 宋知远 | 后端 | 北京 | 276 | 离线 |
| 林小满 | 设计 | 上海 | 128 | 在线 |
| 何田田 | 测试 | 成都 | 64 | 在线 |
| Ada Chen | 产品 | 深圳 | 17 | 离开 |
行选择
selectable 在首列加复选框,表头是全选(部分选中时显示半选)。选中的 key 可受控。
已选 1 人
| 城市 | 状态 | ||||
|---|---|---|---|---|---|
| 林小满 | 设计 | 上海 | 128 | 在线 | |
| 周屿 | 前端 | 杭州 | 342 | 在线 | |
| Ada Chen | 产品 | 深圳 | 17 | 离开 | |
| 宋知远 | 后端 | 北京 | 276 | 离线 | |
| 何田田 | 测试 | 成都 | 64 | 在线 |
吸顶滚动
scroll 让表格限高(默认 320,可用 maxHeight 改)、表头固定在顶部。滚动完全是浏览器原生行为,只换了滚动条的外观;纵向滚动时悬停高亮直接对位,不做滑动动画。
| 城市 | 状态 | |||
|---|---|---|---|---|
| 林小满 1 | 设计 | 上海 | 0 | 在线 |
| 周屿 2 | 前端 | 杭州 | 37 | 在线 |
| Ada Chen 3 | 产品 | 深圳 | 74 | 离开 |
| 宋知远 4 | 后端 | 北京 | 111 | 离线 |
| 何田田 5 | 测试 | 成都 | 148 | 在线 |
| 林小满 6 | 设计 | 上海 | 185 | 在线 |
| 周屿 7 | 前端 | 杭州 | 222 | 在线 |
| Ada Chen 8 | 产品 | 深圳 | 259 | 离开 |
| 宋知远 9 | 后端 | 北京 | 296 | 离线 |
| 何田田 10 | 测试 | 成都 | 333 | 在线 |
| 林小满 11 | 设计 | 上海 | 370 | 在线 |
| 周屿 12 | 前端 | 杭州 | 7 | 在线 |
| Ada Chen 13 | 产品 | 深圳 | 44 | 离开 |
| 宋知远 14 | 后端 | 北京 | 81 | 离线 |
| 何田田 15 | 测试 | 成都 | 118 | 在线 |
| 林小满 16 | 设计 | 上海 | 155 | 在线 |
| 周屿 17 | 前端 | 杭州 | 192 | 在线 |
| Ada Chen 18 | 产品 | 深圳 | 229 | 离开 |
| 宋知远 19 | 后端 | 北京 | 266 | 离线 |
| 何田田 20 | 测试 | 成都 | 303 | 在线 |
| 林小满 21 | 设计 | 上海 | 340 | 在线 |
| 周屿 22 | 前端 | 杭州 | 377 | 在线 |
| Ada Chen 23 | 产品 | 深圳 | 14 | 离开 |
| 宋知远 24 | 后端 | 北京 | 51 | 离线 |
窄屏卡片式
默认情况下表格在窄屏会在容器内横向滚动。加 stackOnMobile 后,视口窄于 520px 时每一行变成一张卡片,单元格变成“列名 —— 值”;可排序的列留在上方排成一行按钮。把浏览器调窄,或在手机上看这个示例。
| 城市 | 状态 | ||||
|---|---|---|---|---|---|
| 林小满 | 设计 | 上海 | 128 | 在线 | |
| 周屿 | 前端 | 杭州 | 342 | 在线 | |
| Ada Chen | 产品 | 深圳 | 17 | 离开 |
空状态
没有数据时显示 empty(默认是“暂无数据”四个字),可以放一个 EmptyState。
| 城市 | 状态 | |||
|---|---|---|---|---|
还没有成员邀请同事加入后会出现在这里。 | ||||
规格
- 单元格
- 内边距 12 × 20 · 首尾行到上下边补足到 20 · 行间发丝线
- 表头
- 12px / 600 · 三级色
- 悬停
- 共享浅灰底跟随指针 · 90ms ease-out
- 数字列
- 右对齐 · 等宽数字
- 窄屏
- 容器内横向滚动;stackOnMobile 时改成卡片
- 可滚动
- 限高 --ok-table-h · 表头固定 · 横纵双向
- 滚动条
- 原生滚动条换肤 · 6px,指向时 8px · 指针移入时淡入
接口
Table
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
columns* | TableColumn<T>[] | — | 列定义。 |
data* | T[] | — | 行数据。 |
rowKey | keyof T | ((row, index) => string) | — | 行的唯一标识:字段名或函数。默认用下标。 |
label | string | — | 表格的名字(aria-label);可滚动时也是滚动区域的名字。 |
caption | ReactNode | — | 可见的表格标题,渲染成 caption。 |
sort / defaultSort | { key: string; direction: 'asc' | 'desc' } | null | null | 排序,受控 / 非受控。null 表示不排序。 |
onSortChange | (sort: TableSort) => void | — | 排序变化时。 |
manualSort | boolean | — | 只发出排序事件、不在内部排序(服务端排序)。 |
selectable | boolean | — | 行选择:首列出现复选框,表头是全选。 |
selectedKeys / defaultSelectedKeys | string[] | — | 选中的行 key,受控 / 非受控。 |
onSelectionChange | (keys: string[]) => void | — | 选择变化时。 |
getRowLabel | (row, index) => string | — | 行的名字,用在复选框的 aria-label 里。默认取第一列的文字。 |
scroll | boolean | — | 可滚动变体:限高、表头吸顶。 |
maxHeight | number | string | 320 | 可滚动变体的最大高度。 |
stackOnMobile | boolean | — | 窄屏(< 520px)把每一行变成卡片式的键值对。 |
empty | ReactNode | '暂无数据' | 没有数据时显示的内容。 |
noHighlight | boolean | — | 关掉跟随指针的共享悬停高亮,退回普通的整行变色。 |
TableColumn
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
key* | string | — | 列标识;没有 accessor / render 时也用它从行数据里取值。 |
header* | ReactNode | — | 表头内容。 |
label | string | — | 表头不是纯文字时,给读屏和卡片式布局用的文字标签。 |
accessor | (row: T) => unknown | — | 取值,用于排序和默认渲染。 |
render | (row: T, index: number) => ReactNode | — | 自定义单元格。 |
sortable | boolean | — | 可排序。 |
compare | (a: T, b: T) => number | — | 自定义比较(升序);降序时自动取反。 |
numeric | boolean | — | 数字列:右对齐、等宽数字。 |
align | 'start' | 'center' | 'end' | — | 对齐方式。 |
width | number | string | — | 列宽。 |
无障碍
- 原生
table,表头是th scope="col";名字来自caption或label,两者至少给一个。 - 可排序的表头里是真的按钮,Tab 聚焦、Enter / 空格切换;当前状态写在
aria-sort(ascending / descending / none)上。箭头只是视觉提示。 - 行选择用原生复选框,名字是“选择 + 行名”,表头是“选择全部”;用 Tab 移动、Space 切换。选中的行带
aria-selected,选中数量通过role="status"播报。 - 可滚动(或内容超宽)时容器成为
role="region"且可聚焦,键盘用户用方向键、PageUp / PageDown 滚动。 - stackOnMobile 把表格元素改成块级后会丢语义,组件已显式写回 table / row / cell 等角色;每个值前面的列名来自表头文字。
- 悬停高亮只是指针反馈,不影响键盘和读屏;触屏上不出现。