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.

FieldTypeDefault
valuestring-
labelstring-
iconstring-
leadingIconstring-
trailingIconstring-
ariaLabelstring-
disabledbooleanfalse

UI Slots

Use the ui prop to override classes.

SlotDescription
baseThe group container
itemEach toggle item

Props

PropTypeDefault
type'single' | 'multiple''single'
valuestring | string[]-
onValueChange(value) => void-
itemsToggleGroupItem[][]
variant'outline' | 'soft' | 'subtle' | 'ghost''ghost'
colorColorType'primary'
size'xs' | 'sm' | 'md' | 'lg' | 'xl''md'
orientation'horizontal' | 'vertical''horizontal'
attachedbooleanfalse
blockbooleanfalse
squarebooleanfalse
disabledbooleanfalse
loopbooleantrue
rovingFocusbooleantrue
itemSlotSnippet<[{ item }]>-
refHTMLElement | nullnull
classstring-
uiRecord<Slot, Class>-