PasswordInput 密码输入框
ui 层组件,封装"密码 Input + 眼睛切换明文/密文"通用 pattern。caller 只关心
value/onChangeText,组件内部 useState(showPw) 自管。
实时预览
下方渲染的就是 src/components/ui/PasswordInput/PasswordInput.tsx 本体,通过 react-native-web 翻译成浏览器节点。点右侧眼睛切换明文 / 密文。
用法
import { PasswordInput } from '@unif/react-native-design';
<PasswordInput
value={pw}
onChangeText={setPw}
placeholder="请输入新密码"
/>
API
| Prop | 类型 | 默认 | 说明 |
|---|---|---|---|
value | string | — | 受控 value |
onChangeText | (v: string) => void | — | 受控 onChange |
placeholder | string? | '请输入密码' | placeholder 文案 |
testID | string? | — | 测试定位;trailing eye Pressable 自动 ${testID}-toggle |
inputProps | Partial<TextInputProps>? | — | 透传给底层 Input(maxLength 等)。不要传 secureTextEntry,组件自管,会被组件覆盖 |
设计稿对照
| 视觉态 | 规则 |
|---|---|
| leading | <Icon name="lock" size={18} color={c.iconFaint40} /> |
| trailing | Pressable eye toggle,默认 eye-off(密文),切到 eye(明文) |
| secureTextEntry | 默认 true,点 eye 切 false |
业务消费
- Login(
login-password) - ForgotPassword(
forgot-newPw/forgot-newPw2) - ChangePassword(
change-password-newPw)
无障碍(a11y)
来源:src/components/ui/PasswordInput/PasswordInput.tsx、types.ts。
- 默认
accessibilityRole:组件本体渲染为底层Input(最终原生<TextInput>),输入框 a11y 继承 RNTextInput,不显式设 role。trailing 的眼睛切换<Pressable>硬编码accessibilityRole="button"。 - a11y props:
PasswordInputProps不直接暴露输入框的 a11y prop,但可通过inputProps(Partial<TextInputProps>) 透传accessibilityLabel等到底层TextInput(⚠ 唯独secureTextEntry组件自管、会被覆盖,不要传)。眼睛按钮的accessibilityLabel由源码按当前态动态给出:明文显示中 →'隐藏密码',密文中 →'显示密码'。 - 状态语义:
secureTextEntry={!showPw}随内部showPw切换;眼睛按钮有意不加accessibilityHint——accessibilityLabel已表达切换意图,再加 hint 会被 SR over-hint(见 CLAUDE.md a11y 规范)。
// 眼睛按钮的 role/label 内置;如需给输入框加 label 走 inputProps
<PasswordInput value={pw} onChangeText={setPw} inputProps={{ accessibilityLabel: '新密码' }} />
不要
- ❌ 不要传
inputProps.secureTextEntry(组件自管,会被覆盖) - ❌ 不要在 caller 自己加 showPw state(组件内部已经有)
- ❌ 不要把 PasswordInput 用在"非密码"场景(它写死了 leading lock + eye toggle 语义)
关联组件
- Input— 底层 Input
- SmsCodeInput— SMS 验证码 Input