Skip to content
# TagsInput **Also known as:** Chips, Tokens ## Description 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. ## 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. | | 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. | | 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. | ## 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. | | 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. | | 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. | ## Enums ### 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. | ## Sub Classes ### 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. | ## CSS Variables Public CSS custom properties read off the component's root. Set one on `:root` to restyle every instance, on any ancestor to restyle the ones inside it, or on the `Style` of one instance to restyle it and every instance nested inside it, which inherits the value too - a parameter changes one alone, as does the real CSS property on its `Style` / `Styles` when that property does not inherit (`opacity`); an inherited one (`color`, `font-family`) reaches the nested instances that do not set it themselves. | 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. | ## Examples \n**Basic**: ```razor ``` \n**Label & description**: ```razor Custom label Separate the addresses with a comma or a semicolon. ``` \n**Variants**: ```razor ``` \n**Separators & pasting**: ```razor ``` \n**Suggestions**: ```razor ``` ```csharp private readonly string[] frameworkSuggestions = ["blazor", "react", "vue", "angular", "svelte"]; private readonly string[] countrySuggestions = ["Argentina", "Australia", "Austria", "Belgium", "Brazil", "Canada", "Chile", "China", "Denmark", "Egypt", "Finland", "France", "Germany", "Greece", "India", "Indonesia", "Iran", "Ireland", "Italy", "Japan", "Mexico", "Morocco", "Netherlands", "New Zealand", "Norway", "Poland", "Portugal", "Spain", "Sweden", "Switzerland", "Turkey", "Ukraine"]; private bool asyncLoading; private int asyncRequestId; private string[] asyncSuggestions = []; private async Task HandleAsyncInput(string text) { // Only the answer to the last keystroke is kept: an earlier fetch coming back late // would otherwise replace a newer list and turn the spinner off over a newer wait. var id = ++asyncRequestId; if (string.IsNullOrEmpty(text)) { asyncLoading = false; asyncSuggestions = []; return; } asyncLoading = true; StateHasChanged(); await Task.Delay(500); if (id != asyncRequestId) return; asyncSuggestions = [.. countrySuggestions.Where(c => c.Contains(text, StringComparison.OrdinalIgnoreCase))]; asyncLoading = false; StateHasChanged(); } ``` \n**Limits & counter**: ```razor ``` ```csharp private ICollection? maxTagsValue = ["blazor"]; ``` \n**Rules & normalization**: ```razor ``` ```csharp private const string emailPattern = @"^[^@\s]+@[^@\s]+\.[^@\s]+$"; private static string NormalizeHashtag(string tag) { return string.Concat(tag.TrimStart('#').Where(c => char.IsWhiteSpace(c) is false)).ToLowerInvariant(); } // null leaves the built-in sentence in place, so only the pattern is worded here. private static string? GetEmailInvalidMessage(BitTagsInputInvalidArgs args) { return args.Reason == BitTagsInputInvalidReason.Pattern ? $"'{args.Tag}' is not an email address." : null; } private static bool ValidateFramework(string tag) { return tag is "blazor" or "react" or "vue" or "angular"; } ``` \n**Editable tags**: ```razor @if (editMessage.HasValue()) {
@editMessage
} ``` ```csharp private string? editMessage; private void HandleEdit(BitTagsInputEditArgs args) { editMessage = $"'{args.Tag}' became '{args.NewTag}'."; // args.Cancel = true; would leave the tag as it was, // and args.NewTag can be corrected on its way in. } ``` \n**Reordering**: ```razor @if (reorderMessage.HasValue()) {
@reorderMessage
} ``` ```csharp private string? reorderMessage; private void HandleReorder(BitTagsInputReorderArgs args) { reorderMessage = $"'{args.Tag}' moved from position {args.OldIndex + 1} to {args.NewIndex + 1}."; } ``` \n**Folding the tags away**: ```razor ``` \n**Clear button**: ```razor @if (clearedMessage.HasValue()) {
@clearedMessage
} @if (beforeClearMessage.HasValue()) {
@beforeClearMessage
} ``` ```csharp private string? clearedMessage; private string? beforeClearMessage; private void HandleClear(IReadOnlyList tags) { clearedMessage = $"Cleared {tags.Count} tag(s)."; } private void HandleBeforeClear(BitTagsInputClearArgs args) { if (args.Tags.Count > 2) { args.Cancel = true; beforeClearMessage = $"Clearing {args.Tags.Count} tags was refused. Remove a few of them first."; } else { beforeClearMessage = $"Cleared {args.Tags.Count} tag(s)."; } } ``` \n**Fixed tags**: ```razor
Tags: @(fixedTags is not null ? string.Join(", ", fixedTags) : "null")
``` ```csharp private ICollection? fixedTags = ["[email protected]", "[email protected]"]; ``` \n**Keyboard & typing**: ```razor ``` \n**Accessibility & localization**: ```razor ``` \n**Prefix & Suffix**: ```razor ``` \n**Tag template & per-tag styling**: ```razor @tag @GetPersonName(tag) ``` ```csharp private const string emailPattern = @"^[^@\s]+@[^@\s]+\.[^@\s]+$"; private static string? GetRecipientStyle(string tag) { return Regex.IsMatch(tag, emailPattern) ? null : "background: #fde7e9; color: #a4262c; border-color: #a4262c;"; } private static string? GetPriorityClass(string tag) => tag.ToLowerInvariant() switch { "high" => "priority-high", "medium" => "priority-medium", "low" => "priority-low", _ => null }; // A template draws the person rather than the address, so the chip is named the same way - // otherwise it is announced by neither the markup nor the value behind it. private static string GetPersonName(string tag) => tag switch { "[email protected]" => "Ada Lovelace", "[email protected]" => "Grace Hopper", _ => tag }; ``` \n**Binding, forms & validation**: ```razor
Tags: @(boundTags is not null ? string.Join(", ", boundTags) : "null")
Tags: @(changedTags is not null ? string.Join(", ", changedTags) : "null")
Submit
Form submitted: @formSubmitted
``` ```csharp public class ValidationTagsInputModel { [Required(ErrorMessage = "At least one tag is required.")] public ICollection? Tags { get; set; } } private ICollection? boundTags; private ICollection? changedTags; private bool formSubmitted; private readonly ValidationTagsInputModel validationModel = new(); private void HandleValidSubmit() => formSubmitted = true; ``` \n**Events**: ```razor
Typing: @typedText
Last event: @eventsLog
``` ```csharp private string? typedText; private string? eventsLog; private void HandleBeforeAdd(BitTagsInputBeforeArgs args) { if (args.Tag.Equals("block", StringComparison.OrdinalIgnoreCase)) { args.Cancel = true; eventsLog = $"Adding '{args.Tag}' was cancelled by OnBeforeAdd."; return; } // An alias the server knows the real spelling of: what the handler leaves in // args.Tag is what the list is given. if (args.Tag.Equals("me", StringComparison.OrdinalIgnoreCase)) { args.Tag = "[email protected]"; eventsLog = "OnBeforeAdd resolved 'me' to [email protected]."; } } private void HandleBeforeRemove(BitTagsInputBeforeArgs args) { eventsLog = $"Removing '{args.Tag}'..."; } private void HandleAdd(IReadOnlyList tags) { eventsLog = $"Added: {string.Join(", ", tags)}"; } private void HandleRemove(string tag) { eventsLog = $"Removed: {tag}"; } private void HandleInvalid(BitTagsInputInvalidArgs args) { eventsLog = $"Rejected '{args.Tag}' ({args.Reason})"; } private void HandleTagClick(string tag) { eventsLog = $"Clicked: {tag}"; } ``` \n**Public API**: ```razor Add "dotnet" Add "web" & "ui" Remove "dotnet" Remove first Move first to the end Edit first Type "razor" into the input Clear Focus ``` ```csharp private BitTagsInput apiTagsInput = default!; private Task ApiAddTag() => apiTagsInput.AddTagAsync("dotnet"); private Task ApiAddTags() => apiTagsInput.AddTagsAsync(["web", "ui"]); private Task ApiRemoveTag() => apiTagsInput.RemoveTagAsync("dotnet"); private Task ApiRemoveFirst() => apiTagsInput.RemoveTagAtAsync(0); private Task ApiMoveFirstToEnd() => apiTagsInput.MoveTagAsync(0, (apiTagsInput.Value?.Count ?? 1) - 1); private Task ApiEditFirst() => apiTagsInput.EditTagAsync(0); private Task ApiSetInputText() => apiTagsInput.SetInputTextAsync("razor"); private Task ApiClear() => apiTagsInput.Clear(); private async Task ApiFocus() => await apiTagsInput.FocusAsync(); ``` \n**Cascading parameters**: ```razor ``` ```csharp private readonly List tagsInputParams = [ new BitTagsInputParams { Size = BitSize.Small, Variant = BitVariant.Fill, TagVariant = BitVariant.Outline, Color = BitColor.Info, Separators = [","], ShowClearButton = true, Placeholder = "Add tag...", Transformer = t => t.ToLowerInvariant() } ]; ``` \n**Color**: ```razor ``` \n**External Icons**: ```razor ``` \n**Size**: ```razor ``` \n**Style & Class**: ```razor @* CSS variables *@ @* Set once on an ancestor, inherited by every field inside it *@
``` \n**RTL**: ```razor ```