Skip to content

Navbar Mega

Navbar with a full-width Product mega menu: six icon + description items in a 3-column grid and a featured launch card, closes on outside click and Escape; grouped mobile menu.

minimal/section/navbar-mega
Open ↗

Source

"use client";

import { useEffect, useId, useRef, useState, type ComponentType, type SVGProps } from "react";
import { Activity, BellRing, BookOpen, ChevronDown, FileText, Gauge, Menu, Radio, Users, X } from "lucide-react";
import { cn } from "@/lib/utils";

export interface NavbarMegaItem {
  label: string;
  description: string;
  href: string;
  icon: ComponentType<SVGProps<SVGSVGElement>>;
}

export interface NavbarMegaProps {
  brand?: string;
  brandHref?: string;
  /** Items listed in the “Product” mega menu. */
  productItems?: NavbarMegaItem[];
  /** Featured card on the right of the mega menu. */
  featured?: { eyebrow: string; title: string; href: string };
  links?: { label: string; href: string }[];
  signIn?: { label: string; href: string };
  cta?: { label: string; href: string };
  className?: string;
}

const DEFAULT_ITEMS: NavbarMegaItem[] = [
  { label: "Alerting", description: "Route alerts from 60+ sources to the right person.", href: "#alerting", icon: BellRing },
  { label: "On-call", description: "Rotations, overrides and fair escalation policies.", href: "#on-call", icon: Users },
  { label: "Incidents", description: "Slack-native war rooms with a live timeline.", href: "#incidents", icon: Activity },
  { label: "Status pages", description: "Public and private pages that update themselves.", href: "#status", icon: Radio },
  { label: "Postmortems", description: "AI-drafted reviews from the incident timeline.", href: "#postmortems", icon: FileText },
  { label: "Insights", description: "MTTA, MTTR and on-call load, by team and service.", href: "#insights", icon: Gauge },
];

