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
Circleda bibliotecalucide-reactpara 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.displayNameAqui, 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
classNamepermite 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 odisplayNamepara 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.displayNameEste 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-4e 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-noneefocus-visible:ring-2para 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 }