Command

Usage

Template macros available

This component ships command() and command_dialog() macros for Jinja and Nunjucks.

Include CSS

Import Tailwind and one full Basecoat style bundle.

@import "tailwindcss";
@import "basecoat-css/vega.css";

Or import only the base CSS, Command component CSS, and one style pack.

@import "tailwindcss";
@import "basecoat-css/base.css";
@import "basecoat-css/components/command.css";
@import "basecoat-css/styles/vega.css";

Using CDN or bundler imports? See the Installation page.

Include JavaScript

Copy or serve the full Basecoat JavaScript bundle.

<script src="/assets/js/all.min.js" defer></script>

Or copy or serve the Basecoat runtime and Command script.

<script src="/assets/js/basecoat.min.js" defer></script>
<script src="/assets/js/command.min.js" defer></script>

Using CDN or bundler imports? See the Installation page.

Add your command HTML

<div id="demo-command-standalone" class="command border" aria-label="Command menu">
  <header><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-search-icon lucide-search"><circle cx="11" cy="11" r="8" /><path d="m21 21-4.3-4.3" /></svg>
    <input type="text" id="demo-command-standalone-input" placeholder="Type a command or search..." autocomplete="off" autocorrect="off" spellcheck="false" aria-autocomplete="list" role="combobox" aria-expanded="true" aria-controls="demo-command-standalone-menu" />
  </header>
  <div role="menu" id="demo-command-standalone-menu" aria-orientation="vertical" data-empty="No results found.">
    <div role="group" aria-labelledby="suggestions">
      <span role="heading" id="suggestions">Suggestions</span>
      <div role="menuitem" data-filter="Calendar" data-keywords="date event schedule"><svg class="lucide lucide-calendar" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M8 2v4" /><path d="M16 2v4" /><rect width="18" height="18" x="3" y="4" rx="2" /><path d="M3 10h18" /></svg>
        <span>Calendar</span>
      </div>
      <div role="menuitem" data-filter="Search Emoji" data-keywords="emoji smile reaction"><svg class="lucide lucide-smile" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10" /><path d="M8 14s1.5 2 4 2 4-2 4-2" /><line x1="9" x2="9.01" y1="9" y2="9" /><line x1="15" x2="15.01" y1="9" y2="9" /></svg>
        <span>Search Emoji</span>
      </div>
      <div role="menuitem" aria-disabled="true"><svg class="lucide lucide-calculator" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="16" height="20" x="4" y="2" rx="2" /><line x1="8" x2="16" y1="6" y2="6" /><line x1="16" x2="16" y1="14" y2="18" /><path d="M16 10h.01" /><path d="M12 10h.01" /><path d="M8 10h.01" /><path d="M12 14h.01" /><path d="M8 14h.01" /><path d="M12 18h.01" /><path d="M8 18h.01" /></svg>
        <span>Calculator</span>
      </div>
    </div>
    <hr role="separator" />
    <div role="group" aria-labelledby="settings">
      <span role="heading" id="settings">Settings</span>
      <div role="menuitem" data-filter="Profile" data-keywords="user account"><svg class="lucide lucide-user" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2" /><circle cx="12" cy="7" r="4" /></svg>
        <span>Profile</span>
        <span data-shortcut>⌘P</span>
      </div>
      <div role="menuitem" data-filter="Billing" data-keywords="invoice payment"><svg class="lucide lucide-credit-card" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="14" x="2" y="5" rx="2" /><line x1="2" x2="22" y1="10" y2="10" /></svg>
        <span>Billing</span>
        <span data-shortcut>⌘B</span>
      </div>
      <div role="menuitem" data-filter="Settings" data-keywords="config preferences"><svg class="lucide lucide-settings" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915" /><circle cx="12" cy="12" r="3" /></svg>
        <span>Settings</span>
        <span data-shortcut>⌘S</span>
      </div>
    </div>
  </div>
</div>

Use <dialog class="command-dialog"> for the command palette variant.

<button class="btn" data-variant="outline" onclick="document.getElementById('command-palette').showModal()">Open</button>
<dialog id="command-palette" class="command-dialog" aria-label="Command menu">
  <div class="command">
    <!-- Command content -->
  </div>
</dialog>

HTML structure

The command menu can be used standalone or inside a native dialog. The structure is:

<dialog class=“command-dialog”> Optional

Dialog variant. Wraps one direct child <div class=“command”>. Add aria-label or aria-labelledby for an accessible name.

<div class=“command”>

Root command menu. Can also be used standalone without the dialog wrapper. Add data-filter=“manual” when your app owns filtering, such as remote search or a local Lunr index.

<header>

Search input wrapper. The macro includes a search icon and input.

<input type=“text” role=“combobox”>
Filter input. Use aria-expanded=“true” and aria-controls=”{ MENU_ID }” to point to the command list.
<div role=“menu” id=”{ MENU_ID }”>

Command list. Set data-empty to customize the empty state.

<div role=“group” aria-labelledby=”{ HEADING_ID }”> Optional
Groups related command items. Hidden automatically when every item in the group is filtered out.
<span role=“heading” id=”{ HEADING_ID }”> Optional
Group heading. Use an id when the parent group uses aria-labelledby.
<div role=“menuitem”> or <a role=“menuitem”>
Selectable command item. Use <a> for navigation and <div> for actions. Supports data-filter, data-keywords, data-force, data-keep-command-open, aria-disabled=“true”, and data-disabled=“true”.
<span data-shortcut> Optional
Shortcut hint aligned to the inline end of the item.
<span data-indicator> Optional
Item indicator. It becomes visible with data-checked=“true” or aria-selected=“true”.
<hr role=“separator”> Optional
Separator between groups/items. Hidden while filtering.

JavaScript API

APITypeDescription
command.refresh()MethodRescans command items after children change inside the existing role="menu" list.

Examples

Basic

A simple command menu in a dialog.

Shortcuts

Groups

Scrollable

RTL

Add dir="rtl" to the command root or an ancestor.