breadcrumb.tsx 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. import * as React from "react"
  2. import { Slot } from "@radix-ui/react-slot"
  3. import { ChevronRight, MoreHorizontal } from "lucide-react"
  4. import { cn } from "@/lib/utils"
  5. function Breadcrumb({ ...props }: React.ComponentProps<"nav">) {
  6. return <nav aria-label="breadcrumb" data-slot="breadcrumb" {...props} />
  7. }
  8. function BreadcrumbList({ className, ...props }: React.ComponentProps<"ol">) {
  9. return (
  10. <ol
  11. data-slot="breadcrumb-list"
  12. className={cn(
  13. "text-muted-foreground flex flex-wrap items-center gap-1.5 text-sm break-words sm:gap-2.5",
  14. className
  15. )}
  16. {...props}
  17. />
  18. )
  19. }
  20. function BreadcrumbItem({ className, ...props }: React.ComponentProps<"li">) {
  21. return (
  22. <li
  23. data-slot="breadcrumb-item"
  24. className={cn("inline-flex items-center gap-1.5", className)}
  25. {...props}
  26. />
  27. )
  28. }
  29. function BreadcrumbLink({
  30. asChild,
  31. className,
  32. ...props
  33. }: React.ComponentProps<"a"> & {
  34. asChild?: boolean
  35. }) {
  36. const Comp = asChild ? Slot : "a"
  37. return (
  38. <Comp
  39. data-slot="breadcrumb-link"
  40. className={cn("hover:text-foreground transition-colors", className)}
  41. {...props}
  42. />
  43. )
  44. }
  45. function BreadcrumbPage({ className, ...props }: React.ComponentProps<"span">) {
  46. return (
  47. <span
  48. data-slot="breadcrumb-page"
  49. role="link"
  50. aria-disabled="true"
  51. aria-current="page"
  52. className={cn("text-foreground font-normal", className)}
  53. {...props}
  54. />
  55. )
  56. }
  57. function BreadcrumbSeparator({
  58. children,
  59. className,
  60. ...props
  61. }: React.ComponentProps<"li">) {
  62. return (
  63. <li
  64. data-slot="breadcrumb-separator"
  65. role="presentation"
  66. aria-hidden="true"
  67. className={cn("[&>svg]:size-3.5", className)}
  68. {...props}
  69. >
  70. {children ?? <ChevronRight />}
  71. </li>
  72. )
  73. }
  74. function BreadcrumbEllipsis({
  75. className,
  76. ...props
  77. }: React.ComponentProps<"span">) {
  78. return (
  79. <span
  80. data-slot="breadcrumb-ellipsis"
  81. role="presentation"
  82. aria-hidden="true"
  83. className={cn("flex size-9 items-center justify-center", className)}
  84. {...props}
  85. >
  86. <MoreHorizontal className="size-4" />
  87. <span className="sr-only">More</span>
  88. </span>
  89. )
  90. }
  91. export {
  92. Breadcrumb,
  93. BreadcrumbList,
  94. BreadcrumbItem,
  95. BreadcrumbLink,
  96. BreadcrumbPage,
  97. BreadcrumbSeparator,
  98. BreadcrumbEllipsis,
  99. }