Tangible Design System · @tangible/ui 0.2.29 · Interactive version · Markdown

NavMenu

import { NavMenu } from '@tangible/ui';

Interactive docs and examples: NavMenu in Storybook.

NavMenu props

Prop Type Default Description
children ReactNode
flyoutTrigger? "click" | "hover" 'click' How a horizontal bar's flyouts open. click (default): click or Enter/Space. hover: also opens for a mouse once the pointer settles on an item (hover intent, as in WordPress's Toolbar: under 6px of movement in 100ms), so sweeping across the bar opens nothing. Once primed (a panel is open, or one just closed), the next opens at once. There's a grace period for crossing into the panel. Escape dismisses it until the pointer leaves (WCAG 1.4.13); clicking pins it open. Touch and keyboard behave as click either way.
labels? NavMenuLabels Visually hidden strings.
orientation? "horizontal" | "vertical" 'vertical' vertical (sidebars) stacks groups and nests a NavMenu.Sub inline. horizontal makes a bar: groups become inline clusters (headings visually hidden, lists still labelled), and an item with a NavMenu.Sub opens it as a flyout. A flyout follows the APG disclosure pattern: a button with aria-expanded, opened by click or Enter/Space (never hover), closed by Escape (focus returns to the button), Tab-ing out or clicking elsewhere. One flyout is open at a time. Groups inside a flyout show their headings.

Also accepts the standard attributes of HTMLAttributes (data-*, aria-*, event handlers), passed to the element it renders.

NavMenu.Group

Prop Type Default Description
children ReactNode
label? ReactNode Visible group heading, styled with the overline text style. It names the group's list via aria-labelledby. Omit it for an unlabelled group.
labelAs? "h2" | "h3" | "h4" | "h5" | "h6" | "span" 'h2' Element for the heading. Pick the level that fits the page outline; use 'span' when headings would be noise (the list stays labelled either way).

Also accepts the standard attributes of HTMLAttributes (data-*, aria-*, event handlers), passed to the element it renders.

NavMenu.Item

Prop Type Default Description
children ReactNode The label, plus an optional NavMenu.Sub of nested items. Vertical: the Sub renders after the link, inside the same list item, and whether it renders at all is up to you (e.g. only while its parent is current). Horizontal: the Sub is a flyout. With no href, the row itself toggles it; with an href (or asChild link), the row navigates and a separate toggle button opens it.
asChild? true Only in some variants; the others reject it.
current? "date" | "location" | "page" | "step" | "time" | "true" | boolean Marks the current item; see NavMenuCurrent.
disabled? boolean Inert item: rendered as a disabled link (role="link", aria-disabled, no href), out of the tab order. For destinations that exist but aren't available yet.
href? string Only in some variants; the others reject it.
icon? IconName Leading icon, from the registry. Sized by --tui-nav-menu-icon-size.
prefix? ReactNode Custom leading content in the icon's place (an avatar, a glyph not in the registry). Replaces icon when both are set. Unlike icon, it isn't hidden from assistive tech: mark decorative content aria-hidden yourself, or its text joins the name. A shape drawn with CSS background disappears in forced colors; give it a border if it carries meaning.
suffix? ReactNode Trailing content pushed to the row's inline end: a badge, a count. It sits inside the row, so its text joins the accessible name: give a bare number context, so 3 <span class="tui-visually-hidden">unread</span> reads "Inbox 3 unread" (put the space outside the hidden span). Must not be interactive (no buttons or links): a control nested in a link is invalid. Both slots reach the name only through the row's content, so don't pass aria-label/aria-labelledby to an item with a slot: either replaces the whole name. On a row that is itself the flyout's disclosure button, the suffix is part of the button's name; on a split row it belongs to the link (the destination), and the toggle stays "Reports submenu".

Also accepts the standard attributes of AnchorHTMLAttributes and ButtonHTMLAttributes (data-*, aria-*, event handlers), passed to the element it renders.

NavMenu.Sub

Prop Type Default Description
children ReactNode

Also accepts the standard attributes of HTMLAttributes (data-*, aria-*, event handlers), passed to the element it renders.

Other exports

Examples

Component API tokens

Read via fallback, never declared. Set one on an ancestor to restyle every instance under it.