|
|
@@ -1,20 +1,11 @@
|
|
|
import { Link } from 'react-router-dom'
|
|
|
-import {
|
|
|
- Tooltip,
|
|
|
- TooltipContent,
|
|
|
- TooltipProvider,
|
|
|
- TooltipTrigger,
|
|
|
-} from './ui/tooltip'
|
|
|
-import { cn } from '@/lib/utils'
|
|
|
+import { IconChevronDown } from '@tabler/icons-react'
|
|
|
import { Button, buttonVariants } from './ui/button'
|
|
|
import {
|
|
|
Collapsible,
|
|
|
CollapsibleContent,
|
|
|
CollapsibleTrigger,
|
|
|
-} from '@/components/ui/collapsible'
|
|
|
-import { IconChevronDown } from '@tabler/icons-react'
|
|
|
-import { SideLink } from '@/data/sidelinks'
|
|
|
-
|
|
|
+} from './ui/collapsible'
|
|
|
import {
|
|
|
DropdownMenu,
|
|
|
DropdownMenuContent,
|
|
|
@@ -22,40 +13,63 @@ import {
|
|
|
DropdownMenuLabel,
|
|
|
DropdownMenuSeparator,
|
|
|
DropdownMenuTrigger,
|
|
|
-} from '@/components/ui/dropdown-menu'
|
|
|
-import useCheckActiveNav from '@/hooks/useCheckActiveNav'
|
|
|
+} from './ui/dropdown-menu'
|
|
|
+import {
|
|
|
+ Tooltip,
|
|
|
+ TooltipContent,
|
|
|
+ TooltipProvider,
|
|
|
+ TooltipTrigger,
|
|
|
+} from './ui/tooltip'
|
|
|
+import { cn } from '@/lib/utils'
|
|
|
+import useCheckActiveNav from '@/hooks/use-check-active-nav'
|
|
|
+import { SideLink } from '@/data/sidelinks'
|
|
|
|
|
|
interface NavProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
isCollapsed: boolean
|
|
|
links: SideLink[]
|
|
|
+ closeNav: () => void
|
|
|
}
|
|
|
|
|
|
-export default function Nav({ links, isCollapsed, className }: NavProps) {
|
|
|
+export default function Nav({
|
|
|
+ links,
|
|
|
+ isCollapsed,
|
|
|
+ className,
|
|
|
+ closeNav,
|
|
|
+}: NavProps) {
|
|
|
const renderLink = ({ sub, ...rest }: SideLink) => {
|
|
|
const key = `${rest.title}-${rest.href}`
|
|
|
if (isCollapsed && sub)
|
|
|
- return <NavLinkIconDropdown {...rest} sub={sub} key={key} />
|
|
|
+ return (
|
|
|
+ <NavLinkIconDropdown
|
|
|
+ {...rest}
|
|
|
+ sub={sub}
|
|
|
+ key={key}
|
|
|
+ closeNav={closeNav}
|
|
|
+ />
|
|
|
+ )
|
|
|
|
|
|
- if (isCollapsed) return <NavLinkIcon {...rest} key={key} />
|
|
|
+ if (isCollapsed)
|
|
|
+ return <NavLinkIcon {...rest} key={key} closeNav={closeNav} />
|
|
|
|
|
|
- if (sub) return <NavLinkDropdown {...rest} sub={sub} key={key} />
|
|
|
+ if (sub)
|
|
|
+ return (
|
|
|
+ <NavLinkDropdown {...rest} sub={sub} key={key} closeNav={closeNav} />
|
|
|
+ )
|
|
|
|
|
|
- return <NavLink {...rest} key={key} />
|
|
|
+ return <NavLink {...rest} key={key} closeNav={closeNav} />
|
|
|
}
|
|
|
return (
|
|
|
<div
|
|
|
data-collapsed={isCollapsed}
|
|
|
className={cn(
|
|
|
- 'group overflow-hidden border-b py-2 transition-[max-height,padding] duration-500 data-[collapsed=true]:py-2 md:border-none',
|
|
|
+ 'group border-b bg-background py-2 transition-[max-height,padding] duration-500 data-[collapsed=true]:py-2 md:border-none',
|
|
|
className
|
|
|
)}
|
|
|
>
|
|
|
<TooltipProvider delayDuration={0}>
|
|
|
- <div className='h-auto overflow-auto md:h-svh'>
|
|
|
- <nav className='grid gap-1 group-[[data-collapsed=true]]:justify-center group-[[data-collapsed=true]]:px-2'>
|
|
|
- {links.map(renderLink)}
|
|
|
- </nav>
|
|
|
- </div>
|
|
|
+ <nav className='grid gap-1 group-[[data-collapsed=true]]:justify-center group-[[data-collapsed=true]]:px-2'>
|
|
|
+ {links.map(renderLink)}
|
|
|
+ </nav>
|
|
|
</TooltipProvider>
|
|
|
</div>
|
|
|
)
|
|
|
@@ -63,13 +77,22 @@ export default function Nav({ links, isCollapsed, className }: NavProps) {
|
|
|
|
|
|
interface NavLinkProps extends SideLink {
|
|
|
subLink?: boolean
|
|
|
+ closeNav: () => void
|
|
|
}
|
|
|
|
|
|
-function NavLink({ title, icon, label, href, subLink = false }: NavLinkProps) {
|
|
|
+function NavLink({
|
|
|
+ title,
|
|
|
+ icon,
|
|
|
+ label,
|
|
|
+ href,
|
|
|
+ closeNav,
|
|
|
+ subLink = false,
|
|
|
+}: NavLinkProps) {
|
|
|
const { checkActiveNav } = useCheckActiveNav()
|
|
|
return (
|
|
|
<Link
|
|
|
to={href}
|
|
|
+ onClick={closeNav}
|
|
|
className={cn(
|
|
|
buttonVariants({
|
|
|
variant: checkActiveNav(href) ? 'secondary' : 'ghost',
|
|
|
@@ -78,6 +101,7 @@ function NavLink({ title, icon, label, href, subLink = false }: NavLinkProps) {
|
|
|
'h-12 justify-start text-wrap rounded-none px-6',
|
|
|
subLink && 'h-10 w-full border-l border-l-slate-500 px-2'
|
|
|
)}
|
|
|
+ aria-current={checkActiveNav(href) ? 'page' : undefined}
|
|
|
>
|
|
|
<div className='mr-2'>{icon}</div>
|
|
|
{title}
|
|
|
@@ -90,7 +114,7 @@ function NavLink({ title, icon, label, href, subLink = false }: NavLinkProps) {
|
|
|
)
|
|
|
}
|
|
|
|
|
|
-function NavLinkDropdown({ title, icon, label, sub }: SideLink) {
|
|
|
+function NavLinkDropdown({ title, icon, label, sub, closeNav }: NavLinkProps) {
|
|
|
const { checkActiveNav } = useCheckActiveNav()
|
|
|
|
|
|
/* Open collapsible by default
|
|
|
@@ -124,7 +148,7 @@ function NavLinkDropdown({ title, icon, label, sub }: SideLink) {
|
|
|
<ul>
|
|
|
{sub!.map((sublink) => (
|
|
|
<li key={sublink.title} className='my-1 ml-8'>
|
|
|
- <NavLink {...sublink} subLink />
|
|
|
+ <NavLink {...sublink} subLink closeNav={closeNav} />
|
|
|
</li>
|
|
|
))}
|
|
|
</ul>
|
|
|
@@ -162,7 +186,7 @@ function NavLinkIcon({ title, icon, label, href }: NavLinkProps) {
|
|
|
)
|
|
|
}
|
|
|
|
|
|
-function NavLinkIconDropdown({ title, icon, label, sub }: SideLink) {
|
|
|
+function NavLinkIconDropdown({ title, icon, label, sub }: NavLinkProps) {
|
|
|
const { checkActiveNav } = useCheckActiveNav()
|
|
|
|
|
|
/* Open collapsible by default
|