Skip to content

Inputs

TagsInput

Bit.BlazorUIChipsTokens

The TagsInput turns free text into a list of short values: the user types a tag, confirms it with Enter (or with a separator of your own), and it becomes a removable chip in front of the input. It binds to a collection of strings, offers known values through the browser's own suggestion list - or accepts nothing else - splits a pasted list into a tag each, and keeps the entries in shape on the way in: trimming, transforming, capping their length and their number, and rejecting the ones that repeat, that are too short, that fail a pattern or that a validator turns down, each rejection reported with the rule that caused it. The chips form a proper accessible list: one stop of the tab order that the arrow keys walk through, removable with Delete, correctable in place, movable by drag, by two taps on the handle a chip grows or with Alt and the arrows, with the ones a predicate pins in place carrying no dismiss button at all, and with every change announced to screen readers. It comes in three sizes, three variants and the whole accent palette, folds a long list away behind a chip, carries a label, a helper text, a prefix, a suffix, a counter, a clear button and a spinner for the suggestions it is still fetching, can be driven entirely from code, and takes part in an EditForm like any other input.

Usage

Every example is live. Open its code to see exactly what produced the component running underneath.

Basic

Type a word and press Enter: it becomes a chip, and its dismiss button takes it back off. Placeholder is the hint shown while the list is still empty; once there is a tag it would only compete with the chips for the width of the field, so it is dropped unless a TagsPlaceholder keeps the invitation visible. ReadOnly keeps the tags visible and navigable while refusing every change, and Disabled dims the whole field along with them.

blazor
1 tags.
Tag 1
Tag 2
2 tags.
Tag 1
Tag 2
2 tags.

Label & description

Label renders the caption above the field and ties it to the input, so clicking it puts the caret in there. With the inherited Required it carries the asterisk that marks the field as mandatory. Description renders a hint under the field which the input references through aria-describedby, so it is announced along with the field rather than only drawn - which is where the rules of the field belong. LabelTemplate and DescriptionTemplate take markup instead of a string.

Press Enter after each skill. Up to 5 of them.
Separate the addresses with a comma or a semicolon.

Variants

Variant decides how much of a frame the field carries - Outline (the default), Fill or only an underline with Text - and NoBorder removes it altogether. TagVariant decides how much of the color the chips are painted with, exactly as a BitTag is. The two are independent, so they combine freely.

blazor
dotnet
2 tags.
blazor
dotnet
2 tags.
blazor
dotnet
2 tags.
blazor
dotnet
2 tags.

Separators & pasting

By default only Enter turns the typed text into a tag. Separators adds characters that do the same: typing one commits what stands before it, and the character itself never reaches the input. A separator is any string - a comma, a space, or something longer such as ", ". The same separators split a paste, so a comma separated list arrives as a whole row of tags, each piece going through the same validation. A paste spread over several lines is joined over the first separator on its way in, so a column copied out of a spreadsheet does not land as one run-on tag.

Try pasting: red,green;blue - or a column copied out of a spreadsheet.

Suggestions

Suggestions offers known values while the user types, through the list the browser itself renders for a datalist - reachable, positioned and announced on every platform without a popup of our own. Picking one only fills the input; the usual Enter turns it into a tag, so every rule still applies. Values already in the list are left out, and so are all of them once MaxTags leaves nothing to add. A datalist suggests rather than restricts: RestrictToSuggestions is what makes them the only accepted values, rejecting anything else with the NotSuggested reason. What counts as one of them is decided by Comparison, and the tag that is stored is the suggestion rather than the spelling it was typed with, so a list to be grouped later never holds two spellings of one value. MaxSuggestions caps how many are written into the page at once - beyond it only the values holding what is being typed are kept, matched without regard to case the way the browser filters the list it is handed, so what the user is shown does not change. Where the catalogue is fetched rather than held, OnInput is what triggers the fetch and IsLoading draws the spinner that says the field is waiting - an indeterminate progressbar, so a screen reader hears the wait instead of missing it. DebounceTime waits for the typing to stop before raising it, which turns a request per keystroke into a request per word (ThrottleTime spaces them out instead, for a list that should keep up while the word is still being typed). Only the callback waits: the text itself is tracked as it is typed, so the tag Enter commits is never a keystroke behind, and the emptying that follows a committed tag is reported at once, taking the pending call down with it.

Type a letter or two to see the list.
Anything else is refused, and BLAZOR is stored as blazor.
Only the five best matches are ever written into the page.
Nothing is fetched until the typing stops for 300ms; the spinner says so meanwhile.

Limits & counter

MaxTags caps how many tags the list may hold; beyond it every tag is rejected with the MaxTags reason, which OnInvalid receives along with the tag - so the field can say why nothing happened instead of appearing to ignore the Enter key. A paste that would overflow the cap stops there rather than being refused whole. MaxLength caps the characters of each tag and truncates rather than rejects - throwing the twelfth character away beats throwing a pasted list away - while MinLength rejects what is too short. Both count the text after trimming and transformation, so they measure exactly what would be added. ShowCounter draws the number of tags under the field, as a plain count or as count / MaxTags.

blazor
1 of 3 tags.
Typing beyond the tenth character does nothing; shorter than three is refused.

Rules & normalization

Transformer normalizes the text before anything else is done with it - lower casing, stripping a leading #, collapsing whitespace - so every rule below sees the normalized text and it is the normalized text that is stored. Pattern is a regular expression every tag has to match (an expression that cannot be compiled is ignored rather than breaking the field, and a runaway match is timed out and treated as a failure); Validator covers what an expression cannot - a lookup, a checksum, a rule depending on the other tags. A tag already in the list is refused by default and reported through OnTagExists; Duplicates lifts that, and Comparison decides which tags count as the same one. Every refusal reaches OnInvalid with the rule that caused it.

A refusal is never silent. ShowInvalidMessage draws why under the field, where the helper text stands - the same sentence screen readers are given, naming the limit the rule was built on ("A tag must be at least 3 characters.") rather than leaving the user to guess; a red rule alone is a message half the readers of a page never get. GetInvalidMessage rewrites that sentence for wording of your own and for localization, and InvalidAnnouncementFormat writes the frame it sits in ({0} the tag, {1} the reason). Alongside it the field wears its invalid color - and says so through aria-invalid - until the next keystroke answers it, and a tag refused as a duplicate marks the chip already in the list that it collided with, since "you already have this one" is only an answer if it says which one. NoInvalidHighlight turns that mark off, and OnInvalid (with OnTagExists for the duplicate alone) hands the refusal to a report of your own.

Lower cased, stripped of a leading # and of the whitespace inside - so the second spelling is a duplicate. Add one twice to see the chip it collided with marked.
Only well formed addresses are accepted, and the refusal is worded here rather than built.
Only those four, and each of them as often as you like.

Editable tags

EditableTags lets a tag be corrected in place instead of being removed and typed again: double click a chip, or press Enter or F2 on the focused one, and it turns into a little input with its text selected - carrying the same InputMode, EnterKeyHint and SpellCheck as the field, since those belong to the values it collects rather than to the one box they are typed into. Enter commits, Escape puts the old text back, and leaving the input commits too. The text goes through the same trimming, transformation and validation as a tag being added - except that the tag is not a duplicate of itself and the ceiling cannot be reached, since the list does not grow. A correction those rules turn down is handed back in the still open input, caret at its end, rather than being thrown away with the chip snapping back: an error is the one moment a field must not lose what was just entered. Committing an empty text removes the tag, and OnEdit receives the old and the new text and can call the change off.

blazor
dotnet
web
Correct one to a single letter: the refusal says why and hands the text back.
3 tags.
Press Enter to edit, or Delete to remove.

Reordering

AllowReorder lets a tag be moved three equal ways, one for each kind of user. Drag a chip onto the one whose position it should take: the carried chip fades and the one under the pointer is outlined, so the landing place is visible before the button is let go of. Tap the handle the chip grows at its start, then the tag whose place it should take - two taps rather than a drag, for every pointer that cannot drag at all: a touch screen, a switch, a head pointer. A second tap on the handle, on the lifted chip, on the field around it, or the Escape key puts it back down. From the keyboard, hold Alt with the arrow keys to walk the focused chip one position at a time, or Alt+Home / Alt+End to send it to either end. Whichever it was, the focus travels with the tag and the move is announced. ReorderIconName, ReorderTitle, ReorderAriaLabelFormat and ReorderDropAriaLabelFormat write the handle, and PickedUpAnnouncementFormat and PutBackAnnouncementFormat what it says out loud. OnReorder reports the tag and the two positions, which is what says which chip moved without diffing the list; the order is part of the value, so the move is written back through @bind-Value as well.

first
second
third
fourth
Drag a chip onto another one; or tap a handle and then the tag whose place it should take; or focus one with Tab and hold Alt while pressing the arrow keys.
4 tags.
Press Alt with the arrow keys to move, or Delete to remove.

Folding the tags away

