# @canvas-components/list-table 中文文档

规范地址：https://npmcn.com/package/%40canvas-components/list-table/

版本：0\.3\.58
npm 元数据更新时间：2026-11-09T07:58:24.381Z
中文译文更新时间：2026-11-09T07:30:37.674Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40canvas-components/list-table
原文对照：https://npmcn.com/package/%40canvas-components/list-table/?lang=original

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：3.4 MB，7 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- Node.js 要求：\>=18\.12\.0
- 运行依赖：6 个
- 首次发布：2026-08-19T10:28:41.004Z
- 最新版本发布：2026-11-09T07:58:24.129Z
- 近 30 天下载量：6009（2026-10-09 至 2026-11-07，npm 官方下载统计）
- 已发布版本数：66（近 12 个月 66 个）

## 中文简介

框架-不可知列表表核心引擎.

## 安装

```sh
npm install @canvas-components/list-table
```

也可以使用：`pnpm add @canvas-components/list-table`、`yarn add @canvas-components/list-table`、`bun add @canvas-components/list-table`

## README

# @canvas-components/list-table

`@canvas-components/list-table` 是整个项目的纯原生 Canvas 表格核心包，不依赖 React，可直接在 DOM 容器中创建高性能表格实例，也可作为适配层的底层引擎使用。

## 表头合并

