Skip to main content
Neural UIv2.0.0Documentation
View v1 GitHub

InputTags

Build a list of tags from text, paste or matching suggestions.

Category
Forms and selection
Import
@neural-ui/core/input-tags
Selector
neu-input-tags
import { NeuInputTagsComponent } from '@neural-ui/core/input-tags';

Usage

The model is a readonly array of values. Enter or a separator commits a token; typing a draft alone does not change the array. options and typeahead add suggestions. Use optionLabel/optionValue with objects, compareWith for identity and textValue to parse free text into domain values.

Examples

Interact with the example and open Code for its complete implementation.

Examples
Angular

Choose a suggestion or press Enter to add text. Paste comma-separated topics to add several; duplicates are excluded by default.

Try and configure

Change the controls and try the live preview. Expand the application value or event to inspect its real data; the generated template stays with the configurator.

Try and configure

Live preview

Angular

Generated template: the options above. The Code tab contains the imports and state.

template.html
<neu-input-tags
  [(value)]="tags"
  [options]="topics"
  [typeahead]="true"
  [allowDuplicates]="false"
  [commitOnBlur]="false"
  size="md"
  [delay]="0"
  [emptyMessage]="'No matching topics'"
  [fluid]="true"
  [label]="'Topics'"
  [placeholder]="'Add a topic'"
/>

Signal Forms

Bind FormField once to the component; the field owns value and validation. The schema requires a non-empty value. Leave the control to mark it touched, then reset the field to clear both value and interaction state.

Signal Forms guide

Signal Forms

Valid: true

Value and events

Use [(value)] or [value] with (valueChange), not both. The model synchronizes application state; other Outputs communicate their documented events. touch reports leaving/visiting the control, not a new value.

Accessibility and keyboard

The visible label names the text field. Give removal buttons a descriptive removeLabel; custom item templates must preserve an accessible remove action. Arrow keys navigate suggestions, Enter adds a token and Escape closes the panel. readonly allows inspecting values without adding or removing tags.

Key
Action
Tab Enters and leaves the control.
Enter Commits a text token or highlighted suggestion.
Backspace / Delete Edits text or removes a focused tag.
Escape Closes the suggestions panel.

API

Inputs, models and Outputs come from the pinned Core contract. Click named types to open their definitions. Each Template below includes its own live example and source.

Inputs

Configure the component with [property]="value". Your application supplies these values; the component does not replace the state you pass in.

Name
Type
Default
Template binding
Description
allowDuplicatesbooleanfalse[allowDuplicates]Allows repeated committed values; otherwise compareWith excludes duplicates.
ariaDescribedBystring''[ariaDescribedBy]IDs of elements describing the control, separated by spaces.
ariaLabelstring''[ariaLabel]Accessible name when no visible label is available.
ariaLabelledBystring''[ariaLabelledBy]ID of the element that supplies the accessible name.
ariaRequiredbooleanfalse[ariaRequired]Accessible required state; it does not install a validator.
autocompletestring'off'[autocomplete]Native browser autocomplete attribute for the input.
autofocusbooleanfalse[autofocus]Requests focus when the control is initialized.
autoOptionFocusbooleanfalse[autoOptionFocus]Moves the active option to an available option when the list opens.
commitOnBlurbooleanfalse[commitOnBlur]Commits the current text draft when focus leaves the composite control.
compareWithNeuOptionCompareWith<V>Object.isDerived default[compareWith]Comparison function for selected values; use stable domain identity.
completeOnFocusbooleanfalse[completeOnFocus]Requests matching suggestions when focus enters the control.
delaynumber300[delay]Debounce time in milliseconds before requesting suggestions.
dirtybooleanfalse[dirty]Form state indicating that the user has changed the value.
disabledbooleanfalse[disabled]Prevents user interaction.
emptyMessagestring'No suggestions'[emptyMessage]Message displayed when the option collection is empty.
errorsreadonly ValidationError.WithOptionalFieldTree[][][errors]Validation errors supplied by the form or the application.
fluidbooleanfalse[fluid]Makes the control fill its containing width.
focusOnHoverbooleantrue[focusOnHover]Changes the active option when the pointer enters an option.
groupsreadonly NeuInputTagsGroup<T>[][][groups]Grouped options, with child items configured through groupConfig.
hiddenbooleanfalse[hidden]Hides the control according to the form state.
hintstring''[hint]Help text associated with the field.
inputIdstring''[inputId]Stable identifier of the native control; automatically generated when omitted.
invalidbooleanfalse[invalid]Displays the invalid state; it does not add a validation rule.
labelstring''[label]Visible label and accessible name of the control.
loadingbooleanfalse[loading]Displays the loading state while the application supplies data.
maxItemsnumber | nullnull[maxItems]Maximum committed tag count, or null for no limit.
maxlengthnumber | nullnull[maxlength]Maximum native draft-text length, or null for no limit.
minlengthnumber | nullnull[minlength]Minimum native draft-text length, or null when unspecified.
minQueryLengthnumber1[minQueryLength]Minimum draft length before requesting suggestions.
namestring''[name]Name associated with the native form control.
normalizeToken(text: string) => string(text) => text.trim()Derived default[normalizeToken]Normalizes free-text tokens before parsing and duplicate comparison. Defaults to trim.
optionDisabledNeuOptionDisabledAccessor<T> | nullnull[optionDisabled]Field name or function that marks an option as disabled.
optionLabelNeuOptionLabelAccessor<T> | nullnull[optionLabel]Field name or function used to obtain the visible option label.
optionsreadonly T[][][options]Loaded option records. Accessors allow using your own domain objects.
optionValueNeuOptionValueAccessor<T, V> | nullnull[optionValue]Field name or function used to obtain the stored option value.
pendingbooleanfalse[pending]Form state indicating that asynchronous validation is pending.
placeholderstring'Add tag...'[placeholder]Text shown when the field has no selected value.
readonlybooleanfalse[readonly]Keeps the control focusable and readable without accepting edits.
removeLabelstring'Remove'[removeLabel]Accessible label prefix for removing a tag.
requiredbooleanfalse[required]Marks the field as required; use a form validator to enforce it.
scrollHeightstring'200px'[scrollHeight]Maximum height of the option viewport.
separatorsreadonly string[][','][separators]Characters that commit a draft or split pasted text into tokens. Defaults to comma.
size"sm" | "md" | "lg"'md'[size]Visual field size: sm, md or lg.
tabindexnumber | nullnull[tabindex]Tab order of the keyboard entry point.
textValue((text: string) => V | null | undefined) | nullnull[textValue]Converts free text into a value. Returning null/undefined rejects the token.
titlestring''[title]Native tooltip text for the text field.
touchedbooleanfalse[touched]Form state indicating that the control has been visited.
typeaheadbooleanfalse[typeahead]Enables the suggestion panel backed by options or groups.
variant"outline" | "solid"'outline'[variant]Visual field variant: outline or solid.