/** Navbar with a “Product” mega menu (6 items + featured card), keyboard and Escape friendly. */
export function NavbarMega({
  brand = "Tracewise",
  brandHref = "/",
  productItems = DEFAULT_ITEMS,
  featured = { eyebrow: "New · Oct 2026", title: "Tracewise AI drafts your postmortem while you sleep", href: "#ai" },
  links = [
    { label: "Customers", href: "#customers" },
    { label: "Pricing", href: "#pricing" },
    { label: "Docs", href: "#docs" },
  ],
  signIn = { label: "Log in", href: "#login" },
  cta = { label: "Start free", href: "#signup" },
  className,
}: NavbarMegaProps) {
  const [menu, setMenu] = useState(false);
  const [mobile, setMobile] = useState(false);
  const panelId = useId();
  const mobileId = useId();
  const root = useRef<HTMLElement>(null);
  const trigger = useRef<HTMLButtonElement>(null);

  useEffect(() => {
    if (!menu && !mobile) return;
    const onKey = (e: KeyboardEvent) => {
      if (e.key !== "Escape") return;
      setMenu(false);
      setMobile(false);
      trigger.current?.focus();
    };
    const onClick = (e: MouseEvent) => {
      if (root.current && !root.current.contains(e.target as Node)) setMenu(false);
    };
    window.addEventListener("keydown", onKey);
    document.addEventListener("mousedown", onClick);
    return () => {
      window.removeEventListener("keydown", onKey);
      document.removeEventListener("mousedown", onClick);
    };
  }, [menu, mobile]);

  return (
    <header ref={root} className={cn("relative z-40 border-b border-da-border bg-da-bg text-da-fg", className)}>
      <nav aria-label="Main" className="da-container flex h-14 items-center gap-6">
        <a href={brandHref} className="da-focus flex items-center gap-2 rounded-da-sm text-[15px] font-semibold tracking-tight">
          <span aria-hidden className="grid size-6 place-items-center rounded-da-sm bg-da-primary text-[11px] font-bold text-da-primary-fg">
            T
          </span>
          {brand}
        </a>
        <ul className="hidden items-center gap-1 md:flex">
          <li>
            <button
              ref={trigger}
              type="button"
              aria-expanded={menu}
              aria-controls={panelId}
              onClick={() => setMenu((m) => !m)}
              className={cn(
                "da-focus da-transition inline-flex items-center gap-1 rounded-da-md px-3 py-1.5 text-sm hover:text-da-fg",
                menu ? "bg-da-muted text-da-fg" : "text-da-muted-fg",
              )}
            >
              Product
              <ChevronDown aria-hidden className={cn("da-transition size-3.5", menu && "rotate-180")} />
            </button>
          </li>
          {links.map((l) => (
            <li key={l.href}>
              <a href={l.href} className="da-focus da-transition rounded-da-md px-3 py-1.5 text-sm text-da-muted-fg hover:text-da-fg">
                {l.label}
              </a>
            </li>
          ))}
        </ul>
        <div className="ml-auto hidden items-center gap-2 md:flex">
          <a href={signIn.href} className="da-focus da-transition rounded-da-md px-3 py-1.5 text-sm text-da-muted-fg hover:text-da-fg">
            {signIn.label}
          </a>
          <a
            href={cta.href}
            className="da-focus da-transition inline-flex h-8 items-center rounded-da-md bg-da-primary px-3.5 text-sm font-medium text-da-primary-fg hover:bg-da-primary/90"
          >
            {cta.label}
          </a>
        </div>
        <button
          type="button"
          aria-expanded={mobile}
          aria-controls={mobileId}
          aria-label={mobile ? "Close menu" : "Open menu"}
          onClick={() => setMobile((o) => !o)}
          className="da-focus ml-auto grid size-9 place-items-center rounded-da-md text-da-muted-fg hover:bg-da-muted md:hidden"
        >
          {mobile ? <X aria-hidden className="size-5" /> : <Menu aria-hidden className="size-5" />}
        </button>
      </nav>

      {/* Desktop mega panel */}
      <div
        id={panelId}
        hidden={!menu}
        className="absolute inset-x-0 top-full hidden border-b border-da-border bg-da-surface text-da-surface-fg shadow-da-lg transition-[opacity,translate] duration-(--da-duration) ease-da starting:-translate-y-1 starting:opacity-0 md:block"
      >
        <div className="da-container grid gap-6 py-6 lg:grid-cols-[1fr_280px]">
          <ul className="grid gap-1 sm:grid-cols-2 lg:grid-cols-3">
            {productItems.map((item) => (
              <li key={item.href}>
                <a href={item.href} onClick={() => setMenu(false)} className="da-focus da-transition group flex gap-3 rounded-da-md p-3 hover:bg-da-muted">
                  <span className="da-stroke grid size-8 shrink-0 place-items-center rounded-da-sm bg-da-bg text-da-muted-fg group-hover:text-da-accent-fg">
                    <item.icon aria-hidden className="size-4" />
                  </span>
                  <span>
                    <span className="block text-sm font-medium">{item.label}</span>
                    <span className="mt-0.5 block text-[13px] leading-snug text-da-muted-fg">{item.description}</span>
                  </span>
                </a>
              </li>
            ))}
          </ul>
          <a
            href={featured.href}
            className="da-focus da-transition da-stroke group relative hidden overflow-hidden rounded-da-lg bg-da-accent p-5 text-da-accent-fg lg:block"
          >
            <span aria-hidden className="absolute -top-10 -right-10 size-40 rounded-full bg-da-primary/25 blur-2xl" />
            <span className="relative font-da-mono text-[11px]">{featured.eyebrow}</span>
            <span className="relative mt-2 block text-[15px] leading-snug font-medium">{featured.title}</span>
            <span className="relative mt-4 inline-flex items-center gap-1 text-[13px] font-medium">
              <BookOpen aria-hidden className="size-3.5" /> Read the launch post
            </span>
          </a>
        </div>
      </div>

      {/* Mobile */}
      <div id={mobileId} hidden={!mobile} className="border-t border-da-border md:hidden">
        <p className="da-container pt-3 pb-1 font-da-mono text-[11px] text-da-muted-fg">Product</p>
        <ul className="da-container grid grid-cols-2 gap-1">
          {productItems.map((item) => (
            <li key={item.href}>
              <a href={item.href} className="da-focus flex items-center gap-2 rounded-da-md px-2 py-2 text-sm hover:bg-da-muted">
                <item.icon aria-hidden className="size-4 text-da-muted-fg" />
                {item.label}
              </a>
            </li>
          ))}
        </ul>
        <ul className="da-container mt-2 border-t border-da-border pt-2 pb-3">
          {links.map((l) => (
            <li key={l.href}>
              <a href={l.href} className="da-focus block rounded-da-md px-2 py-2.5 text-[15px] hover:bg-da-muted">
                {l.label}
              </a>
            </li>
          ))}
          <li className="mt-2 grid grid-cols-2 gap-2">
            <a href={signIn.href} className="da-focus da-stroke rounded-da-md py-2 text-center text-sm font-medium">
              {signIn.label}
            </a>
            <a href={cta.href} className="da-focus rounded-da-md bg-da-primary py-2 text-center text-sm font-medium text-da-primary-fg">
              {cta.label}
            </a>
          </li>
        </ul>
      </div>
    </header>
  );
}

export default NavbarMega;

modules/minimal/section/navbar-mega/index.tsx

Props

PropTypeDefaultDescription
brand / brandHrefstring—Brand.
productItems{ label, description, href, icon }[]—Mega menu items (icon = lucide component).
featured{ eyebrow, title, href }—Featured card.
links{ label, href }[]—Other top-level links.
signIn / cta{ label, href }—Actions.
classNamestring—Classes on the header.

Other navbar variants in Minimal

Navbar in other art directions

Navbar Bold

