Search

import "@taprootio/espalier/search";

<esp-search>

Modal search overlay with a Cmd+K / Ctrl+K interaction pattern.

<esp-search> is a pure UI shell with no search-engine dependency. Consumers wire it to any search backend (Pagefind, MiniSearch, API, etc.) by listening for esp-search-requested events and calling setResults() with the matches.

Examples

Basic search (consumer wiring not shown)

Properties

EspalierSearch has the following properties:

placeholder

placeholder has a type of string.

Placeholder text for the search input.

isOpen

Type: boolean

results

Type: SearchResult[]

loading

Type: boolean

query

Type: string

activeIndex

Type: number

vellumRef

inputRef

resultsRef

idPrefix

Per-instance ID prefix for ARIA id attributes (listbox + options).

_overlay

hasListbox

hasListbox has a type of boolean.

Whether the listbox is currently rendered in the DOM.

listboxId

Type: string

seedColorBacker

Type: string

espRoot

Type: EspalierRoot | null

contextBacker

Type: string

scopedTokenOriginalValues

warnedUnknownContexts

pendingInitialThemeRoot

Type: EspalierRoot | null

rootEventSubscriptionsActive

Type: boolean

subscribedRoot

Type: EspalierRoot | null

rootEventUnsubscribers

Type: Array<() => void>

intentBacker

Type: EspalierIntentVariant

intentEmitsTokens

intentEmitsTokens has a type of boolean.

Whether a non-neutral intent emits its inline tokens (--esp-color-primary and the filled-action pair). Interactive controls need them; chrome whose intent treatment is class-based (badges, callouts, status pills — see intentSurfaceTokens) opts out so a decorative intent never rewrites inherited tokens for slotted content.

warnedUnknownIntents

seedColor

Type: string

correlationId

scheme

scheme has a type of "dark" | "light".

The scheme to use for the component. This property is used internally to control the light/dark scheme so it matches the scheme of esp-root. It should not be set manually, it exists as an attribute for styling purposes.

intent

intent has a type of EspalierIntentVariant.

The element's intent — its meaning: neutral (no pin), or success, warning, danger, info — each pinned to its fixed status family (blue for info), retunable per theme via intents. On token-emitting controls a non-neutral intent pins the filled-action pair to that family, derived over the governing zone's theme; class-styled chrome (badges, callouts, status pills) opts out of inline emission and renders its treatment from CSS classes instead. An intent never repaints the surrounding zone, which is what contexts are for. Removing the attribute restores the element's own default intent.

context

context has a type of string.

A theme-defined color zone. The selected context rebinds designer-facing roles and emits a complete, contrast-enforced semantic token table on this host for descendants to inherit.

handleSeedColorChanged

handleSchemeChanged

handleThemeChanged

handleIconSpriteUrlChanged

intentColorSources

intentColorSources has a type of `Readonly< Record<EspalierIntentVariant, ColorSource | "">

`.

Intent color sources: the meaning-bearing families an intent pins the filled-action pair to. neutral pins nothing; each other intent maps to its own fixed status family (ESP0172 gave info a real blue family, replacing the complementary borrow the retired variant system used), and a theme's intents field retunes the family colors themselves.

semanticActionTokens

semanticActionTokens has a type of ReadonlySet<SemanticColorName>.

Semantic tokens that paint a control's filled action surface — the pair an intent recolors. Everything else inherits the zone cascade, which is the ESP0166 fix: under the SHY fitted theme the retired variant re-seeding painted a danger callout's background mint green; an intent leaves the zone's surfaces alone and pins only the action pair (plus --esp-color-primary for state derivations) to the intent's own status family — fixed hues by default, retunable per theme via intents. Task 098's guarantee survives structurally: the pin is by source, so no theme mapping can rotate a destructive / warning / positive action off its semantic hue.

Events

<esp-search> emits the following events:

esp-search-requested

esp-search-requested is of type CustomEvent<{ query: string }>.

The user changed the query input. Fires on every keystroke (not debounced) so consumers can track the latest query and discard stale async results. Consumers that need debouncing should apply it themselves (e.g. Pagefind's debouncedSearch()). detail: { query: string }

esp-search-result-selected

esp-search-result-selected is of type CustomEvent<{ url: string }>.

The user chose a result. detail: { url: string }

esp-search-closed

esp-search-closed is of type CustomEvent<{}>.

The overlay was closed (Escape, backdrop click, or result selection). Consumers should use this to cancel in-flight searches or discard pending results. detail: {}

CSS Properties

<esp-search> has the following CSS properties:

--esp-search-max-width

Maximum width of the search panel. Defaults to 40rem.

--esp-search-max-height

Maximum height of the results list. Defaults to 60vh.

--esp-search-backdrop

Backdrop color behind the panel. Defaults to oklch(0.15 0 0 / 0.6).

--esp-search-panel-background

Background color of the search panel. Defaults to var(--esp-color-layer-1).

--esp-search-panel-shadow

Box shadow of the search panel.

--esp-search-border-color

Divider and loading-track color used by the search panel. Defaults to var(--esp-color-border).

--esp-search-text-color

Main text color used by the search UI. Defaults to var(--esp-color-text).

--esp-search-muted-color

Muted text color for placeholders, excerpts, and empty states.

--esp-search-title-color

Title color for result rows. Defaults to var(--esp-color-headings).

--esp-search-active-background

Background color of the active result row. Defaults to var(--esp-color-layer-2).

--esp-search-highlight-background

Background color applied to <mark> highlights inside excerpts.

--esp-search-loading-indicator-color

Accent color of the loading spinner. Defaults to var(--esp-color-primary).

--esp-search-loading-indicator-track-color

Track color of the loading spinner. Defaults to var(--esp-search-border-color).

--esp-field-background

Background color of the shared field shell. Defaults to var(--esp-color-layer-2).

--esp-field-border-color

Border color of the shared field shell. Defaults to var(--esp-color-border).

--esp-field-border-width

Border width of the shared field shell. Defaults to 1px.

--esp-field-text-color

Text color used inside the shared field shell. Defaults to var(--esp-color-text).

--esp-field-hover-bg

Hover background color of the shared field shell. Derived from --esp-field-background.

--esp-field-focus-bg

Focus background color of the shared field shell. Derived from --esp-field-background.

--esp-field-focus-shadow

Shadow color used for shared field focus treatment. Defaults to var(--esp-color-shadow).

Components API Guides Getting started Styling Espalier Browser support GitHub npm package Taproot I/O