mcpField
G
goey-toast

goey-toast

github.com/anl331Design & UI1.3k125 installsUpdated 8w ago
Repository

About goey-toast

goey-toast is a skill for adding animated notifications to React apps. Built on Sonner and Framer Motion, it morphs toasts between pill and blob shapes and includes notification states, queue controls, and interaction options.

Key features

  1. 01Pill-to-blob morphing animation
  2. 02Success, error, warning, and info toasts
  3. 03Promise loading and result notifications
  4. 04Update, filter, or dismiss toasts
  5. 05Progress, timestamps, and queue options

Use cases

  1. 01Add notification UI to a React app
  2. 02Show loading and results for async saves
  3. 03Offer clickable actions in notifications
  4. 04Manage toast queues and dismissal

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/anl331/goey-toast --skill goey-toast

After installing, type/goey-toastin Claude Code to confirm it loaded.

Details

From the project README

goey-toast

A gooey, morphing React toast component built on Sonner with Framer Motion animations (pill → blob → pill). Use this skill to install the package and write correct usage code in any React project.

When to use

  • Adding toast / notification UI to a React app (React >= 18).
  • The user mentions "goey-toast", "gooey toast", or wants animated/morphing toasts.
  • Replacing raw sonner toasts with the gooey variant.

Install

npm install goey-toast react react-dom framer-motion

Peer deps (must exist in the host app):

PackageVersion
react>= 18.0.0
react-dom>= 18.0.0
framer-motion>= 10.0.0
shadcn/ui projects
npx shadcn@latest add https://goey-toast.vercel.app/r/goey-toaster.json

Installs a wrapper at components/ui/goey-toaster.tsx and auto-installs deps.

Two required steps to render toasts

  1. Mount <GooeyToaster /> once near the app root.
  2. Import the stylesheet once at the entry point. Without it toasts render unstyled.
import { GooeyToaster, gooeyToast } from 'goey-toast'
import 'goey-toast/styles.css' // REQUIRED — import once at app entry

function App() {
  return (
    <>
      <GooeyToaster position="bottom-right" />
      <button onClick={() => gooeyToast.success('Saved!')}>Save</button>
    </>
  )
}

API: gooeyToast

gooeyToast(title, options?)         // default (neutral)
gooeyToast.success(title, options?) // green
gooeyToast.error(title, options?)   // red
gooeyToast.warning(title, options?) // yellow
gooeyToast.info(title, options?)    // blue
gooeyToast.promise(promise, data)   // loading → success/error
gooeyToast.update(id, options)      // update an existing toast in-place
gooeyToast.dismiss(idOrFilter?)     // dismiss one, by type, or all
Common options (2nd arg)
OptionTypeNotes
descriptionReactNodeString or component body
actionGooeyToastAction{ label, onClick, successLabel? }
iconReactNodeCustom icon (null clears in update)
durationnumberms
idstring | numberStable id (needed for update)
fillColor / borderColor / borderWidthcolors / pxBlob styling
spring / bounceboolean / numberbounce 0.05–0.8, default 0.4
preset'smooth' | 'bouncy' | 'subtle' | 'snappy'Animation preset
showProgressbooleanCountdown bar
showTimestampbooleanDefault true
onDismiss / onAutoClose(id) => voidDismiss callbacks
<GooeyToaster /> key props

position ('top-left'|'top-center'|'top-right'|'bottom-left'|'bottom-center'|'bottom-right', default 'bottom-right'), theme ('light'|'dark'), closeButton, showProgress, closeOnEscape, maxQueue, queueOverflow ('drop-oldest'|'drop-newest'), dir ('ltr'|'rtl'), spring, bounce, preset, swipeToDismiss, showTimestamp, gap, offset.

Recipes

Description + action button
gooeyToast.info('Share link ready', {
  description: 'Your link has been generated.',
  action: {
    label: 'Copy',
    onClick: () => navigator.clipboard.writeText(url),
    successLabel: 'Copied!', // morphs back to pill after click
  },
})
Promise toast
gooeyToast.promise(saveData(), {
  loading: 'Saving...',
  success: (data) => `Saved ${data.count} items`,
  error: (e) => `Failed: ${String(e)}`,
  description: { success: 'All changes synced.', error: 'Try again later.' },
  action: { error: { label: 'Retry', onClick: () => retry() } },
})
Update in place
const id = gooeyToast('Uploading...', { icon: <Spinner /> })
gooeyToast.update(id, { title: 'Done', type: 'success', icon: null })
Dismiss by filter
gooeyToast.dismiss(id)                       // one
gooeyToast.dismiss({ type: 'error' })        // all errors
gooeyToast.dismiss({ type: ['error','warning'] })
gooeyToast.dismiss()                         // all

Gotchas

  • Forgetting import 'goey-toast/styles.css' → unstyled toasts. Most common bug.
  • <GooeyToaster /> must be mounted exactly once, near the root.
  • update() requires the same id returned from the create call.
  • framer-motion is a peer dep — install it explicitly.
  • Backward-compat aliases exist (GoeyToaster, goeyToast) for v0.2.x; prefer the double-o names (GooeyToaster, gooeyToast).

Reference

Comments

Markdown supported