JumboNavbar

JumboNavbar renders the sidebar navigation tree. It reads menu items from JumboNavbarProvider and renders them as grouped sections, collapsible groups, and leaf items. The nav system supports unlimited nesting, icon support, and submenu expansion.

Provider setup

JumboNavbarProvider is typically rendered inside the sidebar component. It receives the menu items array and makes it available to all nav components below it:

tsx
// src/components/SidebarWithMenus/SidebarWithMenus.tsx (simplified)
import { JumboNavbarProvider } from '@jumbo/components/JumboNavbar';
import { JumboNavbar } from '@jumbo/components/JumboNavbar';
 
interface Props {
  menus: NavItemType[];
}
 
export function SidebarWithMenus({ menus }: Props) {
  return (
    <JumboNavbarProvider items={menus}>
      <JumboScrollbar>
        <JumboNavbar />
      </JumboScrollbar>
    </JumboNavbarProvider>
  );
}

Menu items are described by the NavItemType from @jumbo/types/JumboNavbar:

typescript
interface NavItemType {
  label:     string;         // Displayed label
  type:      'section' | 'group' | 'item';
  icon?:     ReactNode;      // Optional icon (MUI Icon or any ReactNode)
  uri?:      string;         // Route path (items only)
  children?: NavItemType[];  // Nested items (groups/sections)
}

Item types

TypeDescriptionRenders as
sectionTop-level category headingNon-clickable label dividing nav sections
groupCollapsible groupExpandable list with children
itemLeaf navigation linkClickable route link

Example menu definition

typescript
// src/utilities/constants/menu-items.ts
export const menuItems: NavItemType[] = [
  {
    label: 'Dashboards',
    type: 'section',
    children: [
      {
        label: 'Misc',
        type: 'item',
        icon: <DashboardOutlined />,
        uri: '/dashboards/misc',
      },
      {
        label: 'CRM',
        type: 'item',
        icon: <PeopleOutlined />,
        uri: '/dashboards/crm',
      },
    ],
  },
  {
    label: 'Apps',
    type: 'section',
    children: [
      {
        label: 'Mail',
        type: 'group',
        icon: <MailOutlined />,
        children: [
          { label: 'Inbox',  type: 'item', uri: '/apps/mail/inbox' },
          { label: 'Sent',   type: 'item', uri: '/apps/mail/sent' },
          { label: 'Drafts', type: 'item', uri: '/apps/mail/drafts' },
        ],
      },
    ],
  },
];

Serving menus from the API

Menu items can be fetched from the menus API route. The service layer in src/services/index.ts currently returns items from static constants but includes the fetch pattern for dynamic use:

typescript
// src/services/index.ts
export async function getMenus(locale: string) {
  // Static: return getMenuItems(locale);
 
  // Dynamic (API):
  const response = await fetch(`/api/menus/${locale}`);
  const data = await response.json();
  return data.menuItems;
}

The API route at src/app/api/menus/[locale]/route.ts accepts a GET request and returns the menu items for the given locale.

useJumboNavbarContext gives any child component access to the nav items and state:

typescript
'use client';
 
import { useJumboNavbarContext } from '@jumbo/components/JumboNavbar';
 
export function NavItemCount() {
  const { navItems } = useJumboNavbarContext();
  return <span>{navItems.length} items</span>;
}

Groups automatically render expand/collapse chevrons. The open state is managed internally by JumboNavbarProvider. To set a group as expanded by default, pass defaultOpen: true on the group item (if using a custom nav tree), or rely on the current-route detection built into the navbar implementation.