--- layout: layouts/page.njk title: Command description: Fast, composable command menu for quick navigation and actions. toc: - label: Usage id: usage children: - label: HTML + JavaScript id: usage-html-js children: - label: "Step 1: Include the JavaScript files" id: usage-html-js-1 - label: "Step 2: Add your command HTML" id: usage-html-js-2 - label: HTML structure id: usage-html-js-3 - label: JavaScript events id: usage-html-js-4 - label: Jinja and Nunjucks id: usage-macro - label: Examples id: examples children: - label: Dialog id: example-dialog --- {% from "macros/code_preview.njk" import code_preview %} {% from "macros/code_block.njk" import code_block %} {% from "command.njk" import command, command_dialog %} {% macro command_items(suggestions_id="suggestions", settings_id="settings") %}
Suggestions
{% lucide "calendar" %} Calendar
{% lucide "smile" %} Search Emoji
{% lucide "calculator" %} Calculator

Settings
{% lucide "user" %} Profile ⌘P
{% lucide "credit-card" %} Billing ⌘B
{% lucide "settings" %} Settings ⌘S
{% endmacro %} {% set code_standalone %} {% call command( id="demo-command-standalone", main_attrs={ "class": "rounded-lg border shadow-md" } ) %} {{ command_items("suggestions", "settings") }} {% endcall %} {% endset %} {{ code_preview("command-standalone", code_standalone | prettyHtml, class=" w-full max-w-[450px]") }}

Usage

HTML + JavaScript

Step 1: Include the JavaScript files

You can either include the JavaScript file for all the components, or just the one for this component by adding this to the <head> of your page:

{% set code_script %} {% endset %} {{ code_block(code_script | prettyHtml, "html") }}
Components with JavaScript {% lucide "arrow-right" %} Use the CLI {% lucide "arrow-right" %} command.js {% lucide "arrow-right" %}

Step 2: Add your command HTML

You can use the command menu standalone:

{{ code_block(code_standalone | prettyHtml, "html") }}

Wrap the command menu in a <dialog class="command-dialog"> to display in a dialog:

{% set code_dialog %}
{% endset %} {{ code_block(code_dialog | prettyHtml, "html") }}

HTML structure

<dialog class="command-dialog"> Optional
For dialog variant, wraps a <div class="command"> to display as a modal. Uses native <dialog> behavior and requires aria-label or aria-labelledby for accessibility.
<div class="command">
Wraps around the entire command component. Can be used standalone or inside a dialog.
<header>
Contains the search input to filter command options.
<input type="text">
The search input. Should have:
  • role="combobox": indicates the input controls a menu with filtering
  • aria-expanded="true": the menu is always expanded
  • aria-controls="{ MENU_ID }": points to the menu's id
<div role="menu">
The menu containing the command items. Should have id="{ MENU_ID }" refered to by the input's aria-controls attribute.
<div role="menuitem"> or <a role="menuitem">
Command item that triggers an action when clicked. Use <a> for navigation links, or <div> for actions. In a command-dialog, clicking a menuitem automatically closes the dialog unless the data-keep-command-open attribute is present. Optional attributes:
  • href: If present on an <a>, the item navigates to that URL
  • data-filter: custom text used for filtering (if different from displayed content, e.g., data-filter="calendar event")
  • data-keywords: additional keywords for enhanced filtering (e.g., data-keywords="calendar event date")
  • data-force: forces the item to always display, regardless of filter (e.g., data-force)
  • aria-disabled="true": marks item as disabled (excluded from keyboard navigation and filtering)
<hr role="separator"> Optional
Separator between groups/items. Hidden when filtering is active.
<div role="group"> Optional
Group of items, can have aria-labelledby attribute to link to a heading.
<span role="heading">
Group heading, must have an id attribute if you use the aria-labelledby attribute on the group.

JavaScript events

basecoat:initialized
Once the component is fully initialized, it dispatches a custom (non-bubbling) basecoat:initialized event on itself.

Jinja and Nunjucks

You can use the command() or command_dialog() Nunjucks or Jinja macros for this component.

Use Nunjucks or Jinja macros {% lucide "arrow-right" %} Jinja macro {% lucide "arrow-right" %} Nunjucks macro {% lucide "arrow-right" %}
{% set raw_code %}{% raw %}{% call command() %}
... Calendar
... Settings
{% endcall %}{% endraw %}{% endset %} {{ code_block(raw_code, "jinja") }}

You can also use the items parameter to pass an array of items:

{% set icon_calendar %}{% lucide "calendar" %}{% endset %} {% set icon_settings %}{% lucide "settings" %}{% endset %} {% set raw_code_items %}{% raw %}{% set icon_calendar %}{% lucide "calendar" %}{% endset %} {% set icon_settings %}{% lucide "settings" %}{% endset %} {% set items = [ { type: "group", label: "Suggestions", items: [ { label: "Calendar", icon: icon_calendar, keywords: "date event" }, { label: "Search Emoji", icon: icon_settings }, { label: "Calculator", disabled: true } ]}, { type: "separator" }, { type: "group", label: "Settings", items: [ { label: "Profile", url: "/profile", icon: icon_settings, keywords: "user account" }, { label: "Billing", url: "/billing", icon: icon_settings }, { label: "Settings", url: "/settings", icon: icon_settings } ]} ] %} {% call command(items=items) %}{% endcall %}{% endraw %}{% endset %} {{ code_block(raw_code_items, "jinja") }}

Examples

Dialog

You can use some simple JavaScript to open the command menu with a keyboard shortcut (in this case ⌘J).

{% set code_dialog %} {% call command_dialog(id="demo-command-dialog") %} {{ command_items("cmd-suggestions", "cmd-settings") }} {% endcall %} {% endset %} {{ code_preview("command-dialog", code_dialog | prettyHtml) }}