# Toast

Notificação flutuante para feedback transitório após uma ação do usuário.

> Documentação do Sinapse DS. Snippets shadcn usam os componentes do seu projeto (`@/components/ui/*`); snippets HTML usam as classes `itps-*` do CSS Sinapse (`/css/<versão>/`, veja `/comecar.md`). Componentes do site de documentação não fazem parte do DS.

- Categoria: Feedback
- Status: stable
- Relacionados: /componentes/banner.md, /componentes/callout.md

## Em cada stack

- HTML e Astro: Classes `itps-*` do CSS Sinapse, com todas as variantes desta página.
- React e Vue: Componentes padrão do shadcn (`sonner`) com o tema Sinapse: cores, fonte e raio vêm do tema, e as variantes `itps-*` desta página existem só no HTML. O Button é o Sinapse.

**React/Next (shadcn/ui)**

```tsx
import { Button } from '@/components/ui/button'
import { Toaster } from '@/components/ui/sonner'
import { toast } from 'sonner'

export function ToastExample() {
  return (
    <>
      <Button
        variant="itps"
        onClick={() =>
          toast.success('Prontuário salvo', {
            description: 'Suas alterações foram aplicadas com sucesso.',
          })
        }
      >
        Mostrar notificação
      </Button>
      <Toaster />
    </>
  )
}
```

**Vue 3/Nuxt 4 (shadcn-vue)**

```vue
<script setup lang="ts">
import { Button } from '@/components/ui/button'
import { Toaster } from '@/components/ui/sonner'
import { toast } from 'vue-sonner'
</script>

<template>
  <Button
    variant="itps"
    @click="toast.success('Prontuário salvo', {
      description: 'Suas alterações foram aplicadas com sucesso.',
    })"
  >
    Mostrar notificação
  </Button>
  <Toaster />
</template>
```

**HTML (copy-first)**

```html
<div role="status" aria-live="polite" class="itps-toast itps-toast--success" data-toast>
  <span class="itps-toast__icon" aria-hidden="true">
    <i class="ti ti-check" aria-hidden="true"></i>
  </span>
  <div class="itps-toast__content">
    <p class="itps-toast__title">Prontuário salvo</p>
    <p class="itps-toast__description">Suas alterações foram aplicadas com sucesso.</p>
  </div>
  <button type="button" class="itps-toast__close" aria-label="Fechar notificação" data-toast-close>
    <i class="ti ti-x" aria-hidden="true"></i>
  </button>
</div>
```

## Instalação

O comando instala o Sonner da sua stack e o Button Sinapse com o tema Sinapse. Configure o registry uma vez por projeto em [Comece por aqui](/comecar).

**terminal · React/Next**

```sh
pnpm dlx shadcn@latest add @sinapse/toast
```

**terminal · Vue 3/Nuxt 4**

```sh
pnpm dlx shadcn-vue@latest add https://dsystem.sinapse.org.br/r/vue/toast.json
```

Sem shadcn, não há instalação por componente: use o CSS Sinapse e as classes da API copy-first desta página.

## Uso

Em React/Next com shadcn/ui e Vue 3/Nuxt 4 com shadcn-vue, use `sonner`: renderize `Toaster` uma vez no app e dispare feedback com `toast.success`, `toast.error`, `toast.info` ou `toast.loading`.

Para HTML ou wrappers finos, use `itps-toast` quando precisar do contrato copy-first. Este site inicializa `.itps-toast[data-toast]` e fecha controles marcados com `data-toast-close` (script não incluído no pacote).

Use Toast para feedback transitório após ação do usuário. Para aviso persistente, use Banner; para contexto local, Callout; para validação de campo, o erro do Field.

## Exemplos

### Estrutura

