{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "mega-menu",
  "title": "Mega Menu",
  "author": "Ballmac <https://ui.ballmac.com>",
  "description": "A data-driven header menu with wide panels of grouped, described links, an optional featured card, and an accordion list for small screens.",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "utils",
    "https://ui.ballmac.com/r/navigation-menu.json",
    "https://ui.ballmac.com/r/i18n.json"
  ],
  "files": [
    {
      "path": "registry/ballmac/components/mega-menu.tsx",
      "content": "// Ballmac UI: Mega Menu. https://ui.ballmac.com/components/mega-menu\n\"use client\";\n\nimport * as React from \"react\";\nimport { ArrowRight, ChevronDown } from \"lucide-react\";\nimport {\n  NavigationMenu,\n  NavigationMenuContent,\n  NavigationMenuItem,\n  NavigationMenuLink,\n  NavigationMenuList,\n  NavigationMenuTrigger,\n} from \"@/components/ballmac/navigation-menu\";\nimport { cn } from \"@/lib/utils\";\nimport { useMessages } from \"@/lib/ballmac/i18n\";\n\ntype MegaMenuLinkItem = {\n  /** Link title. */\n  title: string;\n  /** Destination. */\n  href: string;\n  /** One line under the title. */\n  description?: string;\n  /** Icon shown in a tile before the title. */\n  icon?: React.ReactNode;\n  /** Small label after the title, such as \"New\". */\n  badge?: string;\n};\n\ntype MegaMenuColumn = {\n  /** Small heading above the links. */\n  title?: string;\n  links: MegaMenuLinkItem[];\n};\n\ntype MegaMenuFeatured = {\n  title: string;\n  description: string;\n  href: string;\n  /** Call-to-action text. */\n  cta?: string;\n  /** Visual area above the text: an icon, illustration or gradient element. */\n  media?: React.ReactNode;\n};\n\ntype MegaMenuItem =\n  | { label: string; href: string }\n  | { label: string; columns: MegaMenuColumn[]; featured?: MegaMenuFeatured };\n\ntype MegaMenuProps = Omit<React.ComponentProps<typeof NavigationMenu>, \"children\"> & {\n  /** Top-level entries: a plain link (`href`) or a panel (`columns`, optionally `featured`). */\n  items: MegaMenuItem[];\n  /** Accessible name of the navigation landmark. */\n  label?: string;\n};\n\nfunction isPanel(item: MegaMenuItem): item is Extract<MegaMenuItem, { columns: MegaMenuColumn[] }> {\n  return \"columns\" in item;\n}\n\nfunction LinkCard({ link }: { link: MegaMenuLinkItem }) {\n  return (\n    <NavigationMenuLink\n      href={link.href}\n      className=\"group/link flex-row items-start gap-3 rounded-xl p-2.5\"\n    >\n      {link.icon && (\n        <span className=\"flex size-9 shrink-0 items-center justify-center rounded-lg border bg-background text-foreground shadow-xs transition-colors group-hover/link:border-ring/40 [&_svg]:size-4\">\n          {link.icon}\n        </span>\n      )}\n      <span className=\"grid min-w-0 gap-0.5\">\n        <span className=\"flex items-center gap-2 text-sm font-medium\">\n          {link.title}\n          {link.badge && (\n            <span className=\"rounded-full bg-primary/10 px-1.5 py-px text-[10px] font-semibold tracking-wide text-primary uppercase\">\n              {link.badge}\n            </span>\n          )}\n        </span>\n        {link.description && <span className=\"text-xs leading-snug text-muted-foreground\">{link.description}</span>}\n      </span>\n    </NavigationMenuLink>\n  );\n}\n\n/**\n * A data-driven mega menu on Navigation Menu: wide panels with grouped, described links and an optional featured card.\n * Shown from the `md` breakpoint up; pair it with MegaMenuMobileList inside your mobile menu.\n */\nfunction MegaMenu({ items, label, className, viewportAlign = \"center\", ...props }: MegaMenuProps) {\n  const msg = useMessages()\n  label ??= msg(\"mega-menu.label\", \"Main\")\n  return (\n    <NavigationMenu\n      aria-label={label}\n      viewportAlign={viewportAlign}\n      data-slot=\"mega-menu\"\n      className={cn(\"hidden md:flex\", className)}\n      {...props}\n    >\n      <NavigationMenuList>\n        {items.map((item) =>\n          isPanel(item) ? (\n            <NavigationMenuItem key={item.label}>\n              <NavigationMenuTrigger>{item.label}</NavigationMenuTrigger>\n              <NavigationMenuContent>\n                <div\n                  className={cn(\n                    \"grid gap-2 p-1 md:w-[min(46rem,calc(100vw-3rem))]\",\n                    item.featured ? \"md:grid-cols-[1fr_1fr_14rem]\" : item.columns.length > 1 ? \"md:grid-cols-2\" : \"md:w-80\",\n                  )}\n                >\n                  {item.columns.map((column, index) => (\n                    <div key={column.title ?? index} className=\"grid content-start gap-0.5\">\n                      {column.title && (\n                        <p className=\"px-2.5 pt-1.5 pb-1 text-[11px] font-semibold tracking-wide text-muted-foreground uppercase\">\n                          {column.title}\n                        </p>\n                      )}\n                      {column.links.map((link) => (\n                        <LinkCard key={link.href} link={link} />\n                      ))}\n                    </div>\n                  ))}\n                  {item.featured && (\n                    <NavigationMenuLink\n                      href={item.featured.href}\n                      className=\"group/featured row-span-1 justify-between gap-3 rounded-xl border bg-gradient-to-br from-primary/10 via-muted/60 to-muted/30 p-4 hover:from-primary/15\"\n                    >\n                      <span className=\"flex min-h-20 items-center justify-center text-primary [&_svg]:size-10\">\n                        {item.featured.media}\n                      </span>\n                      <span className=\"grid gap-1\">\n                        <span className=\"text-sm font-semibold\">{item.featured.title}</span>\n                        <span className=\"text-xs leading-snug text-muted-foreground\">{item.featured.description}</span>\n                        <span className=\"mt-1 inline-flex items-center gap-1 text-xs font-medium text-foreground\">\n                          {item.featured.cta ?? msg(\"mega-menu.learnMore\", \"Learn more\")}\n                          <ArrowRight\n                            aria-hidden=\"true\"\n                            className=\"size-3 transition-transform group-hover/featured:translate-x-0.5 motion-reduce:transition-none rtl:rotate-180 rtl:group-hover/featured:-translate-x-0.5\"\n                          />\n                        </span>\n                      </span>\n                    </NavigationMenuLink>\n                  )}\n                </div>\n              </NavigationMenuContent>\n            </NavigationMenuItem>\n          ) : (\n            <NavigationMenuItem key={item.label}>\n              <NavigationMenuLink href={item.href} topLevel>\n                {item.label}\n              </NavigationMenuLink>\n            </NavigationMenuItem>\n          ),\n        )}\n      </NavigationMenuList>\n    </NavigationMenu>\n  );\n}\n\ntype MegaMenuMobileListProps = React.ComponentProps<\"div\"> & {\n  items: MegaMenuItem[];\n  /** Called when a link is chosen, for example to close a sheet. */\n  onNavigate?: () => void;\n};\n\n/** The same items as accordions for small screens. Uses native disclosure elements, so it works without JavaScript. */\nfunction MegaMenuMobileList({ items, onNavigate, className, ...props }: MegaMenuMobileListProps) {\n  return (\n    <div data-slot=\"mega-menu-mobile\" className={cn(\"grid gap-1\", className)} {...props}>\n      {items.map((item) =>\n        isPanel(item) ? (\n          <details key={item.label} className=\"group/details rounded-lg\">\n            <summary className=\"flex h-11 cursor-pointer list-none items-center justify-between rounded-lg px-3 text-[15px] font-medium outline-none hover:bg-accent focus-visible:ring-[3px] focus-visible:ring-ring/50 [&::-webkit-details-marker]:hidden\">\n              {item.label}\n              <ChevronDown\n                aria-hidden=\"true\"\n                className=\"size-4 text-muted-foreground transition-transform group-open/details:rotate-180 motion-reduce:transition-none\"\n              />\n            </summary>\n            <div className=\"grid gap-0.5 pt-1 pb-2 ps-3\">\n              {item.columns.flatMap((column) => column.links).map((link) => (\n                <a\n                  key={link.href}\n                  href={link.href}\n                  onClick={onNavigate}\n                  className=\"grid gap-0.5 rounded-lg px-3 py-2 outline-none hover:bg-accent focus-visible:ring-[3px] focus-visible:ring-ring/50\"\n                >\n                  <span className=\"text-sm font-medium\">{link.title}</span>\n                  {link.description && <span className=\"text-xs text-muted-foreground\">{link.description}</span>}\n                </a>\n              ))}\n            </div>\n          </details>\n        ) : (\n          <a\n            key={item.label}\n            href={item.href}\n            onClick={onNavigate}\n            className=\"flex h-11 items-center rounded-lg px-3 text-[15px] font-medium outline-none hover:bg-accent focus-visible:ring-[3px] focus-visible:ring-ring/50\"\n          >\n            {item.label}\n          </a>\n        ),\n      )}\n    </div>\n  );\n}\n\nexport {\n  MegaMenu,\n  MegaMenuMobileList,\n  type MegaMenuProps,\n  type MegaMenuItem,\n  type MegaMenuColumn,\n  type MegaMenuLinkItem,\n  type MegaMenuFeatured,\n  type MegaMenuMobileListProps,\n};\n",
      "type": "registry:ui",
      "target": "@components/ballmac/mega-menu.tsx"
    }
  ],
  "meta": {
    "schema": 1,
    "tier": "free",
    "tags": [
      "navigation",
      "dropdown",
      "header",
      "radix"
    ],
    "version": "1.0.0",
    "updated": "2026-09-30",
    "ai": {
      "summary": "Pass items: a plain link ({label, href}) or a panel ({label, columns, featured}). MegaMenuMobileList renders the same data for the mobile menu.",
      "whenToUse": [
        "Sites with many products or solutions",
        "Headers that need descriptions beside links"
      ],
      "whenNotToUse": [
        "A handful of plain links; use navbar",
        "Application commands; use menubar"
      ],
      "composesWith": [
        "navbar",
        "navigation-menu"
      ],
      "a11y": [
        {
          "keys": "Enter / Space / ArrowDown",
          "action": "Opens the focused panel"
        },
        {
          "keys": "ArrowLeft / ArrowRight",
          "action": "Moves between top-level items"
        },
        {
          "keys": "Tab",
          "action": "Enters the panel links"
        },
        {
          "keys": "Escape",
          "action": "Closes the panel"
        }
      ],
      "customization": [
        "columns with titles",
        "featured card with media and cta",
        "badge on links",
        "viewportAlign start | center"
      ]
    },
    "examples": [
      "mega-menu-demo",
      "mega-menu-states"
    ],
    "url": "https://ui.ballmac.com/components/mega-menu"
  },
  "categories": [
    "navigation"
  ],
  "type": "registry:ui"
}