MaxDisplayedTags draws only the first few chips and folds the rest behind one saying how many are left, which unfolds the list and folds it back - so a tag that is not drawn is never a tag that cannot be reached, with the pointer or with the keyboard, where the chip is a tab stop of its own. Only how much is drawn changes: the value keeps every tag, the counter counts all of them, and the form posts them. MoreTagsFormat and LessTagsText write its two labels, MoreTagsAriaLabelFormat what it is announced as - "+3" read out alone says nothing about what pressing it would do.

blazor
dotnet
web
The rest of the tags are one click away.
6 tags.
blazor
dotnet
4 tags.

Clear button

ShowClearButton renders a button at the end of the field that empties the whole list along with the text in the input, and raises OnClear with what it removed. It is not rendered while the field is read-only, disabled or already empty, and it stays out of the tab order - Escape on the input is its keyboard equivalent. Escape takes back what is being typed first, though: it is the second press, on the now empty input, that empties the list. OnBeforeClear runs first whichever of the three emptied the field and can call it off, which is where a confirmation belongs. Pressing the button takes the button away with everything else, so the caret is handed back to the input rather than dropped on the page. NoClearOnEscape hands the key back to whatever surrounds the field, for a form inside a modal or a callout where dismissing that is what the user means by pressing it.

blazor
dotnet
web
3 tags.
blazor
dotnet
web
Clearing is refused while there are more than two tags.
3 tags.

Fixed tags

CanRemoveTag decides which tags the user may take off the list, for the values a field holds but does not let go of: the owner among the editors of a document, the tag a saved filter is built on. A tag it turns down is drawn without a dismiss button, ignores Delete and Backspace, is left alone by the Backspace pressed on the empty input, and stays behind when the field is cleared - so clearing empties the field of everything it can be emptied of, and a field holding nothing else does not render a clear button at all. It is still editable and still movable, since neither takes the tag away, and the sentence announced after a fixed chip says so rather than promising a removal that does nothing. It governs what the user may do, not what you may: RemoveTagAsync names a tag outright and takes it off regardless.

[email protected] is the owner: no dismiss button, no Delete, and the clear button leaves it behind.
2 tags.
Press Enter to edit, or Delete to remove.
This tag cannot be removed. Press Enter to edit it.

Keyboard & typing

The chips are a single stop of the tab order rather than one per tag. Left and Right (swapped in RTL) move between them, Home and End jump to the ends, Delete and Backspace remove the focused one and hand the focus to its neighbour, Enter and F2 open the inline edit, Alt with the arrows moves the tag, and Escape goes back to the input. Every one of those keys carries a browser default that is held back for it, so a gesture of the field never turns into a gesture of the browser. NoClearOnEscape leaves Escape alone altogether, for a field inside a surface that closes on it.

From the input, Backspace on an empty field removes the last tag - NoBackspaceRemove turns that off and BackspaceEditsLastTag turns it into a correction, putting the tag's text back into the input instead of letting it disappear - and the backwards arrow walks into the last chip. Tab commits the text left in the input unless NoAddOnTab is set, while Shift+Tab always walks straight out, so the field is never a trap. Losing the focus commits too, which NoAddOnBlur turns off and ClearOnBlur turns into a discard. While an input method is composing a character the Enter that picks a candidate is not treated as a confirmation, so a tag is never cut in half by it.

InputMode and EnterKeyHint decide the virtual keyboard a phone opens and the label on its return key; SpellCheck turns the red underline back on for a field that collects words rather than identifiers, and AutoComplete hands the browser's own autofill back where the field collects values it knows about.

one
two
three
3 tags.
one
two
2 tags.
one
two
Backspace on the empty input takes the last tag back for correction; leaving the field throws away what was still being typed.
2 tags.
An email keyboard with a Done return key.

Accessibility & localization

A chip appearing, disappearing or changing place reaches no screen reader on its own - the list sits away from the caret - so the component says each of them out loud through a polite live region: AddedAnnouncementFormat, AddedManyAnnouncementFormat, RemovedAnnouncementFormat, ClearedAnnouncementFormat, EditedAnnouncementFormat, MovedAnnouncementFormat, PickedUpAnnouncementFormat, PutBackAnnouncementFormat and InvalidAnnouncementFormat. Most take {0} for the tag - the move also {1} for the position it landed on and {2} for how many tags there are, the refusal {1} for why it was turned down - and an empty string keeps that event silent. The two standing for a batch count instead of naming: reading fifty names out is not a confirmation but a wall, and the tags are in the list to be walked through anyway.

The list itself sits away from the caret, so a reader landing in a field that already holds tags would otherwise be told only that the input is empty: the input describes itself with how many there are - "3 of 5 tags" where MaxTags sets a ceiling - which TagCountAriaDescriptionFormat writes. It is referenced rather than announced, so it is read on arriving and never while the field is being typed into.

The names of the parts follow the same idea: TagsAriaLabel names the list, TagAriaDescription is the sentence telling what the keyboard can do with the chip just reached (built from the gestures the field was actually given, and left out when there are none), DismissAriaLabelFormat and DismissTitle name the dismiss button, ReorderAriaLabelFormat, ReorderDropAriaLabelFormat and ReorderTitle the reorder handle, EditAriaLabelFormat the little edit input, and ClearButtonAriaLabel the button that empties the field. Each chip also carries its own position in the whole list, so "the third of six" stays true where MaxDisplayedTags folded the rest away.

One thing a chip cannot give on its own is a 24 CSS-pixel pointer target (WCAG 2.2, SC 2.5.8): the dismiss button and the reorder handle take the full height of the chip and a pad on either side of the glyph, which is all a chip as tall as a line of text has to give. Where that minimum has to be met, grow the chips - --bit-TagsInput-tag-min-height: 1.5rem with a roomier --bit-TagsInput-tag-padding - and widen the buttons through Classes.DismissButton; the keyboard reaches both at any size, Delete removing the focused chip and Alt with the arrows moving it.

blazor
dotnet
2 tags.
Press Enter to edit, Delete to remove, or Alt with the arrow keys to move.
blazor
dotnet
2 of 5 skills chosen.
Press Enter to rename this skill, or Delete to drop it.

Prefix & Suffix

Prefix and Suffix draw a short text inside the field, at its start and at its end, which is not part of the value: the To: of a recipients field, the unit of a list of measurements. The prefix sits in front of the chips and the suffix after everything else, the clear button included. Both are announced with the field - the input references them, ahead of the Description - so a reader is told what a sighted user reads inside it. PrefixTemplate and SuffixTemplate take markup instead, for an icon or a badge; markup is as likely to be a glyph as a word, so those are not announced and what they mean has to be in the Label as well.

1 tags.
12
34
cm
2 tags.
blazor
dotnet
2 tags.

Tag template & per-tag styling

TagTemplate replaces the text of every chip with markup of your own, the tag being the context; the chip around it - its background, its focus ring, its dismiss button - is still the component's, so a template only describes what goes inside. Markup is not something a name can be read off, though, so a chip drawing Ada Lovelace over the tag [email protected] is announced by neither the one nor the other: GetTagName is what names it, and the name it gives is carried by the chip, by its dismiss button, by its reorder handle, by its inline edit and by every announcement the tag takes part in. GetTagClass and GetTagStyle are what tell one chip apart from the next: each receives a tag and returns what that particular chip should carry on top of the shared styling - the address that is not well formed drawn in red, each priority in a color of its own. They run for every drawn tag on every render, so they belong to a lookup rather than a computation, and an exception thrown out of one leaves that chip looking like all the others.

blazor
dotnet
2 tags.
Ada Lovelace
Grace Hopper
The chips read as people; the value keeps the addresses, and so does the form.
2 tags.
not-an-address
An address that is not well formed is drawn in red.
2 tags.
low
medium
high
Each level carries a color of its own.
3 tags.

Binding, forms & validation

The value is the list of tags itself, bound two ways with @bind-Value; DefaultValue seeds an uncontrolled field read through OnChange instead. Removing the last tag leaves the value at null rather than at an empty list, which is what makes a plain [Required] catch an empty field. Inside an EditForm the field validates like any other input: it reports to the EditContext, paints the error state, marks its input with aria-invalid and turns its description red - the annotations that apply being the collection ones. Enter confirms a tag, so it is held back from submitting the form; CancelConfirmKeysOnEmpty hands it back once there is nothing left to confirm. Name posts the whole list as a single field of a plain HTML form, the tags joined by the first separator.

Tags: null
blazor
1 tags.
Tags: null

At least one tag is required.


Form submitted: False

Events

OnBeforeAdd and OnBeforeRemove run before the list changes and can call the change off with args.Cancel, which is the hook for a confirmation or a rule that lives on the server. OnBeforeAdd can also correct the tag on its way in by writing to args.Tag - the address an alias resolves to, the id a code stands for - and what it leaves there is what is added, announced and reported. OnAdd receives every tag added in one go (a paste adds several), OnRemove the one taken off, OnInvalid the one refused with the rule that refused it, and OnInput the text of the input as it is typed - which is what an external suggestion list is driven by. OnInput also reports the emptying the component does itself, so a list of your own is never left filtering on a word that is already a chip. OnTagClick turns a chip into a way in to whatever it stands for - the card of the recipient, the filter the tag is built on - without taking the focus the click already gives it, and Enter on the focused chip does the very same thing, so the way in is not one only a pointer has (unless EditableTags has claimed that key for the inline edit). OnFocusIn, OnFocusOut and OnKeyDown report the plain input events on top of them.

