关于 building-forms
面向开发者的表单构建技能,介绍无障碍 Web 输入与流程设计,涵盖组件选择、验证策略、WCAG 2.1 AA 模式,以及 JavaScript/React 和 Python 示例。
主要功能
- 01输入组件选择指南
- 02验证时机与策略
- 03WCAG 2.1 AA 无障碍模式
- 04多步骤与条件表单模式
- 05JavaScript/React 和 Python 示例
适用场景
- 01构建带验证的注册或联系表单
- 02创建多步骤结账流程
- 03添加无障碍的即时验证
- 04设计带条件字段的问卷
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ ancoleman/ ai-design-components --skill building-forms安装后在 Claude Code 中输入/building-forms确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
outputs.yamlassets/error-messages/errors-en.jsonerrors-es.jsonerrors-fr.jsonassets/form-schemas/contact-form.jsonregistration-form.jsonassets/validation-rules/common-validations.jsonemail-patterns.jsonphone-formats.jsonexamples/basic-form.tsxconditional-form.tsxinline-validation.tsxmulti-step-wizard.tsxsettings-form.tsxexamples/javascript/async-validation.tsxfile-upload-preview.tsxexamples/python/async_database_validation.pybasic_form.pydjango_forms_example.pyfastapi_forms.pyflask_wtf_example.pypydantic_validation.pyreferences/accessibility-forms.mddecision-tree.mdreferences/javascript/react-hook-form.mdzod-validation.mdreferences/javascript/examples/basic-form.tsxinline-validation.tsxmulti-step-wizard.tsxreferences/python/examples/basic_form.py详细介绍
表单系统与输入模式
通过系统化的组件选择、验证策略和 UX 最佳实践,构建易于访问、方便用户使用的表单。
用途
表单是 Web 应用中收集用户数据的主要方式。本技能提供系统化指导,帮助你:
- 根据数据要求选择合适的输入类型
- 实施能够提升用户体验的验证策略
- 确保符合 WCAG 2.1 AA 无障碍标准
- 创建复杂模式(多步骤向导、条件字段、动态表单)
何时使用此技能
触发场景:
- 构建联系表单、登录/注册流程、结账流程
- 实施调查、问卷或设置页面
- 为用户输入添加验证
- 创建多步骤工作流或向导
- 确保表单易于访问
- 收集结构化数据(地址、信用卡、日期)
常见请求:
- “创建带验证功能的注册表单”
- “构建多步骤结账流程”
- “为电子邮件输入框添加内联验证”
- “让屏幕阅读器能够访问此表单”
- “实施包含条件问题的调查”
通用表单概念
组件选择框架
黄金法则: 数据类型 → 输入组件 → 验证模式
先确定要收集的数据类型,然后选择合适的组件:
快速参考:
- 短文本(<100 个字符)→ 文本输入框、电子邮件输入框、密码输入框
- 长文本(>100 个字符)→ 文本区域、富文本编辑器、代码编辑器
- 数值 → 数字输入框、货币输入框、滑块
- 日期/时间 → 日期选择器、时间选择器、日期范围选择器
- 布尔值 → 复选框、切换开关
- 单选 → 单选按钮组(2–7 个选项)、下拉选择框(>7 个选项)、自动补全(>15 个选项)
- 多选 → 复选框组、多选框、标签输入框
- 文件/媒体 → 文件上传、图片上传
- 结构化数据 → 地址输入框、信用卡输入框、电话号码输入框
详细决策树: 请参阅 references/decision-tree.md
验证时机策略
建议的默认方式:失焦时验证,并渐进增强
Field pristine (never touched): No validation
User typing: No errors shown
On blur (field loses focus): Validate and show errors
After first error: Switch to onChange for that field
On fix: Show success immediately
验证模式:
- 提交时 - 表单提交时进行验证(简单表单)
- 失焦时 - 字段失去焦点时进行验证(大多数表单的推荐方式)
- 输入时 - 用户输入时进行验证(密码强度、可用性检查)
- 防抖验证 - 用户停止输入后进行验证(基于 API 的验证)
- 渐进式 - 从失焦时验证开始,首次出错后切换为输入时验证
完整验证指南: 请参阅 references/validation-concepts.md
无障碍要求(WCAG 2.1 AA)
关键无障碍模式:
标签和说明:
- 每个输入框都必须有关联的
<label>或aria-label - 标签必须清晰可见且描述明确
- 明确标示必填字段(不能只通过颜色标示)
- 绝不使用占位文本代替标签
- 为复杂输入提供帮助文本
键盘导航:
- 按 Tab 键的顺序应合乎逻辑且依次排列
- 所有输入框都应可通过键盘操作
- 自定义组件应支持方向键
- Escape 键可关闭模态框/弹出层
- 焦点应清晰可见(轮廓或自定义指示器)
错误处理:
- 通过程序将错误与输入框关联(
aria-describedby) - 错误消息应清晰且便于采取行动
- 屏幕阅读器应能播报错误(
aria-live) - 提交时将焦点移至第一个错误
- 错误不能只通过颜色传达
ARIA 属性:
- 必填字段使用
aria-required="true" - 验证失败时使用
aria-invalid="true" - 使用
aria-describedby关联帮助文本/错误文本 - 相关输入框使用
role="group" - 验证消息使用
aria-live="polite"
完整无障碍检查清单: 请参阅 references/accessibility-forms.md
UX 最佳实践
现代表单 UX 原则(2024-2025):
- 渐进式披露 - 初始仅显示必要字段,按需展示高级选项
- 智能默认值 - 预填已知信息,根据上下文提供建议值
- 内联验证与正向反馈 - 输入有效时显示绿色勾号,并提供有帮助的错误消息
- 移动优先 - 使用较大的触控目标(最小 44px)和合适的键盘类型
- 降低认知负荷 - 将相关字段分组,使用清晰的标签,并提供示例
- 错误预防 - 通过约束防止无效输入,使用自动补全减少拼写错误
- 自动保存与恢复 - 自动保存草稿状态,在数据即将丢失前发出警告
详细 UX 模式: 请参阅 references/ux-patterns.md
错误消息最佳实践
优质错误消息公式:
- 哪里出错了 - “电子邮件地址无效”
- 为什么重要 - “我们需要此地址来发送收据”
- 如何修复 - “格式:[email protected]”
示例:
❌ 不佳: “输入无效” ✅ 良好: “电子邮件地址必须包含 @ 符号(例如:[email protected])”
❌ 不佳: “错误” ✅ 良好: “密码长度至少为 8 个字符”
❌ 不佳: “必填字段” ✅ 良好: “请输入电子邮件地址,以便我们发送订单确认信息”
语气指南:
- 自然亲切,而非机械生硬
- 乐于助人,而非责怪用户
- 具体明确,而非笼统含糊
- 提供可执行的建议,而非仅作描述
特定语言的实现
此技能提供上述通用表单概念,并在下方介绍特定语言的实现。
JavaScript/React(主要)
推荐技术栈:
- React Hook Form - 表单状态管理(性能最佳,包体积为 8KB)
- Zod - 面向 TypeScript 的模式验证
- Radix UI 或 React Aria - 无障碍组件基元
快速入门:
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import * as z from 'zod';
// Define validation schema
const schema = z.object({
email: z.string().email('Invalid email address'),
password: z.string().min(8, 'Password must be at least 8 characters'),
});
type FormData = z.infer<typeof schema>;
function LoginForm() {
const { register, handleSubmit, formState: { errors } } = useForm<FormData>({
resolver: zodResolver(schema),
mode: 'onBlur', // Validate on blur (recommended)
});
const onSubmit = (data: FormData) => {
console.log(data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<label htmlFor="email">Email</label>
<input id="email" {...register('email')} type="email" />
{errors.email && <span role="alert">{errors.email.message}</span>}
<label htmlFor="password">Password</label>
<input id="password" {...register('password')} type="password" />
{errors.password && <span role="alert">{errors.password.message}</span>}
<button type="submit">Login</button>
</form>
);
}
JavaScript/React 详细文档:
references/javascript/react-hook-form.md- React Hook Form 完整指南references/javascript/zod-validation.md- Zod 模式验证模式references/javascript/examples/- 可运行的代码示例
Python(主要)
推荐技术栈:
- Pydantic - 数据验证与设置管理(运行时验证、类型安全)
- FastAPI - 现代异步 Web 框架,支持自动验证
- WTForms - Flask/Django 表单处理(使用传统框架时)
快速入门(FastAPI + Pydantic):
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, EmailStr, Field, validator
app = FastAPI()
# Define validation schema
class LoginForm(BaseModel):
email: EmailStr # Validates email format
password: str = Field(..., min_length=8, description="Password must be at least 8 characters")
@validator('password')
def validate_password_strength(cls, v):
if not any(char.isdigit() for char in v):
raise ValueError('Password must contain at least one number')
if not any(char.isupper() for char in v):
raise ValueError('Password must contain at least one uppercase letter')
return v
@app.post("/api/login")
async def login(form_data: LoginForm):
# Pydantic automatically validates incoming data
# If validation fails, returns 422 with error details
return {"message": "Login successful", "email": form_data.email}
# Example error response (automatic):
# {
# "detail": [
# {
# "loc": ["body", "email"],
# "msg": "value is not a valid email address",
# "type": "value_error.email"
# }
# ]
# }
Python 详细文档:
references/python/pydantic-forms.md- Pydantic 验证模式references/python/wtforms.md- 用于 Flask/Django 的 WTFormsreferences/python/examples/- 可运行的代码示例
Rust(未来)
计划使用的库:
- validator - 结构体字段验证
- Leptos / Yew - 响应式 Web 框架
需要时将添加 Rust 实现。
Go(未来)
计划使用的库:
- Templ - 类型安全的 HTML 模板
- html/template - 标准库模板
需要时将添加 Go 实现。
组件层级
第 1 级:基础输入组件
基于文本的组件:
- 文本字段(单行)
- 多行文本框
- 电子邮件输入框(带验证)
- 密码输入框(带可见性切换)
- 数字输入框(带步进控件)
- 电话输入框(带格式化)
- URL 输入框(带协议验证)
- 搜索输入框(带清除按钮)
选择组件:
- 单选按钮组(2-7 个选项)
- 复选框(布尔值或多选)
- 切换开关(清晰的开/关状态)
- 下拉选择框(多个选项)
- 多选框(多项选择)
日期与时间:
- 日期选择器(日历界面)
- 时间选择器(小时/分钟)
- 日期范围选择器(开始和结束)
- 日期时间选择器(组合)
第 2 级:丰富的输入组件
高级选择:
- 自动补全/组合框(输入以筛选)
- 标签输入(多个标签)
- 穿梭列表(在列表间移动项目)
- 列表框(支持键盘导航)
专用组件:
- 颜色选择器(hex、RGB、HSL)
- 文件上传器(单个、多个、拖放)
- 图片上传器(裁剪、调整大小、预览)
- 滑块/范围(单值或范围)
- 评分输入(星级、数字、表情符号)
- 富文本编辑器(格式设置、媒体)
- 代码编辑器(语法高亮)
- Markdown 编辑器(预览、工具栏)
结构化数据:
- 地址输入(多个字段)
- 信用卡输入(带格式)
- 电话号码(国际格式)
- 货币输入(符号、小数)
第 3 级:复杂表单模式
多步骤表单:
- 线性向导(第 1 步 → 第 2 步 → 第 3 步)
- 分支向导(条件步骤)
- 进度指示器
- 保存并继续(草稿状态)
- 审核和提交页面
动态表单:
- 条件字段(显示/隐藏)
- 可重复部分(添加/移除)
- 字段数组(动态列表)
- 嵌套表单(复杂对象)
高级模式:
- 行内编辑(点击进行编辑)
- 批量编辑(多条记录)
- 自动保存(定期保存或更改时保存)
- 乐观更新
- 撤销/重做功能
与设计令牌集成
所有表单组件都使用 design-tokens 技能进行视觉样式设置,以支持主题切换(浅色/深色/高对比度/自定义品牌)。
主要令牌类别:
- 颜色 - 输入背景、边框、文本、错误/成功状态
- 间距 - 内边距、字段间距、标签边距
- 排版 - 输入、标签、错误提示的字体大小和字重
- 边框 - 边框宽度、圆角、焦点环
- 阴影 - 焦点指示器、层级效果
参见: skills/design-tokens/,查看完整的主题设置文档。
常见用例
联系表单
// Basic contact form with validation
// See: references/javascript/examples/basic-form.tsx
注册流程
// Multi-step registration with password strength
// See: references/javascript/examples/multi-step-wizard.tsx
行内验证
// Real-time validation with debouncing
// See: references/javascript/examples/inline-validation.tsx
带条件逻辑的问卷
// Dynamic form with conditional fields
// See: references/javascript/examples/conditional-form.tsx
设置页面
// Mixed input types with autosave
// See: references/javascript/examples/settings-form.tsx
快速决策指南
问题:应该使用哪种输入组件?
→ 查看 references/decision-tree.md,获取完整的决策树
问题:应该何时验证?
→ 失焦时验证,并渐进增强(首次出错后改为值更改时验证)
→ 查看 references/validation-concepts.md,了解所有策略
问题:如何让表单具备无障碍访问能力?
→ 使用语义化 HTML,为所有输入添加标签,并支持键盘导航
→ 查看 references/accessibility-forms.md,获取 WCAG 2.1 检查清单
问题:如何处理复杂验证?
→ 使用架构验证(TypeScript 使用 Zod,JavaScript 使用 Yup)
→ 查看 references/javascript/zod-validation.md,了解相关模式
问题:如何构建多步骤表单?
→ 使用带进度跟踪的状态管理
→ 查看 references/javascript/examples/multi-step-wizard.tsx
最佳实践总结
- 从语义化 HTML 开始 - 尽可能使用原生
<input>、<select>、<textarea> - 为所有内容添加标签 - 每个输入都需要清晰可见的描述性标签
- 在失焦时验证 - 对大多数表单而言,这是用户体验的最佳平衡
- 提供有用的错误提示 - 说明问题所在以及如何修复
- 支持键盘导航 - Tab 顺序、方向键、按 Escape 关闭
- 优先考虑移动设备 - 使用较大的触控目标和合适的键盘
- 渐进式展示 - 不要一次展示所有字段,以免造成信息过载
- 尽可能自动保存 - 避免数据丢失
- 使用屏幕阅读器测试 - 确保 ARIA 属性正常工作
- 使用设计令牌 - 保持样式一致并支持主题
更多资源
references/decision-tree.md- 完整的组件选择框架references/validation-concepts.md- 所有验证策略和模式references/accessibility-forms.md- WCAG 2.1 AA 合规检查清单references/ux-patterns.md- 现代表单用户体验最佳实践references/javascript/- JavaScript/React 实现指南