DEV3 Technologies home

Command palette search

A keyboard driven command palette that opens with Ctrl or Cmd K, filters a list as you type and runs the highlighted entry.

Tailwind CSSSearchcommand-palettesearchkeyboarddialog

Live preview

Code

<dialog id="palette" aria-label="Command palette"
  class="mx-auto mt-24 w-full max-w-lg rounded-xl bg-white p-0 shadow-2xl backdrop:bg-slate-900/50">
  <input id="palette-input" type="text" role="combobox" aria-expanded="true" aria-controls="palette-list"
    aria-autocomplete="list" placeholder="Search docs..." autocomplete="off"
    class="w-full border-b border-slate-200 px-4 py-3 text-slate-900 outline-none">
  <ul id="palette-list" role="listbox" class="max-h-72 overflow-y-auto p-2 text-sm"></ul>
  <p class="border-t border-slate-100 px-4 py-2 text-xs text-slate-400">Arrows to move, Enter to open, Esc to close</p>
</dialog>

How it works

What it solves

Readers of large documentation sets want to jump to a page without touching the mouse. A palette gives a single shortcut, instant filtering and arrow key navigation using an array and a native dialog.

How it works

The panel is a dialog opened with showModal(), which gives a focus trap, an inert background and Escape handling for free. A global keydown listener watches for k with the Ctrl or Meta key and toggles it. The input handler lowercases the query, filters a plain array of {label, href} items and re-renders the list, setting role="option" and aria-selected on the active row. Arrow keys move the index with wrap-around, and Enter navigates to the active href. The input uses role="combobox" with aria-controls and aria-activedescendant so assistive tech follows the selection without moving focus off the field.

Adapting it

Replace the array with a fetched search index, or add a group field and render headings. For actions instead of links, store a function reference and call it on Enter.

Pitfalls

  • Escape the label before inserting it as HTML; this version uses textContent.
  • Prevent the default browser shortcut for Ctrl K or the address bar may steal it.
  • Reset the index to zero whenever the filter changes.

How to use it

  1. Paste palette.html near the end of <body> in a Tailwind 4 page.
  2. Load palette.js with defer.
  3. Edit the items array with your own labels and URLs.
  4. Add a visible hint button elsewhere that calls dialog.showModal() for touch users.

Licence: DEV3 Snippet Licence. Free to use, change and ship in personal and commercial projects. Attribution is appreciated, not required. Please do not redistribute snippets as a collection.

Related snippets