Tag components

FREE

Free and open-source React tag components built for modern applications and websites. These tags are built using React Aria and styled with Tailwind CSS.

Label
Avatar
Label
Avatar
Label
Label

Installation

You can add this tags component using our CLI or manually:

npx untitledui@latest add tags

Tags examples

Below are examples and variations of this tags component:

Sizes

Our tags component comes with three predefined sizes: sm, md, and lg. You can set the size using the size prop on the TagGroup component, which will apply to all tags within that group.

Label
Avatar
Label
Avatar
Label
Label
Label
Avatar
Label
Avatar
Label
Label
Label
Avatar
Label
Avatar
Label
Label

Close X

Tags can be dismissible by using the onRemove prop on the TagGroup component or the onClose prop on individual Tag components. This will add a remove button to the tag that, when clicked, will trigger the callback function with the key of the tag that was removed.

Label
Avatar
Label
Avatar
Label
Label

Count

Tags can display a count next to the tag by passing a number to the count prop on the Tag component. This is useful when you want to display the number of items associated with the tag.

Label5
Avatar
Label5
Avatar
Label5
Label5

Checkbox

You can make the tags selectable by passing either "single" or "multiple" to the selectionMode prop on the TagGroup component. This will allow users to select one or multiple tags at once.

Label
Avatar
Label
Avatar
Label
Label

Checkbox close X

If you'd like to make selectable tags dismissible, you can pass the onRemove prop to the TagGroup component. This will add a remove button to the tags that, when clicked, will trigger the callback function with the key of the tag that was removed.

Label
Avatar
Label
Avatar
Label
Label

Checkbox count

Selectable tags can also display a count next to the tag, just like non-selectable tags, by passing a number to the count prop on the Tag component. This is useful when you want to display the number of items associated with the tag.

Label5
Avatar
Label5
Avatar
Label5
Label5

API reference

Tag

Import Tag from @/components/base/tags/tags. Renders React Aria’s Tag — all of its props are supported.

