KDS
Overlays

Sonner

Toasts transientes flutuantes — feedback breve que não bloqueia, com promise / undo embutidos.

Overview

Sonner é o sistema de toasts transientes do KDS. Toasts são mensagens flutuantes que aparecem por alguns segundos e somem — feedback breve que não bloqueia o fluxo. KDS usa a biblioteca sonner do Emil Kowalski; ela cuida de stacking, swipe-to-dismiss, animação suave e variantes semânticas.

A hierarquia de feedback é importante:

PrimitiveFormaTempoUso
Sonner (toast)flutuante, canto da tela4–6s"Salvo", "Convite enviado", "Excluído. Desfazer."
Alertin-flow, parte da páginapersistente"Sessão expirada", "Plano quase no limite"
Banner (próximo)page-spanning topopersistente"Manutenção programada para hoje 02:00"
AlertDialogmodal bloqueanteexige ação"Excluir conta para sempre?"

Toast é o canal certo para a maioria dos resultados — Salvo, Falhou, Enviado. Para algo que o usuário precisa ler antes de agir, escale.

Preview
Clique para disparar um toast padrão.

Anatomy

// app/layout.tsx — uma vez no root
<Toaster />

// em qualquer componente
import { toast } from "@kalvner/kds/overlays/sonner";

toast("Mensagem")
toast.success("Convite enviado")
toast.error("Falha ao salvar")
toast.info("Manutenção programada")
toast.warning("Plano quase no limite")
toast.promise(promise, { loading, success, error })

Toaster é o mount root. O toast() é uma função imperativa — não precisa de provider, não precisa de hook. Funciona de qualquer lugar.

Subcomponents / API

APIDescrição
<Toaster />Mount no root da app (uma única vez).
toast(message)Toast neutro.
toast.success(message)Variante success com ícone.
toast.error(message)Variante error com ícone.
toast.info(message)Variante info.
toast.warning(message)Variante warning.
toast.promise(promise, { loading, success, error })Mostra loading e troca para success ou error quando a promessa resolve.
toast(message, { description, action })Toast com descrição e/ou botão de ação (ex.: "Desfazer").

Usage

// app/layout.tsx
import { Toaster } from "@kalvner/kds/overlays/sonner";

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        {children}
        <Toaster />
      </body>
    </html>
  );
}
// any component
"use client";
import { toast } from "@kalvner/kds/overlays/sonner";
import { Button } from "@kalvner/kds/forms/button";

export function SaveButton() {
  return (
    <Button onClick={() => toast.success("Salvo")}>Salvar</Button>
  );
}

Variants

Default
Toast neutro, sem ícone.
Success
Operação concluída.
Error
Operação falhou (não-crítica).
Info
Informação neutra.
Warning
Atenção sem bloqueio.
With description
Linha extra de contexto.

Composition

Undo affordance (Tier 2 stakes)

Fecha o loop com a Tier 2 do modelo de stakes em Dialog. Após confirmar "Excluir", o toast "Excluído. Desfazer." dá ~6s para reverter.

Promise toast

toast.promise(...) mostra loading → success/error automaticamente.

When to use

  • Confirmar uma ação concluída — "Salvo", "Enviado", "Convidado".
  • Fechar o loop de Tier 2 do stakes model — "Excluído. Desfazer."
  • Mostrar progresso de operações async com toast.promise(...).
  • Erros recuperáveis e não-bloqueantes ("Falhou — tente de novo").

When not to use

  • Para erros críticos que precisam acknowledgment — use AlertDialog ou Alert in-flow com botão de ação.
  • Para mensagens persistentes — use Alert ou Banner.
  • Para confirmações antes de uma ação — use Dialog ou AlertDialog.
  • Para feedback que precisa ficar visível por mais de 10s — toast some, e o usuário pode ter perdido. Use Alert.

Best practices

  • Auto-dismiss em 4–6s. Default do sonner é 4s. Nunca abaixo de 3s — usuários com leitura mais lenta perdem a mensagem.
  • Mensagem curta. Toast é uma frase. Se precisa de duas linhas, use description para a segunda. Mais que isso, é Alert.
  • Toast destrutivo + undo. Sempre que possível, expor undo. Reduz o custo de erros de Tier 2 a quase zero.
  • Não empilhe toasts iguais. Sonner faz dedup automaticamente via id; passe um id estável quando a mesma operação puder ser repetida.
  • Não substitua Alert por toast em forms. Erro de validação fica inline, na linha do campo. Falha de rede agregada vai para Alert no topo do form. Toast é para feedback após envio.
  • Toaster vai uma vez. Se você montar dois Toasters por acidente, vai ver duplicação. Mount no layout.tsx, não em páginas.

Accessibility

ConcernComportamento
RolesSonner usa role="status" (default) ou role="alert" (para errors), com aria-live.
FocoToasts não roubam foco. Usuário continua trabalhando.
KeyboardToast com action (Desfazer) é alcançável via Tab da próxima vez que o trigger ganhar foco.
Screen readeraria-live="polite" (default) ou aria-live="assertive" (errors). Mensagens são anunciadas sem interromper o que o usuário estiver fazendo.
Reduced motionA entrada/saída respeita prefers-reduced-motion no nível do tema.
  • Alert — feedback persistente em fluxo.
  • AlertDialog — confirmação modal antes da ação.
  • Dialog — referência ao modelo de stakes.

On this page