mica
mica

Example

Design

Theme builderMake Mica your own.

Components

ListsDialogs
↑ ↓ to move · Enter to open

Try the full interactive example: inline and modal, descriptions, group dividers, empty results, and application-owned actions.

Usage

<script type="module" src="command.js"></script>
<m-command-palette>
  <header>
    <input data-command-input hidden aria-label="Find a command">
  </header>
  <m-command-list dividers aria-label="Commands">
    <m-command-group>
      <h3>Workspace</h3>
      <button type="button" data-command-item data-keywords="add new">
        <span>Create project<small>Start something new.</small></span>
      </button>
      <a data-command-item href="/settings"><span>Settings</span></a>
    </m-command-group>
  </m-command-list>
  <p data-command-empty role="status" hidden>No matching commands.</p>
</m-command-palette>

Use one labeled input and list per command, native buttons for actions, and anchors for destinations. Groups and their heading (h2–h6) are optional. Without JavaScript, links and buttons remain usable; the hidden search input appears after enhancement. Do not nest other interactive controls inside a command item.

Content and separators

Descriptions are optional small content inside the label span. Omit them for single-line rows. An optional decorative SVG before the label receives icon sizing; Mica bundles no icons. A trailing kbd can describe an application shortcut, but does not register one.

Groups use whitespace by default. Add dividers to m-command-list for separators. Override --command-list-height to change the scroll limit or --command-active-background to change the quiet selected fill.

Behavior

Importing command.js registers m-command-palette. It filters case-insensitively by all query words in item text and data-keywords, hides empty groups, and selects the first available match. Arrow keys wrap through enabled results; Enter clicks the authored item. Focus stays in the input using combobox/listbox semantics and aria-activedescendant. Native disabled buttons and aria-disabled="true" items are skipped. Application click handlers own the action.

Use <m-command-palette filter="manual"> when your application owns ranking, remote requests, loading, and result markup. Mica does not filter or hide groups in this mode. DOM updates are observed automatically; call command.refresh() to reconcile synchronously after replacing results. Keep a stable input and list, and use the same item markup. Docs search uses this mode.

Dialog composition

<dialog id="palette" closedby="any" aria-label="Commands">
  <m-command-palette></m-command-palette>
</dialog>
<script>
  const palette = document.querySelector('#palette');
  document.querySelector('#open').onclick = () => palette.showModal();
</script>

The command surface keeps its spacing inside a dialog. The application owns the opening button, global shortcuts, and closing after activation. The browser supplies modal focus containment and Escape dismissal. Use a text input to avoid a search input consuming Escape to clear its value. closedby="any" enables backdrop dismissal where supported; older browsers still close with Escape and can use an application-provided close control. Mica does not add a close button to the command surface.

← comboboxaction menu →