robot-toast 1.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,200 @@
1
+ # πŸ€– robot-toast
2
+
3
+ A lightweight, zero-dependency, framework-agnostic toast notification library featuring an animated robot companion. Fully draggable, typewriter-style messages, multiple themes, rich transitions, and a cast of **16 built-in robots** β€” or bring your own.
4
+
5
+ <p align="center">
6
+ <img src="public/lightmode.png" alt="Light mode" width="320" />
7
+ <img src="public/darkmode.png" alt="Dark mode" width="320" />
8
+ <img src="public/custom.png" alt="Custom styled" width="320" />
9
+ </p>
10
+
11
+ ---
12
+
13
+ ## Features
14
+
15
+ | Category | Details |
16
+ |---|---|
17
+ | **Themes** | `light` Β· `dark` Β· `colored` |
18
+ | **Types** | `default` Β· `info` Β· `success` Β· `warning` Β· `error` |
19
+ | **Transitions** | `bounce` Β· `flip` Β· `zoom` Β· `slide` |
20
+ | **Positions** | `top-left` Β· `top-center` Β· `top-right` Β· `bottom-left` Β· `bottom-center` Β· `bottom-right` |
21
+ | **Robots** | 16 built-in variants β€” or supply any image path (svg, png, jpg, gif, webp) |
22
+ | **Custom styles** | Pass a `style` object to customize the message bubble however you like |
23
+ | **Drag & drop** | Full XY drag with viewport clamping; snaps to nearest screen edge on release |
24
+ | **Typewriter effect** | Characters appear one by one β€” configurable speed or instant |
25
+ | **Multi-toast** | Configurable `limit` for simultaneous toasts; excess is auto-queued |
26
+ | **Progress bar** | Countdown bar β€” show or hide it |
27
+ | **Pause on hover** | Timer pauses when you hover over the toast |
28
+ | **Pause on focus loss** | Timer pauses when the browser tab loses focus |
29
+ | **Robot side** | `nearScreen` flips the robot to the screen-edge side or the inner side |
30
+ | **RTL** | Right-to-left layout support |
31
+ | **Newest on top** | Stack new toasts above existing ones |
32
+ | **Auto-close** | Configurable duration, or disable entirely |
33
+ | **SSR-safe** | All DOM access is guarded β€” safe for Next.js, Nuxt, etc. |
34
+ | **Zero dependencies** | Pure TypeScript β€” ESM + CJS builds, tree-shakable |
35
+
36
+ ---
37
+
38
+ ## Installation
39
+
40
+ ```bash
41
+ npm install robot-toast
42
+ ```
43
+
44
+ ## Quick Start
45
+
46
+ ```ts
47
+ import { toast } from 'robot-toast';
48
+
49
+ // Simple string
50
+ toast('Hello πŸ€–');
51
+
52
+ // With options
53
+ toast({
54
+ message: 'Operation successful!',
55
+ type: 'success',
56
+ theme: 'dark',
57
+ position: 'top-right',
58
+ });
59
+ ```
60
+
61
+ ## Type Shorthands
62
+
63
+ ```ts
64
+ toast.success('Saved!');
65
+ toast.error('Something went wrong');
66
+ toast.info('Did you know…');
67
+ toast.warning('Check your input');
68
+ ```
69
+
70
+ ## Close Programmatically
71
+
72
+ ```ts
73
+ // Close a specific toast by id
74
+ const id = toast('Working…');
75
+ toast.closeById(id);
76
+
77
+ // Close all toasts at once
78
+ toast.closeAll();
79
+ ```
80
+
81
+ ---
82
+
83
+ ## Options
84
+
85
+ | Option | Type | Default | Description |
86
+ |---|---|---|---|
87
+ | `message` | `string` | *required* | The text to display |
88
+ | `autoClose` | `number \| false` | `5000` | Auto-close after ms. `false` = stays until dismissed |
89
+ | `position` | `string` | `'bottom-right'` | One of the 6 position presets (see above) |
90
+ | `type` | `string` | `'default'` | `default` Β· `info` Β· `success` Β· `warning` Β· `error` |
91
+ | `theme` | `string` | `'light'` | `light` Β· `dark` Β· `colored` |
92
+ | `transition` | `string` | `'bounce'` | `bounce` Β· `flip` Β· `zoom` Β· `slide` |
93
+ | `style` | `Record<string, string \| number>` | β€” | Inline styles applied directly to the message bubble for full customization |
94
+ | `typeSpeed` | `number` | `30` | Typing speed in ms per character. `0` = instant |
95
+ | `robotVariant` | `string` | `''` | Built-in name (e.g. `'wave'`) or a custom image path (e.g. `'/my-robot.png'`). `'none'` hides the robot |
96
+ | `hideProgressBar` | `boolean` | `false` | Hide the countdown progress bar |
97
+ | `draggable` | `boolean` | `true` | Allow the user to drag the toast around the screen |
98
+ | `nearScreen` | `boolean` | `true` | `true` = robot near screen edge; `false` = robot on the inner side |
99
+ | `pauseOnHover` | `boolean` | `true` | Pause countdown while the cursor is over the toast |
100
+ | `pauseOnFocusLoss` | `boolean` | `true` | Pause countdown when the browser tab loses focus |
101
+ | `rtl` | `boolean` | `false` | Right-to-left layout |
102
+ | `limit` | `number` | `0` | Max toasts visible at once. `0` = unlimited. Excess is queued |
103
+ | `newestOnTop` | `boolean` | `false` | Stack newest toasts above older ones |
104
+ | `onOpen` | `() => void` | β€” | Callback fired when the toast finishes its entrance |
105
+ | `onClose` | `() => void` | β€” | Callback fired after the toast fully exits |
106
+
107
+ ---
108
+
109
+ ## Built-in Robots
110
+
111
+ Use any of the following names as `robotVariant` β€” no external files needed:
112
+
113
+ `wave` Β· `base` Β· `base2` Β· `success` Β· `error` Β· `angry` Β· `angry2` Β· `shock` Β· `think` Β· `search` Β· `loading` Β· `sleep` Β· `head-palm` Β· `type` Β· `validation` Β· `validation2`
114
+
115
+ ```ts
116
+ toast({ message: 'Thinking…', robotVariant: 'think' });
117
+ toast({ message: 'All good!', robotVariant: 'success', type: 'success' });
118
+ ```
119
+
120
+ ### Custom Robot Image
121
+
122
+ Point to any image accessible in your app:
123
+
124
+ ```ts
125
+ toast({
126
+ message: 'Custom bot!',
127
+ robotVariant: '/images/my-robot.png',
128
+ });
129
+ ```
130
+
131
+ Supported formats: **svg, png, jpg, jpeg, gif, webp**.
132
+ Set `robotVariant: 'none'` to hide the robot entirely.
133
+
134
+ ---
135
+
136
+ ## Themes & Custom Styles
137
+
138
+ ### Built-in Themes
139
+
140
+ ```ts
141
+ toast({ message: 'Light mode', theme: 'light' });
142
+ toast({ message: 'Dark mode', theme: 'dark' });
143
+ toast({ message: 'Colored', theme: 'colored', type: 'success' });
144
+ ```
145
+
146
+ ### Custom Inline Styles
147
+
148
+ Use the `style` option to fully customize the message bubble:
149
+
150
+ ```ts
151
+ toast({
152
+ message: 'Fully custom look',
153
+ style: {
154
+ background: 'linear-gradient(135deg, #667eea, #764ba2)',
155
+ color: '#fff',
156
+ borderRadius: '16px',
157
+ fontFamily: 'monospace',
158
+ },
159
+ });
160
+ ```
161
+
162
+ ---
163
+
164
+ ## Transitions
165
+
166
+ ```ts
167
+ toast({ message: 'Bounce!', transition: 'bounce' });
168
+ toast({ message: 'Flip!', transition: 'flip' });
169
+ toast({ message: 'Zoom!', transition: 'zoom' });
170
+ toast({ message: 'Slide!', transition: 'slide' });
171
+ ```
172
+
173
+ ---
174
+
175
+ ## Framework Examples
176
+
177
+ ### React / Next.js
178
+
179
+ ```tsx
180
+ 'use client';
181
+ import { toast } from 'robot-toast';
182
+ import { useEffect, useRef } from 'react';
183
+
184
+ export default function App() {
185
+ const shown = useRef(false);
186
+
187
+ useEffect(() => {
188
+ toast({
189
+ message: 'Welcome!',
190
+ type: 'success',
191
+ theme: 'dark',
192
+ position: 'top-right',
193
+ robotVariant: 'wave',
194
+ transition: 'bounce',
195
+ });
196
+ }, []);
197
+
198
+ return <div>My App</div>;
199
+ }
200
+ ```
@@ -0,0 +1,250 @@
1
+ /**
2
+ * RobotToast Types & Constants
3
+ * Type definitions and constant arrays for the robot toast notification library
4
+ */
5
+ /** Array of all valid toast positions */
6
+ declare const TOAST_POSITIONS: readonly ["top-right", "top-left", "top-center", "bottom-right", "bottom-left", "bottom-center"];
7
+ /** Array of all valid toast types */
8
+ declare const TOAST_TYPES: readonly ["default", "info", "success", "warning", "error"];
9
+ /** Array of all valid toast themes */
10
+ declare const TOAST_THEMES: readonly ["light", "dark", "colored"];
11
+ /** Array of all valid transition animations */
12
+ declare const TOAST_TRANSITIONS: readonly ["bounce", "slide", "zoom", "flip"];
13
+ /** Type derived from TOAST_POSITIONS constant */
14
+ type ToastPosition = typeof TOAST_POSITIONS[number];
15
+ /** Type derived from TOAST_TYPES constant */
16
+ type ToastType = typeof TOAST_TYPES[number];
17
+ /** Type derived from TOAST_THEMES constant */
18
+ type ToastTheme = typeof TOAST_THEMES[number];
19
+ /** Type derived from TOAST_TRANSITIONS constant */
20
+ type TransitionType = typeof TOAST_TRANSITIONS[number];
21
+ interface RobotToastOptions {
22
+ /** The message text to display in the toast */
23
+ message: string;
24
+ /** Auto-close duration in ms, or false to disable. Default: 5000 */
25
+ autoClose?: boolean | number;
26
+ /** Position of the toast on screen. Default: 'bottom-right' */
27
+ position?: ToastPosition;
28
+ /** Toast type/style. Default: 'default' */
29
+ type?: ToastType;
30
+ /** Visual theme. Default: 'light' */
31
+ theme?: ToastTheme;
32
+ /**
33
+ * Inline style object to apply directly to the message box element.
34
+ * This allows runtime customization of colors, fonts, backgrounds, etc.
35
+ * Example: { color: 'red', backgroundColor: 'blue' }
36
+ * This takes precedence over className for conflicting properties.
37
+ */
38
+ style?: Record<string, string | number>;
39
+ /** Typing speed in ms per character. 0 = instant. Default: 30 */
40
+ typeSpeed?: number;
41
+ /**
42
+ * Robot image to display.
43
+ * - Built-in: 'wave', 'error', 'success', 'base', 'base2', 'angry', 'angry2', 'shock',
44
+ * 'think', 'search', 'loading', 'sleep', 'head-palm', 'type', 'validation', 'validation2'
45
+ * (these use embedded data URLs, no external files needed)
46
+ * - Custom: any path accessible in your app (e.g., 'dxd/bird.jpg', 'public/my-robot.svg')
47
+ * - None: 'none' to hide the robot entirely
48
+ * Accepted formats for custom images: svg, png, jpg, jpeg, gif, webp.
49
+ * Anything unrecognized falls back to the built-in robot.
50
+ */
51
+ robotVariant?: string;
52
+ /** Hide the countdown progress bar. Default: false */
53
+ hideProgressBar?: boolean;
54
+ /** Pause the auto-close countdown when the window loses focus. Default: true */
55
+ pauseOnFocusLoss?: boolean;
56
+ /** Allow the user to drag the toast around the screen. Default: true */
57
+ draggable?: boolean;
58
+ /**
59
+ * Position the robot near the screen edge (true) or away from it (false).
60
+ * - true: robot appears between screen edge and message bubble
61
+ * - false: message bubble appears between screen edge and robot
62
+ * The position is automatically determined by the toast position and this setting.
63
+ * Default: true
64
+ */
65
+ nearScreen?: boolean;
66
+ /** Pause the auto-close countdown while the cursor is over the toast. Default: true */
67
+ pauseOnHover?: boolean;
68
+ /**
69
+ * Maximum number of toasts visible simultaneously.
70
+ * Excess toasts are queued and shown as soon as a slot opens.
71
+ * 0 = unlimited (queue still works, all show in parallel). Default: 0
72
+ */
73
+ limit?: number;
74
+ /** Stack newest toasts on top of older ones. Default: false */
75
+ newestOnTop?: boolean;
76
+ /** Right-to-left layout (message on the right, robot on the left). Default: false */
77
+ rtl?: boolean;
78
+ /** Entry / exit transition style. Default: 'bounce' */
79
+ transition?: TransitionType;
80
+ /** Called when the toast finishes its enter animation and is fully visible. */
81
+ onOpen?: () => void;
82
+ /** Called after the toast has fully exited the screen. */
83
+ onClose?: () => void;
84
+ }
85
+ /** Internal representation of a queued toast item */
86
+ interface ToastQueueItem {
87
+ options: RobotToastOptions;
88
+ id: number;
89
+ }
90
+ interface RobotToastAPI {
91
+ /** Show a toast notification – queued automatically when limit is reached */
92
+ show: (options: RobotToastOptions) => number;
93
+ /** Immediately close all visible toasts and clear the queue */
94
+ closeAll: () => void;
95
+ /** Close a specific toast by the id returned from show() */
96
+ closeById: (id: number) => void;
97
+ /** Get the RobotToastManager instance */
98
+ getInstance: () => RobotToastInstance;
99
+ }
100
+ interface RobotToastInstance {
101
+ show: (options: RobotToastOptions) => number;
102
+ closeAll: () => void;
103
+ closeById: (id: number) => void;
104
+ }
105
+ declare global {
106
+ interface Window {
107
+ __robotToastLoaded?: boolean;
108
+ __robotToastUtilsLoaded?: boolean;
109
+ RobotToast?: RobotToastAPI;
110
+ RobotToastUtils?: {
111
+ showRobotToast: (options: RobotToastOptions) => Promise<number>;
112
+ closeAllRobotToasts: () => Promise<void>;
113
+ closeRobotToastById: (id: number) => Promise<void>;
114
+ getRobotToastInstance: () => Promise<RobotToastAPI>;
115
+ ensureRobotToastReady: (timeout?: number) => Promise<RobotToastAPI>;
116
+ };
117
+ }
118
+ }
119
+
120
+ /**
121
+ * RobotToast v2
122
+ * ─────────────────────────────────────────────────────────────────────────────
123
+ * β€’ Multi-toast support with configurable limit + queue
124
+ * β€’ Each toast is a self-contained ToastItem instance – no shared mutable state
125
+ * β€’ Sequenced robot enter β†’ message pop-in, message pop-out β†’ robot exit
126
+ * β€’ Full XY drag with viewport clamping; on drop the robot snaps to the
127
+ * nearest screen edge (left / right) with a personality animation
128
+ * β€’ Progress bar auto-animates for the countdown; pauses correctly on hover
129
+ * and drag; resumes with exact remaining time
130
+ * β€’ All event listeners are tracked and fully removed on close
131
+ * β€’ SVG-only enforcement for custom robot images; always renders at fixed size
132
+ * β€’ SSR-safe (all DOM access is guarded by typeof window / document checks)
133
+ * ─────────────────────────────────────────────────────────────────────────────
134
+ */
135
+
136
+ declare class RobotToastManager {
137
+ private static _instance;
138
+ private activeToasts;
139
+ private queue;
140
+ private globalLimit;
141
+ private constructor();
142
+ static getInstance(): RobotToastManager;
143
+ show(options: RobotToastOptions): number;
144
+ closeAll(): void;
145
+ closeById(id: number): void;
146
+ private spawnToast;
147
+ private handleRemoved;
148
+ /**
149
+ * Recalculate the vertical position of every active toast so they stack
150
+ * neatly without overlap. Works for both top-* and bottom-* positions.
151
+ */
152
+ private restack;
153
+ }
154
+
155
+ /**
156
+ * RobotToast Utilities v2
157
+ * Helper functions for safer access to the RobotToast API.
158
+ * Handles async readiness checks, SSR guards, and error boundaries.
159
+ * Useful when loading robot-toast via a CDN <script> tag.
160
+ */
161
+
162
+ /**
163
+ * Wait for window.RobotToast to be available, up to `timeout` ms.
164
+ * Resolves immediately if it is already loaded.
165
+ * Useful when the library is loaded via a <script> tag and you need
166
+ * to call it from another script that may execute first.
167
+ */
168
+ declare function ensureRobotToastReady(timeout?: number): Promise<RobotToastAPI>;
169
+ /**
170
+ * Show a robot toast notification.
171
+ * Waits for the library to be ready before showing.
172
+ * Returns the toast id or -1 on failure.
173
+ */
174
+ declare function showRobotToast(options: RobotToastOptions): Promise<number>;
175
+ /**
176
+ * Close all visible toasts and clear the queue.
177
+ */
178
+ declare function closeAllRobotToasts(): Promise<void>;
179
+ /**
180
+ * Get the RobotToast API instance.
181
+ */
182
+ declare function getRobotToastInstance(): Promise<RobotToastAPI>;
183
+
184
+ /**
185
+ * Built-in robot SVG images as base64 data URLs
186
+ * These are embedded directly in the package, no external files needed
187
+ */
188
+ declare const ROBOT_IMAGES: {
189
+ readonly wave: string;
190
+ readonly base: string;
191
+ readonly base2: string;
192
+ readonly success: string;
193
+ readonly error: string;
194
+ readonly angry: string;
195
+ readonly angry2: string;
196
+ readonly shock: string;
197
+ readonly think: string;
198
+ readonly search: string;
199
+ readonly loading: string;
200
+ readonly sleep: string;
201
+ readonly 'head-palm': string;
202
+ readonly type: string;
203
+ readonly validation: string;
204
+ readonly validation2: string;
205
+ };
206
+
207
+ /**
208
+ * robot-toast v2
209
+ * A lightweight, framework-agnostic toast notification library
210
+ * with an animated robot character, multi-toast queue, and smooth drag.
211
+ *
212
+ * ── Basic usage ──────────────────────────────────────────────────────────────
213
+ * import { toast } from 'robot-toast';
214
+ * toast('Hello πŸ€–');
215
+ * toast({ message: 'Hello!', position: 'top-right', type: 'success' });
216
+ *
217
+ * ── Typed shorthands ─────────────────────────────────────────────────────────
218
+ * toast.success('Saved!');
219
+ * toast.error('Something went wrong');
220
+ * toast.info('Did you know…');
221
+ * toast.warning('Check your input');
222
+ *
223
+ * ── Class / manager ──────────────────────────────────────────────────────────
224
+ * import { RobotToast } from 'robot-toast';
225
+ * const manager = RobotToast.getInstance();
226
+ * const id = manager.show({ message: 'Hi!' });
227
+ * manager.closeById(id);
228
+ */
229
+
230
+ type ToastInput = string | RobotToastOptions;
231
+ /**
232
+ * Show a toast notification.
233
+ * Accepts either a plain string or a full options object.
234
+ * Returns the toast id (useful for closeById).
235
+ *
236
+ * @example
237
+ * toast('Hello πŸ€–');
238
+ * toast({ message: 'Hello!', type: 'success', position: 'top-right' });
239
+ */
240
+ declare function toast(input: ToastInput): number;
241
+ declare namespace toast {
242
+ var success: (input: ToastInput) => number;
243
+ var error: (input: ToastInput) => number;
244
+ var info: (input: ToastInput) => number;
245
+ var warning: (input: ToastInput) => number;
246
+ var closeAll: () => void;
247
+ var closeById: (id: number) => void;
248
+ }
249
+
250
+ export { ROBOT_IMAGES, RobotToastManager as RobotToast, type RobotToastAPI, type RobotToastInstance, RobotToastManager, type RobotToastOptions, TOAST_POSITIONS, TOAST_THEMES, TOAST_TRANSITIONS, TOAST_TYPES, type ToastPosition, type ToastQueueItem, type ToastTheme, type ToastType, type TransitionType, closeAllRobotToasts, ensureRobotToastReady, getRobotToastInstance, showRobotToast, toast };