{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "navigation-menu",
  "title": "Navigation Menu",
  "description": "The marker stretches between items and the panel resizes on a spring to fit each menu.",
  "dependencies": [
    "@ui-sdk/core@0.1.0-beta.2",
    "@ui-sdk/react@0.1.0-beta.2"
  ],
  "registryDependencies": [
    "@keyframery/motion"
  ],
  "files": [
    {
      "path": "registry/components/keyframery/primitives/navigation-menu.tsx",
      "content": "\"use client\"\n\n/* Animated drop-in for `@ui-sdk/react/navigation-menu`: same parts, same props. Swap the import and keep your code.\n   This file adds motion only. Colours, radii, shadows and spacing stay yours.\n\n   - Indicator: Stretch. It travels under the open trigger: the edge facing the way it goes leaves at\n     once, the other follows 80ms later, so it stretches across the gap and closes up.\n   - Viewport: Unfold from the trigger, then resizes and moves on a spring as panels trade places.\n   - Content: Direction. A panel comes 28px from the side it was reached from, with 6px blur; the old\n     one leaves the other way. Its links (the panel's grandchildren, as in ul > li) Cascade in.\n   - Triggers: Press; their chevron turns on a spring. */\n\nimport {\n  NavigationMenuContent as NavigationMenuContentPart,\n  NavigationMenuIndicator as NavigationMenuIndicatorPart,\n  NavigationMenuTrigger as NavigationMenuTriggerPart,\n  NavigationMenuViewport as NavigationMenuViewportPart,\n} from \"@ui-sdk/react/navigation-menu\"\nimport * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nexport * from \"@ui-sdk/react/navigation-menu\"\n\n/* The same registered properties as the tabs key (shared by href). */\nconst stretchProperties = [\"la\", \"lb\", \"ra\", \"rb\", \"ta\", \"tb\", \"ba\", \"bb\"]\n  .map((n) => `@property --kf-${n}{syntax:\"<length>\";inherits:true;initial-value:0px}`)\n  .join(\"\")\n\nfunction NavigationMenuTrigger({ className, ...props }: React.ComponentProps<typeof NavigationMenuTriggerPart>) {\n  return (\n    <NavigationMenuTriggerPart\n      className={cn(\n        \"transition-[scale] duration-[calc(200ms*var(--kf-speed,1))] ease-pop active:scale-[0.96]\",\n        \"[&>svg]:transition-[rotate] [&>svg]:duration-[calc(460ms*var(--kf-speed,1))] [&>svg]:ease-spring data-open:[&>svg]:rotate-180\",\n        \"motion-reduce:transition-none! motion-reduce:[&>svg]:transition-none\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\n/* Stretch: each edge is tracked by a fast and a slow (calc(80ms*var(--kf-speed,1)) later) registered property, and the\n   inset is the smaller of the two, so the leading edge leads in either direction with no direction\n   attribute. Hidden while there is nothing to sit under, and it appears in place. */\nfunction NavigationMenuIndicator({ className, ...props }: React.ComponentProps<typeof NavigationMenuIndicatorPart>) {\n  const [ready, setReady] = React.useState(false)\n  React.useEffect(() => {\n    const timer = setTimeout(() => setReady(true), 150)\n    return () => clearTimeout(timer)\n  }, [])\n  return (\n    <>\n      <style href=\"kf-stretch\" precedence=\"default\">\n        {stretchProperties}\n      </style>\n      <NavigationMenuIndicatorPart\n        data-ready={ready || undefined}\n        className={cn(\n          \"pointer-events-none absolute hidden data-visible:block\",\n          \"[--kf-la:var(--active-item-left,0px)] [--kf-lb:var(--active-item-left,0px)] [--kf-ra:var(--active-item-right,0px)] [--kf-rb:var(--active-item-right,0px)]\",\n          \"[--kf-ta:var(--active-item-top,0px)] [--kf-tb:var(--active-item-top,0px)] [--kf-ba:var(--active-item-bottom,0px)] [--kf-bb:var(--active-item-bottom,0px)]\",\n          \"top-[min(var(--kf-ta),var(--kf-tb))] right-[min(var(--kf-ra),var(--kf-rb))] bottom-[min(var(--kf-ba),var(--kf-bb))] left-[min(var(--kf-la),var(--kf-lb))]\",\n          \"motion-reduce:transition-none! data-ready:[transition:--kf-la_calc(260ms*var(--kf-speed,1))_var(--ease-house),--kf-ra_calc(260ms*var(--kf-speed,1))_var(--ease-house),--kf-ta_calc(260ms*var(--kf-speed,1))_var(--ease-house),--kf-ba_calc(260ms*var(--kf-speed,1))_var(--ease-house),--kf-lb_calc(380ms*var(--kf-speed,1))_var(--ease-house)_calc(80ms*var(--kf-speed,1)),--kf-rb_calc(380ms*var(--kf-speed,1))_var(--ease-house)_calc(80ms*var(--kf-speed,1)),--kf-tb_calc(380ms*var(--kf-speed,1))_var(--ease-house)_calc(80ms*var(--kf-speed,1)),--kf-bb_calc(380ms*var(--kf-speed,1))_var(--ease-house)_calc(80ms*var(--kf-speed,1)),opacity_calc(200ms*var(--kf-speed,1))_var(--ease-house)]\",\n          \"starting:opacity-0\",\n          \"motion-reduce:[transition:none]!\",\n          className,\n        )}\n        {...props}\n      />\n    </>\n  )\n}\n\n/* Unfold, then follow the open item on a spring. */\nfunction NavigationMenuViewport({ className, ...props }: React.ComponentProps<typeof NavigationMenuViewportPart>) {\n  return (\n    <NavigationMenuViewportPart\n      className={cn(\n        \"origin-(--transform-origin)\",\n        \"[transition:width_calc(440ms*var(--kf-speed,1))_var(--ease-spring),height_calc(440ms*var(--kf-speed,1))_var(--ease-spring),left_calc(440ms*var(--kf-speed,1))_var(--ease-spring),top_calc(440ms*var(--kf-speed,1))_var(--ease-spring),opacity_calc(380ms*var(--kf-speed,1))_var(--ease-spring),scale_calc(380ms*var(--kf-speed,1))_var(--ease-spring),translate_calc(380ms*var(--kf-speed,1))_var(--ease-spring),filter_calc(380ms*var(--kf-speed,1))_var(--ease-spring)]\",\n        \"data-[side=bottom]:[--kf-from:0_-8px] data-[side=top]:[--kf-from:0_8px] data-[side=left]:[--kf-from:8px_0] data-[side=right]:[--kf-from:-8px_0]\",\n        \"data-starting-style:[translate:var(--kf-from,0_0)] data-starting-style:scale-[0.86] data-starting-style:opacity-0 data-starting-style:blur-[6px]\",\n        \"data-ending-style:scale-[0.96] data-ending-style:opacity-0 data-ending-style:blur-[2px]\",\n        \"data-ending-style:[transition:width_calc(150ms*var(--kf-speed,1))_var(--ease-house),height_calc(150ms*var(--kf-speed,1))_var(--ease-house),left_calc(150ms*var(--kf-speed,1))_var(--ease-house),top_calc(150ms*var(--kf-speed,1))_var(--ease-house),opacity_calc(150ms*var(--kf-speed,1))_var(--ease-house),scale_calc(150ms*var(--kf-speed,1))_var(--ease-house),translate_calc(150ms*var(--kf-speed,1))_var(--ease-house),filter_calc(150ms*var(--kf-speed,1))_var(--ease-house)]\",\n        \"motion-reduce:[transition:none]!\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\n/* Direction + Cascade. */\nfunction NavigationMenuContent({ className, ...props }: React.ComponentProps<typeof NavigationMenuContentPart>) {\n  return (\n    <NavigationMenuContentPart\n      className={cn(\n        \"transition-[opacity,translate,filter] duration-[calc(460ms*var(--kf-speed,1))] ease-spring\",\n        \"data-ending-style:duration-[calc(200ms*var(--kf-speed,1))] data-ending-style:ease-house\",\n        \"data-[motion=from-end]:data-starting-style:translate-x-7 data-[motion=from-start]:data-starting-style:-translate-x-7\",\n        \"data-[motion=to-start]:data-ending-style:-translate-x-6 data-[motion=to-end]:data-ending-style:translate-x-6\",\n        \"rtl:data-[motion=from-end]:data-starting-style:-translate-x-7 rtl:data-[motion=from-start]:data-starting-style:translate-x-7\",\n        \"rtl:data-[motion=to-start]:data-ending-style:translate-x-6 rtl:data-[motion=to-end]:data-ending-style:-translate-x-6\",\n        \"data-motion:data-starting-style:opacity-0 data-motion:data-starting-style:blur-[6px]\",\n        \"data-motion:data-ending-style:opacity-0 data-motion:data-ending-style:blur-[6px]\",\n        /* Cascade the links (grandchildren, as in ul > li) while the panel arrives. */\n        \"[&>*>*]:transition-[opacity,translate,filter] [&>*>*]:duration-[calc(420ms*var(--kf-speed,1))] [&>*>*]:ease-spring\",\n        \"[&>*>*]:[transition-delay:calc((min(sibling-index(),10)-1)*calc(32ms*var(--kf-speed,1)))]\",\n        \"data-starting-style:[&>*>*]:translate-y-2 data-starting-style:[&>*>*]:opacity-0 data-starting-style:[&>*>*]:blur-[4px] data-starting-style:[&>*>*]:[transition:none]\",\n        \"data-ending-style:[&>*>*]:[transition-delay:0ms]\",\n        \"motion-reduce:transition-none! motion-reduce:[&>*>*]:transition-none\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { NavigationMenuContent, NavigationMenuIndicator, NavigationMenuTrigger, NavigationMenuViewport }\n",
      "type": "registry:component",
      "target": "components/keyframery/primitives/navigation-menu.tsx"
    },
    {
      "path": "registry/components/keyframery/navigation-menu.tsx",
      "content": "\"use client\"\n\n/* Styled navigation menu: the animated primitive plus the Keyframery look. */\n\nimport {\n  createNavigationMenuController,\n  NavigationMenu as NavigationMenuRoot,\n  NavigationMenuContent as NavigationMenuContentPart,\n  NavigationMenuIndicator as NavigationMenuIndicatorPart,\n  NavigationMenuItem as NavigationMenuItemPart,\n  NavigationMenuLink as NavigationMenuLinkPart,\n  NavigationMenuLinkIcon as NavigationMenuLinkIconPart,\n  NavigationMenuList as NavigationMenuListPart,\n  type NavigationMenuProps,\n  NavigationMenuTrigger as NavigationMenuTriggerPart,\n  NavigationMenuViewport as NavigationMenuViewportPart,\n} from \"@/components/keyframery/primitives/navigation-menu\"\nimport * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\n/* The label look shared by triggers and top-level links. */\nconst topLevel =\n  \"relative inline-flex h-8 shrink-0 cursor-pointer items-center justify-center gap-1 rounded-[9px] px-3 text-[13px] leading-none font-medium whitespace-nowrap text-muted-foreground outline-none select-none hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\"\n\n/* The root is the positioned ancestor the indicator measures from. */\nfunction NavigationMenu<T extends string = string>({\n  className,\n  ...props\n}: NavigationMenuProps<T>) {\n  return (\n    <NavigationMenuRoot<T>\n      className={cn(\n        \"group/nav relative flex items-center data-[orientation=vertical]:flex-col data-[orientation=vertical]:items-stretch\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction NavigationMenuList({\n  className,\n  ...props\n}: React.ComponentProps<typeof NavigationMenuListPart>) {\n  return (\n    <NavigationMenuListPart\n      className={cn(\n        \"relative z-[1] m-0 flex list-none items-center gap-0.5 p-0 data-[orientation=vertical]:flex-col data-[orientation=vertical]:items-stretch\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction NavigationMenuItem({\n  className,\n  ...props\n}: React.ComponentProps<typeof NavigationMenuItemPart>) {\n  return <NavigationMenuItemPart className={cn(\"relative\", className)} {...props} />\n}\n\n/* A flat label with a chevron that turns while its panel is open. */\nfunction NavigationMenuTrigger({\n  className,\n  children,\n  ...props\n}: Omit<React.ComponentProps<typeof NavigationMenuTriggerPart>, \"children\"> & {\n  children?: React.ReactNode\n}) {\n  return (\n    <NavigationMenuTriggerPart\n      className={cn(\n        topLevel,\n        \"data-open:text-foreground\",\n        \"data-disabled:pointer-events-none data-disabled:opacity-40\",\n        className,\n      )}\n      {...props}\n    >\n      {children}\n      <svg\n        viewBox=\"0 0 16 16\"\n        fill=\"none\"\n        stroke=\"currentColor\"\n        strokeWidth=\"1.5\"\n        strokeLinecap=\"round\"\n        strokeLinejoin=\"round\"\n        aria-hidden\n        className=\"-me-1 size-3.5 shrink-0 opacity-60 in-data-open:opacity-100\"\n      >\n        <path d=\"m4.5 6.5 3.5 3.5 3.5-3.5\" />\n      </svg>\n    </NavigationMenuTriggerPart>\n  )\n}\n\n/* A panel. Inside the viewport it sits at the corner with its own width, so the viewport\n   takes its size. The primitive slides it in from the side it was reached from. */\nfunction NavigationMenuContent({\n  className,\n  ...props\n}: React.ComponentProps<typeof NavigationMenuContentPart>) {\n  return (\n    <NavigationMenuContentPart\n      className={cn(\n        \"p-1.5 outline-none\",\n        \"[[data-slot=navigation-menu-viewport]>&]:absolute [[data-slot=navigation-menu-viewport]>&]:start-0 [[data-slot=navigation-menu-viewport]>&]:top-0 [[data-slot=navigation-menu-viewport]>&]:w-max\",\n        \"[[data-slot=navigation-menu-viewport]>&]:max-h-(--panel-height) [[data-slot=navigation-menu-viewport]>&]:overflow-y-auto\",\n        \"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\n/* The sheet that holds the open panel. The primitive unfolds it and springs it between panels. */\nfunction NavigationMenuViewport({\n  className,\n  sideOffset = 8,\n  ...props\n}: React.ComponentProps<typeof NavigationMenuViewportPart>) {\n  return (\n    <NavigationMenuViewportPart\n      sideOffset={sideOffset}\n      className={cn(\n        \"m-0 overflow-hidden border-0 p-0\",\n        \"h-(--viewport-height) w-(--viewport-width) [--panel-height:var(--available-height)]\",\n        \"rounded-[14px] bg-popover text-popover-foreground\",\n        \"shadow-[0_0_0_1px_rgb(0_0_0/0.06),0_2px_6px_-2px_rgb(0_0_0/0.08),0_12px_32px_-8px_rgb(0_0_0/0.18)]\",\n        \"dark:shadow-[0_0_0_1px_rgb(255_255_255/0.08),0_12px_32px_-8px_rgb(0_0_0/0.7)]\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\n/* A soft pill under the open trigger (or the current page's link). The primitive stretches it. */\nfunction NavigationMenuIndicator({\n  className,\n  ...props\n}: React.ComponentProps<typeof NavigationMenuIndicatorPart>) {\n  return (\n    <NavigationMenuIndicatorPart\n      className={cn(\"z-0 rounded-[9px] bg-accent\", className)}\n      {...props}\n    />\n  )\n}\n\n/* A link. At the top level it reads like a trigger; inside a panel it is a roomy row with\n   an optional icon tile, a title and a hint. */\nfunction NavigationMenuLink({\n  className,\n  ...props\n}: React.ComponentProps<typeof NavigationMenuLinkPart>) {\n  return (\n    <NavigationMenuLinkPart\n      className={cn(\n        \"group/link flex cursor-pointer items-start gap-3 rounded-[10px] px-3 py-2.5 text-[13px] leading-5 text-foreground no-underline outline-none\",\n        \"transition-[background-color] duration-[calc(150ms*var(--kf-speed,1))] hover:bg-accent hover:duration-0 data-current:bg-accent/60\",\n        \"focus-visible:bg-accent focus-visible:ring-2 focus-visible:ring-ring\",\n        \"motion-reduce:transition-none!\",\n        /* Directly in the bar, it is a label like the triggers. */\n        \"[[data-slot=navigation-menu-list]>li>&]:items-center [[data-slot=navigation-menu-list]>li>&]:h-8 [[data-slot=navigation-menu-list]>li>&]:gap-1 [[data-slot=navigation-menu-list]>li>&]:rounded-[9px] [[data-slot=navigation-menu-list]>li>&]:px-3 [[data-slot=navigation-menu-list]>li>&]:py-0 [[data-slot=navigation-menu-list]>li>&]:leading-none [[data-slot=navigation-menu-list]>li>&]:font-medium\",\n        \"[[data-slot=navigation-menu-list]>li>&]:text-muted-foreground [[data-slot=navigation-menu-list]>li>&]:hover:bg-transparent [[data-slot=navigation-menu-list]>li>&]:hover:text-foreground [[data-slot=navigation-menu-list]>li>&]:data-current:bg-transparent [[data-slot=navigation-menu-list]>li>&]:data-current:text-foreground\",\n        \"[[data-slot=navigation-menu-list]>li>&]:focus-visible:bg-transparent [[data-slot=navigation-menu-list]>li>&]:focus-visible:ring-offset-2 [[data-slot=navigation-menu-list]>li>&]:focus-visible:ring-offset-background\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\n/* The icon tile of a panel link. */\nfunction NavigationMenuLinkIcon({\n  className,\n  ...props\n}: React.ComponentProps<typeof NavigationMenuLinkIconPart>) {\n  return (\n    <NavigationMenuLinkIconPart\n      className={cn(\n        \"grid size-8 shrink-0 place-items-center rounded-[8px] bg-muted text-muted-foreground [&>svg]:size-4\",\n        \"shadow-[inset_0_0_0_1px_rgb(0_0_0/0.04)] dark:shadow-[inset_0_0_0_1px_rgb(255_255_255/0.05)]\",\n        \"transition-[background-color,color,box-shadow] duration-[calc(150ms*var(--kf-speed,1))] group-hover/link:bg-background group-hover/link:text-foreground group-hover/link:shadow-[0_0_0_1px_rgb(0_0_0/0.06),0_1px_2px_rgb(0_0_0/0.06)]\",\n        \"dark:group-hover/link:bg-popover dark:group-hover/link:shadow-[0_0_0_1px_rgb(255_255_255/0.08)]\",\n        \"rtl:data-mirror:-scale-x-100 motion-reduce:transition-none!\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  createNavigationMenuController,\n  NavigationMenu,\n  NavigationMenuContent,\n  NavigationMenuIndicator,\n  NavigationMenuItem,\n  NavigationMenuLink,\n  NavigationMenuLinkIcon,\n  NavigationMenuList,\n  NavigationMenuTrigger,\n  NavigationMenuViewport,\n}\n",
      "type": "registry:component",
      "target": "components/keyframery/navigation-menu.tsx"
    }
  ],
  "type": "registry:component"
}