组件交互模式
交互模式说明业务页面如何使用鼠标、键盘、焦点、popup、tooltip、context menu 和拖拽能力。不同组件可以有自己的业务语义,但同类操作应保持一致,避免用户在不同页面形成冲突预期。
Pointer 模式
Click
标准 click 行为:按下时显示 pressed 反馈,在同一可交互目标上释放时触发 action;离开目标或取消操作时恢复原状态。
规则:
- disabled、readonly 不允许修改值;readonly 是否允许 focus 由组件语义决定。
- 取消操作,或组件被隐藏、禁用时,不应留下 pressed 反馈。
- 普通 click 在释放时触发;拖拽 handle 或按住重复操作等特殊行为以对应组件文档为准。
- 命中区域应覆盖视觉目标和可接受空白,不应只命中文字像素。
Hover
- hover 只表达“可交互区域在指针下”。
- hover 不应创建新布局或改变组件尺寸。
- hover tooltip 应有延迟,并在 pointer leave、组件禁用或页面关闭时消失。
- 不可交互区域不绘制 hover。
Drag
拖拽交互必须有明确阶段:
| 阶段 | 要求 |
|---|---|
| pending | 指针按下但未超过拖拽阈值,不应立即移动布局。 |
| dragging | 显示 ghost、guide 或 preview,并持续跟随指针。 |
| cancelled | Esc、pointer cancel 或非法结束时恢复起始状态。 |
| committed | 合法 drop 后更新模型,触发事件。 |
规则:
- 优先使用组件提供的拖拽、排序或分栏 API,不在业务页面重复实现另一套拖拽状态。
- drop target 命中、preview rect 和最终布局应尽量一致。
- 无合法 target 时必须有明确降级策略,例如回到原位或转为 floating。
- 拖拽时不要触发 hover tooltip 或 context menu。
Keyboard 模式
可交互组件应定义键盘路径。
| 键 | 默认语义 |
|---|---|
Tab / Shift+Tab |
焦点前进或后退。 |
Enter |
执行主动作、提交、打开当前项。 |
Space |
按钮按下、checkbox/radio 切换、当前项选择。 |
Esc |
取消编辑、关闭 popup、取消拖拽或收起 overlay。 |
Arrow |
在列表、菜单、tab、tree、grid 中移动 active item。 |
Home / End |
跳到首项或末项。 |
PageUp / PageDown |
大步滚动或 tab 切换。 |
规则:
- 键盘触发的 action 与鼠标触发的 action 应进入同一业务回调或 manager API。
- 快捷键事件应携带 source,例如
keyboard,便于日志和策略区分。 - disabled 组件不响应快捷键。
- popup 打开时,键盘优先路由到 popup;Esc 应先关闭最上层 popup。
- 组合键只用于高级场景,必须在组件文档中说明。
Focus 模式
焦点是可访问性和键盘操作的基础。
规则:
- 可键盘操作组件必须能够通过正常焦点路径到达。
- 只读输入可保持焦点,用于复制和选择;禁用控件不能获得焦点。
- 组件隐藏、禁用或所在页面关闭时不能继续持有焦点。
- focus ring 不改变布局。
- 复合组件应区分容器焦点和内部 active item。
典型模式:
| 组件 | 焦点模式 |
|---|---|
| Button/IconButton | 整个控件一个焦点。 |
| TextField/TextArea | 文本编辑器持有焦点和 caret。 |
| Dropdown/DatePicker | field 持有焦点,popup 内有 active option。 |
| Grid/Tree/List | 容器持有焦点,内部维护 focused row/cell/item。 |
| DockWorkbench | workbench 管理 active item,内容组件可恢复自身焦点。 |
Popup 和 Overlay 模式
Popup 包括 dropdown、context menu、tooltip、popover、modal、auto-hide overlay 等。
规则:
- 优先使用组件库提供的 popup、modal、drawer、popover、dropdown 和 context menu 能力,保持层级与关闭行为一致。
- 打开 popup 时要明确 outside click、Esc、组件禁用和页面关闭时的行为。
- popup 不能被父组件裁剪;需要覆盖布局时使用 overlay。
- popup 内容尺寸必须有最大宽高和滚动策略。
- popup 打开后,不应让底层组件继续收到会造成状态冲突的 pointer action。
- popup 关闭后不应留下 hover、pressed 或 active option 等临时反馈。
Tooltip 模式
tooltip 用于解释图标、显示截断文本或补充轻量说明。
规则:
- 图标按钮如果没有可见文字,应提供 tooltip。
- 文本截断时可以提供完整文本 tooltip。
- disabled 控件是否显示 tooltip 由组件语义决定;若用于解释禁用原因,可以显示。
- tooltip 不能承载必须阅读的业务错误;错误应在组件附近明确展示。
- tooltip 不应抢焦点。
Context Menu 模式
右键菜单用于当前项的上下文操作。
规则:
- 菜单项 enabled/disabled 要根据当前 selection、placement、权限计算。
- 菜单命令应复用组件公开 API,不绕过 guard。
- 批量命令必须说明失败策略,例如遇到拒绝关闭时是否停止。
- context menu 打开时,当前项应成为 active 或至少保持可识别状态。
Icon Button 模式
图标按钮是高频控件,必须统一:
- 默认状态不绘制强底色,除非它是 selected、danger、primary 或 active mode。
- hover 时绘制浅底或弱边框。
- pressed 时绘制更明确但短暂的按下反馈。
- disabled 时弱化图标并阻断 tooltip 以外的交互。
- 命中尺寸不得小于视觉可操作区域,图标本身可小于按钮 rect。
- 不熟悉的图标必须有 tooltip。
Tab 和 Workbench 模式
tab 类组件需要同时处理 selected、hover、close、drag、overflow。
规则:
- active tab 必须比 hover 更明确。
- close 按钮默认可弱化,hover tab 或 active tab 时更清晰。
- tab 宽度不足时必须有降级策略:ellipsis、icon strip 或 overflow menu。
- 哪种降级策略取决于场景:文档 tab 可用 overflow menu,工具区 tab group 在窄宽下优先保留直接 icon 入口。
- 拖拽 tab 时,active 状态、preview 和最终 drop 行为必须一致。
事件来源
复杂组件的事件建议携带 source:
| Source | 含义 |
|---|---|
api |
业务代码直接调用。 |
button |
按钮或可点击控件触发。 |
keyboard |
快捷键或键盘导航触发。 |
menu |
context menu 或 menu bar 触发。 |
drag |
拖拽提交触发。 |
hover |
hover 延迟或 hover 展开触发。 |
source 不是视觉状态,而是审计、日志、权限和遥测的运行时信息。组件文档应说明哪些事件会携带 source。