ATOM
Components (registry)Indicators

Badge

A small status chip that sits on an edge or next to a label. Counts, inbox state, and quiet flags.

Preview

Variants: neutralinbox (default: neutral)

Editorial

<!-- F12c editorial — non-derivable only. Review: Karen. -->

## Ejemplos

Inbox count / quiet status:

```tsx import { Badge } from '@/components/atoms/Badge';

<Badge variant="neutral" state="enabled">3</Badge> <Badge variant="success">Live</Badge> ```

## Accesibilidad

- If the badge is the only indicator of state, include text (not color alone): “3 unread”, not a bare red dot without a name. - Decorative badges next to already-named headings can be `aria-hidden` when they add no new information.

### Correcto

- Badge es un `<span>` — no interactivo, no focusable. Correcto para indicadores visuales - Combinar con aria-label en el padre si el numero no es autoexplicativo (ej: 'Inbox, 3 mensajes sin leer') - Truncar a '99+' en lugar de mostrar numeros largos que rompen el layout

### Evitar

- No usar Badge para texto largo — maximo 3-4 caracteres (numeros) - No depender solo del color para comunicar urgencia — el contexto (posicion, texto adyacente) importa - No usar Badge como boton — es no interactivo. Para acciones, usar Chip con onClose

## Cuándo no usar

- Interactive filters users click to toggle → `Chip` / `Tag` patterns meant for actions. - Category metadata chips that are purely labels → `Tag` may fit better than a count-oriented badge.

## Criterio de uso

- Usa Badge para conteos cortos o estados secundarios próximos a un control o label, no para explicar una situación completa. - Si el número representa elementos no leídos, comunica también su significado: “3 mensajes sin leer”, no sólo “3”. - Mantén el badge inline y proporcional al contenido; una alerta que necesita lectura, acción o detalle debe usar feedback dedicado.

## Gotchas

- El color y la posición no deben ser la única forma de entender el estado. - Si el badge es decorativo junto a un título ya nombrado, puedes ocultarlo a tecnologías asistivas para evitar repetición. - **Nota**: Badge trunca con ellipsis si el texto excede max-width (36px). Para conteos grandes, formatea como '99+' desde el componente padre. - **Nota**: CSS autocontenido. Badge no tiene hover, transiciones ni animaciones — es un indicador estatico puro.

Uso

import { Badge } from '@/components/atoms/Badge';

<Badge variant="inbox" state="enabled">
  3
</Badge>

Props

PropTipoDefaultRango / opcionesWhatHow
variantselectneutral`neutral`, `inbox`Surface style of the status chip.neutral for quiet metadata; inbox for count/attention chips. Default: neutral.
stateselectenabled`enabled`, `focused`, `subtle`Emphasis of the badge relative to surrounding UI.enabled default; focused when the related control is active; subtle for de-emphasized counts.

Gotchas

  • a11y

    If the badge is a live count, expose the meaning in accessible text (e.g. aria-label on the parent control), not only the digit.

  • layout

    Badges are inline; do not stretch them as block-level status banners — use toast or alert patterns for that.

Anatomía CSS

<div class="badge">
  <span class="badge__label"></span>
</div>
ClasePropósito
badgeroot
badge--enabledmodifier
badge--focusedmodifier
badge--inboxmodifier
badge--neutralmodifier
badge--subtlemodifier
badge__labelelement

Tokens resueltos

Valores finales tras seguir la cadena de tokens. Derivados del source: si un token cambia, esta tabla cambia sola.

VariantePropValorToken
neutralbg#f5f5f5muted
neutralfg#0a0a0aforeground
neutralfocused-bg#0a0a0aprimary
neutralfocused-fg#fafafaprimary.foreground
neutralsubtle-bg#262626color.neutral800
neutralsubtle-fg#fafafacolor.neutral50
inboxbg#fb7a6ecolor.coral300
inboxfg#0a0a0acolor.neutral950
inboxfocused-bg#c21e12color.coral700
inboxfocused-fg#fafafacolor.neutral50
inboxsubtle-bg#f84131destructive
inboxsubtle-fg#0a0a0adestructive.foreground

