Blocks

Command

A command palette with fuzzy search and grouped results. Pair it with or another shortcut.

Installation

pnpm dlx @mielui/svelte add command

Usage

Compose Trigger and Content inside Root, with Search and Results in Content. Content is a modal dialog that manages focus and closes on Escape. Search updates the matching results when items change, including while a query is active.

Search composes native input and keyboard handlers; preventDefault in onkeydown cancels command navigation or activation. Enter during text composition confirms the text without running a command. Item forwards data attributes to its button or link.

<script lang="ts">
    import * as Command from '@mielui/svelte/components/command';
</script>

<Command.Root>
    <Command.Trigger>Open palette</Command.Trigger>
    <Command.Content>
        <Command.Header>Workspace</Command.Header>
        <Command.Search />
        <Command.Results>
            <Command.Item name="New project">New project</Command.Item>
            <Command.Item name="Settings" href="/settings">Settings</Command.Item>
        </Command.Results>
    </Command.Content>
</Command.Root>

Search and empty-state slots

Search accepts icon, count(total) and announcement(message) snippets. The count is decorative; announcement stays inside the shared polite live region. Results accepts an empty snippet. Omit any slot to retain its default, or supply an empty snippet to hide its content. These slots use the same filtered result count and announcement as the built-in rendering.

