Combobox
A value-selection input: the text field is a filter over a list, and the committed value is the item you pick, distinct from what you type.
Selected:
<NaviusCombobox Items="_languages" @bind-Value="_value" TItem="string">
<ItemTemplate Context="language">
<NaviusComboboxItem class="... pl-8 data-[highlighted]:bg-accent data-[selected]:font-medium">
<NaviusComboboxItemIndicator class="absolute left-2">✓</NaviusComboboxItemIndicator>
@language
</NaviusComboboxItem>
</ItemTemplate>
<ChildContent>
<NaviusComboboxInput Placeholder="Select a language…" aria-label="Language" class="..." />
<NaviusComboboxPortal>
<NaviusComboboxPositioner Side="bottom" Align="start" SideOffset="4">
<NaviusComboboxPopup class="... bg-popover shadow-md
data-[open]:animate-in data-[closed]:animate-out">
<NaviusComboboxList class="outline-none" />
<NaviusComboboxEmpty class="...">No languages found.</NaviusComboboxEmpty>
</NaviusComboboxPopup>
</NaviusComboboxPositioner>
</NaviusComboboxPortal>
</ChildContent>
</NaviusCombobox>
@code {
private string? _value;
private static readonly string[] _languages =
{
"C#", "TypeScript", "Rust", "Go",
"Python", "Swift", "Kotlin", "Elixir",
};
}Features
- Value selection, not free text: the input filters; selecting an item commits it and shows its label.
- A compound of composable parts: Root, Input, Portal, Positioner, Popup, List, Item, ItemIndicator, Empty.
- Single or multi-select (
Multiple) with Chips, Chip remove, and Clear parts. - Controlled or uncontrolled value (
@bind-Value/@bind-Values) and open state. - The Popup self-portals to
document.body, stays anchored, and flips when space is tight. - Styles off the discrete contract:
data-open/data-closed,data-highlighted,data-selected.
Installation
Reference the Navius.Primitives package for the headless primitive, or vendor a styled version with the CLI: navius add copies the styled zits/ui component plus the brain files it depends on.
navius add comboboxAnatomy
Import the parts and assemble them. The List renders the filtered Items through your ItemTemplate.
@using Navius.Primitives.Components.Combobox
<NaviusCombobox Items="_options" @bind-Value="_value" TItem="string">
<ItemTemplate Context="item">
<NaviusComboboxItem>
<NaviusComboboxItemIndicator />
@item
</NaviusComboboxItem>
</ItemTemplate>
<ChildContent>
<NaviusComboboxInput />
<NaviusComboboxPortal>
<NaviusComboboxPositioner>
<NaviusComboboxPopup>
<NaviusComboboxList />
<NaviusComboboxEmpty />
</NaviusComboboxPopup>
</NaviusComboboxPositioner>
</NaviusComboboxPortal>
</ChildContent>
</NaviusCombobox>API Reference
Root
Owns the filtered collection, the open state and the selected value(s). Cascades the Combobox context. Renders no DOM of its own.
| Prop | Type | Default |
|---|---|---|
| Items | IReadOnlyList<TItem> | [] |
| Value | string? | - |
| ValueChanged | EventCallback<string?> | - |
| Multiple | bool | false |
| Values | IReadOnlyList<string> | [] |
| ValuesChanged | EventCallback<IReadOnlyList<string>> | - |
| Open | bool | false |
| OpenChanged | EventCallback<bool> | - |
| ItemTemplate | RenderFragment<TItem>? | - |
| ChipTemplate | RenderFragment<string>? | - |
| ChildContent | RenderFragment? | - |
Input
The filter field (role=combobox). Typing filters the list; the committed value stays separate. Renders an input.
| Prop | Type | Default |
|---|---|---|
| Placeholder | string? | - |
| Attributes | IDictionary<string, object>? | - |
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-side] | "top" | "right" | "bottom" | "left" |
| [data-align] | "start" | "center" | "end" |
Item
A selectable value. Highlighted by keyboard/pointer; selecting it commits its value and (single-select) closes the popup. Renders a div with role=option.
| Prop | Type | Default |
|---|---|---|
| Value | string? | - |
| 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 is part of the committed value. |
ItemIndicator
Renders the check glyph for a selected Item. Present only when the parent Item is selected. Renders a span.
| Prop | Type | Default |
|---|---|---|
| ChildContent | RenderFragment? | - |
Accessibility
Implements the combobox WAI-ARIA APG pattern (select-only, list-autocomplete): the highlighted option is tracked with aria-activedescendant so DOM focus never leaves the input. Covered by the browser test suite and an axe-core WCAG gate in CI.
The Input renders role="combobox" but ships without an accessible name. Pair it with a NaviusLabel or supply an aria-label; a placeholder is not an accessible name.
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; single-select closes the list. |
| Backspace | In multi-select, when the input is empty, removes the last chip. |
| Escape | Closes the list, keeping focus in the input. |
| Tab | Closes the list and moves focus to the next element. |