goey-toast 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -44,6 +44,24 @@ npx shadcn@latest add https://goey-toast.vercel.app/r/goey-toaster.json
44
44
 
45
45
  This installs a thin wrapper component at `components/ui/goey-toaster.tsx` and auto-installs the `goey-toast` and `framer-motion` packages.
46
46
 
47
+ ### AI Agents (Skill)
48
+
49
+ goey-toast ships a bundled [Agent Skill](https://www.skills.sh/) (`SKILL.md`) so coding agents (Claude Code, Cursor, etc.) know how to install and use it correctly — the required `<GooeyToaster />` mount, the `styles.css` import, and the full API.
50
+
51
+ Install from the skills.sh registry:
52
+
53
+ ```bash
54
+ npx skills add anl331/goey-toast
55
+ ```
56
+
57
+ Or copy the skill into your project from the package itself:
58
+
59
+ ```bash
60
+ npx goey-toast add-skill # -> .claude/skills/goey-toast/SKILL.md
61
+ npx goey-toast add-skill --agents # also append an AGENTS.md pointer
62
+ npx goey-toast add-skill --dir .cursor/skills/goey-toast
63
+ ```
64
+
47
65
  ### Peer Dependencies
48
66
 
49
67
  goey-toast requires the following peer dependencies:
package/bin/cli.mjs ADDED
@@ -0,0 +1,110 @@
1
+ #!/usr/bin/env node
2
+ // goey-toast CLI — install the agent skill into a project so coding agents
3
+ // (Claude Code, Cursor, etc.) know how to install and use goey-toast.
4
+ //
5
+ // Usage:
6
+ // npx goey-toast add-skill # -> ./.claude/skills/goey-toast/SKILL.md
7
+ // npx goey-toast add-skill --agents # also write ./AGENTS.md pointer
8
+ // npx goey-toast add-skill --dir .codex/skills
9
+ // npx goey-toast print-skill # print SKILL.md to stdout
10
+
11
+ import { fileURLToPath } from 'node:url'
12
+ import { dirname, join, resolve } from 'node:path'
13
+ import {
14
+ mkdirSync,
15
+ copyFileSync,
16
+ readFileSync,
17
+ writeFileSync,
18
+ existsSync,
19
+ } from 'node:fs'
20
+
21
+ const __dirname = dirname(fileURLToPath(import.meta.url))
22
+ const SKILL_SRC = resolve(__dirname, '..', 'skills', 'goey-toast', 'SKILL.md')
23
+
24
+ const argv = process.argv.slice(2)
25
+ const cmd = argv[0]
26
+
27
+ function getFlag(name) {
28
+ const i = argv.indexOf(`--${name}`)
29
+ if (i === -1) return undefined
30
+ const next = argv[i + 1]
31
+ return next && !next.startsWith('--') ? next : true
32
+ }
33
+
34
+ function readSkill() {
35
+ if (!existsSync(SKILL_SRC)) {
36
+ console.error(`goey-toast: skill source not found at ${SKILL_SRC}`)
37
+ process.exit(1)
38
+ }
39
+ return readFileSync(SKILL_SRC, 'utf8')
40
+ }
41
+
42
+ function addSkill() {
43
+ const dir = typeof getFlag('dir') === 'string'
44
+ ? getFlag('dir')
45
+ : '.claude/skills/goey-toast'
46
+ const dest = resolve(process.cwd(), dir)
47
+ mkdirSync(dest, { recursive: true })
48
+ const out = join(dest, 'SKILL.md')
49
+ copyFileSync(SKILL_SRC, out)
50
+ console.log(`✓ goey-toast skill installed: ${out}`)
51
+
52
+ if (getFlag('agents')) {
53
+ const agentsPath = resolve(process.cwd(), 'AGENTS.md')
54
+ const pointer =
55
+ '\n## goey-toast\n\n' +
56
+ `See \`${dir}/SKILL.md\` for how to install and use goey-toast ` +
57
+ '(gooey morphing React toasts). Mount `<GooeyToaster />` once and ' +
58
+ "import `'goey-toast/styles.css'` at the app entry.\n"
59
+ if (existsSync(agentsPath)) {
60
+ const cur = readFileSync(agentsPath, 'utf8')
61
+ if (!cur.includes('## goey-toast')) {
62
+ writeFileSync(agentsPath, cur.trimEnd() + '\n' + pointer)
63
+ console.log(`✓ appended goey-toast pointer to ${agentsPath}`)
64
+ } else {
65
+ console.log('• AGENTS.md already references goey-toast — skipped')
66
+ }
67
+ } else {
68
+ writeFileSync(agentsPath, '# AGENTS.md\n' + pointer)
69
+ console.log(`✓ created ${agentsPath}`)
70
+ }
71
+ }
72
+
73
+ console.log('\nNext: restart your agent so it picks up the new skill.')
74
+ }
75
+
76
+ function help() {
77
+ console.log(`goey-toast CLI
78
+
79
+ Commands:
80
+ add-skill Install the agent skill into ./.claude/skills/goey-toast
81
+ --dir <path> Custom target dir (e.g. .codex/skills, .cursor/skills)
82
+ --agents Also add/append an AGENTS.md pointer
83
+ print-skill Print SKILL.md to stdout
84
+ help Show this help
85
+
86
+ Examples:
87
+ npx goey-toast add-skill
88
+ npx goey-toast add-skill --agents
89
+ npx goey-toast add-skill --dir .cursor/skills/goey-toast
90
+ `)
91
+ }
92
+
93
+ switch (cmd) {
94
+ case 'add-skill':
95
+ addSkill()
96
+ break
97
+ case 'print-skill':
98
+ process.stdout.write(readSkill())
99
+ break
100
+ case undefined:
101
+ case 'help':
102
+ case '--help':
103
+ case '-h':
104
+ help()
105
+ break
106
+ default:
107
+ console.error(`goey-toast: unknown command "${cmd}"\n`)
108
+ help()
109
+ process.exit(1)
110
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "goey-toast",
3
- "version": "0.4.1",
3
+ "version": "0.5.0",
4
4
  "description": "A gooey, morphing toast component built on Sonner with Framer Motion animations",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -18,8 +18,13 @@
18
18
  "*.css"
19
19
  ],
20
20
  "files": [
21
- "dist"
21
+ "dist",
22
+ "skills",
23
+ "bin"
22
24
  ],
25
+ "bin": {
26
+ "goey-toast": "bin/cli.mjs"
27
+ },
23
28
  "scripts": {
24
29
  "build": "tsup",
25
30
  "dev": "tsup --watch",
@@ -0,0 +1,152 @@
1
+ ---
2
+ name: goey-toast
3
+ description: Install and use goey-toast — a gooey, morphing React toast component built on Sonner with Framer Motion. Use when adding toast/notification UI to a React app (success/error/warning/info/promise toasts), or when the user mentions goey-toast / gooey toast.
4
+ license: MIT
5
+ ---
6
+
7
+ # goey-toast
8
+
9
+ A gooey, morphing React toast component built on Sonner with Framer Motion
10
+ animations (pill → blob → pill). Use this skill to install the package and write
11
+ correct usage code in any React project.
12
+
13
+ ## When to use
14
+
15
+ - Adding toast / notification UI to a React app (React >= 18).
16
+ - The user mentions "goey-toast", "gooey toast", or wants animated/morphing toasts.
17
+ - Replacing raw `sonner` toasts with the gooey variant.
18
+
19
+ ## Install
20
+
21
+ ```bash
22
+ npm install goey-toast react react-dom framer-motion
23
+ ```
24
+
25
+ Peer deps (must exist in the host app):
26
+
27
+ | Package | Version |
28
+ | ------------- | --------- |
29
+ | react | >= 18.0.0 |
30
+ | react-dom | >= 18.0.0 |
31
+ | framer-motion | >= 10.0.0 |
32
+
33
+ ### shadcn/ui projects
34
+
35
+ ```bash
36
+ npx shadcn@latest add https://goey-toast.vercel.app/r/goey-toaster.json
37
+ ```
38
+
39
+ Installs a wrapper at `components/ui/goey-toaster.tsx` and auto-installs deps.
40
+
41
+ ## Two required steps to render toasts
42
+
43
+ 1. **Mount `<GooeyToaster />` once** near the app root.
44
+ 2. **Import the stylesheet once** at the entry point. Without it toasts render
45
+ unstyled.
46
+
47
+ ```tsx
48
+ import { GooeyToaster, gooeyToast } from 'goey-toast'
49
+ import 'goey-toast/styles.css' // REQUIRED — import once at app entry
50
+
51
+ function App() {
52
+ return (
53
+ <>
54
+ <GooeyToaster position="bottom-right" />
55
+ <button onClick={() => gooeyToast.success('Saved!')}>Save</button>
56
+ </>
57
+ )
58
+ }
59
+ ```
60
+
61
+ ## API: `gooeyToast`
62
+
63
+ ```ts
64
+ gooeyToast(title, options?) // default (neutral)
65
+ gooeyToast.success(title, options?) // green
66
+ gooeyToast.error(title, options?) // red
67
+ gooeyToast.warning(title, options?) // yellow
68
+ gooeyToast.info(title, options?) // blue
69
+ gooeyToast.promise(promise, data) // loading → success/error
70
+ gooeyToast.update(id, options) // update an existing toast in-place
71
+ gooeyToast.dismiss(idOrFilter?) // dismiss one, by type, or all
72
+ ```
73
+
74
+ ### Common options (2nd arg)
75
+
76
+ | Option | Type | Notes |
77
+ | --------------- | ------------------- | ---------------------------------------------- |
78
+ | `description` | `ReactNode` | String or component body |
79
+ | `action` | `GooeyToastAction` | `{ label, onClick, successLabel? }` |
80
+ | `icon` | `ReactNode` | Custom icon (`null` clears in `update`) |
81
+ | `duration` | `number` | ms |
82
+ | `id` | `string \| number` | Stable id (needed for `update`) |
83
+ | `fillColor` / `borderColor` / `borderWidth` | colors / px | Blob styling |
84
+ | `spring` / `bounce` | `boolean` / `number` | bounce `0.05`–`0.8`, default `0.4` |
85
+ | `preset` | `'smooth' \| 'bouncy' \| 'subtle' \| 'snappy'` | Animation preset |
86
+ | `showProgress` | `boolean` | Countdown bar |
87
+ | `showTimestamp` | `boolean` | Default `true` |
88
+ | `onDismiss` / `onAutoClose` | `(id) => void` | Dismiss callbacks |
89
+
90
+ ### `<GooeyToaster />` key props
91
+
92
+ `position` (`'top-left'|'top-center'|'top-right'|'bottom-left'|'bottom-center'|'bottom-right'`, default `'bottom-right'`),
93
+ `theme` (`'light'|'dark'`), `closeButton`, `showProgress`, `closeOnEscape`,
94
+ `maxQueue`, `queueOverflow` (`'drop-oldest'|'drop-newest'`), `dir` (`'ltr'|'rtl'`),
95
+ `spring`, `bounce`, `preset`, `swipeToDismiss`, `showTimestamp`, `gap`, `offset`.
96
+
97
+ ## Recipes
98
+
99
+ ### Description + action button
100
+
101
+ ```tsx
102
+ gooeyToast.info('Share link ready', {
103
+ description: 'Your link has been generated.',
104
+ action: {
105
+ label: 'Copy',
106
+ onClick: () => navigator.clipboard.writeText(url),
107
+ successLabel: 'Copied!', // morphs back to pill after click
108
+ },
109
+ })
110
+ ```
111
+
112
+ ### Promise toast
113
+
114
+ ```tsx
115
+ gooeyToast.promise(saveData(), {
116
+ loading: 'Saving...',
117
+ success: (data) => `Saved ${data.count} items`,
118
+ error: (e) => `Failed: ${String(e)}`,
119
+ description: { success: 'All changes synced.', error: 'Try again later.' },
120
+ action: { error: { label: 'Retry', onClick: () => retry() } },
121
+ })
122
+ ```
123
+
124
+ ### Update in place
125
+
126
+ ```tsx
127
+ const id = gooeyToast('Uploading...', { icon: <Spinner /> })
128
+ gooeyToast.update(id, { title: 'Done', type: 'success', icon: null })
129
+ ```
130
+
131
+ ### Dismiss by filter
132
+
133
+ ```tsx
134
+ gooeyToast.dismiss(id) // one
135
+ gooeyToast.dismiss({ type: 'error' }) // all errors
136
+ gooeyToast.dismiss({ type: ['error','warning'] })
137
+ gooeyToast.dismiss() // all
138
+ ```
139
+
140
+ ## Gotchas
141
+
142
+ - Forgetting `import 'goey-toast/styles.css'` → unstyled toasts. Most common bug.
143
+ - `<GooeyToaster />` must be mounted exactly once, near the root.
144
+ - `update()` requires the same `id` returned from the create call.
145
+ - `framer-motion` is a peer dep — install it explicitly.
146
+ - Backward-compat aliases exist (`GoeyToaster`, `goeyToast`) for v0.2.x; prefer
147
+ the double-`o` names (`GooeyToaster`, `gooeyToast`).
148
+
149
+ ## Reference
150
+
151
+ - Live demo & docs: https://goey-toast.vercel.app
152
+ - npm: https://www.npmjs.com/package/goey-toast