dotnotify 1.0.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 +21 -0
- package/README.md +453 -0
- package/dist/dotnotify.d.ts +149 -0
- package/dist/dotnotify.esm.js +796 -0
- package/dist/dotnotify.js +793 -0
- package/dist/dotnotify.min.js +6 -0
- package/package.json +43 -0
- package/src/dotnotify.js +793 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Your Name
|
|
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,453 @@
|
|
|
1
|
+
# π DotNotify
|
|
2
|
+
|
|
3
|
+
> **iOS-glass particle notifications** β dots fly in from random positions, merge into a frosted-glass card, and explode back into dots on dismiss.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/dotnotify)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
[]()
|
|
8
|
+
[]()
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## β¨ Features
|
|
13
|
+
|
|
14
|
+
| Feature | Details |
|
|
15
|
+
|---|---|
|
|
16
|
+
| π **Particle entry** | 65 dots fly in from random positions with comet trails and glow halos |
|
|
17
|
+
| π₯ **Particle exit** | 52 dots explode outward on dismiss |
|
|
18
|
+
| π§ **iOS glass card** | `backdrop-filter: blur(40px) saturate(220%)` β real frosted glass |
|
|
19
|
+
| βΈοΈ **Hover pause** | Timer freezes on card hover, dots pulse up |
|
|
20
|
+
| πΌοΈ **Developer images** | Pass a URL, File object, or `<img>` element as the notification icon |
|
|
21
|
+
| π΅ **Web Audio sound** | Zero-file sound via Web Audio API |
|
|
22
|
+
| π¦ **Stack & queue** | Up to 4 stacked, extras queue automatically |
|
|
23
|
+
| π **Swipe dismiss** | Drag left/right to fling away |
|
|
24
|
+
| π **Action buttons** | Retry, Dismiss β any labels you want |
|
|
25
|
+
| π **Ring progress** | Circular countdown ring around the icon as alternative to dots |
|
|
26
|
+
| π¨ **4 themes** | `ios-glass` Β· `dark` Β· `light` Β· `minimal` |
|
|
27
|
+
| π· **TypeScript** | Full `.d.ts` included |
|
|
28
|
+
| β‘ **Promise API** | `await notify.fire(...)` β knows how it was dismissed |
|
|
29
|
+
| 0οΈβ£ **Zero deps** | Pure vanilla JS, no external libraries |
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## π¦ Installation
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm install dotnotify
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Or via CDN (no build step):
|
|
40
|
+
|
|
41
|
+
```html
|
|
42
|
+
<script src="https://cdn.jsdelivr.net/npm/dotnotify/dist/dotnotify.min.js"></script>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## π Quick Start
|
|
48
|
+
|
|
49
|
+
```js
|
|
50
|
+
import DotNotify from 'dotnotify';
|
|
51
|
+
|
|
52
|
+
const notify = DotNotify({ position: 'top-right' });
|
|
53
|
+
|
|
54
|
+
notify.fire({
|
|
55
|
+
type: 'success',
|
|
56
|
+
title: 'Logged in!',
|
|
57
|
+
message: 'Welcome back, Rahul.',
|
|
58
|
+
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
That's it. Dots fly in, card appears, dots explode when it disappears.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## π Configuration
|
|
66
|
+
|
|
67
|
+
### `DotNotify(config)` β Global Config
|
|
68
|
+
|
|
69
|
+
```js
|
|
70
|
+
const notify = DotNotify({
|
|
71
|
+
position: 'top-right', // 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left'
|
|
72
|
+
theme: 'ios-glass', // 'ios-glass' | 'dark' | 'light' | 'minimal'
|
|
73
|
+
sound: false, // Web Audio ping on appear
|
|
74
|
+
maxStack: 4, // Max simultaneous notifications
|
|
75
|
+
duration: 4200, // Auto-dismiss after N milliseconds
|
|
76
|
+
zIndex: 99999, // CSS z-index
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## π₯ `notify.fire(options)` β Full API
|
|
83
|
+
|
|
84
|
+
```js
|
|
85
|
+
const result = await notify.fire({
|
|
86
|
+
// ββ Required ββββββββββββββββββββββββββββββ
|
|
87
|
+
type: 'error', // 'error' | 'success' | 'warning' | 'info'
|
|
88
|
+
title: 'Login Failed',
|
|
89
|
+
message: 'Invalid credentials. Please try again.',
|
|
90
|
+
|
|
91
|
+
// ββ Icon / Image ββββββββββββββββββββββββββ
|
|
92
|
+
image: 'https://example.com/avatar.png', // URL β developer picture
|
|
93
|
+
// image: fileInput.files[0], // File β from <input type="file">
|
|
94
|
+
// image: document.querySelector('#myImg'), // HTMLImageElement
|
|
95
|
+
// icon: 'π₯', // Emoji (when no image)
|
|
96
|
+
// icon: '<svg>...</svg>', // SVG string
|
|
97
|
+
|
|
98
|
+
thumbnail: 'https://example.com/preview.jpg', // Small image beside message
|
|
99
|
+
|
|
100
|
+
// ββ Override per-notification βββββββββββββ
|
|
101
|
+
theme: 'ios-glass', // Override global theme
|
|
102
|
+
duration: 6000, // Override global duration (ms)
|
|
103
|
+
app: 'My App', // Override app label above title
|
|
104
|
+
sound: true, // Override global sound setting
|
|
105
|
+
progressStyle: 'dots', // 'dots' | 'ring'
|
|
106
|
+
|
|
107
|
+
// ββ Action Buttons ββββββββββββββββββββββββ
|
|
108
|
+
actions: [
|
|
109
|
+
{ label: 'Retry', primary: true, onClick: () => retryLogin() },
|
|
110
|
+
{ label: 'Dismiss', primary: false, onClick: () => {} },
|
|
111
|
+
],
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// result = { dismissed: 'action' | 'timeout' | 'swipe-left' | 'swipe-right' | 'close', action?: 'Retry' | 'Dismiss' }
|
|
115
|
+
console.log(result.dismissed); // 'action'
|
|
116
|
+
console.log(result.action); // 'Retry'
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## πΌοΈ Developer Images β Full Guide
|
|
122
|
+
|
|
123
|
+
DotNotify lets developers put **any image** β user avatar, app logo, product thumbnail β into the notification icon area. Three ways to do it:
|
|
124
|
+
|
|
125
|
+
### 1. URL string (most common)
|
|
126
|
+
|
|
127
|
+
```js
|
|
128
|
+
notify.fire({
|
|
129
|
+
type: 'info',
|
|
130
|
+
title: 'New message from Priya',
|
|
131
|
+
message: 'Hey, can we jump on a call?',
|
|
132
|
+
image: 'https://i.pravatar.cc/150?img=47', // any image URL
|
|
133
|
+
});
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### 2. File object β from `<input type="file">`
|
|
137
|
+
|
|
138
|
+
```html
|
|
139
|
+
<input type="file" id="avatar" accept="image/*">
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
```js
|
|
143
|
+
document.getElementById('avatar').addEventListener('change', (e) => {
|
|
144
|
+
const file = e.target.files[0];
|
|
145
|
+
|
|
146
|
+
notify.fire({
|
|
147
|
+
type: 'success',
|
|
148
|
+
title: 'Profile picture updated',
|
|
149
|
+
message: 'Your new avatar looks great!',
|
|
150
|
+
image: file, // β File object directly, no FileReader needed
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### 3. Drag and drop
|
|
156
|
+
|
|
157
|
+
```js
|
|
158
|
+
document.addEventListener('drop', (e) => {
|
|
159
|
+
e.preventDefault();
|
|
160
|
+
const file = e.dataTransfer.files[0];
|
|
161
|
+
if (!file?.type.startsWith('image/')) return;
|
|
162
|
+
|
|
163
|
+
notify.fire({
|
|
164
|
+
type: 'info',
|
|
165
|
+
title: 'File received',
|
|
166
|
+
message: file.name,
|
|
167
|
+
image: file,
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### 4. Existing `<img>` element
|
|
173
|
+
|
|
174
|
+
```js
|
|
175
|
+
const img = document.querySelector('#user-avatar');
|
|
176
|
+
|
|
177
|
+
notify.fire({
|
|
178
|
+
type: 'success',
|
|
179
|
+
title: 'Logged in',
|
|
180
|
+
message: 'Welcome back!',
|
|
181
|
+
image: img, // β pass the element directly
|
|
182
|
+
});
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### 5. Thumbnail (secondary image beside message)
|
|
186
|
+
|
|
187
|
+
```js
|
|
188
|
+
notify.fire({
|
|
189
|
+
type: 'info',
|
|
190
|
+
title: 'New photo shared',
|
|
191
|
+
message: 'Suresh shared a photo with you.',
|
|
192
|
+
image: 'https://example.com/suresh-avatar.jpg', // icon area
|
|
193
|
+
thumbnail: 'https://example.com/photo-preview.jpg', // beside message
|
|
194
|
+
});
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## π¨ Themes
|
|
200
|
+
|
|
201
|
+
```js
|
|
202
|
+
// Per-notification theme override:
|
|
203
|
+
notify.fire({ type: 'error', title: 'Oops', message: '...', theme: 'light' });
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
| Theme | Look |
|
|
207
|
+
|---|---|
|
|
208
|
+
| `ios-glass` | Deep dark frosted glass β blur 40px, barely-visible tint |
|
|
209
|
+
| `dark` | Opaque near-black, strong shadow |
|
|
210
|
+
| `light` | White frosted glass, for light-background sites |
|
|
211
|
+
| `minimal` | Ultra-thin dark card, no sheen |
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## π Ring vs Dots Progress
|
|
216
|
+
|
|
217
|
+
```js
|
|
218
|
+
// Circular ring around the icon
|
|
219
|
+
notify.fire({
|
|
220
|
+
type: 'warning',
|
|
221
|
+
title: 'Session expiring',
|
|
222
|
+
message: 'You will be logged out in 60 seconds.',
|
|
223
|
+
progressStyle: 'ring', // β ring traces around the icon
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
// Default dot progress bar (14 dots at bottom)
|
|
227
|
+
notify.fire({
|
|
228
|
+
type: 'info',
|
|
229
|
+
title: 'Syncing...',
|
|
230
|
+
message: 'Your data is being uploaded.',
|
|
231
|
+
progressStyle: 'dots', // default
|
|
232
|
+
});
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## βΈοΈ Hover Behaviour
|
|
238
|
+
|
|
239
|
+
When a user hovers the card:
|
|
240
|
+
- The **timer freezes** (remembers exact progress, resumes on mouse-leave)
|
|
241
|
+
- All **pending dots pulse up** and glow in the accent color
|
|
242
|
+
- Done dots revive slightly
|
|
243
|
+
- Individual dot hover **expands that dot to 12px** with full glow bloom
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## π Swipe to Dismiss
|
|
248
|
+
|
|
249
|
+
Works on both desktop (click-drag) and mobile (touch). Drag left or right past 80px threshold β the card flings away and dots explode.
|
|
250
|
+
|
|
251
|
+
```js
|
|
252
|
+
const result = await notify.fire({ ... });
|
|
253
|
+
if (result.dismissed === 'swipe-left') {
|
|
254
|
+
console.log('User swiped it away');
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## π Framework Examples
|
|
261
|
+
|
|
262
|
+
### React
|
|
263
|
+
|
|
264
|
+
```jsx
|
|
265
|
+
import DotNotify from 'dotnotify';
|
|
266
|
+
import { useRef, useCallback } from 'react';
|
|
267
|
+
|
|
268
|
+
export function useNotify() {
|
|
269
|
+
const notifyRef = useRef(null);
|
|
270
|
+
|
|
271
|
+
function getNotify() {
|
|
272
|
+
if (!notifyRef.current) {
|
|
273
|
+
notifyRef.current = DotNotify({ position: 'top-right', theme: 'ios-glass' });
|
|
274
|
+
}
|
|
275
|
+
return notifyRef.current;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
const fire = useCallback((opts) => getNotify().fire(opts), []);
|
|
279
|
+
return { fire };
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// In any component:
|
|
283
|
+
function LoginForm() {
|
|
284
|
+
const { fire } = useNotify();
|
|
285
|
+
|
|
286
|
+
async function handleSubmit() {
|
|
287
|
+
try {
|
|
288
|
+
await loginAPI();
|
|
289
|
+
fire({ type: 'success', title: 'Welcome!', message: 'Logged in successfully.' });
|
|
290
|
+
} catch (err) {
|
|
291
|
+
const result = await fire({
|
|
292
|
+
type: 'error',
|
|
293
|
+
title: 'Login Failed',
|
|
294
|
+
message: err.message,
|
|
295
|
+
actions: [{ label: 'Retry', primary: true }],
|
|
296
|
+
});
|
|
297
|
+
if (result.action === 'Retry') handleSubmit();
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
return <button onClick={handleSubmit}>Login</button>;
|
|
302
|
+
}
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### Vue 3
|
|
306
|
+
|
|
307
|
+
```js
|
|
308
|
+
// plugins/notify.js
|
|
309
|
+
import DotNotify from 'dotnotify';
|
|
310
|
+
export const notify = DotNotify({ position: 'top-right', theme: 'ios-glass' });
|
|
311
|
+
|
|
312
|
+
// main.js
|
|
313
|
+
import { notify } from './plugins/notify';
|
|
314
|
+
app.config.globalProperties.$notify = notify;
|
|
315
|
+
|
|
316
|
+
// In component:
|
|
317
|
+
this.$notify.fire({ type: 'success', title: 'Done!', message: 'Saved.' });
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### Vanilla JS (CDN)
|
|
321
|
+
|
|
322
|
+
```html
|
|
323
|
+
<script src="https://cdn.jsdelivr.net/npm/dotnotify/dist/dotnotify.min.js"></script>
|
|
324
|
+
<script>
|
|
325
|
+
const notify = DotNotify({ position: 'top-right' });
|
|
326
|
+
|
|
327
|
+
document.querySelector('#login-btn').addEventListener('click', async () => {
|
|
328
|
+
const result = await notify.fire({
|
|
329
|
+
type: 'error',
|
|
330
|
+
title: 'Login Failed',
|
|
331
|
+
message: 'Wrong password. Try again or reset.',
|
|
332
|
+
actions: [
|
|
333
|
+
{ label: 'Retry', primary: true },
|
|
334
|
+
{ label: 'Reset pass', onClick: () => location.href = '/reset' },
|
|
335
|
+
],
|
|
336
|
+
});
|
|
337
|
+
console.log(result); // { dismissed: 'action', action: 'Retry' }
|
|
338
|
+
});
|
|
339
|
+
</script>
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### Next.js / Nuxt
|
|
343
|
+
|
|
344
|
+
```js
|
|
345
|
+
// Works only in browser β wrap in useEffect / onMounted
|
|
346
|
+
useEffect(() => {
|
|
347
|
+
const notify = DotNotify({ position: 'top-right' });
|
|
348
|
+
notify.fire({ type: 'info', title: 'Hello', message: 'Page loaded.' });
|
|
349
|
+
}, []);
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
---
|
|
353
|
+
|
|
354
|
+
## π§ Instance Methods
|
|
355
|
+
|
|
356
|
+
```js
|
|
357
|
+
const notify = DotNotify({ ... });
|
|
358
|
+
|
|
359
|
+
// Fire a notification (returns Promise)
|
|
360
|
+
await notify.fire({ ... });
|
|
361
|
+
|
|
362
|
+
// Dismiss all visible notifications immediately
|
|
363
|
+
notify.dismissAll();
|
|
364
|
+
|
|
365
|
+
// Update global config after init
|
|
366
|
+
notify.configure({ theme: 'light', sound: true });
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
## π΅ Sound
|
|
372
|
+
|
|
373
|
+
DotNotify generates a subtle two-tone ping using the Web Audio API β no audio files, no network requests.
|
|
374
|
+
|
|
375
|
+
```js
|
|
376
|
+
const notify = DotNotify({ sound: true }); // enable globally
|
|
377
|
+
notify.fire({ ..., sound: false }); // override per-notification
|
|
378
|
+
notify.fire({ ..., sound: true }); // override per-notification
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
Sound frequencies by type:
|
|
382
|
+
- `error` β 440Hz β 330Hz (descending, unsettling)
|
|
383
|
+
- `success` β 523Hz β 659Hz (ascending, happy)
|
|
384
|
+
- `warning` β 466Hz β 440Hz (slight drop, cautionary)
|
|
385
|
+
- `info` β 587Hz β 659Hz (gentle rise, neutral)
|
|
386
|
+
|
|
387
|
+
---
|
|
388
|
+
|
|
389
|
+
## π Browser Support
|
|
390
|
+
|
|
391
|
+
| Browser | Support |
|
|
392
|
+
|---|---|
|
|
393
|
+
| Chrome 76+ | β
Full |
|
|
394
|
+
| Safari 14+ | β
Full |
|
|
395
|
+
| Firefox 70+ | β
Full |
|
|
396
|
+
| Edge 79+ | β
Full |
|
|
397
|
+
| iOS Safari 14+ | β
Full (touch swipe works) |
|
|
398
|
+
| Android Chrome | β
Full |
|
|
399
|
+
|
|
400
|
+
> `backdrop-filter` requires Chrome 76+, Safari 9+, Firefox 70+.
|
|
401
|
+
> On older browsers the card still renders β just without the blur effect.
|
|
402
|
+
|
|
403
|
+
---
|
|
404
|
+
|
|
405
|
+
## π Package Structure
|
|
406
|
+
|
|
407
|
+
```
|
|
408
|
+
dotnotify/
|
|
409
|
+
βββ dist/
|
|
410
|
+
β βββ dotnotify.js β UMD build (CommonJS + browser global)
|
|
411
|
+
β βββ dotnotify.esm.js β ES Module build (import/export)
|
|
412
|
+
β βββ dotnotify.min.js β Minified browser build (~9kb gzipped)
|
|
413
|
+
β βββ dotnotify.d.ts β TypeScript definitions
|
|
414
|
+
βββ src/
|
|
415
|
+
β βββ dotnotify.js β Source
|
|
416
|
+
βββ examples/
|
|
417
|
+
β βββ vanilla.html β Vanilla JS demo
|
|
418
|
+
β βββ react-example.jsx β React demo
|
|
419
|
+
βββ package.json
|
|
420
|
+
βββ README.md
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
---
|
|
424
|
+
|
|
425
|
+
## πΊοΈ Roadmap
|
|
426
|
+
|
|
427
|
+
- [ ] `dotnotify/react` β official React component wrapper
|
|
428
|
+
- [ ] `dotnotify/vue` β official Vue plugin
|
|
429
|
+
- [ ] Custom dot count and dot size
|
|
430
|
+
- [ ] Notification center (history panel)
|
|
431
|
+
- [ ] CSS custom properties for full theme control
|
|
432
|
+
- [ ] RTL support
|
|
433
|
+
|
|
434
|
+
---
|
|
435
|
+
|
|
436
|
+
## π License
|
|
437
|
+
|
|
438
|
+
MIT Β© 2024 Your Name
|
|
439
|
+
|
|
440
|
+
---
|
|
441
|
+
|
|
442
|
+
## π€ Contributing
|
|
443
|
+
|
|
444
|
+
1. Fork the repo
|
|
445
|
+
2. `npm install`
|
|
446
|
+
3. Edit `src/dotnotify.js`
|
|
447
|
+
4. `npm run build`
|
|
448
|
+
5. Open `examples/vanilla.html` to test
|
|
449
|
+
6. Submit a PR
|
|
450
|
+
|
|
451
|
+
---
|
|
452
|
+
|
|
453
|
+
<p align="center">Made with β€οΈ Β· <a href="https://github.com/yourusername/dotnotify">GitHub</a> Β· <a href="https://www.npmjs.com/package/dotnotify">npm</a></p>
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
// DotNotify β TypeScript Definitions
|
|
2
|
+
// Version 1.0.0
|
|
3
|
+
|
|
4
|
+
export interface DotNotifyConfig {
|
|
5
|
+
/** Where notifications appear on screen. Default: 'top-right' */
|
|
6
|
+
position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
|
|
7
|
+
|
|
8
|
+
/** Visual theme. Default: 'ios-glass' */
|
|
9
|
+
theme?: 'ios-glass' | 'dark' | 'light' | 'minimal';
|
|
10
|
+
|
|
11
|
+
/** Play a subtle sound on notification appear. Default: false */
|
|
12
|
+
sound?: boolean;
|
|
13
|
+
|
|
14
|
+
/** Max notifications visible at once before queuing. Default: 4 */
|
|
15
|
+
maxStack?: number;
|
|
16
|
+
|
|
17
|
+
/** How long each notification lives in ms. Default: 4200 */
|
|
18
|
+
duration?: number;
|
|
19
|
+
|
|
20
|
+
/** CSS z-index for notifications. Default: 99999 */
|
|
21
|
+
zIndex?: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface ActionButton {
|
|
25
|
+
/** Button label text */
|
|
26
|
+
label: string;
|
|
27
|
+
|
|
28
|
+
/** Style as primary accent button. Default: false */
|
|
29
|
+
primary?: boolean;
|
|
30
|
+
|
|
31
|
+
/** Called when this action button is clicked */
|
|
32
|
+
onClick?: () => void;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface FireOptions {
|
|
36
|
+
/** Notification severity type */
|
|
37
|
+
type: 'error' | 'success' | 'warning' | 'info';
|
|
38
|
+
|
|
39
|
+
/** Bold heading text */
|
|
40
|
+
title: string;
|
|
41
|
+
|
|
42
|
+
/** Body message text */
|
|
43
|
+
message: string;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Custom icon. Three options:
|
|
47
|
+
* - Emoji string: 'π₯'
|
|
48
|
+
* - SVG string: '<svg>...</svg>'
|
|
49
|
+
* - Image URL string: 'https://example.com/avatar.png'
|
|
50
|
+
* - File object: from <input type="file"> or drag-drop
|
|
51
|
+
* - HTMLImageElement: existing <img> element on the page
|
|
52
|
+
*/
|
|
53
|
+
icon?: string | File | HTMLImageElement;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Developer image displayed in the notification icon area.
|
|
57
|
+
* Accepts URL string, File object, or HTMLImageElement.
|
|
58
|
+
* When provided, it replaces the icon.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* // URL
|
|
62
|
+
* image: 'https://example.com/avatar.png'
|
|
63
|
+
*
|
|
64
|
+
* // File from input
|
|
65
|
+
* image: fileInput.files[0]
|
|
66
|
+
*
|
|
67
|
+
* // HTMLImageElement
|
|
68
|
+
* image: document.querySelector('#my-img')
|
|
69
|
+
*/
|
|
70
|
+
image?: string | File | HTMLImageElement;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Small thumbnail image shown to the right of the message.
|
|
74
|
+
* Accepts URL string.
|
|
75
|
+
* @example
|
|
76
|
+
* thumbnail: 'https://example.com/preview.jpg'
|
|
77
|
+
*/
|
|
78
|
+
thumbnail?: string;
|
|
79
|
+
|
|
80
|
+
/** Override theme for this notification only */
|
|
81
|
+
theme?: 'ios-glass' | 'dark' | 'light' | 'minimal';
|
|
82
|
+
|
|
83
|
+
/** Override duration for this notification only (ms) */
|
|
84
|
+
duration?: number;
|
|
85
|
+
|
|
86
|
+
/** Progress style. Default: 'dots' */
|
|
87
|
+
progressStyle?: 'dots' | 'ring';
|
|
88
|
+
|
|
89
|
+
/** Override the app label above the title */
|
|
90
|
+
app?: string;
|
|
91
|
+
|
|
92
|
+
/** Play sound for this notification (overrides global setting) */
|
|
93
|
+
sound?: boolean;
|
|
94
|
+
|
|
95
|
+
/** Action buttons shown at bottom of card */
|
|
96
|
+
actions?: ActionButton[];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface DismissResult {
|
|
100
|
+
/** How the notification was dismissed */
|
|
101
|
+
dismissed: 'timeout' | 'close' | 'action' | 'swipe-left' | 'swipe-right' | 'external';
|
|
102
|
+
|
|
103
|
+
/** Which action button was clicked (if dismissed === 'action') */
|
|
104
|
+
action?: string;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface DotNotifyInstance {
|
|
108
|
+
/**
|
|
109
|
+
* Fire a notification. Returns a Promise that resolves when dismissed.
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* const result = await notify.fire({
|
|
113
|
+
* type: 'error',
|
|
114
|
+
* title: 'Login Failed',
|
|
115
|
+
* message: 'Invalid credentials.',
|
|
116
|
+
* });
|
|
117
|
+
* console.log(result.dismissed); // 'timeout' | 'close' | 'action' | ...
|
|
118
|
+
*/
|
|
119
|
+
fire(opts: FireOptions): Promise<DismissResult>;
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Instantly dismiss all visible notifications.
|
|
123
|
+
*/
|
|
124
|
+
dismissAll(): void;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Update global config after initialization.
|
|
128
|
+
*/
|
|
129
|
+
configure(config: Partial<DotNotifyConfig>): void;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Create a DotNotify instance.
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* import DotNotify from 'dotnotify';
|
|
137
|
+
*
|
|
138
|
+
* const notify = DotNotify({ position: 'top-right', theme: 'ios-glass' });
|
|
139
|
+
*
|
|
140
|
+
* notify.fire({
|
|
141
|
+
* type: 'success',
|
|
142
|
+
* title: 'Saved!',
|
|
143
|
+
* message: 'Your profile has been updated.',
|
|
144
|
+
* });
|
|
145
|
+
*/
|
|
146
|
+
declare function DotNotify(config?: DotNotifyConfig): DotNotifyInstance;
|
|
147
|
+
|
|
148
|
+
export default DotNotify;
|
|
149
|
+
export = DotNotify;
|