Skills Agentes

Ask Sonner

Guía sobre Sonner, la librería de toasts para React: instalación del Toaster, elección de la llamada toast() correcta, promise/loading, actualización, estilos, temas, posicionamiento y solución de problemas.

Estrellas
39.8k

en todo el repo

Actividad
57

0–100, la ruta de este skill

Actualizado
el mes pasado

último commit aquí

Commits
1

últimos 90 días

Contexto
1.7k tok

107 tok en reposo

Paquete
2 archivos

11 KB

Instalar

Funciona con cualquier agente que lea SKILL.md

npx -y skills add emilkowalski/skills --skill ask-sonner --agent claude-code

Se instala solo en este repositorio.

Qué hace

  • Guía para instalar y usar Sonner, la librería de toasts en React
  • Explica cómo montar el <Toaster /> correctamente y elegir la llamada toast() adecuada
  • Cubre promise/loading toasts, actualización, dismiss y persistencia de toasts
  • Explica la escalera de estilos: defaults, inline, classNames con !important, headless
  • Diagnostica problemas comunes: toasts duplicados, sin estilos, detrás de un modal, dark mode ignorado

Úsalo cuando

  • Se está integrando Sonner en un proyecto React o Next.js
  • Los toasts no aparecen, aparecen dos veces, pierden estilos o ignoran clases Tailwind
  • Se necesita estilizar, tematizar o posicionar toasts, o usar múltiples toasters
  • Se quiere encadenar un toast de loading a success/error con toast.promise

