跳到主要内容

Form 表单

表单容器——分组标题 + 行(label + 控件)+ 行间 hairline 分隔。

实时预览

下方渲染的就是 src/components/ui/Form/Form.tsx 本体,通过 react-native-web 翻译成浏览器节点。

基本信息
姓名 *
手机号 *
格式不正确
拜访设置
拜访提醒
同步给团队

API

来源:src/components/ui/Form/types.ts{Form,FormGroup,FormRow}.tsx

<Form>

PropType默认说明
childrenReactNode通常是若干 FormGroup / FormRow;根容器纵向堆叠,组间 gap: space[7](16)
testIDstring?E2E / 测试定位

<FormGroup>

PropType默认说明
labelstring?分组标题(uppercase 小标签风格);不传则不渲染标题行
childrenReactNode该分组下若干 FormRow;行间自动插 1px hairline 分隔(除首行外)
testIDstring?E2E / 测试定位

<FormRow>

PropType默认说明
labelstring字段标题(左侧)
childrenReactNode字段控件(Input / Switch 等,右侧)
requiredboolean?false必填标记,label 后渲染红色 *(色值 c.error
errorstring?错误信息,渲染在该行下方(红字)
testIDstring?E2E / 测试定位

FormGroup 动态列表(运行时增删 FormRow)必须给每个 child 传稳定 key;不传时 fallback 到 __row-${i},仅适用于静态列表,动态列表会导致 state 漂移。

视觉规范

来源:src/components/ui/Form/styles.ts(值取自 src/theme/tokens.ts)。

元素规则
分组标题t.xs(13)/ fw.semi(600)/ c.foregroundSubtle,全大写、letterSpacing: 1paddingHorizontal: space[1](4)
分组卡片c.surface 白底,radius.lg(10)圆角,overflow: hidden,组内 gap: space[3](8)
Form RowminHeight: 48,左 label + 右控件,paddingHorizontal: space[7](16)/ paddingVertical: space[5](12)
行 labelt.sm(14)/ fw.medium(500)/ c.foreground
行间分隔StyleSheet.hairlineWidthc.outline(亮色 #EDEDED)(这是 form 的例外,用 gap)
必填标记label 后带 *,色 c.error(亮色 #F4511E
错误提示行下方 t.micro(11)/ c.error 红字

用法

import { Form, FormGroup, FormRow, Input, Switch } from '@unif/react-native-design';

<Form>
<FormGroup label="基本信息">
<FormRow label="姓名" required>
<Input value={name} onChangeText={setName} placeholder="请输入" />
</FormRow>
<FormRow label="手机号" error="格式不正确">
<Input value={phone} onChangeText={setPhone} keyboardType="phone-pad" />
</FormRow>
</FormGroup>

<FormGroup label="拜访设置">
<FormRow label="提醒">
<Switch value={remind} onChange={setRemind} />
</FormRow>
</FormGroup>
</Form>

无障碍(a11y)

来源:src/components/ui/Form/{Form,FormGroup,FormRow}.tsxtypes.ts

Form / FormGroup / FormRow 都是纯布局容器,源码全是 <View> + <Text>(分组标题 / 字段 label / 必填星号 / 错误文字),三者均未设置任何 a11y prop(无 accessibilityRole / accessibilityLabel / state),也无可传的 a11y prop。

  • 真正的 a11y 语义来自传入 FormRow控件 children(如 Input<TextInput>Switch),由控件自身承载 role / label / state。
  • FormRowlabel、必填 *error 文字渲染为相邻 <Text>,默认对 SR 可读,但未与控件做程序化关联(无 accessibilityLabelledBy / describedBy)。为确保 SR 把字段名读到对应控件上,建议在控件上显式补 accessibilityLabel(如 <Input accessibilityLabel="姓名" />),错误态可补 accessibilityHint
// label 是视觉文本;控件上显式补 accessibilityLabel 把字段名关联到输入
<FormRow label="姓名" required>
<Input value={name} onChangeText={setName} accessibilityLabel="姓名" />
</FormRow>

与 Cell · List 的区别

用途选哪个
数据展示(设置项、客户列表)Cell · List — 白卡 + gap
数据录入(表单)Form — 白卡 + 行间 hairline

录入场景密度更高,hairline 分隔比 gap 更高效;展示场景反之。