robot-toast 2.0.1 → 2.1.2
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 +113 -313
- package/dist/index.d.mts +16 -1
- package/dist/index.d.ts +16 -1
- package/dist/index.js +78 -27
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +78 -27
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,24 +1,11 @@
|
|
|
1
1
|
# 🤖 robot-toast
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Lightweight toast notifications with an animated robot companion. 16 tree-shakeable robots, fully draggable, multiple themes, and optional React hook.
|
|
4
4
|
|
|
5
5
|
<p align="left">
|
|
6
|
-
<a href="https://
|
|
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>
|
|
6
|
+
<a href="https://robot-toast-client.vercel.app/" style="color:#e53935; font-weight:600; text-decoration:none;">Demo & Playground →</a>
|
|
21
7
|
</p>
|
|
8
|
+
|
|
22
9
|
<p align="center">
|
|
23
10
|
<a href="https://www.npmjs.com/package/robot-toast">
|
|
24
11
|
<img src="https://img.shields.io/npm/v/robot-toast?style=flat-square" />
|
|
@@ -27,385 +14,198 @@ A lightweight, zero-dependency, framework-agnostic toast notification library fe
|
|
|
27
14
|
<img src="https://img.shields.io/bundlephobia/minzip/robot-toast?style=flat-square" />
|
|
28
15
|
</p>
|
|
29
16
|
|
|
30
|
-
|
|
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>
|
|
17
|
+
> **[GIF/video of robot in action]** ← [Add robot demo GIF here]
|
|
35
18
|
|
|
36
|
-
|
|
19
|
+
## Install
|
|
37
20
|
|
|
38
|
-
|
|
21
|
+
```bash
|
|
22
|
+
npm install robot-toast
|
|
23
|
+
```
|
|
39
24
|
|
|
40
|
-
|
|
41
|
-
- **Opt-in robots.** Omitting `robotVariant` renders *no robot* now. Pass `'default'` or import from `robot-toast/robots` to bring one back.
|
|
42
|
-
- **Inline buttons.** Pass a `buttons` array for Undo / Retry / Cancel-style inline CTAs — rendered in array order, optional `className` per button for custom visual hierarchy.
|
|
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.
|
|
25
|
+
## Quick Start
|
|
46
26
|
|
|
47
|
-
|
|
27
|
+
```ts
|
|
28
|
+
import { toast } from 'robot-toast';
|
|
29
|
+
import { wave } from 'robot-toast/robots';
|
|
48
30
|
|
|
49
|
-
|
|
31
|
+
toast({ message: 'Hello! 🤖', robotVariant: wave });
|
|
32
|
+
toast.success('Operation successful!');
|
|
33
|
+
toast.error('Something went wrong');
|
|
34
|
+
```
|
|
50
35
|
|
|
51
|
-
|
|
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; snaps to the nearest screen 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 |
|
|
36
|
+
**Explore all features & interactive demos →** [Full Playground](https://robot-toast-client.vercel.app/features)
|
|
75
37
|
|
|
76
|
-
|
|
38
|
+
## Features at a Glance
|
|
77
39
|
|
|
78
|
-
|
|
40
|
+
| Robots | Layout | Styling | Behavior |
|
|
41
|
+
|--------|--------|---------|----------|
|
|
42
|
+
| 16 built-in variants | 6 position options | 3 themes | Fully draggable |
|
|
43
|
+
| Tree-shakeable imports | Auto-queuing | Custom inline styles | Typewriter effect |
|
|
44
|
+
| Custom images (SVG/PNG) | Progress bar | Transitions (4 types) | Promise helpers |
|
|
45
|
+
| | | | React hook included |
|
|
79
46
|
|
|
80
|
-
|
|
81
|
-
npm install robot-toast
|
|
82
|
-
```
|
|
47
|
+
---
|
|
83
48
|
|
|
84
|
-
##
|
|
49
|
+
## Full API Reference
|
|
50
|
+
|
|
51
|
+
### Basic Usage
|
|
85
52
|
|
|
86
53
|
```ts
|
|
87
54
|
import { toast } from 'robot-toast';
|
|
55
|
+
import { wave, success, error } from 'robot-toast/robots';
|
|
56
|
+
|
|
57
|
+
toast('Simple notification');
|
|
58
|
+
toast({ message: 'With options', type: 'success', robotVariant: wave });
|
|
59
|
+
toast.success('Shorthand');
|
|
60
|
+
```
|
|
88
61
|
|
|
89
|
-
|
|
90
|
-
toast('Hello 🤖');
|
|
62
|
+
### All Options
|
|
91
63
|
|
|
92
|
-
|
|
64
|
+
```ts
|
|
93
65
|
toast({
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
66
|
+
// Content
|
|
67
|
+
message: 'Notification text',
|
|
68
|
+
|
|
69
|
+
// Appearance
|
|
70
|
+
type: 'default' | 'info' | 'success' | 'warning' | 'error',
|
|
71
|
+
theme: 'light' | 'dark' | 'colored',
|
|
72
|
+
transition: 'bounce' | 'flip' | 'zoom' | 'slide',
|
|
73
|
+
position: 'top-left' | 'top-center' | 'top-right' |
|
|
74
|
+
'bottom-left' | 'bottom-center' | 'bottom-right',
|
|
75
|
+
|
|
76
|
+
// Robot & Styling
|
|
77
|
+
robotVariant: wave | base | success | error | '...' | 'default' | '/path.svg',
|
|
78
|
+
nearScreen: true,
|
|
79
|
+
style: { background: '...', color: '...' },
|
|
80
|
+
|
|
81
|
+
// Timing & Behavior
|
|
82
|
+
autoClose: 5000 | false,
|
|
83
|
+
typeSpeed: 30,
|
|
84
|
+
hideProgressBar: false,
|
|
85
|
+
draggable: true,
|
|
86
|
+
pauseOnHover: true,
|
|
87
|
+
pauseOnFocusLoss: true,
|
|
88
|
+
rtl: false,
|
|
89
|
+
|
|
90
|
+
// Multi-toast
|
|
91
|
+
limit: 0,
|
|
92
|
+
newestOnTop: false,
|
|
93
|
+
|
|
94
|
+
// Buttons & Callbacks
|
|
95
|
+
buttons: [{ label: 'Undo', onClick: () => {...} }],
|
|
96
|
+
onOpen: () => {...},
|
|
97
|
+
onClose: () => {...},
|
|
98
98
|
});
|
|
99
99
|
```
|
|
100
100
|
|
|
101
|
-
###
|
|
101
|
+
### Built-in Robots
|
|
102
102
|
|
|
103
|
-
|
|
103
|
+
Import any of the 16 built-in robots from `robot-toast/robots`:
|
|
104
104
|
|
|
105
105
|
```ts
|
|
106
|
-
import {
|
|
107
|
-
|
|
106
|
+
import {
|
|
107
|
+
wave, base, base2, success, error,
|
|
108
|
+
angry, angry2, shock, think, search,
|
|
109
|
+
loading, sleep, headPalm, typing,
|
|
110
|
+
validation, validation2,
|
|
111
|
+
} from 'robot-toast/robots';
|
|
108
112
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
toast({ message: 'Failed', robotVariant: error, type: 'error' });
|
|
113
|
+
// Or import directly for guaranteed tree-shaking:
|
|
114
|
+
import { wave } from 'robot-toast/robots/wave';
|
|
112
115
|
```
|
|
113
116
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
```ts
|
|
117
|
-
toast({ message: 'Hello', robotVariant: 'default' });
|
|
118
|
-
```
|
|
117
|
+
Custom images are supported: pass any SVG/PNG/JPG/GIF/WebP path to `robotVariant`.
|
|
119
118
|
|
|
120
|
-
|
|
119
|
+
### Inline Buttons
|
|
121
120
|
|
|
122
|
-
Add
|
|
121
|
+
Add undo/confirm/cancel style buttons to toasts:
|
|
123
122
|
|
|
124
123
|
```ts
|
|
125
|
-
// Undo pattern — one button
|
|
126
124
|
toast({
|
|
127
125
|
message: 'File deleted',
|
|
128
126
|
buttons: [
|
|
129
127
|
{ label: 'Undo', onClick: () => restoreFile() },
|
|
130
|
-
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
// Confirm + cancel — cancel on the left, primary CTA on the right
|
|
134
|
-
toast({
|
|
135
|
-
message: 'Send this email to 1,200 people?',
|
|
136
|
-
buttons: [
|
|
137
|
-
{ label: 'Cancel', onClick: () => abort() },
|
|
138
|
-
{ label: 'Send', onClick: () => send(), className: 'my-primary' },
|
|
128
|
+
{ label: 'Keep', onClick: () => {}, style: { color: 'gray' } },
|
|
139
129
|
],
|
|
140
130
|
});
|
|
141
131
|
```
|
|
142
132
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
All buttons get a neutral outline style by default. Pass a custom `className` on any button to override — e.g. mark one as a filled CTA via your own CSS, or use Tailwind utility classes directly.
|
|
133
|
+
### Promise Lifecycle
|
|
146
134
|
|
|
147
|
-
|
|
135
|
+
Attach loading/success/error messages to any promise:
|
|
148
136
|
|
|
149
137
|
```ts
|
|
150
138
|
toast.promise(fetch('/api/save').then(r => r.json()), {
|
|
151
139
|
loading: 'Saving…',
|
|
152
140
|
success: (data) => `Saved as ${data.name}`,
|
|
153
|
-
error:
|
|
141
|
+
error: (err) => `Failed: ${err.message}`,
|
|
154
142
|
});
|
|
155
143
|
```
|
|
156
144
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
## React bindings
|
|
145
|
+
### React Bindings
|
|
160
146
|
|
|
161
147
|
```tsx
|
|
162
148
|
import { useRobotToast, useToastOnMount } from 'robot-toast/react';
|
|
163
149
|
|
|
164
|
-
function
|
|
150
|
+
function App() {
|
|
165
151
|
const toast = useRobotToast();
|
|
166
152
|
return <button onClick={() => toast.success('Saved!')}>Save</button>;
|
|
167
153
|
}
|
|
168
154
|
|
|
169
|
-
function
|
|
170
|
-
|
|
171
|
-
useToastOnMount({ message: 'Fetching…', autoClose: false });
|
|
155
|
+
function InitBanner() {
|
|
156
|
+
useToastOnMount({ message: 'Welcome!', autoClose: false });
|
|
172
157
|
return null;
|
|
173
158
|
}
|
|
174
159
|
```
|
|
175
160
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
## Close Programmatically
|
|
161
|
+
### Programmatic Control
|
|
179
162
|
|
|
180
163
|
```ts
|
|
181
|
-
// Close a specific toast by id
|
|
182
164
|
const id = toast('Working…');
|
|
183
165
|
toast.closeById(id);
|
|
184
|
-
|
|
185
|
-
// Close all toasts at once
|
|
186
166
|
toast.closeAll();
|
|
187
167
|
```
|
|
188
168
|
|
|
189
|
-
|
|
190
|
-
## All Options at a Glance
|
|
191
|
-
|
|
192
|
-
A single `toast()` call using **every available option** so you can see the full API in one place:
|
|
193
|
-
|
|
194
|
-
```ts
|
|
195
|
-
import { toast } from 'robot-toast';
|
|
196
|
-
import { wave } from 'robot-toast/robots';
|
|
197
|
-
|
|
198
|
-
toast({
|
|
199
|
-
// ─── Content ───────────────────────────────────────────
|
|
200
|
-
message: 'This is the full kitchen-sink example!',
|
|
201
|
-
|
|
202
|
-
// ─── Appearance ────────────────────────────────────────
|
|
203
|
-
type: 'success', // 'default' | 'info' | 'success' | 'warning' | 'error'
|
|
204
|
-
theme: 'dark', // 'light' | 'dark' | 'colored'
|
|
205
|
-
transition: 'bounce', // 'bounce' | 'flip' | 'zoom' | 'slide'
|
|
206
|
-
position: 'bottom-right', // 'top-left' | 'top-center' | 'top-right'
|
|
207
|
-
// 'bottom-left' | 'bottom-center' | 'bottom-right'
|
|
208
|
-
|
|
209
|
-
// ─── Robot ─────────────────────────────────────────────
|
|
210
|
-
// Omit (or '' / 'none') to hide. Use 'default' for the inline built-in SVG.
|
|
211
|
-
// For a built-in variant, import from 'robot-toast/robots' and pass the value.
|
|
212
|
-
// Custom image: pass any path with svg/png/jpg/jpeg/gif/webp extension.
|
|
213
|
-
robotVariant: wave,
|
|
214
|
-
nearScreen: true, // true = robot near screen edge, false = inner side
|
|
215
|
-
|
|
216
|
-
// ─── Timing ────────────────────────────────────────────
|
|
217
|
-
autoClose: 5000, // milliseconds, or false to disable auto-close
|
|
218
|
-
typeSpeed: 30, // ms per character (0 = instant, no typing effect)
|
|
219
|
-
|
|
220
|
-
// ─── Behaviour ─────────────────────────────────────────
|
|
221
|
-
hideProgressBar: false, // true to hide the countdown bar
|
|
222
|
-
draggable: true, // allow drag & drop; snaps to nearest edge on release
|
|
223
|
-
pauseOnHover: true, // pause countdown on mouse hover
|
|
224
|
-
pauseOnFocusLoss: true, // pause countdown when tab loses focus
|
|
225
|
-
rtl: false, // right-to-left layout
|
|
226
|
-
|
|
227
|
-
// ─── Multi-toast ───────────────────────────────────────
|
|
228
|
-
limit: 0, // max visible toasts (0 = unlimited, excess is queued)
|
|
229
|
-
newestOnTop: false, // stack new toasts above older ones
|
|
230
|
-
|
|
231
|
-
// ─── Custom Inline Styles ─────────────────────────────
|
|
232
|
-
style: {
|
|
233
|
-
background: 'linear-gradient(135deg, #667eea, #764ba2)',
|
|
234
|
-
color: '#fff',
|
|
235
|
-
borderRadius: '16px',
|
|
236
|
-
fontFamily: 'monospace',
|
|
237
|
-
},
|
|
238
|
-
|
|
239
|
-
// ─── Callbacks ─────────────────────────────────────────
|
|
240
|
-
onOpen: () => console.log('Toast appeared!'),
|
|
241
|
-
onClose: () => console.log('Toast dismissed!'),
|
|
242
|
-
});
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
### Type Shorthands
|
|
169
|
+
### Themes & Custom Styles
|
|
246
170
|
|
|
247
171
|
```ts
|
|
248
|
-
|
|
249
|
-
toast
|
|
250
|
-
toast
|
|
251
|
-
|
|
252
|
-
toast.warning('Check your input');
|
|
253
|
-
|
|
254
|
-
// With additional options
|
|
255
|
-
import { success } from 'robot-toast/robots';
|
|
256
|
-
toast.success({ message: 'Deployed!', theme: 'colored', position: 'top-center', robotVariant: success });
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
---
|
|
260
|
-
## Options
|
|
261
|
-
|
|
262
|
-
| Option | Type | Default | Description |
|
|
263
|
-
|---|---|---|---|
|
|
264
|
-
| `message` | `string` | *required* | The text to display |
|
|
265
|
-
| `autoClose` | `number \| false` | `5000` | Auto-close after ms. `false` = stays until dismissed |
|
|
266
|
-
| `position` | `string` | `'bottom-right'` | One of the 6 position presets (see above) |
|
|
267
|
-
| `type` | `string` | `'default'` | `default` · `info` · `success` · `warning` · `error` |
|
|
268
|
-
| `theme` | `string` | `'light'` | `light` · `dark` · `colored` |
|
|
269
|
-
| `transition` | `string` | `'bounce'` | `bounce` · `flip` · `zoom` · `slide` |
|
|
270
|
-
| `style` | `Record<string, string \| number>` | — | Inline styles applied directly to the message bubble |
|
|
271
|
-
| `typeSpeed` | `number` | `30` | Typing speed in ms per character. `0` = instant |
|
|
272
|
-
| `robotVariant` | `string` | *hidden* | Data URL from `robot-toast/robots`, `'default'` for built-in SVG, image path, or omit for no robot |
|
|
273
|
-
| `hideProgressBar` | `boolean` | `false` | Hide the countdown progress bar |
|
|
274
|
-
| `draggable` | `boolean` | `true` | Allow the user to drag the toast; snaps to the nearest edge on release |
|
|
275
|
-
| `nearScreen` | `boolean` | `true` | `true` = robot near screen edge; `false` = robot on the inner side |
|
|
276
|
-
| `pauseOnHover` | `boolean` | `true` | Pause countdown while the cursor is over the toast |
|
|
277
|
-
| `pauseOnFocusLoss` | `boolean` | `true` | Pause countdown when the browser tab loses focus |
|
|
278
|
-
| `rtl` | `boolean` | `false` | Right-to-left layout |
|
|
279
|
-
| `limit` | `number` | `0` | Max toasts visible at once. `0` = unlimited. Excess is queued |
|
|
280
|
-
| `newestOnTop` | `boolean` | `false` | Stack newest toasts above older ones |
|
|
281
|
-
| `buttons` | `Array<{ label: string; onClick: (e: MouseEvent) => void; className?: string }>` | — | Inline buttons rendered in array order. Each click fires `onClick` then closes the toast. |
|
|
282
|
-
| `onOpen` | `() => void` | — | Callback fired when the toast finishes its entrance |
|
|
283
|
-
| `onClose` | `() => void` | — | Callback fired after the toast fully exits |
|
|
284
|
-
|
|
285
|
-
---
|
|
286
|
-
|
|
287
|
-
## Built-in Robots
|
|
288
|
-
|
|
289
|
-
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:
|
|
290
|
-
|
|
291
|
-
```ts
|
|
292
|
-
import {
|
|
293
|
-
wave, base, base2, success, error,
|
|
294
|
-
angry, angry2, shock, think, search,
|
|
295
|
-
loading, sleep, headPalm, typing,
|
|
296
|
-
validation, validation2,
|
|
297
|
-
} from 'robot-toast/robots';
|
|
298
|
-
```
|
|
299
|
-
|
|
300
|
-
> v1 → v2 renames: `head-palm` → `headPalm`, `type` → `typing` (the dash isn't a valid identifier; `type` clashes with TypeScript's type-only import syntax).
|
|
301
|
-
|
|
302
|
-
For guaranteed per-variant tree-shaking, you can also import from the direct subpath:
|
|
303
|
-
|
|
304
|
-
```ts
|
|
305
|
-
import { wave } from 'robot-toast/robots/wave';
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
### Custom Robot Image
|
|
309
|
-
|
|
310
|
-
Point to any image accessible in your app:
|
|
311
|
-
|
|
312
|
-
```ts
|
|
313
|
-
toast({
|
|
314
|
-
message: 'Custom bot!',
|
|
315
|
-
robotVariant: '/images/my-robot.png',
|
|
316
|
-
});
|
|
317
|
-
```
|
|
318
|
-
|
|
319
|
-
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.
|
|
320
|
-
|
|
321
|
-
---
|
|
322
|
-
|
|
323
|
-
## Themes & Custom Styles
|
|
324
|
-
|
|
325
|
-
### Built-in Themes
|
|
326
|
-
|
|
327
|
-
```ts
|
|
328
|
-
toast({ message: 'Light mode', theme: 'light' });
|
|
329
|
-
toast({ message: 'Dark mode', theme: 'dark' });
|
|
330
|
-
toast({ message: 'Colored', theme: 'colored', type: 'success' });
|
|
331
|
-
```
|
|
332
|
-
|
|
333
|
-
### Custom Inline Styles
|
|
334
|
-
|
|
335
|
-
Use the `style` option to fully customize the message bubble:
|
|
336
|
-
|
|
337
|
-
```ts
|
|
338
|
-
toast({
|
|
339
|
-
message: 'Fully custom look',
|
|
172
|
+
toast({ message: 'Light', theme: 'light' });
|
|
173
|
+
toast({ message: 'Dark', theme: 'dark' });
|
|
174
|
+
toast({
|
|
175
|
+
message: 'Custom gradient',
|
|
340
176
|
style: {
|
|
341
|
-
background:
|
|
342
|
-
color:
|
|
177
|
+
background: 'linear-gradient(135deg, #667eea, #764ba2)',
|
|
178
|
+
color: '#fff',
|
|
343
179
|
borderRadius: '16px',
|
|
344
|
-
fontFamily: 'monospace',
|
|
345
180
|
},
|
|
346
181
|
});
|
|
347
182
|
```
|
|
348
183
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
## Transitions
|
|
352
|
-
|
|
353
|
-
```ts
|
|
354
|
-
toast({ message: 'Bounce!', transition: 'bounce' });
|
|
355
|
-
toast({ message: 'Flip!', transition: 'flip' });
|
|
356
|
-
toast({ message: 'Zoom!', transition: 'zoom' });
|
|
357
|
-
toast({ message: 'Slide!', transition: 'slide' });
|
|
358
|
-
```
|
|
359
|
-
|
|
360
|
-
---
|
|
361
|
-
|
|
362
|
-
## Drag & responsive layout
|
|
363
|
-
|
|
364
|
-
When `draggable` is on (default):
|
|
365
|
-
|
|
366
|
-
- **Drag anywhere** on the toast to move it. On release it snaps to the nearest horizontal edge — including when you drag all the way across the screen.
|
|
367
|
-
- `touch-action: none` prevents the browser from fighting the drag, and rect dimensions are cached on pointerdown to eliminate layout-thrash jank on low-end devices.
|
|
368
|
-
- Use the **close button**, an **action button**, or `toast.closeById()` / `toast.closeAll()` to dismiss programmatically.
|
|
369
|
-
|
|
370
|
-
**On viewports ≤ 600 px** the toast shrinks slightly (tighter gutters, smaller robot, smaller font) but keeps its configured position preset. Drag still works everywhere.
|
|
184
|
+
### Accessibility
|
|
371
185
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
Every toast ships with the right ARIA hooks out of the box:
|
|
377
|
-
|
|
378
|
-
- `error` and `warning` toasts get `role="alert"` + `aria-live="assertive"` — screen readers announce them immediately.
|
|
379
|
-
- All other types get `role="status"` + `aria-live="polite"` — announced when the user is idle.
|
|
380
|
-
- `aria-atomic="true"` ensures the full message is re-announced on updates.
|
|
381
|
-
- The close button has `type="button"` + `aria-label="Dismiss notification"`.
|
|
186
|
+
- `error` / `warning` toasts: `role="alert"` + `aria-live="assertive"`
|
|
187
|
+
- Other types: `role="status"` + `aria-live="polite"`
|
|
188
|
+
- `aria-atomic="true"` ensures full message re-announcement
|
|
189
|
+
- Labeled close button for screen readers
|
|
382
190
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
## Framework Examples
|
|
386
|
-
|
|
387
|
-
### React / Next.js
|
|
191
|
+
### Framework Examples
|
|
388
192
|
|
|
193
|
+
**React / Next.js**
|
|
389
194
|
```tsx
|
|
390
195
|
'use client';
|
|
391
196
|
import { useRobotToast } from 'robot-toast/react';
|
|
392
197
|
import { wave } from 'robot-toast/robots';
|
|
393
|
-
import { useEffect } from 'react';
|
|
394
198
|
|
|
395
199
|
export default function App() {
|
|
396
200
|
const toast = useRobotToast();
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
toast({
|
|
400
|
-
message: '
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
});
|
|
407
|
-
}, [toast]);
|
|
408
|
-
|
|
409
|
-
return <div>My App</div>;
|
|
201
|
+
|
|
202
|
+
return (
|
|
203
|
+
<button onClick={() => toast.success({
|
|
204
|
+
message: 'Deployed!',
|
|
205
|
+
robotVariant: wave
|
|
206
|
+
})}>
|
|
207
|
+
Deploy
|
|
208
|
+
</button>
|
|
209
|
+
);
|
|
410
210
|
}
|
|
411
211
|
```
|
package/dist/index.d.mts
CHANGED
|
@@ -39,8 +39,23 @@ interface ToastButton {
|
|
|
39
39
|
label: string;
|
|
40
40
|
/** Fired before the toast closes. Receives the click event. */
|
|
41
41
|
onClick: (event: MouseEvent) => void;
|
|
42
|
-
/**
|
|
42
|
+
/**
|
|
43
|
+
* Optional CSS class(es) appended to the button element. Use this when you
|
|
44
|
+
* have a stylesheet rule like `.my-primary { background: black; color: white }`
|
|
45
|
+
* defined elsewhere in your app and want to apply it to this button.
|
|
46
|
+
*/
|
|
43
47
|
className?: string;
|
|
48
|
+
/**
|
|
49
|
+
* Optional inline styles applied directly to the button element. Use this
|
|
50
|
+
* when you don't want to add a CSS rule to your stylesheet — pass an object
|
|
51
|
+
* of camelCased properties (or kebab-case keys; both work):
|
|
52
|
+
*
|
|
53
|
+
* style: { background: 'black', color: 'white', borderRadius: '8px' }
|
|
54
|
+
*
|
|
55
|
+
* Takes precedence over className-based rules and over the default neutral
|
|
56
|
+
* (and solo-CTA) button styles.
|
|
57
|
+
*/
|
|
58
|
+
style?: Record<string, string | number>;
|
|
44
59
|
}
|
|
45
60
|
interface RobotToastOptions {
|
|
46
61
|
/** The message text to display in the toast */
|
package/dist/index.d.ts
CHANGED
|
@@ -39,8 +39,23 @@ interface ToastButton {
|
|
|
39
39
|
label: string;
|
|
40
40
|
/** Fired before the toast closes. Receives the click event. */
|
|
41
41
|
onClick: (event: MouseEvent) => void;
|
|
42
|
-
/**
|
|
42
|
+
/**
|
|
43
|
+
* Optional CSS class(es) appended to the button element. Use this when you
|
|
44
|
+
* have a stylesheet rule like `.my-primary { background: black; color: white }`
|
|
45
|
+
* defined elsewhere in your app and want to apply it to this button.
|
|
46
|
+
*/
|
|
43
47
|
className?: string;
|
|
48
|
+
/**
|
|
49
|
+
* Optional inline styles applied directly to the button element. Use this
|
|
50
|
+
* when you don't want to add a CSS rule to your stylesheet — pass an object
|
|
51
|
+
* of camelCased properties (or kebab-case keys; both work):
|
|
52
|
+
*
|
|
53
|
+
* style: { background: 'black', color: 'white', borderRadius: '8px' }
|
|
54
|
+
*
|
|
55
|
+
* Takes precedence over className-based rules and over the default neutral
|
|
56
|
+
* (and solo-CTA) button styles.
|
|
57
|
+
*/
|
|
58
|
+
style?: Record<string, string | number>;
|
|
44
59
|
}
|
|
45
60
|
interface RobotToastOptions {
|
|
46
61
|
/** The message text to display in the toast */
|