Combobox
is still under development, might break sometimes. But nothing you can't fix manually by your own markup and styling.
Combobox
The Combobox
component is a fully headless and accessible UI primitive that combines an input field with a dropdown list of options. It's inspired by HeadlessUI Combobox, but built natively for Angular.
It is useful for building autocomplete inputs, searchable selects, and typeahead components — while giving you complete control over markup and styling.
When to use it
Use Combobox
when you need a searchable select component that is:
- Fully customizable in layout and appearance
- Accessible with screen readers and keyboard navigation
- Supports filtering and search functionality
- Controlled via Angular
templateRefs
orDependency Injection (DI)
- Compatible with reactive or template-driven forms
Common use cases:
- Autocomplete inputs
- Searchable select dropdowns
- Typeahead components
- User/tag pickers with search
Anatomy
A complete Combobox
is composed of five components:
Combobox
- The provider and wrapper. Manages internal selection and input state.ComboboxInput
- The text input field for typing and filtering.ComboboxButton
- Optional trigger button to toggle the options.ComboboxOptions
- The container for all selectable options.ComboboxOption
- Individual selectable option items.
All five components are standalone and composable.
Features
- ✅ Accessible by default (ARIA attributes)
- ✅ Tailwind-friendly (no styles imposed)
- ✅ Multiple selectors supported:
<Combobox>
<div ngxCombobox>
<ngx-headlessui-combobox>
- ✅ Works with both
#templateRefs
and Angular DI (ComboboxContextService
) - ✅ Supports multiple instances per page
- ✅ Built-in filtering and search capabilities
Installation
Combobox
ships as part of the @ngx-headless/ui
by default. Install if you haven't already.
npm install @ngx-headless/ui
Import the components directly:
import {
ComboboxComponent,
ComboboxInputComponent,
ComboboxButtonComponent,
ComboboxOptionsComponent,
ComboboxOptionComponent,
} from "@ngx-headless/ui";
Usage Examples
Template Reference — Basic Combobox
<Combobox #c="ngxCombobox" [(modelValue)]="selectedValue">
<ComboboxInput [value]="c.getInputValue()" (input)="onInputChange($event)" />
<ComboboxButton>Toggle</ComboboxButton>
<ComboboxOptions *ngIf="c.isOpen()">
<ComboboxOption *ngFor="let option of filteredOptions" [value]="option">
{{ option.name }}
</ComboboxOption>
</ComboboxOptions>
</Combobox>
Template Reference — With Filtering
<Combobox #c="ngxCombobox" [(modelValue)]="selectedPerson">
<ComboboxInput
[value]="c.getInputValue()"
(input)="updateQuery($event)"
placeholder="Search people..." />
<ComboboxOptions *ngIf="c.isOpen() && filteredPeople.length > 0">
<ComboboxOption *ngFor="let person of filteredPeople" [value]="person">
{{ person.name }}
</ComboboxOption>
</ComboboxOptions>
<div *ngIf="c.isOpen() && filteredPeople.length === 0">
No results found.
</div>
</Combobox>
Accessibility
This component handles
aria-expanded
on theComboboxInput
andComboboxButton
aria-haspopup="listbox"
on theCombobox
aria-autocomplete="list"
on theComboboxInput
role="combobox"
on theCombobox
andComboboxInput
role="listbox"
on theComboboxOptions
role="option"
on eachComboboxOption
aria-selected
on the selectedComboboxOption
- Keyboard interaction: arrow keys for navigation, Enter for selection, Escape to close
- Screen reader compatibility for search and selection state
Animations
ComboboxOptions
can be animated freely using Angular's built-in animation system.
Example
Add an animation trigger to your component:
import { trigger, transition, style, animate } from "@angular/animations";
@Component({
animations: [
trigger("slideDown", [
transition(":enter", [
style({ opacity: 0, transform: "translateY(-10px)" }),
animate("150ms ease-out", style({ opacity: 1, transform: "translateY(0)" })),
]),
transition(":leave", [
animate("100ms ease-in", style({ opacity: 0, transform: "translateY(-10px)" })),
]),
]),
],
})
export class ExampleComponent {}
Use it in the template with *ngIf
:
<ComboboxOptions *ngIf="combobox.isOpen()" @slideDown>
Options go here.
</ComboboxOptions>
Component API
ComboboxComponent
Input | Type | Description |
---|---|---|
modelValue | any | Currently selected value |
class | string | Class for styling wrapper |
Output | Type | Description |
---|---|---|
modelValueChange | EventEmitter<any> | Emits when selection changes |
Method | Description |
---|---|
isOpen() | Returns true if options open |
toggle() | Toggles options open/close |
open() | Opens options |
close() | Closes options |
selectValue() | Selects a specific value |
getInputValue() | Returns current input text |
setInputValue() | Sets the input text value |
getFilteredOptions() | Returns filtered option list |
ComboboxInputComponent
- Automatically binds
aria-expanded
,aria-autocomplete
, androle
- Opens options on focus and input
- Handles keyboard navigation (Escape, Arrow Down)
ComboboxButtonComponent
- Automatically binds
aria-expanded
andaria-haspopup
- Toggles options on click and keyboard interaction
ComboboxOptionsComponent
- Visible only when
Combobox
is open - Can be styled or animated freely
hidden
attribute used for visibility
ComboboxOptionComponent
Input | Type | Description |
---|---|---|
value | any | Value for this option |
disabled | boolean | Prevents selection if true |
class | string | Class applied to the option |
Output | Type | Description |
---|---|---|
selected | EventEmitter<any> | Emits when option is selected |