Omnibar
@xui/omnibarReplaces the "no results" row of a xui-omnibar.
Install
pnpm add @xui/omnibar Add the barrel to a standalone component's imports:
import { XuiOmnibarImports } from '@xui/omnibar';@Component({ imports: [XuiOmnibarImports], // …})Examples
Default
Source only — this one needs a component of its own to run, so there is nothing to render here.
<button class="bg-primary text-primary-foreground rounded-lg px-3 py-1.5 text-sm" (click)="open.set(true)"> Open command palette</button><p class="text-foreground-muted mt-3 text-sm">Press ⌘K / Ctrl+K too. Last command: {{ last() ?? '—' }}</p><xui-omnibar [items]="commands" [(open)]="open" (itemSelected)="last.set($event)" />Grouped and faceted
Source only — this one needs a component of its own to run, so there is nothing to render here.
<button class="bg-primary text-primary-foreground rounded-lg px-3 py-1.5 text-sm" (click)="open.set(true)"> Open command palette</button><xui-omnibar [items]="commands" [(open)]="open" [itemGroup]="group" [tags]="tags" [itemTags]="itemTags" [recentItems]="recent()" (itemSelected)="run($event)"/>Async and virtualised
Source only — this one needs a component of its own to run, so there is nothing to render here.
<button class="bg-primary text-primary-foreground rounded-lg px-3 py-1.5 text-sm" (click)="open.set(true)"> Search the index</button><p class="text-foreground-muted mt-3 text-sm">{{ index.length }} entries, fetched a page at a time.</p><xui-omnibar [(open)]="open" [itemsProvider]="search" placeholder="Search 5 000 symbols…" />API
Replaces the "no results" row of a xui-omnibar.
A ⌘K-style command palette: a top-centred overlay with a search field and a keyboard-navigable result list. Toggle with [(open)], or let it bind its own hotkey; Escape or a backdrop click closes. Items render with a custom [xuiSelectOption] template.
Inputs
classClassValueExtra classes, merged into the component's own rather than replacing them.''aria-labelstringAccessible name for the palette dialog, and for its result list.'Command palette'itemsreadonly T[]The commands to search over. Ignored while an itemsProvider is set.[]itemsProviderXuiOmnibarProvider<T> | nullFetch the results rather than filtering items locally. The query is debounced by debounce, only the newest response is kept, and whatever comes back is shown as it arrived — a provider has already decided what matches, so nothing filters it a second time. The filter chips still apply, since they narrow whatever the palette is currently holding.nulldebouncenumberHow long typing has to settle before itemsProvider runs, in milliseconds.150recentItemsreadonly T[]Shown while the query is empty — whatever somebody reached for last time. The palette remembers nothing itself: what counts as recent is the application's call, made from the itemSelected it already receives.[]recentLabelstringHeading over the recent items.'Recent'itemGroup((item: T) => string) | nullWhich group an item belongs under. Results are bucketed in first-seen order and the arrow keys walk them in exactly that order, so the keyboard and the screen never disagree about what comes next.nulltagsreadonly XuiOmnibarTag[]The filter chips shown above the results.[]selectedTagsreadonly string[]Which chips are on. Two-way bindable with [(selectedTags)].[]itemTags((item: T) => readonly string[]) | nullAn item's tag ids. With chips on, an item survives if it carries any of them.nullitemText(item: T) => stringHow an item is labelled. Also what the default filter matches against, so give it the text the user would type.(item: T) => (item == null ? '' : String(item))itemPredicate(query: string, item: T) => booleanCustom filter for one item against the query. Defaults to a case-insensitive substring match on itemText.itemDisabled(item: T) => booleanWhich items cannot be chosen. They stay in the list, greyed out.() => falseitemRanges((item: T, query: string) => readonly XMatchRange[]) | nullWhere an item matched, for the marks in its label. Defaults to matching the query's words against itemText — override it when the ranking came from a search index that already knows where the hits were.nullhighlightMatchesbooleanMark the matched runs of a label. Ignored when a [xuiSelectOption] template owns the row.truevirtualScrollThresholdnumberRow count past which the list virtualises. Above it every row is a fixed itemSize tall, which is the price of not rendering ten thousand of them.200itemSizenumberRow height used while virtualising, in pixels.44hotkeystring | readonly string[] | nullCombo — or combos — that open the palette from anywhere: mod+k, /, ['mod+k', '/']. null leaves the shortcut to the application. A combo with no modifier is ignored while a text field has focus, so / still types a slash where a slash is what was meant.'mod+k'placeholderstringText shown in the empty query field.'Type a command or search…'noResultsTextstringShown in place of the list when the query matches nothing. Replaced by a [xuiOmnibarEmpty] template.'No results.'loadingTextstringAccessible label for the loading spinner.'Searching'resetOnClosebooleanClear the query when the palette closes, so it opens fresh next time.trueopenbooleanWhether the palette is showing. Two-way bindable with [(open)].falseOutputs
itemSelectedTEmits the chosen command. Where the action goes — the palette only closes.