Krizaka UI
Krizaka UI
Components

Rail nav

The compact navigation of an application: a vertical rail of icons on a desktop — the product's mark on top, a tooltip on each icon, an accent bar on the current one, a footer for settings and the account — that becomes a bottom tab bar on a phone. Paired with AppHeader, which carries the product's name (and, on a phone, its mark).

Web · ✓Mobile · n/aDesktop · ✓BetaNavigation
import { RailNav } from "@krizaka/ui/rail-nav";

Web only — React, from @krizaka/ui/rail-nav. Beta: its API may still change in a minor version.

  • Mobile · n/a. On a phone the rail is already a bottom tab bar; a native app uses the TabBar. → Tab bar

Why it is here. Used by Orazaka, Yomizaka, Akinaza.

When to use

  • An application with three to eight destinations the user works in all day (Home, Studios, Chat, Jobs, Settings) and little else in the way: the rail leaves the screen to the work.
  • When the same sections must read as a vertical rail on a desktop and as tabs on a phone, written once.

When not to use

  • Grouped sections, counts and a collapsing sidebar of words, a console with shortcuts.Use instead: App shell
  • A public site's pages.Use instead: Nav bar
  • A native mobile app.Use instead: Tab bar
  • Views of one screen.Use instead: Tabs

Installation

Install

npm install @krizaka/ui @krizaka/tailwind @krizaka/tokens tailwindcss

Styles

@import "tailwindcss";
@import "@krizaka/tailwind";
@import "@krizaka/ui/tailwind.css";

Import

import { RailNav } from "@krizaka/ui/rail-nav";

Examples

A studio

Orazaka's signed-in app: the mark on top of the rail, five sections with the current one lit, settings at the foot, the header with the name and a status chip.

Shortcuts and the family's bar

Akinaza's frame: the rail with a « Shortcuts » group above the expand toggle, expanded from 1280 px, and the family's top bar — search, notifications with a count, the account with its name from 1024 px.

Expandable

The same rail with a button that widens it to show the words, for users who do not know the icons yet.

Props

RailNavRoot

The rail: a vertical column of icons on a desktop, a bottom tab bar on a phone.

PropTypeDefaultDescription
childrenrequiredReactNode—The main destinations: RailNav.Item, the ones you work in. Five at most so that they fit a phone's tab bar.
labelrequiredstring—The navigation's accessible name (Orazaka, Studio).
accentBrandId—The product's brand: scopes its colours (brand-orazaka…) over the rail, so the accent follows. Omit it inside a page that already wears the brand.
defaultExpandedboolean—The starting width when uncontrolled. Unset: expanded from 1280 px (the words fit there), narrow below — until the person toggles it.
expandableboolean—Adds a button that widens the rail to show the words (desktop only). Needs expandLabels.
expandedboolean—Controlled width (pair with onExpandedChange to keep the choice).
expandLabelsreadonly [string, string]—The toggle's words, [expand, collapse].
footerReactNode—At the foot of the rail (settings, account), after the main items; on a phone they follow them in the same bar. RailNav.Items or a control with data-rail-item.
markReactNode—The product's mark on top of the rail, as a link home (<Link href="/"><ProductLogo id="orazaka" /></Link>); named by the app (its aria-label). Hidden on a phone: AppHeader shows it there.
onExpandedChange((expanded: boolean) => void)—Called when the toggle widens or narrows the rail.
shortcutsReactNode—The product's shortcuts (RailNav.Items: a saved view, a client, « New invoice »), a group above the footer and the expand toggle. Desktop only: a phone's tab bar keeps its destinations.
shortcutsLabelstring—The shortcuts' heading (« Raccourcis », « Shortcuts ») — passed translated: the group's name, shown once the rail is expanded.

RailNavItem

A destination of the rail.

PropTypeDefaultDescription
iconrequiredReactNode—The item's icon (a signature icon of @krizaka/icons): all that shows on a desktop rail.
labelrequiredstring—Its words: the accessible name, the tooltip, the tab's caption on a phone, the row's text when the rail is expanded.
asChildboolean—Renders your router's link with the item's look: pass it as the only child.
badgeReactNode—A count (unread, pending) on the icon. Say it in words with badgeLabel.
badgeLabelstring—The count in words (« 3 unread »), appended to the accessible name.
currentboolean—This is the section the user is in: aria-current="page", the accent bar and the accent colour.

Accessibility

  • A nav named by label; the current item carries aria-current="page".
  • The shortcuts are a group named by shortcutsLabel (its heading, visible once the rail is expanded); the arrows walk through them like the other items.
  • Each item is named by its label (and badgeLabel): the tooltip and the caption repeat it, they never replace it.
  • The focus ring is the Krizaka signature (focus-ring-inset), kept inside the rail's edge so it is never clipped.
  • A tab is at least 56 px tall, clear of the home indicator (env(safe-area-inset-bottom)); the motion of the width respects prefers-reduced-motion.
  • Exactly one brand mark is visible at every width: the rail's mark below md is hidden and AppHeader's mark is shown there, and the reverse above.

Keyboard

KeysAction
TabMoves through the items, the footer's controls and the expand button.
↑ ↓ (rail) · ← → (tab bar)Moves the focus to the previous or next item, wrapping at the ends; both pairs always work.
Home / EndFocuses the first or the last item.
EscDismisses a tooltip that is showing.

Best practices

  • Five main items at most: on a phone they are the tabs (the footer's items follow them in the same bar, so keep both short).
  • Give every item an icon and a word: the icon is all a desktop shows, the word is the tooltip, the tab's caption and the accessible name.
  • Put the product's mark in mark and its name in AppHeader: the mark is shown once, in the rail on a desktop and in the header on a phone. Never draw it in both.
  • Render your router's links with RailNav.Item asChild; set current from the route.
  • Scope the product's colours with accent (orazaka, yomizaka…) or let the page's brand class do it.
  • expandable is for apps whose users know the icons less well: it widens the rail to show the words. Uncontrolled and without defaultExpanded, it is expanded from 1280 px (the words fit there) until the person toggles it.
  • shortcuts (with shortcutsLabel, « Raccourcis ») holds the product's quick ways in — a saved view, a frequent client, « New invoice » — above the footer; two to four, never a second navigation. Desktop only: a phone's tab bar keeps its destinations.

Generated from the code of @krizaka/ui 3.63.1: its meta.ts, its examples and its types.Edit this documentation on GitHub

On this page