Radio
BetaElige una sola opción de un grupo corto, con todas las alternativas a la vista.
Abrir en Figma
registry/ds/radio.tsxModalidad
import { Radio, RadioGroup } from "@/registry/ds/radio";
export default function RadioBasic() {
return (
<RadioGroup label="Modalidad" defaultValue="presencial">
<Radio value="presencial" label="Presencial" />
<Radio value="virtual" label="Virtual" />
<Radio value="hibrida" label="Híbrida" />
</RadioGroup>
);
}Cuándo usarlo
Las opciones son mutuamente excluyentes y vale la pena que se vean todas para comparar.
| Usá Radio para… | Usá otra cosa para… |
|---|---|
| Elegir una entre 2 y 5 opciones. | Más de 5 opciones → Select. |
| Opciones que conviene comparar lado a lado. | Varias a la vez → Checkbox. |
| Una decisión que se confirma con un botón. | Sí/No con efecto inmediato → Switch. |
Reglas del grupo
- Siempre en grupo, con un título que diga qué se está eligiendo.
- Una opción preseleccionada siempre que exista un default razonable: la más segura o la más común. Un grupo sin selección no se puede "desmarcar".
- Si "ninguna" es válida, agregala como una opción más.
- Orden lógico: por frecuencia, por magnitud o alfabético. Nunca al azar.
Con texto de apoyo
Plan de pago
import { Radio, RadioGroup } from "@/registry/ds/radio";
export default function RadioSupporting() {
return (
<RadioGroup label="Plan de pago" defaultValue="mensual">
<Radio value="mensual" label="Mensual" supporting="10 cuotas sin interés." />
<Radio value="semestral" label="Semestral" supporting="5% de descuento sobre el total." />
<Radio value="anual" label="Anual" supporting="No disponible para tu programa." disabled />
</RadioGroup>
);
}Orientación
Vertical por defecto: se escanea mejor. Horizontal solo con 2–3 opciones de label corto.
Jornada
import { Radio, RadioGroup } from "@/registry/ds/radio";
export default function RadioHorizontal() {
return (
<RadioGroup label="Jornada" orientation="horizontal" defaultValue="manana">
<Radio value="manana" label="Mañana" />
<Radio value="tarde" label="Tarde" />
<Radio value="noche" label="Noche" />
</RadioGroup>
);
}Tamaños
import { Radio, RadioGroup } from "@/registry/ds/radio";
export default function RadioSizes() {
return (
<RadioGroup aria-label="Tamaños" orientation="horizontal" defaultValue="md">
<Radio size="sm" value="sm" label="Small" />
<Radio size="md" value="md" label="Medium" />
<Radio size="lg" value="lg" label="Large" />
</RadioGroup>
);
}Medidas
| Size | Círculo | Punto | Label | Apoyo |
|---|---|---|---|---|
sm | 16 | 6 | Text sm / Medium | Text sm / Regular |
md | 20 | 8 | Text md / Medium | Text sm / Regular |
lg | 24 | 10 | Text md / Medium | Text sm / Regular |
Gap control–texto: spacing-md (8). Entre opciones: spacing-xl (12).
Borde sin marcar border-sm (1); marcado border-md (1.5).
Tokens por estado
| Parte | Propiedad | Default | Hover | Pressed |
|---|---|---|---|---|
| Círculo sin marcar | Fondo | bg/elevated | bg/elevated | bg/elevated |
| Círculo sin marcar | Borde | border/default | border/strong | border/strong |
| Círculo marcado | Borde | primary/accent | primary/accent-hover | primary/accent-active |
| Punto | Fondo | primary/accent | primary/accent-hover | primary/accent-active |
| Parte | Propiedad | Token |
|---|---|---|
| Foco | Anillo 2 px | focus/ring |
| Deshabilitado | Fondo / borde | bg/subtle |
| Deshabilitado | Punto y textos | text/disabled |
En Figma
Radio (solo el círculo) y Radio item (círculo + textos). No existe Indeterminate: un radio está elegido o no.
| Propiedad en Figma | Valores | En código | Nota |
|---|---|---|---|
| Size | sm · md · lg | size | — |
| Checked | Unchecked · Checked | value (en RadioGroup) | El grupo decide cuál está marcado. |
| State | Default · Hover · Focus · Pressed · Disabled | disabled | — |
| Label · Supporting | Texto | label · supporting | — |
Instalación
npx shadcn@latest add https://polen.cdc.cool/r/radio.jsonPlayground
Configurá el componente y copiá el snippet: se genera del mismo estado que renderiza el preview.
Turno
Orientación
size
<RadioGroup label="Turno" defaultValue="manana">
<Radio value="manana" label="Mañana" />
<Radio value="tarde" label="Tarde" />
<Radio value="noche" label="Noche" />
</RadioGroup>Uso
<RadioGroup label="Modalidad" defaultValue="presencial" name="modalidad">
<Radio value="presencial" label="Presencial" />
<Radio value="virtual" label="Virtual" />
</RadioGroup>Props de RadioGroup
Sobre Base UI Radio Group.
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
label | ReactNode | — | Título visible del grupo. Si es texto, también nombra al grupo para lectores de pantalla. |
value | string | — | Opción elegida, controlada. |
defaultValue | string | — | Opción inicial. |
onValueChange | (value: string) => void | — | Se llama al elegir. |
orientation | "vertical" | "horizontal" | "vertical" | Disposición de las opciones. |
name | string | — | Nombre del campo en formularios. |
disabled | boolean | false | Deshabilita todo el grupo. |
Props de Radio
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
value | string | — | Valor de esta opción. Requerido. |
size | "sm" | "md" | "lg" | "md" | Círculo de 16 / 20 / 24 px. |
label | ReactNode | — | Texto de la opción. |
supporting | ReactNode | — | Línea de apoyo. |
disabled | boolean | false | Deshabilita solo esta opción. |
Teclado
| Tecla | Qué hace |
|---|---|
| Tab | Entra al grupo (a la opción elegida) o sale de él. El grupo es un solo stop. |
| ↓→ | Pasa a la siguiente opción y la elige. |
| ↑← | Pasa a la anterior y la elige. |
| Espacio | Elige la opción enfocada si ninguna lo estaba. |
Qué viene resuelto
role="radiogroup"+role="radio"conaria-checked.- Roving tabindex: un solo tab stop, flechas para moverse.
- Las opciones deshabilitadas se saltean.
Qué tenés que cuidar vos
- El grupo necesita nombre:
label, oaria-label/aria-labelledby. - No uses un radio suelto. Para una sola casilla, es un Checkbox.