Field 表单项
把一个控件和它的标签、说明、错误信息排成一组,并替控件接好无障碍关联。 一组相关的表单项用 FieldSet 字段组 包起来,多个表单项之间的间距交给 FieldGroup 表单项分组。
标签、控件、说明各放一个插槽。标签自动成为控件的可访问名、说明成为它的描述,点标签聚焦控件。
<pt-field>
<span slot="label">邮箱</span>
<pt-input type="email" placeholder="name@example.com"></pt-input>
<span slot="description">用于登录与找回密码,不会公开</span>
</pt-field>插槽
| 插槽 | 放什么 |
|---|---|
label | 标签文字。放纯文字的 <span> 即可,字号、字重、颜色由表单项负责 |
| (默认) | 控件。可以包在容器里(如 pt-input-group),表单项会找到其中第一个控件 |
description | 说明文字 |
error | 错误信息。有内容时优先于 errors 属性 |
「控件」指默认插槽里第一个 kit 表单控件:pt-input、pt-textarea、pt-select、pt-native-select、 pt-checkbox、pt-switch、pt-radio-group、pt-slider。嵌套的 pt-field 里的控件归内层所有。 原生 <input> 不在此列 —— 它在 light DOM 里,直接用原生 <label> 更合适。
必填、出错与禁用
required / invalid / disabled 写在表单项上,会下发给里面的控件:星号、红框、aria-invalid、禁用都跟着走。错误文字放 error 插槽,或用 errors 属性(JS 赋值)。
<pt-field required invalid>
<span slot="label">用户名</span>
<pt-input value="a"></pt-input>
<span slot="error">至少 3 个字符</span>
</pt-field>
<pt-field disabled>
<span slot="label">账号 ID</span>
<pt-input value="PT-20260926"></pt-input>
<span slot="description">创建后不可修改</span>
</pt-field>required、invalid、disabled 写在表单项上,会经继承通道下发给控件(控件的 inherited-required / inherited-invalid / inherited-disabled attribute):必填星号、红框、aria-invalid / aria-required、表单校验、 禁用都跟着控件自己的实现走,不需要在控件上再写一遍。控件的有效状态是它自己的属性与继承的并集。
表单项不改写控件自己的 required / invalid / disabled:应用在控件上另写的同名属性、受控绑定都与表单项互不干扰, 读到的始终是应用自己写的值;表单项撤回后控件回到它自己的状态。外层 pt-field-set 的 disabled 也走同一条通道, 见 FieldSet 字段组。inherited-* 属于内部通道,不要在应用里直接写。
错误信息有两种给法:
<!-- 插槽:任意内容 -->
<pt-field invalid>
<span slot="label">用户名</span>
<pt-input></pt-input>
<span slot="error">至少 3 个字符</span>
</pt-field>// errors 属性:字符串数组,只能用 JS 赋值(React / Vue / Angular 里照常绑定)
field.errors = ['至少 3 个字符', '只能包含字母和数字'];errors 会去掉空串与重复项:剩一条时显示为纯文本,多条时显示为列表,一条都没有时不渲染。 错误区是 role="alert",出现时读屏会立即念出来。invalid 不会因为有错误信息而自动变真 —— 两者分开写, 便于「先显示提示、提交时才标红」这类时机控制。
排列方向
顺序跟随子元素的先后:复选框写在标签前面就排在左侧,开关写在后面就排在右侧,标签与说明那一列撑满剩余宽度。
<pt-field orientation="horizontal">
<pt-checkbox></pt-checkbox>
<span slot="label">记住登录状态</span>
</pt-field>
<pt-field orientation="horizontal">
<span slot="label">邮件通知</span>
<span slot="description">有新评论时发邮件提醒</span>
<pt-switch></pt-switch>
</pt-field>orientation | 排列 |
|---|---|
vertical | 默认。标签、控件、说明、错误上下排列,间距 8px |
horizontal | 标签、说明、错误收成一列,与控件左右排、垂直居中 |
responsive | 视口窄于 768px 时同 vertical,宽屏时同 horizontal |
顺序跟随子元素在 DOM 里的先后:标签、说明、控件谁写在前面谁就排在前面,错误信息总在最后。 横向时控件写在标签前面(复选框、单选组的常见写法)就排在左侧,写在后面(开关、设置项)就排在右侧。
横向时标签那一列撑满剩余宽度、控件保持自身宽度。要让输入框这类控件撑满,写 pt-field::part(control) { flex: 1; }。
无障碍
- 标签成为控件的可访问名,说明与错误信息(按这个顺序)成为它的描述。关联经
utils/aria-link跨过影子边界, 落在控件影子树里真正获得焦点的元素上(与 Label 的for同一套机制)。 - 控件后插入、被替换或移除,标签被移除或改了
slot,文字改了 —— 关联都跟着更新,旧控件上的关联与下发的状态会撤掉。 - 点标签聚焦控件;
pt-checkbox/pt-switch像原生 label 一样直接切换。点在标签里的链接、按钮与 kit 交互组件(如链接形态的pt-badge)上、表单项禁用时不转交。pt-radio-group没有唯一的聚焦目标,点标签不动(与原生<legend>一致)。 - 标签用带
for的pt-label也可以,点击由它自己转交,表单项不会再切一次。 errors属性渲染在表单项的影子树里,支持 ARIA 元素反射的浏览器也引用不到它(不在控件的祖先树里), 这时靠文字镜像进控件的aria-description;error插槽里的元素两条路都走得通。
API
属性
| 属性 | Attribute | 类型 | 默认值 | 说明 |
|---|---|---|---|---|
disabled | disabled | boolean | false | 禁用:标签与说明变淡,点标签不再聚焦,并下发给控件。外层 pt-field-set 的禁用经 `inherited-disabled` 生效,不改写它 |
errors | — | string[] | undefined | — | 错误信息列表(只能用 JS 赋值)。去掉空串与重复项后:一条显示为纯文本,多条显示为列表; 没有内容时不渲染。`error` 插槽有内容时以插槽为准 |
inheritedDisabled | inherited-disabled | boolean | false | 外层 pt-field-set 下发的禁用。内部继承通道:由它以 attribute 维护,不建议使用方直接写。 有效禁用是 `disabled` 与它的并集;父元素只写这一条、不碰 `disabled`,读 `el.disabled` 得到的始终是使用方自己写的值 |
invalid | invalid | boolean | false | 出错态:下发给控件(红框、aria-invalid、表单校验失败)。错误文字由 `errors` 或 `error` 插槽给出 |
orientation | orientation | "horizontal" | "responsive" | "vertical" | 'vertical' | 排列方向。`vertical` 上下排;`horizontal` 标签一列与控件左右排、垂直居中; `responsive` 窄屏(< 768px)上下排、宽屏左右排 |
required | required | boolean | false | 必填:标签后显示星号,并下发给控件(aria-required、表单校验) |
插槽
| 名称 | 说明 |
|---|---|
(默认) | 控件 |
description | 说明文字 |
error | 错误信息。有内容时优先于 `errors` 属性 |
label | 标签文字。放纯文字或 `<span>` 即可,排版由表单项负责 |
可定制的内部元素(::part())
| part | 说明 |
|---|---|
base | 外层排版容器 |
content | 标签、说明、错误信息所在的一列(纵向时不成盒,只在横向时是一列) |
control | 控件 |
description | 说明 |
error | 错误信息(role=alert) |
label | 标签 |
required | 必填星号(aria-hidden,必填语义在控件的 aria-required 上) |