CSS mínimo funcional

Autocontenido: sin imports ni tokens. Para previews y prototipos — en producción se consume el CSS del DS (@atom-uikit/css/components.css</code>, <code>@atom-uikit/tokens/tokens.css).

/* -------------------------------------------------------------------------
   Badge

   Numeric counter pill. Compact indicator for counts and notifications.
   Non-interactive. Fixed height (16px), pill shape, truncates with ellipsis.

   Variants: neutral, inbox
   States:   enabled, focused, subtle
   ------------------------------------------------------------------------- */

.badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1rem;
  max-width: 2.25rem;
  height: 1rem;
  padding: 0 4px;
  border-radius: 9999px;
  font-family: 'inter tight', -apple-system, blinkmacsystemfont, 'segoe ui', roboto, helvetica, arial, sans-serif;
  font-size: 10.24px;
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
  overflow: hidden;
}

.badge__label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-align: center;
  min-width: 1px;
}

/* ---- Neutral ---- */

.badge--neutral.badge--enabled {
  background-color: #f5f5f5;
  color: #0a0a0a;
}

.badge--neutral.badge--focused {
  background-color: #0a0a0a;
  color: #fafafa;
}

.badge--neutral.badge--subtle {
  background-color: #262626;
  color: #fafafa;
}

/* ---- Inbox ---- */

.badge--inbox.badge--enabled {
  background-color: #fb7a6e;
  color: #0a0a0a;
}

.badge--inbox.badge--focused {
  background-color: #c21e12;
  color: #fafafa;
}

.badge--inbox.badge--subtle {
  background-color: #f84131;
  color: #0a0a0a;
}

Codigo fuente

components-react
components/atoms/Badge.tsx
export type BadgeVariant = 'neutral' | 'inbox';
export type BadgeState = 'enabled' | 'focused' | 'subtle';

export type BadgeProps = {
  variant?: BadgeVariant;
  state?: BadgeState;
  children: string;
  className?: string;
};

function cn(...classes: (string | false | undefined | null)[]) {
  return classes.filter(Boolean).join(' ');
}

export function Badge({
  variant = 'neutral',
  state = 'enabled',
  children,
  className,
}: BadgeProps) {
  return (
    <span
      className={cn(
        'badge',
        `badge--${variant}`,
        `badge--${state}`,
        className,
      )}
    >
      <span className="badge__label">{children}</span>
    </span>
  );
}

Webflow

Webflowbadge

Pega en el Designer como application/json, luego convierte a Component (Atom / Badge) y publica. Formato interno no documentado de Webflow — regenerable, no dependencia de runtime.

Setup del sitio (una vez)

Custom Code → Head:

<link rel="stylesheet" href="https://atom-web-ds.vercel.app/v1/tokens.css">
<link rel="stylesheet" href="https://atom-web-ds.vercel.app/v1/components.css">

Unsupported (no silencioso)

  • selector on .badge--neutral.badge--enabledcompound/descendant selector — moved to head Custom Code (Designer styles are single-class)
  • selector on .badge--neutral.badge--focusedcompound/descendant selector — moved to head Custom Code (Designer styles are single-class)
  • selector on .badge--neutral.badge--subtlecompound/descendant selector — moved to head Custom Code (Designer styles are single-class)
  • selector on .badge--inbox.badge--enabledcompound/descendant selector — moved to head Custom Code (Designer styles are single-class)
  • selector on .badge--inbox.badge--focusedcompound/descendant selector — moved to head Custom Code (Designer styles are single-class)
  • selector on .badge--inbox.badge--subtlecompound/descendant selector — moved to head Custom Code (Designer styles are single-class)

Tras pegar: Create component → nombre Atom / Badge → Publish.

On this page

Detalles

Publicado14 de mayo de 2026
Categoriaindicators
Lectura...
Visitas...
Ayuda?Slack

Componente

Badge

Source

components-react / cssDisponible via MCP: atom_uikit_source("badge")