App shell
The shell of an application screen: a sidebar of sections that collapses to its icons on a desktop and opens as a drawer on a phone, a sticky header with the screen's title, a search that opens the command palette and its actions, the content — and the keyboard shortcuts a console lives by (⌘B, ⌘K, g then a letter).
Web uniquement — React, depuis @krizaka/ui/app-shell. Bêta : son API peut encore changer à une version mineure.
Pourquoi il est là. the web apps' adoption: Orochia (PS5), Orazaka (PS6): the shell of every authenticated web screen.
Quand l’utiliser
- Every signed-in screen of a product: a studio, a console, an administration.
- When the app has more than four destinations — fewer fit a NavBar.
Quand ne pas l’utiliser
- For a public page of a site.À la place : Marketing layout
- For a mobile app's tabs: React Native has its own tab bar.
Installation
Installer
npm install @krizaka/ui @krizaka/tailwind @krizaka/tokens tailwindcssStyles
@import "tailwindcss";
@import "@krizaka/tailwind";
@import "@krizaka/ui/tailwind.css";Importer
import { AppShell, useShortcuts, formatShortcut } from "@krizaka/ui/app-shell";Exemples
Console
A finance console: sections with g shortcuts, ⌘K that opens the palette, a server-side table that refreshes when a form creates a row.
Finance
Payouts
Every payout, newest first. Sorting, filters and pages are answered by the API.
0 rows
| Status |
|---|
New payout
Orochia studio
Elena's home in the creator studio: the shell around this week's figures, the payout, the auction and the sales.
Studio
This week
Good morning, Elena
Three sales since yesterday — your auction ends tonight.
Your week
Views
12.4k
+8 %7 days
Supporters
318
+217 days
Earned
€902
+14 %after the 10 % fee
Unlocks
146
±07 days
Next payout
Every Monday, from €20
€902 will reach your bank on Monday.
Auction
“Backstage cut”
€68
7 bids · ends tonight at 21:00
Latest sales
- Unlock · “Night shoot, part 2”Léa M.€4.50
- TipSamir K.€9.00
- Auction won · “Backstage cut”Inès B.€61.20
Administration console
A review queue in a console: sections, counts and a sortable table with bulk actions (cards on a phone).
Verification
Requests to review
Oldest first. A decision is logged with your name.
Pending
identity and payout
2
Oldest wait
40 min
Queue
| Request | Status | Waiting | ||
|---|---|---|---|---|
The shell alone
Sidebar with a group and a count, header with an action, the content.
Home
The screen's content.
Props
AppShellRoot
The shell: holds the collapse (desktop) and the drawer (phone) state. Children: Sidebar, then Body.
| Prop | Type | Défaut | Description |
|---|---|---|---|
collapsed | boolean | — | Controlled collapse (desktop): pair with onCollapsedChange to persist the choice. |
collapseShortcut | string | false | mod+b | The shortcut that folds and unfolds the sidebar (a combination: mod+b is ⌘B on a Mac, Ctrl+B elsewhere), or false
for none. |
defaultCollapsed | boolean | false | The sidebar starts collapsed to its icons (desktop). |
onCollapsedChange | ((collapsed: boolean) => void) | — | Called when the sidebar collapses or expands. |
skipLabel | string | — | The words of the "skip to content" link (Skip to content), the first tab stop; it lands on AppShell.Main. Without it, no link. |
AppShellSidebar
The sidebar: on a desktop a column that collapses to its icons; on a phone the same content in a drawer.
| Prop | Type | Défaut | Description |
|---|---|---|---|
childrenrequis | ReactNode | — | The sections: AppShell.Group and AppShell.Item. |
closeLabelrequis | string | — | The drawer's close button words (phone). |
labelrequis | string | — | The navigation's accessible name (Studio, Administration). |
brand | ReactNode | — | The brand at the top: the product's mark and name (a link home through asChild of your router, or plain). |
collapseLabels | readonly [string, string] | — | The collapse button's words, [collapse, expand] (desktop only). Without it the sidebar cannot collapse. |
footer | ReactNode | — | At the bottom, above the collapse button: the account, a plan, the version. |
AppShellItem
A destination of the sidebar: icon, words, a count.
| Prop | Type | Défaut | Description |
|---|---|---|---|
labelrequis | string | — | Its words: the accessible name, hidden visually when collapsed (the icon carries a tooltip through title). |
asChild | boolean | — | Renders your link (Next's Link) with the item's look: pass it as the only child. |
badge | ReactNode | — | A count beside it (unread, pending): a number or a few characters. |
children | ReactElement<unknown, string | JSXElementConstructor<any>> | — | Your link element when asChild. |
current | boolean | — | The screen it opens is the current one: aria-current="page". |
icon | ReactNode | — | The item's icon (a signature icon): it stays when the sidebar collapses. |
shortcut | string | — | A keyboard shortcut that goes to it: a sequence (g d: G then D) or a combination (mod+1). It clicks the item, so a
router link navigates. The keys are shown on hover and focus when the sidebar is open. |
AppShellHeader
The top of the screen: the drawer's button (phone), the title, the actions. Sticky.
| Prop | Type | Défaut | Description |
|---|---|---|---|
menuLabelrequis | string | — | The button that opens the drawer on a phone: its words. |
actions | ReactNode | — | The screen's actions, on the right. |
title | ReactNode | — | The screen's title (an h1). |
AppShellSearch
The header's search: a button that looks like a field (a magnifier, its words, ⌘K) and opens the app's command palette.
| Prop | Type | Défaut | Description |
|---|---|---|---|
labelrequis | string | — | The words ("Search", "Search creators"): the accessible name, shown beside the keys on a desktop. |
onOpenrequis | () => void | — | Called when the button is pressed or the shortcut is typed: open your command palette (CommandDialog) here. |
shortcut | string | mod+k | The shortcut that opens it (a combination); shown on its keys. |
Accessibilité
skipLabelonAppShell.Rootadds the skip link (WCAG 2.4.1): the first tab stop, landing onAppShell.Main.- The sidebar is a
navnamed bylabel; the current item carriesaria-current="page". - On a phone the drawer is a modal dialog (Radix): focus trapped inside, Escape and the overlay close it, the focus returns to the button.
- The header's title is the screen's
h1; nested layouts useheadingAs="h2". - A combination is announced with
aria-keyshortcuts(Control+K,Meta+Kon a Mac); a sequence is not a chord, so it is only shown on its keys, never named to assistive technology. - The platform's keys are known after the first client render (⌘ on a Mac, Ctrl elsewhere): the server and the first render agree.
Clavier
| Touches | Action |
|---|---|
| Tab | Moves through the sidebar's items, the collapse button and the header's actions. |
| Esc | Closes the drawer on a phone and returns the focus to the menu button. |
| ⌘B / Ctrl+B | Folds and unfolds the sidebar (collapseShortcut, off with false). |
| ⌘K / Ctrl+K | Opens the command palette from AppShell.Search, in a text field too. |
| G then a letter | Goes to the section whose shortcut it is; plain keys never fire while typing in a field. |
Bonnes pratiques
- Five to nine items, grouped by what the user does (
AppShell.Group), the current one marked withcurrent. - Give every item an icon: it is all that remains when the sidebar collapses (its words become a tooltip).
- Persist the collapse with
collapsed+onCollapsedChange; put the account in the sidebar'sfooter. - Render your router's links with
AppShell.Item asChild. - Give the sections a
shortcut(g p: G then P): it clicks the item, so a router link navigates, and the keys show on hover and focus. - Put
AppShell.Searchin the header and open yourCommandDialogfrom itsonOpen: ⌘K (Ctrl+K) opens it from anywhere.
Composants liés
Générée depuis le code de @krizaka/ui 3.9.0 : son meta.ts, ses exemples et ses types.Modifier cette documentation sur GitHub