AvesraAvesrabeta

Badge

Displays a small indicator positioned relative to another element, commonly used for notification counts, status dots, and labels

Import

import { AvBadgeImports } from '@avesra/angular';

Usage

JDJD5ABABNewCDCD
import { Component } from '@angular/core';
import {
  AvAvatarImports,
  AvBadgeImports,
} from '@avesra/angular';

@Component({
  selector: 'app-badge-basic-demo',
  imports: [
    AvBadgeImports,
    AvAvatarImports,
  ],
  template: `<div class="flex items-center gap-6">
      <span av-badge-anchor>
        <span av-avatar>
          <img av-avatar-image alt="JD" [src]="greenAvatarUrl" />
          <span av-avatar-fallback>JD</span>
        </span>
        <span av-badge color="danger" size="sm" label="5"></span>
      </span>

      <span av-badge-anchor>
        <span av-avatar>
          <img av-avatar-image alt="AB" [src]="orangeAvatarUrl" />
          <span av-avatar-fallback>AB</span>
        </span>
        <span av-badge color="accent" size="sm" label="New"></span>
      </span>

      <span av-badge-anchor>
        <span av-avatar>
          <img av-avatar-image alt="CD" [src]="blueAvatarUrl" />
          <span av-avatar-fallback>CD</span>
        </span>
        <span av-badge color="success" placement="bottom-right" size="sm"></span>
      </span>
    </div>`,
})
export class BadgeBasicDemo {
  readonly greenAvatarUrl = '/images/gradients/gradient-pink-magenta.png';
  readonly orangeAvatarUrl = '/images/gradients/gradient-warm-orange-yellow-red.png';
  readonly blueAvatarUrl = '/images/gradients/gradient-blue-cyan.png';
}

Anatomy

Badge is designed to be positioned relative to another element using av-badge-anchor. Use the label input or project content (optionally via av-badge-label). Leave the badge empty for a dot indicator.

For standalone label usage, use the Chip component instead.

<span av-badge-anchor>
  <span av-avatar></span>
  <span av-badge color="danger" label="5"></span>
</span>

Variants

primary

JDJD5JDJD5JDJD5JDJD5JDJD5

secondary

JDJD5JDJD5JDJD5JDJD5JDJD5

soft

JDJD5JDJD5JDJD5JDJD5JDJD5
import { Component } from '@angular/core';
import {
  AvAvatarImports,
  AvBadgeImports,
  AvSeparatorImports,
} from '@avesra/angular';
import type { AvBadgeColor, AvBadgeVariant } from '@avesra/angular';

@Component({
  selector: 'app-badge-variants-demo',
  imports: [
    AvBadgeImports,
    AvAvatarImports,
    AvSeparatorImports,
  ],
  template: `<div class="flex flex-col gap-8">
      @for (variant of variants; track variant; let last = $last) {
        <div class="flex flex-col gap-4">
          <h3 class="text-sm font-semibold text-muted capitalize">{{ variant }}</h3>
          <div class="flex items-center gap-6">
            @for (color of colors; track color) {
              <span av-badge-anchor>
                <span av-avatar>
                  <img av-avatar-image alt="JD" [src]="avatarUrl" />
                  <span av-avatar-fallback>JD</span>
                </span>
                <span
                  av-badge
                  [color]="color"
                  size="sm"
                  [variant]="variant"
                  label="5"
                ></span>
              </span>
            }
          </div>
        </div>
        @if (!last) {
          <hr av-separator />
        }
      }
    </div>`,
})
export class BadgeVariantsDemo {
  readonly avatarUrl = '/images/gradients/gradient-blue-cyan.png';

  readonly variants: AvBadgeVariant[] = ['primary', 'secondary', 'soft'];
  readonly colors: AvBadgeColor[] = ['accent', 'default', 'success', 'warning', 'danger'];
}

Sizes

JDJD5JDJD5JDJD5
import { Component } from '@angular/core';
import {
  AvAvatarImports,
  AvBadgeImports,
} from '@avesra/angular';
import type { AvBadgeSize } from '@avesra/angular';

@Component({
  selector: 'app-badge-sizes-demo',
  imports: [
    AvBadgeImports,
    AvAvatarImports,
  ],
  template: `<div class="flex items-center gap-6">
      @for (size of sizes; track size) {
        <span av-badge-anchor>
          <span av-avatar [size]="size">
            <img av-avatar-image alt="JD" [src]="avatarUrl" />
            <span av-avatar-fallback>JD</span>
          </span>
          <span av-badge color="danger" [size]="size" label="5"></span>
        </span>
      }
    </div>`,
})
export class BadgeSizesDemo {
  readonly avatarUrl = '/images/gradients/gradient-blue-cyan.png';