Models

A model supports [(property)]="signal" or the [property] and (propertyChange) pair. Choose one form, not both.

Name
Type
Default
Template binding
Description
valuereadonly V[][][(value)]Readonly array of committed tag values; the draft is separate.

Outputs

Listen to an event with (event)="handler($event)". The table explains the data your handler receives and how to use it.

Name
Payload
Template binding
Description
clearedNeuInputTagsClearedEvent<V>(cleared)="onCleared($event)"Emitted for the explicit clear action; valueChange carries the resulting value.
closedvoid(closed)="onClosed($event)"Emitted after the browser panel closes.
focusEnteredFocusEvent(focusEntered)="onFocusEntered($event)"Emitted when focus enters the control.
focusLeftFocusEvent(focusLeft)="onFocusLeft($event)"Emitted when focus leaves the control.
itemRemovedNeuInputTagsRemovedEvent<V>(itemRemoved)="onItemRemoved($event)"Reports the removed item and index; valueChange already synchronizes the array.
itemReorderedNeuInputTagsReorderedEvent<V>(itemReordered)="onItemReordered($event)"Reports a reordered item; valueChange synchronizes the new array order.
openedvoid(opened)="onOpened($event)"Emitted after the browser panel opens.
optionActivatedNeuOptionActivatedEvent<T, V>(optionActivated)="onOptionActivated($event)"Activated option, its value and the originating event.
pasteResultNeuInputTagsPasteResult<V>(pasteResult)="onPasteResult($event)"Reports accepted and rejected pasted tokens after processing.
suggestionsRequestNeuOptionDataRequest(suggestionsRequest)="onSuggestionsRequest($event)"Requests suggestions with query and request identity; the application supplies suggestions.
touchvoid(touch)="onTouch($event)"Notifies the form that the control has been touched; not a value change.

Templates

ng-content projects content into the component. TemplateRef inputs receive a template; ng-template directives identify templates with a typed context. A directive shared by an entrypoint is not necessarily a slot of this component.

Name
Mechanism
Contract
NeuInputTagsFooterDirectiveView example Public template directive (entrypoint)ng-template[neuInputTagsFooter]
NeuInputTagsGroupDirectiveView example Public template directive (entrypoint)ng-template[neuInputTagsGroup]
NeuInputTagsHeaderDirectiveView example Public template directive (entrypoint)ng-template[neuInputTagsHeader]
NeuInputTagsItemDirectiveView example Public template directive (entrypoint)ng-template[neuInputTagsItem]
NeuInputTagsOptionDirectiveView example Public template directive (entrypoint)ng-template[neuInputTagsOption]
NeuInputTagsRemoveIconDirectiveView example Public template directive (entrypoint)ng-template[neuInputTagsRemoveIcon]

Each example demonstrates a different template. Switch between Demo and Code to inspect its implementation, imports and state.

Group template

NeuInputTagsGroupDirective

Group template
Angular

Header template

NeuInputTagsHeaderDirective

Header template
Angular

Item template

NeuInputTagsItemDirective

Item template
Angular

Option template

NeuInputTagsOptionDirective

Option template
Angular

RemoveIcon template

NeuInputTagsRemoveIconDirective

RemoveIcon template
Angular

Public Types

Open a type to inspect its definition and interface fields.

Styles and tokens

Load Core styles once. Use the public tokens below for local customization or a preset for application-wide changes. Keep labels, focus, selected options and disabled states readable in both light and dark themes.

Specific tokens

This component uses shared theme tokens rather than dedicated component hooks.

Shared tokens used

Override these on a local wrapper to affect this example. An override on :root affects other components that use the same token.

Token
Purpose here
Other impact
Default / fallback
--neu-border Normal control and cell borders Shared by other Core consumers; scope the override. rgba(15, 23, 42, 0.08)
--neu-error Invalid field or danger-action color Shared by other Core consumers; scope the override. #dc2626
--neu-focus-ring Normal keyboard-focus ring Shared by other Core consumers; scope the override. 0 0 0 var(--neu-focus-ring-width) rgba(0, 122, 255, 0.15)
--neu-primary Brand color for active controls and emphasis Shared by other Core consumers; scope the override. #007aff
--neu-primary-50 Subtle brand surface for hover and focus states Shared by other Core consumers; scope the override. #eff6ff
--neu-radius Control corner radius Shared by other Core consumers; scope the override. 8px
--neu-surface Main field, header or control surface Shared by other Core consumers; scope the override. #ffffff
--neu-surface-2 Secondary surfaces and alternating rows Shared by other Core consumers; scope the override. #f1f5f9