Top navigation
Global navigation that persists across pages within a single app. Aligned with J&J DS v1.2 — single-line logo on the homepage, shorthand on subsequent pages. Three height modes (compact 48 / default 64 / spacious 80), structured action cells with hover and active states, and an optional secondary bar.
Default — full logo, primary nav, action cells
The canonical desktop variant. Logo on the left, optional menu icon, webapp name (20px Johnson Text Medium), inline nav with a menu item that opens a dropdown, then a CTA and action icon cells on the right.
Show sourceHide source
<TopNavigation
notSticky
appName="Webapp name"
links={[
{ label: "Overview", href: "#", active: true },
{ label: "Patients", href: "#" },
{ label: "Studies", href: "#" },
{
label: "Reports",
type: "menu",
items: [
{ label: "Operational", href: "#" },
{ label: "Clinical", href: "#" },
{ label: "Compliance", href: "#" },
{ label: "Custom", href: "#" },
],
},
{ label: "Admin", href: "#" },
]}
cta={
<Button size="sm" variant="primaryAlt">
<Icon icon={Plus} size="xs" />
New study
</Button>
}
actionItems={[
{ label: "Search", icon: <Icon icon={Search} size="md" /> },
{ label: "Notifications", icon: <Icon icon={Bell} size="md" /> },
]}
/>Mode — Compact (48), Default (64), Spacious (80)
Three vertical densities matching the Figma `mode` variant. The webapp name shrinks to 16px in compact; the J&J logo height tracks the bar.
Show sourceHide source
<TopNavigation notSticky mode="compact" appName="Webapp name" links={links} />
<TopNavigation notSticky mode="default" appName="Webapp name" links={links} />
<TopNavigation notSticky mode="spacious" appName="Webapp name" links={links} />Logo — single-line vs shorthand
Per DS guidance: single-line on the homepage, shorthand on subsequent pages. For longer app names (~20+ chars) consider the "Full on Secondary nav" pattern using the secondaryBar slot.
Show sourceHide source
<TopNavigation notSticky logoForm="single-line" appName="Trial dashboard" links={links} />
<TopNavigation notSticky logoForm="shorthand" appName="Trial dashboard" links={links} />With menu button — collapsed nav
Use `showMenuButton` and `onMenuClick` when nav items are collapsed into a side panel. Hides inline nav below the md breakpoint automatically.
Show sourceHide source
<TopNavigation
notSticky
showMenuButton
onMenuClick={() => console.log("open side nav")}
appName="Webapp name"
actionItems={[
{ label: "Help", icon: <Icon icon={HelpCircle} size="md" /> },
{ label: "Settings", icon: <Icon icon={Settings} size="md" /> },
]}
/>With secondary navigation bar
A 32px-tall bar below the main nav, useful for context like locale, region, or breadcrumbs. Two tones (white | gray).
Show sourceHide source
<TopNavigation
notSticky
appName="Webapp name"
links={links}
secondaryBarTone="gray"
secondaryBar={
<div className="flex items-center gap-4 text-[12px] text-jj-text-02">
<span>EN · US</span>
<span aria-hidden>|</span>
<span>Trial: BRIDGE-204</span>
</div>
}
/>Free-form actions slot — avatars, buttons, anything
`actions` accepts any ReactNode and renders to the right of `actionItems`. Use it when you need an avatar, custom dropdown, or anything outside the structured icon-cell pattern.
Show sourceHide source
<TopNavigation
notSticky
appName="Webapp name"
links={links}
actionItems={[
{ label: "Notifications", icon: <Icon icon={Bell} size="md" /> },
]}
actions={
<Avatar size="sm">
<AvatarImage src="https://i.pravatar.cc/80?img=12" alt="" />
<AvatarFallback>PN</AvatarFallback>
</Avatar>
}
/>States — disabled / current / open menu
Items expose `active` (current page, 2px black underline + text-01), `disabled` (text-03, no interaction), and menu items track open state automatically. Click the Reports menu in the first example to see the dropdown.
Show sourceHide source
<TopNavigation
notSticky
appName="States"
links={[
{ label: "Active", href: "#", active: true },
{ label: "Default", href: "#" },
{ label: "Disabled", href: "#", disabled: true },
{
label: "Open menu",
type: "menu",
items: [
{ label: "Item one", href: "#" },
{ label: "Item two (disabled)", disabled: true },
{ label: "Item three", href: "#" },
],
},
]}
/>Custom brand
Pass `brand` to swap the J&J logo for any element. Useful for co-branded experiences.
Show sourceHide source
<TopNavigation
notSticky
brand={
<Link href="/" className="flex items-center gap-2 font-semibold text-jj-text-01">
<ArrowUpRight aria-hidden="true" className="h-4 w-4" />
Acme Health
</Link>
}
appName="Co-branded"
actionItems={[{ label: "Profile", icon: <Icon icon={User} size="md" /> }]}
/>