Xzero UI
Pro library

Mega menu morphPro

A site header whose menus share one floating panel. Moving between sections morphs its size, slides the next menu in from that side and glides the caret under the new trigger, with hover intent, a safe triangle and an accordion sheet on narrow screens.

$ pnpm dlx shadcn@4.23.0 add @xzero-ui-pro/mega-menu-morph
Live · keyboard ready

When to use

When not to use

Installation

Register both Xzero UI namespaces in your project's components.json:

{
  "registries": {
    "@xzero-ui": "https://mcp.xzero.co.uk/r/{name}.json",
    "@xzero-ui-pro": "https://mcp.xzero.co.uk/r/pro/{name}.json"
  }
}
npx shadcn@4.23.0 add @xzero-ui-pro/mega-menu-morph

Install xzero-foundation once, and import @/components/xzero/foundation.css in your app root. No Xzero token is used by this snapshot. For sample portraits, photos, fonts, or logos, download https://mcp.xzero.co.uk/install-assets.mjs and run node xzero-install-assets.mjs <receiving-project>.

Usage

import { MegaMenuMorph } from "@/components/xzero/mega-menu-morph/mega-menu-morph";
import type { MegaMenuItem } from "@/components/xzero/mega-menu-morph/mega-menu-morph";
import { BookOpen, CreditCard, Repeat, Zap } from "lucide-react";

const items: MegaMenuItem[] = [
  {
    value: "products",
    label: "Products",
    groups: [{ title: "Payments", links: [
      { label: "Checkout", description: "Hosted pages in 46 currencies", icon: <CreditCard />, href: "/checkout" },
      { label: "Billing", description: "Subscriptions, usage and invoices", icon: <Repeat />, href: "/billing" },
    ] }],
    feature: { title: "Instant payouts in the EU", description: "Sellers now get paid in seconds.", cta: "Read the announcement", href: "/blog/instant-payouts" },
  },
  {
    value: "developers",
    label: "Developers",
    groups: [{ title: "Documentation", links: [
      { label: "Quickstart", icon: <Zap />, href: "/docs/quickstart" },
      { label: "API reference", icon: <BookOpen />, href: "/docs/api" },
    ] }],
    footer: <span>All systems normal</span>,
  },
  { value: "pricing", label: "Pricing", href: "/pricing" },
];

export function SiteHeader() {
  const router = useRouter();
  const pathname = usePathname();
  return (
    <MegaMenuMorph
      items={items}
      brand={{ name: "Tally", mark: <TallyMark />, href: "/" }}
      actions={[{ label: "Sign in", href: "/login" }, { label: "Start now", href: "/signup", variant: "primary" }]}
      current={pathname.startsWith("/docs") ? "developers" : undefined}
      onNavigate={destination => destination.href && router.push(destination.href)}
    />
  );
}

API reference

MegaMenuMorph

A site header whose menus share one floating surface. Moving from one section to the next morphs the surface to the new menu's width and height, glides it and its caret under the new trigger and slides the content in from the side you came from, instead of closing one menu and opening another. A highlight follows the pointer across the triggers, a muted footer band grows and shrinks with the panel, hover intent and a safe triangle keep diagonal moves toward the open menu from switching sections, and a header too narrow for its row folds into a full width accordion sheet.

PropTypeDefaultDescription
itemsMegaMenuItem[]megaMenuSampleItemsSections of the header, in order. An item with groups or a feature opens a menu; an item without them is a plain link. Each item is { value, label, href?, groups?: { title?, links: { label, description?, icon?, href?, badge? }[] }[], feature?: { title, description?, cta?, href?, media? }, footer? }.
brand{ name: string; mark?: ReactNode; href?: string }Tally sample brandMark and name at the start of the header. Choosing it calls onNavigate.
actionsMegaMenuAction[]Sign in and Start nowActions at the end of the header, each { label, href?, onClick?, variant?: "primary" | "quiet" }. When the header folds, primary actions stay in the bar and quiet ones move to the bottom of the sheet.
valuestring | null–The open menu, controlled. null keeps every menu closed. Pair with onValueChange.
defaultValuestring | nullnullThe menu open on first render when uncontrolled.
onValueChange(value: string | null) => void–Called with the menu that should open, or null when menus close, from hover, click, keyboard, Escape, focus leaving or an outside press.
currentstring–Value of the section that holds the current page. Its trigger carries a short accent mark and plain links get aria-current="page".
openDelaynumber90How long in ms the pointer rests on a trigger before the first menu opens. Once a menu is open, moving to another trigger switches at once unless the pointer is heading into the open menu.
closeDelaynumber240Grace period in ms after the pointer leaves the header and the menu before the menu closes. Re-entering cancels it.
collapseBelownumber | "auto""auto"Header width in px below which the sections fold into the accordion sheet. "auto" measures the natural width of the full row and folds exactly when it stops fitting.
showSafeAreabooleanfalseDraws the safe triangle from the pointer to the top corners of the open menu, tinted with the accent while it is holding a switch back. A development aid for tuning hover behavior.
onNavigate(destination: MegaMenuDestination) => void–Called with { label, href?, section? } for every destination: links, feature cards, plain sections, actions and the brand. When set, the default link navigation is prevented so you can route yourself; menus and the sheet close either way.
labelstring"Main"Accessible name of the navigation landmark.
classNamestring–Class on the root element.
styleCSSProperties–Inline styles on the root element. Set --mm-bar-h to change the bar height and --mm-sheet-max to cap the folded sheet in a small host.

Keyboard interactions

KeysAction
TabMoves through the brand, the sections and the actions. From a trigger whose menu is open, Tab enters that menu; Tab from its last link moves on to the next section and closes it.
Arrow Left / Arrow RightOn the triggers, moves between sections. If a menu is open it follows focus, sliding in from that side. Inside a menu, switches to the previous or next menu and focuses its first link.
Home / EndOn the triggers, moves to the first or last section.
Enter / SpaceToggles the menu of the focused trigger; follows a focused link.
Arrow DownOn a trigger, opens its menu and focuses the first link. Inside a menu, moves to the next link.
Arrow UpInside a menu, moves to the previous link; from the first link, returns to the trigger.
EscapeCloses the open menu and returns focus to its trigger, or closes the folded sheet and returns focus to the menu button.

Accessibility

Motion

Responsive behavior

Performance

Notes for AI

Also in navigation

Guidance for AI tools

Mega menu morph: A site header whose menus share one floating panel. Moving between sections morphs its size, slides the next menu in from that side and glides the caret under the new trigger, with hover intent, a safe triangle and an accordion sheet on narrow screens. Follow the declared prop types and do not invent props. Keep keyboard access, reduced motion support, and both light and dark themes intact when adapting it.

Full library index: https://ui.xzero.co.uk/llms.txt

Browse all components