Command palette
A ⌘K dialog: a large search input over grouped options with shortcut hints.
Examples
Palette
Anatomy
dialog.palette | A native <dialog> about 47rem wide, centred and set high on the screen, with no padding. |
> .icon:first-child | Optional glyph before the input, muted until there is a term. Needs the icon set. |
> input.input | Direct child. Large, borderless, with a hairline below. |
[role=listbox] | The results, scrolling past half the viewport height. |
[role=group] > h6 | Optional group label: wrap each set of options in role="group" with the same aria-label, and hide the <h6> from assistive tech. The group is hidden when none of its options match. |
> [role=option] | One result. Text matching the search is drawn in the accent; a trailing <kbd> is pushed to the end. |
> .icon, small | Optional, in an option: a leading glyph and a muted second label. |
.empty[hidden] | Optional, after the listbox: aequitas.js shows it when nothing matches. |
> footer | Optional key legend below the results. Hidden on touch screens. |
API
| Attribute | Values | Description |
|---|---|---|
aria-selected | true | On an option: the keyboard's place in the list, tinted with an accent edge. aequitas.js moves it. |
data-keywords | <words> | On an option: extra words it matches, beyond its text ("dark" finds Toggle theme). |
data-term | boolean | Inside .empty: aequitas.js writes the search term into it. |
data-close | boolean | On an option: closes the palette when it runs (aequitas.js). |
data-light-dismiss | boolean | A click on the backdrop closes the palette (aequitas.js). |
data-open | <selector> | On the opener: aequitas.js calls showModal() on the palette. |
data-manual | boolean | On the dialog: aequitas.js does not filter or navigate it, for results you render yourself. |
Behaviour
Opens and closes like Dialog. aequitas.js filters the options as you type, moves the highlight, runs the highlighted option on Enter and clears the search each time the palette opens. Matching text is drawn with the CSS Custom Highlight API, so your markup is never rewritten; a [data-manual] palette can call markMatches(listbox, term) after rendering. The ⌘K shortcut and what each option does are yours to wire: listen for click on the options.
From aequitas.js. It initialises itself and enhances markup added later on its own, so it works the same in an SPA.
Accessibility
- aequitas.js gives the input
role="combobox",aria-controlsandaria-activedescendant, so the highlighted result is announced while focus stays in the input. - Label the listbox for what it holds; without a label aequitas.js names it "Results". Only
groupandoptionmay sit inside a listbox, so wrap each set inrole="group"with anaria-labeland mark the visible<h6>aria-hidden="true"so the label is not read twice. - Keep
autofocuson the input so typing starts at once.
| Key | Effect |
|---|---|
| ↑ / ↓ | Moves the highlight through the matching options, wrapping at the ends. |
| Enter | Clicks the highlighted option. |
| Esc | Closes the palette (native, as a modal dialog). |