用途:该技能面向 Expo 应用的表单与输入层,目标是把每个表单收敛为“一个 valibot schema + react-hook-form”,并统一字段组件、错误消息、键盘行为、焦点链与提交语义。适用于新增表单、新增文本框、为已有表单补国际化消息键、处理异步字段校验(如名称是否被占用)与服务器端字段错误回填等场景。
主要能力:
- 单一 schema:每个表单一个 valibot schema,通过 valibotResolver 接入 useForm,字段类型用 v.InferInput、提交值用 v.InferOutput,Controller 上不再写规则,从而让类型、运行时校验与消息来自同一处。
- 消息即目录键:每个校验动作携带源目录的字面量键(如 v.nonEmpty('task-editor.title.required')),由字段层翻译;setError 传键,fieldMessageKey 兜底为通用键。
- 同步且 Hermes 安全:表单 schema 不使用 *Async API;未 polyfill Intl.Segmenter 时不使用 graphemes/words 动作。
- 异步检查独立:异步检查在 useAsyncFieldCheck 中执行,仅在形状合法后启动,等待输入停顿、最新值胜出、有超时、卸载即停,并记录所答值;提交要求 hasPassed(value),服务端写入时仍作最终判定。
- 数字脚本兼容:匹配 \d 或调用 Number() 的 schema 先用 toLatinDigits 转换,小数/金额/数量字段用 normalizeDecimalInput。
- 字段组件统一:界面只渲染 TextField,不直接用 TextInput;TextField 位于 src/ui/form/,统一处理标签、错误、提示、live region、键盘、自动填充。
- 无障碍:可见标签即输入的可访问名称,错误不只靠颜色;iOS 用 accessibilityLabel,Android 用 accessibilityLabelledBy;错误或提示进入 polite live region,无效字段有加粗边缘与文字说明。
- 字段种类:FIELD_KINDS 统一定义键盘、autofill、大小写、自动更正与安全输入;如隐藏文本需 autoComplete,邮箱键盘设 autoCapitalize。
- 绑定方式:使用 onChangeText、onBlur、ref(useTextField),不用 onChange={field.onChange}、{...field} 或 register,ref 需传递下去。
- 错误时机与聚焦:mode: 'onTouched',首次 blur 后才显示错误;提交被拒时聚焦第一个问题并播报。
- 回车焦点链:单行字段用 enterKeyHint 指定下一字段、submitBehavior 与 setFocus,末字段 done 提交,多行字段换行。
- 键盘不遮挡:KeyboardProvider 包裹根栈;表单放在 KeyboardAwareScrollView 中并设 keyboardShouldPersistTaps="handled";数字/小数/电话键盘使用 KeyboardDoneBar,滚动视图的 bottomOffset 由 useDoneBarSpace 根据 Done 条测量高度计算。
- 提交不丢输入:模型调用 handleSubmit(...)() 并捕获 promise,用 useFormState 显示 isSubmitting,仅当保存返回 ok 且 handleSubmit 已结束才 reset,失败保留已输入内容。
使用方式(流程概要):先用 scripts/check-forms.mjs 检查仓库现有表单问题;准备主题、AppText、PressableSurface、i18n、useServices、Result、异步安全辅助与测试渲染辅助等前置技能;安装 react-native-keyboard-controller 与 react-hook-form@7.89.0、@hookform/resolvers@5.9.1、valibot@1.5.0(资料注明安装于 2026-10-03 验证,需重新核对版本);把 templates 中的字段组件、hooks、latin-digits、测试包装器复制到对应路径并合并 forms.* 消息键;在根栈中接入 KeyboardProvider;登记组件目录条目;先写 schema 与其测试,再写模型 hook 与界面,按需加入异步检查,最后编写测试并跑检查脚本直到 PASS,再跑相邻技能的检查器。
适用场景与限制:适合采用 Expo/React Native、使用 react-hook-form 与 valibot、重视无障碍与键盘体验的表单开发。限制包括:依赖多套前置技能与组件已存在;异步检查不得放入 schema;不使用 Intl.Segmenter 时不得使用相关动作;界面不得直接使用 TextInput;不得用 placeholder 充当标签;不得用 watch() 派生提交状态或 live 值;不得用 disabled 隐藏表单问题;不得用 KeyboardAvoidingView 或普通 ScrollView 代替键盘感知滚动;不得在 schema 内翻译消息;不得使用固定 bottomOffset;reset 只能在保存成功且 handleSubmit 结束后执行。check-forms.mjs 含 17 条规则,唯一允许的 SKIP 是 en.json 尚未创建的情况。资料未提供收费、价格、平台覆盖范围(除 iOS 与 Android 手动测试要求外)与效果数据,相关事实暂未提供。