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).