Epicenter
Local-first, open source apps
Suggestions
Calendar
Search Emoji
Calculator
Settings
Profile ⌘P
Billing ⌘B
Settings ⌘S
<script lang="ts">
import CalculatorIcon from "@lucide/svelte/icons/calculator";
import CalendarIcon from "@lucide/svelte/icons/calendar";
import CreditCardIcon from "@lucide/svelte/icons/credit-card";
import SettingsIcon from "@lucide/svelte/icons/settings";
import SmileIcon from "@lucide/svelte/icons/smile";
import UserIcon from "@lucide/svelte/icons/user";
import * as Command from "$lib/components/ui/command/index.js";
</script>
<Command.Root class="max-w-sm rounded-lg border">
<Command.Input placeholder="Type a command or search..." />
<Command.List>
<Command.Empty>No results found.</Command.Empty>
<Command.Group heading="Suggestions">
<Command.Item>
<CalendarIcon />
<span>Calendar</span>
</Command.Item>
<Command.Item>
<SmileIcon />
<span>Search Emoji</span>
</Command.Item>
<Command.Item disabled>
<CalculatorIcon />
<span>Calculator</span>
</Command.Item>
</Command.Group>
<Command.Separator />
<Command.Group heading="Settings">
<Command.Item>
<UserIcon />
<span>Profile</span>
<Command.Shortcut>⌘P</Command.Shortcut>
</Command.Item>
<Command.Item>
<CreditCardIcon />
<span>Billing</span>
<Command.Shortcut>⌘B</Command.Shortcut>
</Command.Item>
<Command.Item>
<SettingsIcon />
<span>Settings</span>
<Command.Shortcut>⌘S</Command.Shortcut>
</Command.Item>
</Command.Group>
</Command.List>
</Command.Root> About #
The <Command /> component uses the Command component from Bits UI, which is inspired by cmdk.
Installation #
pnpm dlx shadcn-svelte@latest add commandnpx shadcn-svelte@latest add commandnpx shadcn-svelte@latest add commandbun x shadcn-svelte@latest add commandInstall 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.
<script lang="ts">
import * as Dialog from "$lib/components/ui/dialog/index.js";
import { cn, type WithoutChildrenOrChild } from "$lib/utils.js";
import Command from "./command.svelte";
import type { Command as CommandPrimitive, Dialog as DialogPrimitive } from "bits-ui";
import type { Snippet } from "svelte";
let {
open = $bindable(false),
ref = $bindable(null),
value = $bindable(""),
title = "Command Palette",
description = "Search for a command to run...",
showCloseButton = false,
portalProps,
children,
class: className,
...restProps
}: WithoutChildrenOrChild<DialogPrimitive.RootProps> &
WithoutChildrenOrChild<CommandPrimitive.RootProps> & {
portalProps?: DialogPrimitive.PortalProps;
children: Snippet;
title?: string;
description?: string;
showCloseButton?: boolean;
class?: string;
} = $props();
</script>
<Dialog.Root bind:open {...restProps}>
<Dialog.Header class="sr-only">
<Dialog.Title>{title}</Dialog.Title>
<Dialog.Description>{description}</Dialog.Description>
</Dialog.Header>
<Dialog.Content
class={cn("rounded-xl! top-1/3 translate-y-0 overflow-hidden p-0", className)}
{showCloseButton}
{portalProps}
>
<Command {...restProps} bind:value bind:ref {children} />
</Dialog.Content>
</Dialog.Root>
Usage #
<script lang="ts">
import * as Command from "$lib/components/ui/command/index.js";
</script> <Command.Root>
<Command.Input placeholder="Type a command or search..." />
<Command.List>
<Command.Empty>No results found.</Command.Empty>
<Command.Group heading="Suggestions">
<Command.Item>Calendar</Command.Item>
<Command.Item>Search Emoji</Command.Item>
<Command.Item>Calculator</Command.Item>
</Command.Group>
<Command.Separator />
<Command.Group heading="Settings">
<Command.Item>Profile</Command.Item>
<Command.Item>Billing</Command.Item>
<Command.Item>Settings</Command.Item>
</Command.Group>
</Command.List>
</Command.Root> Basic #
A simple command menu in a dialog.
Command Palette
Search for a command to run...
<script lang="ts">
import * as Command from "$lib/components/ui/command/index.js";
import { Button } from "$lib/components/ui/button/index.js";
let open = $state(false);
</script>
<div class="flex flex-col gap-4">
<Button onclick={() => (open = true)} variant="outline" class="w-fit"
>Open Menu</Button
>
<Command.Dialog bind:open>
<Command.Input placeholder="Type a command or search..." />
<Command.List>
<Command.Empty>No results found.</Command.Empty>
<Command.Group heading="Suggestions">
<Command.Item>Calendar</Command.Item>
<Command.Item>Search Emoji</Command.Item>
<Command.Item>Calculator</Command.Item>
</Command.Group>
</Command.List>
</Command.Dialog>
</div> Shortcuts #
Command Palette
Search for a command to run...
<script lang="ts">
import CreditCardIcon from "@lucide/svelte/icons/credit-card";
import SettingsIcon from "@lucide/svelte/icons/settings";
import UserIcon from "@lucide/svelte/icons/user";
import * as Command from "$lib/components/ui/command/index.js";
import { Button } from "$lib/components/ui/button/index.js";
let open = $state(false);
</script>
<div class="flex flex-col gap-4">
<Button onclick={() => (open = true)} variant="outline" class="w-fit"
>Open Menu</Button
>
<Command.Dialog bind:open>
<Command.Input placeholder="Type a command or search..." />
<Command.List>
<Command.Empty>No results found.</Command.Empty>
<Command.Group heading="Settings">
<Command.Item>
<UserIcon />
<span>Profile</span>
<Command.Shortcut>⌘P</Command.Shortcut>
</Command.Item>
<Command.Item>
<CreditCardIcon />
<span>Billing</span>
<Command.Shortcut>⌘B</Command.Shortcut>
</Command.Item>
<Command.Item>
<SettingsIcon />
<span>Settings</span>
<Command.Shortcut>⌘S</Command.Shortcut>
</Command.Item>
</Command.Group>
</Command.List>
</Command.Dialog>
</div> Groups #
A command menu with groups, icons and separators.
Command Palette
Search for a command to run...
<script lang="ts">
import CalculatorIcon from "@lucide/svelte/icons/calculator";
import CalendarIcon from "@lucide/svelte/icons/calendar";
import CreditCardIcon from "@lucide/svelte/icons/credit-card";
import SettingsIcon from "@lucide/svelte/icons/settings";
import SmileIcon from "@lucide/svelte/icons/smile";
import UserIcon from "@lucide/svelte/icons/user";
import * as Command from "$lib/components/ui/command/index.js";
import { Button } from "$lib/components/ui/button/index.js";
let open = $state(false);
</script>
<div class="flex flex-col gap-4">
<Button onclick={() => (open = true)} variant="outline" class="w-fit"
>Open Menu</Button
>
<Command.Dialog bind:open>
<Command.Input placeholder="Type a command or search..." />
<Command.List>
<Command.Empty>No results found.</Command.Empty>
<Command.Group heading="Suggestions">
<Command.Item>
<CalendarIcon />
<span>Calendar</span>
</Command.Item>
<Command.Item>
<SmileIcon />
<span>Search Emoji</span>
</Command.Item>
<Command.Item>
<CalculatorIcon />
<span>Calculator</span>
</Command.Item>
</Command.Group>
<Command.Separator />
<Command.Group heading="Settings">
<Command.Item>
<UserIcon />
<span>Profile</span>
<Command.Shortcut>⌘P</Command.Shortcut>
</Command.Item>
<Command.Item>
<CreditCardIcon />
<span>Billing</span>
<Command.Shortcut>⌘B</Command.Shortcut>
</Command.Item>
<Command.Item>
<SettingsIcon />
<span>Settings</span>
<Command.Shortcut>⌘S</Command.Shortcut>
</Command.Item>
</Command.Group>
</Command.List>
</Command.Dialog>
</div> Scrollable #
Scrollable command menu with multiple items.
Command Palette
Search for a command to run...
<script lang="ts">
import BellIcon from "@lucide/svelte/icons/bell";
import CalculatorIcon from "@lucide/svelte/icons/calculator";
import CalendarIcon from "@lucide/svelte/icons/calendar";
import CircleQuestionMarkIcon from "@lucide/svelte/icons/circle-question-mark";
import ClipboardPasteIcon from "@lucide/svelte/icons/clipboard-paste";
import CodeIcon from "@lucide/svelte/icons/code";
import CopyIcon from "@lucide/svelte/icons/copy";
import CreditCardIcon from "@lucide/svelte/icons/credit-card";
import FileTextIcon from "@lucide/svelte/icons/file-text";
import FolderIcon from "@lucide/svelte/icons/folder";
import FolderPlusIcon from "@lucide/svelte/icons/folder-plus";
import HouseIcon from "@lucide/svelte/icons/house";
import ImageIcon from "@lucide/svelte/icons/image";
import InboxIcon from "@lucide/svelte/icons/inbox";
import LayoutGridIcon from "@lucide/svelte/icons/layout-grid";
import ListIcon from "@lucide/svelte/icons/list";
import PlusIcon from "@lucide/svelte/icons/plus";
import ScissorsIcon from "@lucide/svelte/icons/scissors";
import SettingsIcon from "@lucide/svelte/icons/settings";
import TrashIcon from "@lucide/svelte/icons/trash";
import UserIcon from "@lucide/svelte/icons/user";
import ZoomInIcon from "@lucide/svelte/icons/zoom-in";
import ZoomOutIcon from "@lucide/svelte/icons/zoom-out";
import * as Command from "$lib/components/ui/command/index.js";
import { Button } from "$lib/components/ui/button/index.js";
let open = $state(false);
</script>
<div class="flex flex-col gap-4">
<Button onclick={() => (open = true)} variant="outline" class="w-fit"
>Open Menu</Button
>
<Command.Dialog bind:open>
<Command.Input placeholder="Type a command or search..." />
<Command.List>
<Command.Empty>No results found.</Command.Empty>
<Command.Group heading="Navigation">
<Command.Item>
<HouseIcon />
<span>Home</span>
<Command.Shortcut>⌘H</Command.Shortcut>
</Command.Item>
<Command.Item>
<InboxIcon />
<span>Inbox</span>
<Command.Shortcut>⌘I</Command.Shortcut>
</Command.Item>
<Command.Item>
<FileTextIcon />
<span>Documents</span>
<Command.Shortcut>⌘D</Command.Shortcut>
</Command.Item>
<Command.Item>
<FolderIcon />
<span>Folders</span>
<Command.Shortcut>⌘F</Command.Shortcut>
</Command.Item>
</Command.Group>
<Command.Separator />
<Command.Group heading="Actions">
<Command.Item>
<PlusIcon />
<span>New File</span>
<Command.Shortcut>⌘N</Command.Shortcut>
</Command.Item>
<Command.Item>
<FolderPlusIcon />
<span>New Folder</span>
<Command.Shortcut>⇧⌘N</Command.Shortcut>
</Command.Item>
<Command.Item>
<CopyIcon />
<span>Copy</span>
<Command.Shortcut>⌘C</Command.Shortcut>
</Command.Item>
<Command.Item>
<ScissorsIcon />
<span>Cut</span>
<Command.Shortcut>⌘X</Command.Shortcut>
</Command.Item>
<Command.Item>
<ClipboardPasteIcon />
<span>Paste</span>
<Command.Shortcut>⌘V</Command.Shortcut>
</Command.Item>
<Command.Item>
<TrashIcon />
<span>Delete</span>
<Command.Shortcut>⌫</Command.Shortcut>
</Command.Item>
</Command.Group>
<Command.Separator />
<Command.Group heading="View">
<Command.Item>
<LayoutGridIcon />
<span>Grid View</span>
</Command.Item>
<Command.Item>
<ListIcon />
<span>List View</span>
</Command.Item>
<Command.Item>
<ZoomInIcon />
<span>Zoom In</span>
<Command.Shortcut>⌘+</Command.Shortcut>
</Command.Item>
<Command.Item>
<ZoomOutIcon />
<span>Zoom Out</span>
<Command.Shortcut>⌘-</Command.Shortcut>
</Command.Item>
</Command.Group>
<Command.Separator />
<Command.Group heading="Account">
<Command.Item>
<UserIcon />
<span>Profile</span>
<Command.Shortcut>⌘P</Command.Shortcut>
</Command.Item>
<Command.Item>
<CreditCardIcon />
<span>Billing</span>
<Command.Shortcut>⌘B</Command.Shortcut>
</Command.Item>
<Command.Item>
<SettingsIcon />
<span>Settings</span>
<Command.Shortcut>⌘S</Command.Shortcut>
</Command.Item>
<Command.Item>
<BellIcon />
<span>Notifications</span>
</Command.Item>
<Command.Item>
<CircleQuestionMarkIcon />
<span>Help & Support</span>
</Command.Item>
</Command.Group>
<Command.Separator />
<Command.Group heading="Tools">
<Command.Item>
<CalculatorIcon />
<span>Calculator</span>
</Command.Item>
<Command.Item>
<CalendarIcon />
<span>Calendar</span>
</Command.Item>
<Command.Item>
<ImageIcon />
<span>Image Editor</span>
</Command.Item>
<Command.Item>
<CodeIcon />
<span>Code Editor</span>
</Command.Item>
</Command.Group>
</Command.List>
</Command.Dialog>
</div>