Saltar al contenido principal

Radio

Selecciones exclusivas. Estado visual claro. Prevenir errores.

1import { Radio } from '@/components/ui/radio';
2
3const cycles = [
4 {
5 value: 'monthly',
6 title: 'Monthly',
7 detail: '$29 per user, cancel any time',
8 defaultChecked: false,
9 },
10 {
11 value: 'yearly',
12 title: 'Yearly',
13 detail: '$24 per user, two months free',
14 defaultChecked: true,
15 },
16];
17
18export function Default() {
19 return (
20 <div className="flex w-full max-w-sm flex-col gap-2">
21 {cycles.map((cycle) => (
22 <label
23 key={cycle.value}
24 className="border-border bg-card flex cursor-pointer items-center gap-3 rounded-lg border p-3"
25 >
26 <Radio name="billing-cycle" value={cycle.value} defaultChecked={cycle.defaultChecked} />
27 <span className="flex flex-col gap-0.5">
28 <span className="text-sm font-medium">{cycle.title}</span>
29 <span className="text-muted-foreground text-xs">{cycle.detail}</span>
30 </span>
31 </label>
32 ))}
33 </div>
34 );
35}

Instalación

pnpm dlx nachui add radio

Anatomía

1import { Radio } from '@/components/ui/radio';
1<Radio id="option-one" name="radio-group" />

Variantes

Predeterminado (Default)

1import { Radio } from '@/components/ui/radio';
2
3const cycles = [
4 {
5 value: 'monthly',
6 title: 'Monthly',
7 detail: '$29 per user, cancel any time',
8 defaultChecked: false,
9 },
10 {
11 value: 'yearly',
12 title: 'Yearly',
13 detail: '$24 per user, two months free',
14 defaultChecked: true,
15 },
16];
17
18export function Default() {
19 return (
20 <div className="flex w-full max-w-sm flex-col gap-2">
21 {cycles.map((cycle) => (
22 <label
23 key={cycle.value}
24 className="border-border bg-card flex cursor-pointer items-center gap-3 rounded-lg border p-3"
25 >
26 <Radio name="billing-cycle" value={cycle.value} defaultChecked={cycle.defaultChecked} />
27 <span className="flex flex-col gap-0.5">
28 <span className="text-sm font-medium">{cycle.title}</span>
29 <span className="text-muted-foreground text-xs">{cycle.detail}</span>
30 </span>
31 </label>
32 ))}
33 </div>
34 );
35}

Con Etiqueta (With Label)

Acompañado de una etiqueta (Label) para proveer contexto extra. El atributo name se usa para agrupar las opciones de radio.

Send activity email

One email per event.
Everything from the last 24 hours, at 8:00.
Monday mornings only.
1import { Label } from '@/components/ui/label';
2import { Radio } from '@/components/ui/radio';
3
4const frequencies = [
5 {
6 id: 'digest-realtime',
7 label: 'Right away',
8 hint: 'One email per event.',
9 defaultChecked: false,
10 },
11 {
12 id: 'digest-daily',
13 label: 'Daily digest',
14 hint: 'Everything from the last 24 hours, at 8:00.',
15 defaultChecked: true,
16 },
17 {
18 id: 'digest-weekly',
19 label: 'Weekly summary',
20 hint: 'Monday mornings only.',
21 defaultChecked: false,
22 },
23];
24
25export function WithLabel() {
26 return (
27 <div className="flex w-full max-w-md flex-col gap-4">
28 <p className="text-sm font-medium">Send activity email</p>
29 {frequencies.map((frequency) => (
30 <div key={frequency.id} className="flex items-start gap-2.5">
31 <Radio
32 id={frequency.id}
33 name="digest-frequency"
34 defaultChecked={frequency.defaultChecked}
35 className="mt-0.5"
36 />
37 <div className="flex flex-col gap-1">
38 <Label htmlFor={frequency.id}>{frequency.label}</Label>
39 <span className="text-muted-foreground text-xs">{frequency.hint}</span>
40 </div>
41 </div>
42 ))}
43 </div>
44 );
45}

Deshabilitado (Disabled)

Estado en el que el usuario no puede interactuar con él.

Data region

Current region, set when the workspace was created.
Moving regions requires a support request.
1import { Label } from '@/components/ui/label';
2import { Radio } from '@/components/ui/radio';
3
4const regions = [
5 {
6 id: 'region-us',
7 label: 'US East, Virginia',
8 hint: 'Current region, set when the workspace was created.',
9 defaultChecked: true,
10 },
11 {
12 id: 'region-eu',
13 label: 'Europe, Frankfurt',
14 hint: 'Moving regions requires a support request.',
15 defaultChecked: false,
16 },
17];
18
19export function Disabled() {
20 return (
21 <div className="flex w-full max-w-md flex-col gap-4">
22 <p className="text-sm font-medium">Data region</p>
23 {regions.map((region) => (
24 <div key={region.id} className="flex items-start gap-2.5">
25 <Radio
26 id={region.id}
27 name="data-region"
28 defaultChecked={region.defaultChecked}
29 className="mt-0.5"
30 disabled
31 />
32 <div className="flex flex-col gap-1">
33 <Label htmlFor={region.id} className="opacity-50">
34 {region.label}
35 </Label>
36 <span className="text-muted-foreground text-xs">{region.hint}</span>
37 </div>
38 </div>
39 ))}
40 </div>
41 );
42}

Referencia de API

Radio

PropTipoPor defectoDescripción
onCheckedChange(checked: boolean) => void-Handler cuando el estado cambia
disabledboolean-Evita interacción y reduce opacidad
namestring-Nombre del grupo de opciones
¿Encontraste algo que mejorar?

¿Notaste un error, tipografía o detalle faltante en esta página? Ayúdanos a mejorar la documentación abriendo un issue en GitHub.

Crear un Issue
Ctrl+I