Command
A search box with a filtered list of actions.
import { … } from '@inlaylab/ivorie/command'import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IV_COMMAND_IMPORTS } from '@inlaylab/ivorie/command';
@Component({
selector: 'demo-command',
imports: [IV_COMMAND_IMPORTS],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<iv-command class="max-w-sm rounded-lg border shadow-md">
<iv-command-input placeholder="Type a command or search..." />
<iv-command-list>
<iv-command-empty>No results found.</iv-command-empty>
<iv-command-group heading="Suggestions">
<iv-command-item>Calendar</iv-command-item>
<iv-command-item>Search Emoji</iv-command-item>
<iv-command-item [disabled]="true">Calculator</iv-command-item>
</iv-command-group>
<iv-command-separator />
<iv-command-group heading="Settings">
<iv-command-item>Profile<iv-command-shortcut>⌘P</iv-command-shortcut></iv-command-item>
<iv-command-item>Billing<iv-command-shortcut>⌘B</iv-command-shortcut></iv-command-item>
<iv-command-item>Settings<iv-command-shortcut>⌘S</iv-command-shortcut></iv-command-item>
</iv-command-group>
</iv-command-list>
</iv-command>
`,
})
export default class CommandDemo {}
Installation
npx ivorie add commandimport { … } from '@inlaylab/ivorie/command'Type to filter. Arrow keys move the highlight, Enter picks. Like shadcn's Command (cmdk).
Usage
import { IV_COMMAND_IMPORTS } from '@inlaylab/ivorie/command';<iv-command>
<iv-command-input placeholder="Search..." />
<iv-command-list>
<iv-command-empty>No results.</iv-command-empty>
<iv-command-group heading="Suggestions">
<iv-command-item (select)="run($event)">Calendar</iv-command-item>
</iv-command-group>
</iv-command-list>
</iv-command>Examples
In a dialog
Put the command in a Dialog template for a command palette.
Last pick: none
import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
import { IvButton } from '@inlaylab/ivorie/button';
import { IV_COMMAND_IMPORTS } from '@inlaylab/ivorie/command';
import { IV_DIALOG_IMPORTS } from '@inlaylab/ivorie/dialog';
@Component({
selector: 'demo-command-dialog',
imports: [IV_COMMAND_IMPORTS, IV_DIALOG_IMPORTS, IvButton],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<div class="flex flex-col items-center gap-2">
<button ivButton variant="outline" [ivDialogTrigger]="palette" [ivDialogConfig]="{ ariaLabel: 'Command palette', showCloseButton: false }">
Open command palette
</button>
<p class="text-muted-foreground text-sm">Last pick: {{ picked() || 'none' }}</p>
</div>
<ng-template #palette let-ref>
<iv-command>
<iv-command-input placeholder="Search actions..." />
<iv-command-list>
<iv-command-empty>No results found.</iv-command-empty>
@for (action of actions; track action) {
<iv-command-item (select)="picked.set($event); ref.close($event)">{{ action }}</iv-command-item>
}
</iv-command-list>
</iv-command>
</ng-template>
`,
})
export default class CommandDialogDemo {
readonly actions = ['New file', 'Open recent', 'Toggle sidebar', 'Sign out'];
readonly picked = signal('');
}
API
Every part also accepts class.
iv-command
| Name | Type | Default | Description |
|---|---|---|---|
search |
string (two-way) |
'' |
The search text. |
shouldFilter |
boolean |
true |
false shows every item, e.g. when you filter on the server. |
iv-command-input
| Name | Type | Default | Description |
|---|---|---|---|
placeholder |
string | null |
null |
Placeholder text. |
aria-label |
string | null |
'Search' |
Label for the input. |
disabled |
boolean |
false |
Disables the input. |
iv-command-item
| Name | Type | Default | Description |
|---|---|---|---|
value |
string | null |
item text | Text the search matches and select emits. |
keywords |
string[] |
[] |
Extra words the search matches. |
disabled |
boolean |
false |
Skipped by arrows, ignores clicks. |
checked |
boolean |
false |
Shows a check mark. |
Output: select (string): the item's value, on click or Enter.
Other parts
iv-command-list,iv-command-empty(shown when nothing matches),iv-command-group(heading),iv-command-separator,iv-command-shortcut.- A group with no matching item hides.
Accessibility
The input is a combobox that controls the listbox. The highlight uses aria-activedescendant, so focus stays in the input. Disabled items have aria-disabled.