@codeways/ui-shell
Shell
SuiteBar, AppSwitcher, StagingFlag, UserMenu and ImpersonationBanner, rendered in a mock app frame - the reference layout every suite app builds on.
Mock app frame
Viewing as Dinesh Perera. Actions are logged.
Payroll run - September 2026
42 employees - net pay LKR 12,480,000.00
Staging
AppSwitcher
The 9-dot grid popover. Apps missing from `urls` render greyed as 'Coming soon'.
UserMenu
Auth-aware entirely through props - no session/auth-client import inside the package.
StagingFlag / StagingChip
Amber marker for anything that is not production.
Staging
Staging
ImpersonationBanner
Normal-flow block - reserves layout space above the suite bar rather than overlapping content.
Viewing as Dinesh Perera. Actions are logged.
Usage
import { SuiteBar } from "@codeways/ui-shell/suite-bar";
import { ImpersonationBanner } from "@codeways/ui-shell/impersonation-banner";
// grid-template-rows: auto 48px 1fr - the "auto" row only exists while impersonating
<div className="grid h-dvh grid-cols-[var(--sidebar-width)_minmax(0,1fr)] grid-rows-[auto_var(--topbar-height)_minmax(0,1fr)]">
{impersonation ? (
<ImpersonationBanner className="col-span-full" name={impersonation.name} onExit={impersonation.onExit} />
) : null}
<SuiteBar className="col-span-full" app={{ id: "hrm", name: "HRM", icon: Briefcase, href: "/" }} urls={runtime.suiteAppUrls} env={runtime.env} session={session} />
<Sidebar />
<main id="main">{children}</main>
</div>