# Component States

> 定义 UI 组件的所有状态时使用。适用于按钮、表单、列表、对话框等组件的状态完整覆盖。优先使用 8 种核心状态（默认/悬停/聚焦/禁用/加载/成功/错误/空/权限）。

- Skill: `zhaoxuya520/component-states` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add zhaoxuya520/component-states`
- Raw SKILL.md: https://api.skillmd.com/api/skills/zhaoxuya520/component-states/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: zhaoxuya520 (https://skillmd.com/u/zhaoxuya520)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/zhaoxuya520/component-states

---


# 组件状态设计

## 适用场景

- 单个组件的状态完整定义
- 列表、表单、按钮等高频组件
- 给前端的状态实现说明
- 避免"只画静态页面"

## 核心原则

```text
一个组件至少有 5 种状态，不止"默认"和"hover"
缺失任何状态都会导致用户体验断裂
状态必须前端可实现、QA 可测试
```

## 8 种核心状态

```text
1. 默认（Default）
   组件正常显示，无交互

2. 悬停（Hover）
   鼠标悬停，提供视觉反馈

3. 聚焦（Focus）
   键盘 Tab 到该组件，无障碍必备

4. 禁用（Disabled）
   不可交互，显示原因

5. 加载（Loading）
   异步操作进行中

6. 成功（Success）
   操作完成的反馈

7. 错误（Error）
   操作失败 / 数据错误

8. 空（Empty）
   无数据 / 无结果
```

### 高频组件的额外状态

```text
列表：
  - 部分加载（无限滚动）
  - 加载更多失败
  - 筛选结果为空（vs 完全无数据）

表单：
  - 校验中
  - 已修改未保存（dirty）
  - 已提交未确认

按钮：
  - 长按 / Active
  - 主按钮 / 次按钮 / 文本按钮（变体）

对话框：
  - 确认操作中
  - 不可关闭（处理中）

权限相关：
  - 无权限查看
  - 无权限编辑（只读）
  - 需要登录
```

## 状态设计模板

### 按钮组件

```markdown
## Button 组件状态

| 状态 | 触发条件 | 视觉变化 | 行为 |
|------|---------|---------|------|
| Default | 默认显示 | 主色背景 | 可点击 |
| Hover | 鼠标悬停 | 主色加深 10% | 可点击 |
| Focus | 键盘 Tab | 显示焦点环（蓝色 outline） | 可点击 |
| Active | 鼠标按下 | 主色加深 20% | 触发动作 |
| Disabled | 不可用 | 灰色背景 + 50% 透明度 | 不可点击 |
| Loading | 异步操作中 | 显示 Spinner，文字隐藏 | 不可点击 |
```

### 表单字段

```markdown
## Input 组件状态

| 状态 | 触发条件 | 视觉变化 | 用户行动 |
|------|---------|---------|---------|
| Empty | 默认 | 灰色边框 + placeholder | 输入 |
| Focus | 点击/Tab 进入 | 主色边框 + 显示 helper | 输入 |
| Filled | 有值 | 灰色边框 + 显示值 | 编辑 |
| Validating | 失焦后异步校验 | 边框 + Spinner | 等待 |
| Valid | 校验通过 | 绿色边框 + ✅ | 继续 |
| Invalid | 校验失败 | 红色边框 + 错误信息 | 修改 |
| Disabled | 不可编辑 | 灰色背景 | 无 |
```

### 列表组件

```markdown
## List 组件状态

| 状态 | 触发条件 | 显示内容 | 用户行动 |
|------|---------|---------|---------|
| Loading | 初始加载 | Skeleton 占位 | 等待 |
| Has Data | 有数据 | 列表项 | 浏览/操作 |
| Empty | 无数据 | 空状态图 + 文案 + 主操作 | 创建第一项 |
| Filter Empty | 筛选无结果 | "无匹配结果" + 清除筛选 | 调整筛选 |
| Error | 加载失败 | 错误信息 + 重试 | 重试 |
| Loading More | 加载下一页 | 底部 Spinner | 等待 |
| End | 已加载全部 | "没有更多了" | 无 |
| No Permission | 无查看权限 | 权限提示 + 申请链接 | 申请 |
```

### 对话框

```markdown
## Dialog 组件状态

| 状态 | 触发条件 | 显示内容 | 行为 |
|------|---------|---------|------|
| Closed | 默认 | 不显示 | - |
| Opening | 触发打开 | 渐入动画 | 不可交互 |
| Open | 已显示 | 完整内容 + 操作按钮 | 可交互 |
| Confirming | 用户确认中 | 主按钮 Loading | 不可关闭 |
| Closing | 触发关闭 | 渐出动画 | 不可交互 |
```

## 状态对照清单

每个组件设计时填写：

```markdown
## [组件名] 状态清单

✅ Default
✅ Hover
✅ Focus
✅ Disabled
✅ Loading
✅ Success
✅ Error
✅ Empty
✅ Permission（如适用）

总计：[N] 个状态

每个状态需要：
□ 触发条件
□ 视觉变化（颜色/边框/图标/文字）
□ 用户可执行的操作
□ 自动转换条件（如 Loading → Success）
```

## 工作流程

```text
1. 列出所有需要的组件（来自 page-structure）
2. 对每个组件应用 8 种状态清单
3. 删除不适用的状态
4. 添加组件特有的状态
5. 定义每个状态的触发条件
6. 定义状态之间的转换
7. 输出状态对照表
8. 转交 design-handoff 交接给前端
```

## 质量自检

```text
□ 是否覆盖了 8 种核心状态
□ 是否考虑了组件特有状态
□ 每个状态是否有触发条件
□ 每个状态是否有视觉变化
□ 状态转换是否清晰
□ 是否考虑了无障碍（Focus 状态）
□ 错误状态是否可恢复
```

## 常见坑

1. **只画 Default 和 Hover**——忽略 Loading/Error/Empty
2. **Disabled 没有原因**——用户不知道为什么不能点
3. **空状态太"空"**——只有空白没有引导
4. **错误不可恢复**——只显示"出错了"没有重试
5. **Loading 长时间无反馈**——用户以为卡死
6. **筛选无结果 = 完全空**——不区分两种空
7. **没有 Focus 状态**——键盘用户无法操作
8. **状态转换不清**——Loading → ? 用户不知道

## 配套模板

- `templates/interaction-state-template.md` — 通用交互状态模板（按钮/表单/列表/对话框）
- `templates/empty-state-pattern-template.md` — 空状态设计模板

## 与其他 skill 的协作

```text
上游：
  page-structure → 列出页面需要的组件

平行：
  atomic-design → 组件分层
  accessibility → Focus 状态要求
  design-tokens → 颜色/边框 token

下游：
  design-handoff → 交接所有状态给前端
```

