Side Navigation
- Usage
- Styling
- Automatic Highlighting of Current Item
- Prefix & Suffix Elements
- Hierarchy
- Labeled Collapsible List
- Another Browser Tab or Window
- Scrolling
- Keyboard Usage
- Styling Individual Items
- Client-Side Router Integration
Side Navigation provides a vertical list of navigation links with support for collapsible, nested sections.
Note
|
Navigation Disabled in Examples
For technical reasons, actual navigation is disabled in the examples on this page. |
new tab
SideNav nav = new SideNav();
SideNavItem dashboardLink = new SideNavItem("Dashboard",
DashboardView.class, VaadinIcon.DASHBOARD.create());
SideNavItem inboxLink = new SideNavItem("Inbox", InboxView.class,
VaadinIcon.ENVELOPE.create());
SideNavItem calendarLink = new SideNavItem("Calendar",
CalendarView.class, VaadinIcon.CALENDAR.create());
SideNavItem settingsLink = new SideNavItem("Settings",
SettingsView.class, VaadinIcon.COG.create());
SideNavItem vaadinLink = new SideNavItem("Vaadin website",
"https://vaadin.com", VaadinIcon.VAADIN_H.create());
nav.addItem(dashboardLink, inboxLink, calendarLink, settingsLink,
vaadinLink);
The Side Navigation component can be used, for example, in a drawer of an App Layout.
Automatic Highlighting of Current Item
The navigation item matching the current URL is highlighted automatically to indicate it’s active.
Nested Matching
By default, items only match the exact path of the current URL. To enable matching of nested paths or routes, set the matchNested
property to true
. With nested matching, an item with the path /parent
not only matches /parent
, but also /parent/child
, /parent/child/grandchild
, etc.
SideNavItem item = new SideNavItem("Users", "/users");
item.setMatchNested(true);
Query Parameters
If an item’s path contains query parameters, only URLs containing those parameters are considered a match. Additional parameters in the URL not specified in the item path are ignored — the URL is considered a match.
Prefix & Suffix Elements
Navigation items have slots for prefix and suffix elements. The prefix slot is intended primarily for icons, while the suffix slot can be used, for example, for notification badges.
Interactive prefix and suffix elements aren’t recommended since the entire item row acts as a link.
new tab
SideNav nav = new SideNav();
SideNavItem inboxLink = new SideNavItem("Inbox", InboxView.class,
VaadinIcon.ENVELOPE.create());
Span inboxCounter = new Span("12");
inboxCounter.getElement().getThemeList().add("badge contrast pill");
inboxCounter.getElement().setAttribute("aria-label",
"12 unread messages");
inboxLink.setSuffixComponent(inboxCounter);
SideNavItem calendarLink = new SideNavItem("Calendar",
CalendarView.class, VaadinIcon.CALENDAR.create());
Icon calendarNotification = VaadinIcon.BELL.create();
calendarNotification.getElement().getThemeList()
.add("badge error pill");
calendarNotification.getStyle().set("padding", "var(--lumo-space-xs");
calendarNotification.getElement().setAttribute("aria-label",
"Upcoming appointment");
calendarLink.setSuffixComponent(calendarNotification);
nav.addItem(inboxLink, calendarLink);
Hierarchy
Navigation items can contain sub-items, which are collapsed by default. There’s no technical limitation on the number of nesting levels. However, a maximum of three levels is recommended for better usability.
Parent items can be links. Clicking them expands their sub-items in addition to navigating. Non-link parent items can be achieved by omitting the target path.
new tab
SideNav nav = new SideNav();
SideNavItem messagesLink = new SideNavItem("Messages",
MessagesView.class, VaadinIcon.ENVELOPE.create());
messagesLink.addItem(new SideNavItem("Inbox", InboxView.class,
VaadinIcon.INBOX.create()));
messagesLink.addItem(new SideNavItem("Sent", SentView.class,
VaadinIcon.PAPERPLANE.create()));
messagesLink.addItem(new SideNavItem("Trash", TrashView.class,
VaadinIcon.TRASH.create()));
SideNavItem adminSection = new SideNavItem("Admin");
adminSection.setPrefixComponent(VaadinIcon.COG.create());
adminSection.addItem(new SideNavItem("Users", UsersView.class,
VaadinIcon.GROUP.create()));
adminSection.addItem(new SideNavItem("Permissions",
PermissionsView.class, VaadinIcon.KEY.create()));
nav.addItem(messagesLink, adminSection);
Labeled Collapsible List
A label can be applied to the top of the navigation list. This can be useful for cases with multiple adjacent Side Navigation lists. A labeled Side Navigation list can be made collapsible.
new tab
SideNav messagesNav = new SideNav();
messagesNav.setLabel("Messages");
messagesNav.addItem(new SideNavItem("Inbox", InboxView.class,
VaadinIcon.INBOX.create()));
messagesNav.addItem(new SideNavItem("Sent", SentView.class,
VaadinIcon.PAPERPLANE.create()));
messagesNav.addItem(new SideNavItem("Trash", TrashView.class,
VaadinIcon.TRASH.create()));
SideNav adminNav = new SideNav();
adminNav.setLabel("Admin");
adminNav.setCollapsible(true);
adminNav.addItem(new SideNavItem("Users", UsersView.class,
VaadinIcon.GROUP.create()));
adminNav.addItem(new SideNavItem("Permissions", PermissionsView.class,
VaadinIcon.KEY.create()));
Another Browser Tab or Window
A navigation link can be opened in another browser tab or window — depending on the browser’s configuration — by specifying the name of the tab or window as the link’s target. A new, unnamed tab or window can be set as the target by providing the name _blank
, for which the Flow API provides the shorthand method setOpenInNewBrowserTab()
.
SideNavItem item = new SideNavItem("Example", "https://example.com");
item.setOpenInNewBrowserTab(true);
Scrolling
The Side Navigation component doesn’t contain a scroll area. Instead, it can be made scrollable by wrapping it inside a Scroller.
Keyboard Usage
Shortcut | Function |
---|---|
Tab | Navigation between list items. |
Tab | Navigation between link and expand and collapse button. |
Enter / Space | Toggles expand and collapse. |
Enter | Trigger link. |
Styling Individual Items
Individual navigation items can be styled by applying a CSS class name to them.
new tab
SideNav nav = new SideNav();
SideNavItem dashboardLink = new SideNavItem("Dashboard",
DashboardView.class, VaadinIcon.DASHBOARD.create());
SideNavItem inboxLink = new SideNavItem("Inbox", InboxView.class,
VaadinIcon.ENVELOPE.create());
SideNavItem vaadinLink = new SideNavItem("Vaadin website",
"https://vaadin.com", VaadinIcon.VAADIN_H.create());
vaadinLink.addClassName("external");
nav.addItem(dashboardLink, inboxLink, vaadinLink);
Client-Side Router Integration
By default, clicking a navigation link in a client-side application triggers a full page reload. When using a client-side router (e.g., React Router), this might be undesirable as it disrupts the single-page application experience.
To prevent this behavior, you can assign a callback function to the Side Navigation component’s onNavigate
property. That would cancel the default action on a link click and delegate the responsibility of navigation to the provided function. The function receives an object with properties of the clicked navigation item, including path
, which can be used to navigate to the desired route.
Additionally, the Side Navigation component needs to be notified of route changes to have it automatically highlight the currently active item. This can be achieved by updating the Side Navigation component’s location
property whenever the route changes.
The following example demonstrates how to integrate the <SideNav>
component with React Router:
const navigate = useNavigate();
const location = useLocation();
return (
<SideNav
location={location}
onNavigate={({ path }) => {
if (path) {
navigate(path);
}
}}
>
<SideNavItem path="/inbox">Inbox</SideNavItem>
<SideNavItem path="/calendar">Calendar</SideNavItem>
</SideNav>
);
10387B24-0DDF-4FC8-B5F9-B6319633D354