Organisms

Top bar

The Dashboard shell chrome. A sticky 64px bar with a breadcrumb on the left and utilities on the right: Test mode switch, Theme toggle, Notifications bell, Account menu.

Updated Jul 10, 2026 by Leonardo Posada

Live preview

Page content
<TopBar breadcrumb="Home" />

Anatomy

The top bar has two zones separated by justify-between. Left: breadcrumb text (single item, no chevron). Right: a group of utilities separated by vertical dividers, ending with the avatar dropdown.

  1. 1
    Breadcrumb

    Left-side path. Accepts a string (single-item) or an array of segments to render a CaretRight (light, size-3) chevron chain. The last segment is text-foreground (current section); earlier segments are text-muted-foreground and become clickable buttons if onClick is passed.

  2. 2
    Theme toggle

    Sun / Moon icon button. Toggles the .dark class on <html>.

  3. 3
    Notifications bell

    IconButton with BellSimple (light). Opens the notification tray in real Dashboard.

  4. 4
    GlobalChip

    Environment + scope switcher chip. Opens a dropdown with ENVIRONMENT and ACCOUNTS sections. See the dedicated /organisms/global-chip page for full anatomy.

  5. 5
    AccountMenu

    Avatar dropdown with profile actions. See the dedicated /organisms/account-menu page for full anatomy.

  6. 6
    Test mode switch (optional, default off)

    Kit Switch labeled 'Test mode'. Opt-in via showTestMode={true}. When on, the account is operating in sandbox; wire host to actually swap keys.

  7. 7
    Dividers

    Vertical Separator h-6 between each utility group so the utilities read as distinct clusters.

Breadcrumb

The breadcrumb slot accepts either a plain string (single item) or an array of segments. Segments render as a CaretRight-separated chain, and any segment with an onClick becomes a hoverable button. The last segment is always the current section (non-clickable, text-foreground).

Single string — landing pages
<TopBar breadcrumb="Home" />
Segment array — detail views inside a section
<TopBar
  breadcrumb={[
    { label: "Risk conditions", onClick: () => router.push("/risk-conditions") },
    { label: "Rules", onClick: () => router.push("/risk-conditions/rules") },
    { label: "r-005" },
  ]}
/>
  • Single-string form for landing pages (Home, Insights) where there's no parent path.
  • Segment array for detail views inside a section (Risk conditions › Rules › r-005).
  • Only the last segment gets text-foreground — every previous segment is text-muted-foreground.
  • Parent segments should be clickable back to their own list — don't leave the trail dead.
  • Never nest a menu or dropdown inside a segment — the breadcrumb is for wayfinding only.

When to use

  • As the sticky top of any Dashboard-adjacent prototype (pair with Sidebar).
  • Prototypes that need Test mode toggle, notifications, or account menu.
  • When the flow spans multiple pages of the same Dashboard shell.

When not to use

  • Marketing landings — use a marketing top nav.
  • Focused modals or wizards — hide the shell entirely.
  • As a page-title header — use PageHeader below the top bar instead.

Usage

Do
  • Keep the top bar sticky (sticky top-0 z-20) so it stays anchored while content scrolls.
  • Order utilities right-to-left by frequency: avatar last, notifications and theme in the middle, Test mode as the outermost feature.
  • Use the kit Switch and Separator inside — never redeclare a bespoke switch.
  • Fill the breadcrumb with the current section (matches the sidebar selection).
Don't
  • Don't add a title or logo inside the top bar — logo lives in the Sidebar.
  • Don't nest actions or menus inside the breadcrumb slot.
  • Don't stack more than 4 utilities on the right — trim rare ones into the account menu.
  • Don't rename Test mode to 'Sandbox' or 'Preview' — the copy is canonical.

Composition

TopBar is sticky (position: sticky). Render it as the first child of your page content, after the Sidebar, so it hovers above scroll.

See the code block below for the shell pattern.
import { TopBar } from "@/components/organisms/top-bar";
import { Sidebar } from "@/components/organisms/sidebar";

export default function DashboardLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <div className="min-h-screen">
      <div className="fixed inset-y-0 left-0 z-30">
        <Sidebar />
      </div>
      <div className="pl-64">
        <TopBar breadcrumb="Home" />
        <main>{children}</main>
      </div>
    </div>
  );
}

Code

Custom breadcrumb + GlobalChip config.
<TopBar
  breadcrumb="Payments"
  accountMenu={{ userName: "Julián Núñez", userEmail: "julian@y.uno" }}
  globalChip={{
    accounts: [
      { key: "tiendamia-br", label: "Tiendamia BR", type: "organization" },
      { key: "tiendamia-ar", label: "Tiendamia AR", type: "organization" },
    ],
    onAccountChange: (key) => router.push(`/accounts/${key}`),
  }}
/>
Test-mode session + sandbox chip + account scope.
<TopBar
  breadcrumb="Rules"
  showTestMode
  globalChip={{
    activeEnvironment: "sandbox",
    activeAccount: "test-account",
    accounts: [
      { key: "test-account", label: "Test account", type: "account" },
    ],
  }}
/>