Skip to main content
Gremorie
Overlays

Sonner

Notificações toast transitórias construídas sobre o sonner. Monte o Toaster uma vez na raiz e dispare toast() de qualquer lugar.

Visão geral

Sonner é o primitivo de feedback transitório: "Saved", "Invite sent", "Failed - try again". Monte o Toaster uma vez na raiz da aplicação (tipicamente em app/layout.tsx) e dispare toast() de qualquer lugar da árvore, sem um provider adicional.

Para mensagens persistentes dentro do fluxo use Alert; para erros críticos que precisam de reconhecimento use AlertDialog. Toasts devem ser não bloqueantes e dispensáveis.

O Toaster do Gremorie segue automaticamente a classe .dark do documento e vem com ícones do Gremorie para os tipos de toast success, info, warning, error e loading.

Preview

'use client';import { Button } from '@gremorie/rx-forms';import { Toaster, toast } from '@gremorie/rx-overlays';export function SonnerPreview() {  return (    <>      <Button        variant="outline"        onClick={() =>          toast('Primitive added', {            description: 'rx-message is now available in your project.',          })        }      >        Show toast      </Button>      <Toaster />    </>  );}

Anatomia

Toaster                    mount singleton que renderiza a região de toasts
├─ toast(message, opts)    API imperativa disparada de qualquer lugar
│  ├─ toast.success        confirmação positiva
│  ├─ toast.error          falha que o usuário deve saber
│  ├─ toast.warning        estado arriscado, ainda não uma falha
│  ├─ toast.info           mensagem neutra do sistema
│  ├─ toast.loading        operação pendente
│  └─ toast.promise        transiciona automaticamente loading → success/error
└─ action                  botão de ação inline opcional em um toast

Instalação

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

Uso

Monte o Toaster uma vez na raiz da sua aplicação:

// app/layout.tsx
import { Toaster } from '@gremorie/rx-overlays';

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        {children}
        <Toaster />
      </body>
    </html>
  );
}

Depois dispare toasts de qualquer client component:

'use client';
import { Button } from '@gremorie/rx-forms';
import { toast } from '@gremorie/rx-overlays';

export function SaveButton() {
  return (
    <Button
      onClick={() =>
        toast.success('Saved', {
          description: 'Your changes are live.',
        })
      }
    >
      Save
    </Button>
  );
}

A edição Angular deste componente hoje é distribuída a partir do source (veja o workbench para o lado a lado); a entrada no registry vem a seguir.

API

<Toaster>

Envolve o Toaster do sonner com tokens e ícones do Gremorie. Monte uma vez por app.

PropTypeDefaultDescription
theme"light" | "dark" | "system"auto-detectado da classe .darkTema do toast. Passe explicitamente para sobrescrever a detecção pela classe do documento.
position"top-left" | "top-right" | "bottom-left" | "bottom-right" | "top-center" | "bottom-center""bottom-right"Onde os toasts se empilham.
richColorsbooleanfalseUsa fundos com cor codificada para success, error, warning, info.
expandbooleanfalseSempre expande a pilha em vez de colapsar no hover.
durationnumber4000Tempo de vida padrão do toast em milissegundos.
closeButtonbooleanfalseRenderiza um botão de fechar em cada toast.
gapnumber14Espaçamento vertical entre toasts empilhados.
offsetstring | number32Distância da borda da viewport.
visibleToastsnumber3Máximo de toasts visíveis ao mesmo tempo.

Todas as demais ToasterProps do sonner são encaminhadas.

toast(message, options?)

Toast padrão. Retorna um id de toast que você pode passar para toast.dismiss().

OptionTypeDescription
descriptionstring | ReactNodeLinha secundária abaixo da mensagem.
action{ label: string; onClick: () => void }Botão de ação inline único.
cancel{ label: string; onClick?: () => void }Botão secundário de cancel/undo.
durationnumberSobrescreve a duração padrão.
idstring | numberId customizado para atualizações ou dispensa posterior.
onDismiss(toast) => voidDisparado quando o toast é dispensado.
onAutoClose(toast) => voidDisparado quando o toast fecha automaticamente.

Atalhos tipados