blazor
1 tags.
Press Enter to open, or Delete to remove.
Typing:
Last event:

Public API

The component can be driven from the outside: AddTagAsync and AddTagsAsync add through exactly the same pipeline as typing does, RemoveTagAsync and RemoveTagAtAsync take one off, MoveTagAsync moves one - raising OnReorder, and without needing AllowReorder, which offers the gesture to the user rather than permitting the list to be reordered - EditTagAsync opens the inline edit of one, SetInputTextAsync writes the text of the input (which is what fills the field from a suggestion list of your own driven by OnInput), Clear empties the list and FocusAsync puts the caret back. All of them do nothing while the field is disabled or read-only, and all go through the callbacks, the announcements and the validation the equivalent gesture does.

blazor
1 of 6 tags.
Press Enter to edit, or Delete to remove.

Cascading parameters

BitParams carries a BitTagsInputParams down to every tags input under it, so a form, a panel or a whole page sets the shared look, the shared separators and the shared rules once instead of on every field. What it carries is a default and not an override: a field that writes a parameter for itself keeps its own value, and only what it left unset is filled in from the cascade. What travels down is the configuration and never the value - Value, DefaultValue, Name, Required and ReadOnly belong to the one field that holds them, as do the templates and the event callbacks.

blazor
1 tags.
dotnet
1 tags.

Color

Color picks the role the component carries: the tags are painted with it, as much of them as the TagVariant asks for, and so are the border and the focus ring of the focused field. The error state of a failing validation always wins over it, which keeps an invalid field recognizable whatever its color is.

tag
1 tags.
tag
1 tags.
tag
1 tags.
tag
1 tags.
tag
1 tags.
tag
1 tags.
tag
1 tags.
tag
1 tags.
tag
1 tags.
tag
1 tags.
tag
1 tags.
tag
1 tags.
tag
1 tags.
tag
1 tags.
tag
1 tags.
tag
1 tags.
tag
1 tags.

External Icons

The dismiss button of each tag and the clear button of the field take their icon either from the built-in Fluent UI set, through DismissIconName and ClearButtonIconName, or from any external library through DismissIcon and ClearButtonIcon, which take a BitIconInfo built by BitIconInfo.Fa (FontAwesome), BitIconInfo.Bi (Bootstrap Icons) or BitIconInfo.Css (any CSS classes at all). The BitIconInfo wins when both are given.

blazor
dotnet
2 tags.
blazor
dotnet
2 tags.
blazor
dotnet
2 tags.

Size

Size scales the field, the chips and the text inside them together. An empty field takes the control height of its size class, so it lines up with the text fields and pickers beside it in a form, and grows from there with every line of chips that wraps into it.

blazor
dotnet
2 tags.
blazor
dotnet
2 tags.
blazor
dotnet
2 tags.

Style & Class

Style and Class reach the root element only, while Styles and Classes reach every part by name - the label, the description, the sentence a refusal is reported with, the counter, the input container, the affixes, the wrapper of the tags, each tag and its text, the reorder handle and the dismiss button with their icons, the fold chip, the input, the little edit input, the loading spinner and the clear button - plus the state slots Focused, FocusedTag, FixedTag, EditingTag (the chip being corrected), PickedUpTag (the chip waiting to be put down) and DuplicateTag (the chip a refused duplicate collided with). Prefer Classes when your CSS should own states such as hover, which inline styles cannot express.

Component's Style & Class:
blazor
1 tags.
blazor
1 tags.

Styles & Classes:
blazor
dotnet
Every part of the component has a slot of its own.
2 tags.
blazor
dotnet
Every part of the component has a slot of its own.
2 tags.


The component also reads a set of CSS variables off its elements. They inherit, so a value on :root or any ancestor re-skins every tags input below it, and one on the Style of an instance re-skins that one and any tags input nested in it. They restyle the default, not a choice: an explicit Color or Size wins over the variables for what it sets.

CSS variables:

blazor
a-very-long-tag-that-does-not-fit
dotnet
3 tags.
design
system
2 tags.
blazor
1 tags.

Set once on an ancestor, inherited by every field inside it:

blazor
1 tags.
dotnet
1 tags.

RTL

In a right-to-left direction the chips are laid out from right to left and the arrow keys swap along with them, so the key pointing at the visual left still walks towards the tag drawn there. The value keeps its logical order: the first chip is always the first tag of the list.

بلیزر
دات‌نت
با کلید Enter برچسب را ثبت کنید.
2 tags.
بلیزر
دات‌نت
2 tags.

CSS variables

The public custom properties this component reads off its root, for what no parameter covers.

Every variable is read with a fallback and never declared by the component, so it inherits like any other custom property: set one on :root (or in a [bit-theme] block) to restyle every instance, on any ancestor to restyle the ones inside it, or on the Style of one instance to restyle it - and any instance nested inside it, which inherits the value too; a parameter changes one alone, as does the real CSS property on the instance's Style / Styles when that property does not inherit (opacity: 1 keeps one disabled instance undimmed without undimming a disabled one inside it), while an inherited one such as color or font-family also reaches the nested instances that do not set it themselves. Leave a variable unset and the component falls back to the theme token beside it.

BitTagsInput CSS variables

