Summary#
WorkbenchShell splits navigation in two. The activity bar carries one mark per top-level section and is always
in view; the explorer beside it lists the pages of the section you are in, with whatever the app adds under them
(saved views, a queue's filters). Pressing the current section's mark — or Mod+B — folds the explorer away, because
once you know where you are the width is worth more than the map. The page fills full-height panes, and a status line
runs along the foot.
[Layout]
[AllowAnonymous]
component Console() {
action Search() { }
render {
WorkbenchShell(new AppChrome {
Product = "Beacon",
Tagline = "Operations",
Home = "/",
Nav = [
new NavItem { Label = "Queues", Icon = Icons.Inbox, Children = [
new NavItem { Label = "Open", To = "/", Icon = Icons.CircleDot, Exact = true },
new NavItem { Label = "Waiting", To = "/waiting", Icon = Icons.Clock },
] },
new NavItem { Label = "Deploys", To = "/deploys", Icon = Icons.Upload },
],
}) {
Outlet(retain: 8);
slot search { ShellSearch("Search", onPress: Search); }
slot explorer { SectionLabel("Saved views"); }
slot status { Lamp(lit: true, live: true, tone: Tone.Success); Text("Live"); }
}
}
}
[Route("/")] [Layout(Console)] [Title("Open")] [Render(CSR)] [AllowAnonymous]
component OpenQueue() { render { Stack(p: 4) { Text("Nothing open."); } } }
[Route("/waiting")] [Layout(Console)] [Title("Waiting")] [Render(CSR)] [AllowAnonymous]
component WaitingQueue() { render { Stack(p: 4) { Text("Nothing waiting."); } } }
[Route("/deploys")] [Layout(Console)] [Title("Deploys")] [Render(CSR)] [AllowAnonymous]
component Deploys() { render { Stack(p: 4) { Text("No deploys today."); } } }Signature#
WorkbenchShell(AppChrome chrome) {
Outlet(retain: 8);
slot explorer { … } // under the section's pages
slot search { … } // the top bar
slot actions { … } // the top bar, right of search
slot status { … } // the status line along the foot
}Description#
Which items become marks, and which pages does the explorer list?#
Every top-level NavItem is a mark; a NavKind.Section's children are lifted to the top level (a section heading is
a word, and an activity bar has no room for words). A mark with Children is a SECTION: its children are what the
explorer lists while you are in it. A mark with no children is a page on its own, and the explorer lists just it.
A mark's name shows beside it on hover and keyboard focus, with its Badge. A mark with a Badge carries it as a
dot in the badge's tone, and the badge's words are in the mark's accessible name — "Inbox — 3" — so a screen
reader and a test (Ui.Click("Inbox — 3", within: "Main navigation")) read the count without pointing at it.
What happens when a row of the explorer opens a page outside the nav?#
The explorer stays. A tree in the explorer slot — records, files, a backlog — opens pages that are in no section
of the nav (/orders/42), and the explorer is not taken away the moment one of its rows is opened: it stays on the
section of the latest open route that is in one, and that section's mark stays lit, as an editor's side bar stays
on the view a file was opened from. This needs the outlet to keep routes open (Outlet(retain: 8)); with a single
open route, a page outside every section shows no explorer.
Where do the drawers come from?#
From the page, through Dock — the inspector a row opens on the right, a log along the bottom. They belong to the page because they open over what the PAGE has selected; the shell gives them a frame that is full height with nothing scrolling but the panes.
Where does ShowVersion show the versions?#
At the far end of the status line. The workbench's brand is a bare mark with no tagline under it, so where every
other shell puts the app's version under the product's name, this one puts the same two lines in its foot, after
whatever the status slot holds: "Tagline · App.Version" (just the version when there is no tagline) and
"platform " + App.PlatformVersion. A test reads them there: Assert.Visible("platform " + App.PlatformVersion, within: "Status"). See App.Version — which version of your app is running, on which platform release.
What happens on a phone?#
Below Tablet the activity bar and the explorer become one drawer behind the menu button — every section with its
pages under it, then the explorer slot — and the status line stays at the foot.
How do I drive it in a test?#
The marks are links in the region "Main navigation"; the explorer is a region named by the section's label; the
status line is "Status". Ui.Click("Hide the explorer") folds the explorer, and Assert.Visible("Live", within: "Status") reads the foot.
See also#
- Dock — the page's right and bottom drawers
- App shells — the
AppChromecontract every arrangement shares - Arrangements — five ways to build a whole app, and which look wears each — the workbench beside the other four archetypes