Skip to main content

Nav rail

<zeno-nav-rail>NavigationSource

A vertical navigation bar that can collapse to icons.

import '@usezeno/tokens/css';
import '@usezeno/core/web-components';

Examples​

Basic rail​

Set items and activeItem as properties. The rail fires item-select when an item is chosen.

Nothing selected yet.

<zeno-nav-rail></zeno-nav-rail>
<p data-result>Nothing selected yet.</p>
const rail = document.querySelector('zeno-nav-rail');
rail.items = [
{ id: 'home', value: 'home', label: 'Home', icon: 'home' },
{ id: 'search', value: 'search', label: 'Search', icon: 'search' },
{ id: 'saved', value: 'saved', label: 'Saved', icon: 'heart' },
{ id: 'settings', value: 'settings', label: 'Settings', icon: 'settings' },
];
rail.activeItem = 'home';
rail.addEventListener('item-select', event => {
document.querySelector('[data-result]').textContent = 'Selected: ' + event.detail.value;
});

Expanded, with sections and a badge​

With expanded the rail is wider and shows the labels. Items with the same section are listed under that title.

<zeno-nav-rail expanded></zeno-nav-rail>
const rail = document.querySelector('zeno-nav-rail');
rail.items = [
{ id: 'home', value: 'home', label: 'Home', icon: 'home', section: 'Workspace' },
{ id: 'saved', value: 'saved', label: 'Saved', icon: 'star', badge: 3, section: 'Workspace' },
{ id: 'profile', value: 'profile', label: 'Profile', icon: 'user', section: 'Account' },
{ id: 'settings', value: 'settings', label: 'Settings', icon: 'settings', section: 'Account' },
];
rail.activeItem = 'saved';

The toggle button​

The button at the top switches expanded and fires toggle. Set the showToggle property to false to remove it.

The rail is collapsed.

<zeno-nav-rail></zeno-nav-rail>
<p data-result>The rail is collapsed.</p>
const rail = document.querySelector('zeno-nav-rail');
rail.items = [
{ id: 'home', value: 'home', label: 'Home', icon: 'home' },
{ id: 'profile', value: 'profile', label: 'Profile', icon: 'user' },
];
rail.activeItem = 'home';
rail.addEventListener('toggle', event => {
document.querySelector('[data-result]').textContent =
event.detail.expanded ? 'The rail is expanded.' : 'The rail is collapsed.';
});

Attributes and properties​

PropertyAttributeTypeDefaultDescription
itemsitemsNavRailItem[][]
activeItemactiveitemstring''
expandedexpandedreflectsbooleanfalse
showToggleshow-togglereflectsbooleantrue
testIdstringTest ID for automated testing From ZenoElement.

Methods​

MethodDescription
toggleExpanded(): voidToggle expanded state
selectItem(value: string): voidSelect an item
focus(): voidFocus the component or its first focusable element From ZenoElement.
blur(): voidBlur the component or its focused element From ZenoElement.

Events​

EventDetailDescription
toggle{ expanded: boolean }The rail was expanded or collapsed.
item-select{ value: string; item: NavRailItem }An item was selected.

Slots​

SlotDescription
footerContent below the items.
headerContent above the items.

CSS parts​

Part
badge
base
footer
header
icon
item
items
label
link
list
section
section-list
section-title
toggle
tooltip

CSS custom properties​

This element documents no custom properties of its own. Style it through its parts and through the tokens it reads.

The element's own source reads no tokens.

Types​

interface NavRailItem {
id: string;
value: string;
label: string;
icon?: string;
href?: string;
target?: string;
rel?: string;
section?: string;
disabled?: boolean;
badge?: string | number;
}

Accessibility​

Keyboard​

KeyWhat it does
TabMoves focus to the toggle button, then to each item in turn. Every item is a Tab stop.
EnterSpaceOn the toggle button, expands or collapses the rail. On an item, selects it. Enter on an item with href follows the link.
ArrowDownArrowUpSelects the next or previous item and moves focus to it. Wraps at both ends.
HomeEndSelects the first or last item and moves focus to it.

Forms​

This element is not a form control. It adds nothing to a form's data.

Notes​

  • Renders a <nav> landmark. It is named by the aria-label of the element, or “Navigation rail” when there is none.
  • Items are native links when they have href and native buttons when they do not, inside nested lists.
  • The active link has aria-current="page" and the active button has aria-current="true".
  • The toggle button has aria-expanded and is named “Expand navigation” or “Collapse navigation”.
  • With reduced motion the rail has no transitions. The rail is hidden when the page is printed.

Tests and known gaps​

  • No tests of its own. The only check is that the element registers and renders (smoke.test.ts).
  • Not checked with axe-core.
  • Has no Storybook story.
19 of the 28 properties, methods, events, slots and parts above have no description in the source
  • the property items
  • the property activeItem
  • the property expanded
  • the property showToggle
  • the part badge
  • the part base
  • the part footer
  • the part header
  • the part icon
  • the part item
  • the part items
  • the part label
  • the part link
  • the part list
  • the part section
  • the part section-list
  • the part section-title
  • the part toggle
  • the part tooltip

Known gaps:

  • Each link or button is rendered empty. The icon, label and badge are placed after it, not inside it. The control has no accessible name, a click on the icon or label does nothing, and the item looks like an empty box with its content under it.
  • The tooltip of a collapsed rail never shows, because it is not inside the link that the hover style looks at.
  • In a collapsed rail the labels are removed with display: none. Together with the two gaps above, items have no name at all for assistive technology.
  • The arrow keys go to the wrong item when the rail has sections or disabled items. The handler mixes three different ways of counting the items.
  • The arrow keys, Home and End select the item they move to. In a rail of links this changes activeItem and fires item-select without loading the page of that link.
  • A disabled item is only dimmed and closed to the pointer. It is still a Tab stop and is not announced as disabled.
  • show-toggle is on by default and a Boolean attribute cannot turn it off. Only the property showToggle = false works.
  • The header slot is removed together with the toggle button when showToggle is false.
  • The attribute for activeItem is activeitem, with no dash. The other attributes of the element use dashes.
  • Buttons that are not active carry aria-current="false". The attribute should be left out.
  • Item icons only work for the names zeno-icon has built in or the page has registered. The sizes 24 and 20 that the rail asks for do not exist in zeno-icon.
  • “Navigation rail”, “Expand navigation” and “Collapse navigation” are English only. Only the first can be replaced, with aria-label.
  • The width does not animate when the rail expands or collapses. The transition value is not valid CSS.
  • The border, the active marker, the badge and the tooltip are placed with left and right. They do not follow a right-to-left page.