Overlays

Omnibar

@xui/omnibar

Replaces 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

XuiOmnibarEmpty

directiveng-template[xuiOmnibarEmpty]

Replaces the "no results" row of a xui-omnibar.

XuiOmnibar

componentxui-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

NameTypeDefaultclassClassValueExtra 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.[]selectedTagstwo-wayreadonly 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.trueopentwo-waybooleanWhether the palette is showing. Two-way bindable with [(open)].false

Outputs

NameTypeitemSelectedTEmits the chosen command. Where the action goes — the palette only closes.

Source

libs/ui/omnibar/xui

xUI 3.0.0 — Apache 2.0 licensed. Built with Angular and Tailwind CSS.