Tag Input
A free-text field that turns what is typed into removable tags — comma or Enter adds one, Backspace removes the last, duplicates are ignored.
TagInput collects a list of short free-text labels — keywords, categories, e-mail addresses — in one field. The tags
sit inside the field, before the text being typed. It reuses InputGroup's visual system (border,
focus, disabled and error states) and shows each tag as a Tag with a remove button.
For a choice among known options, with suggestions, use Autocomplete instead: TagInput
never proposes anything and accepts any text.
Minimal example
import { Component, signal } from "@angular/core";
import { TagInputComponent } from "@sinequa/galactik";
@Component({
selector: "sample-component",
imports: [TagInputComponent],
template: `<TagInput aria-label="Tags" placeholder="Type a tag and press comma…" [(value)]="tags" />`,
})
export class SampleComponent {
tags = signal<string[]>(["design", "angular"]);
}How it works
TagInput is a signal forms FormValueControl<string[]>: bind it with [(value)], or as a form field.
import { Component, signal } from "@angular/core";
import { form, FormField, required } from "@angular/forms/signals";
import { TagInputComponent } from "@sinequa/galactik";
@Component({
selector: "sample-component",
imports: [TagInputComponent, FormField],
template: `
<form>
<TagInput
aria-label="Keywords"
[scheme]="keywords().touched() && keywords().invalid() ? 'error' : 'default'"
[formField]="keywordsForm.keywords" />
</form>
`,
})
export class SampleComponent {
private readonly model = signal({ keywords: [] as string[] });
protected readonly keywordsForm = form(this.model, path => required(path.keywords));
protected readonly keywords = this.keywordsForm.keywords;
}What typing does:
- The separator (
,by default;separator=",;"gives several) and Enter add the tag being typed. Enter never submits the surrounding form. - A tag is trimmed. An empty one is ignored, and so is a duplicate whatever its case — the first spelling stays.
- Backspace in an empty field removes the last tag. The remove button of a tag removes that one.
- Pasting
a, b, c(or one tag per line) adds three tags. - Leaving the field adds what is typed (
addOnBlur, on by default), so a Save button never loses the last word.
Options
Prop
Type
Methods: commit() adds what is typed and clears the field, add(text) and remove(tag) do what the keyboard does,
and focus() moves the focus into the field.
Nothing in the library translates: pass the five labels translated.
Pitfalls
What's next
Autocomplete
An editable combobox for debounced backend search with multi-selection — labels, filter facets, people pickers — where picked values render as removable chips inside the field.
Display
Presentation primitives — Tag, Badge, Bullet, Kbd, Avatar, List, RowGrid, RowFeed — with no business logic of their own.