Skip to content
CodeAtlas UI

Inputs

SegmentedControl

Single-choice control with a sliding thumb. It always has a selection and honors prefers-reduced-motion.

<script>
  import { SegmentedControl } from "@codeatlasdev/ui";
  let period = $state("month");
</script>

<SegmentedControl
  aria-label="Period"
  bind:value={period}
  items={[{ value: "week", label: "Week" }, { value: "month", label: "Month" }]}
/>

Unlike ToggleGroup, exactly one item is always selected: when value is unset it starts on the first enabled item. Give the control an aria-label since it has no visible heading, and an aria-label on every icon-only item. Arrow keys move between items.

Default

Text items, and text items with icons.

value: month

Code
svelte
<script lang="ts">
  import { SegmentedControl } from '@codeatlasdev/ui';
  import { LayoutGrid, LayoutList } from '@lucide/svelte';

  let period = $state('month');
  let view = $state('list');
</script>

<div class="col">
  <div>
    <SegmentedControl
      aria-label="Period"
      bind:value={period}
      items={[
        { value: 'week', label: 'Week' },
        { value: 'month', label: 'Month' },
        { value: 'year', label: 'Year' },
      ]}
    />
    <p class="out">value: {period}</p>
  </div>
  <SegmentedControl
    aria-label="View"
    bind:value={view}
    items={[
      { value: 'list', label: 'List', icon: LayoutList },
      { value: 'grid', label: 'Grid', icon: LayoutGrid },
    ]}
  />
</div>

<style>
  .col {
    display: flex;
    flex-direction: column;
    gap: var(--ca-space-5);
  }

  .out {
    margin: var(--ca-space-3) 0 0;
    font-size: var(--ca-font-size-caption);
    color: var(--ca-text-secondary);
  }
</style>

Small, full width, disabled item

Code
svelte
<script lang="ts">
  import { SegmentedControl } from '@codeatlasdev/ui';

  let size = $state('b');
</script>

<div class="wide">
  <SegmentedControl
    size="sm"
    fullWidth
    aria-label="Size"
    bind:value={size}
    items={[
      { value: 'a', label: 'Alpha' },
      { value: 'b', label: 'Beta' },
      { value: 'c', label: 'Gamma', disabled: true },
      { value: 'd', label: 'Delta' },
    ]}
  />
</div>

<style>
  .wide {
    width: 100%;
    max-width: 420px;
  }
</style>

Props

PropTypeDefaultDescription
valuestringfirst enabled itemBindable selected value.
itemsToggleGroupItem[]–{ value, label?, icon?, disabled?, 'aria-label'? }.
size'sm' | 'md''md'Item height.
fullWidthbooleanfalseStretches the control to the container width.
disabledbooleanfalseDisables the whole control.
aria-labelstring–Accessible name of the control.
classstring–Extra classes on the root.
onchange(value: string) => void–Called when the selection changes.