Files
basecoat/docs/src/components/command.md
T

14 KiB

templateEngineOverride, layout, title, description, toc
templateEngineOverride layout title description toc
njk layouts/page.njk Command Command menu for search and quick actions.
label id
About about
label id children
Usage usage
label id children
HTML + JavaScript usage-html-js
label id
Step 1: Include the JavaScript files usage-html-js-1
label id
Step 2: Add your command HTML usage-html-js-2
label id
HTML structure usage-html-js-3
label id
JavaScript API usage-html-js-4
label id
Jinja and Nunjucks usage-macro
label id children
Examples examples
label id
Basic example-basic
label id
Shortcuts example-shortcuts
label id
Groups example-groups
label id
Scrollable example-scrollable
label id
RTL example-rtl
label id
API Reference api-reference

{% 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", shortcuts=false) %}

Suggestions
{% lucide "calendar" %} Calendar {% if shortcuts %}⌘K{% endif %}
{% lucide "smile" %} Search Emoji {% if shortcuts %}⌘E{% endif %}
{% lucide "calculator" %} Calculator

Settings
{% lucide "user" %} Profile {% if shortcuts %}⌘P{% endif %}
{% lucide "credit-card" %} Billing {% if shortcuts %}⌘B{% endif %}
{% lucide "settings" %} Settings {% if shortcuts %}⌘S{% endif %}
{% endmacro %}

{% set code_standalone %} {% call command(id="demo-command-standalone", main_attrs={ "class": "border" }) %} {{ command_items("suggestions", "settings") }} {% endcall %} {% endset %}

{{ code_preview("command-standalone", code_standalone | prettyHtml, class="w-full max-w-sm") }}

About

shadcn/ui's Command component is built on cmdk. Basecoat implements the same command-menu pattern with vanilla HTML, CSS, and a small JavaScript controller for filtering, active item navigation, and dialog closing.

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 %}<script src="https://cdn.jsdelivr.net/npm/basecoat-css@{{ pkg.version }}/dist/js/basecoat.min.js" defer></script>

<script src="https://cdn.jsdelivr.net/npm/basecoat-css@{{ pkg.version }}/dist/js/command.min.js" defer></script>{% endset %}

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

Step 2: Add your command HTML

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

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

{% set code_dialog_usage %}Open

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

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 <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, and aria-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

basecoat:initialized
Once the component is initialized, it dispatches a custom non-bubbling basecoat:initialized event on itself.
command.refresh()
Rescans command items after changing children inside the existing role="menu" list.
data-filter="manual"
Disables Basecoat's built-in text filtering. Update the menu items yourself, then call command.refresh().
window.basecoat.refresh(command)
Calls the component refresh method through the global dispatcher.

Jinja and Nunjucks

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

{% set raw_code %}{% raw %}{% call command() %}

... Calendar
... Settings
{% endcall %}{% endraw %}{% endset %} {{ code_block(raw_code, "jinja") }}

Examples

Basic

A simple command menu in a dialog. The button also shows the keyboard shortcut used in this example.

{% set code_basic %} Open command menu ⌘J {% call command_dialog(id="command-basic") %} {{ command_items("command-basic-suggestions", "command-basic-settings") }} {% endcall %}

<script> document.addEventListener('keydown', (event) => { if ((event.metaKey || event.ctrlKey) && event.key === 'j') { event.preventDefault(); const dialog = document.getElementById('command-basic'); dialog.open ? dialog.close() : dialog.showModal(); dialog.querySelector('header input')?.focus(); } }); </script>

{% endset %} {{ code_preview("command-basic", code_basic | prettyHtml) }}

Shortcuts

{% set code_shortcuts %} {% call command(id="command-shortcuts", main_attrs={ "class": "border" }) %} {{ command_items("command-shortcuts-suggestions", "command-shortcuts-settings", true) }} {% endcall %} {% endset %} {{ code_preview("command-shortcuts", code_shortcuts | prettyHtml, class="w-full max-w-sm") }}

Groups

{% set code_groups %} {% call command(id="command-groups", main_attrs={ "class": "border" }) %} {{ command_items("command-groups-suggestions", "command-groups-settings") }} {% endcall %} {% endset %} {{ code_preview("command-groups", code_groups | prettyHtml, class="w-full max-w-sm") }}

Scrollable

{% set code_scrollable %} {% call command(id="command-scrollable", main_attrs={ "class": "border" }) %}

Pages {% for i in range(0, 18) %}
{% lucide "file" %} Page {{ i + 1 }}
{% endfor %}
{% endcall %} {% endset %} {{ code_preview("command-scrollable", code_scrollable | prettyHtml, class="w-full max-w-sm") }}

RTL

Command supports document direction. Set dir="rtl" on the command root or a parent element.

{% set code_rtl %}

{% call command(id="command-rtl", placeholder="اكتب أمراً أو ابحث...", main_attrs={ "class": "border" }) %}
اقتراحات
{% lucide "calendar" %} التقويم ⌘K
{% lucide "settings" %} الإعدادات ⌘S
{% endcall %}
{% endset %} {{ code_preview("command-rtl", code_rtl | prettyHtml, class="w-full max-w-sm") }}

API Reference

.command
Root command menu.
.command-dialog
Native dialog variant. Closes automatically when an item is clicked unless that item has data-keep-command-open.
data-filter
Overrides item text used by the filter.
data-keywords
Additional whitespace- or comma-separated search terms.
data-force
Always keeps an item visible while filtering.
data-empty
Custom empty-state text on the menu element.