robot-toast 1.0.2 β†’ 2.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 CHANGED
@@ -1,283 +1,381 @@
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="left">
6
- <a href="https://stackblitz.com/your-demo-link"
7
- style="color:#e53935; font-weight:600; text-decoration:none;">
8
- Demo
9
- </a>
10
- </p>
11
- <p align="center">
12
- <a href="https://pratham-potfolio.vercel.app/" target="_blank">
13
- <img src="https://img.shields.io/badge/Portfolio-000?style=for-the-badge&logo=vercel&logoColor=white" />
14
- </a>
15
- <a href="https://www.linkedin.com/in/pratham-kumar-a6b672275/" target="_blank">
16
- <img src="https://img.shields.io/badge/LinkedIn-0077B5?style=for-the-badge&logo=linkedin&logoColor=white" />
17
- </a>
18
- <a href="https://github.com/Pratham2703005" target="_blank">
19
- <img src="https://img.shields.io/badge/GitHub-000?style=for-the-badge&logo=github&logoColor=white" />
20
- </a>
21
- </p>
22
- <p align="center">
23
- <a href="https://www.npmjs.com/package/robot-toast">
24
- <img src="https://img.shields.io/npm/v/robot-toast?style=flat-square" />
25
- </a>
26
- <img src="https://img.shields.io/npm/dt/robot-toast?style=flat-square" />
27
- <img src="https://img.shields.io/bundlephobia/minzip/robot-toast?style=flat-square" />
28
- </p>
29
-
30
- <p align="center">
31
- <img src="https://raw.githubusercontent.com/Pratham2703005/robot-toast/refs/heads/main/public/offiicial-page/lightmode.png" alt="Light mode" width="320" />
32
- <img src="https://raw.githubusercontent.com/Pratham2703005/robot-toast/refs/heads/main/public/offiicial-page/darkmode.png" alt="Dark mode" width="320" />
33
- <img src="https://raw.githubusercontent.com/Pratham2703005/robot-toast/refs/heads/main/public/offiicial-page/custom.png" alt="Custom styled" width="320" />
34
- </p>
35
-
36
- ---
37
-
38
- ## Features
39
-
40
- | Category | Details |
41
- |---|---|
42
- | **Themes** | `light` Β· `dark` Β· `colored` |
43
- | **Types** | `default` Β· `info` Β· `success` Β· `warning` Β· `error` |
44
- | **Transitions** | `bounce` Β· `flip` Β· `zoom` Β· `slide` |
45
- | **Positions** | `top-left` Β· `top-center` Β· `top-right` Β· `bottom-left` Β· `bottom-center` Β· `bottom-right` |
46
- | **Robots** | 16 built-in variants β€” or supply any image path (svg, png, jpg, gif, webp) |
47
- | **Custom styles** | Pass a `style` object to customize the message bubble however you like |
48
- | **Drag & drop** | Full XY drag with viewport clamping; snaps to nearest screen edge on release |
49
- | **Typewriter effect** | Characters appear one by one β€” configurable speed or instant |
50
- | **Multi-toast** | Configurable `limit` for simultaneous toasts; excess is auto-queued |
51
- | **Progress bar** | Countdown bar β€” show or hide it |
52
- | **Pause on hover** | Timer pauses when you hover over the toast |
53
- | **Pause on focus loss** | Timer pauses when the browser tab loses focus |
54
- | **Robot side** | `nearScreen` flips the robot to the screen-edge side or the inner side |
55
- | **RTL** | Right-to-left layout support |
56
- | **Newest on top** | Stack new toasts above existing ones |
57
- | **Auto-close** | Configurable duration, or disable entirely |
58
- | **SSR-safe** | All DOM access is guarded β€” safe for Next.js, Nuxt, etc. |
59
- | **Zero dependencies** | Pure TypeScript β€” ESM + CJS builds, tree-shakable |
60
-
61
- ---
62
-
63
- ## Installation
64
-
65
- ```bash
66
- npm install robot-toast
67
- ```
68
-
69
- ## Quick Start
70
-
71
- ```ts
72
- import { toast } from 'robot-toast';
73
-
74
- // Simple string
75
- toast('Hello πŸ€–');
76
-
77
- // With options
78
- toast({
79
- message: 'Operation successful!',
80
- type: 'success',
81
- theme: 'dark',
82
- position: 'top-right',
83
- });
84
- ```
85
-
86
- ## Close Programmatically
87
-
88
- ```ts
89
- // Close a specific toast by id
90
- const id = toast('Working…');
91
- toast.closeById(id);
92
-
93
- // Close all toasts at once
94
- toast.closeAll();
95
- ```
96
-
97
- ---
98
- ## All Options at a Glance
99
-
100
- A single `toast()` call using **every available option** so you can see the full API in one place:
101
-
102
- ```ts
103
- import { toast } from 'robot-toast';
104
-
105
- toast({
106
- // ─── Content ───────────────────────────────────────────
107
- message: 'This is the full kitchen-sink example!',
108
-
109
- // ─── Appearance ────────────────────────────────────────
110
- type: 'success', // 'default' | 'info' | 'success' | 'warning' | 'error'
111
- theme: 'dark', // 'light' | 'dark' | 'colored'
112
- transition: 'bounce', // 'bounce' | 'flip' | 'zoom' | 'slide'
113
- position: 'bottom-right', // 'top-left' | 'top-center' | 'top-right'
114
- // 'bottom-left' | 'bottom-center' | 'bottom-right'
115
-
116
- // ─── Robot ─────────────────────────────────────────────
117
- robotVariant: 'wave', // built-in: 'wave' | 'base' | 'base2' | 'success' | 'error'
118
- // 'angry' | 'angry2' | 'shock' | 'think' | 'search'
119
- // 'loading' | 'sleep' | 'head-palm' | 'type'
120
- // 'validation' | 'validation2'
121
- // custom: '/path/to/image.png' (svg, png, jpg, jpeg, gif, webp)
122
- // hide: 'none'
123
- nearScreen: true, // true = robot near screen edge, false = robot on inner side
124
-
125
- // ─── Timing ────────────────────────────────────────────
126
- autoClose: 5000, // milliseconds, or false to disable auto-close
127
- typeSpeed: 30, // ms per character (0 = instant, no typing effect)
128
-
129
- // ─── Behaviour ─────────────────────────────────────────
130
- hideProgressBar: false, // true to hide the countdown bar
131
- draggable: true, // allow drag & drop with edge-snapping
132
- pauseOnHover: true, // pause countdown on mouse hover
133
- pauseOnFocusLoss: true, // pause countdown when tab loses focus
134
- rtl: false, // right-to-left layout
135
-
136
- // ─── Multi-toast ───────────────────────────────────────
137
- limit: 0, // max visible toasts (0 = unlimited, excess is queued)
138
- newestOnTop: false, // stack new toasts above older ones
139
-
140
- // ─── Custom Inline Styles ─────────────────────────────
141
- style: {
142
- background: 'linear-gradient(135deg, #667eea, #764ba2)',
143
- color: '#fff',
144
- borderRadius: '16px',
145
- fontFamily: 'monospace',
146
- },
147
-
148
- // ─── Callbacks ─────────────────────────────────────────
149
- onOpen: () => console.log('Toast appeared!'),
150
- onClose: () => console.log('Toast dismissed!'),
151
- });
152
- ```
153
-
154
- ### Type Shorthands
155
-
156
- ```ts
157
- // These set the `type` automatically β€” you can also pass a full options object
158
- toast.success('Saved!');
159
- toast.error('Something went wrong');
160
- toast.info('Did you know…');
161
- toast.warning('Check your input');
162
-
163
- // With additional options
164
- toast.success({ message: 'Deployed!', theme: 'colored', position: 'top-center', robotVariant: 'success' });
165
- ```
166
-
167
- ---
168
- ## Options
169
-
170
- | Option | Type | Default | Description |
171
- |---|---|---|---|
172
- | `message` | `string` | *required* | The text to display |
173
- | `autoClose` | `number \| false` | `5000` | Auto-close after ms. `false` = stays until dismissed |
174
- | `position` | `string` | `'bottom-right'` | One of the 6 position presets (see above) |
175
- | `type` | `string` | `'default'` | `default` Β· `info` Β· `success` Β· `warning` Β· `error` |
176
- | `theme` | `string` | `'light'` | `light` Β· `dark` Β· `colored` |
177
- | `transition` | `string` | `'bounce'` | `bounce` Β· `flip` Β· `zoom` Β· `slide` |
178
- | `style` | `Record<string, string \| number>` | β€” | Inline styles applied directly to the message bubble for full customization |
179
- | `typeSpeed` | `number` | `30` | Typing speed in ms per character. `0` = instant |
180
- | `robotVariant` | `string` | `''` | Built-in name (e.g. `'wave'`) or a custom image path (e.g. `'/my-robot.png'`). `'none'` hides the robot |
181
- | `hideProgressBar` | `boolean` | `false` | Hide the countdown progress bar |
182
- | `draggable` | `boolean` | `true` | Allow the user to drag the toast around the screen |
183
- | `nearScreen` | `boolean` | `true` | `true` = robot near screen edge; `false` = robot on the inner side |
184
- | `pauseOnHover` | `boolean` | `true` | Pause countdown while the cursor is over the toast |
185
- | `pauseOnFocusLoss` | `boolean` | `true` | Pause countdown when the browser tab loses focus |
186
- | `rtl` | `boolean` | `false` | Right-to-left layout |
187
- | `limit` | `number` | `0` | Max toasts visible at once. `0` = unlimited. Excess is queued |
188
- | `newestOnTop` | `boolean` | `false` | Stack newest toasts above older ones |
189
- | `onOpen` | `() => void` | β€” | Callback fired when the toast finishes its entrance |
190
- | `onClose` | `() => void` | β€” | Callback fired after the toast fully exits |
191
-
192
- ---
193
-
194
- ## Built-in Robots
195
-
196
- Use any of the following names as `robotVariant` β€” no external files needed:
197
-
198
- `wave` Β· `base` Β· `base2` Β· `success` Β· `error` Β· `angry` Β· `angry2` Β· `shock` Β· `think` Β· `search` Β· `loading` Β· `sleep` Β· `head-palm` Β· `type` Β· `validation` Β· `validation2`
199
-
200
- ```ts
201
- toast({ message: 'Thinking…', robotVariant: 'think' });
202
- toast({ message: 'All good!', robotVariant: 'success', type: 'success' });
203
- ```
204
-
205
- ### Custom Robot Image
206
-
207
- Point to any image accessible in your app:
208
-
209
- ```ts
210
- toast({
211
- message: 'Custom bot!',
212
- robotVariant: '/images/my-robot.png',
213
- });
214
- ```
215
-
216
- Supported formats: **svg, png, jpg, jpeg, gif, webp**.
217
- Set `robotVariant: 'none'` to hide the robot entirely.
218
-
219
- ---
220
-
221
- ## Themes & Custom Styles
222
-
223
- ### Built-in Themes
224
-
225
- ```ts
226
- toast({ message: 'Light mode', theme: 'light' });
227
- toast({ message: 'Dark mode', theme: 'dark' });
228
- toast({ message: 'Colored', theme: 'colored', type: 'success' });
229
- ```
230
-
231
- ### Custom Inline Styles
232
-
233
- Use the `style` option to fully customize the message bubble:
234
-
235
- ```ts
236
- toast({
237
- message: 'Fully custom look',
238
- style: {
239
- background: 'linear-gradient(135deg, #667eea, #764ba2)',
240
- color: '#fff',
241
- borderRadius: '16px',
242
- fontFamily: 'monospace',
243
- },
244
- });
245
- ```
246
-
247
- ---
248
-
249
- ## Transitions
250
-
251
- ```ts
252
- toast({ message: 'Bounce!', transition: 'bounce' });
253
- toast({ message: 'Flip!', transition: 'flip' });
254
- toast({ message: 'Zoom!', transition: 'zoom' });
255
- toast({ message: 'Slide!', transition: 'slide' });
256
- ```
257
-
258
- ---
259
-
260
- ## Framework Examples
261
-
262
- ### React / Next.js
263
-
264
- ```tsx
265
- 'use client';
266
- import { toast } from 'robot-toast';
267
- import { useEffect } from 'react';
268
-
269
- export default function App() {
270
- useEffect(() => {
271
- toast({
272
- message: 'Welcome!',
273
- type: 'success',
274
- theme: 'dark',
275
- position: 'top-right',
276
- robotVariant: 'wave',
277
- transition: 'bounce',
278
- });
279
- }, []);
280
-
281
- return <div>My App</div>;
282
- }
283
- ```
1
+ # πŸ€– robot-toast
2
+
3
+ A lightweight, zero-dependency, framework-agnostic toast notification library featuring an animated robot companion. Fully draggable with **swipe-to-dismiss**, typewriter-style messages, multiple themes, rich transitions, a tree-shakeable cast of **16 built-in robots** β€” and now an optional React hook.
4
+
5
+ <p align="left">
6
+ <a href="https://stackblitz.com/your-demo-link"
7
+ style="color:#e53935; font-weight:600; text-decoration:none;">
8
+ Demo
9
+ </a>
10
+ </p>
11
+ <p align="center">
12
+ <a href="https://pratham-potfolio.vercel.app/" target="_blank">
13
+ <img src="https://img.shields.io/badge/Portfolio-000?style=for-the-badge&logo=vercel&logoColor=white" />
14
+ </a>
15
+ <a href="https://www.linkedin.com/in/pratham-kumar-a6b672275/" target="_blank">
16
+ <img src="https://img.shields.io/badge/LinkedIn-0077B5?style=for-the-badge&logo=linkedin&logoColor=white" />
17
+ </a>
18
+ <a href="https://github.com/Pratham2703005" target="_blank">
19
+ <img src="https://img.shields.io/badge/GitHub-000?style=for-the-badge&logo=github&logoColor=white" />
20
+ </a>
21
+ </p>
22
+ <p align="center">
23
+ <a href="https://www.npmjs.com/package/robot-toast">
24
+ <img src="https://img.shields.io/npm/v/robot-toast?style=flat-square" />
25
+ </a>
26
+ <img src="https://img.shields.io/npm/dt/robot-toast?style=flat-square" />
27
+ <img src="https://img.shields.io/bundlephobia/minzip/robot-toast?style=flat-square" />
28
+ </p>
29
+
30
+ <p align="center">
31
+ <img src="https://raw.githubusercontent.com/Pratham2703005/robot-toast/refs/heads/main/public/offiicial-page/lightmode.png" alt="Light mode" width="320" />
32
+ <img src="https://raw.githubusercontent.com/Pratham2703005/robot-toast/refs/heads/main/public/offiicial-page/darkmode.png" alt="Dark mode" width="320" />
33
+ <img src="https://raw.githubusercontent.com/Pratham2703005/robot-toast/refs/heads/main/public/offiicial-page/custom.png" alt="Custom styled" width="320" />
34
+ </p>
35
+
36
+ ---
37
+
38
+ ## What's new in v2
39
+
40
+ - **36% smaller core bundle** (61 KB β†’ 39 KB). Robots moved to a tree-shakeable subpath β€” only the ones you import end up in your bundle.
41
+ - **Opt-in robots.** Omitting `robotVariant` renders *no robot* now. Pass `'default'` or import from `robot-toast/robots` to bring one back.
42
+ - **Mobile drag actually works.** `touch-action: none`, cached rects to kill layout thrash, and **swipe-to-dismiss**.
43
+ - **`toast.promise()`** β€” attach loading/success/error toasts to any promise.
44
+ - **React subpath.** `useRobotToast()` + `useToastOnMount()` as optional ergonomic bindings.
45
+ - **ARIA roles.** `role="alert"` for `error`/`warning`, `role="status"` elsewhere, plus `aria-atomic` and a labeled close button.
46
+
47
+ Upgrading from v1? See [MIGRATION.md](./MIGRATION.md) for the five-minute changeover.
48
+
49
+ ---
50
+
51
+ ## Features
52
+
53
+ | Category | Details |
54
+ |---|---|
55
+ | **Themes** | `light` Β· `dark` Β· `colored` |
56
+ | **Types** | `default` Β· `info` Β· `success` Β· `warning` Β· `error` |
57
+ | **Transitions** | `bounce` Β· `flip` Β· `zoom` Β· `slide` |
58
+ | **Positions** | `top-left` Β· `top-center` Β· `top-right` Β· `bottom-left` Β· `bottom-center` Β· `bottom-right` |
59
+ | **Robots** | 16 tree-shakeable built-ins β€” import what you use, pass any image path (svg, png, jpg, gif, webp), or skip the robot entirely |
60
+ | **Custom styles** | Pass a `style` object to customize the message bubble however you like |
61
+ | **Drag & drop** | Full XY drag with viewport clamping, swipe-to-dismiss, snap-to-edge on release |
62
+ | **Typewriter effect** | Characters appear one by one β€” configurable speed or instant |
63
+ | **Multi-toast** | Configurable `limit` for simultaneous toasts; excess is auto-queued |
64
+ | **Progress bar** | Countdown bar β€” show or hide it |
65
+ | **Pause on hover** | Timer pauses when you hover over the toast |
66
+ | **Pause on focus loss** | Timer pauses when the browser tab loses focus |
67
+ | **Promise helper** | `toast.promise(p, { loading, success, error })` |
68
+ | **React hook** | `useRobotToast()` + `useToastOnMount()` from `robot-toast/react` |
69
+ | **RTL** | Right-to-left layout support |
70
+ | **Newest on top** | Stack new toasts above existing ones |
71
+ | **Auto-close** | Configurable duration, or disable entirely |
72
+ | **Accessibility** | `role="alert"` / `role="status"`, `aria-live`, `aria-atomic`, labeled dismiss button |
73
+ | **SSR-safe** | All DOM access is guarded β€” safe for Next.js, Nuxt, etc. |
74
+ | **Zero dependencies** | Pure TypeScript β€” ESM + CJS builds, tree-shakeable |
75
+
76
+ ---
77
+
78
+ ## Installation
79
+
80
+ ```bash
81
+ npm install robot-toast
82
+ ```
83
+
84
+ ## Quick Start
85
+
86
+ ```ts
87
+ import { toast } from 'robot-toast';
88
+
89
+ // Simple string β€” no robot by default in v2
90
+ toast('Hello πŸ€–');
91
+
92
+ // With options
93
+ toast({
94
+ message: 'Operation successful!',
95
+ type: 'success',
96
+ theme: 'dark',
97
+ position: 'top-right',
98
+ });
99
+ ```
100
+
101
+ ### Add a robot
102
+
103
+ Robots are opt-in. Import the one you want from the `robot-toast/robots` subpath β€” bundlers only include what you import:
104
+
105
+ ```ts
106
+ import { toast } from 'robot-toast';
107
+ import { wave, success, error } from 'robot-toast/robots';
108
+
109
+ toast({ message: 'Hi!', robotVariant: wave });
110
+ toast({ message: 'Saved!', robotVariant: success, type: 'success' });
111
+ toast({ message: 'Failed', robotVariant: error, type: 'error' });
112
+ ```
113
+
114
+ Prefer the built-in inline SVG with no extra import?
115
+
116
+ ```ts
117
+ toast({ message: 'Hello', robotVariant: 'default' });
118
+ ```
119
+
120
+ ## Promise lifecycle
121
+
122
+ ```ts
123
+ toast.promise(fetch('/api/save').then(r => r.json()), {
124
+ loading: 'Saving…',
125
+ success: (data) => `Saved as ${data.name}`,
126
+ error: (err) => `Failed: ${err.message}`,
127
+ });
128
+ ```
129
+
130
+ The `success` and `error` fields accept a string, a function of the resolved/rejected value, or a partial options object. The original promise's resolution value passes through unchanged β€” `await toast.promise(...)` still gives you the data.
131
+
132
+ ## React bindings
133
+
134
+ ```tsx
135
+ import { useRobotToast, useToastOnMount } from 'robot-toast/react';
136
+
137
+ function SaveButton() {
138
+ const toast = useRobotToast();
139
+ return <button onClick={() => toast.success('Saved!')}>Save</button>;
140
+ }
141
+
142
+ function LoadingBanner() {
143
+ // Fires on mount, auto-closes on unmount
144
+ useToastOnMount({ message: 'Fetching…', autoClose: false });
145
+ return null;
146
+ }
147
+ ```
148
+
149
+ React is an **optional** peer dependency β€” non-React users aren't affected.
150
+
151
+ ## Close Programmatically
152
+
153
+ ```ts
154
+ // Close a specific toast by id
155
+ const id = toast('Working…');
156
+ toast.closeById(id);
157
+
158
+ // Close all toasts at once
159
+ toast.closeAll();
160
+ ```
161
+
162
+ ---
163
+ ## All Options at a Glance
164
+
165
+ A single `toast()` call using **every available option** so you can see the full API in one place:
166
+
167
+ ```ts
168
+ import { toast } from 'robot-toast';
169
+ import { wave } from 'robot-toast/robots';
170
+
171
+ toast({
172
+ // ─── Content ───────────────────────────────────────────
173
+ message: 'This is the full kitchen-sink example!',
174
+
175
+ // ─── Appearance ────────────────────────────────────────
176
+ type: 'success', // 'default' | 'info' | 'success' | 'warning' | 'error'
177
+ theme: 'dark', // 'light' | 'dark' | 'colored'
178
+ transition: 'bounce', // 'bounce' | 'flip' | 'zoom' | 'slide'
179
+ position: 'bottom-right', // 'top-left' | 'top-center' | 'top-right'
180
+ // 'bottom-left' | 'bottom-center' | 'bottom-right'
181
+
182
+ // ─── Robot ─────────────────────────────────────────────
183
+ // Omit (or '' / 'none') to hide. Use 'default' for the inline built-in SVG.
184
+ // For a built-in variant, import from 'robot-toast/robots' and pass the value.
185
+ // Custom image: pass any path with svg/png/jpg/jpeg/gif/webp extension.
186
+ robotVariant: wave,
187
+ nearScreen: true, // true = robot near screen edge, false = inner side
188
+
189
+ // ─── Timing ────────────────────────────────────────────
190
+ autoClose: 5000, // milliseconds, or false to disable auto-close
191
+ typeSpeed: 30, // ms per character (0 = instant, no typing effect)
192
+
193
+ // ─── Behaviour ─────────────────────────────────────────
194
+ hideProgressBar: false, // true to hide the countdown bar
195
+ draggable: true, // allow drag & drop; flick horizontally to dismiss
196
+ pauseOnHover: true, // pause countdown on mouse hover
197
+ pauseOnFocusLoss: true, // pause countdown when tab loses focus
198
+ rtl: false, // right-to-left layout
199
+
200
+ // ─── Multi-toast ───────────────────────────────────────
201
+ limit: 0, // max visible toasts (0 = unlimited, excess is queued)
202
+ newestOnTop: false, // stack new toasts above older ones
203
+
204
+ // ─── Custom Inline Styles ─────────────────────────────
205
+ style: {
206
+ background: 'linear-gradient(135deg, #667eea, #764ba2)',
207
+ color: '#fff',
208
+ borderRadius: '16px',
209
+ fontFamily: 'monospace',
210
+ },
211
+
212
+ // ─── Callbacks ─────────────────────────────────────────
213
+ onOpen: () => console.log('Toast appeared!'),
214
+ onClose: () => console.log('Toast dismissed!'),
215
+ });
216
+ ```
217
+
218
+ ### Type Shorthands
219
+
220
+ ```ts
221
+ // These set the `type` automatically β€” you can also pass a full options object
222
+ toast.success('Saved!');
223
+ toast.error('Something went wrong');
224
+ toast.info('Did you know…');
225
+ toast.warning('Check your input');
226
+
227
+ // With additional options
228
+ import { success } from 'robot-toast/robots';
229
+ toast.success({ message: 'Deployed!', theme: 'colored', position: 'top-center', robotVariant: success });
230
+ ```
231
+
232
+ ---
233
+ ## Options
234
+
235
+ | Option | Type | Default | Description |
236
+ |---|---|---|---|
237
+ | `message` | `string` | *required* | The text to display |
238
+ | `autoClose` | `number \| false` | `5000` | Auto-close after ms. `false` = stays until dismissed |
239
+ | `position` | `string` | `'bottom-right'` | One of the 6 position presets (see above) |
240
+ | `type` | `string` | `'default'` | `default` Β· `info` Β· `success` Β· `warning` Β· `error` |
241
+ | `theme` | `string` | `'light'` | `light` Β· `dark` Β· `colored` |
242
+ | `transition` | `string` | `'bounce'` | `bounce` Β· `flip` Β· `zoom` Β· `slide` |
243
+ | `style` | `Record<string, string \| number>` | β€” | Inline styles applied directly to the message bubble |
244
+ | `typeSpeed` | `number` | `30` | Typing speed in ms per character. `0` = instant |
245
+ | `robotVariant` | `string` | *hidden* | Data URL from `robot-toast/robots`, `'default'` for built-in SVG, image path, or omit for no robot |
246
+ | `hideProgressBar` | `boolean` | `false` | Hide the countdown progress bar |
247
+ | `draggable` | `boolean` | `true` | Allow the user to drag the toast; horizontal swipe dismisses |
248
+ | `nearScreen` | `boolean` | `true` | `true` = robot near screen edge; `false` = robot on the inner side |
249
+ | `pauseOnHover` | `boolean` | `true` | Pause countdown while the cursor is over the toast |
250
+ | `pauseOnFocusLoss` | `boolean` | `true` | Pause countdown when the browser tab loses focus |
251
+ | `rtl` | `boolean` | `false` | Right-to-left layout |
252
+ | `limit` | `number` | `0` | Max toasts visible at once. `0` = unlimited. Excess is queued |
253
+ | `newestOnTop` | `boolean` | `false` | Stack newest toasts above older ones |
254
+ | `onOpen` | `() => void` | β€” | Callback fired when the toast finishes its entrance |
255
+ | `onClose` | `() => void` | β€” | Callback fired after the toast fully exits |
256
+
257
+ ---
258
+
259
+ ## Built-in Robots
260
+
261
+ All 16 robots are importable from `robot-toast/robots`. Each is a pre-encoded data URL β€” no network fetch, no external files, and bundlers drop the ones you don't use:
262
+
263
+ ```ts
264
+ import {
265
+ wave, base, base2, success, error,
266
+ angry, angry2, shock, think, search,
267
+ loading, sleep, headPalm, typing,
268
+ validation, validation2,
269
+ } from 'robot-toast/robots';
270
+ ```
271
+
272
+ > v1 β†’ v2 renames: `head-palm` β†’ `headPalm`, `type` β†’ `typing` (the dash isn't a valid identifier; `type` clashes with TypeScript's type-only import syntax).
273
+
274
+ For guaranteed per-variant tree-shaking, you can also import from the direct subpath:
275
+
276
+ ```ts
277
+ import { wave } from 'robot-toast/robots/wave';
278
+ ```
279
+
280
+ ### Custom Robot Image
281
+
282
+ Point to any image accessible in your app:
283
+
284
+ ```ts
285
+ toast({
286
+ message: 'Custom bot!',
287
+ robotVariant: '/images/my-robot.png',
288
+ });
289
+ ```
290
+
291
+ Supported formats: **svg, png, jpg, jpeg, gif, webp**. Failed loads fall back to the built-in default SVG. Omit `robotVariant` (or pass `''` / `'none'`) to hide the robot entirely.
292
+
293
+ ---
294
+
295
+ ## Themes & Custom Styles
296
+
297
+ ### Built-in Themes
298
+
299
+ ```ts
300
+ toast({ message: 'Light mode', theme: 'light' });
301
+ toast({ message: 'Dark mode', theme: 'dark' });
302
+ toast({ message: 'Colored', theme: 'colored', type: 'success' });
303
+ ```
304
+
305
+ ### Custom Inline Styles
306
+
307
+ Use the `style` option to fully customize the message bubble:
308
+
309
+ ```ts
310
+ toast({
311
+ message: 'Fully custom look',
312
+ style: {
313
+ background: 'linear-gradient(135deg, #667eea, #764ba2)',
314
+ color: '#fff',
315
+ borderRadius: '16px',
316
+ fontFamily: 'monospace',
317
+ },
318
+ });
319
+ ```
320
+
321
+ ---
322
+
323
+ ## Transitions
324
+
325
+ ```ts
326
+ toast({ message: 'Bounce!', transition: 'bounce' });
327
+ toast({ message: 'Flip!', transition: 'flip' });
328
+ toast({ message: 'Zoom!', transition: 'zoom' });
329
+ toast({ message: 'Slide!', transition: 'slide' });
330
+ ```
331
+
332
+ ---
333
+
334
+ ## Drag & Swipe-to-Dismiss
335
+
336
+ When `draggable` is on (default):
337
+
338
+ - **Drag anywhere** on the toast to move it. On release it snaps to the nearest horizontal edge.
339
+ - **Swipe horizontally** past ~50% of the toast's width, or flick quickly (>0.5 px/ms with >60 px travel), to dismiss.
340
+ - Mobile-friendly: `touch-action: none` prevents the browser from fighting the drag, and rect dimensions are cached on pointerdown to eliminate layout-thrash jank.
341
+
342
+ ---
343
+
344
+ ## Accessibility
345
+
346
+ Every toast ships with the right ARIA hooks out of the box:
347
+
348
+ - `error` and `warning` toasts get `role="alert"` + `aria-live="assertive"` β€” screen readers announce them immediately.
349
+ - All other types get `role="status"` + `aria-live="polite"` β€” announced when the user is idle.
350
+ - `aria-atomic="true"` ensures the full message is re-announced on updates.
351
+ - The close button has `type="button"` + `aria-label="Dismiss notification"`.
352
+
353
+ ---
354
+
355
+ ## Framework Examples
356
+
357
+ ### React / Next.js
358
+
359
+ ```tsx
360
+ 'use client';
361
+ import { useRobotToast } from 'robot-toast/react';
362
+ import { wave } from 'robot-toast/robots';
363
+ import { useEffect } from 'react';
364
+
365
+ export default function App() {
366
+ const toast = useRobotToast();
367
+
368
+ useEffect(() => {
369
+ toast({
370
+ message: 'Welcome!',
371
+ type: 'success',
372
+ theme: 'dark',
373
+ position: 'top-right',
374
+ robotVariant: wave,
375
+ transition: 'bounce',
376
+ });
377
+ }, [toast]);
378
+
379
+ return <div>My App</div>;
380
+ }
381
+ ```