Sticky top bar with square logo mark, mono uppercase links, underlined login and a pressable yellow CTA. Collapses into a full-width stacked menu on mobile.

BrutalistNavbar

Navbar Centered

Boxed navbar card with a hard shadow: links split left and right around a tilted yellow wordmark sticker in the center, ink CTA pressing into its shadow. Mobile opens a two-column ruled menu grid.

BrutalistNavbar

Navbar Overlay

Minimal bar (wordmark + ink MENU button with animated burger) that opens a full-screen yellow overlay with giant numbered links sliding on hover, a contact line and CTA. Same menu on every screen size.

BrutalistNavbar

Navbar Ticker

Two-tier sticky header: a scrolling ink announcement ticker on top, then a ruled bar where every link is a full-height cell that floods yellow on hover and a blue CTA block on the right.

BrutalistNavbar

Navbar Bar

Full-width sticky frosted bar with a Features dropdown that opens a glass panel of four icon cards, plain links and a gradient pill CTA; stacked mobile menu.

GlassNavbar

Navbar Dock

macOS-style floating bottom dock: a glass pill of round icon links that magnify with a spring when hovered (neighbours too), tooltips, a gradient active item with dot and an ink CTA.

GlassNavbar

Navbar Floating

Floating frosted pill navbar detached from the top edge: gradient orb logo, centered links, gradient CTA. On mobile the pill opens a frosted dropdown panel that fades in.

GlassNavbar

Navbar Islands

Three separate floating glass islands — brand pill, centered links pill, actions pill with gradient CTA — that merge into a single button and frosted panel on mobile.

GlassNavbar

Navbar Fullscreen

Minimal bar (logo + “Menu”) that opens a full-screen ink overlay with giant stacked links sliding up line by line, mono notes and contact details; Escape closes and scroll is locked.

Mono CleanNavbar

Navbar Index

Studio-style index navbar: numbered links “(01) Work”, a live local clock with city in mono, availability dot in the signal color and an underlined text CTA; stacked list on mobile.

Mono CleanNavbar

Navbar Meta

Two-tier editorial header: a mono meta strip (version, status with signal dot, changelog link) over a nav bar closed by a full-ink rule; oversize logo wordmark on desktop; stacked menu on mobile.

Mono CleanNavbar

Navbar Mono

Clean monochrome navbar on a hairline: square logo, links whose underline wipes in on hover (orange dot marks the active one), text sign-in and an ink button; text “Menu/Close” toggle opens a ruled list on mobile.

Mono CleanNavbar

Navbar Corporate

Corporate navbar: logo, two dropdown menus (items with descriptions), plain links, “Sign in”, bordered “Contact sales” and a blue primary; mobile accordion menu.

Neo CorporateNavbar

Navbar Mega

Navbar with a wide “Platform” mega menu: three titled columns of icon links plus a navy promo card, closing on Escape/outside click; stacked on mobile.

Neo CorporateNavbar

Navbar Scroll

Sticky navbar that starts tall and transparent and condenses on scroll into a white bordered bar with a subtle shadow and a smaller CTA.

Neo CorporateNavbar

Navbar Utility

Two-tier enterprise header: a slim surface-2 utility bar (system status, sales phone, language select, support/login) above the main navbar.

Neo CorporateNavbar

Navbar Announce

Sage announcement strip (leaf icon, message, link, dismiss) above a simple cream navbar with a terracotta-tinted secondary pill and sage primary pill; drop-down menu on mobile.

Organic SoftNavbar

Navbar Floating

Floating pill navbar: a rounded, softly blurred surface bar detached from the top edge, with centered links and an arrow CTA; expands into a rounded panel on mobile.

Organic SoftNavbar

Navbar Organic

Calm cream navbar: round leaf logo + serif wordmark, links with a hand-drawn underline on the active one, text sign-in and a sage pill CTA; rounded sheet menu on mobile.

Organic SoftNavbar

Navbar Split

Editorial symmetric navbar: links split on both sides of a centered logo + large serif wordmark, a thin warm rule below, outlined pill CTA; full-width stacked menu on mobile.

Organic SoftNavbar

Navbar Centered

Symmetric navbar inside a soft rounded well: links split left and right of a centered wordmark with two overlapping dots, ink pill CTA at the far right; stacked sheet on mobile.

Soft FlatNavbar

Navbar Sheet

Minimal bar with a wordmark and a big “Menu” pill that unfolds a grid of pastel link tiles (title, description, arrow) with a staggered bouncy entrance, on every screen size.

Soft FlatNavbar

Navbar Soft

Friendly sticky navbar: rounded pastel logo mark, pill links with a soft lavender active fill, text log-in and a periwinkle pill CTA; rounded drop-down sheet on mobile.

Soft FlatNavbar

Navbar Tabs

Two-row header: brand and CTA on top, then a horizontally scrollable strip of pill tabs with emoji where the active tab is an ink-filled pill.

Soft FlatNavbar