This component is currently in an early preview state and may change in the future. This process allows us to gather feedback and make improvements before the component is considered stable. If you have any feedback or suggestions, please open an issue.
Overview
The Tag Input component provides a flexible and customizable way to create and manage a list of tags/chips.
Key Features
Compound Component Structure: Offers a set of sub-components that work together to create a fully-featured tag input.
Accessibility: Built-in ARIA attributes and keyboard navigation support.
Customizable: Each sub-component can be styled and configured independently.
Custom Validation: Validate the tags input's value before adding them to the list.
Architecture
The Tags Input component is composed of several sub-components, each with a specific role:
Root: The main container component that manages the state and context for the tags input.
List: The container for the tag input's tags.
Tag: The container for a single tag within the tags input. Responsible for managing the tag's state and interactions
TagContent: The content of the tag, which typically includes the tag text and edit/remove buttons and does not include the edit input.
TagText: The text content of the tag.
TagRemove: The button responsible for removing the tag.
TagEdit: The input element which should be displayed in place of the tag when it is being edited.
Input: The main input field for the tags input, which can be used to add new tags.
Clear: A button used to clear all tags from the tags input.
Structure
Here's an overview of how the Tags Input component is structured in code:
Managing Value State
Bits UI offers several approaches to manage and synchronize the Tag Input's value state, catering to different levels of control and integration needs.
1. Two-Way Binding
For seamless state synchronization, use Svelte's bind:value directive. This method automatically keeps your local state in sync with the component's internal state.
Key Benefits
Simplifies state management
Automatically updates myValue when the internal state changes
Allows external control (e.g., updating the value via a separate button)
2. Change Handler
For more granular control or to perform additional logic on state changes, use the onValueChange prop. This approach is useful when you need to execute custom logic alongside state updates.
Use Cases
Implementing custom behaviors on value change
Integrating with external state management solutions
Triggering side effects (e.g., logging, data fetching)
3. Fully Controlled
For complete control over the component's value state, use the controlledValue prop. This approach requires you to manually manage the value state, giving you full control over when and how the component responds to value change events.
To implement controlled state:
Set the controlledValue prop to true on the TagsInput.Root component.
Provide a value prop to TagsInput.Root, which should be a variable holding the current state.
Implement an onValueChange handler to update the state when the internal state changes.
When to Use
Implementing complex logic
Coordinating multiple UI elements
Debugging state-related issues
Note
While powerful, fully controlled state should be used judiciously as it increases complexity and can cause unexpected behaviors if not handled carefully.
For more in-depth information on controlled components and advanced state management techniques, refer to our Controlled State documentation.
Delimiters
Delimiters are used to split the input value into multiple tags when a user types them or pastes them into the input.
By default, a single delimiter is used ',', so when a user types or pastes a,b,c, the input value will be split into three tags: a, b, and c.
You can customize the delimiters used by setting the delimiters prop on the TagsInput.Root component.
Validation
You can use the validate prop to validate the tag input's value before adding it to the list. The validate prop should return true if the value is valid, and false if it is invalid.
This single function enables you to validate a number of different scenarios, such as ensuring the value is not empty, ensuring it doesn't contain any invalid characters, or ensuring it doesn't exceed a certain length.
The following examples show how you might use the validate prop to implement these scenarios.
Maximum Tags
The validate prop can also be used to limit the maximum number of tags that can be added to the list.
Prevent Duplicate Tags
You can also use the validate prop to prevent duplicate tags from being added to the list.
Edit Modes
The editMode prop on the TagsInput.Tag component determines how the tag is editable. It can be set to one of the following values: 'input', 'contenteditable', or 'none'. The default value is 'input'.
'input': the tag will be editable using the TagsInput.TagEdit component, which is an input element.
'contenteditable': the tag will be editable using the contenteditable attribute on the TagsInput.TagText component.
'none': the tag will not be editable.
Examples
Input
The main demo at the top of this page shows an example of the default editMode of 'input'.
Content Editable
The demo below shows an example of the editMode of 'contenteditable'. Try double-clicking on a tag to edit it.
hello
world
Blur Behavior
The blurBehavior prop determines how the input field is handled when it is blurred. It can be set to one of the following values: 'clear', 'add', or 'none'. The default value is 'none'.
'none': the input field will not be cleared or modified when it is blurred, it will behave as an input normally would.
'clear': the input field will be cleared when it is blurred.
'add': the input field will be cleared and the value will be added as a new tag when it is blurred.
Paste Behavior
The pasteBehavior prop determines how the input field is handled when text is pasted into it.
It can be set to one of the following values: 'add' or 'none'.
'add': the pasted text will be added as a new tag when it is pasted into the input field.
'none': the pasted text will not be automatically added as a new tag when it is pasted into the input field.
API Reference
TagsInput.Root
An enhanced label component that can be used with any input.
Property
Type
Description
value$bindable
string[]
The value of the tags input. An array of tag values/strings.
Default: []
onValueChange
function
A callback function called when the active accordion item value changes. If the type is 'single', the argument will be a string. If type is 'multiple', the argument will be an array of strings.
Default: ——undefined
controlledValue
boolean
Whether or not the value is controlled or not. If true, the component will not update the value state internally, instead it will call onValueChange when it would have otherwise, and it is up to you to update the value prop that is passed to the component. See Controlled State for more information.
Default: false
delimiters
string[]
An array of delimiters to use to splitting the input value.
Default: [',']
validate
function
A validation function to determine if the individual tag being added/edited is valid. Return true to allow the tag to be added/edited, or false to prevent it from being added/confirm edited.
Default: ——undefined
name
string
If provided, a hidden input element will be rendered for each tag to submit the values with a form.
Default: ——undefined
required
boolean
Whether or not the hidden input element should be marked as required or not.
Default: false
ref$bindable
HTMLDivElement
The underlying DOM element being rendered. You can bind to this to get a reference to the element.
Default: ——undefined
children
Snippet
The children content to render.
Default: ——undefined
child
Snippet
Use render delegation to render your own element. See Child Snippet docs for more information.
Default: ——undefined
Data Attribute
Value
Description
data-tags-input-root
''
Present on the root element.
TagsInput.List
The container for the tags.
Property
Type
Description
ref$bindable
HTMLDivElement
The underlying DOM element being rendered. You can bind to this to get a reference to the element.
Default: ——undefined
children
Snippet
The children content to render.
Default: ——undefined
child
Snippet
Use render delegation to render your own element. See Child Snippet docs for more information.
Default: ——undefined
Data Attribute
Value
Description
data-invalid
''
Present on the list element when the tags input is invalid.
data-tags-input-list
''
Present on the list element.
TagsInput.Tag
The container for a single tag within the tags input.
Property
Type
Description
valuerequired
string
The value of the tag.
Default: ——undefined
indexrequired
number
The index of the tag in the value array.
Default: ——undefined
editMode
enum
The edit mode of the tag.
Default: 'input'
removable
boolean
Whether or not the tag is removable or not.
Default: true
ref$bindable
HTMLDivElement
The underlying DOM element being rendered. You can bind to this to get a reference to the element.
Default: ——undefined
children
Snippet
The children content to render.
Default: ——undefined
child
Snippet
Use render delegation to render your own element. See Child Snippet docs for more information.
Default: ——undefined
Data Attribute
Value
Description
data-editing
''
Present on the tag element when the tag is being edited.
data-invalid
''
Present on the tag element when the tags input is marked as invalid.
data-editable
''
Present on the tag element when the tag is editable.
data-removable
''
Present on the tag element when the tag is removable.
data-tags-input-tag
''
Present on the tag element.
TagsInput.TagContent
The container for the tag content, which typically includes the tag text and edit/remove buttons and does not include the edit input.
Property
Type
Description
ref$bindable
HTMLDivElement
The underlying DOM element being rendered. You can bind to this to get a reference to the element.
Default: ——undefined
children
Snippet
The children content to render.
Default: ——undefined
child
Snippet
Use render delegation to render your own element. See Child Snippet docs for more information.
Default: ——undefined
Data Attribute
Value
Description
data-tags-input-tag-content
''
TagsInput.TagText
The text content of the tag.
Property
Type
Description
ref$bindable
HTMLSpanElement
The underlying DOM element being rendered. You can bind to this to get a reference to the element.
Default: ——undefined
children
Snippet
The children content to render.
Default: ——undefined
child
Snippet
Use render delegation to render your own element. See Child Snippet docs for more information.
Default: ——undefined
Data Attribute
Value
Description
data-tags-input-tag-text
''
Present on the text element.
data-editable
''
Present when the tag is editable.
data-removable
''
Present when the tag is removable.
TagsInput.TagRemove
The remove button for the tag.
Property
Type
Description
ref$bindable
HTMLButtonElement
The underlying DOM element being rendered. You can bind to this to get a reference to the element.
Default: ——undefined
children
Snippet
The children content to render.
Default: ——undefined
child
Snippet
Use render delegation to render your own element. See Child Snippet docs for more information.
Default: ——undefined
Data Attribute
Value
Description
data-tags-input-tag-remove
''
Present on the remove element.
data-editable
''
Present when the tag is editable.
data-removable
''
Present when the tag is removable.
TagsInput.TagEditInput
The input that will receive focus when the tag is edited and the editMode is 'input'.
Property
Type
Description
ref$bindable
HTMLInputElement
The underlying DOM element being rendered. You can bind to this to get a reference to the element.
Default: ——undefined
children
Snippet
The children content to render.
Default: ——undefined
child
Snippet
Use render delegation to render your own element. See Child Snippet docs for more information.
Default: ——undefined
Data Attribute
Value
Description
data-tags-input-tag-edit
''
Present on the edit element.
data-invalid
''
Present on the edit element when the tags input is marked as invalid.
data-editable
''
Present when the tag is editable.
data-removable
''
Present when the tag is removable.
TagsInput.Input
The input field for the tags input.
Property
Type
Description
blurBehavior
enum
The behavior to use when the input is blurred with text in it.
Default: 'none'
pasteBehavior
enum
How text is handled when it is pasted into the input.
Default: 'add'
value$bindable
string
The value of the input.
Default: ——undefined
onValueChange
function
A callback function called when the value of the input changes.
Default: ——undefined
controlledValue
boolean
Whether or not the value is controlled or not. If true, the component will not update the value internally, instead it will call onValueChange when it would have otherwise, and it is up to you to update the value prop that is passed to the component.
Default: false
ref$bindable
HTMLInputElement
The underlying DOM element being rendered. You can bind to this to get a reference to the element.
Default: ——undefined
children
Snippet
The children content to render.
Default: ——undefined
child
Snippet
Use render delegation to render your own element. See Child Snippet docs for more information.
Default: ——undefined
Data Attribute
Value
Description
data-invalid
''
Present on the input element when the tags input is marked as invalid.
data-tags-input-input
''
Present on the input element.
TagsInput.Clear
The clear button for the tags input.
Property
Type
Description
ref$bindable
HTMLButtonElement
The underlying DOM element being rendered. You can bind to this to get a reference to the element.
Default: ——undefined
children
Snippet
The children content to render.
Default: ——undefined
child
Snippet
Use render delegation to render your own element. See Child Snippet docs for more information.