Components

Navbar

A horizontal navigation bar component with semantic slots for organizing logos, navigation links, and action buttons.View source →

Build consistent navigation experiences with semantic slots for logo, navigation, and actions. The Navbar component provides a flexible foundation for headers that work across all screen sizes.

Built with compound components for maximum flexibility—compose Logo, Navigation, and Actions slots to create any navbar layout.

Installation

shell
npm install @kushagradhawan/kookie-ui

Usage

tsx
import { Navbar, Button, Text } from '@kushagradhawan/kookie-ui';
 
export function MyNavbar() {
  return (
    <Navbar.Root>
      <Navbar.Logo>
        <Text weight="bold">Brand</Text>
      </Navbar.Logo>
      <Navbar.Navigation>
        <Button variant="ghost">Home</Button>
        <Button variant="ghost">About</Button>
        <Button variant="ghost">Contact</Button>
      </Navbar.Navigation>
      <Navbar.Actions>
        <Button variant="soft">Sign In</Button>
      </Navbar.Actions>
    </Navbar.Root>
  );
}

Anatomy

The Navbar is a compound component with four parts:

tsx
<Navbar.Root>
  <Navbar.Logo>{/* Brand identity */}</Navbar.Logo>
  <Navbar.Navigation>{/* Primary links */}</Navbar.Navigation>
  <Navbar.Actions>{/* CTAs and controls */}</Navbar.Actions>
</Navbar.Root>
PartDescription
Navbar.RootThe root container. Renders as <header> with positioning and height controls.
Navbar.LogoLeft-aligned slot for brand identity. Never shrinks.
Navbar.NavigationCenter slot for navigation links. Expands to fill available space.
Navbar.ActionsRight-aligned slot for CTAs and user controls. Never shrinks.

Props

Root

PropTypeDefaultDescription
position'static' | 'fixed' | 'sticky''fixed'Positioning behavior of the navbar
size'1' | '2' | '3''2'Size of the navbar (controls padding)

Logo, Navigation, Actions

All slot components extend FlexProps and support all Flex layout properties.

PropTypeDefaultDescription
asChildbooleanfalseMerge props with child element using Radix Slot pattern
gap'0' - '12'Logo: '2', others: '4'Gap between child elements
align'start' | 'center' | 'end' | 'baseline' | 'stretch''center'Align items along cross axis
justify'start' | 'center' | 'end' | 'between'Logo: 'start', Nav: 'center', Actions: 'end'Justify content along main axis

Examples

Basic Navbar

Simple navbar with logo and navigation links:

tsx
import { Navbar, Button, Avatar } from '@kushagradhawan/kookie-ui';
 
export function BasicNavbar() {
  return (
    <Navbar.Root>
      <Navbar.Logo>
        <Avatar src="/logo.png" fallback="B" size="2" />
      </Navbar.Logo>
      <Navbar.Navigation>
        <Button variant="ghost">Products</Button>
        <Button variant="ghost">Solutions</Button>
        <Button variant="ghost">Pricing</Button>
      </Navbar.Navigation>
    </Navbar.Root>
  );
}

Marketing Navbar

Full marketing navbar with all slots populated:

tsx
import { Navbar, Button, Avatar } from '@kushagradhawan/kookie-ui';
 
export function MarketingNavbar() {
  return (
    <Navbar.Root>
      <Navbar.Logo>
        <Avatar src="/logo.png" fallback="B" size="2" />
      </Navbar.Logo>
 
      <Navbar.Navigation>
        <Button variant="ghost">Features</Button>
        <Button variant="ghost">Pricing</Button>
        <Button variant="ghost">Blog</Button>
        <Button variant="ghost">Docs</Button>
      </Navbar.Navigation>
 
      <Navbar.Actions gap="2">
        <Button variant="ghost">Sign In</Button>
        <Button variant="solid" highContrast>Get Started</Button>
      </Navbar.Actions>
    </Navbar.Root>
  );
}

Slot Architecture

Navbar acts as a layout container with three semantic slots. Each slot has a specific purpose and behavior. Visualize the slot boundaries to understand the layout:

tsx
import { Navbar, Flex, Text } from '@kushagradhawan/kookie-ui';
 
const slotStyle = {
  border: '1px dashed var(--crimson-8)',
  background: 'repeating-linear-gradient(135deg, transparent, transparent 4px, var(--crimson-3) 4px, var(--crimson-3) 5px)',
};
 
