跳到主要内容

TextField 输入框 base(internal)

src/components/ui/TextField/Input / Textarea / PasswordInput / Search 这些公开输入组件共享的内部 base,处理:

  • TextInput 基础 props 透传
  • leading / trailing slot(图标 / 按钮槽位)
  • error 文案 + border 红色态切换
  • disabled 整体半透明 + editable 锁
  • 单行 / 多行布局切换(multiline prop)

业务层不应直接 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.tsTextFieldBase.tsx非公开 API——下表仅说明 Input / Textarea 通过封装间接暴露了哪些行为,请勿直接 import。TextFieldBaseProps = TextInputProps(全部 RN TextInput props 透传)+ 这些扩展:

Prop类型默认说明
multilineboolean?falsefalse=Input 单行固定 height;true=Textarea 多行 minHeight/maxHeight + 顶对齐
heightnumber?control.lg(44)单行高度(multiline=false 时生效)
minHeightnumber?96最小高度(multiline=true 时生效)
maxHeightnumber?最大高度(multiline=true);超出 ScrollView 内滚
leadingReactNode?左侧 slot(Icon / 装饰)
trailingReactNode?右侧 slot(Icon / 操作按钮)
errorstring?非空字符串时 border 切 error 色并在下方显示文本("" / undefined 不进 error 态)
disabledboolean?整体禁用:opacity 0.5 + editable=false,优先级高于 editable
containerStyleStyleProp<ViewStyle>?外层 View 附加 style

forwardRef<TextInputRef>:业务表单可 inputRef.current?.focus()(实际通过 Input / Textarea 透传)。视觉 4 态优先级:error > focus > filled > idle。

无障碍(a11y)

来源:src/components/ui/TextField/TextFieldBase.tsxtypes.ts

TextFieldBase 包裹原生 <TextInput>,因此继承 RN TextInput 内置的可编辑文本 a11y 语义——源码额外硬编码 accessibilityRole(依赖 TextInput 默认)。

  • a11y props(继承):TextFieldBaseProps extends TextInputProps,并把 {...rest} 透传给 <TextInput>,所以 RN 原生 a11y props(accessibilityLabelaccessibilityHintplaceholder 等)都可由调用方传入并生效;本 base 自身不暴露专门的 a11y prop。
  • 状态语义:仅显式设置 accessibilityState={disabled ? { disabled: true } : undefined}——disabled(优先级高于 editable)会同时令 editable=falseerror 仅作视觉态 + 下方 <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 实现细节会变