Search Panel
A slide-in search overlay. Open it, type a query, and pick a result. It is form-associated — the live query is mirrored into the owning form — and also dispatches bubbling search and result-select events. Esc or the backdrop closes it.
Preview
Set el.results in a script, then open with el.open = true.
<button id="open-right">Open search</button>
<esa-search-panel id="sp-right" position="right"></esa-search-panel> Positions
The panel slides in from the right (default) or the left.
<esa-search-panel position="right"></esa-search-panel>
<esa-search-panel position="left"></esa-search-panel> States
Set loading to show a searching message while results are fetched.
<esa-search-panel position="right" loading></esa-search-panel> API
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | false | Reflected attribute that drives visibility. Toggle by setting the property. |
placeholder | string | 'Search...' | Input placeholder text. |
results | EsaSearchResult[] | [] | Results to render, set as a property. Each: { id, title, subtitle?, icon?, category? }. Same-category items are grouped. |
loading | boolean | false | Reflected; shows a loading message instead of results. |
position | 'right' | 'left' | 'right' | Side the panel slides in from. |
Events
| Event | Type | Default | Description |
|---|---|---|---|
search | CustomEvent<{ value: string }> | — | Fired on each input change with the current query. |
result-select | CustomEvent<EsaSearchResult> | — | Fired when a result is chosen. |
open-change | CustomEvent<{ open: boolean }> | — | Fired when the panel closes (Esc or backdrop). |
The live query also participates in the enclosing <form> via ElementInternals.
Accessibility
- The panel is
role="search"; the close button carries anaria-label. - The input is focused automatically when the panel opens.
Escapeand backdrop click both close the panel and fireopen-change.
Theming surface
Every public token this component reads, extracted from its source at build time.
The Resolves to column walks each token's real lineage —
component → semantic → primitive → raw value — so you
can see exactly where re-pointing it lands. A spoke re-skins by overriding these in
its theme-<slug>.css; component internals are never edited. No
hook for what you need? File it with /request-lego.
| Token | Tier | Resolves to |
|---|---|---|
--search-panel-bg | component | #fcfcfc via --color-surface-elevated → --color-gray-1 |
--search-panel-result-bg-hover | component | #f0f0f0 via --color-surface-sunken → --color-gray-3 |
--search-panel-width | component | 400px |
--color-backdrop | semantic | rgba(0, 0, 0, 0.5) via --color-black-a-7 |
--color-border-light | semantic | #d9d9d9 via --color-gray-6 |
--color-surface-sunken | semantic | #f0f0f0 via --color-gray-3 |
--color-text-muted | semantic | #838383 via --color-gray-10 |
--color-text-primary | semantic | #202020 via --color-gray-12 |
--color-text-secondary | semantic | #646464 via --color-gray-11 |
--letter-spacing-wide | semantic | 0.03em |
--font-weight-medium | primitive | 500 |
--font-weight-semibold | primitive | 550 |
--radius-200 | primitive | 0.5rem |
--shadow-400 | primitive | 0 8px 32px -8px rgba(0, 0, 0, 0.08) |
--spacing-100 | primitive | 0.25rem |
--spacing-200 | primitive | 0.5rem |
--spacing-300 | primitive | 0.75rem |
--spacing-400 | primitive | 1rem |
--spacing-500 | primitive | 1.5rem |
--spacing-700 | primitive | 3rem |
--z-modal | primitive | 400 |
--z-modal-backdrop | primitive | 300 |