使用 `children` 自动生成多级表头，或通过 `onHeaderCell(column)` 返回 `rowSpan`、`colSpan` 自定义合并；跨度为 `0` 时隐藏该表头，表体列保持独立。原生表格和 React 适配层共用此配置，详见 [表头合并配置](https://npmcn.com/package/%40canvas-components/list-table/docs/header-cell.md)。

## 双击表头边界自动列宽

双击表头可拖拽的右边界，按内容自动计算当前列宽；双击左边界则调整左侧相邻列，与拖拽边界归属一致。支持左右固定列及最后一列，沿用右键菜单的内容测量、最小/最大宽度限制与列宽缓存设置。禁用列宽调整的边界和空白选择列等特殊列不响应。

## 内置图标

`{ type: "icon", icon: "EditOutlined", size: 20 }` 可绘制原生图标，完整提供官方 848 个图标（线框、实心、双色），另有 58 个内置短名称图标，包含表头同款排序、过滤、固定图标。 图标路径统一维护于 `src/rendering/icons/`，供单元格、评分、时间轴和附件功能复用。 详见 [图标目录与配置](https://npmcn.com/package/%40canvas-components/list-table/docs/icons.md)。

## 时间轴单元格

`render` 返回 `{ type: "timeline", items: [{ title: "09:00", content: "订单创建", color: "green" }] }` 即可绘制原生纵向时间轴；支持自动换行、自动行高、交替布局和倒序。 详见 [时间轴配置](https://npmcn.com/package/%40canvas-components/list-table/docs/timeline.md)。

## 上传单元格

设置 `formItemProps: { valueType: "upload", upload: { action: "/api/upload", multiple: true } }` 即可使用原生上传编辑器。图片回显缩略图，其他文件显示类型图标和文件名，不依赖 React 组件。 详见 [上传配置与接口说明](https://npmcn.com/package/%40canvas-components/list-table/docs/upload.md)。

## 多列排序

使用列配置，设置 `sorter: { multiple: 数值 }` 开启该列的多列排序，数值越大越优先；同优先级按加入排序的先后顺序执行。

```ts
const columns = [
  { title: "部门", dataIndex: "dept", sorter: { multiple: 3 } },
  { title: "绩效", dataIndex: "score", sorter: { multiple: 2 } },
  { title: "姓名", dataIndex: "name", sorter: { multiple: 1 } },
];
```

-   点击排序图标依次切换升序、降序、取消，仅修改当前列；右键“取消排序”同样只清除当前列，“重置排序”清除全部条件。
-   `multiple` 相同时，先点击加入排序的列优先；切换升降序不改变次序，取消后重新加入排在同权重列的最后。缓存恢复保留此顺序，未点击的默认排序按列配置顺序。
-   `sortValueGetter(record)` 用于提取数字或字符串排序值，支持状态权重映射、数值计算等；`sorter.compare(a, b)` 则直接比较两条原始记录，优先于 `sortValueGetter`。按升序返回负数、零或正数，降序由表格自动反转；返回 `0` 或 `NaN` 时继续比较下一列，全部相等保留原始顺序。比较函数需保持纯函数并满足排序一致性。
-   自定义 `compare` 不会序列化到 Worker，支持闭包，采用可取消的主线程分片排序；同一组排序中的普通列仍可使用 Worker。比较函数抛出异常时进入查询错误处理，不会静默改用默认规则。单次比较函数本身仍需快速返回。
-   未配置 `multiple` 的列保持单列交互：开始排序时替换其他排序条件。`sorter: true` 开启单列排序，也可继续使用 `allowSort` 控制排序能力。
-   `defaultSortOrder` 可与 `sorter.multiple` 配合设置多列默认排序，父表和嵌套子表独立维护各自的排序条件。
-   排序状态统一使用数组：`[{ key, order, priority }]`，未排序为 `[]`；`query.onChange` 第三个参数也是数组：`[{ columnKey, field, order, priority }]`。`extra.sorter`、`extra.sorters` 均返回排序状态数组。不转换旧单列缓存数据。
-   本地同步排序、Worker 排序及无 Worker 分片回退遵循相同优先级；服务端模式由业务端按回调数组执行排序。
-   基础示例中已配置部门、绩效、姓名三列，可连续点击它们验证组合排序。

```ts
const scoreColumn = {
  title: "绩效",
  dataIndex: "score",
  sorter: {
    multiple: 2,
    compare: (a, b) => a.score - b.score,
  },
};
```

## 多列拖拽排序

开启 `draggable: true` 后，可先使用 Shift 选中连续列，或使用 Ctrl / Command 选中不连续列，再从任意已选列的表头空白处拖动。同层级中允许拖拽的选中列会按原显示顺序整体移动；不连续选中的列在落点合并为连续的一组。高亮选区跟随列移动，浮层同步展示各列表头。

拖动未选中的列时仍只移动该列。固定列、`draggable: false` 的列不参与移动；多级表头沿用同级重排边界，不把子列移出所属分组。落回原位时不提交重排。

## 图片复制与导出

右键菜单「复制」支持「复制为图片」，「导出」支持「导出图片」，均提供三个范围：

-   所有区域：重新绘制当前已加载、经过排序过滤的全部数据及可见列，包含表头和已开启的汇总行。服务端分页不会额外请求尚未加载的数据。
-   选中区域：绘制当前单元格、拖拽矩形选区、整行或整列选区，不包含表头和汇总行；没有选区时不可用。
-   视口区域：截取当前表格画布，保留当前滚动位置及可见效果，不包含分页器、工具栏或右键菜单。

图片格式为 PNG。复制需要浏览器支持图片剪贴板，且通过 HTTPS 或 localhost 访问；下载不依赖剪贴板权限。 图片包含尚未加载的图片内容时，最多等待 10 秒。跨域资源禁止读取、编码失败或尺寸过大会明确提示，不会静默生成不完整文件。 为防止内存溢出，输出图片单边不超过 16384 像素，总像素不超过 1600 万（计入缩放及设备像素比）；超过时请缩小选区或使用视口范围。 「复制」和「导出」仍分别遵循 `contextMenu.features` 的 `copy`、`export` 开关。

## 功能作用

-   原生 Canvas 表格渲染
-   大数据量虚拟滚动
-   多级表头、固定列、汇总行
-   排序、过滤、自动合并单元格
-   行选择、展开树表、右键菜单
-   单元格编辑、校验、tooltip、图片预览
-   列宽调整、列拖拽、行拖拽、轮播滚动
-   内建二维码、条形码、进度、图表、评分、按钮等单元格内容

### 展开详情自动高度

`expandable.expandedRowRender` 返回标签、文本等富内容时，不传 `expandedRowHeight` 即按实际内容宽度自动换行、测高。容器宽度、列宽、字体或密度变化后会重新计算，并同步更新行位置和滚动范围。测量与绘制共用布局规则，业务侧无需自行测量标签或监听容器宽度。

显式设置 `expandedRowHeight` 数字或回调时仍优先使用该配置；嵌套子表继续使用其独立的内容高度计算。

展开详情中的 `button`、`link` 等交互片段与普通单元格共用点击、禁用及二次确认逻辑。`onClick` 收到所属数据行的 `record`、扁平行索引 `rowIndex`、片段索引 `contentIndex` 和原生事件；`column.key` 为 `__expanded_row__`，`value` 为 `undefined`。文档站「可展开行」的入库条码明细示例演示物料标签与按钮组合、权限切换及明细弹窗。

### 内嵌子表头

`children` 树形数据共用父表列和表头，叶子行会预留展开按钮位置，使文字按 `indentSize` 逐级缩进。展开详情返回 `type: "table"` 时，子表默认独立显示表头，即使父子列配置相同也不会自动隐藏。

内嵌表格内容支持 `showHeader: false`：

```ts
expandable: {
  expandedRowRender: (record) => ({
    type: "table",
    showHeader: false,
    columns: detailColumns,
    dataSource: record.details,
  }),
}
```

隐藏时不绘制子表头、排序/筛选等表头入口，也不预留表头高度；首行数据从子表顶部开始，编辑和选区位置随之调整。`showHeader` 默认 `true`，设为 `false` 时优先于 `headerHeight`。父子可见业务列的字段和显示顺序一致，且子表未显式设置 `width` 时，子表会跟随父表实际列宽及固定列位置，缩进只占首个业务列；显示或隐藏子表头均保持后续列边界对齐。字段或顺序不同、显式指定子表宽度时仍独立计算列宽。文档站「可展开行」示例可切换子表头显示。

### 子表列宽与列顺序拖拽

内嵌 `type: "table"` 子表默认允许拖动相邻列在表头或表体中的边界调整两列宽度，内部边界保持子表总宽不变；拖动最右列的右边界可改变子表总宽，其他列宽保持不变。展开子表超出视口时，共用父表底部横向滚动条，折叠或收窄后自动更新滚动范围；拖动表头超过 5px 后可调整同一固定区域内的列顺序，拖动时显示与父表一致的带蓝色高亮边框的半透明整列浮层、蓝色落点线和圆点，并显示与父表一致的列插入位置 tooltip，松手后以相同的 `320ms` 缓动完成列交换与浮层归位。父子边界重合时，子表可见区域内优先调整子表列宽。调整列宽时，从按下列边界开始全程显示贯穿子表高度的蓝色虚线指示线；边界进入父表可见业务列边界约 `6px` 范围内会自动吸附，指示线与父表边界重合。离开后恢复自由调整，松开或按 Escape 后隐藏指示线并保留当前宽度。吸附距离随表格缩放换算，并遵守相邻列的最小/最大宽度限制。每个子表独立保存当前实例中的布局，父表和其他子表不受影响；折叠后再展开仍保留，刷新页面不持久化。

-   子表级 `resizable: false` / `draggable: false` 分别关闭列宽和列顺序拖拽。
-   列级同名配置可禁止指定列参与调整；任一相邻列禁止调整时，该边界不可拖动。
-   列级 `minWidth`（默认 `40`）/ `maxWidth` 限制调整范围，同时满足相邻列的限制。
-   `showHeader: false` 时不提供拖拽入口。
-   同列子表首次手动调整后改用独立布局，不再自动跟随父表列宽和顺序；编辑、排序、过滤仍按原始列定位。

```ts
{
  type: "table",
  resizable: true,
  draggable: true,
  columns: [
    { title: "名称", dataIndex: "name", width: 220, minWidth: 100 },
    { title: "数量", dataIndex: "quantity", width: 120, minWidth: 60, maxWidth: 240 },
  ],
  dataSource: record.details,
}
```

### 分页尺寸缓存

设置表格 `storageKey` 后，用户选择或输入的每页条数会自动保存到 localStorage，下次创建表格时恢复。可通过 `pagination.cachePageSize: true` 明确开启；默认沿用开启行为，设置为 `false` 后禁止读取和写入已有缓存。不同表格应使用不同的键；不缓存页码，不影响滚动加载。无键、缓存无效、缓存超出当前 `minPageSize` / `maxPageSize` 范围或浏览器禁用存储时，继续使用默认配置。

显式传入 `pagination.pageSize` 时以受控值为准。外部负责请求的封装（如 WWISuperTable）应在首次请求前读取缓存，初始化自己的分页状态，避免只改变显示值而请求条数不一致：

```ts
import { getListTableStoredPageSize } from "@canvas-components/list-table";

const pagination = { cachePageSize: true, minPageSize: 5, maxPageSize: 500 };
const initialPageSize =
  explicitPageSize ?? getListTableStoredPageSize(storageKey, pagination) ?? 10;
// 将 initialPageSize 用于首次请求和受控 pagination.pageSize。
```

该读取方法也由 `@canvas-components/react-list-table` 导出。缓存只记录选中的尺寸，不保存自定义候选历史；React 分页器恢复到自定义尺寸后仍可删除，删除当前自定义项会将回退尺寸写入缓存。

## 本地配置缓存

汇总行右键“汇总方式”中提供“展示汇总方式前缀”，默认勾选。取消后仅显示结果值（如 `173`），勾选时显示 `求和: 173` 等前缀；主表、子表和复制文本使用同一展示规则。列配置可使用 `summary: { type: "sum", showTypePrefix: false }`，该开关随汇总配置缓存，自定义汇总标题不受影响。

配置稳定且唯一的 `storageKey` 后，可在右键通用“缓存到本地”分组中分别设置：列设置、排序、筛选、汇总、对齐、格式（数字、日期、货币等）、表格密度、缩放，以及当前列条件格式，默认全部开启。“列显示”和“条件格式”子菜单不重复提供缓存开关。通用分组中的“列设置”与标题栏“列设置”标题右侧的 Checkbox 共用状态，控制列宽、显隐、固定和顺序；未配置 `storageKey` 时禁用并提示。

关闭某类缓存不会撤销当前页面的操作，只清除该类持久化内容，刷新后使用传入配置；其他类别不受影响。各缓存开关自身也会保存。冻结行、复制、导出等没有对应持久化数据，不提供缓存开关。

可用 `cacheColumnSettings: false` 设置列设置缓存默认关闭；其他类别通过 `cachePreferences` 配置，如 `{ sort: false, filter: false, summary: false, alignment: false, dataFormat: false, density: false, zoom: false }`。未指定默认开启，已保存的用户选择优先。原生实例支持 `setColumnSettingsCache(enabled)`；自定义右键功能列表可通过 `cache` 控制分类缓存分组。

## 按列条件格式

规则通过 `backgroundColor` 和 `textColor` 分别设置背景色与文本颜色，编辑弹窗使用现有颜色选择器并实时预览。文本颜色覆盖当前单元格文字片段的颜色，选中和悬停时仍生效；不修改其他列、表头或汇总行。不提供旧规则文本颜色迁移逻辑。

通用“缓存到本地”分组中的“当前列条件格式”按列控制规则是否持久化，默认开启。关闭后保留当前页面的规则效果，但保存时移除该列已缓存的规则；刷新后只使用代码中配置的初始规则。可通过列属性 `cacheConditionalFormats: false` 设置默认关闭。

单条规则支持新增、删除多个条件，相邻条件之间分别选择“且 / 或”，且优先于或。所有条件比较当前列原始值，命中后使用该规则的样式。例如 `{ id: "score", conditions: [{ operator: "gte", value: 80 }, { relation: "and", operator: "lt", value: 90 }], backgroundColor: "#fff1b8", textColor: "#874d00" }`。每项 `relation` 表示与上一条件的连接关系，首项忽略；删除条件时保留剩余条件携带的关系。未指定时兼容旧的 `conditionRelation`，默认“且”。`conditions` 优先于旧的单条件字段；未配置时兼容原有 `operator/value/endValue`，空条件列表不命中。

右键业务叶子列表头 → **条件格式**，二级菜单以“颜色块 + 规则名称”展示当前列规则，未命名时显示“规则 1”等默认名称，悬停可查看完整名称和条件摘要；并提供“新增规则”“重置条件格式”。点击规则打开编辑弹窗，可修改条件、背景色或删除规则；取消不会改动表格。

规则通过 `scope` 设置作用效果：`"cell"`（默认）只作用于当前列命中的数据单元格，`"row"` 则将命中规则的背景色和文字颜色应用于整条数据行。行级规则按可见列顺序检查，首条命中优先；单元格级规则在同一单元格命中时优先于行级样式。两种规则都不修改表头或汇总行。条件背景优先于选中和悬停背景，保留选区边框；校验错误提示仍优先于条件背景。只对绘制中的数据行和单元格计算，不预扫描全量数据。

```ts
const columns = [
  {
    key: "amount",
    dataIndex: "amount",
    title: "金额",
    conditionalFormats: [
      {
        id: "high",
        name: "高金额",
        operator: "gte",
        value: 1000,
        backgroundColor: "#fff1b8",
        textColor: "#874d00",
      },
      {
        id: "negative",
        name: "负数",
        operator: "lt",
        value: 0,
        backgroundColor: "#ffccc7",
        textColor: "#a8071a",
      },
      {
        id: "review",
        name: "复核整行",
        scope: "row",
        operator: "gte",
        value: 5000,
        backgroundColor: "#e6f4ff",
        textColor: "#0958d9",
      },
    ],
  },
];
```

支持 `eq` / `neq`（原始值转文本后比较）、`gt` / `gte` / `lt` / `lte`（数值比较）、`between`（包含上下界，结束值使用 `endValue`）、`contains`（区分大小写）、`empty` / `notEmpty`。空值及非数值不参与数值比较。

配置 `storageKey` 后规则随列设置保存；“重置条件格式”只清空当前列规则，不清除其他样式或其他列规则。自定义右键菜单功能列表时，可通过 `conditionalFormat` 控制该入口。核心包通过 `HeaderContextMenuConfig.conditionalFormats` 和 `onChangeConditionalFormats` 向 UI 适配层提供配置。

## 分区 CSS 样式

原生 `ListTable` 和 `ReactListTable` 均支持 `styles`。Canvas 区域通过 CSS 属性映射到绘制参数，不创建单元格 DOM，不注入全局样式。

```ts
styles: {
  cell: { fontSize: '14px', padding: '2px 12px', borderColor: '#d9e1ec' },
  header: { backgroundColor: '#f0f9ff', color: '#075985', fontWeight: 700, textAlign: 'center' },
  body: { color: '#334155' },
  summary: { backgroundColor: '#f0fdf4', color: '#166534', textAlign: 'right' },
  activeCell: { backgroundColor: '#fef3c7', borderColor: '#d97706', borderWidth: '2px' },
  activeRow: { backgroundColor: '#e0e7ff', color: '#3730a3' },
  scrollVertical: { width: '14px', color: '#94a3b8', backgroundColor: '#f1f5f9', borderRadius: 4 },
  scrollHorizontal: { height: '12px', color: '#64748b', backgroundColor: '#f8fafc' },
  pagination: {
    root: { backgroundColor: '#f8fafc', color: '#334155', fontSize: '14px' },
    total: { color: '#64748b' },
    pageItem: { borderRadius: 4 },
    activePageItem: { backgroundColor: '#1677ff', color: '#fff' },
    sizeChanger: { width: 140 },
    quickJumperInput: { width: 64 },
  },
}
```

-   `cell` 是表头、表体和汇总单元格的通用默认值；分区覆盖通用值，列级 `headerStyle` / `cellStyle` / `summaryStyle` 优先。
-   Canvas 分区支持 `backgroundColor`、`color`、`fontSize`、`fontWeight`、`fontFamily`、`textAlign`、`verticalAlign`、`padding`、`paddingInline`、`paddingBlock`、`borderColor`、`borderWidth`。长度只支持非负数字或 `px`，`padding` 支持一值或“上下 左右”两值；不支持百分比、`em` 或 DOM 布局属性。
-   `activeCell` 支持背景、文字和边框，`activeRow` 支持背景与文字；仅改变已有选中状态的绘制，不改变选择模式。校验错误提示仍优先。
-   滚动条 `color` 对应滑块、`backgroundColor` 对应槽色；纵轴 `width`、横轴 `height` 对应厚度。显式 `scrollbar.vertical/horizontal: false` 仍禁止对应轴显示。
-   `pagination` 按节点直接应用 DOM CSS，使用 camelCase 属性名，数字长度按 React DOM 规则处理；仅影响当前实例。通过原生 UI 回调自行渲染分页器时，从 `PaginationConfig.styles` 读取并应用样式。当前分页占位高度仍由表格密度决定，避免设置超出该高度的高度或纵向间距。

分页器支持以下节点：

| 节点 | 作用 |
| --- | --- |
| `root` | 分页器根容器，颜色、字体等可向内部继承 |
| `total` | 总条数文本 |
| `pages` | 页码列表容器 |
| `pageItem` | 普通页码按钮；简易模式下为页码文本 |
| `activePageItem` | 当前页按钮，叠加并覆盖 `pageItem` |
| `prevButton` / `nextButton` | 上一页 / 下一页按钮 |
| `prevIcon` / `nextIcon` | 上一页 / 下一页箭头，通过 `borderColor` 设置箭头颜色 |
| `ellipsis` | 页码省略号 |
| `sizeChanger` | 分页尺寸选择控件，不包含弹出选项面板 |
| `quickJumper` | 快速跳转区域容器 |
| `quickJumperText` | “跳至”和“页”文本 |
| `quickJumperInput` | 跳转输入控件外框，可设置宽度、背景与边框 |

节点样式优先于默认样式；未配置节点保持原样。独立使用 `ReactPagination` 时也支持同名 `styles`，其中 `styles.root` 优先于 `style`。

-   更新或移除 `styles` 后即时生效；不额外持久化 `styles` 对象，已有列配置缓存中的对齐设置仍优先。嵌套子表格的独立内容样式仍通过其列/内容配置指定。

文档站“主题”示例增加了“启用分区 CSS 样式”开关，可切换验证。

## 安装方法

```bash
pnpm add @canvas-components/list-table
```

最低环境要求：

-   `Node.js >= 18.12.0`
-   `pnpm >= 9.0.0`

## 使用方法

```ts
import { ListTable } from "@canvas-components/list-table";

const container = document.querySelector("#table") as HTMLElement;

const table = new ListTable(container, {
  type: "list",
  width: "100%",
  height: 480,
  rowKey: "id",
  columns: [
    { key: "name", title: "姓名", dataIndex: "name", width: 180 },
    { key: "age", title: "年龄", dataIndex: "age", width: 120, align: "right" },
  ],
  dataSource: [
    { id: 1, name: "张三", age: 28 },
    { id: 2, name: "李四", age: 31 },
  ],
});

table.mount();
```

## 属性说明

### 实例配置 `ListTableOptions`

| 属性 | 类型 | 说明 |
| --- | --- | --- |
| `type` | `"list"` | 表格类型，当前稳定支持列表表格 |
| `rowKey` | `string | number | Array<string | number> | ((record, index) => string | number)` | 行主键解析规则 |
| `columns` | `ListTableColumn[]` | 列配置集合 |
| `width` | `number | string` | 表格宽度 |
| `height` | `number | string` | 表格高度 |
| `dataSource` | `RecordType[]` | 表格数据源 |
| `emptyText` | `string` | 空状态文案 |
| `theme` | `Partial<ListTableTheme>` | 主题覆盖 |
| `striped` | `boolean` | 是否开启斑马纹 |
| `highlightMode` | `"cell" | "row" | "column" | "cross"` | 点击高亮模式 |
| `keyboardNavigation` | `{ tabWrap?: boolean; verticalWrap?: boolean }` | 键盘边界导航；两项默认均为 `true` |
| `contextMenu` | `false | ListTableContextMenuOptions` | 右键菜单配置 |
| `grouping` | `ListTableGroupingOptions` | 分组栏、初始分组列与变化回调 |
| `rowHeight` | `number | "auto"` | 行高 |
| `headerRowHeight` | `number` | 表头单行高度 |
| `summaryRowHeight` | `number` | 汇总行高度 |
| `overscanRowCount` | `number` | 虚拟滚动预渲染行数 |
| `query` | `ListTableQueryOptions` | 排序、过滤、合并单元格配置 |
| `rowSelector` | `boolean | ListTableRowSelectorOptions` | 最左侧空白整行选择器配置 |
| `rowSelection` | `ListTableRowSelectionOptions` | 行选择配置 |
| `expandable` | `ListTableExpandableOptions` | 树表 / 展开行配置 |
| `pagination` | `false | ListTablePaginationOptions` | 分页或滚动加载配置 |
| `scrollbar` | `ListTableScrollbarOptions` | 滚动条配置 |
| `carouselScroll` | `ListTableCarouselScrollOptions` | 自动轮播滚动配置 |
| `stretchColumns` | `boolean` | 列总宽不足时是否拉伸补齐 |
| `resizable` | `boolean` | 是否开启列宽拖拽 |
| `storageKey` | `string` | 列配置、查询、缩放和密度持久化键 |
| `draggable` | `boolean` | 是否开启列拖拽排序 |
| `tableId` | `string` | 表格唯一标识 |
| `rowDrag` | `ListTableRowDragOptions` | 行拖拽配置 |
| `debug` | `ListTableDebugOptions` | 调试配置 |

通过 `stickToBottom: true` 开启动态数据平滑吸底（默认关闭），React 使用 `<ReactListTable stickToBottom />`。鼠标滚轮、拖动滚动条和触摸滚动均可正常浏览历史；停止滚动后默认等待 3 秒，再平滑滚向最新底部。配置 `stickToBottom={{ enabled: true, resumeDelay: 5000 }}` 可将等待时间改为 5 秒（`resumeDelay` 单位毫秒，范围 0～600000）。右键“吸底”二级菜单可切换开关、选择常用等待时间或输入自定义秒数。菜单设置在相同配置的数据更新中保留，显式改变对应配置时同步新值；可用 `contextMenu.disabledFeatures: ["stickToBottom"]` 隐藏该菜单。

`keyboardNavigation.tabWrap` 控制 Tab / Shift+Tab 在行尾 / 行首是否进入相邻行；`verticalWrap` 控制 ↑ / ↓ 在列首 / 列尾是否进入相邻列。设为 `false` 时到对应边界即停止，不改变当前活动单元格。

### 分批加载与服务端汇总

数据仍在异步生成或分批加载时，设置表格顶层属性 `loading: true`。此时汇总行及标题正常显示，统计结果保持空白，也不会计算首批临时数据。完整数据就绪后，将完整 `dataSource` 与 `loading: false` 一起更新，表格自动计算汇总并在完成后统一显示结果。默认值为 `false`，正常的空数据仍可汇总为零。

使用服务端汇总时，通过 `query.summaryValues` 传入以列 `key` 为键的对象或 Map。若数据和汇总分别请求，可保持 `loading: true`，待两者都返回后再设为 `false`；此配置同样支持 React 适配包，外部无需控制汇总计算状态。

```ts
const options = {
  dataSource: rows,
  loading,
  query: {
    // 服务端汇总可选；不传则使用本地异步汇总。
    summaryValues: serverSummaryValues,
  },
};
```

### 列配置 `ListTableColumn`

| 属性 | 类型 | 说明 |
| --- | --- | --- |
| `key` | `string` | 列唯一标识 |
| `title` | `string` | 列标题 |
| `dataIndex` | `string | number | Array<string | number>` | 取值路径 |
| `children` | `ListTableColumn[]` | 子列，用于多级表头 |
| `width` | `number` | 列宽 |
| `minWidth` / `maxWidth` | `number` | 允许调整的最小 / 最大列宽 |
| `align` | `"left" | "center" | "right"` | 内容对齐 |
| `headerAlign` | `"left" | "center" | "right"` | 表头水平对齐，未传时回退到 `align` |
| `fixed` | `"left" | "right"` | 固定列 |
| `hidden` | `boolean` | 是否隐藏 |
| `ellipsis` | `boolean` | 超出是否省略 |
| `editable` | `boolean | (text, record, index) => boolean` | 是否允许编辑 |
| `formItemProps` | `ListTableFormItemPropsConfig` | 编辑器配置 |
| `resizable` | `boolean` | 单列是否允许调整宽度 |
| `draggable` | `boolean` | 单列是否允许拖拽 |
| `allowSort` | `boolean` | 是否开启排序 |
| `sorter` | `ListTableSorter<RecordType>` | `multiple` 指定优先级，`compare(a, b)` 自定义比较 |
| `defaultSortOrder` | `"ascend" | "descend"` | 默认排序方向，可配合 `sorter.multiple` |
| `allowFilter` | `boolean` | 是否开启过滤 |
| `filterOptions` | `ListTableFilterOption[]` | 精确过滤选项 |
| `cellType` | `ListTableCellContent["type"]` | 内建单元格类型 |
| `moneyFormat` | `ListTableMoneyFormatOptions` | 金额格式配置，仅在 `cellType: "money"` 时生效 |
| `dataFormat` | `"default" | "text" | "number" | "thousands" | "decimal" | ...` | 右键菜单设置的数据展示格式 |
| `cellStyle.verticalAlign` | `"top" | "middle" | "bottom"` | 表体垂直对齐 |
| `headerStyle.verticalAlign` | `"top" | "middle" | "bottom"` | 表头垂直对齐 |
| `render` | `(value, record, rowIndex, column) => ...` | 自定义渲染 |
| `onCell` | `(value, record, rowIndex, column) => { rowSpan?: number; colSpan?: number }` | 单元格跨度控制 |
| `summary` | `boolean | ListTableSummaryConfig` | 汇总配置 |
| `summaryTitle` | `string` | 汇总标题文本 |

### 常见嵌套能力

| 配置 | 说明 |
| --- | --- |
| `query` | 排序、筛选、远程查询、自动合并单元格 |
| `rowSelector` | 空白整行选择器，单击选中一行、纵向拖拽选中连续多行 |
| `rowSelection` | checkbox / radio 行选择 |
| `expandable` | 树形数据、详情展开、展开列 |
| `pagination` | 按钮分页或滚动加载 |
| `rowDrag` | 行拖拽、跨表拖拽、拖放回调 |
| `contextMenu` | 复制、导出、排序、冻结、列显示、分组栏、对齐、数据格式、密度、缩放等菜单能力 |

分组功能默认关闭，只有显式传入 `grouping: {}` 才会启用右键菜单中的分组入口。`grouping.visible` 控制 Canvas 顶部分组栏初始显隐，默认 `false`；`grouping.columnKeys` 按顺序声明初始分组层级。显示分组栏后可将列头拖入栏内；分组列会从表头和表体隐藏，仅以 Canvas 标签展示，移除标签会立即恢复该列。右键分组栏可隐藏分组栏；`grouping.onChange` 会在标签增删时收到最新列 key 列表。点击分组标题可折叠或展开该分组，重新设置分组列后会清除折叠状态。

`rowSelection.selectRowByClick` 控制点击普通表体区域时是否同步切换 checkbox / radio 选择状态，默认关闭。该配置直接复用表格内部选择状态，无需通过外部 `key` 强制重新创建表格；查看详情等业务点击仍使用 `onRow().onClick`。

`rowSelector` 与 `rowSelection` 相互独立。默认在最左侧展示宽度为 `12px` 的空白选择器列；传入 `{ width: 32 }` 可自定义宽度，传入 `false` 可隐藏。该列只建立 Canvas 整行选区，不修改 checkbox / radio 的选中数据。

## 方法说明

| 方法 | 签名 | 说明 |
| --- | --- | --- |
| `constructor` | `new ListTable(container, options)` | 创建实例 |
| `mount` | `() => void` | 挂载表格 |
| `updateOptions` | `(options) => void` | 更新配置并刷新 |
| `getDebugSnapshot` | `() => ListTableDebugSnapshot | null` | 获取调试快照 |
| `validate` | `() => Promise<RecordType[]>` | 手动触发校验，失败时抛出 `ListTableValidationFailure` |
| `exportXlsx` | `(options?: ListTableExportXlsxOptions) => void` | 异步导出全部原始数据为 XLSX，可配置文件名和汇总行 |
| `scrollTo` | `(options: ListTableScrollToOptions) => void` | 滚动到指定行 |
| `destroy` | `() => void` | 销毁实例 |

列配置可通过 `settingTitle`、`hideInSetting`、`disableHide` 约束列设置中的标题和隐藏权限。`hidden` 是业务动态隐藏约束，默认 `false`，不读写缓存；`visible` 是用户显隐偏好，默认 `true`，按 `storageKey` 保存。实际显示为 `hidden !== true && visible !== false`。旧缓存中的显隐 `hidden` 不再恢复，列宽、顺序和固定配置继续保留。详见 [业务显隐与用户列偏好](https://npmcn.com/package/%40canvas-components/list-table/docs/column-visibility.md)。

### XLSX Worker 导出

导出默认先确认文件名称，输入框默认填入配置的名称，后缀单独显示且不可修改。表格选项 `exportOptions: { fileName: "报表", promptFileName: false }` 可跳过弹窗；单次 `exportXlsx({ promptFileName: false })` 可覆盖默认行为。原生接入通过 `ui.onExportNameRequest` 自定义弹窗，未提供时使用浏览器输入框。

当前显示汇总行时，XLSX 默认在全部数据末尾追加汇总行（子表格独立判断）；显式设置 `includeSummary: false` 可排除汇总行，`true` 可强制追加。汇总按导出的全量数据与当前列配置计算。

`exportXlsx()` 默认对 1 万行及以上数据尝试 Worker；现有调用无需修改。表格加载提示会显示已处理行数与文件生成阶段。取值和 `render` 回调仍在主线程执行，工作表构建、文件编码交给 Worker。

```ts
const controller = new AbortController();
table.exportXlsx({
  fileName: "表格数据",
  includeSummary: true,
  worker: "auto", // true：始终尝试；false：使用主线程
  maxRowsPerFile: 100_000, // 默认十万行；20 列以内无需降低每份行数
  signal: controller.signal,
  onError: (error) => console.error("导出失败", error), // 可替换为业务提示
  onProgress: ({ phase, completedRows, totalRows }) => {
    console.log(phase, completedRows, totalRows);
  },
});
// 需要取消时调用 controller.abort()。
```

大数据按行数和单元格预算自动拆成多个独立 XLSX，文件名追加 `_001`、`_002`。每份保留表头，汇总只追加在全部数据末尾。逐份生成、下载并释放，不同时持有全部工作簿。进度包含 `fileIndex`、`fileCount`；可通过 `saveFile(blob, fileName, part)` 接管保存，等待其返回后才生成下一份。

浏览器可能要求允许下载多个文件。取消或失败会停止后续文件，已经下载的文件保留。每份默认最多 10 万行（含汇总尾行、不含表头），20 列以内按此行数分文件；超过 20 列时受 2,000,020 个单元格预算限制，适当减小每份行数。长文本另有 16M UTF-16 码元安全预算，超限时需调低 `maxRowsPerFile`。Worker 不可用时回退；CSV、TXT、JSON 不受影响。千万行多列数据仍建议服务端导出。

## 内建单元格内容

`render` 支持直接返回结构化内容，内建类型包括：

-   `text`
-   `money`
-   `image`
-   `qrcode`
-   `barcode`
-   `progress`
-   `chart`
-   `rate`
-   `button`
-   `tag`
-   `color`
-   `icon`
-   `checkbox`
-   `radio`
-   `switch`
-   `link`

`icon` 当前内置 `star`、`sun`、`moon`、`check`（√）和 `close`（×）。

### 开关二次确认

`switch` 内容可配置 `popconfirm`，与危险按钮复用同一套确认浮层和文案字段。点击后先确认，确认时才触发 `onClick`；取消或禁用时不触发回调。未配置 `popconfirm` 时直接触发回调。开关仍由业务通过 `checked` 控制，组件不会自动修改记录。

```ts
render(value, record) {
  return {
    type: "switch",
    checked: Boolean(value),
    popconfirm: {
      title: value ? "确认停用？" : "确认启用？",
      description: "确认后将更新启用状态。",
      okText: "确定",
      cancelText: "取消",
    },
    onClick: () => updateActive(record.id, !value),
  };
}
```

原生包在未提供 `ui.onDangerConfirmRequest` 时回退使用浏览器 `confirm`；React 适配包自动展示确认浮层。

### 金额单元格示例

```ts
const columns = [
  {
    title: "金额",
    dataIndex: "amount",
    width: 140,
    align: "right",
    cellType: "money",
    moneyFormat: {
      symbol: "¥",
      thousandsSeparator: true,
      decimalPlaces: 2,
    },
  },
  {
    title: "结算金额",
    dataIndex: "settlementAmount",
    width: 160,
    align: "right",
    render(value) {
      return {
        type: "money",
        value: value as number,
        symbol: "$",
        thousandsSeparator: ",",
        decimalPlaces: 1,
      };
    },
  },
];
```

## 行点击事件

`onRow` 使用统一的回调结构。由于表格由 Canvas 渲染，支持整行点击事件及 `style.backgroundColor`、`style.color`。业务可按记录 key 控制持续高亮，初始渲染、冻结列及悬停时均生效；校验错误样式优先。

```ts
const table = new ListTable(container, {
  columns,
  dataSource,
  onRow: (record, rowIndex) => ({
    style:
      record.id === selectedId
        ? { backgroundColor: "#d6eaff", color: "#003a8c" }
        : undefined,
    onClick: (event) => {
      console.log(record, rowIndex, event);
    },
  }),
});
```

## 推荐搭配

-   原生 DOM 场景：直接使用 `ListTable`
-   React 场景：优先使用 `@canvas-components/react-list-table`
-   二维码 / 条形码 / 图表单元格：配合 `@canvas-components/qrcode`、`@canvas-components/barcode`、`@canvas-components/chart`

## 滚动条配置

`scrollbar` 同时适用于原生表格与 React 适配组件。通用配置由 `horizontal`、`vertical` 单独覆盖；不配置时保留原有外观。

```ts
scrollbar: {
  thickness: 10,
  thumbColor: '#8793a5',
  trackColor: '#f1f5f9',
  buttonColor: '#475569',
  thumbRadius: 4,
  horizontal: { thickness: 8, thumbColor: '#1677ff' },
  vertical: { thickness: 14, trackColor: '#e2e8f0' },
}
```

-   `thickness`：横向滚动条高度、纵向滚动条宽度，单位 px，默认 10，最小 6。
-   `thumbColor` / `trackColor` / `buttonColor`：滑块、滚动槽、两端箭头颜色。
-   `thumbRadius`：滑块圆角，`0` 为直角；不传时保持胶囊形状。
-   `horizontal: false` 或 `vertical: false`：单独隐藏某一轴，也可设置该轴的 `visible: false`。
-   `visible: false`：同时隐藏两轴，优先于单轴设置。隐藏后释放对应槽位，仍可通过滚轮或程序滚动。

配置仅作用于当前 Canvas 表格，不修改全局浏览器滚动条样式。

### 级联选择编辑（Cascader）

`formItemProps.valueType: "cascader"` 使用多列展开的单选/多选级联选择器，配置支持级联选择。父表和嵌套子表使用相同配置；React 适配包提供编辑界面，原生包仅提供配置与路径格式化，不引入 React。

```ts
{
  title: '所属地区', dataIndex: 'region', editable: true, width: 240,
  formItemProps: {
    valueType: 'cascader', showSearch: true, allowClear: true,
    expandTrigger: 'click', changeOnSelect: false,
    options: [{ label: '浙江', value: 'zj', children: [
      { label: '杭州', value: 0, children: [{ label: '西湖区', value: 'xh' }] },
      { label: '停用地区', value: 'disabled', disabled: true },
    ] }],
  },
}
// 行数据：{ region: ['zj', 0, 'xh'] }
```

-   值为 `(string | number)[]`，清空将编辑草稿更新为 `[]`，保持编辑状态，可继续选择、失焦提交或按 Escape 取消。默认显示完整标签路径，以 `/` 分隔；可用 `displayRender(labels, selectedOptions)` 定制。显式 `format` 优先级更高。
-   `showSearch` 默认 `false`，开启后按完整路径搜索；`expandTrigger` 支持 `click`（默认）或 `hover`。
-   `changeOnSelect` 默认 `false`；开启后点击中间级更新编辑草稿，失焦或 Tab 提交，选择末级立即提交。
-   方向键在级联菜单中导航，Enter 选择，Escape 取消本次编辑，Tab 切换编辑单元格。
-   支持单选末级、单选任意级、多选父级回填和多选末级回填。使用标准 `label/value/children` 节点；暂不包含异步加载及自定义字段映射。
-   文档站“单元格编辑”示例新增“所属地区（级联）”列。

多选配置如下：

```ts
formItemProps: {
  valueType: 'cascader',
  options: regionOptions,
  multiple: true,
  showCheckedStrategy: 'SHOW_PARENT', // 或 'SHOW_CHILD'
  showSearch: true,
}
// 多选值是二维路径数组，例如：[['zj', 'hz', 0], ['js', 'nj', 1]]
```

-   `multiple` 默认 `false`；开启后复选框切换当前节点及其可用后代，父级支持半选。点击分支文案仅展开，点击末级文案可勾选。
-   `showCheckedStrategy` 默认 `SHOW_PARENT`，全部可用子级选中时回填父级路径；`SHOW_CHILD` 回填全部已选末级路径。该策略同时作用于变更回调、输入框和单元格文本。
-   多选路径以 `；` 分隔回显，`displayRender` 逐条处理路径。禁用节点不参与父子联动，已有禁用值不会被其他分支操作误删。
-   多选勾选及清空不会退出编辑；失焦或 Tab 提交，Escape 取消。方向键导航，Enter / 空格切换当前选项（搜索输入中的空格仍用于输入）。`changeOnSelect` 仅影响单选。
-   示例新增“级联单选（任意级）”“级联多选（父级回填）”“级联多选（末级回填）”列。

### 树选择编辑（TreeSelect）

使用 `formItemProps.valueType: 'tree-select'`，配置支持树形选择。父表和嵌套子表使用同一套编辑配置。

```ts
{
  title: '所属部门', dataIndex: 'departments', editable: true, width: 280,
  formItemProps: {
    valueType: 'tree-select',
    multiple: true, // 不传则单选
    showSearch: true,
    allowClear: true,
    treeDefaultExpandAll: true,
    treeData: [{ title: '组织架构', value: 'root', selectable: false, children: [
      { title: '生产中心', value: 'production', children: [
        { title: '织造车间', value: 0 },
        { title: '检验车间', value: 'inspection' },
      ] },
      { title: '停用部门', value: 'disabled', disabled: true },
    ] }],
  },
}
// 单选值：0；多选值：[0, 'inspection']，不是 Cascader 的路径数组。
```

-   `treeData` 使用 `title/value/children`，`value` 必须在树内唯一；数字 `0` 与字符串 `'0'` 严格区分。`disabled` 禁止选择当前节点，`selectable: false` 用于只能展开的分组。
-   `multiple` 默认 `false`；多选独立切换各个节点，不进行父子联动。单元格和输入框回显节点标题，多选使用 `；` 分隔，显式 `format` 可覆盖单元格显示。
-   `showSearch` 单选默认关闭、多选默认开启，按标题搜索并保留祖先上下文；搜索不修改原展开状态。
-   `treeDefaultExpandAll` 默认 `false`；也可使用 `treeDefaultExpandedKeys` 指定默认展开节点，依据节点的 `key`（省略时使用 `value`）。已选节点的祖先自动展开。
-   单选选择后提交；多选连续选择不提交，失焦或 Tab 提交。清空单选为 `null`、多选为 `[]`，保持焦点和弹层，可继续选择；Escape 取消编辑。
-   上下方向键导航，左右方向键展开/收起，Enter 或空格选择。搜索输入中的空格用于输入。
-   本次实现基础单选与独立多选，不包含 `treeCheckable`、`treeCheckStrictly`、异步加载、`labelInValue` 和自定义字段映射。
-   “单元格编辑”示例新增“树选择（单选）”“树选择（多选）”列。组件内部索引和值处理放在组件目录，不增加公共工具包接口。

### 绘制到已有 Canvas 上下文

`drawListTableToCanvas({ ctx, width, height, options, requestRender })` 使用现有列配置绘制静态表格，复用布局、单元格、表头与汇总规则，不创建表格 DOM 实例，也不重置目标 Canvas 的尺寸或变换。`width`、`height` 为逻辑像素，调用方可通过 `ctx.translate/scale` 定位和缩放。`requestRender` 用于图片加载后的重绘通知。内容按指定边界裁剪；不显示排序、筛选和滚动条等交互控件。汇总同步计算，适合打印和有限数据量的离屏绘制。

## 清空行选择

原生实例调用 `table.clearRowSelection()`。该方法清空通过选中 key 设置的行高亮、行勾选和 Shift 选择锚点，配置 `rowSelection` 且选择发生变化时触发 `rowSelection.onChange([], [], { type: "none" })`。受控模式请在回调中同步 `selectedRowKeys`。

过滤面板勾选或取消过滤项并即时应用时，会立即清空全部已选行，不保留仍在过滤结果中的勾选。

调用 `table.setSelectedRowKeys(["1", "2", "3"])` 可以主动设置行高亮，无需配置 `rowSelection`，也不会新增 checkbox / radio 列。配置 `rowSelection` 时同时同步勾选并触发 `onChange`；单选模式只保留第一个 key。传入空数组等同清空，普通配置更新会保留未受控的选中 key。

普通按钮独立配置 `popconfirm` 即可在执行 `onClick` 前确认，无需设置 `danger`；禁用按钮不发起确认。汇总栏显示继续按现有缓存规则恢复用户选择；仅切换或恢复密度不会主动创建汇总栏，没有汇总配置时重置列设置也不会新增汇总栏。

表头文字区域优先选择并支持复制；拖动表头空白区域调整列顺序。完整交互见文档站“行选择”的业务状态与缓存回归示例。

展开行子表在手动调整列宽或列顺序后使用独立布局。父表配置 `storageKey` 且开启 `cacheColumnSettings` 时，子表的列宽与列顺序一同缓存；缓存按父行 `rowKey`、所在列和内容索引隔离，建议配置稳定的 `rowKey`。刷新或重新挂载后恢复，关闭列缓存后不再保存这些布局。展开行示例提供“重新挂载验证缓存”按钮。

禁用的原生按钮内容（`type: "button", disabled: true`）不会触发内容、单元格、行或列的点击回调，也不会改变活动单元格和鼠标选区；同一单元格内其他启用按钮仍可独立交互。

### 同一单元格编辑多个字段

`formItemProps` 兼容配置对象、配置数组，以及返回对象或数组的函数。数组每项直接配置 `key`、`dataIndex`、`valueType`、`rules`、`onChange`，不需要额外的 valueType。`key` 在当前单元格内唯一；`dataIndex` 相对行记录，嵌套属性使用 `['measurement', 'quantity']`，写入保留未配置属性。`label` 提供无障碍名称，`width` 为固定像素或 fr 比例，默认 `1fr`；可设置 `disabled`、`readOnly`。

```ts
formItemProps: (_value, record, _index, context) => [
  {
    key: "quantity",
    dataIndex: "quantity",
    label: "数量",
    valueType: "number",
    width: "1fr",
    rules: [{ required: true, message: "请填写数量" }],
    onChange: (quantity, { draftRecord, record }) => ({
      totalPrice: Number(quantity ?? 0) * (draftRecord ?? record).unitPrice,
    }),
  },
  {
    key: "unit",
    dataIndex: "unitId",
    label: "单位",
    valueType: "select",
    width: 88,
    options:
      (context?.draftRecord ?? record).kind === "weight"
        ? weightUnits
        : lengthUnits,
    rules: [{ required: true, message: "请选择单位" }],
  },
];
```

函数的 `record` 保持会话基准快照，可选第四参数的只读 `draftRecord` 提供尚未提交的候选行。数组内回调接收当前项值，context 的 `dataIndex` 是该项路径，并增加 `itemKey` 与可选 `draftRecord`；同步补丁按操作顺序累计，整组提交时一次写入，不递归触发其他回调。回调返回 `false`、异常或非法补丁会保持编辑；普通校验失败仍保存整组记录并按项标错，`validate()` 包含没有独立列的字段。数字 `0` 与单位编码 `0` 均为有效值。

Tab/Shift+Tab 在组内遍历，越过首尾才提交并导航；Enter 提交整组，子选择弹层优先处理确认；Escape 先关闭子弹层，再取消整组。非编辑状态也按各项 `width` 分区绘制，空字段保留位置，长文本仅在本项内省略；进入/退出编辑时各字段位置保持一致。复杂展示使用列 `render`。列排序、筛选继续使用列自身 `dataIndex`。空数组不提供编辑，单项数组仍要求显式绑定。

首期数组支持 text、number、select、auto-complete、table-select、year、quarter、month、date、time、datetime、date-range、timerange、datetime-range、input-range、math-interval、number-unit。会话中保持项的顺序、key、路径及类型稳定，不支持嵌套数组、多行布局、动态增删项及 upload/color/tree-select/cascader；这些类型的原有对象配置不受影响。原生宿主须使用声明数组编辑能力的编辑工厂。中文示例位于文档站“单元格编辑 → 多字段组合编辑”。

数组编辑项在非编辑态按各自宽度保留分区，校验背景与 tooltip 仅作用于出错表单，提示锚定该表单区域中间；编辑态不展示tooltip，非编辑态鼠标移入出错表单区域时展示。日期、范围、数学区间及数字单位默认展示沿用编辑控件布局；单元格 padding 传递给表单，避免重复内边距。显式 `format` 与列 `render` 的自定义展示仍优先。

## 紧凑图片与表头操作

图片内容在绘制前按单元格扣除内边距后的可用宽高等比缩小，仅缩小不放大；不会为图片增高固定行高。图片原配置、自动行高测量和原图预览保持原尺寸。

表格和列均支持 `showHeaderActions?: boolean`（默认 `true`）。设为 `false` 时隐藏排序、筛选、固定操作图标及编辑标记，不预留图标空间。表格级关闭优先于列级开启；斜线表头仍需 `headerDiagonal.showActions:true` 才显示操作。普通表头的排序图标同时遵守 `allowSort:false` 和 `sorter:false`。此选项只控制图标显示，右键菜单、拖拽、缩放和编辑能力仍由各自配置决定。

运行时密度、滚动条、列顺序和列配置偏好按 `storageKey` 隔离。切换 key 时先使用新身份源配置，再读取新身份缓存；业务 `hidden` 仍不缓存。

## 常见问题

### @canvas-components/list-table 是什么？

框架-不可知列表表核心引擎\.

### 如何安装 @canvas-components/list-table？

在项目目录运行 npm install @canvas-components/list-table，或使用 pnpm add / yarn add / bun add。

### @canvas-components/list-table 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @canvas-components/list-table 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @canvas-components/list-table 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=18\.12\.0。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @canvas-components/list-table 可以商用吗？

@canvas-components/list-table 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @canvas-components/list-table 的下载量有多少？

根据 npm 官方下载统计，@canvas-components/list-table 在 2026/10/09 – 2026/11/07 这 30 天内被下载 6,009 次，日均约 200 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @canvas-components/list-table 还在维护吗？

最新版本 0\.3\.58 发布于 2026/11/09（今天）；至今共发布 66 个版本，其中过去 12 个月发布了 66 个；首次发布于 2026/08/19。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