No lo uses cuando

    Qué lo activa

    Di cualquiera de estas frases y el agente debería cargar este skill.

    • “¿Por qué mi toast de Sonner aparece dos veces?”
    • “Ayúdame a configurar el Toaster de Sonner en mi layout de Next.js”
    • “Mis toasts no respetan las clases de Tailwind, ¿cómo lo arreglo?”
    • “¿Cómo hago un toast.promise que muestre loading y luego success o error?”
    • “El toast queda detrás de mi modal, ¿cómo lo soluciono?”

    SKILL.md

    En inglés

    Working With Sonner

    A guide skill for Sonner, the toast library. When a task involves Sonner — wiring it up, rendering toasts, styling them, or fixing them — answer from this file first. Full prop tables for <Toaster /> and toast() live in API.md; read it when you need an exact prop name, type, or default.

    Setup

    Two pieces, and only two:

    1. One <Toaster />, mounted once, as close to the root as possible (in Next.js: layout.tsx — it works inside server components). Never render it per-page or conditionally; a second mounted Toaster duplicates every toast.
    2. toast() called from client code — event handlers, effects, callbacks. It's a plain function, no hook or provider needed, but it does nothing on the server: in a server action, return the result and call toast() in the client code that receives it.
    import { Toaster } from 'sonner'; // once, in layout
    import { toast } from 'sonner';   // anywhere client-side
    

    Picking the right call

    You want Call
    Plain message toast('Title') — add { description } for a second line
    Success / error / info / warning icon toast.success('…'), toast.error('…'), etc.
    Spinner while you manage state yourself toast.loading('…'), then update it by id
    Loading → success/error tied to a promise toast.promise(promise, { loading, success, error }) — success/error accept functions receiving the resolved value/error
    Button that does something { action: { label, onClick } } — closes the toast unless onClick calls event.preventDefault(); cancel is the secondary variant
    Custom JSX, default toast shell toast(<jsx />)
    Custom JSX, no styles at all toast.custom((t) => <jsx />) — headless, t gives you the id to dismiss

    Recipes

    Update a toast — call toast() again with the same id; only the props you pass change. Switching to toast.success(…, { id }) changes the type. This is how loading → success flows work without toast.promise:

    const id = toast.loading('Uploading…');
    toast.success('Uploaded', { id });
    

    Persist — { duration: Infinity }. Dismiss — toast.dismiss(id), or toast.dismiss() for all. Read active toasts — useSonner() in React, toast.getActiveToasts() outside it.

    Links or components in the text — pass a function for the title or description: toast(() => <a href="…">View</a>).

    Multiple toasters — give each an id and target with toast('…', { toasterId: 'canvas' }). Without toasterId, every toaster renders the toast.

    Close callbacks — onDismiss fires on close button or swipe; onAutoClose fires on timeout. They are separate; there is no single "closed" callback.

    Styling — the escalation ladder

    Climb only as far as the change requires; jumping to the top rung too early is fine (it's the recommended end state), lingering in the middle is not.

    1. Defaults — plus richColors on the Toaster for colorful success/error, invert to flip against the theme.
    2. Inline tweaks — toastOptions={{ style: {…} }} on the Toaster for all toasts, or style per toast() call.
    3. Classes on parts — toastOptions={{ classNames: { toast, title, description, actionButton, cancelButton, closeButton } }}. Sonner's injected styles win the cascade, so every class needs !important (Tailwind: !text-red-900). If you're marking more than a few things important, stop — go headless.
    4. Headless — toast.custom() with your own JSX, keeping Sonner's positioning, stacking, and swipe. The recommended approach for a design-system toast: wrap it in your own toast() abstraction. (unstyled: true exists as a halfway house, but headless gives more control for the same effort.)

    Icons — swap defaults per-type with the Toaster's icons prop, per-toast with icon, remove with null.

    Theme — theme defaults to 'light' and does not track the OS. Pass theme="system", or wire your theme provider: <Toaster theme={resolvedTheme} /> from next-themes.

    Troubleshooting

    Symptom Cause → fix
    Toast never appears No <Toaster /> mounted, or it unmounted (conditional render, per-page placement). Mount one at the root. If calling from a server action: toast() is client-only — call it with the action's result on the client.
    Same toast appears twice Two Toasters mounted (layout and page) — keep one. Or toast() fired in an effect under React StrictMode's dev double-invoke — fire from the event handler instead, or pass a stable id so the second call updates rather than duplicates.
    Tailwind/CSS classes have no effect Default styles override them. Mark them !important, or use unstyled / headless (see the ladder above).
    Toasts render completely unstyled (common in Astro, view transitions) Sonner's injected stylesheet was lost — import it explicitly in a layout: import 'sonner/dist/styles.css'.
    Unstyled inside Shadow DOM Styles land in document.head, not the shadow root. Copy the style tag whose text includes [data-sonner-toaster] into the shadow root.
    Toast behind a modal/overlay, or clipped An ancestor creates a stacking context (transform, filter, overflow) or the overlay out-z-indexes the toaster. Move <Toaster /> to the document root, outside any dialog/portal container.
    Dark mode ignored theme defaults to 'light' — set theme="system" or pass the resolved theme (see Theme above).
    Success/error look gray, not green/red That's the default. Add richColors to the Toaster.
    Toast never closes duration: Infinity, dismissible: false, or a toast.promise whose promise never settles — the loading toast waits forever.
    toast.promise stuck on loading It needs a promise (or a function returning one) as its first argument, and the promise must actually resolve/reject.
    Swipe-to-dismiss goes the wrong way / doesn't work Directions derive from position. Override with swipeDirections on the Toaster.
    Toast shows up in every toaster Multiple toasters need targeting: give each Toaster an id and pass toasterId in the toast() call.
    Toasts too close to the screen edge on mobile offset (desktop, default 32px) and mobileOffset (<600px, default 16px) — numbers, CSS strings, or per-side objects.

    Reproducido de emilkowalski/skills bajo licencia MIT. Leer esta página en markdown.

    Archivos

    2 archivos en el paquete. Solo se lee SKILL.md al activarse — las referencias se cargan si el skill decide que las necesita.

    Detalles

    Licencia
    MIT
    Recursos incluidos
    Incluye scripts o referencias
    Código fuente
    Ver SKILL.md

    Más de emilkowalski/skills

    Este repo incluye 12 skills. Si instalas uno, normalmente ya tienes los demás. Ver el pack skills entero y su comando de instalación

    Animate

    39.8k

    Construye una animación desde cero, decidiendo en orden si debe animarse, con qué propósito, con qué herramienta, propiedades, curva y duración, cómo se interrumpe y cómo sale; escribe la implementación.

    Costo de contexto al activarse
    2.9k tok
    Tamaño del paquete
    2 archivos
    Última actualización
    el mes pasado
    diseno ui

    Cómo escribir Swift moderno bien: modelado con value types, seguridad ante data races de Swift 6, concurrencia accesible, protocolos y genéricos, diseño de API, rendimiento, ARC, Swift Testing y macros.

    Costo de contexto al activarse
    10.5k tok
    Tamaño del paquete
    1 archivo
    Última actualización
    el mes pasado
    herramientas desarrollo

    Construye animaciones en React Native y Expo decidiendo si debe animarse, en qué hilo corre, spring o timing, y cómo degradar el gesto; implementa con Reanimated, Gesture Handler, Expo Router y expo-haptics.

    Costo de contexto al activarse
    4.4k tok
    Tamaño del paquete
    2 archivos
    Última actualización
    el mes pasado
    herramientas desarrollo

    El enfoque de Apple al diseño de interfaces y al movimiento fluido y físico, traducido a la web: gestos, springs, materiales, tipografía y accesibilidad.

    Costo de contexto al activarse
    5.7k tok
    Tamaño del paquete
    1 archivo
    Última actualización
    hace 3 meses
    diseno ui

    Revisa código de animación y motion contra un estándar de craft alto basado en la filosofía de diseño de Emil Kowalski; por defecto señala problemas, la aprobación se gana.

    Costo de contexto al activarse
    2k tok
    Tamaño del paquete
    2 archivos
    Última actualización
    hace 2 meses
    testing qa

    Busca en un código o interfaz lugares que no animan pero deberían, y rechaza todo lo que no debería animarse. Es de solo lectura: propone movimiento con valores exactos, no lo implementa.

    Costo de contexto al activarse
    2.4k tok
    Tamaño del paquete
    1 archivo
    Última actualización
    hace 2 meses
    diseno ui

    Skills relacionados

    Úsalo cuando la implementación esté completa, todos los tests pasen, y necesites decidir cómo integrar el trabajo.

    Costo de contexto al activarse
    1.9k tok
    Tamaño del paquete
    1 archivo
    Última actualización
    el mes pasado
    herramientas desarrollo

    Úsalo al empezar trabajo de feature que necesita aislamiento del workspace actual, o antes de ejecutar planes de implementación: asegura un workspace aislado vía herramientas nativas o fallback a git worktree.

    Costo de contexto al activarse
    1.7k tok
    Tamaño del paquete
    1 archivo
    Última actualización
    hace 3 meses
    herramientas desarrollo

    Úsala al crear nuevas skills, editar skills existentes o verificar que funcionan antes de desplegarlas.

    Costo de contexto al activarse
    6.6k tok
    Tamaño del paquete
    7 archivos
    Última actualización
    el mes pasado
    herramientas desarrollo