Tag

A tag component is an item with a short label, which helps in any categorization or filtering. Usually, it appears in a group. Each Tag can be interactive for a better user experience.

It has a very flexible API and lets you create many variants of it. It can happen thanks to two props: adornmentStart and adornmentEnd. Each of those can work with prepared sub-components: <TagAvatar /> and <TagButton />, or you can also try use them with other components like <Icon /> or your internal components. You can find some examples of how to use them below.

Quick Start

Installation
npm install @adaptavant/eds-core
Import
import { Tag } from '@adaptavant/eds-core';

Size

Use the size prop to adjust the visual weight of the Tag.

StandardLarge
<div className="flex items-center flex-wrap gap-4">
  <Tag>Standard</Tag>
  <Tag size="large">Large</Tag>
</div>

Removable

Label
<Tag
  adornmentEnd={
    <TagButton
      aria-label="Remove Label"
      icon={RemoveIcon}
      onClick={() => alert('Remove')}
    />
  }
>
 Label
</Tag>

Draggable

If a Tag component is draggable by the user, combine the draggable prop with placement of a DragDropIcon in the adornmentStart prop. This will provide a visual cue that the Tag can be dragged.

Label
<Tag
  draggable
  className="active:bg-neutral-secondary-pressed active:cursor-grabbing cursor-grab hover:bg-neutral-secondary-hover"
  adornmentStart={
    <DragDropIcon size="16" tone="neutralSecondary" />
  }
>
  Label
</Tag>

Clickable

All tags:
Tag 1Tag 2Tag 3Tag 4Tag 5Tag 6Tag 7Tag 8Tag 9Tag 10
const [pickedTags, setPickedTags] = React.useState([]);
const [allTags, setAllTags] = React.useState([
  "Tag 1",
  "Tag 2",
  "Tag 3",
  "Tag 4",
  "Tag 5",
  "Tag 6",
  "Tag 7",
  "Tag 8",
  "Tag 9",
  "Tag 10",
]);

return (
  <div className="flex flex-col gap-4">
    <Text>All tags:</Text>
    <div className="flex flex-wrap gap-4">
      {allTags.map((tag) => (
        <Tag
          adornmentEnd={
            <TagButton
              aria-label="Add label"
              icon={AddIcon}
              onClick={() => {
                setPickedTags((prevPickedTags) => [
                  ...prevPickedTags,
                  tag,
                ]);
                setAllTags((prevAllTags) =>
                  prevAllTags.filter((allTag) => allTag !== tag)
                );
              }}
            />
          }
          key={tag}
        >
          {tag}
        </Tag>
      ))}
    </div>
    {pickedTags.length > 0 ? (
      <React.Fragment>
        <Text>Picked tags:</Text>
        <div className="flex flex-wrap gap-4">
          {pickedTags.map((tag) => (
            <Tag
              adornmentEnd={
                <TagButton
                  aria-label="Remove label"
                  icon={RemoveIcon}
                  onClick={() => {
                    setPickedTags((prevPickedTags) =>
                      prevPickedTags.filter(
                        (prevPickedTag) => prevPickedTag !== tag
                      )
                    );
                    setAllTags((prevAllTags) => [...prevAllTags, tag]);
                  }}
                />
              }
              key={tag}
            >
              {tag}
            </Tag>
          ))}
        </div>
      </React.Fragment>
    ) : null}
  </div>
);

Avatar

Place a TagAvatar component inside the adornmentStart prop of the Tag component to display an avatar at the start of the tag.

Label
<Tag
  adornmentStart={
    <TagAvatar
      imageSrc="https://placehold.co/64.png"
      name="Robert Anderson"
    />
  }
>
  Label
</Tag>

Full props set

Label
<Tag
  draggable
  className="active:bg-neutral-secondary-pressed active:cursor-grabbing cursor-grab hover:bg-neutral-secondary-hover"
  adornmentStart={
    <>
      <DragDropIcon size="16" tone="neutralSecondary" />
      <TagAvatar
        imageSrc="https://placehold.co/64.png"
        name="Robert Anderson"
      />
    </>
  }
  adornmentEnd={
    <TagButton
      aria-label="Remove Label"
      icon={RemoveIcon}
      onClick={() => alert('Remove')}
    />
  }
>
  Label
</Tag>

Style API

Our design system components include style props that allow you to easily customize different parts of each component to match your design needs.

Please refer to the Style API documentation for more insights.

Tag parts

Custom
<Tag className="bg-accent-secondary" classNames={{ label: "text-secondary" }}>
  Custom
</Tag>

Part

Description

label

The text content

Usage guidelines

Do

  1. Standalone display of selected options: Use Tag as a standalone element to display selected options.

Don’t

  1. Replacement for badge: Avoid using Tag as a replacement for Badge, as Badge serves as a singular element providing context to a specific subject.

Best practices

Do

tag1

Create concise labels for Tags, preferably two words or fewer.

Don’t

tag2

Mix removable and non-removable Tags in a group. Organize or distinguish removable Tags from non-removable ones, providing users with a clear pattern indicating which Tags can be removed and which cannot.

Do

tag3

Include Tags directly into TextInput to provide a user-friendly way of adding or editing topics and categories.

Don’t

tag4

Position Tags externally to the input used for adding or editing Tags.