export function SlotVisualization() {
  return (
    <Navbar.Root position="static">
      <Navbar.Logo>
        <Flex p="3" align="center" justify="center" style={slotStyle}>
          <Text size="2" color="gray">Logo Slot</Text>
        </Flex>
      </Navbar.Logo>
 
      <Navbar.Navigation style={{ flex: 1 }}>
        <Flex py="3" px="6" align="center" justify="center" width="100%" style={slotStyle}>
          <Text size="2" color="gray">Navigation Slot (expands)</Text>
        </Flex>
      </Navbar.Navigation>
 
      <Navbar.Actions>
        <Flex p="3" align="center" justify="center" style={slotStyle}>
          <Text size="2" color="gray">Actions Slot</Text>
        </Flex>
      </Navbar.Actions>
    </Navbar.Root>
  );
}

With Icons

Add icons to navigation items for visual clarity:

tsx
import { HugeiconsIcon } from '@hugeicons/react';
import { Home01Icon, Settings01Icon, Notification01Icon, User01Icon } from '@hugeicons/core-free-icons';
import { Navbar, Button, IconButton, Text } from '@kushagradhawan/kookie-ui';
 
export function IconNavbar() {
  return (
    <Navbar.Root>
      <Navbar.Logo>
        <Text weight="bold">Brand</Text>
      </Navbar.Logo>
      <Navbar.Navigation>
        <Button variant="ghost">
          <HugeiconsIcon icon={Home01Icon} />
          Home
        </Button>
        <Button variant="ghost">
          <HugeiconsIcon icon={Settings01Icon} />
          Settings
        </Button>
      </Navbar.Navigation>
      <Navbar.Actions>
        <IconButton variant="ghost" aria-label="Notifications">
          <HugeiconsIcon icon={Notification01Icon} />
        </IconButton>
        <IconButton variant="ghost" aria-label="Profile">
          <HugeiconsIcon icon={User01Icon} />
        </IconButton>
      </Navbar.Actions>
    </Navbar.Root>
  );
}

With Next.js Link

Integrate with Next.js routing using asChild:

tsx
import Link from 'next/link';
import { Navbar, Button, Text } from '@kushagradhawan/kookie-ui';
 
export function NextNavbar() {
  return (
    <Navbar.Root>
      <Navbar.Logo asChild>
        <Link href="/">
          <Text weight="bold">Brand</Text>
        </Link>
      </Navbar.Logo>
      <Navbar.Navigation>
        <Button variant="ghost" asChild>
          <Link href="/products">Products</Link>
        </Button>
        <Button variant="ghost" asChild>
          <Link href="/about">About</Link>
        </Button>
      </Navbar.Navigation>
    </Navbar.Root>
  );
}

With User Menu

Dashboard navbar with dropdown user menu:

tsx
import { Navbar, Button, Avatar, DropdownMenu, Text } from '@kushagradhawan/kookie-ui';
 
export function DashboardNavbar() {
  return (
    <Navbar.Root>
      <Navbar.Logo>
        <Text weight="bold">Dashboard</Text>
      </Navbar.Logo>
      <Navbar.Navigation>
        <Button variant="ghost">Overview</Button>
        <Button variant="ghost">Analytics</Button>
        <Button variant="ghost">Reports</Button>
      </Navbar.Navigation>
      <Navbar.Actions>
        <DropdownMenu.Root>
          <DropdownMenu.Trigger>
            <Button variant="ghost">
              <Avatar size="1" fallback="JD" />
              John Doe
            </Button>
          </DropdownMenu.Trigger>
          <DropdownMenu.Content>
            <DropdownMenu.Item>Profile</DropdownMenu.Item>
            <DropdownMenu.Item>Settings</DropdownMenu.Item>
            <DropdownMenu.Separator />
            <DropdownMenu.Item color="red">Sign Out</DropdownMenu.Item>
          </DropdownMenu.Content>
        </DropdownMenu.Root>
      </Navbar.Actions>
    </Navbar.Root>
  );
}

Minimal Logo Only

When you only need branding without navigation:

tsx
import { Navbar, Button, Avatar } from '@kushagradhawan/kookie-ui';
 
export function MinimalNavbar() {
  return (
    <Navbar.Root>
      <Navbar.Logo>
        <Avatar src="/logo.png" fallback="B" size="2" />
      </Navbar.Logo>
      <Navbar.Actions>
        <Button variant="soft" color="gray" highContrast>Contact</Button>
      </Navbar.Actions>
    </Navbar.Root>
  );
}

With Shell Layout

Combine Navbar with Shell for complete page layouts:

tsx
import { Navbar, Button, Text } from '@kushagradhawan/kookie-ui';
import { Shell } from '@kushagradhawan/kookie-ui';
 
export function AppLayout() {
  return (
    <Shell.Root>
      <Navbar.Root position="fixed">
        <Navbar.Logo>
          <Text weight="bold">App</Text>
        </Navbar.Logo>
        <Navbar.Navigation>
          <Button variant="ghost">Dashboard</Button>
          <Button variant="ghost">Projects</Button>
        </Navbar.Navigation>
        <Navbar.Actions>
          <Button variant="soft">Sign In</Button>
        </Navbar.Actions>
      </Navbar.Root>
      <Shell.Content>
        {/* Page content */}
      </Shell.Content>
    </Shell.Root>
  );
}

