---
title: Tag
description: A versatile badge component that displays labeled tags with customizable colors, icons, and display themes for status indicators and categorization
---

```tsx
'use client';

import { IconsFixture } from '@clubmed/trident-icons/tests/IconsFixture';

import { Tag } from '@/ui/Tag';

export function TagDemo() {
  return (
    <IconsFixture>
      <Tag label="New Feature" icon="Diamond" theme="both" />
    </IconsFixture>
  );
}
```

## Installation

Using the CLI:

```bash
npx shadcn@latest add https://develop.trident-ui.pro.clubmed/r/tag.json
```

Or manually, copy the following code into `/ui/tag.tsx`:

```tsx
import { Icon, type IconicNames } from '@clubmed/trident-icons';
import clsx from 'clsx';
import type { ComponentPropsWithoutRef, FunctionComponent } from 'react';

import {
  type BgColor,
  type BorderColor,
  getBgColor,
  getBorderColor,
  getTextColor,
  type TextColor,
} from './helpers/colors/colors';
import type { LiteralUnion } from './types/LiteralUnion';
import type { IconProps } from '@clubmed/trident-icons';
import { twMerge } from './helpers/twMerge';

export interface TagProps extends Omit<ComponentPropsWithoutRef<'span'>, 'color'> {
  /**
   * Additional class names
   */
  className?: string;
  /**
   * Background color
   */
  backgroundColor?: LiteralUnion<BgColor>;
  /**
   * Text color
   */
  color?: LiteralUnion<TextColor>;
  /**
   * Border color
   */
  border?: LiteralUnion<BorderColor>;
  /**
   * Optional icon name
   */
  icon?: IconicNames;
  /**
   * Tag label
   */
  label?: string;
  /**
   * theme mode
   */
  theme?: 'icon' | 'label' | 'both' | 'swap' | 'unfold' | 'monogram' | 'pill' | 'none';
  /**
   * Icon class name
   */
  iconClassName?: string;
  iconWidth?: IconProps['width'];
  /**
   * Label class name
   */
  labelClassName?: string;
}

export const Tag: FunctionComponent<TagProps> = ({
  className,
  backgroundColor = 'saffron',
  border = backgroundColor,
  color = 'black',
  icon,
  label = '',
  theme = 'both',
  iconClassName,
  labelClassName,
  iconWidth,
  ...attrs
}) => {
  if (!label && !icon) {
    return null;
  }

  const borderColor = getBorderColor(border);
  const bgColor = getBgColor(backgroundColor);
  const textColor = getTextColor(color);

  const hasIcon = !!icon;
  const mode = theme === 'both' && !hasIcon ? 'label' : theme;

  const withBoth = mode === 'both' || mode === 'swap' || mode === 'unfold' || mode === 'none';
  const withIcon = hasIcon && (mode === 'icon' || withBoth);
  const withLabel = mode === 'label' || mode === 'pill' || withBoth;

  return (
    <span
      role="note"
      {...attrs}
      data-name="Tag"
      className={twMerge(
        clsx(
          'box-border inline-flex items-center justify-center gap-x-4 whitespace-nowrap rounded-pill border align-middle font-sans font-semibold',
          {
            'text-b4': mode !== 'pill',
            'text-b5': mode === 'pill',
          },
          {
            'p-4': mode !== 'label' && mode !== 'both',
            'px-16 py-6': mode === 'label',
            'py-4 pe-16 ps-12': mode === 'both',
            'px-8 py-4': mode === 'pill',
            'sm:px-16': mode === 'swap',
            'sm:pe-16 sm:ps-12': mode === 'unfold',
          },
          borderColor,
          bgColor,
          textColor,
        ),
        className,
      )}
      title={label}
    >
      {mode === 'monogram' && <span className="size-24 text-center leading-[1.5rem]">{label}</span>}
      {withIcon && (
        <Icon
          width={iconWidth ?? '1.5rem'}
          name={icon}
          className={clsx({ 'sm:hidden': mode === 'swap' }, iconClassName)}
        />
      )}
      {withLabel && (
        <span
          className={clsx(
            {
              'hidden sm:block': mode === 'swap' || mode === 'unfold',
            },
            labelClassName,
          )}
        >
          {label}
        </span>
      )}
    </span>
  );
};
```