<Command.Search placeholder="Find a command">
    {#snippet icon()}
        <span aria-hidden="true">โŒ˜</span>
    {/snippet}
    {#snippet count(total)}
        {total} matches
    {/snippet}
    {#snippet announcement(message)}
        {message}
    {/snippet}
</Command.Search>
<Command.Results>
    {#snippet empty()}
        <p>Try a different search.</p>
    {/snippet}
    <Command.Item name="Open settings">Open settings</Command.Item>
</Command.Results>

Examples

Workspace palette

A search field opens a palette with a header, three groups, and a shortcut hint on one item.

With groups

Glass surface

Set surface="glass" on Content for a translucent panel with blur, or surface="solid" for an opaque one. Without surface, the panel follows the theme. Glass falls back to an opaque panel when backdrop filtering is unavailable or reduced transparency is on.

Controlling the palette

Bind open on Root to show the palette from a keyboard shortcut or a menu item, and use onOpenChange to hear when it opens or closes. A press outside closes it unless you set allowClickOutside={false} on Content. labels.palette on Root is the palette's accessible name and defaults to Command palette.

Search filters with fuzzy matching. threshold sets how forgiving it is, from 0 for an exact match to 1 for nearly anything, and defaults to 0.2.

Trigger and items

Trigger is built on Button. disabled blocks it, loading with labels shows progress, element binds the DOM node, unstyled removes the Button classes, and onclick runs before the palette opens.

Give an Item callback to run an action, or href to navigate. The palette closes after either, so do not add a second click handler that repeats the action. onclick runs right after callback, name is the text the search matches, and value identifies the item when names repeat. disabled keeps it visible but unselectable.

Root, Content, Header, Results, Group, Item, Separator and Trigger render their children and accept class and style like any element.

Labels

Built-in text is English. Pass a CommandLabels object to labels on Root to translate the palette's name, the search placeholder, the names of the search input and the results list, the empty message, and the result count announced to screen readers. available is a function of the count so the number can sit anywhere in the sentence. Every key is optional, and an omitted key keeps its English default. A placeholder on Search wins over labels.searchPlaceholder.

<script lang="ts">
    import * as Command from '@mielui/svelte/components/command';
    import type { CommandLabels } from '@mielui/svelte/components/command';

    const labels: CommandLabels = {
        palette: 'Palette de commandes',
        searchPlaceholder: 'Rechercher une commandeโ€ฆ',
        search: 'Rechercher',
        results: 'Commandes',
        empty: 'Aucun rรฉsultat',
        available: (count) => {
            return count === 0 ? 'Aucune commande.' : `${count} commandes disponibles.`;
        }
    };
</script>

<Command.Root {labels}>
    <Command.Trigger>Ouvrir la palette</Command.Trigger>
    <Command.Content>
        <Command.Search />
        <Command.Results>
            <Command.Item name="Nouveau projet">Nouveau projet</Command.Item>
        </Command.Results>
    </Command.Content>
</Command.Root>

API reference

Command.Root

Provides command menu state.

  • labels
    CommandLabels

    Overrides the built-in text and accessible names. Every key is optional and English is the fallback.

  • open Bindable
    boolean

    Whether it is open. Bind it to control the state from outside.

    Default false

  • onOpenChange
    ((open: boolean) => void)

    Called with the new state whenever it opens or closes.

  • children
    Snippet<[]>

    Content rendered inside.

Command.Content

Contains command menu controls.

  • surface
    "solid" | "glass"

    Surface treatment. Omit it to inherit --mielui-surface from the theme.

  • children
    Snippet<[]>

    Content rendered inside.

  • class
    string

    Classes added to the element.

  • allowClickOutside
    boolean

    Closes when the pointer is pressed outside it. Set false to keep it open until it is dismissed another way.

    Default true

Command.Group

Groups command items.

  • children Required
    Snippet<[]>

    Content rendered inside.

  • class
    string

    Classes added to the element.

  • heading Required
    string

    Heading shown above the group.

Command.Header

  • class
    string

    Classes added to the element.

  • children
    Snippet<[]>

    Content rendered inside.

Command.Item

Defines a command action.

  • name
    string

    Text the search matches.

  • value
    string

    Identifier for the item when names repeat.

  • callback
    (() => void)

    Called when the item is chosen.

  • disabled
    boolean

    Prevents interaction and dims the control.

    Default false

  • href
    string

    Navigates to this address when the item is chosen.

  • onclick
    (() => void)

    Called when it is clicked or activated.

  • class
    string

    Classes added to the element.

  • children
    Snippet<[]>

    Content rendered inside.

Command.Results

Lists matching commands.

  • class
    string

    Classes added to the element.

  • children
    Snippet<[]>

    Content rendered inside.

  • empty
    Snippet<[]>

    Content shown when nothing matches.

Command.Search

Filters command items.

  • threshold
    number

    How loosely typed text may match, from 0 for exact to 1 for anything.

    Default DEFAULT_COMMAND_SEARCH_THRESHOLD

  • icon
    Snippet<[]>

    Replaces the search icon.

  • count
    Snippet<[count: number]>

    Renders the result count.

  • announcement
    Snippet<[message: string]>

    Renders the screen reader announcement.

Command.Separator

Separates command menu items.

  • children
    Snippet<[]>

    Content rendered inside.

  • class
    string

    Classes added to the element.

Command.Trigger

Opens the command menu.

  • disabled
    boolean

    Prevents activation. A disabled link loses its destination and is skipped by Tab.

  • variant
    ButtonVariant

    Visual style. Choose it for what the action means, not for decoration.

  • size
    "sm" | "md" | "lg" | "icon"

    Control height. icon is a square button for a single icon.

  • children
    Snippet<[]>

    Content rendered inside.

  • element
    HTMLButtonElement | HTMLAnchorElement

    Bindable reference to the rendered DOM element. Type is the union of the two possible element types -- narrow at the use site:

  • unstyled
    boolean

    Skip the variant/size base classes and render with class alone.

  • status
    ButtonStatus

    Controlled visual state. Loading remains focusable and refuses activation.

  • loading
    boolean

    Convenience alias for status="loading".

  • labels
    ButtonLabels

    Overrides the built-in text and accessible names. Every key is optional and English is the fallback.

  • onclick
    ((event: MouseEvent) => void)

    Called when the button is activated. Loading and disabled buttons do not call it.

  • onkeydown
    ((event: KeyboardEvent) => void)

    Called on key down, before the button handles the key itself.

  • href
    string

    Renders a link to this address instead of a button.