Angular Chip Set component groups chips into an accessible, keyboard-navigable container with single or multiple selection.
Available in Other JavaScript Frameworks
CoreUI Angular Chip Set Component is also available for Bootstrap, React, and Vue. Explore framework-specific implementations below:
Overview
The CoreUI Angular Chip Set component groups multiple chips into a single container that manages focus, keyboard navigation, and selection. While an individual chip handles its own state, the chip set is responsible for everything that spans the whole group:
- One tab stop for the whole set, with arrow keys moving between chips and
Home/Endjumping to the edges. - Moving focus to a neighboring chip after one is removed.
- Single or multiple selection through the
selectionModeinput. - Announcing added and removed chips to screen readers.
The chip set forwards selectable, filter, removable, disabled, removeIcon, selectedIcon, and ariaRemoveLabel to every chip it manages, so you set them once on the set. A projected chip can override them with its own inputs; ariaRemoveLabel on a chip is the full name of its remove button, on the set it is the prefix before the chip text. Each chip is identified by its value.
Basic chip set
Pass a chips array to render the chips from data. Each item is a string or a ChipItem with a value, an optional label, and any chip options (so per-chip overrides work).
import { Component } from '@angular/core';
import { ChipSetComponent } from '@coreui/angular';
@Component({
selector: 'docs-chip-set-basic',
templateUrl: './chip-set-basic.component.html',
imports: [ChipSetComponent]
})
export class ChipSetBasicComponent {
readonly chips = ['Apple', 'Banana', 'Cherry', 'Date'];
}<c-chip-set aria-label="Fruits" [chips]="chips" />You can also project c-chip elements instead of passing chips:
<c-chip-set aria-label="Fruits">
<c-chip value="apple">Apple</c-chip>
<c-chip value="banana">Banana</c-chip>
<c-chip value="cherry">Cherry</c-chip>
<c-chip value="date">Date</c-chip>
</c-chip-set>Selectable chips
Set selectable to make every chip in the set selectable. With the default selectionMode of multiple, any number of chips can be active at once — useful for filters. Bind [(selected)] to the values of the selected chips; a one-way [selected] applies every new value, but does not tell you about selections made by the user.
import { Component, signal } from '@angular/core';
import { ChipSetComponent } from '@coreui/angular';
@Component({
selector: 'docs-chip-set-selectable',
templateUrl: './chip-set-selectable.component.html',
imports: [ChipSetComponent]
})
export class ChipSetSelectableComponent {
readonly chips = ['Design', 'Development', 'Marketing', 'Sales'];
readonly selected = signal(['Development', 'Sales']);
}<c-chip-set aria-label="Departments" selectable [chips]="chips" [(selected)]="selected" />
<p class="small text-body-secondary mt-2 mb-0">Selected: {{ selected().join(', ') || 'none' }}</p>Single selection
Use selectionMode="single" to allow only one selected chip at a time — selecting a chip deselects its siblings. This is useful for choice chips.
import { Component, signal } from '@angular/core';
import { ChipSetComponent } from '@coreui/angular';
@Component({
selector: 'docs-chip-set-single',
templateUrl: './chip-set-single.component.html',
imports: [ChipSetComponent]
})
export class ChipSetSingleComponent {
readonly chips = ['Small', 'Medium', 'Large'];
readonly selected = signal(['Small']);
}<c-chip-set aria-label="Size" selectable selectionMode="single" [chips]="chips" [(selected)]="selected" />Filter chips
Set filter to turn the chips into filter chips. A check icon is shown on each selected chip and removed when it is deselected. filter implies selectable, so you don’t need to set both.
import { Component, signal } from '@angular/core';
import { ChipSetComponent } from '@coreui/angular';
@Component({
selector: 'docs-chip-set-filter',
templateUrl: './chip-set-filter.component.html',
imports: [ChipSetComponent]
})
export class ChipSetFilterComponent {
readonly chips = ['Design', 'Development', 'Marketing', 'Sales'];
readonly selected = signal(['Development', 'Sales']);
}<c-chip-set aria-label="Departments" filter [chips]="chips" [(selected)]="selected" />Customize the check with the selectedIcon input, the same way you customize the remove icon with removeIcon.
Removable chips
Set removable to add a remove button to every chip. The set never changes your list itself: it emits remove with the chip value and chipsChange with the list without that chip. Bind [(chips)] and the chip disappears; when the focused chip is removed, focus moves to a neighboring chip. The selection stays yours as well: a removed or hidden chip keeps its value in selected until you drop it.
import { Component, signal } from '@angular/core';
import { ChipItem, ChipSetComponent } from '@coreui/angular';
@Component({
selector: 'docs-chip-set-removable',
templateUrl: './chip-set-removable.component.html',
imports: [ChipSetComponent]
})
export class ChipSetRemovableComponent {
readonly chips = signal<ChipItem[]>([
{ value: 'filter-one', label: 'Filter one' },
{ value: 'filter-two', label: 'Filter two' },
{ value: 'filter-three', label: 'Filter three', disabled: true }
]);
}<c-chip-set aria-label="Filters" removable [(chips)]="chips" />Bind [chips] with (remove) instead to decide yourself — for example, to ask before removing. Focus returns to the chip after the question, and moves to a neighbor once the chip is gone.
import { Component, signal } from '@angular/core';
import { ChipSetComponent } from '@coreui/angular';
@Component({
selector: 'docs-chip-set-removable-confirm',
templateUrl: './chip-set-removable-confirm.component.html',
imports: [ChipSetComponent]
})
export class ChipSetRemovableConfirmComponent {
readonly chips = signal(['Anna', 'Ben', 'Chloe', 'David']);
ask(value: string) {
if (confirm(`Remove ${value}?`)) {
this.chips.update((chips) => chips.filter((chip) => chip !== value));
}
}
}<c-chip-set aria-label="Recipients" removable [chips]="chips()" (remove)="ask($event)" />Keyboard behavior
The set is a single tab stop; Tab moves into the set and out of it again. When a chip inside a chip set is focused:
| Key | Action |
|---|---|
Enter / Space | Toggle selection of the focused chip (when selectable is enabled) |
Backspace / Delete | Request removal of the focused chip (when removable is enabled) |
ArrowLeft | Move focus to the previous chip (the next one in right-to-left layouts) |
ArrowRight | Move focus to the next chip (the previous one in right-to-left layouts) |
Home | Move focus to the first chip |
End | Move focus to the last chip |
Focus does not wrap around at the edges.
Accessibility
- A selectable set is a
listbox(aria-orientation="horizontal",aria-multiselectablein multiple mode) and its chips areoptions witharia-selected. Give it an accessible name witharia-labeloraria-labelledby. - Any other set is a
group. A chip that is selectable on its own inside a group is a toggle button witharia-pressed; when it is also removable it takes its text asaria-label, so its remove button does not add to the chip’s name. - Inside a
listboxthe remove control is hidden from assistive technology, because an option cannot contain a button; removal runs from the chip withBackspaceorDelete. - Remove buttons are named after their chip, e.g. “Remove Angular”;
ariaRemoveLabelon the set sets the prefix. - One chip at a time is in the tab order: the selected chip at first, then the chip that last had focus. When the focused chip is removed, focus moves to a neighbor, or to the set itself after the last chip.
- Added and removed chips are announced with their text through a page live region (inside an open modal when there is one): “Angular added”, “Angular removed”. Change the wording with
ariaAddedAnnouncementandariaRemovedAnnouncement. Chips that arrive after the first render — data loaded later, a form reset — are announced too, one message per update; render the set once the data is there (@if (tags())) when you don’t want that at page load. - Use
roleto override the role of the set.
Customizing
CSS variables
Angular chip sets use local CSS variables on .chip-set for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too.
--cui-chip-set-gap: #{$chip-set-gap};Sass variables
$chip-set-gap: .25rem !default;API
Chip Set Module
import { NgModule } from '@angular/core';
import { ChipSetModule } from '@coreui/angular';
@NgModule({
imports: [ChipSetModule]
})
export class CustomAppModule {}Chip Set Standalone
import { Component } from '@angular/core';
import { ChipComponent, ChipSetComponent } from '@coreui/angular';
@Component({
template: `
<c-chip-set aria-label="Frameworks" selectable>
<c-chip value="angular">Angular</c-chip>
<c-chip value="react">React</c-chip>
</c-chip-set>
`,
imports: [ChipComponent, ChipSetComponent]
})
export class CustomAppComponent {}c-chip-set
component
import { ChipSetComponent } from '@coreui/angular'