Application chrome
ApplicationShellBlock, PageHeaderBlock, WorkspaceSwitcherBlock and CommandPaletteBlock compose into one application frame. Each block’s own page carries its full prop contract, states and verification record; this page is about putting them together.
The composition
import { useState } from "react";
import {
ApplicationShellBlock,
PageHeaderBlock,
WorkspaceSwitcherBlock,
CommandPaletteBlock,
} from "@raydenui/ui/blocks";
const workspaces = [
{ id: "studio", name: "Design studio", initials: "DS" },
{ id: "product", name: "Product team", initials: "PT" },
];
export function Workspace() {
const [workspaceId, setWorkspaceId] = useState("studio");
return (
<ApplicationShellBlock
brand="Acme"
brandHref="/"
navSections={[
{
id: "workspace",
label: "Workspace",
items: [
{ id: "overview", label: "Overview", href: "/overview", current: true },
{ id: "projects", label: "Projects", href: "/projects" },
],
},
]}
switcher={
<WorkspaceSwitcherBlock
current={workspaces.find((item) => item.id === workspaceId)}
workspaces={workspaces}
onSelect={setWorkspaceId}
/>
}
search={
<CommandPaletteBlock
items={[
{ id: "overview", label: "Overview", href: "/overview" },
{ id: "projects", label: "Projects", href: "/projects" },
]}
shortcut={{ key: "k", modifier: "mod", hint: "⌘K" }}
/>
}
>
<PageHeaderBlock
title="Overview"
variant="plain"
description="A clear view of your current work."
meta={[{ id: "workspace", label: "Workspace", value: workspaceId }]}
actions={[
{ id: "projects", label: "View projects", href: "/projects", priority: "primary" },
]}
/>
<section aria-label="Current work" className="py-6">
Your application content
</section>
</ApplicationShellBlock>
);
}What composing them changes
One heading outline. The shell’s section labels default to h2 and the page header owns
the h1. Drop the page header to headingLevel="h2" only if something else already owns the
page heading, and do not repeat the page title as the first heading inside your content.
One scroll region. Leave mainScroll="page" so the palette overlay and the workspace do
not fight two scrollbars. mainScroll="region" needs a bounded height through className.
The page gutter. Use variant="plain" on the page header inside the shell’s existing
gutter rather than relying on negative margins.
Slots, not duplicates. search and switcher each keep one mounted instance at every
width, so neither is dropped from the collapsed arrangement. On a narrow shell the workspace
picker and tools stay together in the top bar and search wraps onto its own row.
Nested dismissal. Escape dismisses a child popover without also dismissing the parent collapsed navigation, so a workspace picker inside the collapsed panel behaves as expected.
Compact mobile context. Secondary page metadata collapses behind the Page details
disclosure below 640px of container width, and secondary actions move into the overflow
disclosure. Set collapseMetaOnSmallScreens={false} where metadata is essential.
Preview
The Storybook group Blocks / Compositions / Application Chrome combines all four blocks
with overview, tasks, supplier and profile content, across eight stories: FullChrome,
PaletteOverChrome, SwitchWorkspace, NarrowChrome, BoundedScrollChrome, DarkChrome,
CustomSurfaceChrome and ShortcutChrome.
Demo data and callbacks are illustrative. These blocks do not authenticate users and do not persist workspace changes — connect your own application logic.