TextField 输入框 base(internal)
src/components/ui/TextField/ 是 Input / Textarea / PasswordInput / Search 这些公开输入组件共享的内部 base,处理:
- TextInput 基础 props 透传
leading/trailingslot(图标 / 按钮槽位)error文案 + border 红色态切换disabled整体半透明 + editable 锁- 单行 / 多行布局切换(
multilineprop)
业务层不应直接 import TextField。所有调用方场景都有更精准的封装:
| 场景 | 用 |
|---|---|
| 单行输入 | <Input> |
| 密码 / 隐显切换 | <PasswordInput> |
| 搜索栏(图标 + 占位) | <Search> |
| 多行输入 | <Textarea> |
设计意图
TextField 抽出来是为了消除 Input / Textarea 之间 50%+ 重复代码(focus 态 border 切换 / disabled 灰化 / error 文案下挂 / leading-trailing slot 布局)。它是实现细节,不是稳定 API,后续重构可能换内部结构。
如果你正在调用 TextField,99% 的可能性是该用 Input / Textarea。
实现路径
src/components/ui/
├── TextField/ ← 共享 base(本组件,internal)
├── Input/ ← multiline=false 单行封装
├── Textarea/ ← multiline=true 多行封装
├── PasswordInput/ ← Input + trailing 眼睛 toggle + secureTextEntry
└── Search/ ← Input + leading 搜索图标 + 圆角胶囊预设
Props(internal)
来源:src/components/ui/TextField/types.ts、TextFieldBase.tsx。非公开 API——下表仅说明 Input / Textarea 通过封装间接暴露了哪些行为,请勿直接 import。TextFieldBaseProps = TextInputProps(全部 RN TextInput props 透传)+ 这些扩展:
| Prop | 类型 | 默认 | 说明 |
|---|---|---|---|
multiline | boolean? | false | false=Input 单行固定 height;true=Textarea 多行 minHeight/maxHeight + 顶对齐 |
height | number? | control.lg(44) | 单行高度(multiline=false 时生效) |
minHeight | number? | 96 | 最小高度(multiline=true 时生效) |
maxHeight | number? | — | 最大高度(multiline=true);超出 ScrollView 内滚 |
leading | ReactNode? | — | 左侧 slot(Icon / 装饰) |
trailing | ReactNode? | — | 右侧 slot(Icon / 操作按钮) |
error | string? | — | 非空字符串时 border 切 error 色并在下方显示文本("" / undefined 不进 error 态) |
disabled | boolean? | — | 整体禁用:opacity 0.5 + editable=false,优先级高于 editable |
containerStyle | StyleProp<ViewStyle>? | — | 外层 View 附加 style |
forwardRef<TextInputRef>:业务表单可inputRef.current?.focus()(实际通过 Input / Textarea 透传)。视觉 4 态优先级:error > focus > filled > idle。
无障碍(a11y)
来源:src/components/ui/TextField/TextFieldBase.tsx、types.ts。
TextFieldBase 包裹原生 <TextInput>,因此继承 RN TextInput 内置的可编辑文本 a11y 语义——源码未额外硬编码 accessibilityRole(依赖 TextInput 默认)。
- a11y props(继承):
TextFieldBasePropsextendsTextInputProps,并把{...rest}透传给<TextInput>,所以 RN 原生 a11y props(accessibilityLabel、accessibilityHint、placeholder等)都可由调用方传入并生效;本 base 自身不暴露专门的 a11y prop。 - 状态语义:仅显式设置
accessibilityState={disabled ? { disabled: true } : undefined}——disabled(优先级高于editable)会同时令editable=false。error仅作视觉态 + 下方<Text>文案,源码未把它接入 a11y(如accessibilityInvalid),需要时由上层封装补。 - 该组件是 internal base:实际 a11y 由公开封装 Input /
Textarea/ PasswordInput / Search 在各自层面传入 label。
// 调用方(如 Input/Textarea)透传 RN 原生 a11y props
<Textarea accessibilityLabel="拜访备注" placeholder="详细说明…" />
不要
- 不要
import { TextField } from '@unif/react-native-design'—— 用对应高层组件,见上表 - 不要把 TextField 当公共 API 写测试 —— 测 Input / Textarea / PasswordInput / Search 的行为,TextField 实现细节会变