A visually persistent menu common in desktop applications that provides quick access to a consistent set of commands.
Epicenter
Local-first, open source apps
<script lang="ts">
import * as Menubar from "$lib/components/ui/menubar/index.js";
let bookmarks = $state(false);
let fullUrls = $state(true);
let profileRadioValue = $state("benoit");
</script>
<Menubar.Root class="w-72">
<Menubar.Menu>
<Menubar.Trigger>File</Menubar.Trigger>
<Menubar.Content>
<Menubar.Group>
<Menubar.Item>
New Tab <Menubar.Shortcut>⌘T</Menubar.Shortcut>
</Menubar.Item>
<Menubar.Item>
New Window <Menubar.Shortcut>⌘N</Menubar.Shortcut>
</Menubar.Item>
<Menubar.Item disabled>New Incognito Window</Menubar.Item>
</Menubar.Group>
<Menubar.Separator />
<Menubar.Group>
<Menubar.Sub>
<Menubar.SubTrigger>Share</Menubar.SubTrigger>
<Menubar.SubContent>
<Menubar.Group>
<Menubar.Item>Email link</Menubar.Item>
<Menubar.Item>Messages</Menubar.Item>
<Menubar.Item>Notes</Menubar.Item>
</Menubar.Group>
</Menubar.SubContent>
</Menubar.Sub>
</Menubar.Group>
<Menubar.Separator />
<Menubar.Group>
<Menubar.Item>
Print... <Menubar.Shortcut>⌘P</Menubar.Shortcut>
</Menubar.Item>
</Menubar.Group>
</Menubar.Content>
</Menubar.Menu>
<Menubar.Menu>
<Menubar.Trigger>Edit</Menubar.Trigger>
<Menubar.Content>
<Menubar.Group>
<Menubar.Item>
Undo <Menubar.Shortcut>⌘Z</Menubar.Shortcut>
</Menubar.Item>
<Menubar.Item>
Redo <Menubar.Shortcut>⇧⌘Z</Menubar.Shortcut>
</Menubar.Item>
</Menubar.Group>
<Menubar.Separator />
<Menubar.Group>
<Menubar.Sub>
<Menubar.SubTrigger>Find</Menubar.SubTrigger>
<Menubar.SubContent>
<Menubar.Group>
<Menubar.Item>Search the web</Menubar.Item>
</Menubar.Group>
<Menubar.Separator />
<Menubar.Group>
<Menubar.Item>Find...</Menubar.Item>
<Menubar.Item>Find Next</Menubar.Item>
<Menubar.Item>Find Previous</Menubar.Item>
</Menubar.Group>
</Menubar.SubContent>
</Menubar.Sub>
</Menubar.Group>
<Menubar.Separator />
<Menubar.Group>
<Menubar.Item>Cut</Menubar.Item>
<Menubar.Item>Copy</Menubar.Item>
<Menubar.Item>Paste</Menubar.Item>
</Menubar.Group>
</Menubar.Content>
</Menubar.Menu>
<Menubar.Menu>
<Menubar.Trigger>View</Menubar.Trigger>
<Menubar.Content class="w-44">
<Menubar.Group>
<Menubar.CheckboxItem bind:checked={bookmarks}
>Bookmarks Bar</Menubar.CheckboxItem
>
<Menubar.CheckboxItem bind:checked={fullUrls}
>Full URLs</Menubar.CheckboxItem
>
</Menubar.Group>
<Menubar.Separator />
<Menubar.Group>
<Menubar.Item inset>
Reload <Menubar.Shortcut>⌘R</Menubar.Shortcut>
</Menubar.Item>
<Menubar.Item disabled inset>
Force Reload <Menubar.Shortcut>⇧⌘R</Menubar.Shortcut>
</Menubar.Item>
</Menubar.Group>
<Menubar.Separator />
<Menubar.Group>
<Menubar.Item inset>Toggle Fullscreen</Menubar.Item>
</Menubar.Group>
<Menubar.Separator />
<Menubar.Group>
<Menubar.Item inset>Hide Sidebar</Menubar.Item>
</Menubar.Group>
</Menubar.Content>
</Menubar.Menu>
<Menubar.Menu>
<Menubar.Trigger>Profiles</Menubar.Trigger>
<Menubar.Content>
<Menubar.RadioGroup bind:value={profileRadioValue}>
<Menubar.RadioItem value="andy">Andy</Menubar.RadioItem>
<Menubar.RadioItem value="benoit">Benoit</Menubar.RadioItem>
<Menubar.RadioItem value="Luis">Luis</Menubar.RadioItem>
</Menubar.RadioGroup>
<Menubar.Separator />
<Menubar.Group>
<Menubar.Item inset>Edit...</Menubar.Item>
</Menubar.Group>
<Menubar.Separator />
<Menubar.Group>
<Menubar.Item inset>Add Profile...</Menubar.Item>
</Menubar.Group>
</Menubar.Content>
</Menubar.Menu>
</Menubar.Root> Installation #
pnpm dlx shadcn-svelte@latest add menubarnpx shadcn-svelte@latest add menubarnpx shadcn-svelte@latest add menubarbun x shadcn-svelte@latest add menubarInstall bits-ui:
pnpm i bits-ui -Dnpm i bits-ui -Dyarn install bits-ui -Dbun install bits-ui -DCopy and paste the following code into your project.
import CheckboxItem from "./menubar-checkbox-item.svelte";
import Content from "./menubar-content.svelte";
import GroupHeading from "./menubar-group-heading.svelte";
import Group from "./menubar-group.svelte";
import Item from "./menubar-item.svelte";
import Label from "./menubar-label.svelte";
import Menu from "./menubar-menu.svelte";
import Portal from "./menubar-portal.svelte";
import RadioGroup from "./menubar-radio-group.svelte";
import RadioItem from "./menubar-radio-item.svelte";
import Separator from "./menubar-separator.svelte";
import Shortcut from "./menubar-shortcut.svelte";
import SubContent from "./menubar-sub-content.svelte";
import SubTrigger from "./menubar-sub-trigger.svelte";
import Sub from "./menubar-sub.svelte";
import Trigger from "./menubar-trigger.svelte";
import Root from "./menubar.svelte";
export {
Root,
CheckboxItem,
Content,
Item,
RadioItem,
Separator,
Shortcut,
SubContent,
SubTrigger,
Trigger,
Menu,
Group,
Sub,
RadioGroup,
Label,
GroupHeading,
Portal,
//
Root as Menubar,
CheckboxItem as MenubarCheckboxItem,
Content as MenubarContent,
Item as MenubarItem,
RadioItem as MenubarRadioItem,
Separator as MenubarSeparator,
Shortcut as MenubarShortcut,
SubContent as MenubarSubContent,
SubTrigger as MenubarSubTrigger,
Trigger as MenubarTrigger,
Menu as MenubarMenu,
Group as MenubarGroup,
Sub as MenubarSub,
RadioGroup as MenubarRadioGroup,
Label as MenubarLabel,
GroupHeading as MenubarGroupHeading,
Portal as MenubarPortal,
};
Usage #
<script lang="ts">
import * as Menubar from "$lib/components/ui/menubar/index.js";
</script> <Menubar.Root>
<Menubar.Menu>
<Menubar.Trigger>File</Menubar.Trigger>
<Menubar.Content>
<Menubar.Item>
New Tab
<Menubar.Shortcut>⌘T</Menubar.Shortcut>
</Menubar.Item>
<Menubar.Item>New Window</Menubar.Item>
<Menubar.Separator />
<Menubar.Item>Share</Menubar.Item>
<Menubar.Separator />
<Menubar.Item>Print</Menubar.Item>
</Menubar.Content>
</Menubar.Menu>
</Menubar.Root> Checkbox #
Use Menubar.CheckboxItem for toggleable options.
<script lang="ts">
import * as Menubar from "$lib/components/ui/menubar/index.js";
let showBookmarksBar = $state(false);
let showFullURLs = $state(true);
let strikethrough = $state(true);
let code = $state(false);
let superscript = $state(false);
</script>
<Menubar.Root class="w-72">
<Menubar.Menu>
<Menubar.Trigger>View</Menubar.Trigger>
<Menubar.Content class="w-64">
<Menubar.CheckboxItem bind:checked={showBookmarksBar}>
Always Show Bookmarks Bar
</Menubar.CheckboxItem>
<Menubar.CheckboxItem bind:checked={showFullURLs}
>Always Show Full URLs</Menubar.CheckboxItem
>
<Menubar.Separator />
<Menubar.Item inset>
Reload <Menubar.Shortcut>⌘R</Menubar.Shortcut>
</Menubar.Item>
<Menubar.Item disabled inset>
Force Reload <Menubar.Shortcut>⇧⌘R</Menubar.Shortcut>
</Menubar.Item>
</Menubar.Content>
</Menubar.Menu>
<Menubar.Menu>
<Menubar.Trigger>Format</Menubar.Trigger>
<Menubar.Content>
<Menubar.CheckboxItem bind:checked={strikethrough}
>Strikethrough</Menubar.CheckboxItem
>
<Menubar.CheckboxItem bind:checked={code}>Code</Menubar.CheckboxItem>
<Menubar.CheckboxItem bind:checked={superscript}
>Superscript</Menubar.CheckboxItem
>
</Menubar.Content>
</Menubar.Menu>
</Menubar.Root> Radio #
Use Menubar.RadioGroup and Menubar.RadioItem for single-select options.
<script lang="ts">
import * as Menubar from "$lib/components/ui/menubar/index.js";
let user = $state("benoit");
let theme = $state("system");
</script>
<Menubar.Root class="w-72">
<Menubar.Menu>
<Menubar.Trigger>Profiles</Menubar.Trigger>
<Menubar.Content>
<Menubar.RadioGroup bind:value={user}>
<Menubar.RadioItem value="andy">Andy</Menubar.RadioItem>
<Menubar.RadioItem value="benoit">Benoit</Menubar.RadioItem>
<Menubar.RadioItem value="luis">Luis</Menubar.RadioItem>
</Menubar.RadioGroup>
<Menubar.Separator />
<Menubar.Item inset>Edit...</Menubar.Item>
<Menubar.Item inset>Add Profile...</Menubar.Item>
</Menubar.Content>
</Menubar.Menu>
<Menubar.Menu>
<Menubar.Trigger>Theme</Menubar.Trigger>
<Menubar.Content>
<Menubar.RadioGroup bind:value={theme}>
<Menubar.RadioItem value="light">Light</Menubar.RadioItem>
<Menubar.RadioItem value="dark">Dark</Menubar.RadioItem>
<Menubar.RadioItem value="system">System</Menubar.RadioItem>
</Menubar.RadioGroup>
</Menubar.Content>
</Menubar.Menu>
</Menubar.Root> Submenu #
Use Menubar.Sub, Menubar.SubTrigger, and Menubar.SubContent for nested menus.
<script lang="ts">
import * as Menubar from "$lib/components/ui/menubar/index.js";
</script>
<Menubar.Root class="w-72">
<Menubar.Menu>
<Menubar.Trigger>File</Menubar.Trigger>
<Menubar.Content>
<Menubar.Sub>
<Menubar.SubTrigger>Share</Menubar.SubTrigger>
<Menubar.SubContent>
<Menubar.Item>Email link</Menubar.Item>
<Menubar.Item>Messages</Menubar.Item>
<Menubar.Item>Notes</Menubar.Item>
</Menubar.SubContent>
</Menubar.Sub>
<Menubar.Separator />
<Menubar.Item>
Print... <Menubar.Shortcut>⌘P</Menubar.Shortcut>
</Menubar.Item>
</Menubar.Content>
</Menubar.Menu>
<Menubar.Menu>
<Menubar.Trigger>Edit</Menubar.Trigger>
<Menubar.Content>
<Menubar.Item>
Undo <Menubar.Shortcut>⌘Z</Menubar.Shortcut>
</Menubar.Item>
<Menubar.Item>
Redo <Menubar.Shortcut>⇧⌘Z</Menubar.Shortcut>
</Menubar.Item>
<Menubar.Separator />
<Menubar.Sub>
<Menubar.SubTrigger>Find</Menubar.SubTrigger>
<Menubar.SubContent>
<Menubar.Item>Find...</Menubar.Item>
<Menubar.Item>Find Next</Menubar.Item>
<Menubar.Item>Find Previous</Menubar.Item>
</Menubar.SubContent>
</Menubar.Sub>
<Menubar.Separator />
<Menubar.Item>Cut</Menubar.Item>
<Menubar.Item>Copy</Menubar.Item>
<Menubar.Item>Paste</Menubar.Item>
</Menubar.Content>
</Menubar.Menu>
</Menubar.Root> With Icons #
<script lang="ts">
import CircleQuestionMarkIcon from "@lucide/svelte/icons/circle-question-mark";
import FileIcon from "@lucide/svelte/icons/file";
import FolderIcon from "@lucide/svelte/icons/folder";
import SaveIcon from "@lucide/svelte/icons/save";
import SettingsIcon from "@lucide/svelte/icons/settings";
import TrashIcon from "@lucide/svelte/icons/trash";
import * as Menubar from "$lib/components/ui/menubar/index.js";
</script>
<Menubar.Root class="w-72">
<Menubar.Menu>
<Menubar.Trigger>File</Menubar.Trigger>
<Menubar.Content>
<Menubar.Item>
<FileIcon />
New File <Menubar.Shortcut>⌘N</Menubar.Shortcut>
</Menubar.Item>
<Menubar.Item>
<FolderIcon />
Open Folder
</Menubar.Item>
<Menubar.Separator />
<Menubar.Item>
<SaveIcon />
Save <Menubar.Shortcut>⌘S</Menubar.Shortcut>
</Menubar.Item>
</Menubar.Content>
</Menubar.Menu>
<Menubar.Menu>
<Menubar.Trigger>More</Menubar.Trigger>
<Menubar.Content>
<Menubar.Group>
<Menubar.Item>
<SettingsIcon />
Settings
</Menubar.Item>
<Menubar.Item>
<CircleQuestionMarkIcon />
Help
</Menubar.Item>
<Menubar.Separator />
<Menubar.Item variant="destructive">
<TrashIcon />
Delete
</Menubar.Item>
</Menubar.Group>
</Menubar.Content>
</Menubar.Menu>
</Menubar.Root>