Hesoyam

Switch

Segmented control for two or three mutually exclusive views of the same surface. Not a boolean on/off.

Switch + SwitchControl is a radio group in a pill. On/off settings use Toggle. Classic circles use Radio.

Default

Give the group a name so the radios stay exclusive. Mark one control defaultChecked (or bind v-model).


        
1 <Switch name="view">
2 <SwitchControl default-checked label="Source" value="source" />
3 <SwitchControl label="Output" value="output" />
4 </Switch>

Sizes

small is 24px, default is 32px, large is 40px. Size on Switch flows to every control.


        
1 <Switch name="sizes-small" size="small">
2 <SwitchControl default-checked label="Source" value="source" />
3 <SwitchControl label="Output" value="output" />
4 </Switch>
5 <Switch name="sizes-default">
6 <SwitchControl default-checked label="Source" value="source" />
7 <SwitchControl label="Output" value="output" />
8 </Switch>
9 <Switch name="sizes-large" size="large">
10 <SwitchControl default-checked label="Source" value="source" />
11 <SwitchControl label="Output" value="output" />
12 </Switch>

Full width

Switch is inline-flex. Stretch it with class w-full so each control shares the row.


        
1 <Switch name="full-width" class="w-full">
2 <SwitchControl default-checked label="Source" value="source" />
3 <SwitchControl label="Output" value="output" />
4 </Switch>

Disabled

disabled on Switch locks the group. On a single SwitchControl it greys out one option.


        
1 <Switch name="view-disabled" disabled>
2 <SwitchControl default-checked label="Source" value="source" />
3 <SwitchControl label="Output" value="output" />
4 </Switch>

Icon

Pass a label even when the icon carries the meaning. The label is sr-only on icon-only controls.


        
1 <Switch name="layout" size="small">
2 <SwitchControl default-checked label="Grid" value="grid">
3 <template #icon>
4 <Icon :icon="GridViewIcon" :size="14" />
5 </template>
6 </SwitchControl>
7 <SwitchControl label="List" value="list">
8 <template #icon>
9 <Icon :icon="ListViewIcon" :size="14" />
10 </template>
11 </SwitchControl>
12 </Switch>

Tooltip

Icon-only switches need a Tooltip so sighted users get the same name as the sr-only label.


        
1 <Switch name="layout-tip" size="large">
2 <Tooltip text="Grid" class="flex-1">
3 <SwitchControl default-checked label="Grid" value="grid">
4 <template #icon>
5 <Icon :icon="GridViewIcon" :size="16" />
6 </template>
7 </SwitchControl>
8 </Tooltip>
9 <Tooltip text="List" class="flex-1">
10 <SwitchControl label="List" value="list">
11 <template #icon>
12 <Icon :icon="ListViewIcon" :size="16" />
13 </template>
14 </SwitchControl>
15 </Tooltip>
16 </Switch>

Controlled

v-model (or value) on Switch. Prefer that over checked on each control.

Selected: source


        
1 <Switch v-model="view" name="view-controlled">
2 <SwitchControl label="Source" value="source" />
3 <SwitchControl label="Output" value="output" />
4 </Switch>

Best practices

  • Two or three peers that change the view of one surface: Source / Output, Grid / List.
  • Boolean on/off is Toggle. More than three options, or labels longer than two words, become Tabs or Select.
  • Always set nameon the group so the radios share a name. Without it, more than one pill can look selected.
  • Initialize with default-checkedon exactly one control, or bind v-model.
  • Title Case, one or two words, parallel grammar. Source / Output, not Source / Show output.
  • Size the controls so the widest label fits. A jumping pill on selection is a layout bug.
  • Icon-only controls still take label. Pair them with a Tooltip.