  readonly sizes: AvBadgeSize[] = ['sm', 'md', 'lg'];
}

Colors

JDJDJDJDJDJDJDJDJDJD
import { Component } from '@angular/core';
import {
  AvAvatarImports,
  AvBadgeImports,
} from '@avesra/angular';
import type { AvBadgeColor } from '@avesra/angular';

@Component({
  selector: 'app-badge-colors-demo',
  imports: [
    AvBadgeImports,
    AvAvatarImports,
  ],
  template: `<div class="flex items-center gap-6">
      @for (color of colors; track color) {
        <span av-badge-anchor>
          <span av-avatar>
            <img av-avatar-image alt="JD" [src]="avatarUrl" />
            <span av-avatar-fallback>JD</span>
          </span>
          <span av-badge [color]="color" size="sm"></span>
        </span>
      }
    </div>`,
})
export class BadgeColorsDemo {
  readonly avatarUrl = '/images/gradients/gradient-blue-cyan.png';

  readonly colors: AvBadgeColor[] = ['default', 'accent', 'success', 'warning', 'danger'];
}

Placements

JDJDtop-right
JDJDtop-left
JDJDbottom-right
JDJDbottom-left
import { Component } from '@angular/core';
import {
  AvAvatarImports,
  AvBadgeImports,
} from '@avesra/angular';
import type { AvBadgePlacement } from '@avesra/angular';

@Component({
  selector: 'app-badge-placements-demo',
  imports: [
    AvBadgeImports,
    AvAvatarImports,
  ],
  template: `<div class="flex items-center gap-8">
      @for (placement of placements; track placement) {
        <div class="flex flex-col items-center gap-2">
          <span av-badge-anchor>
            <span av-avatar>
              <img av-avatar-image alt="JD" [src]="avatarUrl" />
              <span av-avatar-fallback>JD</span>
            </span>
            <span av-badge color="accent" [placement]="placement" size="sm"></span>
          </span>
          <span class="text-xs text-muted">{{ placement }}</span>
        </div>
      }
    </div>`,
})
export class BadgePlacementsDemo {
  readonly avatarUrl = '/images/gradients/gradient-blue-cyan.png';

  readonly placements: AvBadgePlacement[] = [
    'top-right',
    'top-left',
    'bottom-right',
    'bottom-left',
  ];
}

Dot Badge

Empty badges act as status indicators — useful for online/offline states or activity signals.

JDJDJDJDJDJDJDJD
import { Component } from '@angular/core';
import {
  AvAvatarImports,
  AvBadgeImports,
} from '@avesra/angular';
import type { AvBadgeColor } from '@avesra/angular';

@Component({
  selector: 'app-badge-dot-badge-demo',
  imports: [
    AvBadgeImports,
    AvAvatarImports,
  ],
  template: `<div class="flex items-center gap-6">
      @for (color of colors; track color) {
        <span av-badge-anchor>
          <span av-avatar>
            <img av-avatar-image alt="JD" [src]="avatarUrl" />
            <span av-avatar-fallback>JD</span>
          </span>
          <span av-badge [color]="color" placement="bottom-right" size="sm"></span>
        </span>
      }
    </div>`,
})
export class BadgeDotBadgeDemo {
  readonly avatarUrl = '/images/gradients/gradient-blue-cyan.png';

  readonly colors: AvBadgeColor[] = ['accent', 'success', 'warning', 'danger'];
}

With Content

Badge supports text, numbers, and icons as content. When no children are provided, it renders as a dot indicator.

JDJD5JDJDNewJDJD99+JDJD
import { Component } from '@angular/core';
import {
  AvAvatarImports,
  AvBadgeImports,
} from '@avesra/angular';

import { AppIconComponent } from '../../components/app-icon/app-icon.component';

@Component({
  selector: 'app-badge-with-content-demo',
  imports: [
    AvBadgeImports,
    AvAvatarImports,
    AppIconComponent,
  ],
  template: `<div class="flex items-center gap-6">
      <span av-badge-anchor>
        <span av-avatar>
          <img av-avatar-image alt="JD" [src]="avatarUrl" />
          <span av-avatar-fallback>JD</span>
        </span>
        <span av-badge color="danger" size="sm" label="5"></span>
      </span>

      <span av-badge-anchor>
        <span av-avatar>
          <img av-avatar-image alt="JD" [src]="avatarUrl" />
          <span av-avatar-fallback>JD</span>
        </span>
        <span av-badge color="danger" size="sm" label="New"></span>
      </span>

      <span av-badge-anchor>
        <span av-avatar>
          <img av-avatar-image alt="JD" [src]="avatarUrl" />
          <span av-avatar-fallback>JD</span>
        </span>
        <span av-badge color="danger" size="sm" label="99+"></span>
      </span>

      <span av-badge-anchor>
        <span av-avatar>
          <img av-avatar-image alt="JD" [src]="avatarUrl" />
          <span av-avatar-fallback>JD</span>
        </span>
        <span av-badge color="accent" size="sm">
          <app-icon icon="solar:bell-linear" size="10" />
        </span>
      </span>
    </div>`,
})
export class BadgeWithContentDemo {
  readonly avatarUrl = '/images/gradients/gradient-blue-cyan.png';
}

