Skip to main content
Gremorie
Display

Badge

Label compacto para status, contagens e tags. Seis variantes, asChild opcional para badges estilo link.

Visão geral

Badge é o primitive de label estático: uma pílula pequena e arredondada para status ("Active", "Pending"), contagens ("12", "99+"), tags ("AI", "Beta") ou marcadores de categoria. Ele renderiza como um <span> por padrão - ou qualquer elemento via asChild - e é intencionalmente não interativo. Para chips selecionáveis, use ToggleGroup; para badges clicáveis que linkam para algum lugar, use asChild para compor com um <a> ou um componente Link.

Seis variantes são distribuídas por padrão: default (primary preenchido), secondary, destructive, outline, ghost e link. Os estados de hover só se aplicam quando o Badge é renderizado como âncora (via o padrão de seletor [a&]:hover:...), então as variantes estáticas permanecem verdadeiramente estáticas.

Preview

DefaultSecondaryOutlineDestructive
'use client';import { Badge } from '@gremorie/rx-display';export function BadgePreview() {  return (    <div className="flex flex-wrap items-center gap-2">      <Badge>Default</Badge>      <Badge variant="secondary">Secondary</Badge>      <Badge variant="outline">Outline</Badge>      <Badge variant="destructive">Destructive</Badge>    </div>  );}

Anatomia

Badge   rounded, bordered pill wrapping text and/or a leading size-3 icon

Instalação

bash npx gremorie@latest add rx-badge
bash pnpm dlx gremorie@latest add rx-badge
bash yarn dlx gremorie@latest add rx-badge
bash bunx --bun gremorie@latest add rx-badge

Uso

import { Badge } from "@gremorie/rx-display";

export function Example() {
  return (
    <div className="flex flex-wrap items-center gap-2">
      <Badge>Default</Badge>
      <Badge variant="secondary">Secondary</Badge>
      <Badge variant="outline">Outline</Badge>
      <Badge variant="destructive">Destructive</Badge>
    </div>
  );
}
npx gremorie@latest add ng-badge
import { Component } from '@angular/core';
import { Badge } from '@gremorie/ng-display';

@Component({
  selector: 'app-example',
  standalone: true,
  imports: [Badge],
  template: `
    <div class="flex flex-wrap items-center gap-2">
      <gr-badge>Default</gr-badge>
      <gr-badge variant="secondary">Secondary</gr-badge>
      <gr-badge variant="outline">Outline</gr-badge>
      <gr-badge variant="destructive">Destructive</gr-badge>
    </div>
  `,
})
export class ExampleComponent {}

API

<Badge>

PropTypeDefaultDescrição
variant"default" | "secondary" | "destructive" | "outline" | "ghost" | "link""default"Estilo visual. default é primary preenchido; outline mostra apenas uma borda; ghost é invisível até ser renderizado como âncora; link estiliza como texto inline.
asChildbooleanfalseQuando true, renderiza o child imediato via Slot do Radix e mescla todas as classes nele. Use para envolver um <a> ou Link de framework.
classNamestring-Classes extras mescladas via cn.

Todas as outras props de span são encaminhadas.

A função CVA badgeVariants também é exportada, então você pode compor os estilos do Badge em um elemento customizado sem usar o próprio Badge:

import { badgeVariants } from '@gremorie/rx-display';

<a href="/docs" className={badgeVariants({ variant: 'outline' })}>
  Docs
</a>;

Composição

Badge é um componente folha - não tem sub-partes. As duas alavancas de composição são:

  1. variant para trocar o tratamento visual.
  2. asChild para renderizar os estilos do Badge em um elemento diferente (tipicamente uma âncora ou link de framework).

Ícones compõem naturalmente: coloque um SVG dentro do Badge e o CSS da variante cuida do dimensionamento ([&>svg]:size-3).

Variações

Todas as variantes

DefaultSecondaryDestructiveOutlineGhostLink
'use client';import { Badge } from '@gremorie/rx-display';export function BadgeVariantsPreview() {  return (    <div className="flex flex-wrap items-center gap-2">      <Badge>Default</Badge>      <Badge variant="secondary">Secondary</Badge>      <Badge variant="destructive">Destructive</Badge>      <Badge variant="outline">Outline</Badge>      <Badge variant="ghost">Ghost</Badge>      <Badge variant="link">Link</Badge>    </div>  );}

Todas as seis variantes lado a lado: default (primary preenchido), secondary, destructive, outline, ghost e link. ghost lê como texto simples até ser renderizado como âncora.

Indicador de status

ActiveFailedDraft
'use client';import { Badge } from '@gremorie/rx-display';import { AlertCircleIcon, CheckIcon } from 'lucide-react';export function BadgeStatusPreview() {  return (    <div className="flex flex-wrap items-center gap-2">      <Badge variant="secondary">        <CheckIcon />        Active      </Badge>      <Badge variant="destructive">        <AlertCircleIcon />        Failed      </Badge>      <Badge variant="outline">Draft</Badge>    </div>  );}

Combine um ícone com texto para que o status leia claramente sem depender apenas da cor. Ícones dentro do Badge se dimensionam automaticamente via [&>svg]:size-3.

'use client';import { Badge } from '@gremorie/rx-display';export function BadgeLinkPreview() {  return (    <Badge asChild variant="outline">      <a href="#docs">Read the docs</a>    </Badge>  );}

Estilos de hover se ativam automaticamente quando o Badge renderiza como âncora - é o que os seletores [a&]:hover:... fazem internamente.

Badge de contagem

Inbox12Notifications99+
'use client';import { Badge } from '@gremorie/rx-display';export function BadgeCountPreview() {  return (    <div className="flex items-center gap-2">      <span className="text-sm">Inbox</span>      <Badge>12</Badge>      <span className="text-sm">Notifications</span>      <Badge variant="destructive">99+</Badge>    </div>  );}

Acessibilidade

  • Estático por padrão: o Badge renderiza um <span> e não tem role. Leitores de tela anunciam seu conteúdo de texto como texto inline.
  • Atualizações de status: quando o conteúdo de um Badge muda dinamicamente (ex. uma contagem que atualiza ao vivo), envolva um pai em uma região aria-live="polite" para que a tecnologia assistiva anuncie a mudança.
  • Significado só por cor não basta: use ícones ou texto além da cor da variante para que usuários que não conseguem perceber cor ainda recebam a mensagem ("Active" mais um ícone de check, não só uma pílula verde).
  • Badges interativos: ao renderizar como âncora via asChild, a semântica nativa da âncora se aplica - foco, Enter para ativar, anúncio de screen reader como link.
  • aria-invalid: o Badge estiliza aria-invalid={true} automaticamente com borda e ring destructive - útil quando o Badge é parte de um campo de form.

Relacionados

  • Card - host frequente para Badge via CardAction.
  • Avatar - combina com AvatarBadge para dots de presença.
  • Alert - para status não inline que precisa de mais espaço.

On this page