Forms

Radio

Choose exactly one option from a small set, grouped under a shared legend.

Plan
Copy
<script setup lang="ts">
const plan = ref('pro')
</script>

<template>
  <JRadioGroup v-model="plan" label="Plan">
    <JRadio value="free" label="Free" />
    <JRadio value="pro" label="Pro" />
    <JRadio value="team" label="Team" />
  </JRadioGroup>
</template>

Installation #

With the Nuxt module, every component is auto-imported — there is nothing to add. In a plain Vue project, import what you use:

Copy
import { JRadioGroup, JRadio } from '@juxtui/ui'

Usage #

Copy
<JRadioGroup v-model="plan" label="Plan">
  <JRadio value="free" label="Free" />
  <JRadio value="pro" label="Pro" />
  <JRadio value="team" label="Team" />
</JRadioGroup>

Radios only ever work inside a JRadioGroup — it owns the shared name, the selected value and the fieldset semantics. A lone JRadio has nothing to inject into.

Arrow-key movement between radios, and the fact that only one can be checked, come from the browser: every JRadio renders a native <input type="radio"> sharing one name.

Variants & examples #

With descriptions#

Billing cycle

Applies at your next invoice.

Billed every month.
Two months free.
Copy
<script setup lang="ts">
const billing = ref('monthly')
</script>

<template>
  <JRadioGroup v-model="billing" label="Billing cycle" description="Applies at your next invoice.">
    <JRadio value="monthly" label="Monthly" description="Billed every month." />
    <JRadio value="yearly" label="Yearly" description="Two months free." />
  </JRadioGroup>
</template>

Horizontal#

Set orientation="horizontal" on the group.

Size
Copy
<script setup lang="ts">
const size = ref('md')
</script>

<template>
  <JRadioGroup v-model="size" label="Size" orientation="horizontal">
    <JRadio value="sm" label="Small" />
    <JRadio value="md" label="Medium" />
    <JRadio value="lg" label="Large" />
  </JRadioGroup>
</template>

Required, error and disabled options#

Role
Requires an invite.

Choose a role to continue.

Copy
<script setup lang="ts">
const role = ref(null)
</script>

<template>
  <JRadioGroup v-model="role" label="Role" required error="Choose a role to continue.">
    <JRadio value="viewer" label="Viewer" />
    <JRadio value="editor" label="Editor" />
    <JRadio value="admin" label="Admin" disabled description="Requires an invite." />
  </JRadioGroup>
</template>

API #

JRadioGroup

PropTypeDefault Description
modelValuestring | number | nullnullBound with v-model.
labelstring—Group label, rendered as the fieldset legend.
descriptionstring—Supporting text under the legend. Replaced by the error message while one is shown.
errorstring | boolean—An error message, or true to mark the group invalid without a message.
orientation'vertical' | 'horizontal''vertical'Layout of the radios.
disabledbooleanfalseDisables every radio in the group.
requiredbooleanfalseMarks the group as required, natively and visually.
namestring—Form field name shared by every radio. Generated when omitted.

Events

EventPayload Description
update:modelValuestring | numberEmitted when a radio is selected.

Slots

SlotProps Description
default—The JRadio items.
label—Custom legend content.

JRadio

PropTypeDefault Description
valuestring | number—This radio’s value. Required.
labelstring—Label text. The default slot overrides it.
descriptionstring—Supporting text under the label.
disabledbooleanfalseDisables this radio, on top of the group’s own disabled.

Slots

SlotProps Description
default—Custom label content.
description—Custom description content.

Accessibility #

  • The group is a native <fieldset> with a <legend>, and each option a native <input type="radio"> — assistive technology gets the “radio group” role and the “N of M” count for free.
  • Description and error are linked to the fieldset with aria-describedby; an error also sets aria-invalid and aria-required follows required.
  • A per-radio description is linked to that radio’s input with its own aria-describedby.
  • Disabling the group disables every input inside it, including from keyboard and form submission.

Keyboard #

Key Action
↓→Move to and select the next radio in the group, wrapping around.
↑←Move to and select the previous radio in the group, wrapping around.
SpaceSelect the focused radio.
TabMove focus into or out of the group. Enters on the checked radio, or the first if none is checked.