Navigation Menu
A horizontal row of triggers and links that open portaled content panels for site navigation.
Basic
Show codeHide code
import {
NavigationMenu,
NavigationMenuContent,
NavigationMenuContentList,
NavigationMenuItem,
NavigationMenuLink,
NavigationMenuLinkDescription,
NavigationMenuLinkTitle,
NavigationMenuList,
NavigationMenuPanel,
NavigationMenuTrigger,
NavigationMenuViewport,
} from "@makeplane/propel/components/navigation-menu";
const PRODUCT_LINKS = [
{ href: "#issues", title: "Issues", description: "Track work items across projects." },
{ href: "#cycles", title: "Cycles", description: "Time-boxed sprints for your team." },
{ href: "#modules", title: "Modules", description: "Group related work into modules." },
{ href: "#pages", title: "Pages", description: "Rich documents that live with your work." },
];
const RESOURCE_LINKS = [
{ href: "#docs", title: "Documentation", description: "Guides and API references." },
{ href: "#changelog", title: "Changelog", description: "What shipped recently." },
];
export default function BasicDemo() {
return (
<NavigationMenu>
<NavigationMenuList>
<NavigationMenuItem>
<NavigationMenuTrigger label="Product" />
<NavigationMenuContent>
<NavigationMenuContentList>
{PRODUCT_LINKS.map((item) => (
<li key={item.href}>
<NavigationMenuLink href={item.href} presentation="card">
<NavigationMenuLinkTitle>{item.title}</NavigationMenuLinkTitle>
<NavigationMenuLinkDescription>
{item.description}
</NavigationMenuLinkDescription>
</NavigationMenuLink>
</li>
))}
</NavigationMenuContentList>
</NavigationMenuContent>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuTrigger label="Resources" />
<NavigationMenuContent>
<NavigationMenuContentList>
{RESOURCE_LINKS.map((item) => (
<li key={item.href}>
<NavigationMenuLink href={item.href} presentation="card">
<NavigationMenuLinkTitle>{item.title}</NavigationMenuLinkTitle>
<NavigationMenuLinkDescription>
{item.description}
</NavigationMenuLinkDescription>
</NavigationMenuLink>
</li>
))}
</NavigationMenuContentList>
</NavigationMenuContent>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuLink href="#pricing" presentation="item">
Pricing
</NavigationMenuLink>
</NavigationMenuItem>
</NavigationMenuList>
<NavigationMenuPanel>
<NavigationMenuViewport />
</NavigationMenuPanel>
</NavigationMenu>
);
}Presentations
A link’s presentation sets its shape: item is a top-level pill beside the triggers, while card stacks a title over an optional description inside a content panel.
Show codeHide code
import {
NavigationMenu,
NavigationMenuItem,
NavigationMenuLink,
NavigationMenuLinkDescription,
NavigationMenuLinkTitle,
NavigationMenuList,
} from "@makeplane/propel/components/navigation-menu";
export default function PresentationsDemo() {
return (
<NavigationMenu>
<NavigationMenuList>
<NavigationMenuItem>
<NavigationMenuLink href="#pricing" presentation="item">
Pricing
</NavigationMenuLink>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuLink href="#docs" presentation="card">
<NavigationMenuLinkTitle>Documentation</NavigationMenuLinkTitle>
<NavigationMenuLinkDescription>
Guides and API references.
</NavigationMenuLinkDescription>
</NavigationMenuLink>
</NavigationMenuItem>
</NavigationMenuList>
</NavigationMenu>
);
}Large content
Cap the content region’s height and wrap the link list in a ScrollArea so the panel keeps a stable size while long menus scroll.
Show codeHide code
import {
NavigationMenu,
NavigationMenuContent,
NavigationMenuContentList,
NavigationMenuItem,
NavigationMenuLink,
NavigationMenuLinkTitle,
NavigationMenuList,
NavigationMenuPanel,
NavigationMenuTrigger,
NavigationMenuViewport,
} from "@makeplane/propel/components/navigation-menu";
import { ScrollArea } from "@makeplane/propel/components/scroll-area";
const PROJECT_LINKS = Array.from({ length: 24 }, (_, index) => ({
href: `#project-${index + 1}`,
title: `Project ${index + 1}`,
}));
export default function LargeContentDemo() {
return (
<NavigationMenu>
<NavigationMenuList>
<NavigationMenuItem>
<NavigationMenuTrigger label="Projects" />
<NavigationMenuContent>
<div className="flex h-72 flex-col">
<ScrollArea orientation="vertical" visibility="auto" magnitude="thin">
<NavigationMenuContentList>
{PROJECT_LINKS.map((item) => (
<li key={item.href}>
<NavigationMenuLink href={item.href} presentation="card">
<NavigationMenuLinkTitle>{item.title}</NavigationMenuLinkTitle>
</NavigationMenuLink>
</li>
))}
</NavigationMenuContentList>
</ScrollArea>
</div>
</NavigationMenuContent>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuLink href="#pricing" presentation="item">
Pricing
</NavigationMenuLink>
</NavigationMenuItem>
</NavigationMenuList>
<NavigationMenuPanel>
<NavigationMenuViewport />
</NavigationMenuPanel>
</NavigationMenu>
);
}Installation
import {
NavigationMenu,
NavigationMenuContent,
NavigationMenuContentList,
NavigationMenuItem,
NavigationMenuLink,
NavigationMenuLinkDescription,
NavigationMenuLinkTitle,
NavigationMenuList,
NavigationMenuPanel,
NavigationMenuTrigger,
NavigationMenuViewport,
} from "@makeplane/propel/components/navigation-menu";
Props
NavigationMenu
| Prop | Type | Required | Description |
|---|---|---|---|
| render | ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, NavigationMenuRootState> | No | Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render. |
NavigationMenuTrigger
| Prop | Type | Required | Description |
|---|---|---|---|
| render | ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, NavigationMenuTriggerState> | No | Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render. |
| icon | ReactNode | No | Replaces the default disclosure caret (a down chevron) in the trigger's `Icon` slot. |
| label | string | Yes | Visible trigger label. |