## Usage

```tsx showLineNumbers
import { Tag } from '@/docs/lib/ui/tag';

export function Component() {
  return (
    <Tag label="New Feature" icon="Diamond" theme="both" backgroundColor="saffron" color="black" />
  );
}
```

## API Reference

### Tag

| Prop              | Type                                                                                  | Default                   | Description                                                                                                                                                                                                                                                       |
| ----------------- | ------------------------------------------------------------------------------------- | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `label`           | `string`                                                                              | `""`                      | The text label displayed in the tag. Used as the `title` attribute for accessibility.                                                                                                                                                                             |
| `icon`            | `IconicNames`                                                                         | `undefined`               | Optional icon name from the Trident Icons library to display in the tag.                                                                                                                                                                                          |
| `theme`           | `"label" \| "icon" \| "both" \| "swap" \| "unfold" \| "monogram" \| "pill" \| "none"` | `"both"`                  | Display mode for the tag. Controls visibility and layout of icon and label.                                                                                                                                                                                       |
| `backgroundColor` | `BgColor \| string`                                                                   | `"saffron"`               | Background color of the tag. Accepts 17 predefined colors: `black`, `darkGrey`, `green`, `lavender`, `lightGrey`, `lightSand`, `marygold`, `orange`, `red`, `saffron`, `sand`, `sienna`, `ultramarine`, `verdigris`, `wave`, `white`, or custom Tailwind classes. |
| `color`           | `TextColor \| string`                                                                 | `"black"`                 | Text color of the tag. Accepts the same color options as backgroundColor or custom Tailwind classes.                                                                                                                                                              |
| `border`          | `BorderColor \| string`                                                               | Same as `backgroundColor` | Border color of the tag. Accepts the same color options as backgroundColor or custom Tailwind classes.                                                                                                                                                            |
| `iconClassName`   | `string`                                                                              | `undefined`               | Additional CSS classes for the icon element.                                                                                                                                                                                                                      |
| `iconWidth`       | `string`                                                                              | `"1.5rem"`                | Width of the icon.                                                                                                                                                                                                                                                |
| `labelClassName`  | `string`                                                                              | `undefined`               | Additional CSS classes for the label element.                                                                                                                                                                                                                     |
| `className`       | `string`                                                                              | `undefined`               | Additional CSS classes for the tag container.                                                                                                                                                                                                                     |

## Notes

- **Theme Modes**: The `theme` prop offers flexible display options:

  - `"label"`: Shows only the label with padding
  - `"icon"`: Shows only the icon (label used for title attribute)
  - `"both"`: Shows both icon and label side by side
  - `"swap"`: Shows icon on mobile, label on larger screens (sm breakpoint)
  - `"unfold"`: Shows icon always, label on larger screens (sm breakpoint)
  - `"monogram"`: Shows label in a circular format (24x24px)
  - `"pill"`: Shows label with compact pill styling (smaller text)
  - `"none"`: Shows both with minimal padding

- **Semantic Role**: The component renders with `role="note"` for accessibility, indicating informational content.

- **Color Customization**: All color props accept predefined color names or custom Tailwind CSS classes for maximum flexibility.

- **Conditional Rendering**: The tag returns `null` if both `label` and `icon` are empty, preventing empty tags from rendering.

- **Smart Theme Logic**: When `theme="both"` is set but no icon is provided, the component automatically falls back to `"label"` mode.

- **Responsive Design**: The `swap` and `unfold` themes use responsive classes to show different content at different screen sizes.

- **HTML Attributes**: All standard HTML span attributes are supported via `ComponentPropsWithoutRef<"span">`.

- **Border Inheritance**: By default, the border color matches the background color unless explicitly overridden.