| Peça | React/Next e Vue 3/Nuxt 4 | HTML |
|------|--------------------------|------|
| Contêiner | `Toaster` | contêiner fixo da aplicação |
| Disparo | `toast.success(...)` | inserir/remover `.itps-toast` |
| Toast | Sonner renderiza | `itps-toast[data-toast]` |
| Título | `message` | `itps-toast__title` |
| Descrição | `description` | `itps-toast__description` |
| Fechar | Sonner gerencia | `[data-toast-close]` |

### Empilhamento e status

Use status para comunicar severidade: `success` e `info` usam `aria-live="polite"`; `error` pode usar `role="alert"` quando a falha precisa ser anunciada imediatamente.

**HTML (copy-first)**

```html
<div class="flex w-full max-w-[480px] flex-col gap-2">
  <div role="status" aria-live="polite" class="itps-toast itps-toast--loading" data-toast>
    <span class="itps-toast__icon" aria-hidden="true">
      <span class="itps-toast__spinner" aria-hidden="true"></span>
    </span>
    <div class="itps-toast__content">
      <p class="itps-toast__title">Enviando documento</p>
      <p class="itps-toast__description">Aguarde a conclusão do envio.</p>
    </div>
  </div>

  <div role="alert" aria-live="assertive" class="itps-toast itps-toast--error" data-toast>
    <span class="itps-toast__icon" aria-hidden="true">
      <i class="ti ti-alert-circle" aria-hidden="true"></i>
    </span>
    <div class="itps-toast__content">
      <p class="itps-toast__title">Falha ao salvar</p>
      <p class="itps-toast__description">Verifique a conexão e tente novamente.</p>
      <div class="itps-toast__actions">
        <a href="#" class="itps-toast__action">Tentar novamente</a>
      </div>
    </div>
    <button type="button" class="itps-toast__close" aria-label="Fechar notificação" data-toast-close>
      <i class="ti ti-x" aria-hidden="true"></i>
    </button>
  </div>
</div>
```

## API copy-first

| Classe/atributo | Uso |
|-----------------|-----|
| `itps-toast` | Superfície da notificação. |
| `itps-toast--info`, `itps-toast--success`, `itps-toast--alert`, `itps-toast--error`, `itps-toast--loading` | Status visual. |
| `itps-toast__icon`, `itps-toast__content`, `itps-toast__title`, `itps-toast__description`, `itps-toast__actions`, `itps-toast__close` | Anatomia interna. |
| `data-toast` | Marca a notificação inicializável pelo script. |
| `data-toast-close` | Fecha e remove a notificação atual. |
| `role`, `aria-live` | Define prioridade de anúncio. |
| `aria-label` | Nomeia o botão de fechar. |
| `aria-hidden="true"` | Esconde ícones decorativos de tecnologias assistivas. |

## Acessibilidade

Use `role="status"` e `aria-live="polite"` para sucesso, informação, aviso e carregamento. Use `role="alert"` e `aria-live="assertive"` só para falhas que precisam interromper a fila de anúncio.

Tempo e teclado:

| Regra | Como aplicar |
|-------|--------------|
| Tempo na tela | Se o toast some sozinho, deixe pelo menos 5 segundos e mais tempo para textos longos. Erros ficam até a pessoa fechar. |
| Pausa | O tempo para enquanto o mouse ou o foco estiver sobre o toast. |
| Fechar | O botão Fechar é um `<button>` com `aria-label`, alcançável pelo Tab. |
| Ações | Não coloque a única forma de fazer algo em um toast que some. "Desfazer" pode aparecer no toast, mas a ação também precisa existir na tela. |
| Região de anúncio | Mantenha o contêiner com `role="status"` ou `aria-live` na página antes de inserir o toast; muitos leitores de tela não anunciam uma região criada junto com a mensagem. |

No shadcn, o `sonner` já pausa o tempo com o mouse sobre o toast; use `duration` para aumentar o tempo e `duration: Infinity` para erros. Na API copy-first, os toasts deste site não somem sozinhos; se o produto adicionar tempo, implemente a pausa.
