Skip to content

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.

#037

Vertical

The default layout.

Selected: apple

Reference #037 · Pick in the gallery

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>
#036

Horizontal

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

Reference #036 · Pick in the gallery

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" />
#034

Cards

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

Reference #034 · Pick in the gallery

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} />
#035

Disabled

Disable a single item, or the whole group.

Reference #035 · Pick in the gallery

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.
namestring–Native name of the radios, so the value is in FormData on a plain form submit (works without JS and with use:enhance). Unset: an internal id groups them and the value is not submitted by name.
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.