# TagGroup · HeroUI

> A focusable list of tags with support for keyboard navigation, selection, and removal

- Page: https://jiguang132.com/systems/heroui/docs/components/tag-group
- Based on: HeroUI documentation (Apache-2.0) @ 60edd8ed751b1d2a270623fbb182bbcfa8baa9af

## Import

```tsx
import { TagGroup } from '@heroui/react';
```

### Usage


> Example `tag-group-basic`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/tag-group


### Anatomy

```tsx
import { TagGroup, Tag, Label, Description, ErrorMessage } from '@heroui/react';

export default () => (
  <TagGroup>
    <Label />
    <TagGroup.List>
      <Tag>
        <Tag.RemoveButton />
      </Tag>
    </TagGroup.List>
    <Description />
    <ErrorMessage />
  </TagGroup>
)
```

### Sizes


> Example `tag-group-sizes`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/tag-group


### Variants


> Example `tag-group-variants`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/tag-group


### Disabled


> Example `tag-group-disabled`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/tag-group


### Selection Modes


> Example `tag-group-selection-modes`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/tag-group


### Controlled


> Example `tag-group-controlled`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/tag-group


### With Error Message


> Example `tag-group-with-error-message`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/tag-group


### With Prefix


> Example `tag-group-with-prefix`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/tag-group


### With Remove Button


> Example `tag-group-with-remove-button`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/tag-group


### With List Data


> Example `tag-group-with-list-data`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/tag-group


### Custom Render Function


> Example `tag-group-custom-render-function`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/tag-group


## Styling

### Passing Tailwind CSS classes

```tsx
import { TagGroup, Tag, Label } from '@heroui/react';

function CustomTagGroup() {
  return (
    <TagGroup className="w-full">
      <Label>Categories</Label>
      <TagGroup.List className="gap-2">
        <Tag className="rounded-lg px-4 py-2 font-bold">
          Custom Styled
        </Tag>
      </TagGroup.List>
    </TagGroup>
  );
}
```

### Customizing the component classes

To customize the TagGroup component classes, you can use the `@layer components` directive.
  
