- ds
- Components
- Command palette
Command palette
Ctrl+K search over pages and actions.
This site's own search. Also opens with "/".
fin1te.com, topo and this site each have one. It is a native dialog with a combobox input and a listbox. The script is not on the page until you open it for the first time, so it costs nothing on load.
Structure
<dialog class="palette" aria-label="Command menu">
<div class="pbox">
<input type="text" role="combobox" aria-expanded="true" aria-controls="pl" placeholder="Jump to a page, post or action" />
<ul id="pl" role="listbox">
<li class="pg" role="presentation">Pages</li>
<li role="option" id="pi-0" aria-selected="true"><span>Work</span><span class="ph">/work</span></li>
<li role="option" id="pi-1" aria-selected="false"><span>Writing</span><span class="ph">/writing</span></li>
</ul>
<div class="pf"><span><kbd>↑</kbd><kbd>↓</kbd> move</span><span><kbd>↵</kbd> open</span><span><kbd>esc</kbd> close</span></div>
</div>
</dialog>Loading it lazily
addEventListener('keydown', (e) => {
if (e.key === 'k' && (e.metaKey || e.ctrlKey)) {
e.preventDefault();
import('./palette.js').then((m) => m.open());
}
});| Class | On | What it does |
|---|---|---|
.palette | dialog | Centred at 14vh, 35rem wide. |
.pbox | div | The surface: input, list, footer. |
.pg | li | Group heading. |
[role=option][aria-selected=true] | li | Active row, with an accent bar on the left. |
.ph / .pe / .pf | span, li, div | Row hint, empty message, footer with keys. |
.dense | .pbox | A 40px field and 28px options with an icon, a hint and a kbd shortcut. |
[role=option][aria-disabled=true] | li | A command that cannot run now: dimmed, still listed. |
Dense
Light
- Actions
- New sessionin ~/work/checkoutAlt N
- Fork session from the last turn
- Export session as Markdown
- Sessions
- Retry queue fixrunning · 4m
- Rename the billing columns in the warehouse schema and backfill the history2h
- Approve all pendingnothing pending
↑↓ move↵ runesc close
Dark
- Actions
- New sessionin ~/work/checkoutAlt N
- Fork session from the last turn
- Export session as Markdown
- Sessions
- Retry queue fixrunning · 4m
- Rename the billing columns in the warehouse schema and backfill the history2h
- Approve all pendingnothing pending
↑↓ move↵ runesc close
390px, dark
- Actions
- New sessionin ~/work/checkoutAlt N
- Fork session from the last turn
- Export session as Markdown
- Sessions
- Retry queue fixrunning · 4m
- Rename the billing columns in the warehouse schema and backfill the history2h
- Approve all pendingnothing pending
↑↓ move↵ runesc close
Code
<div class="pbox dense" style="box-shadow:none">
<input type="text" role="combobox" aria-expanded="true" aria-label="Command" placeholder="Run a command, open a session or a file" value="ses" />
<ul role="listbox" aria-label="Results">
<li class="pg" role="presentation">Actions</li>
<li role="option" aria-selected="true"><svg class="i" viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12h14"/><path d="M12 5v14"/></svg><span>New session</span><span class="ph">in ~/work/checkout</span><kbd class="kbd">Alt N</kbd></li>
<li role="option" aria-selected="false"><svg class="i" viewBox="0 0 24 24" aria-hidden="true"><line x1="6" x2="6" y1="3" y2="15"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/></svg><span>Fork session from the last turn</span><span class="ph"></span></li>
<li role="option" aria-selected="false"><svg class="i" viewBox="0 0 24 24" aria-hidden="true"><path d="M12 3v12"/><path d="m17 8-5-5-5 5"/><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/></svg><span>Export session as Markdown</span><span class="ph"></span></li>
<li class="pg" role="presentation">Sessions</li>
<li role="option" aria-selected="false"><svg class="i" viewBox="0 0 24 24" aria-hidden="true"><path d="M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z"/></svg><span>Retry queue fix</span><span class="ph">running · 4m</span></li>
<li role="option" aria-selected="false"><svg class="i" viewBox="0 0 24 24" aria-hidden="true"><path d="M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z"/></svg><span>Rename the billing columns in the warehouse schema and backfill the history</span><span class="ph">2h</span></li>
<li role="option" aria-selected="false" aria-disabled="true"><svg class="i" viewBox="0 0 24 24" aria-hidden="true"><path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/></svg><span>Approve all pending</span><span class="ph">nothing pending</span></li>
</ul>
<div class="pf"><span><kbd>↑</kbd><kbd>↓</kbd> move</span><span><kbd>↵</kbd> run</span><span><kbd>esc</kbd> close</span></div>
</div>.pbox.dense is the palette for a workbench: a 40px field at 13px and 28px options at 12px. An option can carry an icon, the label (it truncates), a hint and a shortcut. A command that cannot run now stays in the list, dimmed, with aria-disabled and a hint that says why.
Accessibility
- The input keeps focus;
aria-activedescendantpoints at the active option. - Match on prefix, then substring, then subsequence, so "ckh" finds ClickHouse.