[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-75030":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":14,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":14,"stars7d":16,"stars30d":17,"stars90d":15,"forks30d":15,"starsTrendScore":18,"compositeScore":19,"rankGlobal":10,"rankLanguage":10,"license":20,"archived":21,"fork":21,"defaultBranch":22,"hasWiki":23,"hasPages":21,"topics":24,"createdAt":10,"pushedAt":10,"updatedAt":38,"readmeContent":39,"aiSummary":40,"trendingCount":15,"starSnapshotCount":15,"syncStatus":41,"lastSyncTime":42,"discoverSource":43},75030,"goey-toast","anl331\u002Fgoey-toast","anl331","A gooey, morphing toast component built on Sonner with Framer Motion animations","https:\u002F\u002Fgoey-toast.vercel.app",null,"TypeScript",1110,51,1,0,5,27,3,18.15,"MIT License",false,"main",true,[25,26,27,28,29,30,31,32,33,34,35,36,37],"animation","blob","component","framer-motion","gooey","morph","nextjs","notification","react","sonner","toast","typescript","ui","2026-06-12 02:03:31","# gooey-toast\n\n[![gooey-toast](https:\u002F\u002Fgoey-toast.vercel.app\u002Fog-image.png)](https:\u002F\u002Fgoey-toast.vercel.app)\n\n**[Live Demo & Docs](https:\u002F\u002Fgoey-toast.vercel.app)**\n\n## Features\n\n- Organic blob morph animation (pill &rarr; blob &rarr; pill)\n- Five toast types: default, success, error, warning, info\n- Promise toasts with loading &rarr; success\u002Ferror transitions\n- Action buttons with optional success label morph-back\n- Description body supporting strings and React components\n- Configurable display duration and bounce intensity\n- Custom fill color, border color, and border width\n- CSS class overrides via `classNames` prop\n- 6 positions with automatic horizontal mirroring for right-side positions\n- Center positions with symmetric morph animation\n- Hover pause: hovering an expanded toast pauses the dismiss timer\n- Hover re-expand: hovering a collapsed pill re-expands the toast\n- Pre-dismiss collapse animation\n- In-place toast updates via `gooeyToast.update()`\n- Dismiss by type filter: `gooeyToast.dismiss({ type: 'error' })`\n- Dark mode and RTL layout support\n- Animation presets: smooth, bouncy, subtle, snappy\n- Timestamp display on expanded toasts with optional `showTimestamp` toggle\n- Close button with configurable position (`top-left` \u002F `top-right`)\n- Countdown progress bar with hover-pause and re-expand\n- Keyboard dismiss (Escape) and swipe-to-dismiss on mobile\n- Toast queue with configurable overflow strategy\n- Dismiss callbacks: `onDismiss` and `onAutoClose`\n\n## Installation\n\n```bash\nnpm install goey-toast\n```\n\n### shadcn\u002Fui\n\n```bash\nnpx shadcn@latest add https:\u002F\u002Fgoey-toast.vercel.app\u002Fr\u002Fgoey-toaster.json\n```\n\nThis installs a thin wrapper component at `components\u002Fui\u002Fgoey-toaster.tsx` and auto-installs the `goey-toast` and `framer-motion` packages.\n\n### Peer Dependencies\n\ngoey-toast requires the following peer dependencies:\n\n```bash\nnpm install react react-dom framer-motion\n```\n\n| Package        | Version    |\n| -------------- | ---------- |\n| react          | >= 18.0.0  |\n| react-dom      | >= 18.0.0  |\n| framer-motion  | >= 10.0.0  |\n\n### CSS Import (Required)\n\nYou **must** import the goey-toast stylesheet for the component to render correctly:\n\n```tsx\nimport 'goey-toast\u002Fstyles.css'\n```\n\nAdd this import once in your app's entry point (e.g., `main.tsx` or `App.tsx`). Without it, toasts will appear unstyled.\n\n## Quick Start\n\n```tsx\nimport { GooeyToaster, gooeyToast } from 'goey-toast'\nimport 'goey-toast\u002Fstyles.css'\n\nfunction App() {\n  return (\n    \u003C>\n      \u003CGooeyToaster position=\"bottom-right\" \u002F>\n      \u003Cbutton onClick={() => gooeyToast.success('Saved!')}>\n        Save\n      \u003C\u002Fbutton>\n    \u003C\u002F>\n  )\n}\n```\n\n## API Reference\n\n### `gooeyToast` Methods\n\n```ts\ngooeyToast(title, options?)              \u002F\u002F default (neutral)\ngooeyToast.success(title, options?)      \u002F\u002F green\ngooeyToast.error(title, options?)        \u002F\u002F red\ngooeyToast.warning(title, options?)      \u002F\u002F yellow\ngooeyToast.info(title, options?)         \u002F\u002F blue\ngooeyToast.promise(promise, data)        \u002F\u002F loading -> success\u002Ferror\ngooeyToast.update(id, options)           \u002F\u002F update an existing toast in-place\ngooeyToast.dismiss(idOrFilter?)          \u002F\u002F dismiss one, by type, or all toasts\n```\n\n#### `gooeyToast.update(id, options)`\n\nUpdates an existing toast in-place without removing and re-creating it.\n\n```tsx\nconst id = gooeyToast('Uploading...', {\n  icon: \u003CSpinnerIcon \u002F>,\n})\n\n\u002F\u002F Later, update the toast\ngooeyToast.update(id, {\n  title: 'Upload complete',\n  type: 'success',\n  description: '3 files uploaded.',\n  icon: null, \u002F\u002F clears the custom icon\n})\n```\n\n**`GooeyToastUpdateOptions`:**\n\n| Option        | Type              | Description                   |\n| ------------- | ----------------- | ----------------------------- |\n| `title`       | `string`          | New title text                |\n| `description` | `ReactNode`       | New body content              |\n| `type`        | `GooeyToastType`   | Change the toast type\u002Fcolor   |\n| `action`      | `GooeyToastAction` | New action button             |\n| `icon`        | `ReactNode \\| null` | Custom icon (pass `null` to clear) |\n\n#### `gooeyToast.dismiss(idOrFilter?)`\n\nDismiss a single toast by ID, all toasts of a given type, or all toasts at once.\n\n```ts\n\u002F\u002F Dismiss a specific toast\ngooeyToast.dismiss(toastId)\n\n\u002F\u002F Dismiss all error toasts\ngooeyToast.dismiss({ type: 'error' })\n\n\u002F\u002F Dismiss multiple types\ngooeyToast.dismiss({ type: ['error', 'warning'] })\n\n\u002F\u002F Dismiss all toasts\ngooeyToast.dismiss()\n```\n\n### `GooeyToastOptions`\n\nOptions passed as the second argument to `gooeyToast()` and type-specific methods.\n\n| Option        | Type                 | Description                        |\n| ------------- | -------------------- | ---------------------------------- |\n| `description` | `ReactNode`          | Body content (string or component) |\n| `action`      | `GooeyToastAction`    | Action button configuration        |\n| `icon`        | `ReactNode`          | Custom icon override               |\n| `duration`    | `number`             | Display duration in ms             |\n| `id`          | `string \\| number`   | Unique toast identifier            |\n| `classNames`  | `GooeyToastClassNames`| CSS class overrides                |\n| `fillColor`   | `string`             | Background color of the blob       |\n| `borderColor` | `string`             | Border color of the blob           |\n| `borderWidth` | `number`             | Border width in px (default 1.5)   |\n| `timing`      | `GooeyToastTimings`   | Animation timing overrides         |\n| `spring`      | `boolean`            | Enable spring\u002Fbounce animations (default `true`) |\n| `bounce`      | `number`             | Spring intensity from `0.05` (subtle) to `0.8` (dramatic), default `0.4` |\n| `showTimestamp` | `boolean`         | Show\u002Fhide timestamp in toast header\u002Fbody (default `true`) |\n| `showProgress`| `boolean`            | Show countdown progress bar                      |\n| `onDismiss`   | `(id) => void`       | Called when toast is dismissed (any reason)       |\n| `onAutoClose` | `(id) => void`       | Called only on timer-based auto-dismiss           |\n| `preset`      | `AnimationPresetName`| Animation preset (`'smooth'`, `'bouncy'`, `'subtle'`, `'snappy'`) |\n\n### `GooeyToastAction`\n\n| Property       | Type       | Required | Description                                  |\n| -------------- | ---------- | -------- | -------------------------------------------- |\n| `label`        | `string`   | Yes      | Button text                                  |\n| `onClick`      | `() => void` | Yes   | Click handler                                |\n| `successLabel` | `string`   | No       | Label shown after click (morphs back to pill)|\n\n### `GooeyToastTimings`\n\nFine-tune animation speeds per toast.\n\n| Property           | Type     | Default | Description                          |\n| ------------------ | -------- | ------- | ------------------------------------ |\n| `displayDuration`  | `number` | 4000    | Milliseconds toast stays expanded    |\n\n### `GooeyToastClassNames`\n\nOverride styles for any part of the toast.\n\n| Key             | Target           |\n| --------------- | ---------------- |\n| `wrapper`       | Outer container  |\n| `content`       | Content area     |\n| `header`        | Icon + title row |\n| `title`         | Title text       |\n| `icon`          | Icon wrapper     |\n| `description`   | Body text        |\n| `actionWrapper` | Button container |\n| `actionButton`  | Action button    |\n\n### `GooeyToasterProps`\n\nProps for the `\u003CGooeyToaster \u002F>` component.\n\n| Prop         | Type                                  | Default          | Description                                   |\n| ------------ | ------------------------------------- | ---------------- | --------------------------------------------- |\n| `position`   | `'top-left' \\| 'top-center' \\| 'top-right' \\| 'bottom-left' \\| 'bottom-center' \\| 'bottom-right'` | `'bottom-right'` | Toast position |\n| `duration`   | `number`                              | --               | Default display duration in ms                |\n| `gap`        | `number`                              | `14`             | Gap between stacked toasts (px)               |\n| `offset`     | `number \\| string`                    | `'24px'`         | Distance from screen edge                     |\n| `theme`      | `'light' \\| 'dark'`                   | `'light'`        | Color theme                                   |\n| `toastOptions` | `Partial\u003CExternalToast>`            | --               | Default options passed to Sonner              |\n| `spring`     | `boolean`                             | `true`           | Enable spring\u002Fbounce animations globally      |\n| `bounce`     | `number`                              | `0.4`            | Spring intensity: `0.05` (subtle) to `0.8` (dramatic) |\n| `preset`     | `AnimationPresetName`                 | --               | Animation preset for all toasts               |\n| `closeOnEscape` | `boolean`                          | `true`           | Dismiss most recent toast on Escape key       |\n| `closeButton`  | `boolean \\| 'top-left' \\| 'top-right'` | `false`       | Show close button on hover                    |\n| `showProgress` | `boolean`                           | `false`          | Show countdown progress bar on all toasts     |\n| `maxQueue`   | `number`                              | `Infinity`       | Maximum queued toasts                         |\n| `queueOverflow` | `'drop-oldest' \\| 'drop-newest'`   | `'drop-oldest'`  | Queue overflow strategy                       |\n| `dir`        | `'ltr' \\| 'rtl'`                     | `'ltr'`          | Layout direction                              |\n| `swipeToDismiss` | `boolean`                         | `true`           | Enable swipe-to-dismiss on mobile             |\n\n### `GooeyPromiseData\u003CT>`\n\nConfiguration for `gooeyToast.promise()`.\n\n| Property      | Type                                          | Required | Description                                    |\n| ------------- | --------------------------------------------- | -------- | ---------------------------------------------- |\n| `loading`     | `string`                                      | Yes      | Title shown during loading                     |\n| `success`     | `string \\| ((data: T) => string)`             | Yes      | Title on success (static or derived from result)|\n| `error`       | `string \\| ((error: unknown) => string)`      | Yes      | Title on error (static or derived from error)  |\n| `description` | `object`                                      | No       | Per-phase descriptions (see below)             |\n| `action`      | `object`                                      | No       | Per-phase action buttons (see below)           |\n| `classNames`  | `GooeyToastClassNames`                         | No       | CSS class overrides                            |\n| `fillColor`   | `string`                                      | No       | Background color of the blob                   |\n| `borderColor` | `string`                                      | No       | Border color of the blob                       |\n| `borderWidth` | `number`                                      | No       | Border width in px                             |\n| `timing`      | `GooeyToastTimings`                            | No       | Animation timing overrides                     |\n| `spring`      | `boolean`                                     | No       | Enable spring\u002Fbounce animations (default `true`) |\n| `bounce`      | `number`                                      | No       | Spring intensity: `0.05` (subtle) to `0.8` (dramatic), default `0.4` |\n| `onDismiss`   | `(id: string \\| number) => void`              | No       | Called when toast is dismissed (any reason)       |\n| `onAutoClose` | `(id: string \\| number) => void`              | No       | Called only on timer-based auto-dismiss           |\n\n**`description` sub-fields:**\n\n| Key       | Type                                             |\n| --------- | ------------------------------------------------ |\n| `loading` | `ReactNode`                                      |\n| `success` | `ReactNode \\| ((data: T) => ReactNode)`          |\n| `error`   | `ReactNode \\| ((error: unknown) => ReactNode)`   |\n\n**`action` sub-fields:**\n\n| Key       | Type              |\n| --------- | ----------------- |\n| `success` | `GooeyToastAction` |\n| `error`   | `GooeyToastAction` |\n\n## Usage Examples\n\n### Description\n\n```tsx\ngooeyToast.error('Payment failed', {\n  description: 'Your card was declined. Please try again.',\n})\n```\n\n### Custom React Component as Description\n\n```tsx\ngooeyToast.success('Deployment complete', {\n  description: (\n    \u003Cdiv style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>\n      \u003Cdiv>\n        \u003Cspan>Environment:\u003C\u002Fspan> \u003Cstrong>Production\u003C\u002Fstrong>\n      \u003C\u002Fdiv>\n      \u003Cdiv>\n        \u003Cspan>Branch:\u003C\u002Fspan> \u003Cstrong>main @ 3f8a2c1\u003C\u002Fstrong>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n  ),\n})\n```\n\n### Action Button with Success Label\n\n```tsx\ngooeyToast.info('Share link ready', {\n  description: 'Your link has been generated.',\n  action: {\n    label: 'Copy to Clipboard',\n    onClick: () => navigator.clipboard.writeText(url),\n    successLabel: 'Copied!',\n  },\n})\n```\n\n### Promise Toast\n\n```tsx\ngooeyToast.promise(saveData(), {\n  loading: 'Saving...',\n  success: 'Changes saved',\n  error: 'Something went wrong',\n  description: {\n    success: 'All changes have been synced.',\n    error: 'Please try again later.',\n  },\n  action: {\n    error: {\n      label: 'Retry',\n      onClick: () => retry(),\n    },\n  },\n})\n```\n\n### Custom Styling\n\n```tsx\ngooeyToast.success('Styled!', {\n  fillColor: '#1a1a2e',\n  borderColor: '#333',\n  borderWidth: 2,\n  classNames: {\n    wrapper: 'my-wrapper',\n    title: 'my-title',\n    description: 'my-desc',\n    actionButton: 'my-btn',\n  },\n})\n```\n\n### Display Duration\n\n```tsx\ngooeyToast.success('Saved', {\n  description: 'Your changes have been synced.',\n  timing: { displayDuration: 5000 },\n})\n```\n\n### Disabling Spring Animations\n\nDisable bounce\u002Fspring animations for a cleaner, more subtle look:\n\n```tsx\n\u002F\u002F Per-toast: disable spring for this toast only\ngooeyToast.success('Saved', {\n  description: 'Your changes have been synced.',\n  spring: false,\n})\n\n\u002F\u002F Globally: disable spring for all toasts\n\u003CGooeyToaster spring={false} \u002F>\n```\n\nWhen `spring` is `false`, all spring-based animations (landing squish, blob squish, morph transitions, pill resize, header squish) use smooth ease-in-out curves instead. Error shake animations still work regardless of this setting.\n\n### Bounce Intensity\n\nControl how dramatic the spring effect feels with a single `bounce` value:\n\n```tsx\n\u002F\u002F Subtle, barely-there spring\ngooeyToast.success('Saved', { bounce: 0.1 })\n\n\u002F\u002F Default feel\ngooeyToast.success('Saved', { bounce: 0.4 })\n\n\u002F\u002F Jelly mode\ngooeyToast.success('Saved', { bounce: 0.8 })\n\n\u002F\u002F Set globally via GooeyToaster\n\u003CGooeyToaster bounce={0.6} \u002F>\n```\n\nThe `bounce` value (0.05 to 0.8) controls spring stiffness, damping, and squish magnitude together so you get a consistent feel from one number.\n\n### Dark Mode\n\n```tsx\n\u003CGooeyToaster theme=\"dark\" \u002F>\n```\n\n### RTL Support\n\n```tsx\n\u003CGooeyToaster dir=\"rtl\" \u002F>\n```\n\n### Animation Presets\n\nFour built-in presets: `smooth`, `bouncy`, `subtle`, `snappy`. Apply per-toast or globally:\n\n```tsx\ngooeyToast.success('Saved', { preset: 'bouncy' })\n\n\u002F\u002F Or globally\n\u003CGooeyToaster preset=\"smooth\" \u002F>\n```\n\n### Progress Bar\n\nShow a countdown progress bar on toasts:\n\n```tsx\ngooeyToast.success('Saved', { showProgress: true })\n\n\u002F\u002F Or enable globally\n\u003CGooeyToaster showProgress \u002F>\n```\n\n### Keyboard Shortcuts\n\nPress **Escape** to dismiss the most recent toast. Enabled by default; disable with `closeOnEscape={false}`.\n\n### Swipe to Dismiss\n\nOn mobile, swipe toasts to dismiss them. Enabled by default; disable with `swipeToDismiss={false}`.\n\n### Close Button\n\nShow a close button on hover. Position it `top-left` (default) or `top-right`:\n\n```tsx\n\u003CGooeyToaster closeButton \u002F>\n\u003CGooeyToaster closeButton=\"top-left\" \u002F>\n\u003CGooeyToaster closeButton=\"top-right\" \u002F>\n```\n\nThe close button inherits the toast's border and fill color styling. Hidden during the loading phase of promise toasts.\n\n### Hiding Timestamps\n\nHide the timestamp from toasts:\n\n```tsx\ngooeyToast.success('Saved', { showTimestamp: false })\n```\n\n## Exports\n\n```ts\n\u002F\u002F Components\nexport { GooeyToaster } from 'goey-toast'\n\n\u002F\u002F Toast function\nexport { gooeyToast } from 'goey-toast'\n\n\u002F\u002F Animation presets\nexport { animationPresets } from 'goey-toast'\n\n\u002F\u002F Types\nexport type {\n  GooeyToastOptions,\n  GooeyPromiseData,\n  GooeyToasterProps,\n  GooeyToastAction,\n  GooeyToastClassNames,\n  GooeyToastTimings,\n  GooeyToastUpdateOptions,\n  DismissFilter,\n  AnimationPreset,\n  AnimationPresetName,\n} from 'goey-toast'\n```\n\n## Browser Support\n\ngoey-toast works in all modern browsers that support:\n\n- CSS Modules\n- SVG path animations\n- ResizeObserver\n- `framer-motion` (Chrome, Firefox, Safari, Edge)\n\n## See Also\n\n- **[gooey-search-tabs](https:\u002F\u002Fgithub.com\u002Fanl331\u002Fgooey-search-tabs)** — A morphing search bar with animated tab navigation for React. [Live Demo](https:\u002F\u002Fgooey-search-tabs.vercel.app)\n\n## License\n\n[MIT](.\u002FLICENSE)\n","gooey-toast 是一个基于 Sonner 和 Framer Motion 动画构建的具有流动形态变化效果的通知组件。其核心功能包括有机的 blob 形态变换动画、五种类型的通知（默认、成功、错误、警告、信息）、加载到成功\u002F失败的过渡效果、支持字符串和 React 组件的描述体等。此外，它还提供了多种配置选项，如显示时长、弹跳强度、自定义颜色及边框宽度等，并且兼容暗黑模式与 RTL 布局。该项目特别适合需要在网页或应用中展示具有吸引力且高度可定制通知消息的场景使用，尤其是在注重用户体验和视觉效果的设计项目中。",2,"2026-06-11 03:52:02","high_star"]