Desenvolvedores
src_
components_
ui_
RadioGroup.jsx

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"
  1. React: Importação do React para criar componentes funcionais.
  2. @radix-ui/react-radio-group: Biblioteca para criar grupos de botões de rádio acessíveis e personalizáveis.
  3. Circle: Importação do ícone Circle da biblioteca lucide-react para o indicador visual do botão de rádio selecionado.
  4. 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 o displayName 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 ao RadioGroup, 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 e focus-visible:ring-2 para melhorar a acessibilidade.
    • disabled: Estilos são aplicados quando o item está desabilitado, como disabled:cursor-not-allowed.

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 }