sidebar-nav.tsx 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import { useState, type JSX } from 'react'
  2. import { useLocation, useNavigate } from '@tanstack/react-router'
  3. import { Link } from '@tanstack/react-router'
  4. import { cn } from '@/lib/utils'
  5. import { ScrollArea } from '@/components/ui/scroll-area'
  6. import {
  7. Select,
  8. SelectContent,
  9. SelectItem,
  10. SelectTrigger,
  11. SelectValue,
  12. } from '@/components/ui/select'
  13. import { buttonVariants } from '@/components/button'
  14. interface SidebarNavProps extends React.HTMLAttributes<HTMLElement> {
  15. items: {
  16. href: string
  17. title: string
  18. icon: JSX.Element
  19. }[]
  20. }
  21. export default function SidebarNav({
  22. className,
  23. items,
  24. ...props
  25. }: SidebarNavProps) {
  26. const { pathname } = useLocation()
  27. const navigate = useNavigate()
  28. const [val, setVal] = useState(pathname ?? '/settings')
  29. const handleSelect = (e: string) => {
  30. setVal(e)
  31. navigate({ to: e })
  32. }
  33. return (
  34. <>
  35. <div className='p-1 md:hidden'>
  36. <Select value={val} onValueChange={handleSelect}>
  37. <SelectTrigger className='h-12 sm:w-48'>
  38. <SelectValue placeholder='Theme' />
  39. </SelectTrigger>
  40. <SelectContent>
  41. {items.map((item) => (
  42. <SelectItem key={item.href} value={item.href}>
  43. <div className='flex gap-x-4 px-2 py-1'>
  44. <span className='scale-125'>{item.icon}</span>
  45. <span className='text-md'>{item.title}</span>
  46. </div>
  47. </SelectItem>
  48. ))}
  49. </SelectContent>
  50. </Select>
  51. </div>
  52. <ScrollArea
  53. orientation='horizontal'
  54. type='always'
  55. className='hidden w-full bg-background px-1 py-2 md:block min-w-40'
  56. >
  57. <nav
  58. className={cn(
  59. 'flex py-1 space-x-2 lg:flex-col lg:space-x-0 lg:space-y-1',
  60. className
  61. )}
  62. {...props}
  63. >
  64. {items.map((item) => (
  65. <Link
  66. key={item.href}
  67. to={item.href}
  68. className={cn(
  69. buttonVariants({ variant: 'ghost' }),
  70. pathname === item.href
  71. ? 'bg-muted hover:bg-muted'
  72. : 'hover:bg-transparent hover:underline',
  73. 'justify-start'
  74. )}
  75. >
  76. <span className='mr-2'>{item.icon}</span>
  77. {item.title}
  78. </Link>
  79. ))}
  80. </nav>
  81. </ScrollArea>
  82. </>
  83. )
  84. }