JumboNavbar

JumboNavbar renders the hierarchical navigation tree inside the sidebar. It reads navigation data from JumboNavbarProvider and supports three item types: sections (top-level grouping labels), groups (collapsible submenus), and items (leaf links).

Import

typescript
import { JumboNavbar, JumboNavbarProvider } from '@jumbo/components';
import type { NavbarItem, NavbarGroup, NavbarSection } from '@jumbo/types';

JumboNavbarProvider

Provides the navigation data array to all JumboNavbar instances in the tree.

Props

PropTypeRequiredDescription
menus(NavbarItem | NavbarGroup | NavbarSection)[]YesFlat or nested menu data
childrenReactNodeYesLayout subtree

Usage

tsx
// src/layouts/StretchedLayout/Sidebar/Sidebar.tsx
import { JumboNavbar, JumboNavbarProvider } from '@jumbo/components';
 
type SidebarProps = {
  menus: (NavbarItem | NavbarGroup | NavbarSection)[];
};
 
export function Sidebar({ menus }: SidebarProps) {
  return (
    <JumboNavbarProvider menus={menus}>
      <JumboNavbar />
    </JumboNavbarProvider>
  );
}

Menu data is defined in src/layouts/<LayoutName>/menus.ts and passed through the layout component to <Sidebar>.

typescript
interface NavbarItem {
  label: string;       // Visible nav label
  path: string;        // React Router path
  icon?: ReactNode;    // Optional icon
  type?: string;       // Optional item type hint
}
typescript
interface NavbarGroup {
  label: string;
  icon?: ReactNode;
  collapsible: true;
  children: (NavbarItem | NavbarGroup)[];
}
typescript
interface NavbarSection {
  label: string;
  children: (NavbarItem | NavbarGroup)[];
}
typescript
// src/layouts/StretchedLayout/menus.ts (excerpt)
import DashboardOutlinedIcon from '@mui/icons-material/DashboardOutlined';
 
export const getMenus = () => [
  {
    label: 'Dashboards',
    icon: <DashboardOutlinedIcon />,
    collapsible: true,
    children: [
      { label: 'Misc',      path: '/dashboards/misc' },
      { label: 'CRM',       path: '/dashboards/crm' },
      { label: 'Intranet',  path: '/dashboards/intranet' },
      { label: 'Ecommerce', path: '/dashboards/ecommerce' },
    ],
  },
  {
    label: 'Apps',
    collapsible: true,
    children: [
      { label: 'Chat',      path: '/apps/chats' },
      { label: 'Contacts',  path: '/apps/contacts' },
      { label: 'Mail',      path: '/apps/mail/inbox' },
    ],
  },
];

Nav item colors are configured via the jumboComponents.JumboNavbar extension on the sidebar sub-theme. Override them in src/themes/sidebar/default.ts:

typescript
// src/themes/sidebar/default.ts (excerpt)
export const sidebarTheme = {
  jumboComponents: {
    JumboNavbar: {
      colors: {
        nav: 'rgba(255,255,255,0.7)',
        navHover: '#FFFFFF',
        navActive: '#7352C7',
        subMenuColor: 'rgba(255,255,255,0.6)',
        subMenuHoverColor: '#FFFFFF',
        subMenuHoverBg: 'rgba(255,255,255,0.08)',
        subMenuActiveBg: 'rgba(115,82,199,0.2)',
      },
    },
  },
};

Type guards

@jumbo/utilities/helpers exports type guard functions for narrowing union nav types:

typescript
import { isNavItem, isNavGroup, isNavSection } from '@jumbo/utilities/helpers';
 
menus.forEach((item) => {
  if (isNavItem(item))    { /* item.path is available */ }
  if (isNavGroup(item))   { /* item.collapsible and item.children are available */ }
  if (isNavSection(item)) { /* item.children is available, no collapsible */ }
});