定价

Segmented 使用手册

v1.3.0 · @snowui-design-system/components

许可阅读:首次阅读组件文档、源码或 npm 使用流程,先读完整 LICENSE;同任务同版本去重。公开 API 配置与内部实现修改分别按许可处理;全部组件使用统一运行包,源码权益以许可为准。

组件介绍

将少量互斥选项并排展示,便于快速切换筛选条件或参数,并支持键盘与表单交互。

使用选择

用于多个互斥参数或过滤条件之间单选,使用 radiogroup 语义。切换不同内容面板或视图时使用 Tab。

  • 使用 bind:value 与稳定选项值;缺失或不匹配时只视觉回退到首项,不自动写回绑定值,表单请显式初始化。

  • 显式子项使用 Button as="item";name 非空时提供隐藏表单字段,表单重置由应用恢复业务值。

快速开始

以下示例展示推荐的基本组合。更多场景与组合限制见后文。

<script lang="ts">	import { Segmented } from '@snowui-design-system/components';</script> <Segmented size="lg" value="all" aria-label="Filter components by category" items={[{ value: 'all', label: 'All' }, { value: 'basic', label: 'Basic' }, { value: 'composite', label: 'Composite' }]} />

API

关键字 类型 默认值 描述
value string — 当前选项的唯一值,支持 bind:value;点击或方向键激活选项时更新。未指定或没有匹配项时,视觉回退到首个可用项,但不会自动写回绑定值;表单场景应显式初始化。
name string — 非空时输出同名隐藏字段,原生 FormData 读取当前 value;未定义值提交为空字符串。需置于表单内部;业务绑定初值的恢复由调用方在 reset 时处理。
children Snippet — 无参数的显式子项内容,使用 Button as="item" 与唯一 value;优先于 items,逐项直接配置 Button Props。
class string "" 合并到真实 Tab 根节点的外部 class,保留 Segmented 自身标识;不作用于隐藏表单字段。
parts ComponentPartsOf<{ Button: typeof Button }> — 通过 parts.Button 批量配置 items 模式生成的 Button,例如 scaleOnHover;不覆盖显式 children 子项,不提供 parts.Tab。

未重新声明的继承能力请查所属基础组件文档;本表只列本组件源码具名公开属性。

使用边界与详细说明

默认内置模式 / 显式组合模式

  • Tab 宿主组件特化:Segmented 实际渲染真实 Tab,全部兼容 Tab Props 在根级平铺;不提供 parts.Tab。

  • 默认内置模式(推荐):items 交给 Tab 生成 Button;parts.Button 沿默认生成链路显式转发。

  • 显式组合模式:显式书写 <Button as="item">,逐项 Props 直接配置。


与 Tab 的关系

维度 Tab Segmented
语义 "视图/内容区"切换 "过滤器/参数"单选
ARIA role tablist / 子项 tab(隐式 button) radiogroup / 子项 radio
方向键 仅切焦点(selectionFollowsFocus=false),Enter 激活 直接切换并激活(selectionFollowsFocus=true)
接入 Form 否 是(name 属性 + 内部 hidden input)
视觉(variant/size/token) 完全相同 完全相同

Segmented 是 Tab 的宿主组件特化:真实 Tab 是主要视觉表面、交互节点和根 DOM;Segmented 只固定 radiogroup 语义、方向键直切行为,并增加 name 隐藏表单字段。

Segmented 继承 Tab 的复合控件 hover 规则:item 默认不放大,保留原有颜色与 indicator 反馈;可通过子 Button 或 parts.Button.scaleOnHover=true 显式开启。

宿主 Props 与所有权

  • 类型来源:ComponentProps<typeof Tab>。

  • 受控字段:value、children、role、itemRole、selectionFollowsFocus、class、parts。

  • Tab 继续拥有 variant、size、布局、indicator、键盘基础逻辑、Frame Props 与原始 DOM。

  • Segmented 拥有 radiogroup/radio ARIA、直切语义、name hidden input 及顶层 class 合并。

  • hidden input 是 Tab 根之后的无视觉辅助节点;不复制 Tab 表面。


2.1 Props

关键字 类型 默认值 描述
variant 'pill' | 'solid' | 'underline' | 'icon-toggle' | 'bare' 'pill' pill 为带背景滑块,solid 为实色选中项,underline 为下划线,icon-toggle 仅展开选中项文字,bare 仅通过透明度区分。icon-toggle 子项需包含 Icon 与 Text,或在 items 中同时提供 icon 与 label。
size 'sm' | 'md' | 'lg' 'sm' 控制容器 padding、radius、gap,并作为 Button 子项默认尺寸;子项优先级为 style > class > Button size > Segmented size。
row boolean false 显式横向排列;row 与 column 都未启用时仍按横向显示,两者同时为 true 时 row 优先。
column boolean false 纵向排列,方向键改为上下切换;仅在 row 未启用时生效。
fill boolean false 容器有明确宽度时,让横向子项等宽填满;未限定宽度时按内容布局。
onChange (value: string) => void — 用户激活不同的可用选项后调用,参数为新 value;与绑定值同步,不可取消选择。重复激活当前项不触发。
enableDefaultMotion boolean true 传递给宿主的默认动效开关;关闭默认 Frame 动效,不改变选择值、键盘或表单语义。
items TabItem[] [] 默认内置选项。每项必填唯一 value 与可读 label,可选 icon 组件与 disabled;禁用项不可选择。提供 children 时改用显式内容,不渲染 items。
其余兼容 Props ComponentProps<typeof Tab> 同 Tab 直接传递给 Tab 宿主;role、itemRole、selectionFollowsFocus 由 Segmented 固定,不可作为普通 Tab 参数改写。

