Pricing

Segmented handbook

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

License: Before reading component documentation, source, or npm usage instructions for the first time, read the full LICENSE. Reuse that review for the same task and version. Public API configuration and internal implementation changes have different license implications. All components use the unified runtime package; source rights remain governed by the license.

Overview

Show a small set of mutually exclusive choices side by side for quick changes to filters or parameters, with keyboard and form support.

When to use it

Use radiogroup semantics for choosing one parameter or filter. Use Tab when switching content panels or views.

  • Use bind:value and stable option values. If the value is absent or unmatched, the first available item appears selected, but the binding is not updated automatically; initialize form state explicitly.

  • For explicit items, use Button as="item". A nonempty name adds a hidden form field; the application restores the initial bound value on form reset.

Quick start

This example shows the recommended basic composition. See the sections below for more cases and composition limits.

<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

Keyword Type Default Description
value string — Current unique option value; supports bind:value. Clicking or activating with arrow keys updates it. If missing or unmatched, the first available item appears selected without writing back to the binding; initialize form state explicitly.
name string — A nonempty name adds a hidden input with that name so native FormData receives the current value. An undefined value submits as an empty string. Place it inside a form and restore the initial bound value on reset.
children Snippet — Explicit item content as a parameterless snippet. Use Button as="item" with a unique value. It takes precedence over items; configure each Button directly.
class string "" Merge an external class into the real Tab root while preserving Segmented identity; it does not hide the form input.
parts ComponentPartsOf<{ Button: typeof Button }> — Configure Buttons generated by items through parts.Button, such as scaleOnHover. Explicit child Buttons are configured individually; there is no parts.Tab.

See the base component documentation for inherited capabilities not redeclared here. This table lists only named public Props declared by this component.

Usage boundaries and details

Default built-in mode / explicit combination mode

  • Specialized Tab host: Segmented renders a real Tab and accepts compatible Tab Props at the root. There is no parts.Tab.

  • Default built-in mode (recommended): items lets Tab generate Buttons; parts.Button configures those generated items.

  • Explicit combination mode: explicitly write <Button as="item">, and directly configure Props item by item.


Relationship with Tab

Dimension Tab Segmented
Meaning Switch views or content panels Choose one filter or parameter
ARIA role tablist / child tab (hidden Button) radiogroup / sub-item radio
Arrow keys Move focus only (selectionFollowsFocus=false); Enter activates Move focus and activate (selectionFollowsFocus=true)
Form integration No Yes (name attribute + internal hidden input)
Appearance (variant, size, tokens) Exactly the same Exactly the same

Segmented specializes Tab: the real Tab owns the visible surface, interaction nodes, and root DOM. Segmented fixes radiogroup semantics, immediate arrow-key selection, and the hidden form input supplied by name.

Segmented inherits Tab’s composite hover rules. Items do not scale by default; they retain their color and indicator feedback. Enable scaling on a child Button or through parts.Button.scaleOnHover=true.

Host Props and ownership

  • Type source: ComponentProps<typeof Tab>.

  • Controlled fields: value, children, role, itemRole, selectionFollowsFocus, class, parts.

  • Tab retains its variant, size, layout, indicator, keyboard behavior, Frame Props, and DOM.

  • Segmented adds radiogroup/radio ARIA, immediate selection, a hidden input for name, and root-level class merging.

  • Hidden input is the non-visual auxiliary node after the Tab root; it does not copy the Tab surface.


2.1 Props

Keyword Type Default Description
variant 'pill' | 'solid' | 'underline' | 'icon-toggle' | 'bare' 'pill' pill has a sliding background, solid a solid selected state, underline an underline, icon-toggle expands only the selected item’s text, and bare uses transparency alone. An icon-toggle item needs both Icon and Text, or an icon and label in items.
size 'sm' | 'md' | 'lg' 'sm' Control the container padding, radius, gap, and use it as the default size of the Button sub-item; the sub-item priority is style > class > Button size > Segmented size.
row boolean false Horizontal by default. row takes precedence if both row and column are true.
column boolean false Vertical arrangement, the arrow keys are changed to up and down switching; it only takes effect when the row is not enabled.
fill boolean false When the container has a clear width, fill the horizontal sub-item with equal width; when the width is not specified, it is laid out according to the content.
onChange (value: string) => void — Called with the new value when another enabled option is activated; it stays synchronized with bind:value. The current choice cannot be deselected, and activating it again does not call the callback.
enableDefaultMotion boolean true The default dynamic effect switch passed to the host; turn off the default Frame dynamic effect without changing the selection value, keyboard or form semantics.
items TabItem[] [] Default built-in options. Each item must fill in the unique value and readable label, optional icon component and disabled; disabled items cannot be selected. When providing children, change to explicit content and do not render items.
Other compatible Props ComponentProps<typeof Tab> Same Tab Directly passed to the Tab host; role, itemRole, selectionFollowsFocus are fixed by Segmented and cannot be rewritten as ordinary Tab parameters.

2.2 Child item contract

As in Tab.md §2.2, each child item must be <Button as="item" value="...">.


Form access

<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> 

When name is set, Segmented appends <input type="hidden" name={name} value={value}> after the Tab root, exposing the current choice through native form submission.


Dynamic effect

Completely inherit Tab. See Tab.md §4 for details.


Keyboard behavior

  • ←/→ in a row or ↑/↓ in a column: move focus and activate immediately (selectionFollowsFocus=true).

  • Home/End: move to the first/last option and activate.

  • The focus behavior is consistent with Tab (roving tabindex).


Usage examples

<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="Favorite"><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 style overlay

Read the full LICENSE first; reuse that review for the same task, version, and scope.

First use public component Props to match the desired appearance, preserving the existing look where possible. If changes are necessary, follow the style selection and override order: use your own class (including Tailwind already in the project) or an instance style. The names below are public overrides actually consumed by source; check their scope and do not modify private DOM. Choose the correct SnowUI token family. External apps need not install SnowUI website utilities.

This component source does not directly consume a registered component-specific override. Style composed children through public parts or an explicit child; do not guess variable names.

Design Guide · Token · Combination boundary

Segmented Type and Status

Required Props: no named required Props.

Two-way binding: bind:value.

Inheritance statement: Omit<TabProps, ControlledTabKeys>. The inheritance ability is subject to the public document of the base class; the fields in Omit have been excluded and cannot be used as they are according to the base class.

Share Frame API · Return API

The following type declarations are actually referenced by public Props and come from source. A Svelte Snippet denotes a content fragment; ComponentProps denotes the Props of the corresponding component.

ComponentPartsOf

Source: components/src/logic/component-parts.svelte.ts

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

ConfigurableComponentPartProps

Source: components/src/logic/component-parts.svelte.ts

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

ComponentPartControlledKey

Source: 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

Source: components/src/components/Segmented.svelte

type TabProps = ComponentProps<typeof Tab>;

ControlledTabKeys

Source: components/src/components/Segmented.svelte

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