Autocomplete
A free-text input that filters a list of suggestions. The committed value is the text you type; selecting a suggestion fills it in.
Value:
<NaviusAutocomplete Items="_frameworks" @bind-Value="_value" TItem="string">
<ItemTemplate Context="framework">
<NaviusAutocompleteItem class="... data-[highlighted]:bg-accent data-[selected]:font-medium">
@framework
</NaviusAutocompleteItem>
</ItemTemplate>
<ChildContent>
<NaviusAutocompleteInput Placeholder="Search framework…" class="..." />
<NaviusAutocompletePortal>
<NaviusAutocompletePositioner Side="bottom" Align="start" SideOffset="4">
<NaviusAutocompletePopup class="... bg-popover shadow-md
data-[open]:animate-in data-[closed]:animate-out">
<NaviusAutocompleteList class="outline-none" />
<NaviusAutocompleteEmpty class="...">No frameworks found.</NaviusAutocompleteEmpty>
</NaviusAutocompletePopup>
</NaviusAutocompletePositioner>
</NaviusAutocompletePortal>
</ChildContent>
</NaviusAutocomplete>
@code {
private string? _value;
private static readonly string[] _frameworks =
{
"Next.js", "SvelteKit", "Nuxt.js", "Remix",
"Astro", "Blazor", "SolidStart", "Qwik City",
};
}Features
- A compound of composable parts (Root, Input, Portal, Positioner, Popup, List, Item, Empty) you assemble and style yourself.
- Live, case-insensitive filtering with a pluggable
Filterand genericItems<T>. - Focus stays in the input; the highlight moves via
aria-activedescendant; arrows never steal focus. - Can be controlled (
@bind-Value,@bind-Open) or uncontrolled (DefaultOpen). - The Popup self-portals to
document.body, stays anchored, and flips when space is tight. - Styles off the discrete contract:
data-open/data-closedon the Popup,data-highlighted/data-selectedon items.
Installation
Install the brain, or copy just this primitive in with the CLI.
navius add autocompleteAnatomy
Import the parts and assemble them. The List renders the filtered Items through your ItemTemplate.
@using Navius.Primitives.Components.Autocomplete
<NaviusAutocomplete Items="_options" @bind-Value="_value" TItem="string">
<ItemTemplate Context="item">
<NaviusAutocompleteItem>@item</NaviusAutocompleteItem>
</ItemTemplate>
<ChildContent>
<NaviusAutocompleteInput />
<NaviusAutocompletePortal>
<NaviusAutocompletePositioner>
<NaviusAutocompletePopup>
<NaviusAutocompleteList />
<NaviusAutocompleteEmpty />
</NaviusAutocompletePopup>
</NaviusAutocompletePositioner>
</NaviusAutocompletePortal>
</ChildContent>
</NaviusAutocomplete>API Reference
Root
Owns the filtered collection, the open state and the committed value. Cascades the Autocomplete context. Renders no DOM of its own.
| Prop | Type | Default |
|---|---|---|
| Items | IReadOnlyList<TItem> | [] |
| Value | string? | - |
| ValueChanged | EventCallback<string?> | - |
| Open | bool | false |
| OpenChanged | EventCallback<bool> | - |
| DefaultOpen | bool | false |
| ItemToString | Func<TItem, string>? | - |
| Filter | Func<TItem, string, bool>? | - |
| ItemTemplate | RenderFragment<TItem>? | - |
| Dir | string? | - |
| ChildContent | RenderFragment? | - |
Input
The editable text field (role=combobox). Typing filters the list and updates the value. Renders an input.
| Prop | Type | Default |
|---|---|---|
| Placeholder | string? | - |
| Attributes | IDictionary<string, object>? | - |
Positioner
Owns placement (side / align / offsets / collision). A flag-setter; the Popup renders the positioning element the engine anchors and writes data-side / data-align + --anchor-* onto.
| Prop | Type | Default |
|---|---|---|
| Side | string | "bottom" |
| Align | string | "start" |
| SideOffset | double | 0 |
| AlignOffset | double | 0 |
| Flip | bool | true |
| AvoidCollisions | bool | true |
| ChildContent | RenderFragment? | - |
Popup
The floating listbox surface, self-portaled and anchored to the input. role=listbox.
| Prop | Type | Default |
|---|---|---|
| ChildContent | RenderFragment? | - |
| Attributes | IDictionary<string, object>? | - |
Data attributes
| Data attribute | Values |
|---|---|
| [data-open] | Present while the popup is open. |
| [data-closed] | Present while the popup is closed (during the exit transition). |
| [data-starting-style] | Present on the first committed open frame. |
| [data-ending-style] | Present while the popup is animating out. |
| [data-side] | "top" | "right" | "bottom" | "left" |
| [data-align] | "start" | "center" | "end" |
List
Renders one Item per filtered entry using the Root's ItemTemplate. Renders a div.
| Prop | Type | Default |
|---|---|---|
| Attributes | IDictionary<string, object>? | - |
Item
A single suggestion. Highlighted by keyboard/pointer; selecting it commits its value. Renders a div with role=option.
| Prop | Type | Default |
|---|---|---|
| ChildContent | RenderFragment? | - |
| Attributes | IDictionary<string, object>? | - |
Data attributes
| Data attribute | Values |
|---|---|
| [data-highlighted] | Present when the item is the active (aria-activedescendant) option. |
| [data-selected] | Present when the item matches the committed value. |
| [data-disabled] | Present when disabled. |
Empty
Shown inside the Popup when the filter matches nothing. Renders a div.
| Prop | Type | Default |
|---|---|---|
| ChildContent | RenderFragment? | - |
Accessibility
Adheres to the combobox WAI-ARIA design pattern (editable, list-autocomplete). The highlighted option is tracked with aria-activedescendant so DOM focus never leaves the input.
Keyboard interactions
| Key | Description |
|---|---|
| ArrowDown | Opens the list if closed; otherwise moves the highlight to the next option. |
| ArrowUp | Moves the highlight to the previous option. |
| Enter | Selects the highlighted option and closes the list. |
| Escape | Closes the list, keeping focus in the input. |
| Tab | Closes the list and moves focus to the next element. |