Skip to main content

Overview

AxHeader is a horizontal navigation header that supports sidebar integration, horizontal navigation items, and flexible content zones. It includes two visual variants (default white and branded navy) and automatic mobile responsiveness.

Import

import AxHeader from "axmed-design-system"
import type { HeaderNavItem } from "axmed-design-system"

Basic Usage

import { BellOutlined } from "@ant-design/icons"

function AppHeader() {
  const [collapsed, setCollapsed] = useState(false)

  return (
    <AxHeader
      onSidebarToggle={() => setCollapsed(!collapsed)}
      sidebarCollapsed={collapsed}
      left={<Logo />}
      right={
        <>
          <Badge count={3}>
            <Button icon={<BellOutlined />} />
          </Badge>
          <Avatar icon={<UserOutlined />} />
        </>
      }
    />
  )
}

Props

left
React.ReactNode
Left slot - logo, breadcrumbs, or any content. Renders after the sidebar toggle button (if present).
center
React.ReactNode
Center slot - custom content that overrides navItems. Hidden on mobile (< 768px).
right
React.ReactNode
Right slot - action buttons, badges, profile dropdown, or any content.
navItems
HeaderNavItem[]
Convenience prop for horizontal navigation items rendered in the center zone. Ignored when center is provided. Items automatically collapse to a dropdown menu on mobile.
selectedKey
string
Key of the currently active navigation item (when using navItems).
onSidebarToggle
() => void
Callback when sidebar toggle button is clicked. When provided, renders a toggle button on the far left. Shows fold/unfold icon on desktop, hamburger on mobile.
sidebarCollapsed
boolean
Whether the companion sidebar is collapsed. Controls which toggle icon is shown (fold vs unfold).
variant
'default' | 'branded'
default:"'default'"
Visual variant:
  • "default" - White background, bottom border (dashboard)
  • "branded" - Navy background, white text (marketplace)
sticky
boolean
default:true
Use sticky positioning to keep header visible on scroll.
height
number
default:56
Header height in pixels.
bordered
boolean
Show a bottom border. Defaults to true for “default” variant, false for “branded” variant.
Logo shown on mobile in place of the sidebar toggle. Use when the sidebar is replaced by bottom navigation on mobile and the hamburger toggle is no longer needed.
className
string
Additional CSS class name.
style
React.CSSProperties
Inline styles.

HeaderNavItem

Navigation items for the center zone of the header.
type HeaderNavItem = {
  key: string
  label: React.ReactNode
  icon?: React.ReactNode
  onClick?: () => void
  badge?: number
  disabled?: boolean
}

Examples

Dashboard Header (Default Variant)

import { RobotOutlined, ShoppingCartOutlined } from "@ant-design/icons"

function DashboardHeader() {
  const [collapsed, setCollapsed] = useState(false)

  return (
    <AxHeader
      variant="default"
      onSidebarToggle={() => setCollapsed(!collapsed)}
      sidebarCollapsed={collapsed}
      right={
        <Space>
          <AxButton variant="text" icon={<RobotOutlined />}>
            Ask Axmed AI
          </AxButton>
          <Badge count={3}>
            <AxButton variant="secondary" icon={<ShoppingCartOutlined />}>
              Draft Orders
            </AxButton>
          </Badge>
          <Avatar icon={<UserOutlined />} />
        </Space>
      }
    />
  )
}

Marketplace Header (Branded Variant)

import { DashboardOutlined, AppstoreOutlined, ShoppingCartOutlined } from "@ant-design/icons"

function MarketplaceHeader() {
  const [active, setActive] = useState("dashboard")

  const navItems = [
    { key: "dashboard", label: "Dashboard", icon: <DashboardOutlined />, onClick: () => setActive("dashboard") },
    { key: "catalogue", label: "Catalogue", icon: <AppstoreOutlined />, onClick: () => setActive("catalogue") },
    { key: "orders", label: "My Orders", icon: <ShoppingCartOutlined />, badge: 3, onClick: () => setActive("orders") },
  ]

  return (
    <AxHeader
      variant="branded"
      left={<AxBrand variant="wordmark" theme="dark" />}
      navItems={navItems}
      selectedKey={active}
      right={
        <Space>
          <Badge count={5}>
            <AxButton variant="text" icon={<ShoppingCartOutlined />} />
          </Badge>
          <Avatar icon={<UserOutlined />} />
        </Space>
      }
    />
  )
}

With Sidebar Integration

function AppLayout() {
  const [collapsed, setCollapsed] = useState(false)
  const [selected, setSelected] = useState("dashboard")

  return (
    <div style={{ display: "flex", height: "100vh" }}>
      {/* Sidebar */}
      <AxSideNav
        items={sidenavItems}
        selectedKey={selected}
        collapsed={collapsed}
        onCollapse={setCollapsed}
        hideCollapseButton  {/* Let header control the toggle */}
      />

      <div style={{ flex: 1, display: "flex", flexDirection: "column" }}>
        {/* Header */}
        <AxHeader
          onSidebarToggle={() => setCollapsed(!collapsed)}
          sidebarCollapsed={collapsed}
          mobileLogo={<AxBrand variant="wordmark" />}
          right={<UserActions />}
        />

        {/* Page content */}
        <main style={{ flex: 1, overflow: "auto" }}>
          {/* Your page content */}
        </main>
      </div>
    </div>
  )
}

With Horizontal Navigation

const navItems = [
  { key: "dashboard", label: "Dashboard", icon: <DashboardOutlined /> },
  { key: "catalogue", label: "Catalogue", icon: <AppstoreOutlined /> },
  { key: "orders", label: "My Orders", icon: <ShoppingCartOutlined />, badge: 3 },
  { key: "reports", label: "Reports", icon: <BarChartOutlined />, disabled: true },
]

<AxHeader
  left={<AxBrand variant="wordmark" />}
  navItems={navItems}
  selectedKey={activeKey}
  right={<Avatar />}
/>

Custom Center Content

<AxHeader
  left={<Logo />}
  center={
    <Input.Search
      placeholder="Search products, suppliers, tenders..."
      style={{ maxWidth: 500 }}
    />
  }
  right={<UserMenu />}
/>

Variants

Default

White background with bottom border. Suitable for dashboard and internal application pages.
<AxHeader variant="default" bordered={true} />

Branded

Navy background with white text. Suitable for marketplace and public-facing pages.
<AxHeader variant="branded" bordered={false} />

Mobile Behavior

  • Sidebar toggle shows as hamburger icon on mobile
  • navItems collapse into a dropdown menu on mobile
  • Center content is hidden on mobile (< 768px)
  • Use mobileLogo prop when sidebar uses bottom navigation instead of hamburger menu
<AxHeader
  onSidebarToggle={toggleSidebar}
  mobileLogo={<AxBrand variant="wordmark" />}  {/* Shows on mobile */}
  navItems={items}  {/* Becomes dropdown on mobile */}
/>

Accessibility

  • Uses semantic <header> with role="banner"
  • Toggle button has proper aria-label describing its action
  • Navigation uses <nav> with role="navigation"
  • Active items marked with aria-current="page"
  • Keyboard navigation support for all interactive elements
  • AxSideNav - Vertical sidebar navigation
  • AxButton - Action buttons for header slots
  • AxBrand - Logo component for branding

Build docs developers (and LLMs) love