Noctis

SearchDialog

A centred, focus-trapped command palette: a trigger opens a query field over a keyboard-navigated list of hits, with a footer of key hints. The caller runs the search and feeds the results, so the dialog stays index-agnostic.

Basic

A trigger — commonly a Button — opens SearchDialog.Root, which owns the open state, the controlled query, and the keyboard-driven active row. Compose a SearchDialog.Input for the query, a SearchDialog.Results listing one SearchDialog.Item per hit, and a SearchDialog.Footer of SearchDialog.Hints. The root reports onSelect when a row is clicked or opened with Enter; here it just closes the dialog.

Empty state

The result region shows one of several panes, gated on the dialog state in a fixed priority. SearchDialog.Empty supplies the copy for three of them: the empty-query prompt (children, before anything is typed), the in-flight searching line, and the noResults line — which receives the trimmed query so it can quote the term back. Feed an empty results array with a settled query to land on the no-results pane.

Anatomy

Compose the dialog from its parts. SearchDialog.Root owns the open state, the controlled query, the settled results, and the keyboard-driven active row, and shares them with every part through context — so a part rendered outside the root throws a named error.

  • SearchDialog.Root — the chassis and the keyboard contract, built on Base UI's Dialog (focus trap, dismissal) inside a portal. Props: open / onOpenChange, the controlled query / onQueryChange, results, onSelect, the loading and searching flags, and an accessible title (default Search).
  • SearchDialog.Input — the query field, with a leading search glyph, an in-flight spinner, and a decorative Esc close chip. It auto-focuses when the dialog opens and forwards arrow / Enter keys to the root.
  • SearchDialog.Results — the role="listbox" container; renders nothing unless there are results to show.
  • SearchDialog.Item — one role="option" row: its title opposite a crumb (or method + path), over an optional <mark>-highlighted excerpt. Pass the hit as result and its zero-based index; pointer hover makes it active, click chooses it.
  • SearchDialog.Loading — the index-loading copy, shown before any query can run; renders nothing once the index is ready.
  • SearchDialog.Empty — the empty-query, searching, and noResults copy; the root gates which one shows, so it renders nothing while results are present.
  • SearchDialog.Footer + SearchDialog.Hint — the key-hints row and one hint each, a keys cluster (compose Kbds) beside its label.

All copy arrives as part children, so a consuming app routes it through its own i18n. Every rendered part carries a data-slot (noctis-search-dialog, noctis-search-dialog-header, noctis-search-dialog-input, noctis-search-dialog-results, noctis-search-dialog-result, noctis-search-dialog-footer) for host-side styling — the row's resting highlight keys off the aria-selected axis, and its scroll-into-view off data-index. Per-part prop types are exposed through the matching namespace — e.g. SearchDialog.Item.Props.

Keyboard

KeyAction
/ Move the active row down / up. The active row stays scrolled into view.
EnterOpen the active row — calls onSelect with its result and index.
EscClose the dialog and return focus to the trigger.

The field auto-focuses on open, so typing filters immediately without a tab in. Arrow and Enter handling lives on the input; Esc is Base UI's Dialog dismissal. A fresh result set always re-highlights the top row.

Design tokens

Generated from the component's declaration — the same graph that mints the CSS, so a variable name or its resolution default can't drift. The minted tokens are the public override seam: set one on any ancestor and every search dialog in that region retunes — e.g. .brand { --noctis-search-dialog-result-background-color-highlighted: var(--noctis-color-accent-muted); } recolors the active row. Knobs that aren't minted are reached through the part's data-slot. See Customization for the full override ladder and Tokens for the whole graph.

Token

API reference

Generated from the component's types — every prop, type, default, and description comes straight from the source. Each part gets its own table; parts that only forward to Base UI list just the props they pass through.

SearchDialog.Root

Prop

SearchDialog.Input

Prop

SearchDialog.Results

Prop

SearchDialog.Item

Prop

SearchDialog.Empty

Prop

SearchDialog.Loading

Prop

SearchDialog.Footer

Prop

SearchDialog.Hint

Prop

AttributeDescription
data-slotThe slot marker on every rendered part.
data-elevation`menu` — the elevated surface scope on the portalled popup.
data-indexThe zero-based position of a result row in the list.