Skip to content
CodeAtlas UI

Inputs

RadioGroup

Single-selection radio group as a list of rows or a grid of selectable cards.

<script>
  import { RadioGroup } from "@codeatlasdev/ui";
  let plan = $state("pro");
</script>

<RadioGroup items={[{ value: "free", label: "Free" }, { value: "pro", label: "Pro" }]} bind:value={plan} />

The options are native radio inputs that share one name, so arrow keys move focus and selection inside the group and Tab leaves it. The group has no visible title of its own: pass aria-label, or wrap it in a fieldset with a legend when the choice needs a visible heading.

Vertical

The default layout.

Selected: apple

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

  let fruit = $state('apple');

  const fruits = [
    { value: 'apple', label: 'Apple' },
    { value: 'banana', label: 'Banana' },
    { value: 'cherry', label: 'Cherry' },
  ];
</script>

<RadioGroup items={fruits} bind:value={fruit} />
<p class="out">Selected: <code>{fruit}</code></p>

<style>
  .out {
    flex-basis: 100%;
    margin: 0;
    font-size: var(--ca-font-size-caption);
    color: var(--ca-text-secondary);
  }
</style>

Horizontal

orientation="horizontal" lays the options out in a row.

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

  let size = $state('md');

  const sizes = [
    { value: 'sm', label: 'Small' },
    { value: 'md', label: 'Medium' },
    { value: 'lg', label: 'Large' },
  ];
</script>

<RadioGroup items={sizes} bind:value={size} orientation="horizontal" />

Cards

variant="cards" renders each option as a selectable card with an optional description.

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

  let plan = $state('pro');

  const plans = [
    { value: 'free', label: 'Free', description: 'For side projects.' },
    { value: 'pro', label: 'Pro', description: 'For teams that ship weekly.' },
    { value: 'team', label: 'Team', description: 'Shared billing and audit log.', disabled: true },
  ];
</script>

<RadioGroup variant="cards" aria-label="Plan" items={plans} bind:value={plan} />

Disabled

Disable a single item, or the whole group.

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

  let answer = $state('yes');

  const yesNo = [
    { value: 'yes', label: 'Yes' },
    { value: 'no', label: 'No' },
    { value: 'maybe', label: 'Maybe', disabled: true },
  ];

  const fruits = [
    { value: 'apple', label: 'Apple' },
    { value: 'banana', label: 'Banana' },
    { value: 'cherry', label: 'Cherry' },
  ];
</script>

<RadioGroup items={yesNo} bind:value={answer} orientation="horizontal" />
<RadioGroup items={fruits} value="banana" disabled />

Props

PropTypeDefaultDescription
valuestring''Bindable selected value.
itemsRadioItem[]–Options: { value, label, description?, disabled? }. description is shown in the cards variant.
variant'list' | 'cards''list'list renders radio and label rows. cards renders each option as a card in a responsive grid, and the whole card is the hit area.
orientation'vertical' | 'horizontal''vertical'Layout direction and arrow-key axis.
disabledbooleanfalseDisables the entire group.
aria-labelstring–Accessible name of the group.
classstring–Extra classes on the group.
onchange(value: string) => void–Called when the selection changes.