Tag props
PropTypeDefaultDescription
countnumber—A number shown in a rounded counter at the end of the tag.
avatarSrcstring—The URL of an avatar image shown before the label. Takes precedence over dot.
avatarContrastBorderbooleantrueWhether to draw a subtle dark outline around the avatar so it stays visible on light images.
dotboolean—Whether to show a small colored dot before the label. Ignored when avatarSrc is set.
dotClassNamestring—Additional classes for the leading dot, typically used to change its color.
onClose((id: string) => void)—Handler called with the tag's id when its close button is pressed. Providing it renders the close button.
Props from React Aria (28)
Tag inherited props
PropTypeDefaultDescription
onClick((e: MouseEvent<FocusableElement>) => void)—Not recommended – use onPress instead. onClick is an alias for onPress provided for compatibility with other libraries. onPress provides additional event details for non-mouse interactions.
onPress((e: PressEvent) => void)—Handler that is called when the press is released over the target.
onPressChange((isPressed: boolean) => void)—Handler that is called when the press state changes.
onPressEnd((e: PressEvent) => void)—Handler that is called when a press interaction ends, either over the target or when the pointer leaves the target.
onPressStart((e: PressEvent) => void)—Handler that is called when a press interaction starts.
onPressUp((e: PressEvent) => void)—Handler that is called when a press is released over the target, regardless of whether it started on the target or not.
onHoverChange((isHovering: boolean) => void)—Handler that is called when the hover state changes.
onHoverEnd((e: HoverEvent) => void)—Handler that is called when a hover interaction ends.
onHoverStart((e: HoverEvent) => void)—Handler that is called when a hover interaction starts.
onBlur((e: FocusEvent<Element, Element>) => void)—Handler that is called when the element loses focus.
onFocus((e: FocusEvent<Element, Element>) => void)—Handler that is called when the element receives focus.
onFocusChange((isFocused: boolean) => void)—Handler that is called when the element's focus status changes.
downloadstring | boolean—Causes the browser to download the linked URL. A string may be provided to suggest a file name.
hrefstring—A URL to link to.
hrefLangstring—Hints at the human language of the linked URL.
pingstring—A space-separated list of URLs to ping when the link is followed.
referrerPolicy
"""no-referrer""no-referrer-when-downgrade""origin""origin-when-cross-origin""same-origin""strict-origin""strict-origin-when-cross-origin""unsafe-url"
—How much of the referrer to send when following the link.
relstring—The relationship between the linked resource and the current page.
routerOptionsRouterOptions—Options for the configured client side router.
targetHTMLAttributeAnchorTarget—The target window for the link.
idKey—A unique id for the tag.
isDisabledboolean—Whether the tag is disabled.
onAction(() => void)—Handler that is called when a user performs an action on the item. The exact user event depends on the collection's selectionBehavior prop and the interaction modality.
textValuestring—A string representation of the tags's contents, used for accessibility. Required if children is not a plain text string.
styleStyleOrFunction<TagRenderProps>—The inline style for the element. A function may be provided to compute the style based on component state.
childrenChildrenOrFunction<T>—The children of the component. A function may be provided to alter the children based on component state.
classNameClassNameOrFunction<TagRenderProps>—The CSS className for the element. A function may be provided to compute the class based on component state.
renderDOMRenderFunction<"div", TagRenderProps>—Overrides the default DOM element with a custom render function. This allows rendering existing components with built-in styles and behaviors such as router links, animation libraries, and pre-styled components.Requirements:
  • You must render the expected element type (e.g. if <button> is expected, you cannot render an <a>).
  • Only a single root DOM element can be rendered (no fragments).
  • You must pass through props and ref to the underlying DOM element, merging with your own prop as appropriate.

Also accepts the global HTML attributes (dir, lang, hidden, inert, translate), all standard React DOM event handlers.

TagAvatar

Import TagAvatar from @/components/base/tags/tags. Renders a <div> element.

TagAvatar props
PropTypeDefaultDescription
contrastBorderbooleantrueWhether to draw a subtle dark outline around the avatar so it stays visible on light images.

Also accepts all standard image attributes, all standard HTML attributes, all aria-* attributes, all standard React DOM event handlers.

TagGroup

Import TagGroup from @/components/base/tags/tags. Renders React Aria’s TagGroup — all of its props are supported.

TagGroup props
PropTypeDefaultDescription
label* (required)string—An accessible name for the group of tags, applied as aria-label.
size
"sm""md""lg"
"sm"Controls the padding, text size and spacing of every tag in the group.
Props from React Aria (21)
TagGroup inherited props
PropTypeDefaultDescription
childrenReactNode—The children of the component.
defaultSelectedKeysIterable<Key> | "all"—The initial selected keys in the collection (uncontrolled).
disabledKeysIterable<Key>—The item keys that are disabled. These items cannot be selected, focused, or otherwise interacted with.
disallowEmptySelectionboolean—Whether the collection allows empty selection.
escapeKeyBehavior
"none""clearSelection"
"clearSelection"Whether pressing the escape key should clear selection in the TagGroup or not.Most experiences should not modify this option as it eliminates a keyboard user's ability to easily clear selection. Only use if the escape key is being handled externally or should not trigger selection clearing contextually.
idstring—The element's unique identifier.
onAction((key: Key) => void)—Handler that is called when a user performs an action on an item. The exact user event depends on the collection's selectionBehavior prop and the interaction modality.
onRemove((keys: Set<Key>) => void)—Handler that is called when a user deletes a tag.
onSelectionChange((keys: Selection) => void)—Handler that is called when the selection changes.
selectedKeysIterable<Key> | "all"—The currently selected keys in the collection (controlled).
selectionBehavior
"replace""toggle"
"toggle"How multiple selection should behave in the collection.
selectionMode
"none""single""multiple"
"none"The type of selection that is allowed in the collection.
shouldSelectOnPressUpboolean—Whether selection should occur on press up instead of press down.
slotstring | null—A slot name for the component. Slots allow the component to receive props from a parent component. An explicit null value indicates that the local props completely override all props received from a parent.
classNamestring—The CSS className for the element.
renderDOMRenderFunction<"div", undefined>—Overrides the default DOM element with a custom render function. This allows rendering existing components with built-in styles and behaviors such as router links, animation libraries, and pre-styled components.Requirements:
  • You must render the expected element type (e.g. if <button> is expected, you cannot render an <a>).
  • Only a single root DOM element can be rendered (no fragments).
  • You must pass through props and ref to the underlying DOM element, merging with your own prop as appropriate.
styleCSSProperties—The inline style for the element.
aria-describedbystring—Identifies the element (or elements) that describes the object.
aria-detailsstring—Identifies the element (or elements) that provide a detailed, extended description for the object.
aria-labelstring—Defines a string value that labels the current element.
aria-labelledbystring—Identifies the element (or elements) that labels the current element.

Also accepts the global HTML attributes (dir, lang, hidden, inert, translate), all standard React DOM event handlers.

FAQs

Please refer to our frequently asked questions page for more.

Pass onRemove to TagGroup. Every tag then gets an X button, and the callback receives a Set of the removed keys, so filter those ids out of your own state. With onRemove, a focused tag can also be removed with Backspace or Delete. If you only need a close button on certain tags, pass onClose to those Tag components instead, which is called with the tag's id.

Set selectionMode on TagGroup to "single" or "multiple" (the default is "none"). Each tag then shows a checkbox, and you can track the selection with selectedKeys and onSelectionChange. In "single" mode the group sets disallowEmptySelection, so the user can't deselect the last selected tag.

Tags support "sm", "md", and "lg", with "sm" as the default. Set size on TagGroup and every Tag inside it, including its checkbox and close button, picks it up through context.

Pass avatarSrc for a leading avatar or dot for a status dot, which is green by default and can be recolored with dotClassName. If both are set, the avatar wins. Pass a number to count to show a counter after the label.

The label string isn't rendered visibly. TagGroup passes it to React Aria as the group's aria-label, so screen readers can announce what the set of tags is for. Use a short description such as "Filters" or "Selected skills".

Pass your array to TagList through items and render each entry with a function child, for example {(item) => <Tag {...item}>{item.label}</Tag>}. Give each item a unique id, because selection and removal work with those ids.

Yes. Set isDisabled on a Tag, or pass the ids to disabledKeys on TagGroup. A disabled tag can't be selected or removed. It shows a cursor-not-allowed cursor, and in selectable groups its checkbox is dimmed.