Explicação detalhada 📝
Este código define componentes para criar um grupo de botões de rádio customizados utilizando o React, com o auxílio da biblioteca @radix-ui/react-radio-group
e o ícone Circle
da lucide-react
. Vamos entender cada parte do código.
Importações 🔧
import * as React from "react"
import * as RadioGroupPrimitive from "@radix-ui/react-radio-group"
import { Circle } from "lucide-react"
import { cn } from "@/lib/utils"
- React: Importação do React para criar componentes funcionais.
- @radix-ui/react-radio-group: Biblioteca para criar grupos de botões de rádio acessíveis e personalizáveis.
- Circle: Importação do ícone
Circle
da bibliotecalucide-react
para o indicador visual do botão de rádio selecionado. - cn: Função utilitária para combinar ou condicionar classes CSS.
Componente RadioGroup
🔘
const RadioGroup = React.forwardRef(({ className, ...props }, ref) => {
return (
<RadioGroupPrimitive.Root className={cn("grid gap-2", className)} {...props} ref={ref} />
);
})
RadioGroup.displayName = RadioGroupPrimitive.Root.displayName
Aqui, definimos o componente RadioGroup
, que é uma simples extensão do RadioGroupPrimitive.Root
da Radix. Esse componente envolve os itens de botão de rádio e é responsável por agrupá-los visualmente.
- className: A propriedade
className
permite passar classes CSS personalizadas para o grupo de botões de rádio. - ref: A referência é passada para o
RadioGroupPrimitive.Root
, permitindo que o componente seja referenciado por um componente pai, se necessário. displayName
: Definimos odisplayName
para facilitar a depuração e visualização do componente nos DevTools.
Componente RadioGroupItem
⚪
const RadioGroupItem = React.forwardRef(({ className, ...props }, ref) => {
return (
<RadioGroupPrimitive.Item
ref={ref}
className={cn(
"aspect-square h-4 w-4 rounded-full border border-primary text-primary ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className
)}
{...props}>
<RadioGroupPrimitive.Indicator className="flex items-center justify-center">
<Circle className="h-2.5 w-2.5 fill-current text-current" />
</RadioGroupPrimitive.Indicator>
</RadioGroupPrimitive.Item>
);
})
RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName
Este componente representa um único item dentro do grupo de botões de rádio. Ele é um item clicável, que permite selecionar uma opção dentro do grupo.
className
: Similar aoRadioGroup
, ele permite adicionar classes CSS personalizadas ao botão de rádio.- Estilos: O botão de rádio tem um formato circular, utilizando a classe
aspect-square h-4 w-4
e borda arredondada. RadioGroupPrimitive.Indicator
: Dentro do item, temos um indicador visual, que é um pequeno círculo (<Circle />
) que representa o botão de rádio selecionado.- Classes CSS:
- focus: O efeito de foco é aplicado com
focus:outline-none
efocus-visible:ring-2
para melhorar a acessibilidade. - disabled: Estilos são aplicados quando o item está desabilitado, como
disabled:cursor-not-allowed
.
- focus: O efeito de foco é aplicado com
Exportação do componente 🚀
export { RadioGroup, RadioGroupItem }
Finalmente, ambos os componentes RadioGroup
e RadioGroupItem
são exportados para serem utilizados em outros lugares do aplicativo.
Código completo 👇
import * as React from "react"
import * as RadioGroupPrimitive from "@radix-ui/react-radio-group"
import { Circle } from "lucide-react"
import { cn } from "@/lib/utils"
const RadioGroup = React.forwardRef(({ className, ...props }, ref) => {
return (
<RadioGroupPrimitive.Root className={cn("grid gap-2", className)} {...props} ref={ref} />
);
})
RadioGroup.displayName = RadioGroupPrimitive.Root.displayName
const RadioGroupItem = React.forwardRef(({ className, ...props }, ref) => {
return (
<RadioGroupPrimitive.Item
ref={ref}
className={cn(
"aspect-square h-4 w-4 rounded-full border border-primary text-primary ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className
)}
{...props}>
<RadioGroupPrimitive.Indicator className="flex items-center justify-center">
<Circle className="h-2.5 w-2.5 fill-current text-current" />
</RadioGroupPrimitive.Indicator>
</RadioGroupPrimitive.Item>
);
})
RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName
export { RadioGroup, RadioGroupItem }