Radio Group
Lista de opções sempre visíveis em que o usuário escolhe exatamente uma.
Forma de contato preferida
'use client';
import { Radio, RadioGroup } from '@/components/ui/radio-group';
export default function RadioGroupDemo() {
return (
<RadioGroup name="contato" label="Forma de contato preferida" defaultValue="whatsapp">
<Radio value="whatsapp">WhatsApp</Radio>
<Radio value="email">E-mail</Radio>
<Radio value="telefone">Ligação</Radio>
</RadioGroup>
);
}Instalação
npx shadcn@latest add @lenstech/radio-groupUso
import { Radio, RadioGroup } from "@/components/ui/radio-group"<RadioGroup name="contato" label="Forma de contato" defaultValue="whatsapp">
<Radio value="whatsapp">WhatsApp</Radio>
<Radio value="email">E-mail</Radio>
</RadioGroup>O valor fica no grupo
O RadioGroup guarda a escolha: use defaultValue ou value + onChange no grupo (e não em cada Radio).
onChange recebe a string do value escolhido. As setas do teclado movem a seleção entre as opções.
Exemplos
Horizontal
Período da consulta
'use client';
import { Radio, RadioGroup } from '@/components/ui/radio-group';
export default function RadioGroupHorizontal() {
return (
<RadioGroup name="periodo" label="Período da consulta" orientation="horizontal" defaultValue="manha">
<Radio value="manha">Manhã</Radio>
<Radio value="tarde">Tarde</Radio>
<Radio value="noite">Noite</Radio>
</RadioGroup>
);
}Com descrição e opção desabilitada
Entrega
Pronto em 30 minutos no balcão.
Até 5 km, em cerca de 1 hora.
De 3 a 7 dias úteis.
'use client';
import { Radio, RadioGroup } from '@/components/ui/radio-group';
export default function RadioGroupDescription() {
return (
<RadioGroup name="entrega" label="Entrega" defaultValue="retirada">
<Radio value="retirada" description="Pronto em 30 minutos no balcão.">
Retirar na loja
</Radio>
<Radio value="motoboy" description="Até 5 km, em cerca de 1 hora.">
Motoboy
</Radio>
<Radio value="correios" description="De 3 a 7 dias úteis." isDisabled>
Correios (indisponível)
</Radio>
</RadioGroup>
);
}Cartões
variant="card" transforma cada opção em um cartão clicável. Use addon para preço ou destaque à direita.
Plano de hospedagemTodos incluem SSL e backup diário.
Site de até 5 páginas e 1 e-mail.
Blog, 10 e-mails e relatório de acessos.
Loja virtual com até 500 produtos.
'use client';
import { Radio, RadioGroup } from '@/components/ui/radio-group';
export default function RadioGroupCard() {
return (
<RadioGroup
name="plano"
label="Plano de hospedagem"
description="Todos incluem SSL e backup diário."
variant="card"
orientation="horizontal"
defaultValue="profissional"
className="w-full max-w-3xl"
>
<Radio value="essencial" addon="R$ 49/mês" description="Site de até 5 páginas e 1 e-mail.">
Essencial
</Radio>
<Radio value="profissional" addon="R$ 99/mês" description="Blog, 10 e-mails e relatório de acessos.">
Profissional
</Radio>
<Radio value="loja" addon="R$ 199/mês" description="Loja virtual com até 500 produtos.">
Loja
</Radio>
</RadioGroup>
);
}Obrigatório
Tente finalizar sem escolher uma opção.
'use client';
import { Button } from '@/components/ui/button';
import { Form } from '@/components/ui/form';
import { Radio, RadioGroup } from '@/components/ui/radio-group';
export default function RadioGroupInvalid() {
return (
<Form onSubmit={(e) => e.preventDefault()}>
<RadioGroup
name="pagamento"
label="Forma de pagamento"
isRequired
errorMessage="Escolha uma forma de pagamento."
>
<Radio value="pix">Pix</Radio>
<Radio value="cartao">Cartão de crédito</Radio>
<Radio value="boleto">Boleto</Radio>
</RadioGroup>
<Button type="submit" className="self-start">
Finalizar pedido
</Button>
</Form>
);
}Controlado
Cobrança
Valor: R$ 99/mês
'use client';
import { useState } from 'react';
import { Radio, RadioGroup } from '@/components/ui/radio-group';
const precos: Record<string, string> = { mensal: 'R$ 99/mês', anual: 'R$ 990/ano (2 meses grátis)' };
export default function RadioGroupControlled() {
const [ciclo, setCiclo] = useState('mensal');
return (
<div className="flex flex-col gap-4">
<RadioGroup label="Cobrança" orientation="horizontal" value={ciclo} onChange={setCiclo}>
<Radio value="mensal">Mensal</Radio>
<Radio value="anual">Anual</Radio>
</RadioGroup>
<p className="text-sm text-muted-foreground">
Valor: <span className="font-medium text-foreground">{precos[ciclo]}</span>
</p>
</div>
);
}Quando usar
- Use para 2 a 6 opções mutuamente exclusivas que o usuário deve comparar (planos, entrega, pagamento).
- Não use com muitas opções — use
SelectouCombobox. - Não use para escolher várias opções — use
Checkbox(CheckboxGroup). - Para ligar/desligar uma única configuração, use
Switch.
API
RadioGroup
Aceita todas as props do RadioGroup do React Aria, mais:
Prop
Type
Radio
Aceita todas as props do Radio do React Aria, mais:
Prop
Type
Composição
RadioField, RadioButton e RadioIndicator são as peças usadas pelo Radio, para layouts próprios.