# 桌面数据表格交互规范 ## 目录 1. 适用范围与交互契约 2. 状态模型 3. 指针事件与优先级 4. 筛选、排序与搜索 5. 勾选、多选与批量操作 6. 键盘与无障碍 7. 数据变化、分页与虚拟化 8. 视觉与反馈 9. 测试矩阵 10. 交付检查清单 ## 1. 适用范围与交互契约 为展示结构化多列数据且支持选择、筛选、操作或编辑的表格、网格和高密度列表使用本规范。只读报表也要定义排序、复制、焦点和空状态;可编辑数据网格还要定义验证、提交和撤销。 在设计或编码前写出交互契约,至少回答: - 选择单位是整行、单元格还是列;支持单选、连续多选还是非连续多选; - 复选框代表“批量选择”还是一个真实业务字段; - 单击行只选择,还是还会导航、展开或编辑; - 双击行执行默认命令、进入编辑,还是禁用; - 右键未选中行与已选中行时,命令作用于哪一组对象; - 筛选作用于本地数据、当前页、已加载数据还是服务端完整结果; - 排序、筛选、刷新、分页后是否保留选择和勾选; - 主键、权限和数据变化如何使已有选择失效; - 每个鼠标操作对应什么键盘和无障碍操作。 若产品未指定,采用本规范的推荐默认值。不要把框架初始属性当作已经确认的产品行为。 ## 2. 状态模型 ### 分离四类状态 | 状态 | 含义 | 推荐规则 | |---|---|---| | 当前行/当前单元格 | 后续键盘命令的目标和导航位置 | 同一表格通常只有一个;刷新后尽量保持稳定主键 | | 键盘焦点 | 当前接收键盘输入的元素 | 必须始终可见;可能在单元格内按钮或编辑器上 | | 选择集 | 详情、上下文命令或批量操作的对象 | 使用稳定记录 ID,不使用视图行号 | | 勾选集 | 选择复选框或业务布尔字段的值 | 先确定语义;不得默认等同选择集 | ### 选择复选框与业务复选框 - **选择复选框:** 复选框只是多选的可见入口,勾选集与选择集是同一状态;表头复选框控制明确范围内的选择。 - **业务复选框:** 复选框表示“启用”“已审核”等领域字段,与行选择完全独立;列标题必须表达业务含义,不使用无标签的选择列样式。 - 同一表格同时需要两者时使用不同列、不同标题/工具提示和不同视觉反馈,并在规格中分别命名。 - 不要让整行单击切换业务复选框。不要维护两个看似相同但可能不同步的选择数组。 ### 状态不变量 - 排序和筛选改变视图顺序,不改变记录 ID。 - 当前行可以未被多选;选中行也不一定拥有单元格焦点。 - 失效、无权限或被删除的记录必须从操作集合移除并告知用户。 - 行号只用于展示位置,不能作为选择、缓存、编辑或命令参数。 - 视觉上区分 hover、当前、焦点、选中、勾选、编辑、错误和禁用状态。 ## 3. 指针事件与优先级 ### 推荐交互矩阵 | 输入 | 目标 | 推荐结果 | |---|---|---| | 左键单击 | 行的非交互区域 | 将该行设为当前行;无修饰键时单选,Ctrl 切换,Shift 从锚点范围选择 | | 左键单击 | 选择复选框 | 切换该行选择状态;更新当前行,但不触发行默认操作 | | 左键单击 | 业务复选框 | 仅切换/提交该字段;不触发行默认操作,选择是否变化须显式规定 | | 左键单击 | 按钮、链接、菜单或编辑器 | 仅执行该控件行为;事件不得冒泡成行操作 | | 左键双击 | 行的非交互区域 | 执行唯一的非破坏性默认命令,或按契约进入编辑 | | 右键/长按 | 未选中行 | 将其设为当前且唯一选中行,再打开针对该行的上下文菜单 | | 右键/长按 | 已选中行 | 保留现有多选,打开针对整个选择集的菜单 | | 右键 | 空白区域/表头 | 不借用旧行上下文;显示表格级/列级菜单或不显示菜单 | ### 事件优先级 按“单元格内控件 → 编辑器 → 行 → 表格空白区域”处理命中目标,内层处理后阻止外层重复执行。不得使用任意延时猜测单击还是双击。 单击行只负责当前项和选择,不执行打开、删除、提交等业务副作用。这样双击产生的两次单击不会重复执行业务命令。双击仅在同一有效记录的非交互区域触发;滚动条、复选框、按钮、链接、输入框和空白区不得触发。 双击默认命令必须满足: - 非破坏性,通常是打开详情、预览或开始编辑; - 同时提供 Enter、显式按钮或菜单入口; - 与内联编辑的双击触发二选一,不同时绑定; - 数据变化后按稳定 ID 再次确认目标仍存在且允许操作。 上下文菜单打开前先解析命中行和有效选择集。命令文案、启用状态和作用对象数量必须一致;菜单关闭不清除选择。提供 Shift+F10、菜单键或可见命令入口。 ## 4. 筛选、排序与搜索 ### 筛选模型 - 明确全局搜索、列筛选、固定范围筛选和高级条件之间是 AND 还是 OR。 - 按字段类型提供合适运算:文本包含/等于,数字和日期范围,枚举多选,布尔三态,空值/非空。 - 显示每个活动筛选、结果数量和“清除全部”;仅靠输入框内容或列标题颜色不足以表达状态。 - 区分“无数据”与“筛选后无结果”,后者保留条件并提供清除入口。 - 定义大小写、重音、全半角、区域设置、时区、空白和无效输入规则。 - 本地筛选保持界面即时;服务端筛选使用防抖、取消或请求 ID,忽略过期响应并显示加载/错误状态。 - 筛选条件变化通常返回第一页或合适的首个结果,同时避免让焦点跳回页面顶部。 ### 排序 - 表头明确未排序、升序和降序;向无障碍 API 暴露排序状态。 - 多列排序必须显示优先级;不支持时只保留一个排序键。 - 使用稳定排序,定义空值位置和区域感知比较。 - 排序后按记录 ID 保持当前项、选择和未提交编辑,不按旧行号恢复。 ### 筛选与选择的关系 默认保留被筛选隐藏的已选记录,并在批量工具栏显示“已选 N 项,其中 M 项当前不可见”,同时提供仅清除隐藏选择或清除全部。若业务要求筛选即清除选择,必须在操作发生前明确提示并保持一致。 表头全选必须标明范围:当前可见页、当前已加载结果,或所有符合筛选的结果。跨服务端完整结果选择时使用“筛选条件 + 排除 ID”或后端选择令牌等模型,不要假装客户端已持有所有 ID。 ## 5. 勾选、多选与批量操作 - 选择复选框列固定在行首,表头使用三态:无、部分、全部;状态以已声明的全选范围计算。 - 点击表头全选前后都应让范围可理解,例如“选择本页 50 项”或“已选择全部 2,418 个匹配项”。 - Ctrl 支持独立增减选择,Shift 使用上次选择锚点扩展范围;筛选、排序后锚点无效时安全重置。 - 批量工具栏显示选择数量,只提供所有选中记录共同允许的命令。 - 对危险批量操作显示准确对象数和影响;可恢复操作优先支持撤销。 - 处理部分成功:列出成功、失败、跳过和权限不足的数量,允许重试失败项。 - 选择数很大时不要为每个 ID 创建 Widget 或重复复制完整对象;存储 ID/选择表达式。 - 禁用行仍可按需求查看,但不可勾选或执行命令;说明禁用原因。 ## 6. 键盘与无障碍 ### 键盘基线 | 按键 | 推荐行为 | |---|---| | 上/下方向键 | 移动当前行;是否同时改变选择取决于选定的选择模式 | | 左/右方向键 | 单元格导航,或在行模式下滚动/进入单元格控件 | | Ctrl+Space | 切换当前行的多选状态 | | Shift+方向键/单击 | 从选择锚点扩展连续范围 | | Ctrl+A | 选择明确定义的当前范围;大规模/服务端数据需二次表达全量范围 | | Space | 当前焦点为复选框时切换它;不得同时触发行默认操作 | | Enter | 执行与双击相同的默认命令,或提交当前编辑 | | F2 | 进入可编辑单元格;与双击编辑契约保持一致 | | Escape | 取消菜单/编辑;再次按键是否清除选择须明确规定 | | Shift+F10/菜单键 | 为当前行或选择集打开上下文菜单 | ### 无障碍 - 为表格提供可感知名称、列标题、行/列关系、排序状态、选择状态、复选状态和总数/可见数。 - 焦点与选择使用不同视觉信号,不只依赖颜色。 - 复选框、按钮和链接使用其真实控件语义与名称;不要让整个数据行伪装成多个按钮。 - HTML 静态数据优先使用原生 `