Desenvolvedores
src_
components_
ui_
Breadcrumb.jsx

Aqui temos um conjunto de componentes para implementar um sistema de navegação "breadcrumb" (caminho de navegação) utilizando React e Radix UI. Vamos entender cada parte do código e a sua função.

1. Componente Breadcrumb

Este componente serve como um contêiner para o "breadcrumb". Ele usa a funcionalidade forwardRef do React para permitir que o componente receba uma referência externa.

const Breadcrumb = React.forwardRef(
  ({ ...props }, ref) => <nav ref={ref} aria-label="breadcrumb" {...props} />
)
Breadcrumb.displayName = "Breadcrumb"

🔹 Explicação:

  • React.forwardRef: Permite que o componente tenha uma referência (ref) para se conectar com o DOM, permitindo manipulações diretas no elemento.
  • aria-label="breadcrumb": Atributo de acessibilidade que descreve o propósito do componente.

2. Componente BreadcrumbList

Este componente é uma lista ordenada (<ol>) que mantém os itens do breadcrumb organizados. Ele utiliza a classe cn para aplicar um conjunto de estilos.

const BreadcrumbList = React.forwardRef(({ className, ...props }, ref) => (
  <ol
    ref={ref}
    className={cn(
      "flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5",
      className
    )}
    {...props} />
))
BreadcrumbList.displayName = "BreadcrumbList"

🔹 Explicação:

  • className: Aplica classes de estilo para o layout e o design visual do breadcrumb. A classe cn permite combinar as classes passadas com as classes padrão.
  • flex flex-wrap: Flexbox para organizar os itens, permitindo que quebrem para a linha seguinte quando necessário.

3. Componente BreadcrumbItem

Este componente representa cada item individual dentro do breadcrumb. Ele também usa a classe cn para customizar os estilos.

const BreadcrumbItem = React.forwardRef(({ className, ...props }, ref) => (
  <li
    ref={ref}
    className={cn("inline-flex items-center gap-1.5", className)}
    {...props} />
))
BreadcrumbItem.displayName = "BreadcrumbItem"

🔹 Explicação:

  • inline-flex: Exibe os itens de forma inline, ou seja, lado a lado.
  • gap-1.5: Define o espaço entre os itens do breadcrumb.

4. Componente BreadcrumbLink

Este componente permite a navegação entre os itens do breadcrumb, seja como um link normal (<a>) ou um componente filho, dependendo do valor de asChild.

const BreadcrumbLink = React.forwardRef(({ asChild, className, ...props }, ref) => {
  const Comp = asChild ? Slot : "a"
 
  return (
    (<Comp
      ref={ref}
      className={cn("transition-colors hover:text-foreground", className)}
      {...props} />)
  );
})
BreadcrumbLink.displayName = "BreadcrumbLink"

🔹 Explicação:

  • asChild: Se verdadeiro, o componente Slot da biblioteca Radix UI será usado no lugar do <a>.
  • transition-colors: Aplica uma transição suave na cor do link quando o usuário passa o mouse sobre ele.

5. Componente BreadcrumbPage

Este componente representa a página atual dentro do breadcrumb. Ele é visualmente destacado para indicar que a navegação não está mais disponível para o item.

const BreadcrumbPage = React.forwardRef(({ className, ...props }, ref) => (
  <span
    ref={ref}
    role="link"
    aria-disabled="true"
    aria-current="page"
    className={cn("font-normal text-foreground", className)}
    {...props} />
))
BreadcrumbPage.displayName = "BreadcrumbPage"

🔹 Explicação:

  • aria-current="page": Indica que este item é a página atual.
  • aria-disabled="true": Desativa a interação com o item, já que ele não é clicável.

6. Componente BreadcrumbSeparator

Este componente representa o separador entre os itens do breadcrumb, geralmente um ícone como uma seta.

const BreadcrumbSeparator = ({
  children,
  className,
  ...props
}) => (
  <li
    role="presentation"
    aria-hidden="true"
    className={cn("[&>svg]:w-3.5 [&>svg]:h-3.5", className)}
    {...props}>
    {children ?? <ChevronRight />}
  </li>
)
BreadcrumbSeparator.displayName = "BreadcrumbSeparator"

🔹 Explicação:

  • ChevronRight: Ícone de seta para a direita que é usado como separador padrão.
  • role="presentation" e aria-hidden="true": Esses atributos indicam que o elemento é decorativo e não interativo.

7. Componente BreadcrumbEllipsis

Este componente exibe um ícone de elipses (...) quando houver muitos itens no breadcrumb para serem exibidos.

const BreadcrumbEllipsis = ({
  className,
  ...props
}) => (
  <span
    role="presentation"
    aria-hidden="true"
    className={cn("flex h-9 w-9 items-center justify-center", className)}
    {...props}>
    <MoreHorizontal className="h-4 w-4" />
    <span className="sr-only">More</span>
  </span>
)
BreadcrumbEllipsis.displayName = "BreadcrumbElipssis"

🔹 Explicação:

  • MoreHorizontal: Ícone de três pontos horizontais, representando um menu ou mais opções.
  • sr-only: Classe usada para ocultar o texto para leitores de tela, garantindo acessibilidade.

Código Completo

import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { ChevronRight, MoreHorizontal } from "lucide-react"
 
import { cn } from "@/lib/utils"
 
const Breadcrumb = React.forwardRef(
  ({ ...props }, ref) => <nav ref={ref} aria-label="breadcrumb" {...props} />
)
Breadcrumb.displayName = "Breadcrumb"
 
const BreadcrumbList = React.forwardRef(({ className, ...props }, ref) => (
  <ol
    ref={ref}
    className={cn(
      "flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5",
      className
    )}
    {...props} />
))
BreadcrumbList.displayName = "BreadcrumbList"
 
const BreadcrumbItem = React.forwardRef(({ className, ...props }, ref) => (
  <li
    ref={ref}
    className={cn("inline-flex items-center gap-1.5", className)}
    {...props} />
))
BreadcrumbItem.displayName = "BreadcrumbItem"
 
const BreadcrumbLink = React.forwardRef(({ asChild, className, ...props }, ref) => {
  const Comp = asChild ? Slot : "a"
 
  return (
    (<Comp
      ref={ref}
      className={cn("transition-colors hover:text-foreground", className)}
      {...props} />)
  );
})
BreadcrumbLink.displayName = "BreadcrumbLink"
 
const BreadcrumbPage = React.forwardRef(({ className, ...props }, ref) => (
  <span
    ref={ref}
    role="link"
    aria-disabled="true"
    aria-current="page"
    className={cn("font-normal text-foreground", className)}
    {...props} />
))
BreadcrumbPage.displayName = "BreadcrumbPage"
 
const BreadcrumbSeparator = ({
  children,
  className,
  ...props
}) => (
  <li
    role="presentation"
    aria-hidden="true"
    className={cn("[&>svg]:w-3.5 [&>svg]:h-3.5", className)}
    {...props}>
    {children ?? <ChevronRight />}
  </li>
)
BreadcrumbSeparator.displayName = "BreadcrumbSeparator"
 
const BreadcrumbEllipsis = ({
  className,
  ...props
}) => (
  <span
    role="presentation"
    aria-hidden="true"
    className={cn("flex h-9 w-9 items-center justify-center", className)}
    {...props}>
    <MoreHorizontal className="h-4 w-4" />
    <span className="sr-only">More</span>
  </span>
)
BreadcrumbEllipsis.displayName = "BreadcrumbElipssis"
 
export {
  Breadcrumb,
  BreadcrumbList,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbPage,
  BreadcrumbSeparator,
  BreadcrumbEllipsis,
}