AppShell
Workspace context
Asset workspace
Caller-supplied workspace content.
AppShell is an in-page named region. The host owns document landmarks. Pass
navigation, toolbar, and footer as flat slots.
Navigation and toolbar
Asset workspace
Select an asset in the hierarchy to review its last reported state.
Navigation precedes the workspace content: beside it when the shell is at least
640px wide, above it when narrower. The shell follows its own width, not the
window's, so a shell in a narrow panel stacks on a wide screen too. Stacked, the
navigation is capped at about eight rows and scrolls inside its named navigation
landmark; side by side it has no cap. The shell fills its container's width, so
put spacing on the container, not as a margin on the shell. Beside other content in
a flex row, give the shell min-w-0 flex-1, so a Sidebar beside it keeps its width.
The toolbar slot grows with a toolbar that wraps onto more rows.
Modes are live, paused, replay, and training. These are context labels;
the application owns data handling. The Facility Monitoring recipe
shows a shared review time and returning to the latest supplied source reference.
Connection labels distinguish connected, connecting, reconnecting, offline, and
unknown. Reference time is supplied epoch milliseconds and always displays UTC to
the second (2026-09-25 14:30:00 UTC); the date and the clock wrap apart, and UTC
stays with the clock. Missing or invalid time remains unknown. No connection, classification, or
freshness is inferred; policy markings and identity are caller-supplied.
Props
| PROP | TYPE | DEFAULT | REQUIRED |
|---|---|---|---|
identityApplication-supplied user or role identity; displayed verbatim. | string | — | yes |
title | string | "Workspace" | no |
modePresentation context. Does not connect to services or freeze data itself. | enumlive | paused | replay | training | "live" | no |
connection | enumconnected | connecting | reconnecting | offline | unknown | "unknown" | no |
timeSupplied reference time in epoch milliseconds, shown as YYYY-MM-DD HH:MM:SS UTC. Missing, null or invalid renders Time unknown; no running clock. | number | — | no |
markingsCaller-supplied policy/training markings. No classification is inferred. | node | — | no |
navigationNavigation slot, usually a Sidebar, before the content in reading order. Beside the content when the shell is at least 640px wide (the shell's own width, not the window's); above it when narrower, capped at about eight rows and scrolling inside its named navigation landmark. The slot is the one navigation landmark, named from the title ("<title> navigation"); a Sidebar inside it adds no landmark of its own. | node | — | no |
toolbarToolbar slot under the header; it grows with a toolbar that wraps onto more rows. | node | — | no |
footer | node | — | no |
Accessibility
- A visible heading names the workspace region.
- The navigation slot is one landmark, named from the title (
Asset workspace navigation). ASidebarpassed to it adds no landmark of its own. - Status labels carry text in addition to color.
- No focus movement, modality, or keyboard shortcuts are added.
- Body content retains supplied case; interface headings and status labels use uppercase.
- Long titles, identities, markings and unbroken identifiers wrap inside the shell instead of widening the page.
Manifest entry
<AppShell identity="Exercise analyst" mode="training" connection="offline" markings="EXERCISE" time={referenceTime}><DataGrid columns={columns} data={rows} getRowId={(row) => row.id} /></AppShell>View agent manifest
{
"description": "In-page operational workspace with explicit identity, mode, connection, UTC reference time, and caller-supplied markings.",
"props": {
"identity": {
"type": "string",
"required": true,
"description": "Application-supplied user or role identity; displayed verbatim."
},
"title": {
"type": "string",
"default": "Workspace"
},
"mode": {
"type": "enum",
"values": [
"live",
"paused",
"replay",
"training"
],
"default": "live",
"description": "Presentation context. Does not connect to services or freeze data itself."
},
"connection": {
"type": "enum",
"values": [
"connected",
"connecting",
"reconnecting",
"offline",
"unknown"
],
"default": "unknown"
},
"time": {
"type": "number",
"description": "Supplied reference time in epoch milliseconds, shown as YYYY-MM-DD HH:MM:SS UTC. Missing, null or invalid renders Time unknown; no running clock."
},
"markings": {
"type": "node",
"description": "Caller-supplied policy/training markings. No classification is inferred."
},
"navigation": {
"type": "node",
"description": "Navigation slot, usually a Sidebar, before the content in reading order. Beside the content when the shell is at least 640px wide (the shell's own width, not the window's); above it when narrower, capped at about eight rows and scrolling inside its named navigation landmark. The slot is the one navigation landmark, named from the title (\"<title> navigation\"); a Sidebar inside it adds no landmark of its own."
},
"toolbar": {
"type": "node",
"description": "Toolbar slot under the header; it grows with a toolbar that wraps onto more rows."
},
"footer": {
"type": "node"
}
},
"slots": {
"children": {
"type": "ReactNode",
"required": true
}
},
"composable_with": [
"Sidebar",
"Inspector",
"TreeView",
"OperationalStatus",
"TimeRange",
"DataGrid"
],
"never_inside": [
"Button"
],
"example": "<AppShell identity=\"Exercise analyst\" mode=\"training\" connection=\"offline\" markings=\"EXERCISE\" time={referenceTime}><DataGrid columns={columns} data={rows} getRowId={(row) => row.id} /></AppShell>"
}