Table
Table 是一个由 table 特性提供的通用、数据驱动表格组件。你描述列、给出行数据以及一个 render_row 闭包,组件负责列宽解析、CJK/emoji 视宽感知的单元格换行、单元格网格边框、选中态、页脚行与布局高度。它保持业务中立:行类型 T 是你自己的,组件从不假设一行代表什么。

该录制由 docs/tapes/table.tape 生成:默认选中一行(▶ gutter 与行高亮),用 l/h 移动列高亮,用 c 切换密度,用 PageDown 滚出页脚合计,用 e 切换空态。
按 j/k 移动选中行,h/l 移动选中列,PageUp/PageDown 或鼠标滚轮滚动,c 切换紧凑密度,e 切换空态,q 退出。
Table 在 table 特性之后:
示例使用 full 特性,可以直接运行。主库默认特性集刻意为空;裸 cargo check 不会编译 table 组件。
为什么不用原生 ratatui Table?
Section titled “为什么不用原生 ratatui Table?”Table 是从零手写的渲染器,并没有包裹 ratatui::widgets::Table。它存在的意义正是原生 widget 做不到的三件事:
- 单元格网格线 ——
TableBorderMode::Grid在每个单元格与每行之间绘制盒线边框(原生表格只有外层Block)。这正是它能渲染 markdown 风格表格的原因。 - 自动换行 —— 过长的单元格文本按列宽换行,并正确处理 CJK/emoji 的视觉宽度(原生表格只截断,或需要你预换行并设置行高)。
- 响应式列 —— 通过
min_table_width,列可以在表格窄于阈值时自动隐藏。
如果你想要的是原生的窗口化滚动表格(只渲染可见行、二维单元格选择、footer),它已经能通过 stateful(...) adapter 直接使用——因为 ratatui::widgets::Table 就是 StatefulWidget。当你要边框、换行与框架集成的选中态时,才用 Table。
一列由表头、宽度 Constraint、对齐方式,以及可选的响应式阈值组成:
宽度接受 Length / Min / Max / Percentage / Ratio / Fill;组件在可用宽度(扣除边框、内边距与选中 gutter 之后)内解析它们,并在溢出时按比例缩小。min_table_width(n) 在表格窄于 n 时整列隐藏,让宽表在终端收窄时仍然可读。
行与 render_row
Section titled “行与 render_row”行是你自己的数据。render_row 把一行(以及它是否被选中)转成 Vec<TableCell>,每列一个单元格:
TableCell 是一个 Line 加上可选的单元格级 style 与 alignment(对齐方式缺省回退到列的对齐)。超过列数的单元格被忽略;缺失的单元格渲染为空。
边框、换行与分隔线
Section titled “边框、换行与分隔线”Grid绘制完整单元格网格;Outer只绘制外框;None不绘制边框,列间用column_spacing。Wrap在空白处断行(退化时硬断),并把 CJK/emoji 记为宽度 2;Truncate截断为单行。- 行分隔线与表头分隔线只在
Grid模式下占一条可见的线。
传入一行 footer 单元格(每列一个)用于合计或摘要。它对齐到相同的列,绘制在表体之后,并可选带分隔线:
选中、高亮与 gutter
Section titled “选中、高亮与 gutter”Table 在 TableState 中跟踪选中行(以及可选的选中列)。
highlight_spacing决定选中符号是否预留前置 gutter。默认WhenSelected时,选中一行就出现 gutter,▶符号永远不会覆盖首列内容(与原生HighlightSpacing一致)。Always无条件预留;Never从不绘制符号。column_highlight_style为整个选中列(表头、表体、页脚)着色;cell_highlight_style在行/列交叉处再叠加一层。两者默认为空,只有选中某列后才显现。- 内置按键(
active时):j/k/Down/Up移动行,Home/End跳转,Enter触发on_select。设column_navigation: true会加上h/l/Left/Right来移动选中列。
Table 默认自己拥有 TableState。当页面需要读取当前选中、用自己的按键驱动选择,或在重新挂载后保持稳定时,传入外部状态。示例用页面驱动选择,好让外层 ScrollView 仍然独占 PageUp/PageDown 与滚轮:
TableState 对行暴露 selected() / select() / next() / previous() / select_first() / select_last(),对列暴露 selected_column() / select_column() / next_column() / previous_column()。选中列是完整列表里的索引,因此即便响应式隐藏改变了可见列,它也保持稳定。
Table 接受 width、height、margin、offset。当 height 保持默认时,它会估算渲染高度(含换行、网格线与页脚),让表格恰好占据所需空间。表格高于视口时,把它放进 ScrollView——示例正是这么做的,让 ScrollView 裁剪溢出、PageUp/PageDown 滚动。普通长列表优先用 VirtualList;普通单选/多选见 Select 与 MultiSelect。