Name Default value Description
--bit-TagsInput-font-size --bit-tpg-fs-sm Text size of the field. The helper text and the counter take theirs from --bit-TagsInput-description-font-size, and the chips from --bit-TagsInput-tag-font-size. The Size parameter wins over it.
--bit-TagsInput-color --bit-clr-fg-pri Color of the text being typed into the input.
--bit-TagsInput-placeholder-color --bit-clr-fg-sec Color of the Placeholder and the TagsPlaceholder.
--bit-TagsInput-label-color --bit-clr-fg-pri Color of the label above the field.
--bit-TagsInput-required-color --bit-clr-req Color of the asterisk a Required label carries.
--bit-TagsInput-description-color --bit-clr-fg-sec Color of the helper text under the field. The error state overrides it with the invalid color.
--bit-TagsInput-description-font-size --bit-tpg-fs-xs Text size of the helper text and of the counter under the field, a step under the field's own. The Size parameter wins over it.
--bit-TagsInput-counter-color --bit-clr-fg-sec Color of the tag counter ShowCounter draws.
--bit-TagsInput-affix-color --bit-clr-fg-sec Color of the Prefix and the Suffix.
--bit-TagsInput-background Per Variant Fill of the field: the page surface in Outline, the secondary surface in Fill, transparent in Text. Shared by the variants: --bit-TagsInput-fill-background, --bit-TagsInput-outline-background and --bit-TagsInput-text-background are read ahead of it.
--bit-TagsInput-border-color Per Variant Rule around the field at rest. Shared by the variants: --bit-TagsInput-fill-border-color, --bit-TagsInput-outline-border-color and --bit-TagsInput-text-border-color are read ahead of it.
--bit-TagsInput-hover-border-color Per Variant Rule around the hovered field (pointer devices only). Shared by the variants: --bit-TagsInput-fill-hover-border-color, --bit-TagsInput-outline-hover-border-color and --bit-TagsInput-text-hover-border-color are read ahead of it.
--bit-TagsInput-fill-background --bit-TagsInput-background Fill of the field of a Fill tags input alone, read ahead of --bit-TagsInput-background so a theme can set this variant apart from the others. The Color parameter leaves it alone.
--bit-TagsInput-fill-border-color --bit-TagsInput-border-color Rule around the field at rest of a Fill tags input alone, read ahead of --bit-TagsInput-border-color so a theme can set this variant apart from the others. The Color parameter leaves it alone.
--bit-TagsInput-fill-hover-border-color --bit-TagsInput-hover-border-color Rule around the hovered field (pointer devices only) of a Fill tags input alone, read ahead of --bit-TagsInput-hover-border-color so a theme can set this variant apart from the others. The Color parameter leaves it alone.
--bit-TagsInput-outline-background --bit-TagsInput-background Fill of the field of an Outline tags input alone, read ahead of --bit-TagsInput-background so a theme can set this variant apart from the others. The Color parameter leaves it alone.
--bit-TagsInput-outline-border-color --bit-TagsInput-border-color Rule around the field at rest of an Outline tags input alone, read ahead of --bit-TagsInput-border-color so a theme can set this variant apart from the others. The Color parameter leaves it alone.
--bit-TagsInput-outline-hover-border-color --bit-TagsInput-hover-border-color Rule around the hovered field (pointer devices only) of an Outline tags input alone, read ahead of --bit-TagsInput-hover-border-color so a theme can set this variant apart from the others. The Color parameter leaves it alone.
--bit-TagsInput-text-background --bit-TagsInput-background Fill of the field of a Text tags input alone, read ahead of --bit-TagsInput-background so a theme can set this variant apart from the others. The Color parameter leaves it alone.
--bit-TagsInput-text-border-color --bit-TagsInput-border-color Rule around the field at rest of a Text tags input alone, read ahead of --bit-TagsInput-border-color so a theme can set this variant apart from the others. The Color parameter leaves it alone.
--bit-TagsInput-text-hover-border-color --bit-TagsInput-hover-border-color Rule around the hovered field (pointer devices only) of a Text tags input alone, read ahead of --bit-TagsInput-hover-border-color so a theme can set this variant apart from the others. The Color parameter leaves it alone.
--bit-TagsInput-border-width --bit-shp-brd-width Thickness of that rule, and of the underline the Text variant keeps.
--bit-TagsInput-radius --bit-shp-radius-control Corner of the field and of its focus ring. The Text variant squares it off.
--bit-TagsInput-min-height --bit-siz-ctrl-md Smallest height of the field, which is what lines an empty tags input up with the text fields and pickers beside it. It is a floor: the field still grows with every line of chips that wraps into it. The Size parameter wins over it.
--bit-TagsInput-padding spacing(0.375) spacing(0.5) Inset between the field and the chips, the input and the affixes inside it. The Size parameter wins over it.
--bit-TagsInput-gap spacing(0.375) Room between the chips, the input and the affixes, on both axes. The Size parameter wins over it.
--bit-TagsInput-focus-color --bit-clr-pri-focus Color of the focus ring the field wears while anything inside it holds the focus. The Color parameter wins over it. While it is unset, the focus ring is the library's own --bit-shd-focus-ring, so replacing that token re-shapes it too.
--bit-TagsInput-focus-border-color --bit-clr-pri Rule around the focused field, and the focus ring of the clear button. The Color parameter wins over it.
--bit-TagsInput-invalid-color --bit-clr-err Rule and helper text of a field failing validation and its focus ring, and the mark a refused tag leaves on the field and on the chip it collided with.
--bit-TagsInput-disabled-color --bit-clr-fg-dis Text of a disabled field, of its chips, its label, its helper text and its affixes.
--bit-TagsInput-disabled-background --bit-clr-bg-dis Fill of a disabled field and of the chips in it.
--bit-TagsInput-disabled-border-color --bit-clr-brd-dis Rule of a disabled field and of the chips in it.
--bit-TagsInput-tag-color Per TagVariant, from the primary role Text of a chip, and of the chip that folds the tags away. The Color parameter wins over it. Shared by the variants: --bit-TagsInput-fill-tag-color, --bit-TagsInput-outline-tag-color and --bit-TagsInput-text-tag-color are read ahead of it.
--bit-TagsInput-tag-background Per TagVariant, from the primary role Fill of a chip. Setting it is how a field paints its chips apart from its accent. The Color parameter wins over it in the Fill tag variant; the transparent fill of Outline and Text is its alone. Shared by the variants: --bit-TagsInput-fill-tag-background, --bit-TagsInput-outline-tag-background and --bit-TagsInput-text-tag-background are read ahead of it.
--bit-TagsInput-tag-border-color Per TagVariant, from the primary role Rule of a chip, drawn in every tag variant and transparent where it is not painted, so switching variants never moves the text in a chip. The Color parameter wins over it, except over the transparent rule of Text. Shared by the variants: --bit-TagsInput-fill-tag-border-color, --bit-TagsInput-outline-tag-border-color and --bit-TagsInput-text-tag-border-color are read ahead of it.
--bit-TagsInput-fill-tag-color --bit-TagsInput-tag-color Text of a chip, and of the chip that folds the tags away in the Fill tag variant alone, read ahead of --bit-TagsInput-tag-color so a theme can set this tag variant apart from the others. The Color parameter wins over it.
--bit-TagsInput-fill-tag-background --bit-TagsInput-tag-background Fill of a chip in the Fill tag variant alone, read ahead of --bit-TagsInput-tag-background so a theme can set this tag variant apart from the others. The Color parameter wins over it.
--bit-TagsInput-fill-tag-border-color --bit-TagsInput-tag-border-color Rule of a chip in the Fill tag variant alone, read ahead of --bit-TagsInput-tag-border-color so a theme can set this tag variant apart from the others. The Color parameter wins over it.
--bit-TagsInput-outline-tag-color --bit-TagsInput-tag-color Text of a chip, and of the chip that folds the tags away in the Outline tag variant alone, read ahead of --bit-TagsInput-tag-color so a theme can set this tag variant apart from the others. The Color parameter wins over it.
--bit-TagsInput-outline-tag-background --bit-TagsInput-tag-background Fill of a chip in the Outline tag variant alone, read ahead of --bit-TagsInput-tag-background so a theme can set this tag variant apart from the others. The Color parameter leaves it alone.
--bit-TagsInput-outline-tag-border-color --bit-TagsInput-tag-border-color Rule of a chip in the Outline tag variant alone, read ahead of --bit-TagsInput-tag-border-color so a theme can set this tag variant apart from the others. The Color parameter wins over it.
--bit-TagsInput-text-tag-color --bit-TagsInput-tag-color Text of a chip, and of the chip that folds the tags away in the Text tag variant alone, read ahead of --bit-TagsInput-tag-color so a theme can set this tag variant apart from the others. The Color parameter wins over it.
--bit-TagsInput-text-tag-background --bit-TagsInput-tag-background Fill of a chip in the Text tag variant alone, read ahead of --bit-TagsInput-tag-background so a theme can set this tag variant apart from the others. The Color parameter leaves it alone.
--bit-TagsInput-text-tag-border-color --bit-TagsInput-tag-border-color Rule of a chip in the Text tag variant alone, read ahead of --bit-TagsInput-tag-border-color so a theme can set this tag variant apart from the others. The Color parameter leaves it alone.
--bit-TagsInput-tag-border-width --bit-shp-brd-width Thickness of that rule.
--bit-TagsInput-tag-radius --bit-shp-radius-chip Corner of a chip. A pill takes 999px, a square 0.
--bit-TagsInput-tag-padding 0 calc(--bit-siz-ctrl-pad-x-md / 2) Inset of a chip. The block half is 0 on purpose: the height is set by the minimum height below, so the text stays centered whatever the chip holds. The Size parameter wins over it.
--bit-TagsInput-tag-gap 0.1875rem Room between a chip's text and its dismiss button.
--bit-TagsInput-tag-font-size --bit-tpg-fs-xs Text size of a chip, which is a step under the field's own at the Medium and Large sizes. The Size parameter wins over it.
--bit-TagsInput-tag-min-height --bit-siz-chip-sm Smallest height of a chip, of the input and of the affixes, so a chip holding an icon or a template is exactly as tall as the one beside it. The Size parameter wins over it.
--bit-TagsInput-tag-max-width 100% Widest a chip grows before its text is cut off with an ellipsis. Set it to keep one long value from taking a whole line of the field.
--bit-TagsInput-tag-hover-color Per TagVariant The text of a chip an OnTagClick opens, while the pointer is over it. A chip nothing opens does not react, a target that lights up without doing anything being a promise the field does not keep. The Color parameter wins over it. Shared by the variants: --bit-TagsInput-fill-tag-hover-color, --bit-TagsInput-outline-tag-hover-color and --bit-TagsInput-text-tag-hover-color are read ahead of it.
--bit-TagsInput-tag-hover-background Per TagVariant The fill and the rule of that same chip while it is hovered. The Color parameter wins over it where the tag variant paints them. Shared by the variants: --bit-TagsInput-fill-tag-hover-background, --bit-TagsInput-outline-tag-hover-background and --bit-TagsInput-text-tag-hover-background are read ahead of it.
--bit-TagsInput-tag-focus-color Per TagVariant The inset ring of the focused chip, of the focused dismiss button and of the chip a dragged one would land on. The Color parameter wins over it. Shared by the variants: --bit-TagsInput-fill-tag-focus-color, --bit-TagsInput-outline-tag-focus-color and --bit-TagsInput-text-tag-focus-color are read ahead of it.
--bit-TagsInput-fill-tag-hover-color --bit-TagsInput-tag-hover-color The text of a chip an OnTagClick opens, while the pointer is over it in the Fill tag variant alone, read ahead of --bit-TagsInput-tag-hover-color so a theme can set this tag variant apart from the others. The Color parameter wins over it.
--bit-TagsInput-fill-tag-hover-background --bit-TagsInput-tag-hover-background The fill and the rule of that same chip while it is hovered in the Fill tag variant alone, read ahead of --bit-TagsInput-tag-hover-background so a theme can set this tag variant apart from the others. The Color parameter wins over it.
--bit-TagsInput-fill-tag-focus-color --bit-TagsInput-tag-focus-color The inset ring of the focused chip, of the focused dismiss button and of the chip a dragged one would land on in the Fill tag variant alone, read ahead of --bit-TagsInput-tag-focus-color so a theme can set this tag variant apart from the others. The Color parameter wins over it.
--bit-TagsInput-outline-tag-hover-color --bit-TagsInput-tag-hover-color The text of a chip an OnTagClick opens, while the pointer is over it in the Outline tag variant alone, read ahead of --bit-TagsInput-tag-hover-color so a theme can set this tag variant apart from the others. The Color parameter wins over it.
--bit-TagsInput-outline-tag-hover-background --bit-TagsInput-tag-hover-background The fill and the rule of that same chip while it is hovered in the Outline tag variant alone, read ahead of --bit-TagsInput-tag-hover-background so a theme can set this tag variant apart from the others. The Color parameter wins over it for the rule; the transparent fill is its alone.
--bit-TagsInput-outline-tag-focus-color --bit-TagsInput-tag-focus-color The inset ring of the focused chip, of the focused dismiss button and of the chip a dragged one would land on in the Outline tag variant alone, read ahead of --bit-TagsInput-tag-focus-color so a theme can set this tag variant apart from the others. The Color parameter wins over it.
--bit-TagsInput-text-tag-hover-color --bit-TagsInput-tag-hover-color The text of a chip an OnTagClick opens, while the pointer is over it in the Text tag variant alone, read ahead of --bit-TagsInput-tag-hover-color so a theme can set this tag variant apart from the others. The Color parameter wins over it.
--bit-TagsInput-text-tag-hover-background --bit-TagsInput-tag-hover-background The fill and the rule of that same chip while it is hovered in the Text tag variant alone, read ahead of --bit-TagsInput-tag-hover-background so a theme can set this tag variant apart from the others. The Color parameter leaves it alone.
--bit-TagsInput-text-tag-focus-color --bit-TagsInput-tag-focus-color The inset ring of the focused chip, of the focused dismiss button and of the chip a dragged one would land on in the Text tag variant alone, read ahead of --bit-TagsInput-tag-focus-color so a theme can set this tag variant apart from the others. The Color parameter wins over it.
--bit-TagsInput-tag-dragging-opacity 0.4 Alpha of the chip being dragged, which is what reads as a gap waiting to be filled rather than as a chip in two places at once.
--bit-TagsInput-dismiss-icon-size 1em Glyph of a chip's dismiss button, relative to the chip's own text by default so it scales with the chip rather than with the field.
--bit-TagsInput-reorder-icon-size 1em of the chip's text The glyph of the reorder handle AllowReorder draws on each chip.
--bit-TagsInput-icon-size --bit-siz-icon-md Glyph of the clear button, and the diameter of the spinner, at the end of the field. The Size parameter wins over it.
--bit-TagsInput-spinner-color --bit-clr-pri The turning arc of the spinner IsLoading draws. The Color parameter wins over it.
--bit-TagsInput-spinner-track-color --bit-clr-brd-sec The track that arc turns in.
--bit-TagsInput-clear-color --bit-clr-fg-sec The clear button at rest.
--bit-TagsInput-clear-hover-color --bit-clr-fg-pri The clear button under the pointer.
--bit-TagsInput-toggle-hover-color Per TagVariant Text of the hovered chip that folds and unfolds the tags MaxDisplayedTags put away. The Color parameter wins over it. Shared by the variants: --bit-TagsInput-fill-toggle-hover-color, --bit-TagsInput-outline-toggle-hover-color and --bit-TagsInput-text-toggle-hover-color are read ahead of it.
--bit-TagsInput-toggle-hover-background Per TagVariant Fill and rule of that same chip while it is hovered. The Color parameter wins over it where the tag variant paints them. Shared by the variants: --bit-TagsInput-fill-toggle-hover-background, --bit-TagsInput-outline-toggle-hover-background and --bit-TagsInput-text-toggle-hover-background are read ahead of it.
--bit-TagsInput-fill-toggle-hover-color --bit-TagsInput-toggle-hover-color Text of the hovered chip that folds and unfolds the tags in the Fill tag variant alone, read ahead of --bit-TagsInput-toggle-hover-color so a theme can set this tag variant apart from the others. The Color parameter wins over it.
--bit-TagsInput-fill-toggle-hover-background --bit-TagsInput-toggle-hover-background Fill and rule of that same chip while it is hovered in the Fill tag variant alone, read ahead of --bit-TagsInput-toggle-hover-background so a theme can set this tag variant apart from the others. The Color parameter wins over it.
--bit-TagsInput-outline-toggle-hover-color --bit-TagsInput-toggle-hover-color Text of the hovered chip that folds and unfolds the tags in the Outline tag variant alone, read ahead of --bit-TagsInput-toggle-hover-color so a theme can set this tag variant apart from the others. The Color parameter wins over it.
--bit-TagsInput-outline-toggle-hover-background --bit-TagsInput-toggle-hover-background Fill and rule of that same chip while it is hovered in the Outline tag variant alone, read ahead of --bit-TagsInput-toggle-hover-background so a theme can set this tag variant apart from the others. The Color parameter wins over it for the rule; the transparent fill is its alone.
--bit-TagsInput-text-toggle-hover-color --bit-TagsInput-toggle-hover-color Text of the hovered chip that folds and unfolds the tags in the Text tag variant alone, read ahead of --bit-TagsInput-toggle-hover-color so a theme can set this tag variant apart from the others. The Color parameter wins over it.
--bit-TagsInput-text-toggle-hover-background --bit-TagsInput-toggle-hover-background Fill and rule of that same chip while it is hovered in the Text tag variant alone, read ahead of --bit-TagsInput-toggle-hover-background so a theme can set this tag variant apart from the others. The Color parameter leaves it alone.

