AppShell
A viewport-constrained application grid with persistent chrome and a native content pane.@gemologic/sheen-patterns · applicationPlayground
This example has no scalar controls. Its validated source remains interactive below.
Workspace
Application content
<MetaProvider><AppShell label="Workspace" documentTitle="Workspace · Sheen" header={<h1>Workspace</h1>} statusBar={<span>Ready</span>}><p>Application content</p></AppShell></MetaProvider>Variant matrix
Application frame
Workspace
Application content
Shared shortcut help
Application content
Anatomy
- Package
@gemologic/sheen-patterns- Source
packages/patterns/src/AppShell.tsx- Tokens
--sheen-color-bg--sheen-color-border
Accessibility
Role: main, complementary, banner, contentinfoKeyboard: Tab, Shift+Tab, PageUp, PageDownDo
- Load the patterns stylesheet alongside sheen styles.
- Use one shell per document; compare complete shells in separate iframes.
Do not
- Do not remount the shell during background refresh.
- Do not treat the initial layout as completed router or mobile-drawer integration.
Generated props
| Name | Type | Default | Description |
|---|---|---|---|
label * | string | — | Required accessible name for the primary content scrolling region. |
documentTitle | string | — | Optional accepted-route document title. Requires an app-owned MetaProvider and never derives copy from a URL. |
header | JSX.Element | — | Fixed top chrome, rendered once in a native header. |
sidebar | JSX.Element | — | Retained sidebar content, projected into desktop aside or phone modal without recreating its owner. Requires ThemeProvider; supply named navigation and constrain internal scrolling. |
sidebarOpen | boolean | — | Controlled desktop sidebar visibility. Rejected proposals leave accepted state unchanged; hiding retains the sidebar DOM and removes it from interaction. Phone state is separate. |
defaultSidebarOpen | boolean | — | Initial uncontrolled desktop visibility, true by default. Uncontrolled phone drawers independently start closed and reset when returning to desktop. |
onSidebarOpenChange | (open: boolean) => void | — | Proposed sidebar visibility from the shell control or mod+/ binding. Supply sidebarOpen to own acceptance and persistence. |
sidebarBehavior | "hide" | "collapse" | hide | Desktop toggle behavior. hide removes the sidebar from layout; collapse retains an interactive icon rail. Phone always uses the independent drawer. |
mobileSidebarOpen | boolean | — | Controlled phone drawer state, independent of desktop sidebarOpen. Uncontrolled phone drawers start closed. Sidebar content requires ThemeProvider. |
onMobileSidebarOpenChange | (open: boolean) => void | — | Phone drawer visibility proposals from the toggle, shortcut, Escape, or outside press. Apps own controlled acceptance and persistence. |
statusBar | JSX.Element | — | Fixed bottom chrome, rendered once in a native footer. |
router | RouterAdapter | — | Optional app-injected router adapter for dirty navigation blocking. Retry must bypass only this registration once. Requires the shell to be inside ThemeProvider. |
contentReady | boolean | — | Defaults to true. Set false while main-pane route content is incomplete so saved scroll restoration can wait for growth; true settles at the current clamped boundary. |
shortcutHelp | boolean | — | Enable localized help, pending indicator, global question-mark binding, and development-only mod+shift+d theme cycling. Requires app-owned ThemeProvider and ShortcutProvider ancestors; defaults to false. Apps should enable this even when character shortcuts are disabled. Development policy comes from ShortcutProvider. |