Header
Header is a sticky top navigation bar built as a compound component. It is meant for layout composition rather than variant switching, so the public API stays intentionally small: Header, HeaderContent, HeaderLeft, HeaderCenter, and HeaderRight.
Default header layout
Header with dropdown navigation
Header with centered search
Header used with a sidebar layout
Header with a custom background
Full-width header content
Usage
Default layout
Use HeaderContent with HeaderLeft and HeaderRight for the standard layout: branding and navigation on the left, actions on the right.
import {
Header,
HeaderContent,
HeaderLeft,
HeaderRight,
} from "@e-infra/design-system";
import { Avatar, AvatarImage, AvatarFallback } from "@e-infra/design-system";
import { Button } from "@e-infra/design-system";
import { Bell } from "lucide-react";
<Header>
<HeaderContent>
<HeaderLeft>
<Logo />
<nav className="flex items-center gap-4 text-sm font-medium">
<a href="/dashboard">Dashboard</a>
<a href="/projects">Projects</a>
<a href="/team">Team</a>
</nav>
</HeaderLeft>
<HeaderRight>
<Button variant="ghost" size="icon">
<Bell className="h-4 w-4" />
</Button>
<Avatar>
<AvatarImage src="https://github.com/shadcn.png" alt="User" />
<AvatarFallback>U</AvatarFallback>
</Avatar>
</HeaderRight>
</HeaderContent>
</Header>;Centered content
HeaderCenter is a flex item that fills the available space between the left and right sections. It works well for search bars and centered tools.
import {
Header,
HeaderContent,
HeaderLeft,
HeaderCenter,
HeaderRight,
} from "@e-infra/design-system";
import { Input } from "@e-infra/design-system";
import { Search } from "lucide-react";
<Header>
<HeaderContent>
<HeaderLeft>
<Logo />
<nav className="flex items-center gap-4 text-sm font-medium">
<a href="/dashboard">Dashboard</a>
<a href="/projects">Projects</a>
</nav>
</HeaderLeft>
<HeaderCenter>
<div className="relative w-full max-w-md">
<Search className="absolute left-2.5 top-2.5 h-4 w-4 text-text" />
<Input type="search" placeholder="Search..." className="w-full pl-8" />
</div>
</HeaderCenter>
<HeaderRight>
<UserActions />
</HeaderRight>
</HeaderContent>
</Header>;Navigation menus
Use the NavigationMenu primitives for dropdown menus and multi-level navigation. NavigationMenu renders the viewport automatically by default, and NavigationMenuIndicator should be placed after NavigationMenuList when you want the active indicator arrow.
import {
Header,
HeaderContent,
HeaderLeft,
HeaderRight,
} from "@e-infra/design-system";
import {
NavigationMenu,
NavigationMenuList,
NavigationMenuItem,
NavigationMenuLink,
NavigationMenuTrigger,
NavigationMenuContent,
NavigationMenuIndicator,
} from "@e-infra/design-system";
<Header>
<HeaderContent>
<HeaderLeft>
<Logo />
<NavigationMenu>
<NavigationMenuList>
<NavigationMenuItem>
<NavigationMenuLink href="/dashboard">Dashboard</NavigationMenuLink>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuTrigger>Analytics</NavigationMenuTrigger>
<NavigationMenuContent>
<div className="grid gap-3 p-4 w-100">...</div>
</NavigationMenuContent>
</NavigationMenuItem>
</NavigationMenuList>
<NavigationMenuIndicator />
</NavigationMenu>
</HeaderLeft>
<HeaderRight>
<UserActions />
</HeaderRight>
</HeaderContent>
</Header>;If you need to place the viewport manually, disable the automatic viewport and render NavigationMenuViewport yourself.
<NavigationMenu viewport={false}>
<NavigationMenuList>...</NavigationMenuList>
<NavigationMenuViewport />
</NavigationMenu>Sidebar layouts
When a sidebar already owns branding, use container={false} so the header can span the full width without an extra max-width wrapper.
import { Header, HeaderContent, HeaderRight } from "@e-infra/design-system";
import { Sidebar, SidebarHeader, SidebarContent } from "@e-infra/design-system";
<div className="flex min-h-screen">
<Sidebar>
<SidebarHeader>
<span className="font-semibold">Lab Management</span>
</SidebarHeader>
<SidebarContent>{/* navigation */}</SidebarContent>
</Sidebar>
<div className="flex-1">
<Header>
<HeaderContent container={false}>
<HeaderRight>
<UserActions />
</HeaderRight>
</HeaderContent>
</Header>
</div>
</div>;Full-width and custom backgrounds
Header accepts native className overrides, so you can apply gradients, transparent borders, or other visual treatments without changing the component implementation.
<Header className="bg-linear-to-r from-primary/90 to-secondary/90 border-transparent">
<HeaderContent>
<HeaderLeft>
<Logo />
<nav className="flex items-center gap-4 text-sm font-medium text-white/90">
<a href="#" className="hover:text-white">
Dashboard
</a>
</nav>
</HeaderLeft>
<HeaderRight>
<UserActions />
</HeaderRight>
</HeaderContent>
</Header>Components
| Component | Description |
|---|---|
Header | Root sticky header element rendered as header |
HeaderContent | Inner flex container with optional width constraint |
HeaderLeft | Left-aligned row for branding and navigation |
HeaderCenter | Center flex area for search or centered controls |
HeaderRight | Right-aligned row for actions and user controls |
Props
Header
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | - | Additional CSS classes |
| ...props | React.HTMLAttributes<HTMLElement> | - | Native header props |
HeaderContent
| Prop | Type | Default | Description |
|---|---|---|---|
| container | boolean | true | Whether to constrain width to the container max-width |
| className | string | - | Additional CSS classes |
| ...props | React.HTMLAttributes<HTMLDivElement> | - | Native div props |
HeaderLeft
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | - | Additional CSS classes |
| ...props | React.HTMLAttributes<HTMLDivElement> | - | Native div props |
HeaderCenter
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | - | Additional CSS classes |
| ...props | React.HTMLAttributes<HTMLDivElement> | - | Native div props |
HeaderRight
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | - | Additional CSS classes |
| ...props | React.HTMLAttributes<HTMLDivElement> | - | Native div props |
Structure
| Part | Details |
|---|---|
| Outer wrapper | Sticky header with top positioning, border-bottom, blur, and z-50 layering |
| Content row | Flex container with h-14, horizontal padding, and responsive gap spacing |
| Left section | flex items-center gap-4 md:gap-6 for branding and navigation |
| Center section | flex flex-1 items-center justify-center for balanced centered content |
| Right section | ml-auto flex items-center gap-2 for action controls |
Behavior
| Behavior | Details |
|---|---|
| Sticky layout | Header stays pinned to the top of the viewport while scrolling |
| Width control | HeaderContent constrains width by default and can opt out with container={false} |
| Composition-first API | Layout is built by arranging the subcomponents rather than selecting from variants |
| Navigation menus | The header works with the NavigationMenu primitives for dropdowns and indicators |
| Custom styling | Native className props allow local overrides without changing the implementation |
Notes
HeaderCenteris optional, but it is the supported way to place centered content in this layout.NavigationMenuViewportis rendered automatically byNavigationMenuunless you setviewport={false}.- The header implementation is intentionally small; prefer composing the existing subcomponents over adding new header-specific props.