Interactive
Command search
Makes a .command-palette searchable: items filter by text and data-keywords, empty headings hide, arrows move the selection, Enter runs the item, and a hotkey such as Ctrl K opens the dialog. Needs monsoon.js.
Needs monsoon.js. The styles work on their own, and the behavior comes from the optional interactive layer: add <script src="https://cdn.jsdelivr.net/npm/monsooncss/dist/monsoon.js" defer></script> or import 'monsooncss/js'. See the interactive layer.
Example
<button type="button" commandfor="cmd-js" command="show-modal" class="btn btn-outline btn-sm"><svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></svg>Search<kbd class="kbd kbd-xs">Ctrl K</kbd></button>
<dialog id="cmd-js" class="modal modal-top" aria-label="Command palette">
<div class="command-palette" data-m-command data-m-command-hotkey="mod+k">
<label class="command-palette-search"><input class="command-palette-input" placeholder="Type a command or search"></label>
<div class="command-palette-list">
<p class="command-palette-heading">Actions</p>
<button type="button" class="command-palette-item" data-keywords="create add page"><svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M14 3H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"/><path d="M14 3v6h6"/></svg>New document<span class="command-palette-shortcut"><kbd>Ctrl</kbd><kbd>N</kbd></span></button>
<button type="button" class="command-palette-item" data-keywords="people team members"><svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="9" cy="8" r="4"/><path d="M2 21a7 7 0 0 1 14 0M16 4a4 4 0 0 1 0 8M22 21a7 7 0 0 0-4-6.3"/></svg>Invite teammates</button>
<button type="button" class="command-palette-item" data-keywords="night appearance"><svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"/></svg>Toggle dark mode</button>
<p class="command-palette-heading">Settings</p>
<button type="button" class="command-palette-item" data-keywords="account avatar"><svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="8" r="4"/><path d="M4 21a8 8 0 0 1 16 0"/></svg>Profile</button>
<button type="button" class="command-palette-item" data-keywords="alerts email"><svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"/></svg>Notifications</button>
<button type="button" class="command-palette-item" data-keywords="invoice card plan"><svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="2" y="5" width="20" height="14" rx="2"/><path d="M2 10h20"/></svg>Billing</button>
</div>
<div class="command-palette-footer"><span><kbd>Up</kbd> <kbd>Down</kbd> to move</span><span><kbd>Enter</kbd> to run</span><span><kbd>Esc</kbd> to close</span></div>
</div>
<form method="dialog" class="modal-backdrop"><button aria-label="Close">Close</button></form>
</dialog>JavaScript API
Attribute
data-m-command
Options
| Option | Description |
|---|---|
data-m-command-hotkey="mod+k" (Ctrl K, or Cmd K on a Mac) | |
data-m-command-empty="Nothing found" | |
data-keywords and data-value on items |
Methods
| Method | Description |
|---|---|
Monsoon.command(el).open() | |
Monsoon.command(el).close() | |
Monsoon.command(el).filter("theme") |
Events
| Event | Description |
|---|---|
monsoon:command { item, value } (preventDefault keeps the palette open) |
Classes
9 classes. Click a name to copy it. Utilities on the same element always win over component defaults, so any of them can be adjusted with plain utility classes.
| Class | Type | What it does |
|---|---|---|
| Base | Base class of the command search. On a <div> in the example. Sets transform, flex display, alignment, width, height and overflow, and --tone and --tone-fg.CSS |
|
| Part | Part of the command search. On a <label> in the example. Sets flex display, alignment, gap, padding, border and generated content.CSS |
|
| Part | Part of the command search. On an <input> in the example. Sets alignment, width, height, text size, background and text color.CSS |
|
| Part | Part of the command search. On a <div> in the example. Sets alignment, overflow and padding.CSS |
|
| Part | Part of the command search. On a <p> in the example. Sets padding, text size, font weight and text color.CSS |
|
| Part | Part of the command search. On a <button> in the example. Sets flex display, alignment, gap, width, padding and corner radius.CSS |
|
| Part | Part of the command search. On a <span> in the example. Sets inline-flex display, gap, margin, text size, text color and inline-grid display.CSS |
|
| Modifier | Modifier, combined with the command-palette class. Not used in the example above. Sets padding, text size, text style and text color.CSS |
|
| Part | Part of the command search. On a <div> in the example. Sets inline-grid display, alignment, width, height, padding and text size.CSS |
Usage
The styles ship inside the same stylesheet as the utilities, and the behavior comes from the optional monsoon.js script, which enhances any element with a matching data-m attribute, including markup added later.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/monsooncss">
<script src="https://cdn.jsdelivr.net/npm/monsooncss/dist/monsoon.js" defer></script>
<!-- Command search: start from the base class, then add modifiers -->
<button type="button" commandfor="cmd-js" command="show-modal" class="btn btn-outline btn-sm"><svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></svg>Search<kbd class="kbd kbd-xs">Ctrl K</kbd></button>
<dialog id="cmd-js" class="modal modal-top" aria-label="Command palette">
<div class="command-palette" data-m-command data-m-command-hotkey="mod+k">
<label class="command-palette-search"><input class="command-palette-input" placeholder="Type a command or search"></label>
<div class="command-palette-list">
<p class="command-palette-heading">Actions</p>
<button type="button" class="command-palette-item" data-keywords="create add page"><svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M14 3H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"/><path d="M14 3v6h6"/></svg>New document<span class="command-palette-shortcut"><kbd>Ctrl</kbd><kbd>N</kbd></span></button>
<button type="button" class="command-palette-item" data-keywords="people team members"><svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="9" cy="8" r="4"/><path d="M2 21a7 7 0 0 1 14 0M16 4a4 4 0 0 1 0 8M22 21a7 7 0 0 0-4-6.3"/></svg>Invite teammates</button>
<button type="button" class="command-palette-item" data-keywords="night appearance"><svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"/></svg>Toggle dark mode</button>
<p class="command-palette-heading">Settings</p>
<button type="button" class="command-palette-item" data-keywords="account avatar"><svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="8" r="4"/><path d="M4 21a8 8 0 0 1 16 0"/></svg>Profile</button>
<button type="button" class="command-palette-item" data-keywords="alerts email"><svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"/></svg>Notifications</button>
<button type="button" class="command-palette-item" data-keywords="invoice card plan"><svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="2" y="5" width="20" height="14" rx="2"/><path d="M2 10h20"/></svg>Billing</button>
</div>
<!-- the full example is in the Code tab above -->Theme it with --seed on any ancestor, for example style="--seed: #0d9488", and force a scheme with class="dark" or class="light" on a wrapper.
Accessibility
- Built on the native
dialogelement. Opened withshowModal()(or a command button) it goes to the top layer, makes the rest of the page inert, closes with Escape and returns focus to the button that opened it. - Give every control a visible
labellinked withfor, or anaria-labelwhen the purpose is obvious from context. Link help and error text witharia-describedby; invalid styles use:user-invalid, so they appear only after the user interacts. - Use
buttonfor actions andafor navigation. Icon only buttons need anaria-label; decorative icons carryaria-hidden="true". - Give meaningful images an
alttext and decorative onesalt="". Initials avatars should expose the full name to screen readers. - Every interactive part shows a visible focus ring with
:focus-visible, and tone colors pair with-foregroundtokens that keep text at 4.5:1 or better in light and dark mode.