Position

Use the position prop to control how the navbar behaves when scrolling.

Fixed

Fixed navbars stay at the top of the viewport. Content scrolls beneath them. Add padding to your page content to prevent overlap.

tsx
<Navbar.Root position="fixed">
  <Navbar.Logo>
    <Text weight="bold">Brand</Text>
  </Navbar.Logo>
</Navbar.Root>

Sticky

Sticky navbars scroll with content until they reach the top, then stick in place.

tsx
<Navbar.Root position="sticky">
  <Navbar.Logo>
    <Text weight="bold">Brand</Text>
  </Navbar.Logo>
</Navbar.Root>

Static

Static navbars flow with the document and scroll out of view.

tsx
<Navbar.Root position="static">
  <Navbar.Logo>
    <Text weight="bold">Brand</Text>
  </Navbar.Logo>
</Navbar.Root>

Size

Use the size prop to control navbar padding. Height is content-driven, adjusting automatically to fit your content.

Size 1

Compact padding for dense interfaces or mobile layouts.

tsx
<Navbar.Root size="1">
  <Navbar.Logo>
    <Text weight="bold">Brand</Text>
  </Navbar.Logo>
</Navbar.Root>

Size 2

Standard padding for most applications. The default size.

tsx
<Navbar.Root size="2">
  <Navbar.Logo>
    <Text weight="bold">Brand</Text>
  </Navbar.Logo>
</Navbar.Root>

Size 3

Spacious padding for prominent headers or when you want more breathing room.

tsx
<Navbar.Root size="3">
  <Navbar.Logo>
    <Text weight="bold">Brand</Text>
  </Navbar.Logo>
</Navbar.Root>

Slots

Navbar exposes three semantic slots that handle layout automatically. Understanding slot behavior helps you build effective navigation.

Logo

The Logo slot is designed for brand identity elements. It never shrinks and stays left-aligned.

tsx
<Navbar.Root>
  <Navbar.Logo>
    <img src="/logo.svg" alt="Company Logo" height={32} />
  </Navbar.Logo>
</Navbar.Root>

Navigation

The Navigation slot expands to fill available space and centers its content. Use it for primary navigation links.

tsx
<Navbar.Root>
  <Navbar.Navigation>
    <Button variant="ghost">Products</Button>
    <Button variant="ghost">Solutions</Button>
    <Button variant="ghost">Pricing</Button>
    <Button variant="ghost">Docs</Button>
  </Navbar.Navigation>
</Navbar.Root>

Actions

The Actions slot is right-aligned and never shrinks. Use it for CTAs, user menus, and utility controls.

tsx
<Navbar.Root>
  <Navbar.Actions>
    <Button variant="ghost">Log In</Button>
    <Button variant="solid">Sign Up</Button>
  </Navbar.Actions>
</Navbar.Root>

Polymorphism

AsChild

Use the asChild prop on any slot to merge its props with a child element. This is useful for custom wrappers or routing integration.

tsx
<Navbar.Root>
  <Navbar.Logo asChild>
    <a href="/">
      <Text weight="bold">Brand</Text>
    </a>
  </Navbar.Logo>
  <Navbar.Navigation asChild>
    <nav>
      <a href="/products">Products</a>
      <a href="/about">About</a>
    </nav>
  </Navbar.Navigation>
</Navbar.Root>

Accessibility

The Navbar component follows WAI-ARIA best practices for navigation landmarks.

Semantic Structure

  • Navbar.Root renders as a semantic <header> element
  • Navbar.Navigation renders as a <nav> element with role="navigation"
  • Proper heading hierarchy should be maintained within logo content

Keyboard Navigation

  • All interactive elements within the navbar are keyboard accessible
  • Focus order follows visual order: logo, navigation, actions
  • Use Button or Link components for interactive elements to ensure proper focus handling

Screen Readers

  • The <header> landmark helps screen reader users identify the navigation area
  • The <nav> element within Navigation slot provides additional context
  • Ensure all interactive elements have appropriate labels

Changelog

Changed

  • Replaced height prop with size prop (1, 2, 3) for padding-based sizing
  • Height is now content-driven instead of fixed
  • Slots now extend FlexProps for full layout control (gap, align, justify, etc.)

Added

  • Initial release with compound component architecture
  • Semantic slots for Logo, Navigation, and Actions
  • Position variants: fixed, sticky, static
  • Size options: 1 (compact), 2 (default), 3 (spacious)
  • asChild prop for all slots using Radix Slot pattern
  • Responsive gap adjustments for mobile layouts
© 2026 Kushagra Dhawan. Licensed under MIT. GitHub.

Theme

Accent color

Gray color

Appearance

Radius

Scaling

Panel background