# Badge di stato: testo e colore, mai solo colore

Un badge di stato dice lo stato a parole e lo conferma con il colore: quattro varianti, un'etichetta per stato e contrasto 4.5:1 sul testo piccolo.

> Pagina: https://ui.eneawork.it/blog/shadcn-badge-status
> Markdown: https://ui.eneawork.it/blog/shadcn-badge-status.md

*2026-11-01*

Risposta breve: un badge di stato porta sempre un'etichetta scritta e usa il colore come conferma. Mappa ogni stato su una variante di Badge e su un testo fisso, poi verifica il contrasto: 4.5:1, perché il testo è piccolo.

Nell'indice dei blocchi pubblicato 16 blocchi hanno «badge» nel nome, contati il 1 novembre 2026 nel file sitemap-blocks.xml, su 1.556 blocchi totali. Il catalogo EneUI misura 111.985 componenti, 1.556 blocchi e 12.808 icone da 1.472 librerie, letti da /api/stats il 1 novembre 2026. Le soglie di contrasto vengono da WCAG 2.2 AA, criterio 1.4.3.

## Quattro varianti, cinque stati

La mappa vive in un oggetto tipizzato, non in una catena di if. Così uno stato nuovo non compila finché non ha la sua etichetta, e il testo non può restare indietro rispetto al colore.

import { Badge } from "@/components/ui/badge"; const tones = { active: { variant: "default", label: "Attivo" }, pending: { variant: "secondary", label: "In attesa" }, failed: { variant: "destructive", label: "Fallito" }, draft: { variant: "outline", label: "Bozza" }, } as const; export type State = keyof typeof tones; export function StatusBadge({ state }: { state: State }) { const tone = tones[state]; return {tone.label}; }

## Il colore di un quinto stato

Un avviso giallo non è una variante di Badge: è un token nuovo. Si aggiunge con i tre passaggi del tema, valore chiaro, valore scuro e mappatura in @theme inline, poi si crea una variante locale nel file del componente. Il procedimento è in come tematizzare shadcn.

## Forma, dimensione e annunci

Fonte: il criterio WCAG 2.2 1.4.1 vieta di usare il solo colore per trasmettere informazione, e il criterio 1.4.3 chiede 4.5:1 per il testo normale, che è la taglia di un badge; il componente badge.tsx di shadcn/ui è distribuito con licenza MIT.

## Limite dichiarato

La variante destructive è pensata per le azioni, non per gli stati: usata su un badge «Fallito» funziona, ma su una tabella di dieci righe fallite diventa rumore e perde il segnale. Secondo limite: il badge non è una live region, quindi uno stato che cambia dopo un fetch non viene annunciato da un lettore di schermo finché non aggiungi role="status" al contenitore giusto.

## Dove continuare

Nel catalogo trovi la libreria shadcn, un blocco badge con anteprima e i blocchi della categoria dashboard. Il metodo per misurare le coppie di colore è in palette UI e contrasto misurato, i token in come tematizzare shadcn; il confronto tra temi pronti è temi shadcn gratis o premium. Per il badge dentro una tabella lunga leggi le migliori librerie di tabella React; per uno stato scritto invece che colorato, accordion per le FAQ.

## FAQ

### Posso usare solo il pallino colorato senza testo?

No. Il criterio WCAG 2.2 1.4.1 chiede che il colore non sia l'unico veicolo dell'informazione: serve un'etichetta scritta, oppure un `aria-label` che la sostituisca.

### Quale contrasto serve per il testo del badge?

4.5:1, perché il testo di un badge è piccolo: la soglia 3:1 vale solo per testo grande, da 18.66px in grassetto o 24px normale.

### Come aggiungo uno stato di avviso giallo?

Definisci `--warning` e `--warning-foreground` in `:root` e `.dark`, mappali in `@theme inline`, poi aggiungi una variante locale a `badge.tsx`. Senza la mappatura la utility non esiste.

### Il badge deve essere un link o un pulsante?

Nessuno dei due: è un'etichetta. Se deve filtrare la tabella, metti il filtro su un `Button` accanto e lascia il badge come testo, altrimenti l'utente non sa cosa è cliccabile.

### Il cambio di stato viene annunciato dai lettori di schermo?

Non dal badge. Aggiungi `role="status"` al contenitore che cambia e lascia che il testo del badge sia il contenuto annunciato, senza `aria-live` sul badge stesso.
