1import {2 Menubar,3 MenubarCheckboxItem,4 MenubarContent,5 MenubarItem,6 MenubarMenu,7 MenubarRadioGroup,8 MenubarRadioItem,9 MenubarSeparator,10 MenubarShortcut,11 MenubarSub,12 MenubarSubContent,13 MenubarSubTrigger,14 MenubarTrigger,15} from "~/components/ui/menubar";16
17export default function MenubarDemo() {18 return (19 <Menubar>20 <MenubarMenu>21 <MenubarTrigger>File</MenubarTrigger>22 <MenubarContent>23 <MenubarItem>24 New Tab <MenubarShortcut>⌘T</MenubarShortcut>25 </MenubarItem>26 <MenubarItem>27 New Window <MenubarShortcut>⌘N</MenubarShortcut>28 </MenubarItem>29 <MenubarItem disabled>New Incognito Window</MenubarItem>30 <MenubarSeparator />31 <MenubarSub>32 <MenubarSubTrigger>Share</MenubarSubTrigger>33 <MenubarSubContent>34 <MenubarItem>Email link</MenubarItem>35 <MenubarItem>Messages</MenubarItem>36 <MenubarItem>Notes</MenubarItem>37 </MenubarSubContent>38 </MenubarSub>39 <MenubarSeparator />40 <MenubarItem>41 Print... <MenubarShortcut>⌘P</MenubarShortcut>42 </MenubarItem>43 </MenubarContent>44 </MenubarMenu>45 <MenubarMenu>46 <MenubarTrigger>Edit</MenubarTrigger>47 <MenubarContent>48 <MenubarItem>49 Undo <MenubarShortcut>⌘Z</MenubarShortcut>50 </MenubarItem>51 <MenubarItem>52 Redo <MenubarShortcut>⇧⌘Z</MenubarShortcut>53 </MenubarItem>54 <MenubarSeparator />55 <MenubarSub>56 <MenubarSubTrigger>Find</MenubarSubTrigger>57 <MenubarSubContent>58 <MenubarItem>Search the web</MenubarItem>59 <MenubarSeparator />60 <MenubarItem>Find...</MenubarItem>61 <MenubarItem>Find Next</MenubarItem>62 <MenubarItem>Find Previous</MenubarItem>63 </MenubarSubContent>64 </MenubarSub>65 <MenubarSeparator />66 <MenubarItem>Cut</MenubarItem>67 <MenubarItem>Copy</MenubarItem>68 <MenubarItem>Paste</MenubarItem>69 </MenubarContent>70 </MenubarMenu>71 <MenubarMenu>72 <MenubarTrigger>View</MenubarTrigger>73 <MenubarContent>74 <MenubarCheckboxItem>Always Show Bookmarks Bar</MenubarCheckboxItem>75 <MenubarCheckboxItem checked>76 Always Show Full URLs77 </MenubarCheckboxItem>78 <MenubarSeparator />79 <MenubarItem inset>80 Reload <MenubarShortcut>⌘R</MenubarShortcut>81 </MenubarItem>82 <MenubarItem disabled inset>83 Force Reload <MenubarShortcut>⇧⌘R</MenubarShortcut>84 </MenubarItem>85 <MenubarSeparator />86 <MenubarItem inset>Toggle Fullscreen</MenubarItem>87 <MenubarSeparator />88 <MenubarItem inset>Hide Sidebar</MenubarItem>89 </MenubarContent>90 </MenubarMenu>91 <MenubarMenu>92 <MenubarTrigger>Profiles</MenubarTrigger>93 <MenubarContent>94 <MenubarRadioGroup defaultValue="benoit">95 <MenubarRadioItem value="andy">Andy</MenubarRadioItem>96 <MenubarRadioItem value="benoit">Benoit</MenubarRadioItem>97 <MenubarRadioItem value="Luis">Luis</MenubarRadioItem>98 </MenubarRadioGroup>99 <MenubarSeparator />100 <MenubarItem inset>Edit...</MenubarItem>101 <MenubarSeparator />102 <MenubarItem inset>Add Profile...</MenubarItem>103 </MenubarContent>104 </MenubarMenu>105 </Menubar>106 );107}
npx shadcn@latest add https://solid-ui-neobrutalism.vercel.app/r/menubar.json
yarn shadcn@latest add https://solid-ui-neobrutalism.vercel.app/r/menubar.json
pnpm dlx shadcn@latest add https://solid-ui-neobrutalism.vercel.app/r/menubar.json
bunx --bun shadcn@latest add https://solid-ui-neobrutalism.vercel.app/r/menubar.json
Install the following dependencies
npm install @kobalte/core
yarn add @kobalte/core
pnpm add @kobalte/core
bun add @kobalte/core
Copy and paste the following code into your project
1import type { PolymorphicProps } from "@kobalte/core/polymorphic";2import type { Component, ComponentProps, JSX, ValidComponent } from "solid-js";3
4import { splitProps } from "solid-js";5import * as MenubarPrimitive from "@kobalte/core/menubar";6import CheckIcon from "lucide-solid/icons/check";7import ChevronRightIcon from "lucide-solid/icons/chevron-right";8import DotIcon from "lucide-solid/icons/dot";9
10import { cn } from "~/lib/utils";11
12const MenubarGroup = <T extends ValidComponent = "div">(13 props: PolymorphicProps<T, MenubarPrimitive.MenubarGroupProps<T>>,14) => {15 return <MenubarPrimitive.Group data-slot="menubar-group" {...props} />;16};17
18const MenubarPortal = (props: MenubarPrimitive.MenubarPortalProps) => {19 return <MenubarPrimitive.Portal data-slot="menubar-portal" {...props} />;20};21
22const MenubarSub = (props: MenubarPrimitive.MenubarSubProps) => {23 return <MenubarPrimitive.Sub data-slot="menubar-sub" {...props} />;24};25
26const MenubarRadioGroup = <T extends ValidComponent = "div", TValue = string>(27 props: PolymorphicProps<28 T,29 MenubarPrimitive.MenubarRadioGroupProps<T, TValue>30 >,31) => {32 return (33 <MenubarPrimitive.RadioGroup data-slot="menubar-radio-group" {...props} />34 );35};36
37type MenubarRootProps<T extends ValidComponent = "div"> =38 MenubarPrimitive.MenubarRootProps<T> & {39 class?: string | undefined;40 };41
42const Menubar = <T extends ValidComponent = "div">(43 props: PolymorphicProps<T, MenubarRootProps<T>>,44) => {45 const [local, others] = splitProps(props as MenubarRootProps, ["class"]);46 return (47 <MenubarPrimitive.Root48 data-slot="menubar-root"49 class={cn(50 "flex h-10 items-center space-x-1 rounded-base border-2 border-border bg-background p-1",51 local.class,52 )}53 {...others}54 />55 );56};57
58const MenubarMenu: Component<MenubarPrimitive.MenubarMenuProps> = (props) => {59 return (60 <MenubarPrimitive.Menu data-slot="menubar-menu" gutter={8} {...props} />61 );62};63
64type MenubarTriggerProps<T extends ValidComponent = "button"> =65 MenubarPrimitive.MenubarTriggerProps<T> & { class?: string | undefined };66
67const MenubarTrigger = <T extends ValidComponent = "button">(68 props: PolymorphicProps<T, MenubarTriggerProps<T>>,69) => {70 const [local, others] = splitProps(props as MenubarTriggerProps, ["class"]);71 return (72 <MenubarPrimitive.Trigger73 data-slot="menubar-trigger"74 class={cn(75 "flex cursor-default items-center rounded-base px-3 py-1.5 text-sm font-medium outline-none select-none focus:bg-primary focus:text-primary-foreground ui-expanded:bg-primary ui-expanded:text-primary-foreground",76 local.class,77 )}78 {...others}79 />80 );81};82
83type MenubarContentProps<T extends ValidComponent = "div"> =84 MenubarPrimitive.MenubarContentProps<T> & { class?: string | undefined };85
86const MenubarContent = <T extends ValidComponent = "div">(87 props: PolymorphicProps<T, MenubarContentProps<T>>,88) => {89 const [local, others] = splitProps(props as MenubarContentProps, ["class"]);90 return (91 <MenubarPrimitive.Portal>92 <MenubarPrimitive.Content93 data-slot="menubar-content"94 class={cn(95 "z-50 min-w-48 origin-[var(--kb-menu-content-transform-origin)] overflow-hidden rounded-base border-2 border-border bg-background p-1 text-foreground ui-expanded:animate-in ui-expanded:fade-in-0 ui-expanded:zoom-in-95 ui-closed:animate-out ui-closed:fade-out-0 ui-closed:zoom-out-95",96 local.class,97 )}98 {...others}99 />100 </MenubarPrimitive.Portal>101 );102};103
104type MenubarSubTriggerProps<T extends ValidComponent = "div"> =105 MenubarPrimitive.MenubarSubTriggerProps<T> & {106 class?: string | undefined;107 children?: JSX.Element;108 inset?: boolean;109 };110
111const MenubarSubTrigger = <T extends ValidComponent = "div">(112 props: PolymorphicProps<T, MenubarSubTriggerProps<T>>,113) => {114 const [local, others] = splitProps(props as MenubarSubTriggerProps, [115 "class",116 "children",117 "inset",118 ]);119 return (120 <MenubarPrimitive.SubTrigger121 data-slot="menubar-sub-trigger"122 class={cn(123 "flex cursor-default items-center rounded-base px-2 py-1.5 text-sm transition-colors outline-none select-none focus:bg-primary focus:text-primary-foreground ui-expanded:bg-primary ui-expanded:text-primary-foreground",124 local.inset && "pl-8",125 local.class,126 )}127 {...others}128 >129 {local.children}130 <ChevronRightIcon class="ml-auto size-4" />131 </MenubarPrimitive.SubTrigger>132 );133};134
135type MenubarSubContentProps<T extends ValidComponent = "div"> =136 MenubarPrimitive.MenubarSubContentProps<T> & {137 class?: string | undefined;138 };139
140const MenubarSubContent = <T extends ValidComponent = "div">(141 props: PolymorphicProps<T, MenubarSubContentProps<T>>,142) => {143 const [local, others] = splitProps(props as MenubarSubContentProps, [144 "class",145 ]);146 return (147 <MenubarPrimitive.Portal>148 <MenubarPrimitive.SubContent149 data-slot="menubar-sub-content"150 class={cn(151 "z-50 min-w-32 origin-[var(--kb-menu-content-transform-origin)] animate-in overflow-hidden rounded-base border-2 bg-background p-1 text-foreground ui-expanded:animate-in ui-expanded:fade-in-0 ui-expanded:zoom-in-95 ui-closed:animate-out ui-closed:fade-out-0 ui-closed:zoom-out-95",152 local.class,153 )}154 {...others}155 />156 </MenubarPrimitive.Portal>157 );158};159
160type MenubarItemProps<T extends ValidComponent = "div"> =161 MenubarPrimitive.MenubarItemProps<T> & {162 class?: string | undefined;163 inset?: boolean;164 };165
166const MenubarItem = <T extends ValidComponent = "div">(167 props: PolymorphicProps<T, MenubarItemProps<T>>,168) => {169 const [local, others] = splitProps(props as MenubarItemProps, [170 "class",171 "inset",172 ]);173 return (174 <MenubarPrimitive.Item175 data-slot="menubar-item"176 class={cn(177 "relative flex cursor-default items-center rounded-base px-2 py-1.5 text-sm transition-colors outline-none select-none focus:bg-primary focus:text-primary-foreground ui-disabled:pointer-events-none ui-disabled:opacity-50",178 local.inset && "pl-8",179 local.class,180 )}181 {...others}182 />183 );184};185
186type MenubarCheckboxItemProps<T extends ValidComponent = "div"> =187 MenubarPrimitive.MenubarCheckboxItemProps<T> & {188 class?: string | undefined;189 children?: JSX.Element;190 };191
192const MenubarCheckboxItem = <T extends ValidComponent = "div">(193 props: PolymorphicProps<T, MenubarCheckboxItemProps<T>>,194) => {195 const [local, others] = splitProps(props as MenubarCheckboxItemProps, [196 "class",197 "children",198 ]);199 return (200 <MenubarPrimitive.CheckboxItem201 data-slot="menubar-checkbox-item"202 class={cn(203 "relative flex cursor-default items-center rounded-base py-1.5 pr-2 pl-8 text-sm transition-colors outline-none select-none focus:bg-primary focus:text-primary-foreground ui-disabled:pointer-events-none ui-disabled:opacity-50",204 local.class,205 )}206 {...others}207 >208 <span class="absolute left-2 flex size-3.5 items-center justify-center">209 <MenubarPrimitive.ItemIndicator>210 <CheckIcon class="size-4" />211 </MenubarPrimitive.ItemIndicator>212 </span>213 {local.children}214 </MenubarPrimitive.CheckboxItem>215 );216};217
218type MenubarRadioItemProps<T extends ValidComponent = "div"> =219 MenubarPrimitive.MenubarRadioItemProps<T> & {220 class?: string | undefined;221 children?: JSX.Element;222 };223
224const MenubarRadioItem = <T extends ValidComponent = "div">(225 props: PolymorphicProps<T, MenubarRadioItemProps<T>>,226) => {227 const [local, others] = splitProps(props as MenubarRadioItemProps, [228 "class",229 "children",230 ]);231 return (232 <MenubarPrimitive.RadioItem233 data-slot="menubar-radio-item"234 class={cn(235 "relative flex cursor-default items-center rounded-base py-1.5 pr-2 pl-8 text-sm transition-colors outline-none select-none focus:bg-primary focus:text-primary-foreground ui-disabled:pointer-events-none ui-disabled:opacity-50",236 local.class,237 )}238 {...others}239 >240 <span class="absolute left-2 flex size-3.5 items-center justify-center">241 <MenubarPrimitive.ItemIndicator>242 <DotIcon class="size-10" />243 </MenubarPrimitive.ItemIndicator>244 </span>245 {local.children}246 </MenubarPrimitive.RadioItem>247 );248};249
250type MenubarItemLabelProps<T extends ValidComponent = "div"> =251 MenubarPrimitive.MenubarItemLabelProps<T> & {252 class?: string | undefined;253 inset?: boolean;254 };255
256const MenubarItemLabel = <T extends ValidComponent = "div">(257 props: PolymorphicProps<T, MenubarItemLabelProps<T>>,258) => {259 const [local, others] = splitProps(props as MenubarItemLabelProps, [260 "class",261 "inset",262 ]);263 return (264 <MenubarPrimitive.ItemLabel265 data-slot="menubar-item-label"266 class={cn(267 "px-2 py-1.5 text-sm font-semibold",268 local.inset && "pl-8",269 local.class,270 )}271 {...others}272 />273 );274};275
276type MenubarGroupLabelProps<T extends ValidComponent = "span"> =277 MenubarPrimitive.MenubarGroupLabelProps<T> & {278 class?: string | undefined;279 inset?: boolean;280 };281
282const MenubarGroupLabel = <T extends ValidComponent = "span">(283 props: PolymorphicProps<T, MenubarGroupLabelProps<T>>,284) => {285 const [local, others] = splitProps(props as MenubarGroupLabelProps, [286 "class",287 "inset",288 ]);289 return (290 <MenubarPrimitive.GroupLabel291 data-slot="menubar-group-label"292 class={cn(293 "px-2 py-1.5 text-sm font-semibold",294 local.inset && "pl-8",295 local.class,296 )}297 {...others}298 />299 );300};301
302type MenubarSeparatorProps<T extends ValidComponent = "hr"> =303 MenubarPrimitive.MenubarSeparatorProps<T> & { class?: string | undefined };304
305const MenubarSeparator = <T extends ValidComponent = "hr">(306 props: PolymorphicProps<T, MenubarSeparatorProps<T>>,307) => {308 const [local, others] = splitProps(props as MenubarSeparatorProps, ["class"]);309 return (310 <MenubarPrimitive.Separator311 data-slot="menubar-separator"312 class={cn("-mx-1 my-1 h-0.5 border-border bg-border", local.class)}313 {...others}314 />315 );316};317
318const MenubarShortcut: Component<ComponentProps<"span">> = (props) => {319 const [local, others] = splitProps(props, ["class"]);320 return (321 <span322 data-slot="menubar-shortcut"323 class={cn(324 "ml-auto text-xs tracking-widest text-muted-foreground",325 local.class,326 )}327 {...others}328 />329 );330};331
332export {333 Menubar,334 MenubarMenu,335 MenubarTrigger,336 MenubarContent,337 MenubarItem,338 MenubarSeparator,339 MenubarItemLabel,340 MenubarGroupLabel,341 MenubarCheckboxItem,342 MenubarRadioGroup,343 MenubarRadioItem,344 MenubarPortal,345 MenubarSubContent,346 MenubarSubTrigger,347 MenubarGroup,348 MenubarSub,349 MenubarShortcut,350};
Update the import paths to match your project setup.
1import {2 Menubar,3 MenubarCheckboxItem,4 MenubarContent,5 MenubarGroup,6 MenubarGroupLabel,7 MenubarItem,8 MenubarItemLabel,9 MenubarMenu,10 MenubarRadioGroup,11 MenubarRadioItem,12 MenubarSeparator,13 MenubarShortcut,14 MenubarSub,15 MenubarSubContent,16 MenubarSubTrigger,17 MenubarTrigger,18} from "~/components/ui/menubar";
1<Menubar>2 <MenubarMenu>3 <MenubarTrigger>File</MenubarTrigger>4 <MenubarContent>5 <MenubarItem>6 New Tab <MenubarShortcut>⌘T</MenubarShortcut>7 </MenubarItem>8 <MenubarItem>New Window</MenubarItem>9 <MenubarSeparator />10 <MenubarItem>Share</MenubarItem>11 <MenubarSeparator />12 <MenubarItem>Print</MenubarItem>13 </MenubarContent>14 </MenubarMenu>15</Menubar>