diff --git a/src/components/layout/nav-group.tsx b/src/components/layout/nav-group.tsx
index 8553454c..4ae54f34 100644
--- a/src/components/layout/nav-group.tsx
+++ b/src/components/layout/nav-group.tsx
@@ -18,75 +18,35 @@ import {
useSidebar,
} from '@/components/ui/sidebar'
import { Badge } from '../ui/badge'
-import { NavItem, type NavGroup } from './types'
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuLabel,
+ DropdownMenuSeparator,
+ DropdownMenuTrigger,
+} from '../ui/dropdown-menu'
+import { NavCollapsible, NavItem, NavLink, type NavGroup } from './types'
export function NavGroup({ title, items }: NavGroup) {
- const { setOpenMobile } = useSidebar()
+ const { state } = useSidebar()
const href = useLocation({ select: (location) => location.href })
return (
{title}
{items.map((item) => {
- if (!item.items) {
+ const key = `${item.title}-${item.url}`
+
+ if (!item.items)
+ return
+
+ if (state === 'collapsed')
return (
-
-
- setOpenMobile(false)}>
- {item.icon && }
- {item.title}
- {item.badge && {item.badge}}
-
-
-
+
)
- }
- return (
-
-
-
-
- {item.icon && }
- {item.title}
- {item.badge && {item.badge}}
-
-
-
-
-
- {item.items.map((subItem) => (
-
-
- setOpenMobile(false)}
- >
- {subItem.icon && }
- {subItem.title}
- {subItem.badge && (
- {subItem.badge}
- )}
-
-
-
- ))}
-
-
-
-
- )
+
+ return
})}
@@ -97,6 +57,117 @@ const NavBadge = ({ children }: { children: ReactNode }) => (
{children}
)
+const SidebarMenuLink = ({ item, href }: { item: NavLink; href: string }) => {
+ const { setOpenMobile } = useSidebar()
+ return (
+
+
+ setOpenMobile(false)}>
+ {item.icon && }
+ {item.title}
+ {item.badge && {item.badge}}
+
+
+
+ )
+}
+
+const SidebarMenuCollapsible = ({
+ item,
+ href,
+}: {
+ item: NavCollapsible
+ href: string
+}) => {
+ const { setOpenMobile } = useSidebar()
+ return (
+
+
+
+
+ {item.icon && }
+ {item.title}
+ {item.badge && {item.badge}}
+
+
+
+
+
+ {item.items.map((subItem) => (
+
+
+ setOpenMobile(false)}>
+ {subItem.icon && }
+ {subItem.title}
+ {subItem.badge && {subItem.badge}}
+
+
+
+ ))}
+
+
+
+
+ )
+}
+
+const SidebarMenuCollapsedDropdown = ({
+ item,
+ href,
+}: {
+ item: NavCollapsible
+ href: string
+}) => {
+ return (
+
+
+
+
+ {item.icon && }
+ {item.title}
+ {item.badge && {item.badge}}
+
+
+
+
+
+ {item.title} {item.badge ? `(${item.badge})` : ''}
+
+
+ {item.items.map((sub) => (
+
+
+ {sub.icon && }
+ {sub.title}
+ {sub.badge && (
+ {sub.badge}
+ )}
+
+
+ ))}
+
+
+
+ )
+}
+
function checkIsActive(href: string, item: NavItem, mainNav = false) {
return (
href === item.url || // /endpint?search=param
diff --git a/src/components/layout/types.ts b/src/components/layout/types.ts
index 75a8a64e..86e8f6e5 100644
--- a/src/components/layout/types.ts
+++ b/src/components/layout/types.ts
@@ -18,15 +18,17 @@ interface BaseNavItem {
icon?: React.ElementType
}
-export type NavItem =
- | (BaseNavItem & {
- items: (BaseNavItem & { url: LinkProps['to'] })[]
- url?: never
- })
- | (BaseNavItem & {
- url: LinkProps['to']
- items?: never
- })
+type NavLink = BaseNavItem & {
+ url: LinkProps['to']
+ items?: never
+}
+
+type NavCollapsible = BaseNavItem & {
+ items: (BaseNavItem & { url: LinkProps['to'] })[]
+ url?: never
+}
+
+type NavItem = NavCollapsible | NavLink
interface NavGroup {
title: string
@@ -39,4 +41,4 @@ interface SidebarData {
navGroups: NavGroup[]
}
-export type { SidebarData, NavGroup }
+export type { SidebarData, NavGroup, NavItem, NavCollapsible, NavLink }