CommunityImagemgithub.com

RevantThota55/FreeFrame-Studio

Guia para Sonner, a biblioteca React de toasts — instale e configure o Toaster, escolha a chamada toast() correta, toasts de promise e carregamento, atualização, dispensa e persistência de toasts, estilo, temas e ícones, posicionamento e múltiplos toasters. Use ao trabalhar com Sonner ou para solucionar problemas — toasts que não aparecem, aparecem duas vezes, perdem o estilo, ignoram classes Tailwind, ficam atrás de um modal ou não seguem o modo escuro.

O que é FreeFrame-Studio?

Esta skill fornece um guia completo e prático para a biblioteca Sonner, a solução moderna de toasts para React. Ela ensina desde a configuração inicial — com a montagem única do componente `<Toaster />` — até as chamadas corretas da função `toast()` para diferentes cenários: mensagens simples, sucesso/erro, carregamento com promise, atualização por ID, persistência e até criação de toasts com JSX personalizado. A documentação detalha uma escada de estilização progressiva: comece com os padrões e `richColors`, passe por ajustes inline e classes com `!important`, e, se necessário, adote a abordagem headless com `toast.custom()` para controle total sobre a renderização. Além disso, a skill inclui uma tabela de solução de problemas abrangente que cobre desde toasts que não aparecem (falta do Toaster, chamada em server action) até problemas com estilos perdidos, modo escuro ignorado, toasts duplicados ou sobrepostos por modais, com causas e correções claras. É ideal para desenvolvedores React, Next.js, Astro e qualquer framework que use Sonner, oferecendo tanto o passo a passo de uso quanto diagnósticos rápidos para os bugs mais comuns.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/RevanthThota55/FreeFrame-Studio/tree/HEAD/.claude/skills/ask-sonner

Installed? Explore more Imagem skills: steipete/songsee, affaan-m/frontend-design, mattpocock/improve-codebase-architecture · View all 6 →

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Trabalhando com Sonner

Resposta Inicial

Quando esta skill for invocada pela primeira vez sem uma pergunta específica, responda apenas com:

Estou pronto para ajudá-lo a configurar, estilizar e solucionar problemas com Sonner. Meu conhecimento vem de seu autor, Emil Kowalski.

Não forneça nenhuma outra informação até que o usuário faça uma pergunta.

Uma skill guia para Sonner, a biblioteca de toasts. Quando uma tarefa envolve Sonner — configurá-la, renderizar toasts, estilizá-los ou corrigi-los — responda a partir deste arquivo primeiro. Tabelas completas de props para <Toaster /> e toast() estão em API.md; leia-o quando precisar de um nome de prop exato, tipo ou valor padrão.

Configuração

Duas peças, e apenas duas:

  1. Um <Toaster />, montado uma vez, o mais próximo possível da raiz (em Next.js: layout.tsx — funciona dentro de componentes de servidor). Nunca o renderize por página ou condicionalmente; um segundo Toaster montado duplica cada toast.
  2. toast() chamado a partir do código cliente — manipuladores de eventos, efeitos, callbacks. É uma função simples, sem necessidade de hook ou provider, mas não faz nada no servidor: em uma server action, retorne o resultado e chame toast() no código cliente que o recebe.
import { Toaster } from 'sonner'; // uma vez, no layout
import { toast } from 'sonner';   // em qualquer lugar no lado do cliente

Escolhendo a chamada correta

Você querChamada
Mensagem simplestoast('Título') — adicione { description } para uma segunda linha
Ícone de sucesso / erro / info / avisotoast.success('…'), toast.error('…'), etc.
Spinner enquanto você gerencia o estado manualmentetoast.loading('…'), então atualize-o pelo id
Carregamento → sucesso/erro vinculado a uma promisetoast.promise(promise, { loading, success, error }) — success/error aceitam funções que recebem o valor resolvido/erro
Botão que faz algo{ action: { label, onClick } } — fecha o toast a menos que onClick chame event.preventDefault(); cancel é a variante secundária
JSX personalizado, shell de toast padrãotoast(<jsx />)
JSX personalizado, sem estilostoast.custom((t) => <jsx />) — headless, t fornece o id para descartar

Receitas

Atualizar um toast — chame toast() novamente com o mesmo id; apenas as props que você passar mudam. Mudar para toast.success(…, { id }) altera o tipo. É assim que fluxos de loading → success funcionam sem toast.promise:

const id = toast.loading('Enviando…');
toast.success('Enviado', { id });

Persistir — { duration: Infinity }. Dispensar — toast.dismiss(id), ou toast.dismiss() para todos. Ler toasts ativos — useSonner() no React, toast.getActiveToasts() fora dele.

Links ou componentes no texto — passe uma função para o título ou descrição: toast(() => <a href="…">Ver</a>).

Múltiplos toasters — dê a cada um um id e direcione com toast('…', { toasterId: 'canvas' }). Sem toasterId, cada toaster renderiza o toast.

Callbacks de fechamento — onDismiss dispara no botão de fechar ou deslize; onAutoClose dispara no timeout. Eles são separados; não existe um único callback "fechado".

Estilização — a escada de escalada

