Select 使用手册
v3.3.0 · @snowui-design-system/components
许可阅读:首次阅读组件文档、源码或 npm 使用流程,先读完整 LICENSE;同任务同版本去重。公开 API 配置与内部实现修改分别按许可处理;全部组件使用统一运行包,源码权益以许可为准。
组件介绍
在下拉列表中选择选项,可由数据直接生成面板,也可自定义选项组合,支持搜索与键盘操作。
使用选择
用于下拉单选。默认传 options 生成 Listbox / MenuItem;显式 children 替换默认选项面板。命令菜单优先 SelectButton;不是任意多选或自由输入控件。
options 默认生成列表;显式 children 提供 Listbox / MenuItem 后替换默认列表。
persistent 保存选择;action 只调用 onAction 并关闭,不保存本次选择。默认子项用 parts,显式子项直接配置。
列表通过 Escape 关闭后,字段型与 buttonTrigger/SelectButton 模式均恢复真实触发按钮焦点;搜索头关闭行为由共享 Listbox 管理。
快速开始
以下示例展示推荐的基本组合。更多场景与组合限制见后文。
API
未重新声明的继承能力请查所属基础组件文档;本表只列本组件源码具名公开属性。
使用边界与详细说明
默认内置模式 / 显式组合模式
默认内置模式(推荐):传入
options,Select 自动生成 Listbox 与 MenuItem;搜索框默认关闭,通过parts.Listbox.search=true开启;通过parts.Button、parts.Listbox、parts.Input、parts.MenuItem配置隐藏实例。options中同一value的label或disabled更新时,当前选择的显示标签、搜索与键盘选项按新数据更新;调用方负责提供目标语言的业务文案。显式组合模式:显式书写 Listbox / Input / MenuItem,用于复杂内容或逐项差异;子组件 Props 直接写在实例上。
显式 children 存在时替换默认内置 Listbox,不同时激活两套选项。
Select 内的 Listbox 默认 search=false。显式组合时使用 <Listbox search> 开启;默认内置模式使用 parts={{ Listbox: { search: true } }} 开启。独立 Listbox 的默认值不受影响。
buttonTrigger 可将字段型 trigger 切换为真正的 bare Button;优先使用 triggerContent snippet,未提供时依次回退到选中项、placeholder、ariaLabel。适合 TableToolbar 的排序、筛选等图标操作。按钮保持 aria-haspopup="listbox"、aria-expanded、键盘导航和选中后焦点恢复。该模式的 Select 外层是无视觉 wrapper,不接入独立字段的 .snowui-field-bordered 外壳,最终背景、边框、尺寸与圆角只由真实 Button 宿主拥有。
2026-04-20 更新: 新增搜索 + 自定义值支持 — filterText / customOptions 状态由 Select 持有,内嵌 <Input as="search"> 可连接过滤逻辑;内嵌 Input 的 allowCustomValue prop 允许用户添加自定义选项;该属性不属于 Select。Combobox 已废弃。
2026-04-18 架构升级: Select v3.0.0 — Listbox 拆分为独立组件,API 从 <option> 切换到 <Listbox> + <MenuItem> 组合模式,表单提交改用 hidden <input>,不再依赖隐藏 <select> + MutationObserver。
2026-04-04 补充: 参考 Figma 9996:17631,Select 单独使用时默认保持 12 / 16 padding 与 8px gap;进入 Field 后,只看有没有 as="segment"。未标 segment 时由外层 Field 处理 12 / 16 与 gap = 8,Select 去掉自身 padding,但保留自身 gap;标了 segment 时保留 Select 自身的 padding 与 gap,并作为连续字段表面的一段参与分割线。
继承: 复用 Frame.svelte 的所有通用能力(状态、动效、响应式、Skeleton、样式编排)。 推荐容器: Field.svelte。 默认能力开关: enableResponsive=false, enableContext=true, enableScaleObserver=false。 自动布局协议: Select 根元素为 <Frame row>,trigger(content/fill)+ indicator(trailing/hug)由自动布局协议管理。
字段型原生 trigger 显式接入 layout.css 的 .snowui-native-control,只归一化 box sizing、margin 并继承消费环境的字体与颜色;Select 自身字号、行高、Padding、边框和状态视觉不依赖可选的 snowui-base.css。buttonTrigger 模式由 Button / Frame 的同一宿主基线承接。
2026-04-27 更新: Select v3.1.0 — 支持直系复杂 leading / trailing 槽位;自定义 trailing 替换默认 indicator。
显式内容与默认槽位
直系
Frame as="leading"/Frame as="trailing"支持复杂结构;图形与短标签并排时使用singleLine和Text lines={1},内部单行与最小间距由附件 Frame 管理。Select 根布局为
leading: auto、trigger: minmax(0, 1fr)、trailing: auto。存在自定义直系
as="trailing"时,默认 indicator 隐藏,由自定义 trailing 替换末位槽。
槽位组合边界
复杂附件需要为可编辑/可选内容保留宽度;下例显式设置最小240 CSS px,并用ScrollArea在更窄容器中局部横向滚动。
支持直系复杂
leading/trailing槽位。自定义 trailing 替换默认 indicator。
表单组合与间距
基础节奏统一:
Field默认padding = 12 / 16,gap = 8Select单独使用时:组件自身带12 / 16padding 和8gap放进
Field后,先看有没有as="segment"没有
as="segment":由外层Field负责12 / 16padding 与8gap;Select去掉自身 padding,但保留自身 gap有
as="segment":这是连续字段表面的一段;保留Select自身的 padding 与 gapsegment之间才有分割线:横向是左右分割线,纵向是上下分割线相邻
segment之间只能有一条分割线,不能重复画线label / description / error不负责 padding、gap、分割线,它们只是内容元素普通
label + host + error:不作为 padding、gap 的判断依据,只负责文字内容Field row或Field column里,如果是连续输入段,子项要显式写as="segment"
组件定位
Select 是自定义下拉选择框,采用 Trigger + Listbox 组合架构:
自身渲染 Trigger 按钮 +
ArrowLineUpDown指示器子内容为
<Listbox>+<MenuItem>组合,Listbox 自行 portal 到 body通过
ListboxOwnerContext(setContext)与子组件通信表单提交通过 hidden
<input type="hidden">桥接标签、错误提示与连续字段段逻辑建议通过
Field容器组合完成单独使用时可保持兼容性的默认输入框表现
Frame 能力继承
Select 仍然通过外层 Frame 继承:
responsive / stateStyle / customStates / variants / stylesHover / Click / Focus / whileAppear / timeline / orchestrateloading / skeleton / renderHintsas / use / layoutId / itemId / scope / access
因此 Select 不是一个单纯的裸 <select>,而是 Frame + 原生 select host。
错误反馈 Shake
Select invalid / aria-invalid 默认自动播放错误 shake。单独使用时由 Select 自身反馈;进入 Field 后,嵌入态 Select 不单独抖动,由外层 Field 汇总后整体反馈。
错误态与 shake 不会自动聚焦,也不会模拟 focus-within;焦点态只来自用户真实聚焦、显式 autofocus 或业务代码主动调用 focus()。
布局模型
主布局模型:槽位宿主布局。定义见 ../../../specs/maintainers/LayoutProtocol.md §12.3(源码参考:specs/maintainers/LayoutProtocol.md)。
普通字段模式的根宿主固定采用单行内容协议,选中值可收缩,图标与标签的有效间距至少为 4 CSS px;gap={0}、根字号或间距缩放不压低下限,较大首选间距保持。buttonTrigger 模式由真实 Button 拥有图文内容,Select 的无视觉定位外壳不增加空白间距。自定义 children 保留原结构,弹层与表单协议不变。
Select 的根布局固定按 Leading / Trigger / Trailing 三段组织:
根节点是
Frame row,并在组件内部固定启用enableAutoLayout;外部传入enableAutoLayout={false}不关闭 Select 的内部槽位协议。trigger 是 Content / Fill 槽,负责显示选中值或 placeholder,必须保持
min-width: 0与文本截断能力。默认 indicator 是 Trailing / Hug 槽。
存在直系自定义
as="trailing"时,默认 indicator 隐藏,由自定义 trailing 替换末位槽。Listbox / MenuItem 是 Select 的弹层内容协议,不参与 Select 根三槽位布局。
能力边界
Select 负责:
单选下拉选择(Trigger + Listbox 组合架构)
value / defaultValue解析ARIA combobox + listbox 完整语义
键盘导航(↑↓ / Enter / Space / Escape / Tab)
通过 hidden
<input>桥接表单提交通过
ListboxOwnerContext驱动子 Listbox / MenuItem持有
filterText与filteredOptions状态,为内嵌Input as="search"提供过滤能力持有
customOptions列表,支持用户在运行时添加 / 删除自定义选项
Select 不负责:
业务级选项获取与远程联想
多选模式(未来可扩展)
使用示例
无障碍与表单建议
Trigger 使用
role="combobox"+aria-haspopup="listbox"+aria-expanded+aria-controlsListbox 使用
role="listbox",每个选项role="option"+aria-selected键盘导航完整支持:↑↓ 移动焦点,Enter/Space 确认,Escape 关闭,Tab 关闭
如果需要错误提示,建议通过
aria-describedby关联Field内错误节点如果需要搜索型下拉或异步联想,应使用
Combobox组件
Select 样式覆盖
先阅读 完整 LICENSE;同任务、同版本、同范围去重。
优先用组件公开 Props 匹配合适样式,尽可能保留原有视觉。确需改写时按 样式选择与改写顺序 使用自己的 class(含项目已有 Tailwind)或实例 style。以下名称来自源码实际消费的公开 override;先核对目标作用域,不修改私有 DOM。采用 SnowUI Token 时选择正确类别,外部应用不被要求安装一方 utilities。
Select 类型与状态
必填属性:无具名必填属性。
可双向绑定:bind:value。
继承声明:Omit<FrameProps, "children" | "tag">。继承能力以基类公开文档为准;Omit 中的字段已排除,不能按基类原样使用。
以下为公开属性实际引用的类型声明,来自源码;Svelte Snippet 表示内容片段,ComponentProps 表示对应组件的 Props。
SelectValue
来源:components/src/components/Select.svelte
SelectOption
来源:components/src/components/Select.svelte
ListboxItem
来源:components/src/components/Listbox.svelte
SelectTriggerContext
来源:components/src/components/Select.svelte
SelectParts
来源:components/src/components/Select.svelte
ComponentPartsOf
来源:components/src/logic/component-parts.svelte.ts
ConfigurableComponentPartProps
来源:components/src/logic/component-parts.svelte.ts
ComponentPartControlledKey
来源:components/src/logic/component-parts.svelte.ts