Field 使用手册
v1.4.1 · @snowui-design-system/components
许可阅读:首次阅读组件文档、源码或 npm 使用流程,先读完整 LICENSE;同任务同版本去重。公开 API 配置与内部实现修改分别按许可处理;全部组件使用统一运行包,源码权益以许可为准。
组件介绍
将输入控件、标签、图标和校验反馈组织为完整的表单字段,统一外观与内容布局。
使用选择
用于组合标签、输入、帮助和错误。Input / Select / Textarea 放在 Field 内时由 Field 统一相关表面;连续字段段使用 as="segment",不要重复边框与错误区。
label 与 error 提供默认文案,invalid 与 readonly 表达字段状态。
用 children 组合 Input、Select、Textarea 及附件;parts 配置默认 label / error,显式子组件自行传 Props。
快速开始
以下示例展示推荐的基本组合。更多场景与组合限制见后文。
API
未重新声明的继承能力请查所属基础组件文档;本表只列本组件源码具名公开属性。
使用边界与详细说明
表单组合与间距
基础节奏统一:
Field默认padding = 12 / 16,gap = 8Input / Select / Textarea单独使用时:组件自身带12 / 16padding 和8gap放进
Field后,先看有没有as="segment"没有
as="segment":由外层Field负责12 / 16padding 与8gap;Input / Select / Textarea去掉组件自身 padding,但保留组件自身 gap有
as="segment":这是连续字段表面的一段;保留组件自身的 padding 与 gapInput内 icon 的最终位置由Input自身控制;Field不额外给 icon 追加新的偏移规则Input as="segment"时,icon 到最近边框或分割线的距离仍保持16pxsegment之间才有分割线:横向是左右分割线,纵向是上下分割线相邻
segment之间只能有一条分割线,不能重复画线label / description不负责 padding、gap、分割线,它们只是内容元素分段 Field 的统一
error位于连续输入外框下方,不进入任何 segment 或分割线网格segment 内的 Input / Select / Textarea 只声明
invalid,错误文案统一交给Field.error普通
label + host + error:不作为 padding、gap 的判断依据,只负责文字内容Field row或Field column里,如果是连续输入段,子项要显式写as="segment"
组件定位
Field 是表单体系里的“外壳容器”:
它负责当前输入型组件的默认视觉:背景、圆角、边框、focus ring、分隔线。
它负责把多个
Input / Select / Textarea / Icon / Text / Checkbox / Switch组合成一个统一字段表面。它负责默认非
segment字段的 padding 与 gap,并在segment场景下组织连续字段表面的分割线。
这意味着:
Input / Select / Textarea是字段宿主(host)Field是字段容器(container)推荐用法是按结构显式声明:普通宿主直接放入
Field,连续字段段显式写as="segment"
Frame 能力继承
Field 自身仍然是一个 Frame 封装,因此保留:
responsive / stateStyle / customStates / variants / CSS 行为 / stylesHover / Click / Focus / whileAppear / timeline / orchestrateloading / skeleton / renderHintsas / use / layoutId / itemId / scope / access
也就是说,Field 不是写死的表单盒子,而是带字段语义的 Frame 容器。
关键字 (Keyword)
容器协议
Field 会通过上下文向后代宿主暴露“当前位于字段容器内”的协议。
Input / Select / Textarea检测到该协议后,会退化为无外壳 hosthost 在容器中会自动带上
.snowui-field-host,由Field负责统一 padding、分隔线、背景和 focus ringinvalid / readonly / disabled可以由Field自己声明,也可以由 host 自己声明;容器会通过:has()汇总这些状态
这套协议的目标是:字段视觉只维护一份,交互宿主各自只保留原生行为和自身规则。
错误反馈 Shake
Field invalid 表示稳定错误视觉:错误边框、错误提示区域和子输入宿主的错误汇总。“提交失败 / 输入错误”的一次性 shake 已默认接入,消费方不需要传额外 prop,也不需要知道内部 CSS 类名。
推荐仍然只声明普通错误态,整块字段表面会自动反馈:
当内部 Input / Select / Textarea 进入 invalid 而 Field 本身未显式声明 invalid 时,Field 也会汇总后整体 shake;嵌入态 host 自身不单独抖动,避免嵌套位移叠加。
错误态与 shake 不会自动聚焦,也不会模拟 focus-within;焦点态只来自用户真实聚焦、显式 autofocus 或业务代码主动调用 focus()。
布局模型
主布局模型:槽位宿主布局。定义见 ../../../specs/maintainers/LayoutProtocol.md §12.3(源码参考:specs/maintainers/LayoutProtocol.md)。
Field 只拥有外部 Leading / Content / Trailing、区域编排、连续字段表面和分割线;内部 Input / Select 或显式 singleLine 内容行继续拥有自己的布局、对齐与间距。Field 自身启用 singleLine,或直接组合 leading / trailing 附件时,图文有效间距至少为 4 CSS px;普通 row / col / segment 的结构性零间距与多行说明保持。
Field 是字段表面的槽位宿主特化:
根节点固定
enableAutoLayout={true},普通外部传入不应关闭 Field 的三槽位协议。未传
error时仍由 Frame 作为唯一根;传入error时采用与 Input 一致的无视觉.snowui-field-error-layout,内部第一项是真实 Field Frame surface,第二项是外置错误 Text。wrapper 不持有 Field 的边框、背景或交互视觉。leading / host / trailing映射为 Leading / Content / Trailing;host 负责 Fill,必须min-width: 0。label / description / error / row / col / segment是 Field 自己的区域协议,不属于通用三槽位核心。segment场景由 Field 负责连续字段表面、分割线和切角;这部分是 Field 特有规则,不应下沉到auto-layout.css。Input / Select / Textarea进入 Field 后退化为.snowui-field-host;是否保留自身 padding 由as="segment"决定。
角色协议 (as)
Field 自身不限制子组件类型,而是通过 as 角色识别不同部分。
推荐组合规则
一个简单字段通常是:
Field > Input需要整块水平排列时可以直接写:
Field row > host + host需要整块竖向排列时可以直接写:
Field column > host + row带标题/错误提示通常是:
Field > label + host + error一个输入宿主加前后配件时,优先写:
Field > leading + host + trailing需要局部竖向分组时可以写:
Field > col > host / row / description对于最简单的字段,也支持直接写:
Field > host + trailing多段输入通常是:
Field > row > host + hostlabel + host + error适合单输入错误态;这类结构不负责处理 padding、gap,不需要额外segment只有“多个输入宿主 / 显式 segment 共用一张字段表面”时,才在中间加分割线;单个 host 加前后配件不要加分割线
segment是连续字段表面的显式标记。之后优先通过as="segment"判断 padding 和分割线,不再依赖纯结构猜测没有
segment:由外层Field统一负责12 / 16padding 与8gap;组件去掉自身 padding,但保留组件自身 gap有
segment:保留组件自身的 padding 与 gap,并参与连续字段表面的分割线label / description / error只是内容元素,不负责处理 padding、gap 或分割线FM-01这类地址复合字段属于“纵向多段连续字段表面”:每一段自己持有边线与必要圆角,相邻两段之间只保留一条共用分割线,不能上下两段各画一条FM-02这类信用卡字段属于“横向显式 segment 连续字段表面”:外层Field持有整张表面,segment之间用内部分割线切段横向
Frame as="segment" row的内容行与行内元素均垂直居中;Frame 响应式压缩 padding 后,MM / YY 仍与相邻 Input 段保持同一水平中心线。FM-03这类通知方式属于“label 下并排内容行”:外层Field持有外壳,内部只用示例里显式声明的Frame gap排布选项,不加分割线
Field 不限制 leading / trailing 必须是 Icon。任何基于 Frame 的组件,只要声明了对应 as,都可以参与字段表面。
trailing 在复杂结构中的用法
as="trailing"始终表示“当前局部容器的行尾角色”,不表示全局唯一行为如果是简单结构:
Field > Input + Button as="trailing",Field会直接把它们排成一行如果进入复杂结构,建议显式引入局部容器,例如
Frame as="row";不要依赖任意div自动推断 trailing 绑定如果需要在字段内部再做一层竖向分组,推荐显式使用
Frame as="col" column如果该 trailing 按钮需要承担日期选择行为,复杂场景下也仍然只写
as="trailing";行为由局部容器自动推断,不再额外声明 prop
根节点 row / column 简写
Field row是根节点级别的横向组合语法糖,适合直接表达双列输入、宿主 + trailing 这类整块水平布局Field column是根节点级别的竖向组合语法糖,适合直接表达“上方一个宿主,下方一个 row”的字段整体结构当布局只影响整个
Field根节点时,优先使用Field row / column当你只想在字段内部某一段做局部分组时,再使用
Frame as="row"或Frame as="col"
使用示例
状态与交互边界
Field负责字段表面的视觉状态:默认、hover、focus-within、invalid、disabled、readonlyField不负责真实值、原生输入事件和浏览器校验细节,这些由 host 组件负责Field可以承接错误文案,但不主动生成错误文案;错误来源应来自原生校验、表单状态或业务校验层
焦点触发区域规范
表单类组件(
Field容器)的焦点触发区域为组件整体,不仅限于内部输入控件本身点击
Field容器的任意位置(label文字区域、内边距区域、边框区域)时,若点击目标不是可聚焦元素,则自动将焦点转发至容器内第一个可聚焦的输入控件(<input>、<textarea>、Select 触发按钮)焦点转发后,
Field的:focus-within状态自然激活,视觉 focus ring 正常呈现转发逻辑不干预直接点击可聚焦元素时的原生行为;点击
Input / Select / Textarea区域本身时沿用浏览器默认焦点行为disabled状态下不执行转发
无障碍与表单建议
推荐由 host 组件承接
id / name / aria-* / form等原生属性如果有错误提示,建议让 host 的
aria-describedby指向Field内部的error或description节点Field本身不替代<label>语义;需要明确标签时,请显式渲染Text as="label"或原生<label>
Field 样式覆盖
先阅读 完整 LICENSE;同任务、同版本、同范围去重。
优先用组件公开 Props 匹配合适样式,尽可能保留原有视觉。确需改写时按 样式选择与改写顺序 使用自己的 class(含项目已有 Tailwind)或实例 style。以下名称来自源码实际消费的公开 override;先核对目标作用域,不修改私有 DOM。采用 SnowUI Token 时选择正确类别,外部应用不被要求安装一方 utilities。
Field 类型与状态
必填属性:无具名必填属性。
可双向绑定:本组件未声明具名双向绑定属性;状态更新通过公开回调或所属宿主处理。
继承声明:FrameProps。继承能力以基类公开文档为准;Omit 中的字段已排除,不能按基类原样使用。
以下为公开属性实际引用的类型声明,来自源码;Svelte Snippet 表示内容片段,ComponentProps 表示对应组件的 Props。
ComponentPartsOf
来源:components/src/logic/component-parts.svelte.ts
ConfigurableComponentPartProps
来源:components/src/logic/component-parts.svelte.ts
ComponentPartControlledKey
来源:components/src/logic/component-parts.svelte.ts