|
1 | 1 | <script setup lang="ts"> |
2 | | -import { SidebarGroup, SidebarGroupLabel, SidebarMenu, SidebarMenuButton, SidebarMenuItem } from '@/components/ui/sidebar'; |
| 2 | +import { SidebarGroup, SidebarGroupLabel, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem } from '@/components/ui/sidebar' |
3 | 3 | import { type NavItem, type SharedData } from '@/types'; |
4 | 4 | import { Link, usePage } from '@inertiajs/vue3'; |
| 5 | +import { ChevronRight } from 'lucide-vue-next' |
| 6 | +import { Collapsible, CollapsibleContent, CollapsibleTrigger } from './ui/collapsible' |
5 | 7 |
|
6 | 8 | defineProps<{ |
7 | 9 | items: NavItem[]; |
8 | 10 | }>(); |
9 | 11 |
|
10 | 12 | const page = usePage<SharedData>(); |
| 13 | +
|
| 14 | +function isChildActive(item: { children: any[], href: string }) { |
| 15 | + return item.children?.some(child => child.href === page.url) || item.href === page.url |
| 16 | +} |
11 | 17 | </script> |
12 | 18 |
|
13 | 19 | <template> |
14 | 20 | <SidebarGroup class="px-2 py-0"> |
15 | 21 | <SidebarGroupLabel>Platform</SidebarGroupLabel> |
16 | 22 | <SidebarMenu> |
17 | | - <SidebarMenuItem v-for="item in items" :key="item.title"> |
18 | | - <SidebarMenuButton |
19 | | - as-child :is-active="item.href === page.url" |
20 | | - :tooltip="item.title" |
21 | | - > |
22 | | - <Link :href="item.href"> |
| 23 | + <template v-for="item in items" :key="item.title"> |
| 24 | + <!-- Regular items (no children) --> |
| 25 | + <SidebarMenuItem v-if="!item.children"> |
| 26 | + <SidebarMenuButton as-child :is-active="item.href === page.url" :tooltip="item.title"> |
| 27 | + <Link :href="item.href"> |
23 | 28 | <component :is="item.icon" /> |
24 | 29 | <span>{{ item.title }}</span> |
25 | | - </Link> |
26 | | - </SidebarMenuButton> |
27 | | - </SidebarMenuItem> |
| 30 | + </Link> |
| 31 | + </SidebarMenuButton> |
| 32 | + </SidebarMenuItem> |
| 33 | + |
| 34 | + <!-- Collapsible items (with children) --> |
| 35 | + <Collapsible v-else :default-open="isChildActive({ children: item.children || [], href: item.href })" |
| 36 | + class="group/collapsible"> |
| 37 | + <SidebarMenuItem> |
| 38 | + <CollapsibleTrigger as-child> |
| 39 | + <SidebarMenuButton |
| 40 | + :is-active="isChildActive({ children: item.children || [], href: item.href })" |
| 41 | + :tooltip="item.title"> |
| 42 | + <component :is="item.icon" v-if="item.icon" /> |
| 43 | + <span>{{ item.title }}</span> |
| 44 | + <ChevronRight |
| 45 | + class="ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90" /> |
| 46 | + </SidebarMenuButton> |
| 47 | + </CollapsibleTrigger> |
| 48 | + <CollapsibleContent> |
| 49 | + <SidebarMenuSub> |
| 50 | + <SidebarMenuSubItem v-for="subItem in item.children" :key="subItem.title"> |
| 51 | + <SidebarMenuSubButton as-child :is-active="subItem.href === page.url"> |
| 52 | + <Link :href="subItem.href"> |
| 53 | + <span>{{ subItem.title }}</span> |
| 54 | + </Link> |
| 55 | + </SidebarMenuSubButton> |
| 56 | + </SidebarMenuSubItem> |
| 57 | + </SidebarMenuSub> |
| 58 | + </CollapsibleContent> |
| 59 | + </SidebarMenuItem> |
| 60 | + </Collapsible> |
| 61 | + </template> |
28 | 62 | </SidebarMenu> |
29 | 63 | </SidebarGroup> |
30 | 64 | </template> |
0 commit comments