breadcrumb.tsx 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. import { Slot } from '@radix-ui/react-slot';
  2. import { ChevronRight, MoreHorizontal } from 'lucide-react';
  3. import * as React from 'react';
  4. import { cn } from '@/common/helpers/cn';
  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('flex flex-wrap items-center gap-1.5 text-sm break-words text-muted-foreground sm:gap-2.5', className)}
  13. {...props}
  14. />
  15. );
  16. }
  17. function BreadcrumbItem({ className, ...props }: React.ComponentProps<'li'>) {
  18. return <li data-slot="breadcrumb-item" className={cn('inline-flex items-center gap-1.5', className)} {...props} />;
  19. }
  20. function BreadcrumbLink({
  21. asChild,
  22. className,
  23. ...props
  24. }: React.ComponentProps<'a'> & {
  25. asChild?: boolean;
  26. }) {
  27. const Comp = asChild ? Slot : 'a';
  28. return <Comp data-slot="breadcrumb-link" className={cn('transition-colors hover:text-foreground', className)} {...props} />;
  29. }
  30. function BreadcrumbPage({ className, ...props }: React.ComponentProps<'span'>) {
  31. return (
  32. <span
  33. data-slot="breadcrumb-page"
  34. role="link"
  35. aria-disabled="true"
  36. aria-current="page"
  37. className={cn('font-normal text-foreground', className)}
  38. {...props}
  39. />
  40. );
  41. }
  42. function BreadcrumbSeparator({ children, className, ...props }: React.ComponentProps<'li'>) {
  43. return (
  44. <li data-slot="breadcrumb-separator" role="presentation" aria-hidden="true" className={cn('[&>svg]:size-3.5', className)} {...props}>
  45. {children ?? <ChevronRight />}
  46. </li>
  47. );
  48. }
  49. function BreadcrumbEllipsis({ className, ...props }: React.ComponentProps<'span'>) {
  50. return (
  51. <span
  52. data-slot="breadcrumb-ellipsis"
  53. role="presentation"
  54. aria-hidden="true"
  55. className={cn('flex size-9 items-center justify-center', className)}
  56. {...props}
  57. >
  58. <MoreHorizontal className="size-4" />
  59. <span className="sr-only">More</span>
  60. </span>
  61. );
  62. }
  63. export { Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator };