Files
workbuddy_skills/oil-ui-pro/references/interaction-and-state.md
T
admin d9445b5888 oil-ui-pro 0.15.4 → 0.22.2(上游 ui.oiloil.org 正式包)+ 记 P0-98 跨盘 rename 坑
- oil-ui-pro 升到 0.22.2:references 13→28 份(新增 16、删 imagery.md)、assets 增 cards/(22 组)与 fonts/、SKILL.md 顶层五步结构未改名。
- 升级路径:官方 `npx github:oil-oil/oil-cli update` 稳定失败(error=replace、报「检查目录权限」)。
  真身为 EXDEV —— 解压在 os.tmpdir()(C 盘)、技能目录在 E 盘,Windows 上 rename 不能跨盘;
  CLI 的 catch 把非 CliError 原生异常一律兜底成 replaceFailed,真错误一个字不吐。
  做法=借其 prepare() 只做下载+校验,再 cp 到同盘 stage、rename 交换;官方命令复验 up_to_date。
- 回归:product-planning 按名引用的 visual-review.md/tools.md/design-direction.md/style-explorer.md 全部健在;命名闸门 2061|0|27。
- session-mechanism/references/pitfalls.md 新增 P0-98(含通则:更新器把原生错误兜底成指错方向的人话)。
2026-10-14 10:21:46 +08:00

