toastywave 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Toastwave Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,345 @@
1
+ # Toastywave
2
+
3
+ Lightweight React toast notifications with zero CSS dependencies.
4
+
5
+ - **~3KB** gzipped
6
+ - **Deduplication** — identical messages won't stack
7
+ - **Countdown timer** with configurable text, pause-on-hover, and "click to stop"
8
+ - **Action presets** — built-in "undo", "retry" or custom actions
9
+ - **Custom icons** — use any React icon library (Hero Icons, Lucide, etc.)
10
+ - **Theming** — dark, light, or fully custom theme objects
11
+ - **Container scoping** — render at window level or inside any element
12
+ - **Promise toasts** — loading → success/error transitions
13
+ - **TypeScript** — full type definitions included
14
+
15
+ ## Install
16
+
17
+ ```bash
18
+ bun add toastywave
19
+ ```
20
+
21
+ ## Quick Start
22
+
23
+ ```jsx
24
+ import { toast, Toaster } from 'toastywave';
25
+
26
+ function App() {
27
+ return (
28
+ <div>
29
+ <Toaster position="bottom-right" theme="dark" />
30
+ <button onClick={() => toast.success('Saved!')}>
31
+ Save
32
+ </button>
33
+ </div>
34
+ );
35
+ }
36
+ ```
37
+
38
+ ## API Reference
39
+
40
+ ### `toast(message, options?)`
41
+
42
+ Show a toast notification. Returns a numeric toast ID.
43
+
44
+ ```js
45
+ toast('Hello world');
46
+ toast('Custom duration', { duration: 8000 });
47
+ ```
48
+
49
+ #### Shorthand Methods
50
+
51
+ ```js
52
+ toast.success('Changes saved');
53
+ toast.error('Something went wrong');
54
+ toast.warning('Are you sure?');
55
+ toast.info('New version available');
56
+ toast.loading('Uploading...'); // duration: Infinity
57
+ ```
58
+
59
+ #### Options
60
+
61
+ | Option | Type | Default | Description |
62
+ |---|---|---|---|
63
+ | `type` | `string` | `"default"` | `"default"` `"success"` `"error"` `"warning"` `"info"` `"loading"` |
64
+ | `description` | `string` | — | Secondary text below the title |
65
+ | `duration` | `number` | `5000` | Auto-dismiss in ms. Use `Infinity` to persist. |
66
+ | `action` | `string \| object` | — | Preset name, preset config, or custom action |
67
+ | `icon` | `ReactNode` | — | Custom icon element (overrides default type icon) |
68
+ | `dedupeKey` | `string` | `${type}::${message}` | Custom key for deduplication |
69
+ | `showCountdown` | `boolean` | `true` | Show/hide the countdown footer |
70
+ | `countdownText` | `string` | `"This message will close in {seconds} second{s}."` | Countdown template |
71
+ | `pausedText` | `string` | `"Timer paused"` | Text when hovering (timer paused) |
72
+ | `stopText` | `string` | `"Click to stop."` | Clickable text to permanently stop timer |
73
+
74
+ ### Action Buttons
75
+
76
+ Actions support three formats: preset name, preset with callback, or custom action.
77
+
78
+ ```js
79
+ // Using preset name (no callback)
80
+ toast.success('Deleted', { action: 'undo' });
81
+
82
+ // Using preset with callback
83
+ toast.success('Message archived', {
84
+ action: {
85
+ preset: 'undo',
86
+ onAction: () => {
87
+ restoreMessage();
88
+ toast.info('Message restored');
89
+ },
90
+ },
91
+ });
92
+
93
+ // Custom action
94
+ toast.error('Upload failed', {
95
+ action: {
96
+ label: 'Retry',
97
+ onClick: () => retryUpload(),
98
+ },
99
+ });
100
+ ```
101
+
102
+ #### Registering Custom Presets
103
+
104
+ ```js
105
+ import { registerActionPreset } from 'toastywave';
106
+
107
+ registerActionPreset('retry', (onRetry) => ({
108
+ label: 'Retry',
109
+ onClick: onRetry,
110
+ }));
111
+
112
+ // Now use it anywhere
113
+ toast.error('Request failed', {
114
+ action: { preset: 'retry', onAction: () => fetchData() },
115
+ });
116
+ ```
117
+
118
+ ### Custom Icons
119
+
120
+ Use any React icon library by passing the `icon` prop:
121
+
122
+ ```jsx
123
+ import { RocketLaunchIcon } from '@heroicons/react/24/outline';
124
+
125
+ // Override default icon with Hero Icons
126
+ toast('Launching soon!', {
127
+ icon: <RocketLaunchIcon style={{ width: 20, height: 20, color: '#f472b6' }} />,
128
+ });
129
+
130
+ // Works with any toast type
131
+ toast.success('Deployed!', {
132
+ icon: <RocketLaunchIcon style={{ width: 20, height: 20, color: '#4ade80' }} />,
133
+ });
134
+
135
+ // Or use Lucide, FontAwesome, custom SVGs, etc.
136
+ toast.info('Syncing...', {
137
+ icon: <CloudIcon className="w-5 h-5 text-blue-400" />,
138
+ });
139
+ ```
140
+
141
+ ### Promise Toasts
142
+
143
+ ```js
144
+ toast.promise(
145
+ fetch('/api/deploy'),
146
+ {
147
+ loading: 'Deploying...',
148
+ success: 'Deployed successfully!',
149
+ error: 'Deploy failed',
150
+ }
151
+ );
152
+ ```
153
+
154
+ ### Dismissing
155
+
156
+ ```js
157
+ const id = toast('Persistent message', { duration: Infinity });
158
+
159
+ // Later...
160
+ toast.dismiss(id);
161
+ ```
162
+
163
+ ### Custom Countdown Text
164
+
165
+ ```js
166
+ // Custom text
167
+ toast.success('Saved', {
168
+ countdownText: 'Auto-closing in {seconds}s',
169
+ stopText: 'Keep open',
170
+ pausedText: 'Paused',
171
+ });
172
+
173
+ // Hide countdown entirely
174
+ toast.info('Clean notification', {
175
+ showCountdown: false,
176
+ });
177
+ ```
178
+
179
+ ### Deduplication
180
+
181
+ Identical toasts (same type + message) are automatically deduplicated:
182
+
183
+ ```js
184
+ toast.success('Saved'); // shown
185
+ toast.success('Saved'); // ignored (already active)
186
+ toast.success('Saved'); // ignored
187
+
188
+ // Custom dedup key
189
+ toast.info('Update', { dedupeKey: 'update-check' });
190
+ ```
191
+
192
+ ---
193
+
194
+ ## `<Toaster />` Component
195
+
196
+ Place once in your app layout.
197
+
198
+ ```jsx
199
+ <Toaster
200
+ position="bottom-right"
201
+ theme="dark"
202
+ />
203
+ ```
204
+
205
+ #### Props
206
+
207
+ | Prop | Type | Default | Description |
208
+ |---|---|---|---|
209
+ | `position` | `string` | `"bottom-right"` | `"top-left"` `"top-center"` `"top-right"` `"bottom-left"` `"bottom-center"` `"bottom-right"` |
210
+ | `theme` | `string \| object` | `"dark"` | `"dark"`, `"light"`, or a custom theme object |
211
+ | `container` | `RefObject` | — | Ref to a container element for scoped rendering |
212
+
213
+ ### Container Scoping
214
+
215
+ Render toasts inside a specific element instead of the window:
216
+
217
+ ```jsx
218
+ function Panel() {
219
+ const containerRef = useRef(null);
220
+
221
+ return (
222
+ <div ref={containerRef} style={{ position: 'relative', overflow: 'hidden' }}>
223
+ <Toaster position="top-center" container={containerRef} theme="light" />
224
+ <button onClick={() => toast.success('Scoped!')}>
225
+ Toast inside panel
226
+ </button>
227
+ </div>
228
+ );
229
+ }
230
+ ```
231
+
232
+ > **Note:** The container must have `position: relative` (or `absolute`/`fixed`).
233
+
234
+ ---
235
+
236
+ ## Theming
237
+
238
+ ### Built-in Themes
239
+
240
+ ```jsx
241
+ <Toaster theme="dark" />
242
+ <Toaster theme="light" />
243
+ ```
244
+
245
+ ### Custom Theme
246
+
247
+ Pass an object with any subset of theme tokens. Missing tokens fall back to the dark theme.
248
+
249
+ ```jsx
250
+ const customTheme = {
251
+ toastBg: 'rgba(15, 10, 40, 0.96)',
252
+ toastBorder: 'rgba(120, 80, 255, 0.15)',
253
+ toastShadow: '0 16px 48px rgba(60, 20, 180, 0.25)',
254
+ title: '#e8e0ff',
255
+ // ... other tokens
256
+ };
257
+
258
+ <Toaster theme={customTheme} />
259
+ ```
260
+
261
+ ### Theme Token Reference
262
+
263
+ | Token | Description |
264
+ |---|---|
265
+ | `toastBg` | Toast card background |
266
+ | `toastBorder` | Toast card border |
267
+ | `toastShadow` | Toast card box-shadow |
268
+ | `title` | Title text color |
269
+ | `desc` | Description text color |
270
+ | `footerBg` | Countdown footer background |
271
+ | `footerBorder` | Countdown footer top border |
272
+ | `footerText` | Countdown text color |
273
+ | `footerLink` | "Click to stop" link color |
274
+ | `progressTrack` | Progress bar track background |
275
+ | `closeBtnColor` | Close button default color |
276
+ | `closeBtnHover` | Close button hover color |
277
+ | `closeBtnHoverBg` | Close button hover background |
278
+ | `actionBg` | Action button background |
279
+ | `actionBorder` | Action button border |
280
+ | `actionHoverBg` | Action button hover background |
281
+ | `actionHoverBorder` | Action button hover border |
282
+ | `actionText` | Action button text color |
283
+ | `backdrop` | CSS backdrop-filter value |
284
+
285
+ ### Utilities
286
+
287
+ ```js
288
+ import { darkTheme, lightTheme, resolveTheme } from 'toastywave';
289
+
290
+ // Extend the dark theme
291
+ const custom = resolveTheme({
292
+ ...darkTheme,
293
+ toastBg: '#1a1a2e',
294
+ title: '#eee',
295
+ });
296
+ ```
297
+
298
+ ---
299
+
300
+ ## Development
301
+
302
+ ### Running the Playground
303
+
304
+ The repo includes a comprehensive playground that showcases all features.
305
+
306
+ ```bash
307
+ # Install dependencies
308
+ bun install
309
+
310
+ # Build library and start playground
311
+ bun run dev
312
+ ```
313
+
314
+ Then open **http://localhost:5173** in your browser.
315
+
316
+ The playground demonstrates:
317
+ - All toast types (default, success, error, warning, info, loading)
318
+ - Action presets (undo, retry) and custom actions
319
+ - Promise toasts
320
+ - Countdown timer options
321
+ - Position anchoring (6 positions)
322
+ - Theme switching (dark, light, custom)
323
+ - Deduplication
324
+ - Container scoping
325
+ - Programmatic dismissal
326
+
327
+ ### Scripts
328
+
329
+ | Script | Description |
330
+ |---|---|
331
+ | `bun run dev` | Build library and start playground |
332
+ | `bun run build` | Build the library |
333
+ | `bun run watch` | Watch mode for library development |
334
+ | `bun run playground` | Start playground only (requires build) |
335
+
336
+ ---
337
+
338
+ ## Browser Support
339
+
340
+ Works in all modern browsers (Chrome, Firefox, Safari, Edge).
341
+ Requires `backdrop-filter` support for the glass effect (gracefully degrades).
342
+
343
+ ## License
344
+
345
+ MIT
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),t=require("react/jsx-runtime");function r(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r<t;r++)n[r]=e[r];return n}function n(e,t,r){return(t=function(e){var t=function(e,t){if("object"!=typeof e||!e)return e;var r=e[Symbol.toPrimitive];if(void 0!==r){var n=r.call(e,t);if("object"!=typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==typeof t?t:t+""}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach(function(t){n(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}function a(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var n,o,i,a,s=[],c=!0,u=!1;try{if(i=(r=r.call(e)).next,0===t);else for(;!(c=(n=i.call(r)).done)&&(s.push(n.value),s.length!==t);c=!0);}catch(e){u=!0,o=e}finally{try{if(!c&&null!=r.return&&(a=r.return(),Object(a)!==a))return}finally{if(u)throw o}}return s}}(e,t)||c(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function s(e){return function(e){if(Array.isArray(e))return r(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||c(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function c(e,t){if(e){if("string"==typeof e)return r(e,t);var n={}.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?r(e,t):void 0}}var u=0,l=null,d=new Map,f=function(e){return d.delete(e)},p={undo:function(e){return{label:"Undo",onClick:e}}},g=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=t.dedupeKey||"".concat(t.type||"default","::").concat(e);if(d.has(r))return d.get(r);var n=++u,o=function(e){if(!e)return null;if("string"==typeof e){var t=p[e];return t?t(function(){}):null}if(e.preset){var r=p[e.preset];return r?r(e.onAction||function(){}):null}return e}(t.action),a=i(i({id:n,message:e,type:"default",duration:5e3,showCountdown:!0,countdownText:"This message will close in {seconds} second{s}.",pausedText:"Timer paused",stopText:"Click to stop."},t),{},{action:o,dedupeKey:r,createdAt:Date.now()});return d.set(r,n),l&&l(a),n};g.success=function(e,t){return g(e,i(i({},t),{},{type:"success"}))},g.error=function(e,t){return g(e,i(i({},t),{},{type:"error"}))},g.warning=function(e,t){return g(e,i(i({},t),{},{type:"warning"}))},g.info=function(e,t){return g(e,i(i({},t),{},{type:"info"}))},g.loading=function(e,t){return g(e,i(i({},t),{},{type:"loading",duration:1/0}))},g.promise=function(e,t,r){var n=g(t.loading,i(i({},r),{},{type:"loading",duration:1/0}));return e.then(function(){l&&l({id:n,message:t.success,type:"success",duration:5e3,showCountdown:!0,countdownText:(null==r?void 0:r.countdownText)||"This message will close in {seconds} second{s}.",pausedText:(null==r?void 0:r.pausedText)||"Timer paused",stopText:(null==r?void 0:r.stopText)||"Click to stop.",createdAt:Date.now(),replace:!0,dedupeKey:"p-ok-".concat(n)})}).catch(function(){l&&l({id:n,message:t.error,type:"error",duration:5e3,showCountdown:!0,countdownText:(null==r?void 0:r.countdownText)||"This message will close in {seconds} second{s}.",pausedText:(null==r?void 0:r.pausedText)||"Timer paused",stopText:(null==r?void 0:r.stopText)||"Click to stop.",createdAt:Date.now(),replace:!0,dedupeKey:"p-err-".concat(n)})}),n},g.dismiss=function(e){l&&l({id:e,_dismiss:!0})};var x={toastBg:"rgba(30,30,32,.95)",toastBorder:"rgba(255,255,255,.08)",toastShadow:"0 16px 48px rgba(0,0,0,.5),0 2px 8px rgba(0,0,0,.3),inset 0 1px 0 rgba(255,255,255,.04)",title:"#f0f0f0",desc:"rgba(255,255,255,.5)",footerBg:"rgba(0,0,0,.15)",footerBorder:"rgba(255,255,255,.06)",footerText:"rgba(255,255,255,.35)",footerLink:"rgba(255,255,255,.6)",progressTrack:"rgba(255,255,255,.04)",closeBtnColor:"rgba(255,255,255,.3)",closeBtnHover:"rgba(255,255,255,.7)",closeBtnHoverBg:"rgba(255,255,255,.06)",actionBg:"rgba(255,255,255,.08)",actionBorder:"rgba(255,255,255,.15)",actionHoverBg:"rgba(255,255,255,.14)",actionHoverBorder:"rgba(255,255,255,.25)",actionText:"#f0f0f0",backdrop:"blur(16px) saturate(1.4)"},b={toastBg:"rgba(255,255,255,.97)",toastBorder:"rgba(0,0,0,.08)",toastShadow:"0 16px 48px rgba(0,0,0,.08),0 4px 12px rgba(0,0,0,.05),0 1px 3px rgba(0,0,0,.06)",title:"#1a1a1a",desc:"rgba(0,0,0,.5)",footerBg:"rgba(0,0,0,.025)",footerBorder:"rgba(0,0,0,.06)",footerText:"rgba(0,0,0,.35)",footerLink:"rgba(0,0,0,.6)",progressTrack:"rgba(0,0,0,.05)",closeBtnColor:"rgba(0,0,0,.25)",closeBtnHover:"rgba(0,0,0,.6)",closeBtnHoverBg:"rgba(0,0,0,.05)",actionBg:"rgba(0,0,0,.05)",actionBorder:"rgba(0,0,0,.12)",actionHoverBg:"rgba(0,0,0,.1)",actionHoverBorder:"rgba(0,0,0,.2)",actionText:"#1a1a1a",backdrop:"blur(16px) saturate(1.2)"},h={dark:x,light:b},y=function(e){return e?"string"==typeof e?h[e]||x:i(i({},x),e):x},v=function(){return t.jsxs("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"none",children:[t.jsx("circle",{cx:"10",cy:"10",r:"9",stroke:"#4ade80",strokeWidth:"1.5",opacity:".3"}),t.jsx("path",{d:"M6.5 10.5l2 2 5-5",stroke:"#4ade80",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})]})},m=function(){return t.jsxs("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"none",children:[t.jsx("circle",{cx:"10",cy:"10",r:"9",stroke:"#f87171",strokeWidth:"1.5",opacity:".3"}),t.jsx("path",{d:"M10 6v5",stroke:"#f87171",strokeWidth:"1.5",strokeLinecap:"round"}),t.jsx("circle",{cx:"10",cy:"13.5",r:".75",fill:"#f87171"})]})},k=function(){return t.jsxs("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"none",children:[t.jsx("path",{d:"M10 2.5L1.5 17h17L10 2.5z",stroke:"#fbbf24",strokeWidth:"1.3",strokeLinejoin:"round",opacity:".35"}),t.jsx("path",{d:"M10 8v4",stroke:"#fbbf24",strokeWidth:"1.5",strokeLinecap:"round"}),t.jsx("circle",{cx:"10",cy:"14.5",r:".75",fill:"#fbbf24"})]})},j=function(){return t.jsxs("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"none",children:[t.jsx("circle",{cx:"10",cy:"10",r:"9",stroke:"#60a5fa",strokeWidth:"1.5",opacity:".3"}),t.jsx("path",{d:"M10 9v5",stroke:"#60a5fa",strokeWidth:"1.5",strokeLinecap:"round"}),t.jsx("circle",{cx:"10",cy:"6.5",r:".75",fill:"#60a5fa"})]})},w=function(){return t.jsxs("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"none",style:{animation:"toastywave-spin .7s linear infinite"},children:[t.jsx("circle",{cx:"10",cy:"10",r:"8",stroke:"currentColor",strokeWidth:"1.8",opacity:".15"}),t.jsx("path",{d:"M10 2a8 8 0 018 8",stroke:"currentColor",strokeWidth:"1.8",strokeLinecap:"round",opacity:".5"})]})},T=function(){return t.jsx("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",children:t.jsx("path",{d:"M3.5 3.5l7 7M10.5 3.5l-7 7"})})},B={success:t.jsx(v,{}),error:t.jsx(m,{}),warning:t.jsx(k,{}),info:t.jsx(j,{}),loading:t.jsx(w,{})},S={success:"#4ade80",error:"#f87171",warning:"#fbbf24",info:"#60a5fa",loading:"#a78bfa",default:"#888"};function C(r){var n=r.data,o=r.onDismiss,i=r.position,s=r.theme,c=a(e.useState("enter"),2),u=c[0],l=c[1],d=a(e.useState(!1),2),f=d[0],p=d[1],g=a(e.useState(n.duration),2),x=g[0],b=g[1],h=e.useRef(null),y=e.useRef(Date.now()),v=i.startsWith("top"),m=n.duration!==1/0,k=m&&!1!==n.showCountdown,j=s;e.useEffect(function(){if(m&&!f){y.current=Date.now();var e=y.current+x;return h.current=setInterval(function(){var t=e-Date.now();t<=0?(clearInterval(h.current),l("exit"),setTimeout(function(){return o(n.id,n.dedupeKey)},320)):b(t)},50),function(){return clearInterval(h.current)}}h.current&&clearInterval(h.current)},[f,m]),e.useEffect(function(){n.duration!==1/0&&b(n.duration)},[n.type,n.duration,n.createdAt]),e.useEffect(function(){var e=requestAnimationFrame(function(){return l("visible")});return function(){return cancelAnimationFrame(e)}},[]);var w,C,O=function(){l("exit"),setTimeout(function(){return o(n.id,n.dedupeKey)},320)},M=m?Math.max(0,x/n.duration):1,W=Math.ceil(x/1e3),A=v?-24:24,L={enter:"translateY(".concat(A,"px) scale(.95)"),visible:"translateY(0) scale(1)",exit:"translateY(".concat(A,"px) scale(.95)")};return t.jsxs("div",{onMouseEnter:function(){return!f&&p(!0)},onMouseLeave:function(){return p(!1)},style:{width:420,maxWidth:"calc(100vw - 32px)",background:j.toastBg,backdropFilter:j.backdrop,WebkitBackdropFilter:j.backdrop,border:"1px solid ".concat(j.toastBorder),borderRadius:12,overflow:"hidden",transform:L[u],opacity:"visible"===u?1:0,transition:"all .32s cubic-bezier(.16,1,.3,1)",boxShadow:j.toastShadow},children:[t.jsxs("div",{style:{padding:"14px 16px",display:"flex",alignItems:"flex-start",gap:12},children:[(n.icon||"default"!==n.type)&&t.jsx("div",{style:{flexShrink:0,marginTop:1,color:j.title},children:n.icon||B[n.type]}),t.jsxs("div",{style:{flex:1,minWidth:0},children:[t.jsx("div",{style:{fontSize:14,fontWeight:600,color:j.title,lineHeight:1.4},children:n.message}),n.description&&t.jsx("div",{style:{fontSize:13,color:j.desc,marginTop:4,lineHeight:1.45},children:n.description}),n.action&&t.jsx("button",{onClick:function(e){e.stopPropagation(),n.action.onClick&&n.action.onClick(),O()},onMouseEnter:function(e){e.currentTarget.style.background=j.actionHoverBg,e.currentTarget.style.borderColor=j.actionHoverBorder},onMouseLeave:function(e){e.currentTarget.style.background=j.actionBg,e.currentTarget.style.borderColor=j.actionBorder},style:{marginTop:10,padding:"6px 14px",fontSize:13,fontWeight:600,fontFamily:"inherit",borderRadius:6,border:"1px solid ".concat(j.actionBorder),background:j.actionBg,color:j.actionText,cursor:"pointer",transition:"all .15s ease"},children:n.action.label})]}),t.jsx("button",{onClick:function(e){e.stopPropagation(),O()},onMouseEnter:function(e){e.currentTarget.style.color=j.closeBtnHover,e.currentTarget.style.background=j.closeBtnHoverBg},onMouseLeave:function(e){e.currentTarget.style.color=j.closeBtnColor,e.currentTarget.style.background="transparent"},style:{flexShrink:0,width:28,height:28,border:"none",background:"transparent",color:j.closeBtnColor,cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",borderRadius:6,transition:"all .15s ease",padding:0},children:t.jsx(T,{})})]}),k&&t.jsx("div",{style:{borderTop:"1px solid ".concat(j.footerBorder),padding:"8px 16px",background:j.footerBg,display:"flex",alignItems:"center"},children:t.jsx("div",{style:{fontSize:12,color:j.footerText},children:f?n.pausedText:t.jsxs(t.Fragment,{children:[(w=n.countdownText,C=W,w.replace(/\{seconds\}/g,String(C)).replace(/\{s\}/g,1!==C?"s":""))," ",t.jsx("span",{onClick:function(e){e.stopPropagation(),p(!0)},style:{color:j.footerLink,fontWeight:600,cursor:"pointer",textDecoration:"underline",textUnderlineOffset:2},children:n.stopText})]})})}),m&&!f&&t.jsx("div",{style:{height:2,background:j.progressTrack,position:"relative"},children:t.jsx("div",{style:{position:"absolute",left:0,top:0,height:"100%",width:"".concat(100*M,"%"),background:S[n.type]||S.default,transition:"width .1s linear",borderRadius:"0 1px 1px 0"}})})]})}exports.Toaster=function(r){var n=r.position,o=void 0===n?"bottom-right":n,c=r.theme,u=void 0===c?"dark":c,d=r.container,p=a(e.useState([]),2),g=p[0],x=p[1],b=y(u);e.useEffect(function(){return l=function(e){e._dismiss?x(function(t){var r=t.find(function(t){return t.id===e.id});return r&&f(r.dedupeKey),t.filter(function(t){return t.id!==e.id})}):x(function(t){if(e.replace){var r=t.find(function(t){return t.id===e.id});return r&&f(r.dedupeKey),t.map(function(t){return t.id===e.id?i({},e):t})}return[].concat(s(t),[e])})},function(){l=null}},[]);var h=e.useCallback(function(e,t){f(t),x(function(t){return t.filter(function(t){return t.id!==e})})},[]),v=a(o.split("-"),2),m=v[0],k=v[1],j="center"===k;return t.jsxs("div",{style:i(i({position:d?"absolute":"fixed",zIndex:99999,display:"flex",flexDirection:"top"===m?"column":"column-reverse",alignItems:j?"center":"left"===k?"flex-start":"flex-end",gap:10,padding:d?12:20,pointerEvents:"none"},"top"===m?{top:0}:{bottom:0}),j?{left:0,right:0}:"left"===k?{left:0}:{right:0}),children:[t.jsx("style",{children:"@keyframes toastywave-spin{to{transform:rotate(360deg)}}"}),g.map(function(e){return t.jsx("div",{style:{pointerEvents:"auto"},children:t.jsx(C,{data:e,onDismiss:h,position:o,theme:b})},e.id)})]})},exports.darkTheme=x,exports.default=g,exports.lightTheme=b,exports.registerActionPreset=function(e,t){p[e]=t},exports.resolveTheme=y,exports.toast=g;
2
+ //# sourceMappingURL=index.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs.js","sources":["../src/index.jsx"],"sourcesContent":["import { useState, useEffect, useCallback, useRef, createContext, useContext } from \"react\";\n\n/* ═══════════════════════════════════════════════════════════════\n TOASTYWAVE - Lightweight React Toast Notification System\n ═══════════════════════════════════════════════════════════════ */\n\n// ── Internal State ──────────────────────────────────────────────\n\nlet _id = 0;\nlet _addToast = null;\nlet _active = new Map();\n\nconst _unreg = (k) => _active.delete(k);\n\n// ── Public API ──────────────────────────────────────────────────\n\n// ── Action Presets ───────────────────────────────────────────────\n\nconst actionPresets = {\n undo: (onUndo) => ({\n label: \"Undo\",\n onClick: onUndo,\n }),\n};\n\n/**\n * Register a custom action preset.\n * @param {string} name - Preset name\n * @param {Function} factory - Factory function (onAction) => { label, onClick }\n */\nconst registerActionPreset = (name, factory) => {\n actionPresets[name] = factory;\n};\n\n/**\n * Resolve action from preset string or custom object.\n * @param {string|Object} action - \"undo\", { preset: \"undo\", onAction }, or { label, onClick }\n * @returns {Object|null} Resolved action object\n */\nconst resolveAction = (action) => {\n if (!action) return null;\n if (typeof action === \"string\") {\n // Preset name only (e.g., \"undo\") - return preset with no-op\n const factory = actionPresets[action];\n return factory ? factory(() => {}) : null;\n }\n if (action.preset) {\n // Preset with callback (e.g., { preset: \"undo\", onAction: () => {...} })\n const factory = actionPresets[action.preset];\n return factory ? factory(action.onAction || (() => {})) : null;\n }\n // Custom action object { label, onClick }\n return action;\n};\n\n/**\n * Show a toast notification.\n *\n * @param {string} message - The toast title/message\n * @param {Object} [opts] - Options\n * @param {string} [opts.type=\"default\"] - Toast type: \"default\"|\"success\"|\"error\"|\"warning\"|\"info\"|\"loading\"\n * @param {string} [opts.description] - Secondary text below the message\n * @param {number} [opts.duration=5000] - Auto-dismiss duration in ms. Use Infinity to persist.\n * @param {string|Object} [opts.action] - Action button: preset name (\"undo\"), preset config ({ preset: \"undo\", onAction }), or custom ({ label, onClick })\n * @param {React.ReactNode} [opts.icon] - Custom icon element. Overrides the default type icon.\n * @param {string} [opts.dedupeKey] - Custom dedup key. Defaults to `${type}::${message}`\n * @param {string} [opts.countdownText] - Custom countdown text. Use `{seconds}` as placeholder.\n * @param {string} [opts.pausedText] - Custom text shown when timer is paused.\n * @param {string} [opts.stopText] - Custom \"Click to stop\" text.\n * @param {boolean} [opts.showCountdown=true] - Whether to show the countdown footer.\n * @returns {number} Toast ID\n */\nconst toast = (message, opts = {}) => {\n const dk = opts.dedupeKey || `${opts.type || \"default\"}::${message}`;\n if (_active.has(dk)) return _active.get(dk);\n const id = ++_id;\n const resolvedAction = resolveAction(opts.action);\n const t = {\n id,\n message,\n type: \"default\",\n duration: 5000,\n showCountdown: true,\n countdownText: \"This message will close in {seconds} second{s}.\",\n pausedText: \"Timer paused\",\n stopText: \"Click to stop.\",\n ...opts,\n action: resolvedAction,\n dedupeKey: dk,\n createdAt: Date.now(),\n };\n _active.set(dk, id);\n if (_addToast) _addToast(t);\n return id;\n};\n\ntoast.success = (m, o) => toast(m, { ...o, type: \"success\" });\ntoast.error = (m, o) => toast(m, { ...o, type: \"error\" });\ntoast.warning = (m, o) => toast(m, { ...o, type: \"warning\" });\ntoast.info = (m, o) => toast(m, { ...o, type: \"info\" });\ntoast.loading = (m, o) => toast(m, { ...o, type: \"loading\", duration: Infinity });\n\n/**\n * Show a promise-based toast that transitions from loading → success/error.\n *\n * @param {Promise} promise\n * @param {Object} msgs - { loading, success, error }\n * @param {Object} [opts] - Same options as toast()\n * @returns {number} Toast ID\n */\ntoast.promise = (promise, msgs, o) => {\n const id = toast(msgs.loading, { ...o, type: \"loading\", duration: Infinity });\n promise\n .then(() => {\n if (_addToast)\n _addToast({\n id, message: msgs.success, type: \"success\", duration: 5000,\n showCountdown: true,\n countdownText: o?.countdownText || \"This message will close in {seconds} second{s}.\",\n pausedText: o?.pausedText || \"Timer paused\",\n stopText: o?.stopText || \"Click to stop.\",\n createdAt: Date.now(), replace: true, dedupeKey: `p-ok-${id}`,\n });\n })\n .catch(() => {\n if (_addToast)\n _addToast({\n id, message: msgs.error, type: \"error\", duration: 5000,\n showCountdown: true,\n countdownText: o?.countdownText || \"This message will close in {seconds} second{s}.\",\n pausedText: o?.pausedText || \"Timer paused\",\n stopText: o?.stopText || \"Click to stop.\",\n createdAt: Date.now(), replace: true, dedupeKey: `p-err-${id}`,\n });\n });\n return id;\n};\n\n/**\n * Programmatically dismiss a toast by ID.\n * @param {number} id\n */\ntoast.dismiss = (id) => {\n if (_addToast) _addToast({ id, _dismiss: true });\n};\n\n// ── Default Themes ──────────────────────────────────────────────\n\nconst darkTheme = {\n toastBg: \"rgba(30,30,32,.95)\",\n toastBorder: \"rgba(255,255,255,.08)\",\n toastShadow: \"0 16px 48px rgba(0,0,0,.5),0 2px 8px rgba(0,0,0,.3),inset 0 1px 0 rgba(255,255,255,.04)\",\n title: \"#f0f0f0\",\n desc: \"rgba(255,255,255,.5)\",\n footerBg: \"rgba(0,0,0,.15)\",\n footerBorder: \"rgba(255,255,255,.06)\",\n footerText: \"rgba(255,255,255,.35)\",\n footerLink: \"rgba(255,255,255,.6)\",\n progressTrack: \"rgba(255,255,255,.04)\",\n closeBtnColor: \"rgba(255,255,255,.3)\",\n closeBtnHover: \"rgba(255,255,255,.7)\",\n closeBtnHoverBg: \"rgba(255,255,255,.06)\",\n actionBg: \"rgba(255,255,255,.08)\",\n actionBorder: \"rgba(255,255,255,.15)\",\n actionHoverBg: \"rgba(255,255,255,.14)\",\n actionHoverBorder: \"rgba(255,255,255,.25)\",\n actionText: \"#f0f0f0\",\n backdrop: \"blur(16px) saturate(1.4)\",\n};\n\nconst lightTheme = {\n toastBg: \"rgba(255,255,255,.97)\",\n toastBorder: \"rgba(0,0,0,.08)\",\n toastShadow: \"0 16px 48px rgba(0,0,0,.08),0 4px 12px rgba(0,0,0,.05),0 1px 3px rgba(0,0,0,.06)\",\n title: \"#1a1a1a\",\n desc: \"rgba(0,0,0,.5)\",\n footerBg: \"rgba(0,0,0,.025)\",\n footerBorder: \"rgba(0,0,0,.06)\",\n footerText: \"rgba(0,0,0,.35)\",\n footerLink: \"rgba(0,0,0,.6)\",\n progressTrack: \"rgba(0,0,0,.05)\",\n closeBtnColor: \"rgba(0,0,0,.25)\",\n closeBtnHover: \"rgba(0,0,0,.6)\",\n closeBtnHoverBg: \"rgba(0,0,0,.05)\",\n actionBg: \"rgba(0,0,0,.05)\",\n actionBorder: \"rgba(0,0,0,.12)\",\n actionHoverBg: \"rgba(0,0,0,.1)\",\n actionHoverBorder: \"rgba(0,0,0,.2)\",\n actionText: \"#1a1a1a\",\n backdrop: \"blur(16px) saturate(1.2)\",\n};\n\nconst builtInThemes = { dark: darkTheme, light: lightTheme };\n\n/**\n * Resolve a theme by name or merge a custom theme object on top of the dark base.\n * @param {\"dark\"|\"light\"|Object} themeOrName\n * @returns {Object} Resolved theme tokens\n */\nconst resolveTheme = (themeOrName) => {\n if (!themeOrName) return darkTheme;\n if (typeof themeOrName === \"string\") return builtInThemes[themeOrName] || darkTheme;\n return { ...darkTheme, ...themeOrName };\n};\n\n// ── SVG Icons ───────────────────────────────────────────────────\n\nconst CheckIcon = () => (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\n <circle cx=\"10\" cy=\"10\" r=\"9\" stroke=\"#4ade80\" strokeWidth=\"1.5\" opacity=\".3\" />\n <path d=\"M6.5 10.5l2 2 5-5\" stroke=\"#4ade80\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n);\nconst ErrorIcon = () => (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\n <circle cx=\"10\" cy=\"10\" r=\"9\" stroke=\"#f87171\" strokeWidth=\"1.5\" opacity=\".3\" />\n <path d=\"M10 6v5\" stroke=\"#f87171\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n <circle cx=\"10\" cy=\"13.5\" r=\".75\" fill=\"#f87171\" />\n </svg>\n);\nconst WarningIcon = () => (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\n <path d=\"M10 2.5L1.5 17h17L10 2.5z\" stroke=\"#fbbf24\" strokeWidth=\"1.3\" strokeLinejoin=\"round\" opacity=\".35\" />\n <path d=\"M10 8v4\" stroke=\"#fbbf24\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n <circle cx=\"10\" cy=\"14.5\" r=\".75\" fill=\"#fbbf24\" />\n </svg>\n);\nconst InfoIcon = () => (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\n <circle cx=\"10\" cy=\"10\" r=\"9\" stroke=\"#60a5fa\" strokeWidth=\"1.5\" opacity=\".3\" />\n <path d=\"M10 9v5\" stroke=\"#60a5fa\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n <circle cx=\"10\" cy=\"6.5\" r=\".75\" fill=\"#60a5fa\" />\n </svg>\n);\nconst LoadingIcon = () => (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" style={{ animation: \"toastywave-spin .7s linear infinite\" }}>\n <circle cx=\"10\" cy=\"10\" r=\"8\" stroke=\"currentColor\" strokeWidth=\"1.8\" opacity=\".15\" />\n <path d=\"M10 2a8 8 0 018 8\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" opacity=\".5\" />\n </svg>\n);\nconst CloseIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\">\n <path d=\"M3.5 3.5l7 7M10.5 3.5l-7 7\" />\n </svg>\n);\n\nconst iconMap = {\n success: <CheckIcon />,\n error: <ErrorIcon />,\n warning: <WarningIcon />,\n info: <InfoIcon />,\n loading: <LoadingIcon />,\n};\n\nconst accentMap = {\n success: \"#4ade80\",\n error: \"#f87171\",\n warning: \"#fbbf24\",\n info: \"#60a5fa\",\n loading: \"#a78bfa\",\n default: \"#888\",\n};\n\n// ── Countdown Text Formatter ────────────────────────────────────\n\nconst formatCountdown = (template, seconds) => {\n return template\n .replace(/\\{seconds\\}/g, String(seconds))\n .replace(/\\{s\\}/g, seconds !== 1 ? \"s\" : \"\");\n};\n\n// ── Toast Item ──────────────────────────────────────────────────\n\nfunction ToastItem({ data, onDismiss, position, theme }) {\n const [phase, setPhase] = useState(\"enter\");\n const [paused, setPaused] = useState(false);\n const [remain, setRemain] = useState(data.duration);\n const ivRef = useRef(null);\n const startRef = useRef(Date.now());\n const isTop = position.startsWith(\"top\");\n const hasDur = data.duration !== Infinity;\n const showFooter = hasDur && data.showCountdown !== false;\n const th = theme;\n\n useEffect(() => {\n if (!hasDur || paused) {\n if (ivRef.current) clearInterval(ivRef.current);\n return;\n }\n startRef.current = Date.now();\n const end = startRef.current + remain;\n ivRef.current = setInterval(() => {\n const left = end - Date.now();\n if (left <= 0) {\n clearInterval(ivRef.current);\n setPhase(\"exit\");\n setTimeout(() => onDismiss(data.id, data.dedupeKey), 320);\n } else {\n setRemain(left);\n }\n }, 50);\n return () => clearInterval(ivRef.current);\n }, [paused, hasDur]);\n\n useEffect(() => {\n if (data.duration !== Infinity) setRemain(data.duration);\n }, [data.type, data.duration, data.createdAt]);\n\n useEffect(() => {\n const r = requestAnimationFrame(() => setPhase(\"visible\"));\n return () => cancelAnimationFrame(r);\n }, []);\n\n const dismiss = () => {\n setPhase(\"exit\");\n setTimeout(() => onDismiss(data.id, data.dedupeKey), 320);\n };\n\n const stopTimer = (e) => {\n e.stopPropagation();\n setPaused(true);\n };\n\n const progress = hasDur ? Math.max(0, remain / data.duration) : 1;\n const secs = Math.ceil(remain / 1000);\n const enterY = isTop ? -24 : 24;\n const tf = {\n enter: `translateY(${enterY}px) scale(.95)`,\n visible: \"translateY(0) scale(1)\",\n exit: `translateY(${enterY}px) scale(.95)`,\n };\n\n return (\n <div\n onMouseEnter={() => !paused && setPaused(true)}\n onMouseLeave={() => setPaused(false)}\n style={{\n width: 420,\n maxWidth: \"calc(100vw - 32px)\",\n background: th.toastBg,\n backdropFilter: th.backdrop,\n WebkitBackdropFilter: th.backdrop,\n border: `1px solid ${th.toastBorder}`,\n borderRadius: 12,\n overflow: \"hidden\",\n transform: tf[phase],\n opacity: phase === \"visible\" ? 1 : 0,\n transition: \"all .32s cubic-bezier(.16,1,.3,1)\",\n boxShadow: th.toastShadow,\n }}\n >\n {/* Content */}\n <div style={{ padding: \"14px 16px\", display: \"flex\", alignItems: \"flex-start\", gap: 12 }}>\n {(data.icon || data.type !== \"default\") && (\n <div style={{ flexShrink: 0, marginTop: 1, color: th.title }}>\n {data.icon || iconMap[data.type]}\n </div>\n )}\n <div style={{ flex: 1, minWidth: 0 }}>\n <div style={{ fontSize: 14, fontWeight: 600, color: th.title, lineHeight: 1.4 }}>\n {data.message}\n </div>\n {data.description && (\n <div style={{ fontSize: 13, color: th.desc, marginTop: 4, lineHeight: 1.45 }}>\n {data.description}\n </div>\n )}\n {data.action && (\n <button\n onClick={(e) => {\n e.stopPropagation();\n if (data.action.onClick) data.action.onClick();\n dismiss();\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.background = th.actionHoverBg;\n e.currentTarget.style.borderColor = th.actionHoverBorder;\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.background = th.actionBg;\n e.currentTarget.style.borderColor = th.actionBorder;\n }}\n style={{\n marginTop: 10,\n padding: \"6px 14px\",\n fontSize: 13,\n fontWeight: 600,\n fontFamily: \"inherit\",\n borderRadius: 6,\n border: `1px solid ${th.actionBorder}`,\n background: th.actionBg,\n color: th.actionText,\n cursor: \"pointer\",\n transition: \"all .15s ease\",\n }}\n >\n {data.action.label}\n </button>\n )}\n </div>\n <button\n onClick={(e) => {\n e.stopPropagation();\n dismiss();\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.color = th.closeBtnHover;\n e.currentTarget.style.background = th.closeBtnHoverBg;\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.color = th.closeBtnColor;\n e.currentTarget.style.background = \"transparent\";\n }}\n style={{\n flexShrink: 0,\n width: 28,\n height: 28,\n border: \"none\",\n background: \"transparent\",\n color: th.closeBtnColor,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n borderRadius: 6,\n transition: \"all .15s ease\",\n padding: 0,\n }}\n >\n <CloseIcon />\n </button>\n </div>\n\n {/* Countdown footer */}\n {showFooter && (\n <div\n style={{\n borderTop: `1px solid ${th.footerBorder}`,\n padding: \"8px 16px\",\n background: th.footerBg,\n display: \"flex\",\n alignItems: \"center\",\n }}\n >\n <div style={{ fontSize: 12, color: th.footerText }}>\n {paused ? (\n data.pausedText\n ) : (\n <>\n {formatCountdown(data.countdownText, secs)}{\" \"}\n <span\n onClick={stopTimer}\n style={{\n color: th.footerLink,\n fontWeight: 600,\n cursor: \"pointer\",\n textDecoration: \"underline\",\n textUnderlineOffset: 2,\n }}\n >\n {data.stopText}\n </span>\n </>\n )}\n </div>\n </div>\n )}\n\n {/* Progress bar */}\n {hasDur && !paused && (\n <div style={{ height: 2, background: th.progressTrack, position: \"relative\" }}>\n <div\n style={{\n position: \"absolute\",\n left: 0,\n top: 0,\n height: \"100%\",\n width: `${progress * 100}%`,\n background: accentMap[data.type] || accentMap.default,\n transition: \"width .1s linear\",\n borderRadius: \"0 1px 1px 0\",\n }}\n />\n </div>\n )}\n </div>\n );\n}\n\n// ── Toaster Component ───────────────────────────────────────────\n\n/**\n * Toaster container component. Place once in your app.\n *\n * @param {Object} props\n * @param {\"top-left\"|\"top-center\"|\"top-right\"|\"bottom-left\"|\"bottom-center\"|\"bottom-right\"} [props.position=\"bottom-right\"]\n * @param {\"dark\"|\"light\"|Object} [props.theme=\"dark\"] - Built-in theme name or custom theme object\n * @param {React.RefObject} [props.container] - Optional ref to scope toasts inside a container (uses absolute positioning)\n */\nfunction Toaster({ position = \"bottom-right\", theme = \"dark\", container }) {\n const [toasts, setToasts] = useState([]);\n const resolvedThemeObj = resolveTheme(theme);\n\n useEffect(() => {\n _addToast = (t) => {\n if (t._dismiss) {\n setToasts((p) => {\n const f = p.find((x) => x.id === t.id);\n if (f) _unreg(f.dedupeKey);\n return p.filter((x) => x.id !== t.id);\n });\n return;\n }\n setToasts((p) => {\n if (t.replace) {\n const o = p.find((x) => x.id === t.id);\n if (o) _unreg(o.dedupeKey);\n return p.map((x) => (x.id === t.id ? { ...t } : x));\n }\n return [...p, t];\n });\n };\n return () => {\n _addToast = null;\n };\n }, []);\n\n const dismiss = useCallback((id, dk) => {\n _unreg(dk);\n setToasts((p) => p.filter((x) => x.id !== id));\n }, []);\n\n const [vPos, hPos] = position.split(\"-\");\n const isCenter = hPos === \"center\";\n\n return (\n <div\n style={{\n position: container ? \"absolute\" : \"fixed\",\n zIndex: 99999,\n display: \"flex\",\n flexDirection: vPos === \"top\" ? \"column\" : \"column-reverse\",\n alignItems: isCenter ? \"center\" : hPos === \"left\" ? \"flex-start\" : \"flex-end\",\n gap: 10,\n padding: container ? 12 : 20,\n pointerEvents: \"none\",\n ...(vPos === \"top\" ? { top: 0 } : { bottom: 0 }),\n ...(isCenter ? { left: 0, right: 0 } : hPos === \"left\" ? { left: 0 } : { right: 0 }),\n }}\n >\n <style>{`@keyframes toastywave-spin{to{transform:rotate(360deg)}}`}</style>\n {toasts.map((t) => (\n <div key={t.id} style={{ pointerEvents: \"auto\" }}>\n <ToastItem data={t} onDismiss={dismiss} position={position} theme={resolvedThemeObj} />\n </div>\n ))}\n </div>\n );\n}\n\n// ── Exports ─────────────────────────────────────────────────────\n\nexport { toast, Toaster, darkTheme, lightTheme, resolveTheme, registerActionPreset };\nexport default toast;\n"],"names":["_id","_addToast","_active","Map","_unreg","k","actionPresets","undo","onUndo","label","onClick","toast","message","opts","arguments","length","undefined","dk","dedupeKey","concat","type","has","get","id","resolvedAction","action","factory","preset","onAction","resolveAction","t","_objectSpread","duration","showCountdown","countdownText","pausedText","stopText","createdAt","Date","now","set","success","m","o","error","warning","info","loading","Infinity","promise","msgs","then","replace","dismiss","_dismiss","darkTheme","toastBg","toastBorder","toastShadow","title","desc","footerBg","footerBorder","footerText","footerLink","progressTrack","closeBtnColor","closeBtnHover","closeBtnHoverBg","actionBg","actionBorder","actionHoverBg","actionHoverBorder","actionText","backdrop","lightTheme","builtInThemes","dark","light","resolveTheme","themeOrName","CheckIcon","_jsxs","width","height","viewBox","fill","children","_jsx","cx","cy","r","stroke","strokeWidth","opacity","d","strokeLinecap","strokeLinejoin","ErrorIcon","WarningIcon","InfoIcon","LoadingIcon","style","animation","CloseIcon","iconMap","accentMap","default","ToastItem","_ref","data","onDismiss","position","theme","_useState2","_slicedToArray","useState","phase","setPhase","_useState4","paused","setPaused","_useState6","remain","setRemain","ivRef","useRef","startRef","isTop","startsWith","hasDur","showFooter","th","useEffect","current","end","setInterval","left","clearInterval","setTimeout","requestAnimationFrame","cancelAnimationFrame","template","seconds","progress","Math","max","secs","ceil","enterY","tf","enter","visible","exit","onMouseEnter","onMouseLeave","maxWidth","background","backdropFilter","WebkitBackdropFilter","border","borderRadius","overflow","transform","transition","boxShadow","padding","display","alignItems","gap","icon","flexShrink","marginTop","color","flex","minWidth","fontSize","fontWeight","lineHeight","description","e","stopPropagation","currentTarget","borderColor","fontFamily","cursor","justifyContent","borderTop","_Fragment","String","textDecoration","textUnderlineOffset","top","_ref2","_ref2$position","_ref2$theme","container","_useState8","toasts","setToasts","resolvedThemeObj","p","f","find","x","filter","map","_toConsumableArray","useCallback","_position$split2","split","vPos","hPos","isCenter","zIndex","flexDirection","pointerEvents","bottom","right","name"],"mappings":"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"}
@@ -0,0 +1,130 @@
1
+ import { FC, RefObject, ReactNode } from "react";
2
+
3
+ // ── Theme ───────────────────────────────────────────────────────
4
+
5
+ export interface ToastTheme {
6
+ toastBg?: string;
7
+ toastBorder?: string;
8
+ toastShadow?: string;
9
+ title?: string;
10
+ desc?: string;
11
+ footerBg?: string;
12
+ footerBorder?: string;
13
+ footerText?: string;
14
+ footerLink?: string;
15
+ progressTrack?: string;
16
+ closeBtnColor?: string;
17
+ closeBtnHover?: string;
18
+ closeBtnHoverBg?: string;
19
+ actionBg?: string;
20
+ actionBorder?: string;
21
+ actionHoverBg?: string;
22
+ actionHoverBorder?: string;
23
+ actionText?: string;
24
+ backdrop?: string;
25
+ }
26
+
27
+ // ── Toast Options ───────────────────────────────────────────────
28
+
29
+ /** Custom action button configuration */
30
+ export interface ToastAction {
31
+ /** Button label text */
32
+ label: string;
33
+ /** Callback when button is clicked */
34
+ onClick: () => void;
35
+ }
36
+
37
+ /** Preset action with callback */
38
+ export interface ToastActionPreset {
39
+ /** Preset name (e.g., "undo") */
40
+ preset: string;
41
+ /** Callback when the action is triggered */
42
+ onAction?: () => void;
43
+ }
44
+
45
+ /** Action can be a preset name, preset config, or custom action */
46
+ export type ToastActionInput = string | ToastActionPreset | ToastAction;
47
+
48
+ /** Factory function for creating action presets */
49
+ export type ActionPresetFactory = (onAction: () => void) => ToastAction;
50
+
51
+ export interface ToastOptions {
52
+ /** Toast type */
53
+ type?: "default" | "success" | "error" | "warning" | "info" | "loading";
54
+ /** Secondary description text */
55
+ description?: string;
56
+ /** Auto-dismiss in ms. Use Infinity to persist. Default: 5000 */
57
+ duration?: number;
58
+ /** Action button: preset name ("undo"), preset config ({ preset: "undo", onAction }), or custom ({ label, onClick }) */
59
+ action?: ToastActionInput;
60
+ /** Custom icon element. Overrides the default type icon. Use with any icon library (Hero Icons, Lucide, etc.) */
61
+ icon?: ReactNode;
62
+ /** Custom dedup key. Defaults to `${type}::${message}` */
63
+ dedupeKey?: string;
64
+ /** Countdown text template. Use {seconds} and {s} as placeholders. */
65
+ countdownText?: string;
66
+ /** Text shown when timer is paused on hover. */
67
+ pausedText?: string;
68
+ /** "Click to stop" link text. */
69
+ stopText?: string;
70
+ /** Whether to show countdown footer. Default: true */
71
+ showCountdown?: boolean;
72
+ }
73
+
74
+ export interface PromiseMessages {
75
+ loading: string;
76
+ success: string;
77
+ error: string;
78
+ }
79
+
80
+ // ── toast() API ─────────────────────────────────────────────────
81
+
82
+ export interface ToastAPI {
83
+ (message: string, opts?: ToastOptions): number;
84
+ success(message: string, opts?: Omit<ToastOptions, "type">): number;
85
+ error(message: string, opts?: Omit<ToastOptions, "type">): number;
86
+ warning(message: string, opts?: Omit<ToastOptions, "type">): number;
87
+ info(message: string, opts?: Omit<ToastOptions, "type">): number;
88
+ loading(message: string, opts?: Omit<ToastOptions, "type">): number;
89
+ promise(promise: Promise<any>, msgs: PromiseMessages, opts?: ToastOptions): number;
90
+ dismiss(id: number): void;
91
+ }
92
+
93
+ export declare const toast: ToastAPI;
94
+ export default toast;
95
+
96
+ // ── Toaster Component ───────────────────────────────────────────
97
+
98
+ export type ToastPosition =
99
+ | "top-left"
100
+ | "top-center"
101
+ | "top-right"
102
+ | "bottom-left"
103
+ | "bottom-center"
104
+ | "bottom-right";
105
+
106
+ export interface ToasterProps {
107
+ /** Position of toast stack. Default: "bottom-right" */
108
+ position?: ToastPosition;
109
+ /** "dark" | "light" | custom ToastTheme object */
110
+ theme?: "dark" | "light" | ToastTheme;
111
+ /** Ref to a container element for scoped rendering */
112
+ container?: RefObject<HTMLElement>;
113
+ }
114
+
115
+ export declare const Toaster: FC<ToasterProps>;
116
+
117
+ // ── Built-in Themes ─────────────────────────────────────────────
118
+
119
+ export declare const darkTheme: ToastTheme;
120
+ export declare const lightTheme: ToastTheme;
121
+ export declare function resolveTheme(themeOrName: "dark" | "light" | ToastTheme): ToastTheme;
122
+
123
+ // ── Action Presets ───────────────────────────────────────────────
124
+
125
+ /**
126
+ * Register a custom action preset.
127
+ * @param name - Preset name (e.g., "retry", "dismiss")
128
+ * @param factory - Factory function that takes onAction callback and returns { label, onClick }
129
+ */
130
+ export declare function registerActionPreset(name: string, factory: ActionPresetFactory): void;
@@ -0,0 +1,2 @@
1
+ import{useState as t,useEffect as e,useCallback as r,useRef as n}from"react";import{jsxs as o,jsx as i,Fragment as a}from"react/jsx-runtime";function c(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=Array(e);r<e;r++)n[r]=t[r];return n}function s(t,e,r){return(e=function(t){var e=function(t,e){if("object"!=typeof t||!t)return t;var r=t[Symbol.toPrimitive];if(void 0!==r){var n=r.call(t,e);if("object"!=typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}(t,"string");return"symbol"==typeof e?e:e+""}(e))in t?Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):t[e]=r,t}function l(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),r.push.apply(r,n)}return r}function u(t){for(var e=1;e<arguments.length;e++){var r=null!=arguments[e]?arguments[e]:{};e%2?l(Object(r),!0).forEach(function(e){s(t,e,r[e])}):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(r)):l(Object(r)).forEach(function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(r,e))})}return t}function d(t,e){return function(t){if(Array.isArray(t))return t}(t)||function(t,e){var r=null==t?null:"undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(null!=r){var n,o,i,a,c=[],s=!0,l=!1;try{if(i=(r=r.call(t)).next,0===e);else for(;!(s=(n=i.call(r)).done)&&(c.push(n.value),c.length!==e);s=!0);}catch(t){l=!0,o=t}finally{try{if(!s&&null!=r.return&&(a=r.return(),Object(a)!==a))return}finally{if(l)throw o}}return c}}(t,e)||p(t,e)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function f(t){return function(t){if(Array.isArray(t))return c(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||p(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function p(t,e){if(t){if("string"==typeof t)return c(t,e);var r={}.toString.call(t).slice(8,-1);return"Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r?Array.from(t):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?c(t,e):void 0}}var g=0,b=null,h=new Map,y=function(t){return h.delete(t)},v={undo:function(t){return{label:"Undo",onClick:t}}},x=function(t,e){v[t]=e},m=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=e.dedupeKey||"".concat(e.type||"default","::").concat(t);if(h.has(r))return h.get(r);var n=++g,o=function(t){if(!t)return null;if("string"==typeof t){var e=v[t];return e?e(function(){}):null}if(t.preset){var r=v[t.preset];return r?r(t.onAction||function(){}):null}return t}(e.action),i=u(u({id:n,message:t,type:"default",duration:5e3,showCountdown:!0,countdownText:"This message will close in {seconds} second{s}.",pausedText:"Timer paused",stopText:"Click to stop."},e),{},{action:o,dedupeKey:r,createdAt:Date.now()});return h.set(r,n),b&&b(i),n};m.success=function(t,e){return m(t,u(u({},e),{},{type:"success"}))},m.error=function(t,e){return m(t,u(u({},e),{},{type:"error"}))},m.warning=function(t,e){return m(t,u(u({},e),{},{type:"warning"}))},m.info=function(t,e){return m(t,u(u({},e),{},{type:"info"}))},m.loading=function(t,e){return m(t,u(u({},e),{},{type:"loading",duration:1/0}))},m.promise=function(t,e,r){var n=m(e.loading,u(u({},r),{},{type:"loading",duration:1/0}));return t.then(function(){b&&b({id:n,message:e.success,type:"success",duration:5e3,showCountdown:!0,countdownText:(null==r?void 0:r.countdownText)||"This message will close in {seconds} second{s}.",pausedText:(null==r?void 0:r.pausedText)||"Timer paused",stopText:(null==r?void 0:r.stopText)||"Click to stop.",createdAt:Date.now(),replace:!0,dedupeKey:"p-ok-".concat(n)})}).catch(function(){b&&b({id:n,message:e.error,type:"error",duration:5e3,showCountdown:!0,countdownText:(null==r?void 0:r.countdownText)||"This message will close in {seconds} second{s}.",pausedText:(null==r?void 0:r.pausedText)||"Timer paused",stopText:(null==r?void 0:r.stopText)||"Click to stop.",createdAt:Date.now(),replace:!0,dedupeKey:"p-err-".concat(n)})}),n},m.dismiss=function(t){b&&b({id:t,_dismiss:!0})};var k={toastBg:"rgba(30,30,32,.95)",toastBorder:"rgba(255,255,255,.08)",toastShadow:"0 16px 48px rgba(0,0,0,.5),0 2px 8px rgba(0,0,0,.3),inset 0 1px 0 rgba(255,255,255,.04)",title:"#f0f0f0",desc:"rgba(255,255,255,.5)",footerBg:"rgba(0,0,0,.15)",footerBorder:"rgba(255,255,255,.06)",footerText:"rgba(255,255,255,.35)",footerLink:"rgba(255,255,255,.6)",progressTrack:"rgba(255,255,255,.04)",closeBtnColor:"rgba(255,255,255,.3)",closeBtnHover:"rgba(255,255,255,.7)",closeBtnHoverBg:"rgba(255,255,255,.06)",actionBg:"rgba(255,255,255,.08)",actionBorder:"rgba(255,255,255,.15)",actionHoverBg:"rgba(255,255,255,.14)",actionHoverBorder:"rgba(255,255,255,.25)",actionText:"#f0f0f0",backdrop:"blur(16px) saturate(1.4)"},w={toastBg:"rgba(255,255,255,.97)",toastBorder:"rgba(0,0,0,.08)",toastShadow:"0 16px 48px rgba(0,0,0,.08),0 4px 12px rgba(0,0,0,.05),0 1px 3px rgba(0,0,0,.06)",title:"#1a1a1a",desc:"rgba(0,0,0,.5)",footerBg:"rgba(0,0,0,.025)",footerBorder:"rgba(0,0,0,.06)",footerText:"rgba(0,0,0,.35)",footerLink:"rgba(0,0,0,.6)",progressTrack:"rgba(0,0,0,.05)",closeBtnColor:"rgba(0,0,0,.25)",closeBtnHover:"rgba(0,0,0,.6)",closeBtnHoverBg:"rgba(0,0,0,.05)",actionBg:"rgba(0,0,0,.05)",actionBorder:"rgba(0,0,0,.12)",actionHoverBg:"rgba(0,0,0,.1)",actionHoverBorder:"rgba(0,0,0,.2)",actionText:"#1a1a1a",backdrop:"blur(16px) saturate(1.2)"},T={dark:k,light:w},B=function(t){return t?"string"==typeof t?T[t]||k:u(u({},k),t):k},C=function(){return o("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"none",children:[i("circle",{cx:"10",cy:"10",r:"9",stroke:"#f87171",strokeWidth:"1.5",opacity:".3"}),i("path",{d:"M10 6v5",stroke:"#f87171",strokeWidth:"1.5",strokeLinecap:"round"}),i("circle",{cx:"10",cy:"13.5",r:".75",fill:"#f87171"})]})},S=function(){return o("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"none",children:[i("path",{d:"M10 2.5L1.5 17h17L10 2.5z",stroke:"#fbbf24",strokeWidth:"1.3",strokeLinejoin:"round",opacity:".35"}),i("path",{d:"M10 8v4",stroke:"#fbbf24",strokeWidth:"1.5",strokeLinecap:"round"}),i("circle",{cx:"10",cy:"14.5",r:".75",fill:"#fbbf24"})]})},j=function(){return o("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"none",children:[i("circle",{cx:"10",cy:"10",r:"9",stroke:"#60a5fa",strokeWidth:"1.5",opacity:".3"}),i("path",{d:"M10 9v5",stroke:"#60a5fa",strokeWidth:"1.5",strokeLinecap:"round"}),i("circle",{cx:"10",cy:"6.5",r:".75",fill:"#60a5fa"})]})},O=function(){return o("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"none",style:{animation:"toastywave-spin .7s linear infinite"},children:[i("circle",{cx:"10",cy:"10",r:"8",stroke:"currentColor",strokeWidth:"1.8",opacity:".15"}),i("path",{d:"M10 2a8 8 0 018 8",stroke:"currentColor",strokeWidth:"1.8",strokeLinecap:"round",opacity:".5"})]})},M=function(){return i("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",children:i("path",{d:"M3.5 3.5l7 7M10.5 3.5l-7 7"})})},W={success:i(function(){return o("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"none",children:[i("circle",{cx:"10",cy:"10",r:"9",stroke:"#4ade80",strokeWidth:"1.5",opacity:".3"}),i("path",{d:"M6.5 10.5l2 2 5-5",stroke:"#4ade80",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})]})},{}),error:i(C,{}),warning:i(S,{}),info:i(j,{}),loading:i(O,{})},A={success:"#4ade80",error:"#f87171",warning:"#fbbf24",info:"#60a5fa",loading:"#a78bfa",default:"#888"};function L(r){var c=r.data,s=r.onDismiss,l=r.position,u=r.theme,f=d(t("enter"),2),p=f[0],g=f[1],b=d(t(!1),2),h=b[0],y=b[1],v=d(t(c.duration),2),x=v[0],m=v[1],k=n(null),w=n(Date.now()),T=l.startsWith("top"),B=c.duration!==1/0,C=B&&!1!==c.showCountdown,S=u;e(function(){if(B&&!h){w.current=Date.now();var t=w.current+x;return k.current=setInterval(function(){var e=t-Date.now();e<=0?(clearInterval(k.current),g("exit"),setTimeout(function(){return s(c.id,c.dedupeKey)},320)):m(e)},50),function(){return clearInterval(k.current)}}k.current&&clearInterval(k.current)},[h,B]),e(function(){c.duration!==1/0&&m(c.duration)},[c.type,c.duration,c.createdAt]),e(function(){var t=requestAnimationFrame(function(){return g("visible")});return function(){return cancelAnimationFrame(t)}},[]);var j,O,L=function(){g("exit"),setTimeout(function(){return s(c.id,c.dedupeKey)},320)},D=B?Math.max(0,x/c.duration):1,H=Math.ceil(x/1e3),I=T?-24:24,P={enter:"translateY(".concat(I,"px) scale(.95)"),visible:"translateY(0) scale(1)",exit:"translateY(".concat(I,"px) scale(.95)")};return o("div",{onMouseEnter:function(){return!h&&y(!0)},onMouseLeave:function(){return y(!1)},style:{width:420,maxWidth:"calc(100vw - 32px)",background:S.toastBg,backdropFilter:S.backdrop,WebkitBackdropFilter:S.backdrop,border:"1px solid ".concat(S.toastBorder),borderRadius:12,overflow:"hidden",transform:P[p],opacity:"visible"===p?1:0,transition:"all .32s cubic-bezier(.16,1,.3,1)",boxShadow:S.toastShadow},children:[o("div",{style:{padding:"14px 16px",display:"flex",alignItems:"flex-start",gap:12},children:[(c.icon||"default"!==c.type)&&i("div",{style:{flexShrink:0,marginTop:1,color:S.title},children:c.icon||W[c.type]}),o("div",{style:{flex:1,minWidth:0},children:[i("div",{style:{fontSize:14,fontWeight:600,color:S.title,lineHeight:1.4},children:c.message}),c.description&&i("div",{style:{fontSize:13,color:S.desc,marginTop:4,lineHeight:1.45},children:c.description}),c.action&&i("button",{onClick:function(t){t.stopPropagation(),c.action.onClick&&c.action.onClick(),L()},onMouseEnter:function(t){t.currentTarget.style.background=S.actionHoverBg,t.currentTarget.style.borderColor=S.actionHoverBorder},onMouseLeave:function(t){t.currentTarget.style.background=S.actionBg,t.currentTarget.style.borderColor=S.actionBorder},style:{marginTop:10,padding:"6px 14px",fontSize:13,fontWeight:600,fontFamily:"inherit",borderRadius:6,border:"1px solid ".concat(S.actionBorder),background:S.actionBg,color:S.actionText,cursor:"pointer",transition:"all .15s ease"},children:c.action.label})]}),i("button",{onClick:function(t){t.stopPropagation(),L()},onMouseEnter:function(t){t.currentTarget.style.color=S.closeBtnHover,t.currentTarget.style.background=S.closeBtnHoverBg},onMouseLeave:function(t){t.currentTarget.style.color=S.closeBtnColor,t.currentTarget.style.background="transparent"},style:{flexShrink:0,width:28,height:28,border:"none",background:"transparent",color:S.closeBtnColor,cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",borderRadius:6,transition:"all .15s ease",padding:0},children:i(M,{})})]}),C&&i("div",{style:{borderTop:"1px solid ".concat(S.footerBorder),padding:"8px 16px",background:S.footerBg,display:"flex",alignItems:"center"},children:i("div",{style:{fontSize:12,color:S.footerText},children:h?c.pausedText:o(a,{children:[(j=c.countdownText,O=H,j.replace(/\{seconds\}/g,String(O)).replace(/\{s\}/g,1!==O?"s":""))," ",i("span",{onClick:function(t){t.stopPropagation(),y(!0)},style:{color:S.footerLink,fontWeight:600,cursor:"pointer",textDecoration:"underline",textUnderlineOffset:2},children:c.stopText})]})})}),B&&!h&&i("div",{style:{height:2,background:S.progressTrack,position:"relative"},children:i("div",{style:{position:"absolute",left:0,top:0,height:"100%",width:"".concat(100*D,"%"),background:A[c.type]||A.default,transition:"width .1s linear",borderRadius:"0 1px 1px 0"}})})]})}function D(n){var a=n.position,c=void 0===a?"bottom-right":a,s=n.theme,l=void 0===s?"dark":s,p=n.container,g=d(t([]),2),h=g[0],v=g[1],x=B(l);e(function(){return b=function(t){t._dismiss?v(function(e){var r=e.find(function(e){return e.id===t.id});return r&&y(r.dedupeKey),e.filter(function(e){return e.id!==t.id})}):v(function(e){if(t.replace){var r=e.find(function(e){return e.id===t.id});return r&&y(r.dedupeKey),e.map(function(e){return e.id===t.id?u({},t):e})}return[].concat(f(e),[t])})},function(){b=null}},[]);var m=r(function(t,e){y(e),v(function(e){return e.filter(function(e){return e.id!==t})})},[]),k=d(c.split("-"),2),w=k[0],T=k[1],C="center"===T;return o("div",{style:u(u({position:p?"absolute":"fixed",zIndex:99999,display:"flex",flexDirection:"top"===w?"column":"column-reverse",alignItems:C?"center":"left"===T?"flex-start":"flex-end",gap:10,padding:p?12:20,pointerEvents:"none"},"top"===w?{top:0}:{bottom:0}),C?{left:0,right:0}:"left"===T?{left:0}:{right:0}),children:[i("style",{children:"@keyframes toastywave-spin{to{transform:rotate(360deg)}}"}),h.map(function(t){return i("div",{style:{pointerEvents:"auto"},children:i(L,{data:t,onDismiss:m,position:c,theme:x})},t.id)})]})}export{D as Toaster,k as darkTheme,m as default,w as lightTheme,x as registerActionPreset,B as resolveTheme,m as toast};
2
+ //# sourceMappingURL=index.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.esm.js","sources":["../src/index.jsx"],"sourcesContent":["import { useState, useEffect, useCallback, useRef, createContext, useContext } from \"react\";\n\n/* ═══════════════════════════════════════════════════════════════\n TOASTYWAVE - Lightweight React Toast Notification System\n ═══════════════════════════════════════════════════════════════ */\n\n// ── Internal State ──────────────────────────────────────────────\n\nlet _id = 0;\nlet _addToast = null;\nlet _active = new Map();\n\nconst _unreg = (k) => _active.delete(k);\n\n// ── Public API ──────────────────────────────────────────────────\n\n// ── Action Presets ───────────────────────────────────────────────\n\nconst actionPresets = {\n undo: (onUndo) => ({\n label: \"Undo\",\n onClick: onUndo,\n }),\n};\n\n/**\n * Register a custom action preset.\n * @param {string} name - Preset name\n * @param {Function} factory - Factory function (onAction) => { label, onClick }\n */\nconst registerActionPreset = (name, factory) => {\n actionPresets[name] = factory;\n};\n\n/**\n * Resolve action from preset string or custom object.\n * @param {string|Object} action - \"undo\", { preset: \"undo\", onAction }, or { label, onClick }\n * @returns {Object|null} Resolved action object\n */\nconst resolveAction = (action) => {\n if (!action) return null;\n if (typeof action === \"string\") {\n // Preset name only (e.g., \"undo\") - return preset with no-op\n const factory = actionPresets[action];\n return factory ? factory(() => {}) : null;\n }\n if (action.preset) {\n // Preset with callback (e.g., { preset: \"undo\", onAction: () => {...} })\n const factory = actionPresets[action.preset];\n return factory ? factory(action.onAction || (() => {})) : null;\n }\n // Custom action object { label, onClick }\n return action;\n};\n\n/**\n * Show a toast notification.\n *\n * @param {string} message - The toast title/message\n * @param {Object} [opts] - Options\n * @param {string} [opts.type=\"default\"] - Toast type: \"default\"|\"success\"|\"error\"|\"warning\"|\"info\"|\"loading\"\n * @param {string} [opts.description] - Secondary text below the message\n * @param {number} [opts.duration=5000] - Auto-dismiss duration in ms. Use Infinity to persist.\n * @param {string|Object} [opts.action] - Action button: preset name (\"undo\"), preset config ({ preset: \"undo\", onAction }), or custom ({ label, onClick })\n * @param {React.ReactNode} [opts.icon] - Custom icon element. Overrides the default type icon.\n * @param {string} [opts.dedupeKey] - Custom dedup key. Defaults to `${type}::${message}`\n * @param {string} [opts.countdownText] - Custom countdown text. Use `{seconds}` as placeholder.\n * @param {string} [opts.pausedText] - Custom text shown when timer is paused.\n * @param {string} [opts.stopText] - Custom \"Click to stop\" text.\n * @param {boolean} [opts.showCountdown=true] - Whether to show the countdown footer.\n * @returns {number} Toast ID\n */\nconst toast = (message, opts = {}) => {\n const dk = opts.dedupeKey || `${opts.type || \"default\"}::${message}`;\n if (_active.has(dk)) return _active.get(dk);\n const id = ++_id;\n const resolvedAction = resolveAction(opts.action);\n const t = {\n id,\n message,\n type: \"default\",\n duration: 5000,\n showCountdown: true,\n countdownText: \"This message will close in {seconds} second{s}.\",\n pausedText: \"Timer paused\",\n stopText: \"Click to stop.\",\n ...opts,\n action: resolvedAction,\n dedupeKey: dk,\n createdAt: Date.now(),\n };\n _active.set(dk, id);\n if (_addToast) _addToast(t);\n return id;\n};\n\ntoast.success = (m, o) => toast(m, { ...o, type: \"success\" });\ntoast.error = (m, o) => toast(m, { ...o, type: \"error\" });\ntoast.warning = (m, o) => toast(m, { ...o, type: \"warning\" });\ntoast.info = (m, o) => toast(m, { ...o, type: \"info\" });\ntoast.loading = (m, o) => toast(m, { ...o, type: \"loading\", duration: Infinity });\n\n/**\n * Show a promise-based toast that transitions from loading → success/error.\n *\n * @param {Promise} promise\n * @param {Object} msgs - { loading, success, error }\n * @param {Object} [opts] - Same options as toast()\n * @returns {number} Toast ID\n */\ntoast.promise = (promise, msgs, o) => {\n const id = toast(msgs.loading, { ...o, type: \"loading\", duration: Infinity });\n promise\n .then(() => {\n if (_addToast)\n _addToast({\n id, message: msgs.success, type: \"success\", duration: 5000,\n showCountdown: true,\n countdownText: o?.countdownText || \"This message will close in {seconds} second{s}.\",\n pausedText: o?.pausedText || \"Timer paused\",\n stopText: o?.stopText || \"Click to stop.\",\n createdAt: Date.now(), replace: true, dedupeKey: `p-ok-${id}`,\n });\n })\n .catch(() => {\n if (_addToast)\n _addToast({\n id, message: msgs.error, type: \"error\", duration: 5000,\n showCountdown: true,\n countdownText: o?.countdownText || \"This message will close in {seconds} second{s}.\",\n pausedText: o?.pausedText || \"Timer paused\",\n stopText: o?.stopText || \"Click to stop.\",\n createdAt: Date.now(), replace: true, dedupeKey: `p-err-${id}`,\n });\n });\n return id;\n};\n\n/**\n * Programmatically dismiss a toast by ID.\n * @param {number} id\n */\ntoast.dismiss = (id) => {\n if (_addToast) _addToast({ id, _dismiss: true });\n};\n\n// ── Default Themes ──────────────────────────────────────────────\n\nconst darkTheme = {\n toastBg: \"rgba(30,30,32,.95)\",\n toastBorder: \"rgba(255,255,255,.08)\",\n toastShadow: \"0 16px 48px rgba(0,0,0,.5),0 2px 8px rgba(0,0,0,.3),inset 0 1px 0 rgba(255,255,255,.04)\",\n title: \"#f0f0f0\",\n desc: \"rgba(255,255,255,.5)\",\n footerBg: \"rgba(0,0,0,.15)\",\n footerBorder: \"rgba(255,255,255,.06)\",\n footerText: \"rgba(255,255,255,.35)\",\n footerLink: \"rgba(255,255,255,.6)\",\n progressTrack: \"rgba(255,255,255,.04)\",\n closeBtnColor: \"rgba(255,255,255,.3)\",\n closeBtnHover: \"rgba(255,255,255,.7)\",\n closeBtnHoverBg: \"rgba(255,255,255,.06)\",\n actionBg: \"rgba(255,255,255,.08)\",\n actionBorder: \"rgba(255,255,255,.15)\",\n actionHoverBg: \"rgba(255,255,255,.14)\",\n actionHoverBorder: \"rgba(255,255,255,.25)\",\n actionText: \"#f0f0f0\",\n backdrop: \"blur(16px) saturate(1.4)\",\n};\n\nconst lightTheme = {\n toastBg: \"rgba(255,255,255,.97)\",\n toastBorder: \"rgba(0,0,0,.08)\",\n toastShadow: \"0 16px 48px rgba(0,0,0,.08),0 4px 12px rgba(0,0,0,.05),0 1px 3px rgba(0,0,0,.06)\",\n title: \"#1a1a1a\",\n desc: \"rgba(0,0,0,.5)\",\n footerBg: \"rgba(0,0,0,.025)\",\n footerBorder: \"rgba(0,0,0,.06)\",\n footerText: \"rgba(0,0,0,.35)\",\n footerLink: \"rgba(0,0,0,.6)\",\n progressTrack: \"rgba(0,0,0,.05)\",\n closeBtnColor: \"rgba(0,0,0,.25)\",\n closeBtnHover: \"rgba(0,0,0,.6)\",\n closeBtnHoverBg: \"rgba(0,0,0,.05)\",\n actionBg: \"rgba(0,0,0,.05)\",\n actionBorder: \"rgba(0,0,0,.12)\",\n actionHoverBg: \"rgba(0,0,0,.1)\",\n actionHoverBorder: \"rgba(0,0,0,.2)\",\n actionText: \"#1a1a1a\",\n backdrop: \"blur(16px) saturate(1.2)\",\n};\n\nconst builtInThemes = { dark: darkTheme, light: lightTheme };\n\n/**\n * Resolve a theme by name or merge a custom theme object on top of the dark base.\n * @param {\"dark\"|\"light\"|Object} themeOrName\n * @returns {Object} Resolved theme tokens\n */\nconst resolveTheme = (themeOrName) => {\n if (!themeOrName) return darkTheme;\n if (typeof themeOrName === \"string\") return builtInThemes[themeOrName] || darkTheme;\n return { ...darkTheme, ...themeOrName };\n};\n\n// ── SVG Icons ───────────────────────────────────────────────────\n\nconst CheckIcon = () => (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\n <circle cx=\"10\" cy=\"10\" r=\"9\" stroke=\"#4ade80\" strokeWidth=\"1.5\" opacity=\".3\" />\n <path d=\"M6.5 10.5l2 2 5-5\" stroke=\"#4ade80\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n);\nconst ErrorIcon = () => (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\n <circle cx=\"10\" cy=\"10\" r=\"9\" stroke=\"#f87171\" strokeWidth=\"1.5\" opacity=\".3\" />\n <path d=\"M10 6v5\" stroke=\"#f87171\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n <circle cx=\"10\" cy=\"13.5\" r=\".75\" fill=\"#f87171\" />\n </svg>\n);\nconst WarningIcon = () => (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\n <path d=\"M10 2.5L1.5 17h17L10 2.5z\" stroke=\"#fbbf24\" strokeWidth=\"1.3\" strokeLinejoin=\"round\" opacity=\".35\" />\n <path d=\"M10 8v4\" stroke=\"#fbbf24\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n <circle cx=\"10\" cy=\"14.5\" r=\".75\" fill=\"#fbbf24\" />\n </svg>\n);\nconst InfoIcon = () => (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\n <circle cx=\"10\" cy=\"10\" r=\"9\" stroke=\"#60a5fa\" strokeWidth=\"1.5\" opacity=\".3\" />\n <path d=\"M10 9v5\" stroke=\"#60a5fa\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n <circle cx=\"10\" cy=\"6.5\" r=\".75\" fill=\"#60a5fa\" />\n </svg>\n);\nconst LoadingIcon = () => (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" style={{ animation: \"toastywave-spin .7s linear infinite\" }}>\n <circle cx=\"10\" cy=\"10\" r=\"8\" stroke=\"currentColor\" strokeWidth=\"1.8\" opacity=\".15\" />\n <path d=\"M10 2a8 8 0 018 8\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" opacity=\".5\" />\n </svg>\n);\nconst CloseIcon = () => (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\">\n <path d=\"M3.5 3.5l7 7M10.5 3.5l-7 7\" />\n </svg>\n);\n\nconst iconMap = {\n success: <CheckIcon />,\n error: <ErrorIcon />,\n warning: <WarningIcon />,\n info: <InfoIcon />,\n loading: <LoadingIcon />,\n};\n\nconst accentMap = {\n success: \"#4ade80\",\n error: \"#f87171\",\n warning: \"#fbbf24\",\n info: \"#60a5fa\",\n loading: \"#a78bfa\",\n default: \"#888\",\n};\n\n// ── Countdown Text Formatter ────────────────────────────────────\n\nconst formatCountdown = (template, seconds) => {\n return template\n .replace(/\\{seconds\\}/g, String(seconds))\n .replace(/\\{s\\}/g, seconds !== 1 ? \"s\" : \"\");\n};\n\n// ── Toast Item ──────────────────────────────────────────────────\n\nfunction ToastItem({ data, onDismiss, position, theme }) {\n const [phase, setPhase] = useState(\"enter\");\n const [paused, setPaused] = useState(false);\n const [remain, setRemain] = useState(data.duration);\n const ivRef = useRef(null);\n const startRef = useRef(Date.now());\n const isTop = position.startsWith(\"top\");\n const hasDur = data.duration !== Infinity;\n const showFooter = hasDur && data.showCountdown !== false;\n const th = theme;\n\n useEffect(() => {\n if (!hasDur || paused) {\n if (ivRef.current) clearInterval(ivRef.current);\n return;\n }\n startRef.current = Date.now();\n const end = startRef.current + remain;\n ivRef.current = setInterval(() => {\n const left = end - Date.now();\n if (left <= 0) {\n clearInterval(ivRef.current);\n setPhase(\"exit\");\n setTimeout(() => onDismiss(data.id, data.dedupeKey), 320);\n } else {\n setRemain(left);\n }\n }, 50);\n return () => clearInterval(ivRef.current);\n }, [paused, hasDur]);\n\n useEffect(() => {\n if (data.duration !== Infinity) setRemain(data.duration);\n }, [data.type, data.duration, data.createdAt]);\n\n useEffect(() => {\n const r = requestAnimationFrame(() => setPhase(\"visible\"));\n return () => cancelAnimationFrame(r);\n }, []);\n\n const dismiss = () => {\n setPhase(\"exit\");\n setTimeout(() => onDismiss(data.id, data.dedupeKey), 320);\n };\n\n const stopTimer = (e) => {\n e.stopPropagation();\n setPaused(true);\n };\n\n const progress = hasDur ? Math.max(0, remain / data.duration) : 1;\n const secs = Math.ceil(remain / 1000);\n const enterY = isTop ? -24 : 24;\n const tf = {\n enter: `translateY(${enterY}px) scale(.95)`,\n visible: \"translateY(0) scale(1)\",\n exit: `translateY(${enterY}px) scale(.95)`,\n };\n\n return (\n <div\n onMouseEnter={() => !paused && setPaused(true)}\n onMouseLeave={() => setPaused(false)}\n style={{\n width: 420,\n maxWidth: \"calc(100vw - 32px)\",\n background: th.toastBg,\n backdropFilter: th.backdrop,\n WebkitBackdropFilter: th.backdrop,\n border: `1px solid ${th.toastBorder}`,\n borderRadius: 12,\n overflow: \"hidden\",\n transform: tf[phase],\n opacity: phase === \"visible\" ? 1 : 0,\n transition: \"all .32s cubic-bezier(.16,1,.3,1)\",\n boxShadow: th.toastShadow,\n }}\n >\n {/* Content */}\n <div style={{ padding: \"14px 16px\", display: \"flex\", alignItems: \"flex-start\", gap: 12 }}>\n {(data.icon || data.type !== \"default\") && (\n <div style={{ flexShrink: 0, marginTop: 1, color: th.title }}>\n {data.icon || iconMap[data.type]}\n </div>\n )}\n <div style={{ flex: 1, minWidth: 0 }}>\n <div style={{ fontSize: 14, fontWeight: 600, color: th.title, lineHeight: 1.4 }}>\n {data.message}\n </div>\n {data.description && (\n <div style={{ fontSize: 13, color: th.desc, marginTop: 4, lineHeight: 1.45 }}>\n {data.description}\n </div>\n )}\n {data.action && (\n <button\n onClick={(e) => {\n e.stopPropagation();\n if (data.action.onClick) data.action.onClick();\n dismiss();\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.background = th.actionHoverBg;\n e.currentTarget.style.borderColor = th.actionHoverBorder;\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.background = th.actionBg;\n e.currentTarget.style.borderColor = th.actionBorder;\n }}\n style={{\n marginTop: 10,\n padding: \"6px 14px\",\n fontSize: 13,\n fontWeight: 600,\n fontFamily: \"inherit\",\n borderRadius: 6,\n border: `1px solid ${th.actionBorder}`,\n background: th.actionBg,\n color: th.actionText,\n cursor: \"pointer\",\n transition: \"all .15s ease\",\n }}\n >\n {data.action.label}\n </button>\n )}\n </div>\n <button\n onClick={(e) => {\n e.stopPropagation();\n dismiss();\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.color = th.closeBtnHover;\n e.currentTarget.style.background = th.closeBtnHoverBg;\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.color = th.closeBtnColor;\n e.currentTarget.style.background = \"transparent\";\n }}\n style={{\n flexShrink: 0,\n width: 28,\n height: 28,\n border: \"none\",\n background: \"transparent\",\n color: th.closeBtnColor,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n borderRadius: 6,\n transition: \"all .15s ease\",\n padding: 0,\n }}\n >\n <CloseIcon />\n </button>\n </div>\n\n {/* Countdown footer */}\n {showFooter && (\n <div\n style={{\n borderTop: `1px solid ${th.footerBorder}`,\n padding: \"8px 16px\",\n background: th.footerBg,\n display: \"flex\",\n alignItems: \"center\",\n }}\n >\n <div style={{ fontSize: 12, color: th.footerText }}>\n {paused ? (\n data.pausedText\n ) : (\n <>\n {formatCountdown(data.countdownText, secs)}{\" \"}\n <span\n onClick={stopTimer}\n style={{\n color: th.footerLink,\n fontWeight: 600,\n cursor: \"pointer\",\n textDecoration: \"underline\",\n textUnderlineOffset: 2,\n }}\n >\n {data.stopText}\n </span>\n </>\n )}\n </div>\n </div>\n )}\n\n {/* Progress bar */}\n {hasDur && !paused && (\n <div style={{ height: 2, background: th.progressTrack, position: \"relative\" }}>\n <div\n style={{\n position: \"absolute\",\n left: 0,\n top: 0,\n height: \"100%\",\n width: `${progress * 100}%`,\n background: accentMap[data.type] || accentMap.default,\n transition: \"width .1s linear\",\n borderRadius: \"0 1px 1px 0\",\n }}\n />\n </div>\n )}\n </div>\n );\n}\n\n// ── Toaster Component ───────────────────────────────────────────\n\n/**\n * Toaster container component. Place once in your app.\n *\n * @param {Object} props\n * @param {\"top-left\"|\"top-center\"|\"top-right\"|\"bottom-left\"|\"bottom-center\"|\"bottom-right\"} [props.position=\"bottom-right\"]\n * @param {\"dark\"|\"light\"|Object} [props.theme=\"dark\"] - Built-in theme name or custom theme object\n * @param {React.RefObject} [props.container] - Optional ref to scope toasts inside a container (uses absolute positioning)\n */\nfunction Toaster({ position = \"bottom-right\", theme = \"dark\", container }) {\n const [toasts, setToasts] = useState([]);\n const resolvedThemeObj = resolveTheme(theme);\n\n useEffect(() => {\n _addToast = (t) => {\n if (t._dismiss) {\n setToasts((p) => {\n const f = p.find((x) => x.id === t.id);\n if (f) _unreg(f.dedupeKey);\n return p.filter((x) => x.id !== t.id);\n });\n return;\n }\n setToasts((p) => {\n if (t.replace) {\n const o = p.find((x) => x.id === t.id);\n if (o) _unreg(o.dedupeKey);\n return p.map((x) => (x.id === t.id ? { ...t } : x));\n }\n return [...p, t];\n });\n };\n return () => {\n _addToast = null;\n };\n }, []);\n\n const dismiss = useCallback((id, dk) => {\n _unreg(dk);\n setToasts((p) => p.filter((x) => x.id !== id));\n }, []);\n\n const [vPos, hPos] = position.split(\"-\");\n const isCenter = hPos === \"center\";\n\n return (\n <div\n style={{\n position: container ? \"absolute\" : \"fixed\",\n zIndex: 99999,\n display: \"flex\",\n flexDirection: vPos === \"top\" ? \"column\" : \"column-reverse\",\n alignItems: isCenter ? \"center\" : hPos === \"left\" ? \"flex-start\" : \"flex-end\",\n gap: 10,\n padding: container ? 12 : 20,\n pointerEvents: \"none\",\n ...(vPos === \"top\" ? { top: 0 } : { bottom: 0 }),\n ...(isCenter ? { left: 0, right: 0 } : hPos === \"left\" ? { left: 0 } : { right: 0 }),\n }}\n >\n <style>{`@keyframes toastywave-spin{to{transform:rotate(360deg)}}`}</style>\n {toasts.map((t) => (\n <div key={t.id} style={{ pointerEvents: \"auto\" }}>\n <ToastItem data={t} onDismiss={dismiss} position={position} theme={resolvedThemeObj} />\n </div>\n ))}\n </div>\n );\n}\n\n// ── Exports ─────────────────────────────────────────────────────\n\nexport { toast, Toaster, darkTheme, lightTheme, resolveTheme, registerActionPreset };\nexport default toast;\n"],"names":["_id","_addToast","_active","Map","_unreg","k","actionPresets","undo","onUndo","label","onClick","registerActionPreset","name","factory","toast","message","opts","arguments","length","undefined","dk","dedupeKey","concat","type","has","get","id","resolvedAction","action","preset","onAction","resolveAction","t","_objectSpread","duration","showCountdown","countdownText","pausedText","stopText","createdAt","Date","now","set","success","m","o","error","warning","info","loading","Infinity","promise","msgs","then","replace","dismiss","_dismiss","darkTheme","toastBg","toastBorder","toastShadow","title","desc","footerBg","footerBorder","footerText","footerLink","progressTrack","closeBtnColor","closeBtnHover","closeBtnHoverBg","actionBg","actionBorder","actionHoverBg","actionHoverBorder","actionText","backdrop","lightTheme","builtInThemes","dark","light","resolveTheme","themeOrName","ErrorIcon","_jsxs","width","height","viewBox","fill","children","_jsx","cx","cy","r","stroke","strokeWidth","opacity","d","strokeLinecap","WarningIcon","strokeLinejoin","InfoIcon","LoadingIcon","style","animation","CloseIcon","iconMap","accentMap","default","ToastItem","_ref","data","onDismiss","position","theme","_useState2","_slicedToArray","useState","phase","setPhase","_useState4","paused","setPaused","_useState6","remain","setRemain","ivRef","useRef","startRef","isTop","startsWith","hasDur","showFooter","th","useEffect","current","end","setInterval","left","clearInterval","setTimeout","requestAnimationFrame","cancelAnimationFrame","template","seconds","progress","Math","max","secs","ceil","enterY","tf","enter","visible","exit","onMouseEnter","onMouseLeave","maxWidth","background","backdropFilter","WebkitBackdropFilter","border","borderRadius","overflow","transform","transition","boxShadow","padding","display","alignItems","gap","icon","flexShrink","marginTop","color","flex","minWidth","fontSize","fontWeight","lineHeight","description","e","stopPropagation","currentTarget","borderColor","fontFamily","cursor","justifyContent","borderTop","_Fragment","String","textDecoration","textUnderlineOffset","top","Toaster","_ref2","_ref2$position","_ref2$theme","container","_useState8","toasts","setToasts","resolvedThemeObj","p","f","find","x","filter","map","_toConsumableArray","useCallback","_position$split2","split","vPos","hPos","isCenter","zIndex","flexDirection","pointerEvents","bottom","right"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "toastywave",
3
+ "version": "0.1.0",
4
+ "description": "Lightweight React toast notifications with deduplication, countdown timers, theming, and container scoping.",
5
+ "main": "dist/index.cjs.js",
6
+ "module": "dist/index.esm.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.esm.js",
11
+ "require": "./dist/index.cjs.js",
12
+ "types": "./dist/index.d.ts"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md",
18
+ "LICENSE"
19
+ ],
20
+ "scripts": {
21
+ "build": "rollup -c && cp src/index.d.ts dist/",
22
+ "dev": "bun run build && bun run playground",
23
+ "watch": "rollup -c -w",
24
+ "playground": "cd playground && bun run dev",
25
+ "playground:install": "cd playground && bun install",
26
+ "prepublishOnly": "bun run build"
27
+ },
28
+ "peerDependencies": {
29
+ "react": ">=17.0.0",
30
+ "react-dom": ">=17.0.0"
31
+ },
32
+ "devDependencies": {
33
+ "@rollup/plugin-babel": "^6.0.4",
34
+ "@rollup/plugin-node-resolve": "^15.2.3",
35
+ "@rollup/plugin-terser": "^0.4.4",
36
+ "rollup": "^4.9.0",
37
+ "rollup-plugin-peer-deps-external": "^2.2.4",
38
+ "@babel/core": "^7.24.0",
39
+ "@babel/preset-env": "^7.24.0",
40
+ "@babel/preset-react": "^7.23.3"
41
+ },
42
+ "keywords": [
43
+ "react",
44
+ "toast",
45
+ "notification",
46
+ "toastywave",
47
+ "snackbar",
48
+ "alert",
49
+ "lightweight",
50
+ "dedup",
51
+ "theming"
52
+ ],
53
+ "repository": {
54
+ "type": "git",
55
+ "url": "https://github.com/papiguy/toastywave"
56
+ },
57
+ "license": "MIT",
58
+ "author": "",
59
+ "sideEffects": false
60
+ }