Tag Input
Free text materialized into removable chips: delimiters commit a chip, chip navigation is a roving tab stop, and commit rules (transform, validate, dedupe, cap) live on the root.
Tags:
<NaviusTagInput @bind-Value="_tags" class="flex flex-wrap items-center gap-1.5 rounded-md border p-1.5">
<NaviusTagInputList class="contents">
@for (var i = 0; i < _tags.Count; i++)
{
var tag = _tags[i];
<NaviusTag @key="tag" Value="@tag" Index="i"
class="inline-flex items-center gap-1 rounded bg-secondary px-2 py-0.5
data-[highlighted]:ring-2 data-[highlighted]:ring-ring">
@tag
<NaviusTagRemove>×</NaviusTagRemove>
</NaviusTag>
}
</NaviusTagInputList>
<NaviusTagInputField Placeholder="Add tag…" class="flex-1 bg-transparent outline-none" />
</NaviusTagInput>Features
-
Delimiterspick which keys / chars commit (Enter + Comma by default); a typed or pasted comma / space splits and commits. - The commit pipeline runs on the root:
Transformnormalizes, then duplicate (AllowDuplicates),MaxTagsandValidategate it; a blocked add raisesOnInvalid. - Backspace on an empty field highlights then removes the last chip; ArrowLeft enters chip navigation, where the highlighted chip is the single roving tab stop.
- Controlled via
@bind-Value(anIList<string>), uncontrolled viaDefaultValue;OnAdd/OnRemovereport each change.
Installation
Install the brain, or copy just this primitive in with the CLI.
navius add tag-inputAnatomy
Iterate the bound tag list into chips, then a field. The List is layout only; the roving tabindex lives on the chips.
@using Navius.Primitives.Components.TagInput
<NaviusTagInput @bind-Value="_tags">
<NaviusTagInputList>
@foreach (var tag in _tags)
{
<NaviusTag @key="tag" Value="@tag">
@tag
<NaviusTagRemove />
</NaviusTag>
}
</NaviusTagInputList>
<NaviusTagInputField />
</NaviusTagInput>API Reference
Root
NaviusTagInput. Owns the tag collection, the chip highlight and the commit rules. Renders a wrapper div. Value is two-way bindable.
| Prop | Type | Default |
|---|---|---|
| Value | IList<string>? | - |
| ValueChanged | EventCallback<IList<string>> | - |
| DefaultValue | IList<string>? | - |
| Delimiters | IReadOnlyList<TagDelimiter>? | Enter, Comma |
| AllowDuplicates | bool | false |
| MaxTags | int? | - |
| Validate | Func<string, bool>? | - |
| Transform | Func<string, string>? | - |
| AddOnBlur | bool | false |
| Disabled | bool | false |
| OnAdd | EventCallback<string> | - |
| OnRemove | EventCallback<string> | - |
| OnInvalid | EventCallback<string> | - |
| ChildContent | RenderFragment? | - |
| …attributes | IDictionary<string, object>? | - |
Data attributes
| Data attribute | Values |
|---|---|
| [data-navius-tag-input] | Present on the wrapper |
| [data-disabled] | Present when disabled |
| [data-empty] | Present when there are no tags |
List
NaviusTagInputList. The chip container (layout only). Renders a div.
| Prop | Type | Default |
|---|---|---|
| ChildContent | RenderFragment? | - |
| …attributes | IDictionary<string, object>? | - |
Data attributes
| Data attribute | Values |
|---|---|
| [data-navius-tag-input-list] | Present on the chip container |
Tag
NaviusTag. One chip; the highlighted chip is the single roving tab stop. Cascades its value to a nested Remove. Renders a span.
| Prop | Type | Default |
|---|---|---|
| Value | string | "" |
| Index | int | -1 |
| ChildContent | RenderFragment? | - |
| …attributes | IDictionary<string, object>? | - |
Data attributes
| Data attribute | Values |
|---|---|
| [data-navius-tag] | Present on each chip |
| [data-highlighted] | Present on the chip-navigation highlight (the roving tab stop) |
TagRemove
NaviusTagRemove. A button inside a Tag that removes it (tabindex=-1; auto aria-label 'Remove {value}'). Renders a button.
| Prop | Type | Default |
|---|---|---|
| ChildContent | RenderFragment? | - |
| …attributes | IDictionary<string, object>? | - |
Data attributes
| Data attribute | Values |
|---|---|
| [data-navius-tag-remove] | Present on the remove button |
Field
NaviusTagInputField. The text input that commits chips on the delimiters. Renders an input.
| Prop | Type | Default |
|---|---|---|
| Placeholder | string? | - |
| …attributes | IDictionary<string, object>? | - |
Data attributes
| Data attribute | Values |
|---|---|
| [data-navius-tag-input-field] | Present on the input |
Delimiters is an IReadOnlyList<TagDelimiter> where TagDelimiter is Enter / Comma / Tab / Space.
Accessibility
Chips carry a roving tabindex (only the highlighted chip is tabbable). Each remove button labels itself "Remove {value}" unless you override it. Pair the field with a Label.
Keyboard interactions
| Key | Description |
|---|---|
| Enter / , (comma) | Commits the current field text as a chip (the default delimiters). |
| Backspace (empty field) | Highlights the last chip, then removes it on the next press. |
| Arrow Left (empty field) | Enters chip navigation, highlighting the last chip. |
| Arrow Left / Arrow Right (on a chip) | Moves the highlight between chips (Right past the last returns to the field). |
| Home / End (on a chip) | Highlights the first / last chip. |
| Delete / Backspace (on a chip) | Removes the highlighted chip. |