2.2 子项约定

同 Tab.md §2.2:子项必须是 <Button as="item" value="...">。


Form 接入

<Form onSubmit={data => console.log(data)}>  <Segmented name="device" value="web">    <Button as="item" value="web">Web</Button>    <Button as="item" value="mobile">Mobile</Button>  </Segmented></Form> 

实现:当传入 name 时,Segmented 在 Tab 根节点之后追加 <input type="hidden" name={name} value={value}>,通过原生表单提交机制把当前 value 暴露给 Form。


动效

完全继承 Tab。详见 Tab.md §4。


键盘行为

  • ← / →(row)或 ↑ / ↓(column):直接切换并激活(Tab 的 selectionFollowsFocus=true 模式)。

  • Home / End:跳到首/末项并激活。

  • 焦点行为与 Tab 一致(roving tabindex)。


使用示例

<script lang="ts">  import { Button, Icon } from '@snowui-design-system/components';  import { Segmented } from '@snowui-design-system/components';  import { FourLeafClover, Star } from '@snowui-design-system/resource-svelte';  let value = $state('web');</script> <Segmented bind:value variant="pill" size="md">  <Button as="item" value="web"><Icon><FourLeafClover /></Icon>Web</Button>  <Button as="item" value="mobile"><Icon><Star /></Icon>Mobile</Button></Segmented>  <Segmented fill style="width: calc(var(--size-20) * 4)" value="web">  <Button as="item" value="web">Web</Button>  <Button as="item" value="mobile">Mobile</Button></Segmented>  <Segmented variant="bare" value="all">  <Button as="item" value="all">All</Button>  <Button as="item" value="random" iconOnly aria-label="收藏"><Icon><Star /></Icon></Button></Segmented>  <form>  <Segmented name="device" value="web" variant="solid">    <Button as="item" value="web">Web</Button>    <Button as="item" value="mobile">Mobile</Button>  </Segmented></form>

Segmented 样式覆盖

先阅读 完整 LICENSE;同任务、同版本、同范围去重。

优先用组件公开 Props 匹配合适样式,尽可能保留原有视觉。确需改写时按 样式选择与改写顺序 使用自己的 class(含项目已有 Tailwind)或实例 style。以下名称来自源码实际消费的公开 override;先核对目标作用域,不修改私有 DOM。采用 SnowUI Token 时选择正确类别,外部应用不被要求安装一方 utilities。

本组件源文件没有直接消费已登记的专属 override。组合子组件的样式通过公开 parts 或显式 child 配置;不要凭名称猜测变量。

设计指南 · Token · 组合边界

Segmented 类型与状态

必填属性:无具名必填属性。

可双向绑定:bind:value。

继承声明:Omit<TabProps, ControlledTabKeys>。继承能力以基类公开文档为准;Omit 中的字段已排除,不能按基类原样使用。

共享 Frame API · 返回 API

以下为公开属性实际引用的类型声明,来自源码;Svelte Snippet 表示内容片段,ComponentProps 表示对应组件的 Props。

ComponentPartsOf

来源:components/src/logic/component-parts.svelte.ts

export type ComponentPartsOf<    T extends Record<string, Component<any>>,> = {    [K in keyof T]?: ConfigurableComponentPartProps<T[K]>;};

ConfigurableComponentPartProps

来源:components/src/logic/component-parts.svelte.ts

export type ConfigurableComponentPartProps<C extends Component<any>> = Partial<    Omit<ComponentProps<C>, ComponentPartControlledKey>>;

ComponentPartControlledKey

来源:components/src/logic/component-parts.svelte.ts

export type ComponentPartControlledKey =    | "children"    | "as"    | "value"    | "defaultValue"    | "open"    | "selected"    | "checked"    | "disabled"    | "readonly"    | "id"    | `on${string}`    | `aria-${string}`;

TabProps

来源:components/src/components/Segmented.svelte

type TabProps = ComponentProps<typeof Tab>;

ControlledTabKeys

来源:components/src/components/Segmented.svelte

type ControlledTabKeys =        | "value"        | "children"        | "role"        | "itemRole"        | "selectionFollowsFocus"        | "class"        | "parts";