MethodIconWhen to use
toast.success(message, options)CircleCheckConfirmação positiva.
toast.error(message, options)OctagonXFalha que o usuário deve saber.
toast.warning(message, options)TriangleAlertEstado arriscado que ainda não é uma falha.
toast.info(message, options)InfoMensagem neutra do sistema.
toast.loading(message, options)Loader2 (animado)Operação pendente. Emparelhe com toast.success na resolução.
toast.promise(promise, opts)Loader2 e depois o ícone resolvidoTransiciona automaticamente loading → success/error a partir de uma Promise.
toast.custom(jsx, options)-Corpo de toast totalmente customizado.
toast.dismiss(id?)-Dispensa um toast específico ou todos.

Assinatura de toast.promise:

toast.promise(savePost(), {
  loading: 'Saving...',
  success: (data) => `Saved post #${data.id}`,
  error: 'Save failed',
});

Composição

  1. <Toaster> na raiz do app (app/layout.tsx para Next.js).
  2. toast() disparado imperativamente a partir de event handlers, fluxos assíncronos ou effects.
  3. action opcional para undo ou navegação de follow-up.
  4. toast.promise para qualquer fluxo aguardável que deva comunicar progresso.

Variações

Tipos de toast

Cada botão dispara um toast diferente: default, success, error, um com ação inline e uma promise que transiciona de loading para success.

'use client';import { Button } from '@gremorie/rx-forms';import { Toaster, toast } from '@gremorie/rx-overlays';export function SonnerVariantsPreview() {  return (    <>      <div className="flex flex-wrap gap-2">        <Button          variant="outline"          onClick={() =>            toast('Event created', {              description: 'Friday, June 20 at 10:00 AM',            })          }        >          Default        </Button>        <Button          variant="outline"          onClick={() =>            toast.success('Changes saved', {              description: 'Your profile is up to date.',            })          }        >          Success        </Button>        <Button          variant="outline"          onClick={() =>            toast.error('Save failed', {              description: 'Check your connection and try again.',            })          }        >          Error        </Button>        <Button          variant="outline"          onClick={() =>            toast('Item archived', {              description: 'You can restore it within 30 days.',              action: {                label: 'Undo',                onClick: () => toast('Restored'),              },            })          }        >          With action        </Button>        <Button          variant="outline"          onClick={() =>            toast.promise(new Promise((resolve) => setTimeout(resolve, 1500)), {              loading: 'Publishing post...',              success: 'Post is live',              error: 'Publish failed',            })          }        >          Promise        </Button>      </div>      <Toaster />    </>  );}

Success com undo

O padrão canônico "salvo com undo".

toast.success('Item archived', {
  description: 'You can restore it within 30 days.',
  action: {
    label: 'Undo',
    onClick: () => restore(item.id),
  },
});

Promise

Dirija os estados de loading, success e error a partir de uma única chamada.

toast.promise(api.publish(post), {
  loading: 'Publishing post...',
  success: (post) => `${post.title} is live`,
  error: 'Publish failed - retry?',
});

Posição customizada com rich colors

Pilha top-center com fundos semânticos.

<Toaster position="top-center" richColors duration={5000} />

Toast de erro persistente

Desabilite o auto-close para falhas que exigem a atenção do usuário.

toast.error('Connection lost', {
  description: 'Reconnecting...',
  duration: Infinity,
  action: {
    label: 'Retry now',
    onClick: () => reconnect(),
  },
});

Acessibilidade

  • Live region: os toasts anunciam via aria-live="polite" por padrão; a tecnologia assistiva os lê sem interromper.
  • Erros: toast.error usa aria-live="assertive" para que as falhas sejam lidas imediatamente.
  • Dispensa: Esc dispensa o toast mais recente quando um deles está focado.
  • Hover e focus: passar o cursor ou focar a pilha pausa o timer de auto-dismiss.
  • Teclado: os botões de ação dentro dos toasts são alcançáveis via Tab uma vez que a pilha está focada.
  • Tema: o Toaster observa automaticamente a classe .dark do documento; passe theme explicitamente ao montar em um iframe ou sandbox sem tema.
  • Touch: o swipe-to-dismiss é implementado pelo sonner; usuários de teclado podem dispensar via Esc.
  • Reduced motion: as animações de entrada/saída respeitam prefers-reduced-motion.

Relacionados

  • Alert - mensagem persistente no fluxo que vive no layout.
  • Alert Dialog - confirmação interruptiva para ações irreversíveis.
  • Dialog - modal focado para fluxos curtos.

On this page