Components/SearchPanel

SearchPanel

An inline search card with a field, live results, and an empty state.

VerifiedSince 0.3.9

Usage

Live Filtering

Loading demo...

Best Practices

  • Use TxCommandPalette for a globally invoked launcher and this panel for search that stays on the page; both share one keyboard contract.
  • As a launcher, run the action in select and clear the query; as a filter, keep the query visible.
  • For remote search, pass :filter="items => items" to disable the built-in match and debounce your own fetch on queryChange.
  • Put synonyms in keywords, and mark unavailable entries disabled instead of removing them from items.
  • Size minHeight for your most common result count; too small brings the jumping back.

API Reference

Props

PropTypeDefaultDescription
modelValuestring''Query text, bound with v-model.
itemsSearchPanelItem[][]Candidate items.
placeholderstring'Search'Field placeholder.
ariaLabelstring-Accessible name of the field; falls back to placeholder.
idleCountnumber5Items shown for an empty query; 0 shows all.
emptyThresholdnumber3Shortest query that may show the empty state.
emptyTitlestring'No results found'Empty-state title.
emptyDescriptionstring'Adjust your search to try again'Empty-state description.
clearLabelstring'Clear search'Accessible name of the clear button.
listLabelstring'Search results'Accessible name of the result list.
minHeightnumber | string248Reserved height, so results don't resize the panel.
filter(items, query) => items-Replaces the built-in match: case-insensitive includes over label and keywords.
clearablebooleantrueShows the clear button.
disabledbooleanfalseDisables the field.

Events

EventPayloadDescription
update:modelValuestringFires when the query changes.
queryChangestringSame value as update:modelValue, for hosts without v-model.
selectSearchPanelItemFires when a result is clicked or chosen with Enter.
clear-Fires when the clear button or Escape empties the field.

Slots

SlotScopeDescription
item{ item, active, query }Replaces a row's content.
empty{ query }Replaces the empty state.
footer-Content below the list, inside the card.

Exposed Methods

NameDescription
focus() / blur()Focuses or blurs the field.
clear()Empties the query and emits clear.

Types

NameDescription
SearchPanelItem{ id, label, keywords?, disabled? }; keywords join the built-in match but aren't displayed.

Overview

  • Renders inline: no overlay, no modal semantics, no focus trap — it fits in a page, sidebar, or popover.
  • ↑ ↓ wrap and skip disabled rows, Home / End jump to the first and last enabled rows, Enter selects, and Escape clears when there is text. Enter is ignored during IME composition.
  • Follows the combobox pattern: the field is role="combobox" with aria-autocomplete="list", aria-controls, and aria-activedescendant; rows are role="option" with tabindex="-1", so focus stays in the field.
  • The highlight is is-active, and pointer movement syncs it to the row under the mouse.
  • Selecting a result doesn't write it back into the field; the host handles select.
  • Below emptyThreshold characters, a query with no matches doesn't show the empty state.

Technologies

  • The empty state reuses TxSearchEmpty, tuned only through its public CSS variables and icon slot.
  • Adapted from Beautiful UI, © 2026 Shane Levine, MIT; keyboard navigation and ARIA are additions.
  • Source: packages/tuffex/packages/components/src/search-panel/.
查看源码
packages/tuffex/packages/components/src/search-panel/index.ts