Forms
ToggleGroup
A set of related toggles with roving-focus keyboard navigation. Use type to switch between single and multiple selection.
Playground
Experiment with different props in real-time.
Basic Usage
Single selection: value is a string.
<script lang="ts">
import { ToggleGroup } from 'sv5ui';
let alignment = $state('left');
const items = [
{ value: 'left', icon: 'lucide:align-left', ariaLabel: 'Align left' },
{ value: 'center', icon: 'lucide:align-center', ariaLabel: 'Align center' },
{ value: 'right', icon: 'lucide:align-right', ariaLabel: 'Align right' }
];
</script>
<ToggleGroup {items} bind:value={alignment} />Multiple Selection
With type="multiple" the value is a string[].
Active: bold
<script lang="ts">
import { ToggleGroup } from 'sv5ui';
// With type="multiple" the value is a string[]
let formats = $state(['bold']);
const items = [
{ value: 'bold', icon: 'lucide:bold', ariaLabel: 'Bold' },
{ value: 'italic', icon: 'lucide:italic', ariaLabel: 'Italic' },
{ value: 'underline', icon: 'lucide:underline', ariaLabel: 'Underline' }
];
</script>
<ToggleGroup type="multiple" {items} bind:value={formats} />
<p>Active: {formats.join(', ') || 'none'}</p>With Labels
<ToggleGroup
value="weekly"
items={[
{ value: 'daily', label: 'Daily' },
{ value: 'weekly', label: 'Weekly' },
{ value: 'monthly', label: 'Monthly' }
]}
/>Attached (Segmented Control)
Set attached for a flush, segmented look.
<!-- Segmented-control look -->
<ToggleGroup
attached
value="grid"
items={[
{ value: 'list', leadingIcon: 'lucide:list', label: 'List' },
{ value: 'grid', leadingIcon: 'lucide:grid-3x3', label: 'Grid' }
]}
/>Variants
<ToggleGroup variant="ghost" value="a" items={items} />
<ToggleGroup variant="outline" value="a" items={items} />
<ToggleGroup variant="soft" value="a" items={items} />
<ToggleGroup variant="subtle" value="a" items={items} />Colors
<ToggleGroup color="primary" value="a" attached items={items} />
<ToggleGroup color="success" value="a" attached items={items} />
<ToggleGroup color="error" value="a" attached items={items} />Sizes
<ToggleGroup size="xs" value="a" attached items={items} />
<ToggleGroup size="md" value="a" attached items={items} />
<ToggleGroup size="xl" value="a" attached items={items} />Block
Stretch to fill the container with equal-width items.
<ToggleGroup
block
attached
value="grid"
items={[
{ value: 'list', label: 'List' },
{ value: 'grid', label: 'Grid' },
{ value: 'board', label: 'Board' }
]}
/>Vertical
<ToggleGroup
orientation="vertical"
attached
value="center"
items={[
{ value: 'start', icon: 'lucide:align-start-vertical', ariaLabel: 'Start' },
{ value: 'center', icon: 'lucide:align-center-vertical', ariaLabel: 'Center' },
{ value: 'end', icon: 'lucide:align-end-vertical', ariaLabel: 'End' }
]}
/>ToggleGroupItem
Shape of each entry in the items array.
| Field | Type | Default |
|---|---|---|
value | string | - |
label | string | - |
icon | string | - |
leadingIcon | string | - |
trailingIcon | string | - |
ariaLabel | string | - |
disabled | boolean | false |
UI Slots
Use the ui prop to override classes.
| Slot | Description |
|---|---|
base | The group container |
item | Each toggle item |
Props
| Prop | Type | Default |
|---|---|---|
type | 'single' | 'multiple' | 'single' |
value | string | string[] | - |
onValueChange | (value) => void | - |
items | ToggleGroupItem[] | [] |
variant | 'outline' | 'soft' | 'subtle' | 'ghost' | 'ghost' |
color | ColorType | 'primary' |
size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'md' |
orientation | 'horizontal' | 'vertical' | 'horizontal' |
attached | boolean | false |
block | boolean | false |
square | boolean | false |
disabled | boolean | false |
loop | boolean | true |
rovingFocus | boolean | true |
itemSlot | Snippet<[{ item }]> | - |
ref | HTMLElement | null | null |
class | string | - |
ui | Record<Slot, Class> | - |