112 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 交互与状态
## 先走通用户任务
先用一条主要路径把任务讲清楚:用户从哪里进来,认出哪个对象,要做什么决定,执行哪个动作,最后看到什么结果。只展开和这次范围有关的分支,不为了一个小表单去设计整个产品的流程。
浏览、比较、选择和编辑是四种不同的任务。列表里放方便比较的东西:对象的身份、数据或预览。只读的详情页不要默认铺满禁用的输入框,等用户明确要编辑了,再显示需要的控件。要连续批量填写的表格可以一直处于编辑状态,但改的是哪个对象、什么时候算保存,全表要一致。
同一个对象、同一个动作,在各处用同一个名字。品牌可以改变它们的外观,但返回、关闭、保存、删除这些用户熟悉的动作,意思不能随便改。
## 对象身份
一个对象靠四样东西认出来,按顺序取,够区分就停:
1. **视觉身份**:缩略图、头像、封面、Logo 或媒体帧。同一对象在各处用同一裁切和比例;加载失败时用稳定的兜底图,并保留名称。
2. **主名称**:用户平时称呼和搜索用的名字。
3. **区分字段**:同名或相似对象之间最能区分的一个字段。
4. **影响判断的状态**:只在它会改变选择或操作时显示。
数据库 ID、看不懂的长文件名、所有对象都一样的类型标签、装饰图标、截断后彼此相同的文字,都不能充当身份。
选择器首先是对象识别器,不是字符串下拉框。选项显示图片、名称和必要的区分字段;收起后仍显示足够的身份,用户不用重新打开就能确认选了谁;搜索覆盖名称和区分字段;已选对象不在当前分页或筛选结果里时,仍然显示。
把这四样做成一个共享的对象身份组件,列表、表格第一列、选择器、已选结果和详情标题都用它。
## 列表、表格与详情
列表只回答三件事:有哪些对象,它们在决策上有什么不同,该打开哪一个。每项只放身份、一个影响判断的状态、比较所需的最少字段、整项点击和“更多”。完整分析、证据、关联对象、编辑和历史放进详情。
- **表格还是卡片**:要横向比较同一字段(数值、状态、日期、价格)用表格;主要靠图片和内容挑选用卡片或列表;每项主体是长文或完整媒体时不压进表格行。同一类对象在整个产品里只保留一种主要形态,只有用户确实有两种任务时才提供视图切换。
- **每一列都要有答案**:它帮助比较、表达状态、需要直接修改,还是可执行操作?答不上来就删,不把详情字段逐列搬进表格。用来识别对象的那一列放在最前,横向滚动时固定;单位写在表头,不在每个单元格里重复。
- **一个单元格只做一件事**:识别、比较、状态、编辑或操作中的一种。不在单元格里拼“预览 + 状态 + 数量 + 按钮”的迷你卡片;状态只在固定的一列表达一次;行级动作放固定的操作列,不在内容下面再排一行按钮。
- **批量**:只有真的存在批量动作时才显示多选框。筛选变化后不静默操作看不见的已选项:要么清除隐藏的选择,要么写明数量和范围。
- **点击**:卡片主体和“查看”按钮不做同一件事;整张卡可点时,卡内的独立控件不触发外层点击。编辑完成后回到原行,原行显示最新状态。
## 动作层级
| 层级 | 用途 | 呈现 |
| --- | --- | --- |
| 主操作 | 完成这个区域的主要任务 | 一个高强调按钮,写成“动作 + 对象”,例如“发送报价” |
| 次级操作 | 高频但不是主要任务 | 低强调文字按钮 |
| 管理操作 | 重命名、复制、重新处理、可撤销的删除 | 收进“更多”,菜单项写文字 |
| 危险操作 | 不可恢复或损失大 | 在菜单里用分隔线隔开,并确认 |
可撤销的操作直接执行并提供撤销,不再确认;不可撤销的操作确认时写出对象和后果,按钮写动作,例如“删除 3 个文件”,不写“确定”。同一区域出现两个高强调按钮,就重新判断主任务。“处理”“管理”“继续”这类词说不出结果,换成动作加对象。次级操作可以在悬停、聚焦或选中该项后出现,但要预留位置、不挤动内容,触屏上要有等价入口。
每个可见动作都要有真实结果:数据变化、明确范围的预览、可观察的任务状态、导航,或者复制、下载这类本地结果。没有写入能力就不显示写操作,不用长期禁用的按钮占位;当前状态不允许的菜单项直接隐藏,不留无法解释的灰色图标。
帮助文案只解释从界面上看不出来的规则、限制和风险;流程乱的时候,先改标题、默认值或结构,不靠一大段说明来补。控件用原生的或项目里已有的可靠控件,标签、焦点、键盘操作和可访问名称都保留;校验结果和重要的状态,不能只用颜色或悬停提示来表示。
## 表单与提交
只让用户填这次任务必须要、系统又没法可靠带出来的信息。系统已经知道的值先填好;需要用户判断的值,填好了也要能改。数据来自别的对象时,说明它是从哪里来的,不能悄悄改掉源头上的那一份。
哪些字段是一起提交的,要让人看得出来。用户想做一件事,就只提交一次,处理的过程中不让重复点;改了就立刻生效的地方,不再多放一个“保存”按钮。
只有字段之间有先后依赖、填错的代价很高,或者任务确实很长时,才加步骤、预览、草稿或额外的确认。简单、独立的字段适合在行内直接改;互相关联的复杂编辑,放到装得下整个任务的弹窗、侧面板或页面里。
校验信息显示在用户能改的那个地方,写清楚错在哪里、怎么改。提交失败时,用户填的内容、当前的对象和所在的位置都要留着;退回上一步,或者去改完源数据再回来,流程要能接着往下走。
## 按范围表达状态
| 情况 | 界面要表达的内容 |
| --- | --- |
| 首次加载,尚无内容 | 在最终内容区域提供适量占位或进度,保持结构稳定 |
| 刷新或筛选,已有内容 | 保留可用内容并标示正在更新,不把旧结果误当成新查询完成 |
| 集合确实为空 | 说明原因,并给适合当前任务的开始动作 |
| 搜索或筛选无结果 | 保留查询条件,提供调整或清除条件的方式 |
| 局部提交 | 在触发位置表达处理中,保持按钮尺寸,防止重复提交 |
| 后台长任务 | 给对象明确的排队、处理中、完成或失败状态及必要进度 |
| 加载或提交失败 | 在相应范围解释原因和恢复动作,不要求用户重新寻找对象 |
同一个区域里不要同时出现互相矛盾的状态。只请求一小块数据时不清空整页,进度提示不叠好几层,还在等结果的时候不显示成“没有数据”。
占位的骨架要和实际内容的样子接近,不能比实际内容多出一段滚动。已有数据在刷新时,结果、数量和查询条件三者要对得上;用户连续快速操作时,只显示最后一次操作对应的结果。
## 模型在交互上的默认做法
这些做法单看都说得过去,所以模型会不假思索地用。出现时换成右边的做法:
| 默认做法 | 换成 |
| --- | --- |
| 首页开头四张指标卡,数字没有比较基准,也引不出动作 | 首页回答“现在该处理什么”,见 [工作区骨架](direction-workspace.md) |
| 可撤销的操作也弹确认框 | 直接执行并提供撤销;只有不可撤销的操作才确认,见“动作层级” |
| 所有反馈都用角落里的浮动提示,包括错误 | 反馈出现在触发的位置;错误留在原处直到解决。浮动提示只用于离开视线的结果,例如已复制、已发送 |
| 一加载就整页转圈 | 保留已有内容,只在变化的区域标示更新,见“按范围表达状态”和下文数字 |
| 空状态只有一张插图和“暂无数据” | 说明为什么空、下一步做什么,给一个能直接开始的动作;能导入或预填示例就提供 |
| 字段一字排开,用占位文字当标签,提交后才一起报错 | 标签常驻在输入框上方,按任务分组;离开字段时校验,提交出错时聚焦到第一个错误并说明怎么改;少数可选字段标“选填”,不给满屏必填项加星号 |
| 按钮禁用,却不说为什么;每行末尾一排图标按钮;必要按钮只在悬停时出现 | 按“动作层级”重排:主操作一个,管理操作进“更多”,触屏和键盘都能到达 |
| 详情和设置默认用弹窗 | 按任务选择弹窗、侧面板或完整页面,见空间、滚动与浮层的“选择承载方式” |
| 表格所有列等宽、居中 | 按“列表、表格与详情”删掉答不出用途的列;对齐方式见视觉自查与精修的“细节” |
| 按回车才搜索,无结果时只写“无结果” | 输入即筛选(请求较重时防抖 150–300ms);无结果时保留查询,给出放宽条件或清除的入口 |
| 一两个字段也拆成多步向导 | 只有步骤之间确实依赖时才分步;否则一页完成,并能看到全部范围 |
| 保存后跳回列表,看不出刚改的是哪一条 | 回到原位置,把刚改动的对象高亮 1–2 秒 |
## 有数字的底线
- **响应**:100ms 内给出按下反馈。300ms 内能完成的操作不显示加载,避免一闪而过;超过 1 秒显示骨架或进度;超过 10 秒显示进度,并允许离开后回来查看。加载指示一旦出现,至少停留 400–500ms。
- **对比度**:正文与背景至少 4.5:1;大字(约 24px 以上,或 19px 以上的粗体)、图标和控件边界至少 3:1。
- **点击区域**:触屏至少 44×44pt(Android 48dp),相邻目标之间留 8px;桌面指针目标至少 24×24px。
- **文字**:手机上的输入框文字不小于 16px,否则 iOS 聚焦时会自动放大页面。正文字号和行高见 [视觉语言](visual-language.md) 的“可读性是交付门槛”;阅读型正文每行中文 25–40 字、英文 45–75 个字符。
- **提示停留**:普通提示 4–6 秒,带撤销的 5–10 秒;鼠标悬停在提示上时暂停计时。重要错误不用会自动消失的提示。
- **键盘**:Esc 关闭浮层,并把焦点还给打开它的元素;Enter 提交单行表单;弹窗打开时焦点落在第一个输入或主按钮上,Tab 不跑到弹窗外面。
## 确认与完成
要等一会儿才有结果的操作,从提交到结束的每个阶段都要让人看得见。提交以后,对象和反馈留在原处;等真的完成了再显示成功,失败了要留一个能重试或恢复的入口。
任务在后台跑、窗口可以先关掉的,关掉以后要有地方能继续看到它的进展。关闭窗口不等于取消请求;系统并不能真的取消时,不要把“关闭”或“取消”说成操作已经撤回。
重要的保存要验证:重新读取一次,或者退出再进来,看数据是不是真的在。原型里可以用模拟数据演示各种状态,但交付时要说清楚哪些是模拟的,不能说真实数据已经写进去了。