Field Search

Control K
Recent searches
  • Nils Frahm
  • Royal Albert Hall
  • Says
About this component

Field Search

A search field that does the whole job: `onSearch` fires once typing pauses (and at once on Enter), a shortcut shown as key caps focuses it from anywhere on the page (Command K on a Mac, Control K elsewhere), a spinner takes the search icon's place while results load, and a clear button appears once there is a query. With a `storageKey` it remembers recent searches and offers them in a list while the field is empty, each one removable, with a Clear all; the list is a proper combobox with arrow keys, Enter and Delete. Escape closes the list, then clears the query, then lets go of the field. Built on the shadcn Input.

Usage

The import and the props worth knowing about, in one place.

import { FieldSearch } from "@/components/beste/component/field-search";

const [loading, setLoading] = useState(false);

<FieldSearch
  placeholder="Search songs and venues"
  storageKey="recent-searches"     // remembers searches on this device
  debounce={300}                   // ms of quiet before onSearch
  loading={loading}
  onSearch={async (query) => {
    setLoading(true);
    console.log("Search", query);
    setLoading(false);
  }}
/>

// No shortcut, no memory, just a field
<FieldSearch shortcut={false} tone="muted" size="sm" onSearch={(query) => console.log(query)} />

Keyboard and gestures

Every one of these is in the component already. They are listed because a props table cannot mention a gesture, so nothing else on this page can tell you they exist.

Command K / Control KFocus the field from anywhere on the page.
EnterSearch at once and remember the query, or pick the highlighted recent search.
Arrow down / Arrow upMove through the recent searches while the field is empty.
DeleteRemove the highlighted recent search.
EscapeClose the list, then clear the query, then leave the field.

Props

Read from the component's own type, so this cannot drift from what it accepts.

PropTypeDefaultDescription
valuestring—The query, controlled.
defaultValuestring""
onValueChange(value: string) => void—Every keystroke.
onSearch(query: string) => void—The query once typing pauses for `debounce` ms, and at once on Enter or a picked recent search.
debouncenumber—Milliseconds of quiet before `onSearch`. @defaultValue 250
loadingboolean—Shows a spinner in place of the search icon.
shortcutstring | false—Focuses the field from anywhere on the page; `false` turns it off. @defaultValue "mod+k"
storageKeystring—Remembers searches under this localStorage key and offers them while the field is empty.
defaultRecentstring[]—Recent searches used until the reader has any of their own.
maxRecentnumber5
placeholderstring"Search"
aria-labelstring"Search"
labelsPartial<typeof DEFAULT_LABELS>—Words used by the component, for translation.
namestring—
disabledboolean—
tone"muted" | "outline" | "ghost""outline"
size"sm" | "default" | "lg""default"
classNamestring—

More Field components

View all Field

Use at least 12 characters. A short sentence works well.

Strength
  • At least 12 characters, not met yet
  • A lowercase letter, not met yet
  • An uppercase letter, not met yet
  • A number, not met yet
  • A symbol, not met yet

We sent a code to hello@beste.co. Try 246810.