Component
navigation menu
dx components add navigation_menuA collection of links and disclosure panels for site navigation.
Installation
Use the CLI command for the common path, or copy the component files manually.
Manual installation files
Copy the component source and CSS into your app. Import the shared theme CSS once near your app root.
use dioxus::prelude::*;
use dioxus_icons::lucide::ChevronDown;
use dioxus_primitives::navigation_menu::{
self, NavigationMenuContentProps, NavigationMenuItemProps, NavigationMenuLinkProps,
NavigationMenuListProps, NavigationMenuProps, NavigationMenuTriggerProps,
};
#[component]
pub fn NavigationMenu(props: NavigationMenuProps) -> Element {
rsx! {
document::Link { rel: "stylesheet", href: asset!("/src/components/navigation_menu/style.css") }
navigation_menu::NavigationMenu {
class: "dx-navigation-menu",
disabled: props.disabled,
attributes: props.attributes,
{props.children}
}
}
}
#[component]
pub fn NavigationMenuList(props: NavigationMenuListProps) -> Element {
rsx! {
document::Link { rel: "stylesheet", href: asset!("/src/components/navigation_menu/style.css") }
navigation_menu::NavigationMenuList {
class: "dx-navigation-menu-list",
attributes: props.attributes,
{props.children}
}
}
}
#[component]
pub fn NavigationMenuItem(props: NavigationMenuItemProps) -> Element {
rsx! {
document::Link { rel: "stylesheet", href: asset!("/src/components/navigation_menu/style.css") }
navigation_menu::NavigationMenuItem {
class: "dx-navigation-menu-item",
index: props.index,
disabled: props.disabled,
attributes: props.attributes,
{props.children}
}
}
}
#[component]
pub fn NavigationMenuTrigger(props: NavigationMenuTriggerProps) -> Element {
rsx! {
document::Link { rel: "stylesheet", href: asset!("/src/components/navigation_menu/style.css") }
navigation_menu::NavigationMenuTrigger {
class: "dx-navigation-menu-trigger",
id: props.id,
attributes: props.attributes,
{props.children}
ChevronDown {
class: "dx-navigation-menu-expand-icon",
size: "16px",
stroke: "currentColor",
}
}
}
}
#[component]
pub fn NavigationMenuContent(props: NavigationMenuContentProps) -> Element {
rsx! {
document::Link { rel: "stylesheet", href: asset!("/src/components/navigation_menu/style.css") }
navigation_menu::NavigationMenuContent {
class: "dx-navigation-menu-content",
id: props.id,
attributes: props.attributes,
{props.children}
}
}
}
#[component]
pub fn NavigationMenuLink(props: NavigationMenuLinkProps) -> Element {
rsx! {
document::Link { rel: "stylesheet", href: asset!("/src/components/navigation_menu/style.css") }
navigation_menu::NavigationMenuLink {
class: "dx-navigation-menu-link",
active: props.active,
disabled: props.disabled,
content_index: props.content_index,
onclick: props.onclick,
attributes: props.attributes,
{props.children}
}
}
}Usage notes
The NavigationMenu component displays a collection of links and disclosure panels for site navigation.
Unlike Navbar, which implements the APG Menu and
Menubar pattern (role="menubar"/"menu"/"menuitem", roving tabindex),
NavigationMenu implements the APG Disclosure (Show/Hide) Navigation
pattern: plain links and button[aria-expanded][aria-controls] disclosure
triggers, with no menu role anywhere. Every trigger and link keeps its
native tab stop, so Tab/Shift+Tab move through them (and, once a panel is
open, through its links) in DOM order -- there is no roving-focus
collection to manage. Use this component for real site navigation; use
Navbar (or Menubar) when you need the fuller
menu-button keyboard contract.
Component Structure
// The NavigationMenu component wraps the whole nav landmark. It needs an
// accessible name -- pass `aria_label` or `aria_labelledby`.
NavigationMenu {
aria_label: "Main",
// The NavigationMenuList is the `ul` that holds the top-level items.
NavigationMenuList {
// Each NavigationMenuItem is one top-level entry, in order of its index.
NavigationMenuItem {
index: 0usize,
// A trigger discloses a panel of links on click or hover.
NavigationMenuTrigger { "Components" }
NavigationMenuContent {
// Compose any markup here -- typically a grid of links.
NavigationMenuLink { href: "/component/?name=accordion", "Accordion" }
NavigationMenuLink { href: "/component/?name=dialog", "Dialog" }
}
}
NavigationMenuItem {
index: 1usize,
// Or an item can be a single plain link with no panel.
NavigationMenuLink { href: "/docs", "Docs" }
}
}
}Keyboard interaction
Enter/Space: activates a focused trigger, toggling its panel.Escape: closes the open panel and returns focus to its trigger.Tab/Shift+Tab: move through every top-level trigger/link, and (once a panel is open) through its links, in page order.Left/Rightarrow (optional in APG, supported here): move between top-level items.Home/End(optional in APG, supported here): move to the first/last top-level item.Downarrow on a trigger: opens its panel (if not already open) and moves focus into its first link.Up/Downarrow on a link inside an open panel (optional in APG, supported here): move to the previous/next link in that panel, stopping at the first/last link rather than wrapping.- Moving focus out of the whole navigation menu closes an open panel.