App frame
The one signed-in frame of a Krizaka web product: the rail (a bottom tab bar on a phone), the family's top bar and the account menu, composed from data — sections, account and the primary action. The frame owns what must not differ between products: the account menu's content and order, the preferences living in the menu, a place being on the rail or under the avatar, never both.
import { AppFrame, navWords, publicBarLinks, framePlaces } from "@krizaka/ui/app-frame";Web only — React, from @krizaka/ui/app-frame. Beta: its API may still change in a minor version.
- Mobile · n/a. On a phone the frame is a tab bar, a header and a screen: the native twin is the tabs shell template. → Tab bar
Why it is here. The one signed-in frame of Yomizaka, Akinaza and Orazaka (UX audit F1, F2; yomizaka#429, akinaza#396, orazaka-web-client#294).
When to use
- Every signed-in screen of a product: Yomizaka, Akinaza, Orazaka — and each one's administration (
variant="admin"). - When a fourth product needs the frame: write its sections, not another header.
When not to use
Installation
Install
npm install @krizaka/ui @krizaka/tailwind @krizaka/tokens tailwindcssStyles
@import "tailwindcss";
@import "@krizaka/tailwind";
@import "@krizaka/ui/tailwind.css";Import
import { AppFrame, navWords, publicBarLinks, framePlaces } from "@krizaka/ui/app-frame";Examples
A product's signed-in app
Yomizaka: four sections with a count, the search, the primary action « Check a document », and the account menu with Language and Theme.
The administration
variant="admin" in French: the same frame, a chip that says where you are, and no way into the administration offered again.
Props
The signed-in frame: sections, account and the primary action in; the rail, the top bar and the account menu out.
| Prop | Type | Default | Description |
|---|---|---|---|
accountrequired | AppFrameAccount | — | Who is signed in, the places under their avatar and Sign out. |
childrenrequired | ReactNode | — | The page, inside RailNav.Body under the top bar. |
homeHrefrequired | string | — | Where the mark and the name lead (/app). |
markrequired | ReactNode | — | The product's mark (<ProductLogo id="yomizaka" size={26} />): on the rail on a desktop, in the top bar on a phone. |
namerequired | string | — | The product's name, as text in the top bar. |
sectionsrequired | readonly FrameSection[] | — | The destinations. place: "foot" puts one at the rail's foot; gated leaves one out for this person. |
accent | BrandId | — | The product's brand: scopes its colours over the rail. |
chips | ReactNode | — | Chips beside the name (Dev, Local · Sovereign). |
currentId | string | — | The id of the section the person is in. |
headerMark | ReactNode | — | The mark in the top bar below md (smaller). Defaults to mark. |
label | string | — | The rail's accessible name. Defaults to the product's name. |
language | AppFrameLanguage | — | The language row of the account menu; absent for a product with one language. |
linkAs | ElementType<any, keyof IntrinsicElements> | — | The router's link component (Next's Link) for the rail and the menu. |
locale | string | en | en or fr: the words of the shared vocabulary. |
notifications | ReactNode | — | Notifications: an AppHeaderCount, or the trigger of the host's popover. |
primary | ReactNode | — | The one primary action of the app (« Check a document »). |
search | { label: string; onOpen: () => void; } | — | The search (⌘K): opens the app's command palette. |
theme | false | AppFrameTheme | — | The theme row. By default the ThemeProvider's; pass false for a product that has none. |
variant | "app" | "admin" | app | admin: the administration's frame — a chip says so, and the way into it is not offered again. |
words | Partial<NavWords> | — | Overrides of the shared words, for a product that needs one different (use sparingly). |
Accessibility
- The rail is a
navnamed bylabel; the current section carriesaria-current="page". - Exactly one brand mark is visible at every width (the rail's on a desktop, the top bar's on a phone).
- A count on a section is said in words with
badgeLabel.
Keyboard
| Keys | Action |
|---|---|
| Tab | Moves through the rail's items, the search, the primary action and the account menu. |
| ↑ ↓ (rail) · ← → (tab bar) | Moves between the rail's items. |
| Enter / Space / Arrow down | Opens the account menu; Arrow right opens Language or Theme, Esc goes back. |
| ⌘K / Ctrl+K | Opens the search (the host's command palette). |
Best practices
- Pass the sections the product has:
place: "foot"puts one at the rail's foot;gatedleaves one out for this person (a permission, a feature not open). Five main sections at most: a phone's tab bar carries five. - The account menu is fixed: identity, Profile, Settings, Billing (only when you pass it), Administration (only for an admin), then Language and Theme, then Sign out. Settings is one entry that lands on the settings home, never a tab.
- A place is on the rail or under the avatar, never both: a section with the id of an account link (
settings,billing) leaves the rail. - The theme and the language are always in the menu, never in the header: a phone's header has no room. The theme is the
ThemeProvider's unless you passtheme. - Say the shared words with the shared vocabulary (
navWords, EN/FR): Docs, Terms / Conditions d'utilisation, Settings / Réglages. Override one (words) only when the product truly says it otherwise (« Credits and usage »). - The public bar is the other half of the family:
publicBarLinksgives its flat links, four at most — How it works · Pricing · Docs · Download. - The page inside is
<main id="content">; the frame does not draw it.
Related components
Generated from the code of @krizaka/ui 3.65.0: its meta.ts, its examples and its types.Edit this documentation on GitHub