Search for a command to run...
A collection of links for navigating websites.
npx shadcn@latest add @zaidan/navigation-menupnpx shadcn add @zaidan/navigation-menuyarn dlx shadcn@latest add @zaidan/navigation-menubunx shadcn@latest add @zaidan/navigation-menuCopy and paste the following code into your project.
1import {2 Content,3 Menu,4 type NavigationMenuContentProps as NavigationMenuContentPrimitiveProps,5 type NavigationMenuRootProps,6 type NavigationMenuTriggerProps as NavigationMenuTriggerPrimitiveProps,7 Portal,8 Root,9 Trigger,10 Viewport,11} from "@kobalte/core/navigation-menu";12import type { PolymorphicProps } from "@kobalte/core/polymorphic";13import { cva } from "class-variance-authority";14import { ChevronDown } from "lucide-solid";15import type { ComponentProps, JSX, ValidComponent } from "solid-js";16import { mergeProps, splitProps } from "solid-js";17import { cn } from "~/lib/utils";18
19type NavigationMenuProps<T extends ValidComponent = "ul"> = PolymorphicProps<20 T,21 NavigationMenuRootProps<T>22> &23 Pick<ComponentProps<T>, "class" | "children">;24
25const NavigationMenu = <T extends ValidComponent = "ul">(props: NavigationMenuProps<T>) => {26 const mergedProps = mergeProps({ gutter: 8, placement: "bottom-start" }, props);27 const [local, others] = splitProps(mergedProps as NavigationMenuProps, ["class", "children"]);28 return (29 <Root30 data-slot="navigation-menu"31 class={cn(32 "group/navigation-menu relative z-navigation-menu flex max-w-max flex-1 items-center justify-center",33 local.class,34 )}35 {...others}36 >37 <div38 data-slot="navigation-menu-list"39 class="group z-navigation-menu-list flex flex-1 list-none items-center justify-center"40 >41 {local.children}42 </div>43 <Viewport class="origin-(--kb-menu-content-transform-origin)" />44 </Root>45 );46};47
48type NavigationMenuItemProps = ComponentProps<"div">;49
50const NavigationMenuItem = (props: NavigationMenuItemProps) => {51 const [local, others] = splitProps(props, ["class"]);52 return (53 <Menu>54 <div55 data-slot="navigation-menu-item"56 class={cn("relative z-navigation-menu-item", local.class)}57 {...others}58 />59 </Menu>60 );61};62
63const navigationMenuTriggerStyle = cva(64 "group/navigation-menu-trigger z-navigation-menu-trigger inline-flex h-9 w-max items-center justify-center outline-none disabled:pointer-events-none",65);66
67type NavigationMenuTriggerProps<T extends ValidComponent = "div"> = PolymorphicProps<68 T,69 NavigationMenuTriggerPrimitiveProps<T>70> &71 Pick<ComponentProps<T>, "class" | "children">;72
73const NavigationMenuTrigger = <T extends ValidComponent = "div">(74 props: NavigationMenuTriggerProps<T>,75) => {76 const [local, others] = splitProps(props as NavigationMenuTriggerProps, ["class", "children"]);77 return (78 <Trigger79 data-slot="navigation-menu-trigger"80 class={cn(navigationMenuTriggerStyle(), "group", local.class)}81 {...others}82 >83 {local.children}84 <ChevronDown class="z-navigation-menu-trigger-icon" aria-hidden="true" />85 </Trigger>86 );87};88
89type NavigationMenuContentProps<T extends ValidComponent = "ul"> = PolymorphicProps<90 T,91 NavigationMenuContentPrimitiveProps<T>92> &93 Pick<ComponentProps<T>, "class" | "children">;94
95const NavigationMenuContent = <T extends ValidComponent = "ul">(96 props: NavigationMenuContentProps<T>,97) => {98 const [local, others] = splitProps(props as NavigationMenuContentProps, ["class"]);99 return (100 <Portal>101 <Content102 data-slot="navigation-menu-content"103 class={cn(104 "absolute top-0 z-navigation-menu-content h-full w-auto origin-(--kb-menu-content-transform-origin) **:data-[slot=navigation-menu-link]:focus:outline-none **:data-[slot=navigation-menu-link]:focus:ring-0",105 local.class,106 )}107 {...others}108 />109 </Portal>110 );111};112
113type NavigationMenuLinkProps = ComponentProps<"a"> & {114 class?: string;115 children?: JSX.Element;116};117
118const NavigationMenuLink = (props: NavigationMenuLinkProps) => {119 const [local, others] = splitProps(props, ["class"]);120 return (121 <a122 data-slot="navigation-menu-link"123 class={cn("z-navigation-menu-link", local.class)}124 {...others}125 />126 );127};128
129type NavigationMenuIndicatorProps = ComponentProps<"div"> & {130 class?: string;131};132
133const NavigationMenuIndicator = (props: NavigationMenuIndicatorProps) => {134 const [local, others] = splitProps(props, ["class"]);135 return (136 <div137 data-slot="navigation-menu-indicator"138 class={cn(139 "top-full z-1 z-navigation-menu-indicator flex h-1.5 items-end justify-center overflow-hidden",140 local.class,141 )}142 {...others}143 >144 <div class="relative top-[60%] z-navigation-menu-indicator-arrow h-2 w-2 rotate-45" />145 </div>146 );147};148
149export {150 NavigationMenu,151 NavigationMenuContent,152 NavigationMenuIndicator,153 NavigationMenuItem,154 NavigationMenuLink,155 NavigationMenuTrigger,156 navigationMenuTriggerStyle,157};You can use the as prop to make another component render as a navigation menu link.
1import { A } from "@solidjs/router";2
3export function NavigationMenuDemo() {4 return (5 <NavigationMenuItem>6 <NavigationMenuLink as={A} href="/docs">7 Documentation8 </NavigationMenuLink>9 </NavigationMenuItem>10 );11}Here are the source code of all the examples from the preview page:
import { CircleAlert } from "lucide-solid";import { type ComponentProps, For, splitProps } from "solid-js";import { NavigationMenu, NavigationMenuContent, NavigationMenuItem, NavigationMenuLink, NavigationMenuTrigger, navigationMenuTriggerStyle,} from "~/components/ui/navigation-menu";function NavigationMenuBasic() { return ( <Example title="Basic"> <NavigationMenu> <NavigationMenuItem> <NavigationMenuTrigger>Getting started</NavigationMenuTrigger> <NavigationMenuContent> <ul class="w-96 rounded-md bg-popover p-2"> <ListItem href="#" title="Introduction"> Re-usable components built with Tailwind CSS. </ListItem> <ListItem href="#" title="Installation"> How to install dependencies and structure your app. </ListItem> <ListItem href="#" title="Typography"> Styles for headings, paragraphs, lists...etc </ListItem> </ul> </NavigationMenuContent> </NavigationMenuItem> <NavigationMenuItem> <NavigationMenuTrigger>Components</NavigationMenuTrigger> <NavigationMenuContent> <ul class="grid w-[400px] gap-2 rounded-md bg-popover p-2 md:w-[500px] md:grid-cols-2 lg:w-[600px]"> <For each={components}> {(component) => ( <ListItem title={component.title} href={component.href}> {component.description} </ListItem> )} </For> </ul> </NavigationMenuContent> </NavigationMenuItem> <NavigationMenuItem> <NavigationMenuLink href="/docs" class={navigationMenuTriggerStyle()}> Documentation </NavigationMenuLink> </NavigationMenuItem> </NavigationMenu> </Example> );}The ListItem helper component used in the example:
function ListItem(props: ComponentProps<"li"> & { href: string }) { const [local, others] = splitProps(props, ["title", "children", "href"]); return ( <li {...others}> <NavigationMenuLink href={local.href}> <div class="flex flex-col gap-1 style-lyra:text-xs style-maia:text-sm style-mira:text-xs style-nova:text-sm style-vega:text-sm"> <div class="font-medium leading-none">{local.title}</div> <div class="line-clamp-2 text-muted-foreground">{local.children}</div> </div> </NavigationMenuLink> </li> );}