KDS
Feedback

Alert

Mensagem persistente, em fluxo de página — distinto de Toast (transiente) e Banner (page-spanning).

Overview

Alert é a mensagem persistente, em fluxo do KDS. Aparece dentro da página (não em overlay) e fica até que o usuário ou o sistema a remova. Convive com dois irmãos:

  • Toast (Phase 2 — Sonner): transitivo, flutuante. Some sozinho.
  • Banner (futuro): page-spanning, no topo do app. Comunica algo global (manutenção, conta suspensa).
  • Alert: in-flow, contextual. Persistente.

A escolha errada aqui é a fonte mais comum de UX confuso — Alert para algo passageiro vira ruído visual; Toast para algo crítico desaparece antes do usuário ler.

shadcn entrega apenas duas variantes: default e destructive. KDS não introduz mais variantes visuais. Para semântica de info/success/warning, use um ícone à esquerda e mantenha a variante default. Mantém a paleta enxuta e força uma hierarquia clara: variante destructive é só para erros.

Preview
Alert default com ícone informacional.

Anatomy

<Alert variant="default">
  ├─ [data-slot="alert"]
  ├─ role="alert"
  ├─ <Icon /> (opcional — primeiro filho, ocupa col 1)
  ├─ <AlertTitle />        ← linha de cabeçalho, font-medium
  └─ <AlertDescription />   ← corpo, text-muted-foreground
</Alert>

O grid CSS reserva uma coluna para o ícone (grid-cols-[0_1fr]grid-cols-[calc(var(--spacing)*4)_1fr] quando há SVG). Sem ícone, título e descrição ocupam tudo.

Subcomponents

ComponenteDescrição
AlertContainer com role="alert" e variante.
AlertTitleHeadline — font-medium, tracking-tight.
AlertDescriptionCorpo do texto — text-muted-foreground.

Usage

import { Alert, AlertDescription, AlertTitle } from "@kalvner/kds/feedback/alert";
import { Info } from "lucide-react";

export function MaintenanceNotice() {
  return (
    <Alert>
      <Info />
      <AlertTitle>Manutenção programada</AlertTitle>
      <AlertDescription>
        O sistema ficará indisponível domingo, das 02:00 às 04:00 (BRT).
      </AlertDescription>
    </Alert>
  );
}

Props

Alert

PropTipoDefaultDescrição
variant'default' | 'destructive''default'Variante visual.
...restReact.ComponentProps<'div'>Tudo o que <div> aceita. role="alert" é fixo.

AlertTitle / AlertDescription

Aceitam todos os props de <div> (className, id).

Variants

Default
Texto neutro em fundo card. Use ícone para semântica.
Destructive
Reservado para erros — tom destructive.

Padrões semânticos via ícone

shadcn entrega apenas default e destructive. Para informacional / sucesso / aviso, KDS usa default + ícone semântico:

Info
Ícone Info, variante default.
Success
CheckCircle2 em emerald-600.
Warning
AlertTriangle em amber-600.

States

With action
Alert com ação à direita — Reconectar, Tentar novamente.

Composition

Form-level error
Alert no topo de um form, agregando erros do servidor.
In-page success
Confirmação após salvar — sticky até next mudança.

When to use

  • Erros de validação agregados no topo de um formulário (não inline em cada campo — esses ficam em FormMessage).
  • Confirmação que precisa ficar visível por mais que segundos — "Configurações salvas" enquanto o usuário ainda olha a tela.
  • Avisos contextuais em settings ("Workspaces privados não são listados").
  • Estado degradado em uma área específica ("Sincronização pausada — clique para reconectar").

When not to use

  • Para feedback breve de uma ação (Item adicionado, Copiado pra clipboard) — use Toast (Sonner, Phase 2).
  • Para anúncios globais que afetam o app inteiro — use Banner no topo do layout (futuro Phase).
  • Para erros de campo específicos em um form — use FormMessage, inline abaixo do campo. Alert no topo deve ser para o agregado.
  • Para diálogos de confirmação — use Dialog/AlertDialog (Phase 2).

Best practices

  • Um Alert por superfície. Múltiplos Alerts competem por atenção e o usuário ignora todos. Se você está empilhando 3, consolide em um Alert com lista interna.
  • Variante destructive só para erros. "Beta" não é destructive, "Em rascunho" não é destructive. Reserve para falhas de verdade.
  • Ícone reforça, não substitui texto. Mesmo com ícone, Title e Description devem ser auto-suficientes — leitores de tela pulam SVG decorativo.
  • Não anime altura na entrada. Alert que cresce/encolhe causa CLS — ver [[ui/layout/cumulative-layout-shift]]. Renderize em posição fixa ou reserve espaço com min-height.
  • Texto direto. Evite "Houve um problema." Diga o que aconteceu e, idealmente, o que fazer.

Accessibility

ConcernComportamento
Rolesrole="alert" aplicado pelo componente — leitores de tela anunciam o conteúdo assim que aparece.
Live regionrole="alert" é uma aria-live="assertive" implícita. Mantém para erros críticos; para info passiva, considere envolver em região com aria-live="polite".
KeyboardAlert em si não recebe foco. Quando há ação inline, garanta que o botão da ação está no fluxo de tab natural.
Cor + ícone + textoVariante destructive usa cor para semântica — combine com ícone (XCircle) e texto claro (Erro, Falhou) para usuários com daltonismo.
Não use Alert para confirmaçãorole="alertdialog" é diferente — esse exige Dialog/AlertDialog (Phase 2) com gestão de foco.
Animação de entradaSe animar entrada, evite mover conteúdo abaixo. Use opacity + altura reservada.
  • Button — para a ação inline ("Reconectar", "Tentar novamente").
  • Form — Alert costuma sentar acima de formulários para erros agregados.
  • Toast (Phase 2) — feedback transitivo em vez de in-flow.
  • [[ui/layout/cumulative-layout-shift]] — sobre por que reservar espaço em vez de empurrar conteúdo.

On this page