Angular ng-select - Lightweight all in one UI Select, Multiselect and Autocomplete
See Demo page.
Versions
Warning: Do not use versions 15.2.0, 16.0.0, 17.0.0, 18.0.0, 19.0.0, 20.0.0 as they contain unresolved issues
| Angular | ng-select |
|---|---|
| >=22.0.0 <23.0.0 | v23.x.x |
| >=21.0.0 <22.0.0 | v21.x.x |
| >=20.0.0 <21.0.0 | <=15.1.3, >=20.0.1 |
| >=19.0.0 <20.0.0 | v14.x |
| >=18.0.0 <19.0.0 | v13.x |
| >=17.0.0 <18.0.0 | v12.x |
| >=16.0.0 <17.0.0 | v11.x |
| >=15.0.0 <16.0.0 | v10.x |
| >=14.0.0 <15.0.0 | v9.x |
| >=13.0.0 <14.0.0 | v8.x |
| >=12.0.0 <13.0.0 | v7.x |
| >=11.0.0 <12.0.0 | v6.x |
| >=10.0.0 <11.0.0 | v5.x |
| >=9.0.0 <10.0.0 | v4.x |
| >=8.0.0 <9.0.0 | v3.x |
| >=6.0.0 <8.0.0 | v2.x |
| v5.x.x | v1.x |
Browser Support
ng-select supports all browsers supported by Angular. For current list, see https://angular.io/guide/browser-support#browser-support. This includes the following specific versions:
Chrome 2 most recent versions
Firefox latest and extended support release (ESR)
Edge 2 most recent major versions
Safari 2 most recent major versions
iOS 2 most recent major versions
Android 2 most recent major versions
Table of contents
- Features
- Getting started
- Documentation and examples
- Dropdown panel rendering
- Contributing
- Development
- Inspiration
Features
- Custom binding to property or object
- Custom option, label, header and footer templates
- Virtual Scroll support with large data sets (>5000 items).
- Infinite scroll
- Keyboard navigation
- Multiselect
- Flexible autocomplete with client/server filtering
- Custom search
- Custom tags
- CDK overlay positioning (top-layer rendering, no clipping)
- Group items
- Output events
- Accessibility
- Good base functionality test coverage
- Themes
Warning
Library is under active development and may have API breaking changes for subsequent major versions after 1.0.0.
Getting started
Step 1: Install ng-select and its @angular/cdk peer dependency:
NPM
npm install --save @ng-select/ng-select @angular/cdk
Yarn
yarn add @ng-select/ng-select @angular/cdk
PNPM
pnpm add @ng-select/ng-select @angular/cdk
Step 2:
Standalone: Import NgSelectComponent and other necessary directives directly:
import { NgLabelTemplateDirective, NgOptionTemplateDirective, NgSelectComponent } from '@ng-select/ng-select';
import { FormsModule } from '@angular/forms';
@Component({
selector: 'example',
standalone: true,
template: './example.component.html',
styleUrl: './example.component.scss',
imports: [NgLabelTemplateDirective, NgOptionTemplateDirective, NgSelectComponent],
})
export class ExampleComponent {}
NgModule: Import the NgSelectModule and angular FormsModule module:
import { NgSelectModule } from '@ng-select/ng-select';
import { FormsModule } from '@angular/forms';
@NgModule({
declarations: [AppComponent],
imports: [NgSelectModule, FormsModule],
bootstrap: [AppComponent],
})
export class AppModule {}
Step 3: Include a theme:
To allow customization and theming, ng-select bundle includes only generic styles that are necessary for correct layout and positioning. To get full look of the control, include one of the themes in your application. If you're using the Angular CLI, you can add this to your styles.scss or include it in .angular-cli.json (Angular v5 and below) or angular.json (Angular v6 onwards).
@import '~@ng-select/ng-select/themes/default.theme.css';
// ... or
@import '~@ng-select/ng-select/themes/material.theme.css';
Step 4 (Optional): Configuration
You can also set global configuration and localization messages by injecting NgSelectConfig service, typically in your root component, and customize the values of its properties in order to provide default values.
constructor(private config: NgSelectConfig) {
this.config.notFoundText = 'Custom not found';
// set the bindValue to global config when you use the same
// bindValue in most of the place.
// You can also override bindValue for the specified template
// by defining `bindValue` as property
// Eg : <ng-select bindValue="some-new-value"></ng-select>
this.config.bindValue = 'value';
}
Usage
Define options in your consuming component:
@Component({...})
export class ExampleComponent {
selectedCar: number;
cars = [
{ id: 1, name: 'Volvo' },
{ id: 2, name: 'Saab' },
{ id: 3, name: 'Opel' },
{ id: 4, name: 'Audi' },
];
}
In template use ng-select component with your options
<!--Using ng-option and for loop-->
<ng-select [(ngModel)]="selectedCar">
@for (car of cars; track car.id) {
<ng-option [value]="car.id">{{car.name}}</ng-option>
}
</ng-select>
<!--Using items input-->
<ng-select [items]="cars" bindLabel="name" bindValue="id" [(ngModel)]="selectedCar"> </ng-select>
For more detailed examples see Demo page
SystemJS
If you are using SystemJS, you should also adjust your configuration to point to the UMD bundle.
In your systemjs config file, map needs to tell the System loader where to look for ng-select:
map: {
'@ng-select/ng-select': 'node_modules/@ng-select/ng-select/bundles/ng-select.umd.js',
}
Documentation and examples
Full documentation, live examples and the complete API reference live on the docs site:
- Getting started
- Examples — data sources, bindings, forms, search, tags, templates, multiselect, grouping, virtual scroll and more
- API reference — inputs, outputs and methods for
NgSelectComponent,NgSelectConfig, template directives andNgOptionHighlightDirective - Styling
- Change detection notes
Dropdown panel rendering
Since v24 the dropdown panel is positioned by Angular CDK Overlay instead of the previous hand-rolled geometry code. @angular/cdk is a peer dependency — install it alongside the library. There is nothing to configure; every dropdown renders in an overlay attached to the document body, stays anchored to the select while any ancestor scrolls, resizes with the select, and dropdownPosition="auto" measures the real rendered panel (including header/footer templates) when deciding between top and bottom.
Things to know when migrating:
- DOM location. The panel is no longer a child of
<ng-select>in the DOM — it lives inside.cdk-overlay-container(the same situation asappendTo="body"produced before). CSS that scoped panel styles through an ancestor of the select, like.my-wrapper ng-dropdown-panel { ... }, will no longer match. The panel still receives the select'sclass/ngClassvalues, so scope panel styles through those classes instead:.my-select-class.ng-dropdown-panel .ng-option { ... }. appendTochanged meaning;popoveris a deprecated no-op. Overlay rendering already solves the clipping/stacking problems both existed for, so most usages ofappendTocan simply be removed. It still works — but it now controls where the overlay lives in the DOM (ancestor-scoped styles, stacking context, focus containment) rather than how the panel is positioned; painting and positioning stay viewport-based either way.popoverhas no effect anymore (the overlay uses the native Popover API top layer automatically) and logs a one-time dev-mode warning.- Stacking / z-index. The hardcoded panel
z-index: 1050is gone. In browsers with the native Popover API (all evergreen browsers), the CDK renders the overlay in the top layer, which paints above everyz-index— including Bootstrap modals — with no configuration. In older browsers the panel falls back into.cdk-overlay-containerwith the CDK defaultz-index: 1000(declared in thecdk-overlayCSS layer). If you need the fallback to beat a higher stacking context such as a Bootstrap modal (z-index: 1055), raise the container in your global styles:.cdk-overlay-container { z-index: 1056; }— unlayered author CSS wins over the CDK's layered default regardless of specificity. - Custom themes. The shipped themes no longer position the panel (
top: 100%,bottom: 100%,left: 0and friends were removed — margins, borders, shadows and radii remain). The library neutralizes those offsets for panels rendered in the overlay, so themes copied from older versions keep working, but you should remove positional offsets from.ng-dropdown-panelrules when you update your own theme.
Contributing
Contributions are welcome. You can start by looking at issues with label Help wanted or creating new Issue with proposal or bug report. Note that we are using https://conventionalcommits.org/ commits format.
Development
Perform the clone-to-launch steps with these terminal commands.
Run demo page in watch mode
git clone https://github.com/ng-select/ng-select
cd ng-select
pnpm i
pnpm run start
Testing
pnpm test
or
pnpm test:watch
Release
To release to npm just run ./release.sh, of course if you have permissions ;)
Inspiration
This component is inspired by React select and Virtual scroll. Check theirs amazing work and components :)