Field
field把标签、控件、帮助文字和错误串成一个无障碍字段
用法
基础用法
label 串 Field.Label,children 为控件(Input / Textarea)。
tsx
<Field label="邮箱">
<Input placeholder="you@work.com" />
</Field>帮助说明
description 渲染 muted 小字,自动串 aria-describedby。
我们不会公开你的邮箱
tsx
<Field label="邮箱" description="我们不会公开你的邮箱">
<Input placeholder="you@work.com" />
</Field>错误态
error 非空即隐含 invalid(标红 + 显错),无需另传 invalid。
邮箱格式不正确
tsx
<Field label="邮箱" error="邮箱格式不正确">
<Input defaultValue="not-an-email" />
</Field>必填
required 在 label 前画红星,并把 aria-required 注入控件;校验仍写在 rules 里,这个 prop 不产生校验。
tsx
<Field label="banner类型" required>
<Input placeholder="请选择" />
</Field>横排设置行
orientation=horizontal:标签区在左、控件在右、错误另起一行占满整行。
选择你偏好的配色方案
tsx
<Field
orientation="horizontal"
label="主题"
description="选择你偏好的配色方案"
>
<Input defaultValue="深色" />
</Field>横排定宽标签列
顶掉默认列模板即可换成定宽标签 + 控件填满,不需要额外的 prop。
邮箱格式不正确
tsx
<Field
orientation="horizontal"
label="邮箱"
error="邮箱格式不正确"
className="grid-cols-[6rem_1fr]"
>
<Input defaultValue="not-an-email" />
</Field>禁用态
disabled 透传 Field.Root,控件随之禁用。
tsx
<Field label="邮箱" disabled>
<Input placeholder="you@work.com" />
</Field>何时用
给单个输入控件(Input/Textarea 等)套 label + 帮助文案 + 错误提示,并自动把三者用 aria-describedby/aria-invalid 串好无障碍关系时用。它是表单的最小积木——Form/ProForm 内部就靠它布字段;你手搓一行字段、或在 StepsForm 各步里放控件时也直接用它。
导入
ts
import { Field } from "@hulianui/ui"Props
| 名称 | 类型 | 默认 | 说明 |
|---|---|---|---|
| invalid | boolean | false | 显式覆盖 invalid;缺省时由 error 是否非空推导 |
| required | boolean | false | 必填态:label 前画红星 + 给控件注入 aria-required。不产生校验(校验仍只由 rules 表达),解决的是「提交前看不出哪些字段必填」。useForm 的 register() 会按 rules 派生 required,直接透传即可 |
| requiredMark | boolean | ReactNode | true | 必填标记形态。false = 只留 aria-required 不画标记;传 ReactNode = 换成自家标记。required 为假时无效 |
| disabled | boolean | false | 禁用 |
| name | string | - | 提交标识,透传 Field.Root |
| orientation | "vertical" | "horizontal" | "vertical" | 排列方向。horizontal = 标签区在左、控件在右、错误另起一行占满整行(设置页「一行一个设置项」版式),a11y 串联与错误渲染完全一致 |
| colSpan | "full" | - | 在 ProForm columns 栅格中跨整行;栅格外无副作用 |
| className | string | - | 落在 Field.Root(竖排为 flex 列容器,横排为两列网格) |
| labelClassName | string | - | 追加到 label(默认 text-sm font-medium text-foreground w-fit);走 twMerge,传 text-xs 会顶掉默认字号,传 w-full 会让 label 恢复满宽 |
| descriptionClassName | string | - | 追加到 description(默认 text-xs text-muted-foreground) |
| errorClassName | string | - | 追加到 error(默认 text-xs text-danger) |
Slots
| 插槽 | 类型 | 说明 |
|---|---|---|
| children* | ReactNode | 控件(hulian Input / Textarea,= Field.Control) |
| label | ReactNode | 标签 |
| description | ReactNode | help 文案 |
| error | ReactNode | 错误文案;非空即隐含 invalid 并强制显错 |
禁忌 / 坑
required的aria-required只在 `children` 是单个元素时能注入 —— 那是 Field 唯一够得着的节点。children 是多节点(控件 + 按钮)或纯文本时,请自己给控件加aria-required,否则读屏拿不到必填信息(自建的aria-hidden星号读屏读不到)。aria-required只对输入型 role 有效(textbox / combobox / listbox / radiogroup / checkbox …)。控件的可聚焦元素是role="button"时(典型是 Upload 的落区),注进去读屏也不会念 —— 那一档由组件自己把必填翻成说明文本,用法不变。- label 默认按文字宽收窄(
w-fit):它是带htmlFor的真<label>,被 flex 拉满整行时行尾那片看不见的空白照样把点击转发给控件 —— 对浮层型控件就是「点了下拉框上方的空处,浮层凭空弹开」。需要满宽 label(如标签与右侧开关两端对齐)时传labelClassName="w-full"。 - 不要为了画星号把 label 包成自定义的
RequiredLabel—— 那样只有视力用户知道必填,读屏用户拿不到,而且每个页面的星号位置/颜色会各写各的。 error字符串非空时已隐含invalid,无需再传invalid;想强制无错状态下也标红才单独传invalid。- 底层是 Base UI Field,错误文本通过
match={true}强制渲染——别在 Field 外另起一个<p>写错误,会丢失自动的aria-describedby串联。详见 [[base-ui-field-error-match-true-for-external-controlled-error]]:外部受控 error 不走 Base UI 校验时,默认分支会让错误文本「框红字没」。 - 若 children 是 Textarea,注意 render-as 的类型问题,见 [[base-ui-field-control-render-textarea-type-safe]]。
- 横排的标签列宽度没有单独的 prop:
orientation="horizontal"下 Field.Root 是grid-cols-[1fr_auto]的网格,传className="grid-cols-[8rem_1fr]"顶掉默认列模板即可。默认的auto列让控件贴右边缘(设置行),换成1fr则让控件填满(表单行)。 - 只要一个标签、不要 help/error 三段与 a11y 串联时,用 Label,别为了拿标签皮肤而空套一层 Field。
相关
Label · Form · ModalForm / DrawerForm · ProForm · StepsForm · LoginForm · SearchForm
Playground
我们不会公开你的邮箱
<Field label="邮箱" description="我们不会公开你的邮箱">
<Input placeholder="you@work.com" />
</Field>