[Learn more](https://tailwindcss.com/docs/adding-custom-styles#adding-component-classes).

```css
@layer components {
  .tag-group {
    @apply flex flex-col gap-2;
  }

  .tag-group__list {
    @apply flex flex-wrap gap-2;
  }

  .tag {
    @apply rounded-full px-3 py-1;
  }

  .tag__remove-button {
    @apply ml-1;
  }
}
```

HeroUI follows the [BEM](https://getbem.com/) methodology to ensure component variants and states are reusable and easy to customize.

### CSS Classes

The TagGroup component uses these CSS classes ([View source styles](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/tag-group.css) and [tag.css](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/tag.css)):

#### Base Classes
- `.tag-group` - Base tag group container
- `.tag-group__list` - Container for the list of tags
- `.tag` - Base tag styles
- `.tag__remove-button` - Remove button trigger

#### Slot Classes
- `.tag-group [slot="description"]` - Description slot styles
- `.tag-group [slot="errorMessage"]` - ErrorMessage slot styles

#### Size Classes
- `.tag--sm` - Small size tag
- `.tag--md` - Medium size tag (default)
- `.tag--lg` - Large size tag

#### Variant Classes
- `.tag--default` - Default variant
- `.tag--surface` - Surface variant with surface background

#### State Classes
- `.tag[data-selected="true"]` - Selected tag state
- `.tag[data-disabled="true"]` - Disabled tag state
- `.tag[data-hovered="true"]` - Hovered tag state
- `.tag[data-pressed="true"]` - Pressed tag state
- `.tag[data-focus-visible="true"]` - Focused tag state (keyboard focus)

### Interactive States

The component supports both CSS pseudo-classes and data attributes for flexibility:

- **Hover**: `:hover` or `[data-hovered="true"]` on tag
- **Focus**: `:focus-visible` or `[data-focus-visible="true"]` on tag
- **Pressed**: `:active` or `[data-pressed="true"]` on tag
- **Selected**: `[data-selected="true"]` or `[aria-selected="true"]` on tag
- **Disabled**: `:disabled` or `[data-disabled="true"]` on tag

## API Reference

### TagGroup Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `selectionMode` | `"none" \| "single" \| "multiple"` | `"none"` | The type of selection that is allowed |
| `selectedKeys` | `Selection` | - | The currently selected keys (controlled) |
| `defaultSelectedKeys` | `Selection` | - | The initial selected keys (uncontrolled) |
| `onSelectionChange` | `(keys: Selection) => void` | - | Handler called when the selection changes |
| `disabledKeys` | `Iterable` | - | Keys of disabled tags |
| `isDisabled` | `boolean` | - | Whether the tag group is disabled |
| `onRemove` | `(keys: Set) => void` | - | Handler called when tags are removed |
| `size` | `"sm" \| "md" \| "lg"` | `"md"` | Size of the tags in the group |
| `variant` | `"default" \| "surface"` | `"default"` | Visual variant of the tags |
| `className` | `string` | - | Additional CSS classes |
| `children` | `ReactNode \| RenderFunction` | - | TagGroup content or render function |
| `render` | `DOMRenderFunction<keyof React.JSX.IntrinsicElements, undefined>` | - | Overrides the default DOM element with a custom render function.|

### TagGroup.List Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `items` | `Iterable` | - | The items to display in the tag list |
| `renderEmptyState` | `() => ReactNode` | - | Function to render when the list is empty |
| `className` | `string` | - | Additional CSS classes |
| `children` | `ReactNode \| RenderFunction` | - | TagList content or render function |
| `render` | `DOMRenderFunction<keyof React.JSX.IntrinsicElements, TagListRenderProps>` | - | Overrides the default DOM element with a custom render function.|

### Tag Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `id` | `Key` | - | The unique identifier for the tag |
| `textValue` | `string` | - | A string representation of the tag's content, used for accessibility |
| `isDisabled` | `boolean` | - | Whether the tag is disabled |
| `className` | `string` | - | Additional CSS classes |
| `children` | `ReactNode \| RenderFunction` | - | Tag content or render function |
| `render` | `DOMRenderFunction<keyof React.JSX.IntrinsicElements, TagRenderProps>` | - | Overrides the default DOM element with a custom render function.|

**Note**: `size`, `variant` are inherited from the parent `TagGroup` component and cannot be set directly on individual `Tag` components.

### Tag.RemoveButton Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `className` | `string` | - | Additional CSS classes |
| `children` | `ReactNode` | - | Custom remove button content (defaults to close icon) |

**Note**: The `Tag.RemoveButton` component supports customization similar to `SearchField.ClearButton`. When `onRemove` is provided to `TagGroup`:

- **Auto-rendering**: If no custom `Tag.RemoveButton` is included in the `Tag` children, a default remove button is automatically rendered.
- **Custom button**: If a custom `Tag.RemoveButton` is provided as a child of `Tag`, it will be used instead of the auto-rendered button.
- **Custom icon**: You can pass custom content (like icons) to `Tag.RemoveButton` children to customize the appearance.

**Example - Auto-rendered (default)**:
```tsx
<TagGroup onRemove={handleRemove}>
  <TagGroup.List>
    <Tag id="news">News</Tag>
    {/* Remove button is automatically rendered */}
  </TagGroup.List>
</TagGroup>
```

**Example - Custom RemoveButton with icon**:
```tsx
<TagGroup onRemove={handleRemove}>
  <TagGroup.List>
    <Tag id="news">
      News
      <Tag.RemoveButton>
        <CustomIcon />
      </Tag.RemoveButton>
    </Tag>
  </TagGroup.List>
</TagGroup>
```

**Example - Custom RemoveButton in render props**:
```tsx
<Tag id="news">
  {(renderProps) => (
    <>
      News
      {!!renderProps.allowsRemoving && (
        <Tag.RemoveButton>
          <CustomIcon />
        </Tag.RemoveButton>
      )}
    </>
  )}
</Tag>
```

### RenderProps

When using render functions with TagGroup.List, these values are provided:

| Prop | Type | Description |
|------|------|-------------|
| `isSelected` | `boolean` | Whether the tag is selected |
| `isDisabled` | `boolean` | Whether the tag is disabled |
| `isHovered` | `boolean` | Whether the tag is hovered |
| `isPressed` | `boolean` | Whether the tag is pressed |
| `isFocused` | `boolean` | Whether the tag is focused |
| `isFocusVisible` | `boolean` | Whether the tag has keyboard focus |

---

Index of all JGuang resources: https://jiguang132.com/llms.txt
