04 · 组件选择与反馈模式

适用:实现按钮、输入、导航、弹层和数据展示。先查当前项目的组件库;外观相似的控件不一定有相同行为。

CMP-01 · 组件语义决定行为

用户意图优先选择常见错误
前往另一个地址带真实 href 的链接用 div 点击跳转,失去新窗口和复制地址
执行动作button链接写 href="#" 模拟按钮
立即改变二元设置switch / 原生可用的等价控件改完还需找隐蔽的保存按钮
表单中勾选多项checkbox用颜色表示勾选,缺少选中状态
少量互斥选项radio group多个开关允许互相矛盾的状态
长列表单选select;需要检索时用 combobox自制下拉却没做键盘、过滤和读屏
同页切换内容面板tabs导航链接错误使用 Tab 语义
展开补充内容details / disclosure整块容器可点却没有可操作元素
连续数值调整range + 精确数值输入只能拖动,无法精确输入
多层级对象普通列表与展开;确有需要时 tree简单导航直接升级为复杂树控件

复杂控件实现前查对应的 WAI-ARIA APG 模式。ARIA 角色不会自动生成键盘行为;优先原生 HTML,避免只补属性。

CMP-02 · 表单帮助用户完成输入

标签持久可见;必填与格式在提交前能理解;相关字段分组;允许常用粘贴格式。校验时区分未填写、填写中、已校验和服务端拒绝。

建议:首次输入避免每敲一个字符就报错;提交时给出汇总并定位首个错误。修正已经报错的字段时可以及时更新。服务器拒绝后保留输入,允许修正重试。

错误信息说明具体问题和可行的改法,例如“项目名称最多 60 个字符”。不要只写“参数错误”。字段错误用 aria-describedby 关联;必要时用 aria-invalid 表示无效。

CMP-03 · 按打断程度选择反馈

情况默认反馈要点
保存完成原位状态或简短 status不抢焦点,不反复播报
某字段不合法字段附近的错误保留输入,关联具体字段
当前模块加载失败模块内状态 + 重试其他区域仍可工作
全局离线或账户受限持久横幅提供用户能执行的下一步
必须现在做决定模态对话框明确对象、后果、取消与确认
补充说明文本、帮助入口、tooltip不能只靠 hover,重要说明应直接可见

Toast 适合短暂、非关键反馈。包含操作、长错误或重要结果时,提供持久位置;别让唯一的恢复入口几秒后消失。

CMP-04 · 弹层要有焦点与退出策略

模态框打开后应把焦点放到合适位置,Tab 限制在模态框内,Escape 通常关闭,关闭后返回合理的触发位置。长内容先聚焦标题或说明可能比直接聚焦危险按钮更适合。见 APG 模态对话框模式。

原生 dialog.showModal() 提供模态基础能力,仍需命名、合适的初始焦点、关闭按钮和业务行为。示例见代码配方。不把重要确认只绑定在点遮罩关闭上。

抽屉适合保留上下文的补充任务。Popover 适合轻量内容或选项,不能仅因视觉上漂浮就当模态框使用。

CMP-05 · 列表浏览与数据比较分开设计

需要比较字段用表格;对象视觉差异重要时用卡片;时间顺序重要时用时间线。表格提供 caption、表头和明确排序状态,普通表格不必升级成可编辑 grid。

分页适合定位和稳定返回;“加载更多”适合保留浏览节奏;无限滚动要处理位置恢复、页尾可达性与辅助技术。筛选后无结果要允许清除条件,不能显示成“首次创建项目”。

批量操作应说明选择范围:“本页 20 项”与“全部 2,400 项”是不同动作。操作完成后报告成功与失败数量,并提供逐项恢复。

检查

逐个检查组件的默认、悬停、焦点、按下、选中、禁用、忙碌、错误状态。并非每个组件都需要全部状态,但不适用应有理由。主要功能还必须在异常状态下可理解。