goey-toast 0.4.0 → 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 +23 -2
- package/bin/cli.mjs +110 -0
- package/dist/index.cjs +26 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +8 -3
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +26 -25
- package/dist/index.js.map +1 -1
- package/package.json +7 -2
- package/skills/goey-toast/SKILL.md +152 -0
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:
|
|
@@ -224,6 +242,7 @@ Props for the `<GooeyToaster />` component.
|
|
|
224
242
|
| `queueOverflow` | `'drop-oldest' \| 'drop-newest'` | `'drop-oldest'` | Queue overflow strategy |
|
|
225
243
|
| `dir` | `'ltr' \| 'rtl'` | `'ltr'` | Layout direction |
|
|
226
244
|
| `swipeToDismiss` | `boolean` | `true` | Enable swipe-to-dismiss on mobile |
|
|
245
|
+
| `showTimestamp` | `boolean` | `true` | Show/hide timestamp on all toasts globally |
|
|
227
246
|
|
|
228
247
|
### `GooeyPromiseData<T>`
|
|
229
248
|
|
|
@@ -439,10 +458,12 @@ The close button inherits the toast's border and fill color styling. Hidden duri
|
|
|
439
458
|
|
|
440
459
|
### Hiding Timestamps
|
|
441
460
|
|
|
442
|
-
Hide the timestamp from toasts:
|
|
443
|
-
|
|
444
461
|
```tsx
|
|
462
|
+
// Per-toast: hide timestamp for this toast only
|
|
445
463
|
gooeyToast.success('Saved', { showTimestamp: false })
|
|
464
|
+
|
|
465
|
+
// Globally: hide timestamp for all toasts
|
|
466
|
+
<GooeyToaster showTimestamp={false} />
|
|
446
467
|
```
|
|
447
468
|
|
|
448
469
|
## Exports
|
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/dist/index.cjs
CHANGED
|
@@ -86,6 +86,13 @@ function setGooeyShowProgress(show) {
|
|
|
86
86
|
function getGooeyShowProgress() {
|
|
87
87
|
return _showProgress;
|
|
88
88
|
}
|
|
89
|
+
var _showTimestamp = true;
|
|
90
|
+
function setGooeyShowTimestamp(show) {
|
|
91
|
+
_showTimestamp = show;
|
|
92
|
+
}
|
|
93
|
+
function getGooeyShowTimestamp() {
|
|
94
|
+
return _showTimestamp;
|
|
95
|
+
}
|
|
89
96
|
var _closeButton = false;
|
|
90
97
|
function setGooeyCloseButton(value) {
|
|
91
98
|
_closeButton = value;
|
|
@@ -341,23 +348,23 @@ function registerSonnerObserver(ol, callback) {
|
|
|
341
348
|
let entry = observerRegistry.get(ol);
|
|
342
349
|
if (!entry) {
|
|
343
350
|
const callbacks = /* @__PURE__ */ new Set();
|
|
344
|
-
|
|
345
|
-
const observer = new MutationObserver(() => {
|
|
346
|
-
if (applying) return;
|
|
347
|
-
applying = true;
|
|
348
|
-
requestAnimationFrame(() => {
|
|
349
|
-
callbacks.forEach((cb) => cb());
|
|
350
|
-
requestAnimationFrame(() => {
|
|
351
|
-
applying = false;
|
|
352
|
-
});
|
|
353
|
-
});
|
|
354
|
-
});
|
|
355
|
-
observer.observe(ol, {
|
|
351
|
+
const observeOptions = {
|
|
356
352
|
attributes: true,
|
|
357
353
|
attributeFilter: ["style", "data-visible"],
|
|
358
354
|
subtree: true,
|
|
359
355
|
childList: true
|
|
356
|
+
};
|
|
357
|
+
const observer = new MutationObserver(() => {
|
|
358
|
+
observer.disconnect();
|
|
359
|
+
try {
|
|
360
|
+
for (const cb of callbacks) {
|
|
361
|
+
cb();
|
|
362
|
+
}
|
|
363
|
+
} finally {
|
|
364
|
+
observer.observe(ol, observeOptions);
|
|
365
|
+
}
|
|
360
366
|
});
|
|
367
|
+
observer.observe(ol, observeOptions);
|
|
361
368
|
entry = { observer, callbacks };
|
|
362
369
|
observerRegistry.set(ol, entry);
|
|
363
370
|
}
|
|
@@ -385,17 +392,10 @@ function syncSonnerHeights(wrapperEl, includeOffsets = false) {
|
|
|
385
392
|
const h = content ? content.getBoundingClientRect().height : 0;
|
|
386
393
|
return h > 0 ? h : PH;
|
|
387
394
|
});
|
|
388
|
-
const isExpanded = includeOffsets && toasts[0]?.getAttribute("data-expanded") === "true";
|
|
389
|
-
if (isExpanded) {
|
|
390
|
-
for (const t of toasts) t.style.setProperty("transition", "none", "important");
|
|
391
|
-
}
|
|
392
395
|
for (let i = 0; i < toasts.length; i++) {
|
|
393
396
|
toasts[i].style.setProperty("--initial-height", `${heights[i]}px`);
|
|
394
397
|
}
|
|
395
398
|
if (!includeOffsets) {
|
|
396
|
-
if (isExpanded) {
|
|
397
|
-
for (const t of toasts) t.style.removeProperty("transition");
|
|
398
|
-
}
|
|
399
399
|
return;
|
|
400
400
|
}
|
|
401
401
|
const gapStr = getComputedStyle(ol).getPropertyValue("--gap").trim();
|
|
@@ -411,10 +411,6 @@ function syncSonnerHeights(wrapperEl, includeOffsets = false) {
|
|
|
411
411
|
runningOffset += heights[i] + gap;
|
|
412
412
|
}
|
|
413
413
|
}
|
|
414
|
-
if (isExpanded) {
|
|
415
|
-
void ol.offsetHeight;
|
|
416
|
-
for (const t of toasts) t.style.removeProperty("transition");
|
|
417
|
-
}
|
|
418
414
|
}
|
|
419
415
|
function memoizePath(fn) {
|
|
420
416
|
let lastArgs = null;
|
|
@@ -545,7 +541,7 @@ var GooeyToast = ({
|
|
|
545
541
|
preset,
|
|
546
542
|
spring: springProp,
|
|
547
543
|
bounce: bounceProp,
|
|
548
|
-
showTimestamp
|
|
544
|
+
showTimestamp: showTimestampProp,
|
|
549
545
|
showProgress: showProgressProp,
|
|
550
546
|
toastId
|
|
551
547
|
}) => {
|
|
@@ -563,6 +559,7 @@ var GooeyToast = ({
|
|
|
563
559
|
const useSpring = springProp ?? presetConfig?.spring ?? getGooeySpring();
|
|
564
560
|
const bounceVal = bounceProp ?? presetConfig?.bounce ?? getGooeyBounce() ?? 0.4;
|
|
565
561
|
const showProgress = showProgressProp ?? getGooeyShowProgress();
|
|
562
|
+
const showTimestamp = showTimestampProp ?? getGooeyShowTimestamp();
|
|
566
563
|
const [actionSuccess, setActionSuccess] = react.useState(null);
|
|
567
564
|
const [dismissing, setDismissing] = react.useState(false);
|
|
568
565
|
const [progressKey, setProgressKey] = react.useState(0);
|
|
@@ -1767,7 +1764,8 @@ function GooeyToaster({
|
|
|
1767
1764
|
closeOnEscape = true,
|
|
1768
1765
|
maxQueue = Infinity,
|
|
1769
1766
|
queueOverflow = "drop-oldest",
|
|
1770
|
-
showProgress = false
|
|
1767
|
+
showProgress = false,
|
|
1768
|
+
showTimestamp = true
|
|
1771
1769
|
}) {
|
|
1772
1770
|
const presetConfig = preset ? animationPresets[preset] : void 0;
|
|
1773
1771
|
const resolvedSpring = spring ?? presetConfig?.spring ?? true;
|
|
@@ -1820,6 +1818,9 @@ function GooeyToaster({
|
|
|
1820
1818
|
react.useEffect(() => {
|
|
1821
1819
|
setGooeyCloseButton(closeButton ?? false);
|
|
1822
1820
|
}, [closeButton]);
|
|
1821
|
+
react.useEffect(() => {
|
|
1822
|
+
setGooeyShowTimestamp(showTimestamp);
|
|
1823
|
+
}, [showTimestamp]);
|
|
1823
1824
|
react.useEffect(() => {
|
|
1824
1825
|
let expandObs = null;
|
|
1825
1826
|
let currentOl = null;
|