TabNav
Underlined tabs that go to other pages, marking the current one, with the links that don't fit in a menu.
import { TabNav } from "@butteryui/react";Demo
When to use it
Use it for
- Views of a list that each have their own address, such as All, Open and Shipped orders
- Sections of settings that are pages of their own
Not for
- Panels on the same page: use Tabs
- Sections down a long page: use SubNav
Examples
Order views
Order views as pages: each tab is a link, and the page shown is marked.
Showing all 128 orders
Orders page
A page header whose views are tabs that go to pages, over the orders in the view picked.
Orders
4Order 1042 · 2 bags of house blend
Order 1041 · 1 bag of decaf
Order 1040 · A tasting set
Order 1039 · 3 bags of single origin
Router links
A router's own links as tabs, with asChild and a label for the overflow menu.
Variants and states
Pages as tabs
The underline slides to the page shown, marked aria-current.
Props
TabNav
| Prop | Type | Default | Description |
|---|---|---|---|
labelrequired | string | Names the navigation for screen readers, such as "Order views". | |
moreLabel | string | "More pages" | Names the button that lists the links that don't fit. Defaults to "More pages". |
It also takes Omit<ComponentPropsWithRef<"nav">, "aria-label">.
TabNav.Link
| Prop | Type | Default | Description |
|---|---|---|---|
current | boolean | Whether this link is the page shown. | |
asChild | boolean | Render the single child element, such as a router's link, with the tab's look merged in. | |
childrenrequired | string | ReactElement | With asChild={false}: The link's text. It's also its entry in the "…" menu once it doesn't fit. With asChild={true}: The router's link, holding the text. | |
label | string | With asChild={true}: The link's text for its entry in the "…" menu once it doesn't fit. |
It also takes Omit<ComponentPropsWithRef<"a">, "children">.
Accessibility
A navigation named by its label; the current link has aria-current="page". Tab moves along the links. Links folded into the menu stay reachable from the More pages button, and choosing one follows it.
| Keys | What they do |
|---|---|
| Tab | Moves along the links, then to the More pages button once some have folded into it |
| Enter | Follows the focused link |
| Enter, Space or Arrow Down | Opens the More pages menu from its button |
| Arrow Down or Arrow Up | Moves through the folded links in the menu |
| Enter or Space | Follows the folded link focused in the menu |
| Escape | Closes the menu and puts focus back on its button |
Motion
Its selection indicator slides to the chosen option on `spring.snappy`, inside one track.
With reduced motion: The underline appears under the current page's link at once instead of sliding there.
Layout
It fills its container's width over a 1px line. Its links are --bt-h-button (36px) tall and 16px apart, each as wide as its text and padding and each wholly its own hit area; they never wrap or truncate: the ones that don't fit fold into the More pages menu at the end, last ones first, and the current page's link stays in the row.
Related
See it in the roastery demo's wholesale.