SearchCtrlK

  • ↑↓navigate
  • ↵open
  • escclose

Can’t find it? Contact us

CommandPalette

The app's ⌘K command palette.

Monitors
Account
View code
tsx
<CommandPalette.Trigger for="ops-palette" shortcut="mod+shift+k">Search or jump to…</CommandPalette.Trigger>

<form id="pause-all" method="post" action="/monitors/pause-all" hidden></form>

<CommandPalette
	id="ops-palette"
	shortcut="mod+shift+k"
	recent={["go-incidents", "create-monitor"]}
	remember="pulse:palette"
	labels={{
		title: "Command menu",
		open: "Open command menu",
		placeholder: "Search monitors or run a command…",
		recent: "Recent",
		noResults: "No commands match",
		noResultsHint: "Try a monitor name, or “create”.",
		results: "{count} results",
		back: "Back",
		close: "Close",
	}}
>
	<CommandPalette.Group heading="Navigation">
		<CommandPalette.Item id="go-monitors" title="Go to Monitors" icon={<ActivityIcon size={16} />} href="/monitors" shortcut="g m" />
		<CommandPalette.Item id="go-incidents" title="Go to Incidents" icon={<SirenIcon size={16} />} href="/incidents" shortcut="g i" />
	</CommandPalette.Group>
	<CommandPalette.Group heading="Monitors">
		<CommandPalette.Item id="create-monitor" title="Create Monitor" keywords={["new", "check", "add"]} icon={<PlusIcon size={16} />} href="/monitors/new" shortcut="c" />
		<CommandPalette.Item id="pause-all" title="Pause All Monitors" description="Stops every check until resumed" icon={<CirclePauseIcon size={16} />} form="pause-all" />
	</CommandPalette.Group>
	<CommandPalette.Group heading="Account">
		<CommandPalette.Item id="copy-account-id" title="Copy Account ID" keywords={["clipboard"]} icon={<CopyIcon size={16} />} command="--copy-account-id" commandfor="account" />
		<CommandPalette.Item id="switch-team" title="Switch Team…" icon={<UsersIcon size={16} />} page="teams" />
	</CommandPalette.Group>
	<CommandPalette.Page id="teams" title="Switch Team" placeholder="Search teams…">
		<CommandPalette.Item id="team-acme" title="Acme Ops" href="/teams/acme" />
		<CommandPalette.Item id="team-globex" title="Globex Infrastructure" href="/teams/globex" />
		<CommandPalette.Item id="team-paris" title="Équipe Paris" href="/teams/paris" />
	</CommandPalette.Page>
</CommandPalette>

Demo apps

Whole pages built only from @sdxc/ui, each for an invented product with its own palette and type. They open in a new tab.

Every demo, landings and docs sites alike, is listed in the demo gallery.

Installation

An ordinary dependency: install it, import the theme once, and import the component where it is used.

Terminal
npm add @sdxc/ui remix
typescript
import "@sdxc/ui/theme.css";

Usage

typescript
import { CommandPalette } from "@sdxc/ui/app";

Renders the palette: a modal dialog 640px wide, 15% from the top, full width less a gutter on a phone. Without JavaScript a trigger still opens it and every command stays a working link or button; the island adds filtering, arrow keys, pages and the ⌘K binding.

Composition

The parts the component publishes, each a static property of the host.

  • CommandPalette
  • CommandPalette.GroupRenders a titled group of commands, hidden by the island while none of its commands match.
  • CommandPalette.ItemRenders one 36px command row whose control is a link, a form submitter, an Invoker Command button, or a button opening a page.
  • CommandPalette.PageRenders a nested page of commands, shown in place of the root list when an item opens it.
  • CommandPalette.TriggerRenders the button that opens the palette, styled as a quiet search field with the key that opens it: one route for the pointer, and the place a reader learns the key.

Props

Read from the component's own types, so every prop, every default and every allowed value is listed.

PropTypeRequiredDescription
idstringYesThe dialog's id, which a trigger's commandfor names.
labelsLabelsYes
shortcutstringNoThe combo that toggles the palette from anywhere on the page. @default "mod+k"
recentstring[]NoIds of commands to offer under Recent before anything is typed, most recent first.
rememberstringNoA localStorage key under which the palette remembers the commands run from it.
childrenRemixNodeYesCommandPalette.Groups, loose CommandPalette.Items and CommandPalette.Pages.

Also accepts everything in Omit<TagProps<"dialog">, "children">.

CommandPalette.Group

PropTypeRequiredDescription
headingstringYesTitle Case heading, e.g. "Navigation".
childrenRemixNodeYes

Also accepts everything in TagProps<"div">.

CommandPalette.Item

PropTypeRequiredDescription
idstringYesA document-unique id, which recent and the remembered list name.
titlestringYesTitle Case verb and noun, e.g. "Create Monitor".
keywordsstring[]NoOther words that find it, e.g. aliases and the old name.
descriptionstringNoA short muted line after the title.
shortcutstringNoA combo or sequence the item shows as a hint and binds on the page, e.g. "g m".
iconRemixNodeNo
hrefstringNoMakes the item a link.
formstringNoThe id of a form the item submits.
formactionstringNo
formmethod"get" | "post"No
namestringNoThe submitted button's name and value.
valuestringNo
commandstringNoAn Invoker Command the item sends, e.g. "--copy-account-id", to ItemProps.commandfor.
commandforstringNo
pagestringNoThe CommandPalette.Page the item opens.
mixTagProps<"div">["mix"]No

CommandPalette.Page

PropTypeRequiredDescription
idstringYesThe id items open it by.
titlestringYesShown beside the search field while the page is open.
placeholderstringNoReplaces the root placeholder while the page is open.
childrenRemixNodeYes

CommandPalette.Trigger

PropTypeRequiredDescription
forstringYesThe palette's id.
shortcutstringNoThe combo the trigger advertises. @default "mod+k"
childrenRemixNodeYes

Also accepts everything in Omit<Button.Props, "commandfor" | "command">.

@sdxc/ui

Can’t find it? Contact us