Suba apenas até onde a mudança exigir; pular para o degrau mais alto muito cedo é aceitável (é o estado final recomendado), mas permanecer no meio não é.

  1. Padrões — mais richColors no Toaster para sucesso/erro coloridos, invert para inverter contra o tema.
  2. Ajustes inline — toastOptions={{ style: {…} }} no Toaster para todos os toasts, ou style por chamada toast().
  3. Classes nas partes — toastOptions={{ classNames: { toast, title, description, actionButton, cancelButton, closeButton } }}. Os estilos injetados do Sonner vencem a cascata, então toda classe precisa de !important (Tailwind: !text-red-900). Se você estiver marcando mais do que algumas coisas como important, pare — vá para headless.
  4. Headless — toast.custom() com seu próprio JSX, mantendo o posicionamento, empilhamento e deslize do Sonner. A abordagem recomendada para um toast de design system: envolva-o em sua própria abstração toast(). (unstyled: true existe como um meio-termo, mas headless dá mais controle pelo mesmo esforço.)

Ícones — troque os padrões por tipo com a prop icons do Toaster, por toast com icon, remova com null.

Tema — theme padrão é 'light' e não acompanha o SO. Passe theme="system", ou conecte seu provedor de tema: <Toaster theme={resolvedTheme} /> de next-themes.

Solução de Problemas

SintomaCausa → Correção
Toast nunca apareceNenhum <Toaster /> montado, ou ele foi desmontado (renderização condicional, posicionamento por página). Monte um na raiz. Se chamado de uma server action: toast() é apenas cliente — chame-o com o resultado da ação no cliente.
Mesmo toast aparece duas vezesDois Toasters montados (layout e página) — mantenha um. Ou toast() disparado em um efeito sob a dupla invocação de desenvolvimento do React StrictMode — dispare a partir do manipulador de evento, ou passe um id estável para que a segunda chamada atualize em vez de duplicar.
Classes CSS/Tailwind não têm efeitoOs estilos padrão os sobrescrevem. Marque-os com !important, ou use unstyled / headless (veja a escada acima).
Toasts renderizam completamente sem estilo (comum em Astro, transições de visualização)A folha de estilo injetada do Sonner foi perdida — importe-a explicitamente em um layout: import 'sonner/dist/styles.css'.
Sem estilo dentro de Shadow DOMOs estilos vão para document.head, não para a shadow root. Copie a tag de estilo cujo texto inclui [data-sonner-toaster] para a shadow root.
Toast atrás de um modal/overlay, ou cortadoUm ancestral cria um contexto de empilhamento (transform, filter, overflow) ou o overlay tem um z-index maior que o toaster. Mova <Toaster /> para a raiz do documento, fora de qualquer contêiner de diálogo/portal.
Modo escuro ignoradotheme padrão é 'light' — defina theme="system" ou passe o tema resolvido (veja Tema acima).
Sucesso/erro parecem cinza, não verde/vermelhoEsse é o padrão. Adicione richColors ao Toaster.
Toast nunca fechaduration: Infinity, dismissible: false, ou uma toast.promise cuja promise nunca se resolve — o toast de loading espera para sempre.
toast.promise preso em loadingPrecisa de uma promise (ou uma função que retorna uma) como primeiro argumento, e a promise deve de fato resolver/rejeitar.
Deslizar para descartar vai na direção errada / não funcionaAs direções derivam de position. Substitua com swipeDirections no Toaster.
Toast aparece em todos os toastersMúltiplos toasters precisam de direcionamento: dê a cada Toaster um id e passe toasterId na chamada toast().
Toasts muito próximos da borda da tela no mobileoffset (desktop, padrão 32px) e mobileOffset (<600px, padrão 16px) — números, strings CSS, ou objetos por lado.

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

RevanthThota55/FreeFrame-Studio

Build an animation from scratch, making the decisions in the order that determines whether it feels right — should it animate at all, what purpose, which tool, which properties, which curve and duration, how it interrupts, how it exits. Writes the implementation. Use when asked to animate something, add motion, make a component feel alive, or build a transition. For critiquing existing motion use review-animations; for auditing a whole codebase use improve-animations.

RevanthThota55/FreeFrame-Studio

Keep web animations inside the frame budget — animate composite-only properties, keep motion off the main thread when the page is busy, and find the cause when an animation drops frames. Covers the layout/paint/composite pipeline, cheaper property swaps, CSS vs WAAPI vs requestAnimationFrame, Framer Motion's hardware-accelerated path, React re-rendering per frame, inherited CSS variable recalculation, blur cost, and when `will-change` actually helps. Use when an animation is janky, choppy, stutters, or drops frames; when choosing which property to animate; when deciding between CSS and JS animation on performance grounds; or when reaching for `will-change` or GPU layers. For choosing easing, duration, or whether to animate at all use animate; for reviewing motion as a whole use review-animations.

RevanthThota55/FreeFrame-Studio

Reverse-lookup glossary that turns a vague description of a web animation or motion effect into its exact term ("the bouncy thing when a popover opens" → Pop in; "the iOS rubber-band scroll" → Rubber-banding). Use when the user asks "what's it called when…", or describes a motion effect without knowing its name and wants the right word to prompt an AI or designer with. For naming an effect, not designing or building one.

RevanthThota55/FreeFrame-Studio

Apple's approach to interface design and fluid, physical motion, translated for the web. Use when building or reviewing gesture-driven UI, spring animations, drag/swipe/sheet interactions, momentum and interruptible transitions, translucent materials and depth, typography (optical sizing, tracking, leading), reduced-motion, or the design foundations (feedback, spatial consistency, restraint) behind Apple-style interfaces.

Habilidades Relacionadas