Skip to main content
info

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 or Dependency 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 the ComboboxInput and ComboboxButton
  • aria-haspopup="listbox" on the Combobox
  • aria-autocomplete="list" on the ComboboxInput
  • role="combobox" on the Combobox and ComboboxInput
  • role="listbox" on the ComboboxOptions
  • role="option" on each ComboboxOption
  • aria-selected on the selected ComboboxOption
  • 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

InputTypeDescription
modelValueanyCurrently selected value
classstringClass for styling wrapper
OutputTypeDescription
modelValueChangeEventEmitter<any>Emits when selection changes
MethodDescription
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, and role
  • Opens options on focus and input
  • Handles keyboard navigation (Escape, Arrow Down)

ComboboxButtonComponent

  • Automatically binds aria-expanded and aria-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

InputTypeDescription
valueanyValue for this option
disabledbooleanPrevents selection if true
classstringClass applied to the option
OutputTypeDescription
selectedEventEmitter<any>Emits when option is selected

See Also