Skip to content

TkxCommandPalette

TkxCommandPalette is a keyboard-first command launcher in the Linear / Raycast / GitHub style. It opens on a hotkey (Cmd-K / Ctrl-K by default), fuzzy-matches as you type, groups commands into sections, floats your recent picks to the top, and renders into a portal so it is never trapped by a clipped ancestor. It is headless about side effects: your parent owns the command list and the onSelect behaviour.

import { TkxCommandPalette } from 'tekivex-ui';
<TkxCommandPalette
commands={[
{ id: 'settings', title: 'Open settings', section: 'App',
shortcut: ['Cmd', ','], onSelect: () => openSettings() },
{ id: 'docs', title: 'Search docs', subtitle: 'Find anything',
section: 'Help', onSelect: () => openDocs() },
]}
/>
PropTypeDefaultDescription
commandsCommandPaletteCommand[]The full command list (required).
hotkeyCommandHotkey | null{ ctrl: true, key: 'k' }Key to toggle open. null disables the hotkey.
openbooleanControlled open state. Omit for uncontrolled.
onOpenChange(open: boolean) => voidFires on open/close (controlled and uncontrolled).
placeholderstring'Type a command…'Search input placeholder.
onSelect(cmd) => voidGlobal selection callback (in addition to a command’s own onSelect).
recentsbooleantrueShow a “Recents” group at the top when the query is empty.
maxRecentsnumber5Max recent commands retained.
emptyStateReactNodeNo matches for "…"Node shown when nothing matches.
classNamestringClass on the overlay.
KeyTypeDescription
idstringStable identifier; also the recents key.
titlestringPrimary label.
subtitlestring?One-line description under the title (also fuzzy-matched).
sectionstring?Group header. Defaults to 'Commands'.
iconReactNode?Emoji or short text icon.
shortcutstring[]?Right-aligned keyboard hint, rendered as kbd pills.
dataunknown?Free-form payload returned to your callback.
hiddenboolean?Hide this command without removing it from the list.
onSelect(cmd) => void?Per-command override of the global onSelect.
  • Hotkey is platform-aware: with ctrl: true, it matches metaKey on Mac (Cmd) and ctrlKey elsewhere. shift/alt must match exactly (both default to false).
  • Keyboard model: type to search, ↑/↓ to move, Enter to run, Esc to close, Home/End jump to the first/last result. Hovering or moving the mouse over a row also makes it active.
  • Fuzzy scoring requires a case-insensitive subsequence match; prefix hits, word-boundary hits, and contiguous runs score higher, and long titles are slightly penalised so short exact matches win. The fuzzyScore(query, text) helper is exported if you want to reuse the same ranking. A subtitle match scores 4 points lower than the same match on the title.
  • Running a command bumps it to the front of recents (capped at maxRecents) and closes the palette. Recents are component-local state — they are not persisted across reloads.
  • Filter commands with hidden: true rather than recreating the list, so recents and identities stay stable.
  • Renders via createPortal into document.body; returns null when closed or during SSR (no document). Uses role="dialog" / aria-modal with an ARIA combobox + listbox and aria-activedescendant for the active option.

src/components/TkxCommandPalette.tsx