Active menu item follow react router state

Signed-off-by: gearnode <bryan@frimin.fr>
This commit is contained in:
gearnode
2025-02-26 10:51:29 +01:00
parent 9bc966b32c
commit 56f3c8aea3
2 changed files with 80 additions and 37 deletions

View File

@@ -31,6 +31,7 @@ import {
} from "@/components/ui/sidebar"; } from "@/components/ui/sidebar";
import type { AppSidebarQuery as AppSidebarQueryType } from "./__generated__/AppSidebarQuery.graphql"; import type { AppSidebarQuery as AppSidebarQueryType } from "./__generated__/AppSidebarQuery.graphql";
import { TeamSwitcher } from "@/components/TeamSwitcher"; import { TeamSwitcher } from "@/components/TeamSwitcher";
import { url } from "inspector";
const staticData = { const staticData = {
user: { user: {
name: "shadcn", name: "shadcn",
@@ -46,7 +47,7 @@ const staticData = {
{ {
title: "Organizations", title: "Organizations",
icon: Building, icon: Building,
isActive: true, url: "/peoples",
items: [ items: [
{ {
title: "Peoples", title: "Peoples",

View File

@@ -1,7 +1,7 @@
"use client"; "use client";
import { ChevronRight, type LucideIcon } from "lucide-react"; import { ChevronRight, type LucideIcon } from "lucide-react";
import { Link } from "react-router"; import { Link, useLocation } from "react-router";
import { import {
Collapsible, Collapsible,
@@ -34,45 +34,87 @@ export function NavMain({
}[]; }[];
}[]; }[];
}) { }) {
const location = useLocation();
// Determine if an item is active based on the current route
const isItemActive = (item: { url?: string; items?: { url: string }[] }) => {
// If the item has a URL and it matches the current path
if (item.url && location.pathname.startsWith(item.url)) {
return true;
}
// If the item has sub-items, check if any of them match the current path
if (item.items?.length) {
return item.items.some((subItem) =>
location.pathname.startsWith(subItem.url)
);
}
return false;
};
return ( return (
<SidebarGroup> <SidebarGroup>
<SidebarGroupLabel>Compliance</SidebarGroupLabel> <SidebarGroupLabel>Compliance</SidebarGroupLabel>
<SidebarMenu> <SidebarMenu>
{items.map((item) => ( {items.map((item) => {
<Collapsible key={item.title} asChild defaultOpen={item.isActive}> const active = isItemActive(item) || item.isActive;
<SidebarMenuItem>
<SidebarMenuButton asChild tooltip={item.title}> return (
<Link to={item.url ?? "#"}> <Collapsible key={item.title} asChild defaultOpen={active}>
<item.icon /> <SidebarMenuItem>
<span>{item.title}</span> <SidebarMenuButton
</Link> asChild
</SidebarMenuButton> tooltip={item.title}
{item.items?.length ? ( data-active={active ? "true" : undefined}
<> className={active ? "text-primary font-medium" : ""}
<CollapsibleTrigger asChild> >
<SidebarMenuAction className="data-[state=open]:rotate-90"> <Link to={item.url ?? "#"}>
<ChevronRight /> <item.icon />
<span className="sr-only">Toggle</span> <span>{item.title}</span>
</SidebarMenuAction> </Link>
</CollapsibleTrigger> </SidebarMenuButton>
<CollapsibleContent> {item.items?.length ? (
<SidebarMenuSub> <>
{item.items?.map((subItem) => ( <CollapsibleTrigger asChild>
<SidebarMenuSubItem key={subItem.title}> <SidebarMenuAction className="data-[state=open]:rotate-90">
<SidebarMenuSubButton asChild> <ChevronRight />
<Link to={subItem.url}> <span className="sr-only">Toggle</span>
<span>{subItem.title}</span> </SidebarMenuAction>
</Link> </CollapsibleTrigger>
</SidebarMenuSubButton> <CollapsibleContent>
</SidebarMenuSubItem> <SidebarMenuSub>
))} {item.items?.map((subItem) => {
</SidebarMenuSub> const subItemActive = location.pathname.startsWith(
</CollapsibleContent> subItem.url
</> );
) : null}
</SidebarMenuItem> return (
</Collapsible> <SidebarMenuSubItem key={subItem.title}>
))} <SidebarMenuSubButton
asChild
data-active={subItemActive ? "true" : undefined}
className={
subItemActive
? "text-primary font-medium"
: ""
}
>
<Link to={subItem.url}>
<span>{subItem.title}</span>
</Link>
</SidebarMenuSubButton>
</SidebarMenuSubItem>
);
})}
</SidebarMenuSub>
</CollapsibleContent>
</>
) : null}
</SidebarMenuItem>
</Collapsible>
);
})}
</SidebarMenu> </SidebarMenu>
</SidebarGroup> </SidebarGroup>
); );