Tag group

A tag group controls the layout and alignment for a collection of tags.

Default

By default, a tag group lays out a collection of tags from left to right. It handles overflow by wrapping to the next line.

Tags inside of a tag group should be of the same type to provide a consistent user experience.

TagTagTagTag
Rounded tagRounded tagRounded tagRounded tag
Removable tagRemovable tagRemovable tagRemovable tag
import { css, jsx } from '@compiled/react'; import TagGroup from '@atlaskit/tag-group/tag-group'; import Tag from '@atlaskit/tag/removable-tag'; import { token } from '@atlaskit/tokens'; const layoutStyles = css({ display: 'flex', gap: token('space.300'), flexDirection: 'column', paddingBlockEnd: token('space.300'), paddingBlockStart: token('space.300'), paddingInlineEnd: 0, paddingInlineStart: 0, }); const _default: () => JSX.Element = () => ( <div css={layoutStyles}> <TagGroup label="Simple tags"> <Tag text="Tag" isRemovable={false} /> <Tag text="Tag" isRemovable={false} /> <Tag text="Tag" isRemovable={false} /> <Tag text="Tag" isRemovable={false} /> </TagGroup> <TagGroup label="Link tags"> <Tag text="Tag link" href="/components/tag-group" isRemovable={false} /> <Tag text="Tag link" href="/components/tag-group" isRemovable={false} /> <Tag text="Tag link" href="/components/tag-group" isRemovable={false} /> <Tag text="Tag link" href="/components/tag-group" isRemovable={false} /> </TagGroup> <TagGroup label="Rounded tags"> <Tag text="Rounded tag" appearance="rounded" isRemovable={false} /> <Tag text="Rounded tag" appearance="rounded" isRemovable={false} /> <Tag text="Rounded tag" appearance="rounded" isRemovable={false} /> <Tag text="Rounded tag" appearance="rounded" isRemovable={false} /> </TagGroup> <TagGroup label="Removable tags"> <Tag text="Removable tag" /> <Tag text="Removable tag" /> <Tag text="Removable tag" /> <Tag text="Removable tag" /> </TagGroup> </div> ); export default _default;

Add tags

Add and remove tags to see their enter and exit motion in a tag group.

import { useState } from 'react'; import { css, jsx } from '@compiled/react'; import TagGroup from '@atlaskit/tag-group/tag-group'; import Tag from '@atlaskit/tag/tag-new'; import { token } from '@atlaskit/tokens'; const tagNames = [ 'Design', 'Engineering', 'Research', 'Content', 'Analytics', 'A realllllllllllllly long tag name that should be truncated', 'Marketing', ]; const layoutStyles = css({ display: 'flex', alignItems: 'flex-start', gap: token('space.150'), flexDirection: 'column', }); const addButtonStyles = css({ appearance: 'none', backgroundColor: token('color.background.neutral.bold'), borderRadius: token('radius.small'), borderStyle: 'none', color: token('color.text.inverse'), cursor: 'pointer', font: token('font.body'), fontWeight: token('font.weight.semibold'), paddingBlock: token('space.100'), paddingInline: token('space.150'), '&:hover': { backgroundColor: token('color.background.neutral.bold.hovered'), }, '&:active': { backgroundColor: token('color.background.neutral.bold.pressed'), }, '&:disabled': { cursor: 'not-allowed', }, }); export default function AddTagsToGroupExample(): JSX.Element { const [tags, setTags] = useState<string[]>([]); const nextTag = tagNames.find((tag) => !tags.includes(tag)); return ( <div css={layoutStyles}> <button css={addButtonStyles} disabled={nextTag === undefined} onClick={() => nextTag && setTags((currentTags) => [...currentTags, nextTag])} type="button" > Add tag </button> <TagGroup label="Project tags"> {tags.map((tag) => ( <Tag key={tag} text={tag} removeButtonLabel="Remove" onAfterRemoveAction={(removedTag) => setTags((currentTags) => currentTags.filter((item) => item !== removedTag)) } /> ))} </TagGroup> </div> ); }

Alignment

The alignment direction can be set to either the start or end of the tag group container using the alignment prop. This will also impact the direction of the exiting animation when a removable tag is removed.

Start

Set the alignment prop to "start" to align the tags to the start of the tag group container. Tags will animate out to the left when removed.

BitbucketCompassConfluenceJiraJira Service ManagementJira SoftwareJira Work ManagementOpsgenieStatuspageTrello
import React from 'react'; import TagGroup from '@atlaskit/tag-group/tag-group'; import Tag from '@atlaskit/tag/removable-tag'; export default (): React.JSX.Element => ( <TagGroup label="Atlassian apps" alignment="start"> <Tag text="Bitbucket" /> <Tag text="Compass" /> <Tag text="Confluence" /> <Tag text="Jira" /> <Tag text="Jira Service Management" /> <Tag text="Jira Software" /> <Tag text="Jira Work Management" /> <Tag text="Opsgenie" /> <Tag text="Statuspage" /> <Tag text="Trello" /> </TagGroup> );

End

Set the alignment prop to "end" to align the tags to the end of the group. Tags will animate out to the right when removed.

BitbucketCompassConfluenceJiraJira Service ManagementJira SoftwareJira Work ManagementOpsgenieStatuspageTrello
import React from 'react'; import TagGroup from '@atlaskit/tag-group/tag-group'; import Tag from '@atlaskit/tag/removable-tag'; export default (): React.JSX.Element => ( <TagGroup label="Atlassian apps" alignment="end"> <Tag text="Bitbucket" /> <Tag text="Compass" /> <Tag text="Confluence" /> <Tag text="Jira" /> <Tag text="Jira Service Management" /> <Tag text="Jira Software" /> <Tag text="Jira Work Management" /> <Tag text="Opsgenie" /> <Tag text="Statuspage" /> <Tag text="Trello" /> </TagGroup> );

Focus

When a tag is removed, focus should go to the next focusable element on the page, which is likely the next tag (sibling).

If the removed tag was the last focusable element, move focus to next focusable element after the trigger. If there are no focusable elements after the trigger, then focus should move to the previous focusable element before the trigger.

If you remove a tag element from the DOM and don't set the focus, it returns to the body element at the top of the page. And for people using assistive technology, this means they'll need to navigate through the entire page to return to where they originally were, which we don’t want.

Was this page helpful?
We use this feedback to improve our documentation.
© 2026 AtlassianTrademark, (opens new window)Privacy, (opens new window)License