API

Every parameter, public member, sub-class and enum this component exposes.

BitTagsInput parameters

Name Type Default value Description
AllowReorder bool false Lets a tag be moved within the list, either by dragging it onto the position it should take or from the keyboard: Alt with the arrow keys walks the focused tag one position at a time, and Alt with Home or End sends it to either end.
AddedAnnouncementFormat string? null The format of the message announced by screen readers when a tag is added, where {0} is the tag. The default is "{0} added.". An empty string keeps the addition from being announced.
AddedManyAnnouncementFormat string? null The format of the message announced by screen readers when several tags are added at once (a pasted list, most of the time), where {0} is how many of them there were. The default is "{0} tags added.". An empty string keeps the addition from being announced. A single tag is always announced with AddedAnnouncementFormat instead.
AutoComplete string? off Sets the autocomplete html attribute of the input element. It is off by default, since the browser's own autofill would otherwise be offered over the suggestion list of the field - and what it saved for a single line text box is the last tag that was typed rather than the list the field holds.
AutoFocus bool false Whether the input should receive focus on first render.
BackspaceEditsLastTag bool false Turns the Backspace pressed on an empty input from a removal into a correction: the last tag is taken off the list and its text is put back into the input, ready to be fixed and confirmed again. NoBackspaceRemove still wins over it, the key doing nothing at all then.
CancelConfirmKeysOnEmpty bool false When true, pressing Enter while the input is empty does not suppress the event, allowing it to propagate (e.g., to submit a parent form).
CanRemoveTag Func<string, bool>? null A predicate deciding which tags the user is allowed to take off the list. A tag it turns down is drawn without a dismiss button, ignores the Delete and Backspace keys, is left alone by the Backspace pressed on the empty input, and stays behind when the field is cleared. It is still editable and still movable. RemoveTagAsync and RemoveTagAtAsync name a tag outright and are not held back by it.
Classes BitTagsInputClassStyles? null Custom CSS classes for different parts of the tags input.
ClearButtonAriaLabel string? null Accessible label of the clear button, for the benefit of screen readers and of localization. The default is "Clear all tags".
ClearButtonIcon BitIconInfo? null Gets or sets the icon of the clear button using custom CSS classes for external icon libraries. Takes precedence over ClearButtonIconName when both are set.
ClearButtonIconName string? Clear Gets or sets the name of the icon of the clear button from the built-in Fluent UI icons.
ClearButtonTitle string? null The tooltip of the clear button, which is what the pointer reads rather than the screen reader. It falls back to the ClearButtonAriaLabel and then to "Clear all tags".
ClearedAnnouncementFormat string? null The format of the message announced by screen readers when every tag is removed at once, where {0} is how many of them there were. The default is "{0} tags removed.". An empty string keeps the clearing from being announced.
ClearOnBlur bool false Throws away whatever text is still sitting in the input when the field loses the focus. It runs after the text has had its chance to become a tag, so on its own it only takes away what was refused; paired with NoAddOnBlur it makes leaving the field cancel what was being typed.
Color BitColor? null The color role of the tags input (Primary by default). It is carried by the tags themselves, the way a BitTag carries it, and by the border and the focus ring of the focused field. How much of it the tags are painted with is decided by the TagVariant. An explicit value wins over the --bit-TagsInput-* color variables it paints (the chip colors, the field's focus ring and rule, the spinner); left unset, the tags input is primary unless they say otherwise.
Comparison StringComparison StringComparison.Ordinal The string comparison used to tell one tag from another, which is what decides whether a tag is a duplicate of one that is already in the list.
DebounceTime int 0 How long, in milliseconds, the field waits for the typing to stop before raising OnInput, which turns a suggestion list fetched from a server into one request per word rather than one per keystroke. Only the callback waits: the typed text is tracked as it is typed, and an emptying the component itself caused is reported at once, taking a pending callback down with it. 0 means no wait.
Description string? null A hint rendered under the field, referenced by the input through its aria-describedby attribute so it is announced along with the field.
DescriptionTemplate RenderFragment? null A custom template rendered in place of the Description, referenced by the input through its aria-describedby attribute just the same.
DismissAriaLabelFormat string? null The format of the accessible label of the dismiss button of each tag, where {0} is the tag. The default is "Remove {0}".
DismissIcon BitIconInfo? null Gets or sets the icon for the dismiss button using custom CSS classes for external icon libraries. Takes precedence over DismissIconName when both are set.
DismissIconName string? Cancel Gets or sets the name of the icon for the dismiss button from the built-in Fluent UI icons.
DismissTitle string? null The title (tooltip) of the dismiss button of each tag. The default is "Remove".
Duplicates bool false Whether duplicate tags are allowed. Which tags count as duplicates of one another is decided by the Comparison.
EditableTags bool false Lets a tag be corrected in place: double clicking a tag (or pressing Enter or F2 on the focused one) turns it into a little input, Enter commits the new text and Escape puts the old one back. The text goes through the same rules as a tag being added, and a correction they turn down is handed back in the still open input rather than being thrown away. Committing an empty text removes the tag.
EditAriaLabelFormat string? null The format of the accessible label of the little input that replaces a tag while it is being edited in place, where {0} is the tag. The default is "Edit {0}".
EditedAnnouncementFormat string? null The format of the message announced by screen readers when a tag is edited, where {0} is the tag as it now reads. The default is "{0} updated.". An empty string keeps the edit from being announced.
EnterKeyHint BitEnterKeyHint? null Sets the enterkeyhint html attribute of the input element, which decides the label a virtual keyboard draws on its return key. The key confirms a tag here, so Done and Next are the ones that describe it on a phone.
FixedTagAriaDescription string? null The sentence announced after each tag CanRemoveTag holds in place, which answers to one gesture fewer than the others. It defaults to the built-in one - unless TagAriaDescription is set, in which case it defaults to none, since a sentence of yours written for the removable tags would promise a removal that does nothing. An empty string keeps it from being rendered.
GetInvalidMessage Func<BitTagsInputInvalidArgs, string?>? null The sentence that says why a tag was refused, for wording of your own and for localization. It receives the tag with the rule that turned it down and returns what the field announces - and draws under itself where ShowInvalidMessage is on. null falls back to the built-in sentence, an empty string keeps that refusal silent.
GetTagName Func<string, string?>? null How a tag is called wherever the component names it: the accessible name of its chip, of the dismiss button, of the reorder handle and of the inline edit, and the announcements it takes part in. It defaults to the tag itself, which a TagTemplate is exactly what breaks - a chip drawing "Ada Lovelace" over [email protected] is announced by neither without this. null falls back to the tag.
GetTagClass Func<string, string?>? null A function returning extra CSS classes for a single tag, which is what tells one chip apart from the next. It is called for every drawn tag on every render, so it should be a lookup rather than a computation, and the classes are added to those the Classes give every chip alike.
GetTagStyle Func<string, string?>? null A function returning extra inline CSS styles for a single tag, the counterpart of GetTagClass. It is appended after the Tag and FocusedTag of the Styles, so it wins over both.
InputMode BitInputMode? null Sets the inputmode html attribute of the input element, which decides the virtual keyboard a phone opens over the field. It changes nothing about what the field accepts - that is what Pattern and Validator are for - only about which keys the user is given to type it with.
IsLoading bool false Draws a spinner at the end of the field, for the wait the field itself is the cause of: the suggestions being fetched for what is being typed, the tag being checked against a server. It is an indeterminate progressbar rather than a decoration, and it changes nothing about what the field accepts.
InvalidAnnouncementFormat string? null The format of the sentence a rejection is reported with, where {0} is the tag and {1} is why it was turned down ("It is already in the list.", "A tag must be at least 3 characters."). The default is "{0} was not added. {1}". It is what screen readers announce and what ShowInvalidMessage draws. An empty string keeps a rejection from being announced.
Label string? null The label displayed above the input.
LabelTemplate RenderFragment? null A custom template for the label.
LessTagsText string? null The label of the chip that folds the tags back once MaxDisplayedTags unfolded them. The default is "Show less".
LoadingAriaLabel string? null The accessible name of the spinner IsLoading draws, which is the whole of what a screen reader has to go on. The default is "Loading".
MaxDisplayedTags int 0 The number of tags drawn before the rest of them are folded away behind a chip that says how many are left, which unfolds the list and folds it back. Only how much of the value is drawn changes, never the value itself. 0 means all of them.
MaxLength int 0 The maximum number of characters allowed for each individual tag. Text beyond it is truncated rather than rejected. 0 means no limit.
MaxSuggestions int 0 The number of values the suggestion list is allowed to offer at once. Beyond this ceiling only the values that hold what is being typed are offered, and only as many of them as it allows, which is what keeps a catalogue of thousands from being written into the page in full on every keystroke. What holds what is being typed is decided without regard to case, the way the browser filters the list it is handed - the Comparison says when two tags are the same value, which is a different question. 0 means all of them.
MaxTags int 0 The maximum number of tags allowed. Once it is reached, further tags are rejected with the MaxTags reason. 0 means no limit.
MinLength int 0 The minimum number of characters a tag has to hold to be accepted. Shorter ones are rejected with the MinLength reason. 0 means no limit.
MoreTagsFormat string? null The format of the label of the chip that stands for the tags MaxDisplayedTags folded away, where {0} is how many of them there are. The default is "+{0}".
MoreTagsAriaLabelFormat string? null The format of the accessible label of that same chip, where {0} is how many tags are folded away. The default is "Show {0} more tags", since "+3" read out on its own says nothing about what pressing it would do.
MovedAnnouncementFormat string? null The format of the message announced by screen readers when a tag is moved with AllowReorder, where {0} is the tag, {1} its new one based position and {2} the number of tags. The default is "{0} moved to position {1} of {2}.".
NoAddOnBlur bool false Stops the text left in the input from being committed as a tag when the field loses the focus.
NoAddOnTab bool false Stops the Tab key from committing the text left in the input, leaving it to do nothing but move the focus.
NoBackspaceRemove bool false Stops the Backspace key from removing the last tag when the input is empty.
NoBorder bool false Removes the default border of the tags input.
NoClearOnEscape bool false Leaves the Escape key alone, so that it takes back neither the text being typed nor the tags the clear button would empty - which hands the key back to the modal or the callout the field sits in.
NoInvalidHighlight bool false Stops the field from marking a tag it refused. The mark is what makes a rejection visible to everyone rather than only to a screen reader: the field wears its invalid color until the user types again, and a tag refused as a duplicate marks the one already in the list that it collided with.
NoTrim bool false Keeps the leading and trailing whitespace of a tag instead of trimming it away.
OnAdd EventCallback<IReadOnlyList<string>> Callback for when one or more tags are added. Receives the list of all newly added tags.
OnBeforeAdd EventCallback<BitTagsInputBeforeArgs> Callback invoked before a tag is added, carrying the tag every rule has already accepted. Set args.Cancel = true to call the add off, or write to args.Tag to correct the text on its way in - what the handler leaves there is what is added, announced and reported through OnAdd.
OnBeforeRemove EventCallback<BitTagsInputBeforeArgs> Callback invoked before a tag is removed. Set args.Cancel = true to cancel the remove.
OnBeforeClear EventCallback<BitTagsInputClearArgs> Callback invoked before every tag is removed at once, by the clear button, the Escape key or the Clear method, carrying the whole list that is about to go. Set args.Cancel = true to leave it as it is.
OnClear EventCallback<IReadOnlyList<string>> Callback for when every tag is removed at once, by the clear button or by the Clear method. It receives the tags that were removed.
OnEdit EventCallback<BitTagsInputEditArgs> Callback invoked when an inline edit of a tag is about to be committed, carrying both the old and the new text. Set args.Cancel = true to leave the tag as it was.
OnFocusIn EventCallback<FocusEventArgs> Callback for when the input receives focus.
OnFocusOut EventCallback<FocusEventArgs> Callback for when the input loses focus.
OnInput EventCallback<string> Callback for when the text of the input changes, which is what an external suggestion list is driven by.
OnInvalid EventCallback<BitTagsInputInvalidArgs> Callback for when a tag is rejected, carrying the tag along with the rule that rejected it.
OnKeyDown EventCallback<KeyboardEventArgs> Callback for when a key is pressed down on the input. It is invoked for every key, including the ones the component handles itself.
OnRemove EventCallback<string> Callback for when a tag is removed.
OnReorder EventCallback<BitTagsInputReorderArgs> Callback for when a tag is moved within the list with AllowReorder, carrying the tag along with the positions it left and took.
OnTagClick EventCallback&lt;string&gt; Callback for when a tag is clicked, carrying the tag. It changes nothing about what the click already does, the tag still taking the focus; the dismiss button is not a click on the tag, and neither is the second click of the double click that opens the inline edit. Enter on the focused chip does the same, unless EditableTags has claimed that key for the inline edit.
OnTagExists EventCallback<string> Callback fired when a duplicate tag is attempted and Duplicates is false.
Pattern string? null A regular expression that every tag has to match to be accepted. An unusable expression is ignored rather than breaking the input.
PickedUpAnnouncementFormat string? null The format of the message announced by screen readers when a tag is picked up with its reorder handle, where {0} is the tag. The default names the tag and says how to put it down. An empty string keeps the pick up from being announced.
Placeholder string? null The placeholder text of the input, shown while there is no tag in the list.
Prefix string? null A short text drawn at the start of the field, in front of the tags, which is not part of the value: the "To:" of a recipients field, the "#" of a hashtag one. It is announced with the field, the input referencing it along with the Suffix and the Description.
PrefixTemplate RenderFragment? null A custom template drawn in place of the Prefix.
PutBackAnnouncementFormat string? null The format of the message announced by screen readers when a picked up tag is put back where it came from, where {0} is the tag. The default is "{0} put back.".
RemovedAnnouncementFormat string? null The format of the message announced by screen readers when a tag is removed, where {0} is the tag. The default is "{0} removed.". An empty string keeps the removal from being announced.
ReorderAriaLabelFormat string? null The format of the accessible label of the reorder handle of each tag, where {0} is the tag. The default is "Move {0}".
ReorderDropAriaLabelFormat string? null The format of the accessible label the other reorder handles take while one tag is picked up, where {0} is the tag being carried. The default is "Move {0} here".
ReorderIcon BitIconInfo? null The icon of the reorder handle, as custom CSS classes for external icon libraries. It takes precedence over ReorderIconName.
ReorderIconName string? null The name of the icon of the reorder handle from the built-in Fluent UI icons. It defaults to GripperBarVertical.
ReorderTitle string? null The title (tooltip) of the reorder handle of each tag. The default is "Move".
RestrictToSuggestions bool false Turns the Suggestions into the whole of what the field accepts: a tag that is not one of them is rejected with the NotSuggested reason, which is what a datalist on its own cannot do since it suggests rather than restricts.
Separators IEnumerable<string>? null The character(s) that turn the typed text into a tag on top of the Enter key, which is the only one there is by default. The very same separators split a pasted list into a tag each, and a pasted text holding line breaks is joined over the first of them before it is split.
ShowClearButton bool false Whether to render a button that removes every tag at once. It stays out of the tab order, the Escape key being its keyboard equivalent.
ShowCounter bool false Whether to render the number of tags under the field, next to the Description, as a plain count or as "count / MaxTags" when there is a ceiling to reach.
ShowInvalidMessage bool false Draws the sentence saying why the last tag was refused under the field, in the invalid color, where the Description otherwise stands - so the refusal is read rather than only seen as a red rule. It is the very sentence a screen reader is given, and it stands until the next keystroke answers it.
Size BitSize? null The size of the tags input. An explicit value wins over the --bit-TagsInput-* size variables (font sizes, min heights, paddings, gap, icon size); left unset, the tags input is medium unless they say otherwise.
SpellCheck bool? false Sets the spellcheck html attribute of the input, and of the little input an inline edit opens. It is off by default, a tag being a value rather than a sentence - an identifier or a hashtag underlined in red says only that the dictionary has not heard of it.
Suggestions IEnumerable<string>? null The values offered to the user while typing, through the suggestion list the browser itself renders for a datalist. Picking one fills the input; the usual Enter (or a separator) turns it into a tag, so every validation rule still applies. Values already in the list are left out unless Duplicates allows them back in, and all of them are once the MaxTags ceiling is reached. See RestrictToSuggestions to make them the only accepted values.
Styles BitTagsInputClassStyles? null Custom CSS styles for different parts of the tags input.
Suffix string? null A short text drawn at the end of the field, after everything else, which is not part of the value: the unit of a list of measurements. Like the Prefix it is announced with the field, the input referencing it.
SuffixTemplate RenderFragment? null A custom template drawn in place of the Suffix.
TagTemplate RenderFragment<string>? null A custom template for rendering each tag.
TagAriaDescription string? null The sentence announced after each tag, telling what the keyboard can do with the one that has just been reached. It defaults to a sentence built from what the component was actually given (the inline edit, the reordering, a click that opens the chip), and is left out entirely when there is none. An empty string keeps it from being rendered at all.
TagCountAriaDescriptionFormat string? null The format of the sentence describing the input, where {0} is how many tags the list already holds and {1} the MaxTags ceiling (0 when there is none). The default is "{0} tags." - or "{0} of {1} tags." where there is a ceiling. It is referenced by the input rather than announced, so it is read on arriving in a field that is not empty. An empty string leaves it out.
TagsAriaLabel string? null The accessible name of the list the tags form, which is what a screen reader announces before walking through them. The default is "Tags".
TagsPlaceholder string? null The placeholder text of the input shown once there is at least one tag in the list, where the Placeholder would otherwise be replaced by nothing at all.
TagVariant BitVariant? null How much of the Color the tags are painted with: Fill (the default) fills each chip with it, the way a BitTag is filled, Outline leaves the chip unfilled and draws the color as its rule and its text, and Text keeps only the text in it. It is independent of the Variant, which is about the frame of the field rather than the tags in it.
ThrottleTime int 0 How long, in milliseconds, OnInput waits between two raises while the typing goes on, for a suggestion list that should keep up with the word rather than only answer once it is finished. DebounceTime wins over it when both are set. 0 means no limit.
Transformer Func<string, string>? null A function applied to the text of a tag before anything else is done with it, which normalizes the tags of a list that has to stay consistent. It runs before every validation rule.
Validator Func<string, bool>? null A predicate every tag has to satisfy to be accepted, for the rules a regular expression cannot express. Returning false rejects the tag with the Validator reason.
Variant BitVariant? null The visual variant of the field: an outline (the default), a filled surface, or only an underline.

BitTagsInput public members

Name Type Default value Description
InputElement ElementReference The ElementReference to the input element of the BitTagsInput.
FocusAsync ValueTask Gives focus to the input element of the BitTagsInput.
AddTagAsync Task Adds a tag through exactly the same pipeline as typing it does: the trimming, the Transformer, every validation rule and every callback included. It does nothing while the component is disabled or read-only.
AddTagsAsync Task Adds several tags at once, exactly as pasting a separated list of them does. The rejected ones are reported through OnInvalid while the rest are still added.
RemoveTagAsync Task Removes the first tag equal to the given one (per the Comparison), exactly as its dismiss button does.
RemoveTagAtAsync Task Removes the tag sitting at the given index.
MoveTagAsync Task Moves the tag sitting at the given index to another one, exactly as dragging it there or walking it with Alt and the arrow keys does, raising OnReorder along with it. Unlike the gestures, it does not require AllowReorder.
EditTagAsync Task Opens the inline edit of the tag sitting at the given index, exactly as double clicking it does. It requires EditableTags.
SetInputTextAsync Task Sets the text of the input, which is what fills the field from a suggestion list of your own driven by OnInput - and what empties it again once the pick has been turned into a tag. The MaxLength is applied to it and OnInput is raised with the text that was kept.
Clear Task Removes all tags along with the text left in the input, and raises OnClear with the tags that were removed.

BitInputBase parameters

Name Type Default value Description
DefaultValue TValue? null The default value of the input to be used in uncontrolled mode (i.e. when the Value is not bound), typically used alongside the OnChange callback.
DisplayName string? null Gets or sets the display name for this field.
InputHtmlAttributes IReadOnlyDictionary<string, object>? null Gets or sets a collection of additional attributes that will be applied to the created element.
Name string? null Gets or sets the name of the element. Allows access by name from the associated form.
NoValidate bool false Disables the validation of the input.
OnChange EventCallback<TValue?> Callback for when the input value changes.
ReadOnly bool false Makes the input read-only.
Required bool false Makes the input required.
Value TValue? null Gets or sets the value of the input. This should be used with two-way binding.

BitInputBase public members

Name Type Default value Description
InputElement ElementReference The ElementReference of the input element.
FocusAsync() () => ValueTask Gives focus to the input element.
FocusAsync(bool preventScroll) (bool preventScroll) => ValueTask Gives focus to the input element.

BitComponentBase parameters

Name Type Default value Description
AriaLabel string? null Gets or sets the accessible label for the component, used by assistive technologies.
Class string? null Gets or sets the CSS class name(s) to apply to the rendered element.
Dir BitDir? null Gets or sets the text directionality for the component's content.
Disabled bool false Gets or sets a value indicating whether the component is disabled and cannot respond to user interaction.
ForceAnimation bool false Gets or sets a value indicating whether the component's animations play at their full duration even when reduced motion is requested.
HtmlAttributes Dictionary<string, object> new Dictionary<string, object>() Captures additional HTML attributes to be applied to the rendered element, in addition to the component's parameters. An attribute written on the component wins over an entry of the same name.
Id string? null Gets or sets the unique identifier for the component's root element.
Style string? null Gets or sets the CSS style string to apply to the rendered element.
TabIndex string? null Gets or sets the tab order index for the component when navigating with the keyboard.
Visibility BitVisibility BitVisibility.Visible Gets or sets the visibility state (visible, hidden, or collapsed) of the component.

BitComponentBase public members

Name Type Default value Description
UniqueId Guid Guid.NewGuid() Gets the readonly unique identifier for the component's root element, assigned when the component instance is constructed.
RootElement ElementReference Gets the reference to the root HTML element associated with this component.

BitTagsInputBeforeArgs properties

Arguments passed to the OnBeforeAdd and OnBeforeRemove callbacks.

Name Type Default value Description
Tag string string.Empty The tag text being added or removed, after the trimming and the transformation. On an add it is also what the handler hands back: what is written to it is what the list is given, exactly as an OnEdit handler corrects a tag on its way in. Leaving it empty is not a way to call the add off, which is what Cancel is for.
Cancel bool false Set to true to cancel the add or remove operation.

BitTagsInputInvalidArgs properties

Arguments passed to the OnInvalid callback, describing the tag that was rejected along with the rule that rejected it.

Name Type Default value Description
Tag string string.Empty The tag text that was rejected, after the trimming and the transformation were applied to it.
Reason BitTagsInputInvalidReason BitTagsInputInvalidReason.None The rule that rejected the tag.

BitTagsInputEditArgs properties

Arguments passed to the OnEdit callback, describing an inline edit of a tag that is about to be committed.

Name Type Default value Description
Tag string string.Empty The tag as it stands in the list, before the edit.
NewTag string string.Empty The text the tag is about to become, after the trimming and the transformation were applied to it.
Cancel bool false Set to true to cancel the edit, leaving the tag as it was.

BitTagsInputClearArgs properties

Arguments passed to the OnBeforeClear callback, describing the whole list that is about to be emptied.

Name Type Default value Description
Tags IReadOnlyList<string> [] The tags that are about to be removed.
Cancel bool false Set to true to cancel the clear, leaving every tag in the list.

BitTagsInputReorderArgs properties

Arguments passed to the OnReorder callback, describing a tag that was moved within the list.

Name Type Default value Description
Tag string string.Empty The tag that was moved.
OldIndex int 0 The zero based position the tag was moved from.
NewIndex int 0 The zero based position the tag was moved to.

BitTagsInputClassStyles properties

Name Type Default value Description
Root string? null Custom CSS classes/styles for the root element of the tags input.
Focused string? null Custom CSS classes/styles for the focus state of the tags input.
Label string? null Custom CSS classes/styles for the label of the tags input.
InputContainer string? null Custom CSS classes/styles for the input container of the tags input.
Prefix string? null Custom CSS classes/styles for the prefix of the tags input.
Suffix string? null Custom CSS classes/styles for the suffix of the tags input.
TagsContainer string? null Custom CSS classes/styles for the element that wraps the rendered tags.
Tag string? null Custom CSS classes/styles for each tag element.
FocusedTag string? null Custom CSS classes/styles for the tag element that currently has the keyboard focus.
FixedTag string? null Custom CSS classes/styles for a tag the CanRemoveTag predicate holds in place, which carries no dismiss button of its own.
EditingTag string? null Custom CSS classes/styles for the tag that is currently being corrected in place, which carries the little edit input instead of its text.
PickedUpTag string? null Custom CSS classes/styles for the tag that has been picked up with its reorder handle and is waiting to be put down.
DuplicateTag string? null Custom CSS classes/styles for the tag a refused duplicate collided with, which is marked until the user types again.
TagText string? null Custom CSS classes/styles for the tag text.
ReorderButton string? null Custom CSS classes/styles for the reorder handle AllowReorder draws on each tag.
ReorderIcon string? null Custom CSS classes/styles for the icon of that reorder handle.
DismissButton string? null Custom CSS classes/styles for the dismiss button of each tag.
DismissIcon string? null Custom CSS classes/styles for the dismiss icon of each tag.
ToggleButton string? null Custom CSS classes/styles for the chip that stands for the tags MaxDisplayedTags folded away, which unfolds the list and folds it back.
Input string? null Custom CSS classes/styles for the text input element.
EditInput string? null Custom CSS classes/styles for the little input that replaces a tag while it is being edited in place.
Counter string? null Custom CSS classes/styles for the counter of the tags input.
Spinner string? null Custom CSS classes/styles for the spinner IsLoading draws at the end of the field.
ClearButton string? null Custom CSS classes/styles for the clear button of the tags input.
ClearIcon string? null Custom CSS classes/styles for the clear icon of the tags input.
Description string? null Custom CSS classes/styles for the description (helper text) of the tags input.
InvalidMessage string? null Custom CSS classes/styles for the sentence ShowInvalidMessage draws under the field when a tag is refused, which stands where the description otherwise would.

BitIconInfo properties

Name Type Default value Description
Name string? null Gets or sets the name of the icon.
BaseClass string? null Gets or sets the base CSS class for the icon. For built-in Fluent UI icons, this defaults to "bit-icon". For external icon libraries like FontAwesome, you might set this to "fa" or leave empty.
Prefix string? null Gets or sets the CSS class prefix used before the icon name. For built-in Fluent UI icons, this defaults to "bit-icon--". For external icon libraries, you might set this to "fa-" or leave empty.

BitTagsInputInvalidReason enum

Name Value Description
None 0 No reason was given, which is what an uninitialized value stands for rather than an actual rule.
Duplicate 1 The tag is already in the list and duplicates are not allowed.
MaxTags 2 The list already holds the maximum number of tags.
MinLength 3 The tag is shorter than the minimum length.
Pattern 4 The tag does not match the required pattern.
Validator 5 The tag was rejected by the custom validator.
NotSuggested 6 The tag is not one of the suggestions, which RestrictToSuggestions made the only accepted values.

BitInputMode enum

Name Value Description
None 0 No virtual keyboard. For when the page implements its own keyboard input control.
Text 1 Standard input keyboard for the user's current locale.
Decimal 2 Fractional numeric input keyboard containing the digits and decimal separator for the user's locale.
Numeric 3 Numeric input keyboard, but only requires the digits 0–9.
Tel 4 A telephone keypad input, including the digits 0–9, the asterisk (*), and the pound (#) key.
Search 5 A virtual keyboard optimized for search input.
Email 6 A virtual keyboard optimized for entering email addresses.
Url 7 A keypad optimized for entering URLs.

BitEnterKeyHint enum

Name Value Description
Enter 0 Typically inserting a new line.
Done 1 Typically meaning there is nothing more to input and the input method editor will be closed.
Go 2 Typically meaning to take the user to the target of the text they typed.
Next 3 Typically taking the user to the next field that will accept text.
Previous 4 Typically taking the user to the previous field that will accept text.
Search 5 Typically taking the user to the results of searching for the text they have typed.
Send 6 Typically delivering the text to its target.

BitVariant enum

Name Value Description
Fill 0 Fill styled variant.
Outline 1 Outline styled variant.
Text 2 Text styled variant.

BitSize enum

Name Value Description
Small 0 The small size.
Medium 1 The medium size.
Large 2 The large size.

BitColor enum

Name Value Description
Primary 0 Primary general color.
Secondary 1 Secondary general color.
Tertiary 2 Tertiary general color.
Info 3 Info general color.
Success 4 Success general color.
Warning 5 Warning general color.
SevereWarning 6 SevereWarning general color.
Error 7 Error general color.
PrimaryBackground 8 Primary background color.
SecondaryBackground 9 Secondary background color.
TertiaryBackground 10 Tertiary background color.
PrimaryForeground 11 Primary foreground color.
SecondaryForeground 12 Secondary foreground color.
TertiaryForeground 13 Tertiary foreground color.
PrimaryBorder 14 Primary border color.
SecondaryBorder 15 Secondary border color.
TertiaryBorder 16 Tertiary border color.

BitVisibility enum

Name Value Description
Visible 0 The content of the component is visible.
Hidden 1 The content of the component is hidden, but the space it takes on the page remains (visibility:hidden).
Collapsed 2 The component is hidden (display:none).

BitDir enum

Name Value Description
Ltr 0 Ltr (left to right) is to be used for languages that are written from the left to the right (like English).
Rtl 1 Rtl (right to left) is to be used for languages that are written from the right to the left (like Arabic).
Auto 2 Auto lets the user agent decide. It uses a basic algorithm as it parses the characters inside the element until it finds a character with a strong directionality, then applies that directionality to the whole element.

Feedback

Found a mistake, a gap, or something that could be clearer? Every page and every component is one click from its source.