Styling

Passing Tailwind CSS classes

Pass utility classes on the badge host to customize typography, sizing, and decoration.

Kate WilsonKW5
import { Component } from '@angular/core';
import {
  AvAvatarImports,
  AvBadgeImports,
} from '@avesra/angular';

@Component({
  selector: 'app-badge-custom-styles-demo',
  imports: [
    AvBadgeImports,
    AvAvatarImports,
  ],
  template: `<span av-badge-anchor>
      <span av-avatar>
        <img
          av-avatar-image
          alt="Kate Wilson"
          src="/images/gradients/gradient-purple-violet.png"
        />
        <span av-avatar-fallback>KW</span>
      </span>
      <span
        av-badge
        class="min-w-5 font-semibold tabular-nums"
        color="accent"
        size="sm"
        variant="soft"
        label="5"
      ></span>
    </span>`,
})
export class BadgeCustomStylesDemo {}

Customizing the component classes

To customize the Badge classes, use the @layer components directive. Learn more.

@layer components {
  .av-badge {
    @apply rounded-full text-xs;
  }

  .av-badge__label {
    @apply font-semibold;
  }

  .av-badge--accent {
    @apply shadow-sm;
  }
}

Avesra follows the BEM methodology so component variants and states stay reusable and easy to customize.

CSS Classes

The Badge component uses these CSS classes:

Base Classes

  • .av-badge — Base badge container styles
  • .av-badge__label — Label text slot styles
  • .av-badge-anchor — Positioning wrapper for the anchored element

Color Classes

  • .av-badge--accent — Accent color variant
  • .av-badge--danger — Danger color variant
  • .av-badge--default — Default color variant
  • .av-badge--success — Success color variant
  • .av-badge--warning — Warning color variant

Variant Classes

  • .av-badge--primary — Primary variant with filled background
  • .av-badge--secondary — Secondary variant with default background
  • .av-badge--soft — Soft variant with lighter background

Size Classes

  • .av-badge--sm — Small size
  • .av-badge--md — Medium size (default)
  • .av-badge--lg — Large size

Placement Classes

  • .av-badge--top-right — Position at top-right corner (default)
  • .av-badge--top-left — Position at top-left corner
  • .av-badge--bottom-right — Position at bottom-right corner
  • .av-badge--bottom-left — Position at bottom-left corner

Compound Variant Classes

Badges support combining variant and color classes (e.g. .av-badge--primary.av-badge--accent).

Primary Variants:

  • .av-badge--primary.av-badge--accent — Primary accent with filled background
  • .av-badge--primary.av-badge--default — Primary default with filled background
  • .av-badge--primary.av-badge--success — Primary success with filled background
  • .av-badge--primary.av-badge--warning — Primary warning with filled background
  • .av-badge--primary.av-badge--danger — Primary danger with filled background

Soft Variants:

  • .av-badge--soft.av-badge--accent — Soft accent with lighter background
  • .av-badge--soft.av-badge--default — Soft default with lighter background
  • .av-badge--soft.av-badge--success — Soft success with lighter background
  • .av-badge--soft.av-badge--warning — Soft warning with lighter background
  • .av-badge--soft.av-badge--danger — Soft danger with lighter background

API Reference

Anchor the badge with span[av-badge-anchor], configure the indicator on span[av-badge], and optionally use span[av-badge-label] for projected label content.

PropTypeDefaultDescription
labelstring | number—Content shorthand (text or number). When omitted with no projected content, renders as a dot.
color'default' | 'accent' | 'success' | 'warning' | 'danger''default'Color variant of the badge.
variant'primary' | 'secondary' | 'soft''primary'Visual style variant.
size'sm' | 'md' | 'lg''md'Size of the badge.
placement'top-right' | 'top-left' | 'bottom-right' | 'bottom-left''top-right'Position of the badge relative to `av-badge-anchor`.

Made with ❤ by SyntaxHertz. Open source and available on GitHub.