top-nav.tsx 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import { Link } from '@tanstack/react-router'
  2. import { Menu } from 'lucide-react'
  3. import { cn } from '@/lib/utils'
  4. import { Button } from '@/components/ui/button'
  5. import {
  6. DropdownMenu,
  7. DropdownMenuContent,
  8. DropdownMenuItem,
  9. DropdownMenuTrigger,
  10. } from '@/components/ui/dropdown-menu'
  11. type TopNavProps = React.HTMLAttributes<HTMLElement> & {
  12. links: {
  13. title: string
  14. href: string
  15. isActive: boolean
  16. disabled?: boolean
  17. }[]
  18. }
  19. export function TopNav({ className, links, ...props }: TopNavProps) {
  20. return (
  21. <>
  22. <div className='lg:hidden'>
  23. <DropdownMenu modal={false}>
  24. <DropdownMenuTrigger asChild>
  25. <Button size='icon' variant='outline' className='md:size-7'>
  26. <Menu />
  27. </Button>
  28. </DropdownMenuTrigger>
  29. <DropdownMenuContent side='bottom' align='start'>
  30. {links.map(({ title, href, isActive, disabled }) => (
  31. <DropdownMenuItem key={`${title}-${href}`} asChild>
  32. <Link
  33. to={href}
  34. className={!isActive ? 'text-muted-foreground' : ''}
  35. disabled={disabled}
  36. >
  37. {title}
  38. </Link>
  39. </DropdownMenuItem>
  40. ))}
  41. </DropdownMenuContent>
  42. </DropdownMenu>
  43. </div>
  44. <nav
  45. className={cn(
  46. 'hidden items-center space-x-4 lg:flex lg:space-x-4 xl:space-x-6',
  47. className
  48. )}
  49. {...props}
  50. >
  51. {links.map(({ title, href, isActive, disabled }) => (
  52. <Link
  53. key={`${title}-${href}`}
  54. to={href}
  55. disabled={disabled}
  56. className={`hover:text-primary text-sm font-medium transition-colors ${isActive ? '' : 'text-muted-foreground'}`}
  57. >
  58. {title}
  59. </Link>
  60. ))}
  61. </nav>
  62. </>
  63. )
  64. }