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/MIGRATION.md ADDED
@@ -0,0 +1,192 @@
1
+ # Migrating from v1.x → v2.0
2
+
3
+ v2.0 is a **breaking** release focused on bundle size. The core bundle dropped
4
+ from 61 KB to 39 KB, and users who don't need the built-in robot library don't
5
+ pay for it at all.
6
+
7
+ **If you don't use `robotVariant` with a built-in name, no changes are needed.**
8
+
9
+ ---
10
+
11
+ ## What changed
12
+
13
+ ### 1. Built-in robots moved to their own subpath
14
+
15
+ Before (v1):
16
+
17
+ ```js
18
+ import { toast } from 'robot-toast';
19
+ toast({ message: 'Hi!', robotVariant: 'wave' });
20
+ ```
21
+
22
+ After (v2):
23
+
24
+ ```js
25
+ import { toast } from 'robot-toast';
26
+ import { wave } from 'robot-toast/robots';
27
+ toast({ message: 'Hi!', robotVariant: wave });
28
+ ```
29
+
30
+ You now import each robot as a data URL and pass it directly. Only the
31
+ variants you import end up in your bundle. Typical savings: 20–50 KB depending
32
+ on which variants you used to reference by string name.
33
+
34
+ For maximum guaranteed tree-shaking, you can import from the per-variant
35
+ subpath:
36
+
37
+ ```js
38
+ import { wave } from 'robot-toast/robots/wave';
39
+ ```
40
+
41
+ ### 2. Two variant names got renamed
42
+
43
+ Dashed and ambiguous identifiers don't work as named imports. They've been
44
+ renamed:
45
+
46
+ | v1 (string) | v2 (import) |
47
+ |----------------|----------------|
48
+ | `'head-palm'` | `headPalm` |
49
+ | `'type'` | `typing` |
50
+
51
+ ```js
52
+ // v1
53
+ toast({ message: '…', robotVariant: 'head-palm' });
54
+ toast({ message: '…', robotVariant: 'type' });
55
+
56
+ // v2
57
+ import { headPalm, typing } from 'robot-toast/robots';
58
+ toast({ message: '…', robotVariant: headPalm });
59
+ toast({ message: '…', robotVariant: typing });
60
+ ```
61
+
62
+ All 14 other variants (`wave`, `base`, `base2`, `success`, `error`, `angry`,
63
+ `angry2`, `shock`, `think`, `search`, `loading`, `sleep`, `validation`,
64
+ `validation2`) keep the same name — just import them.
65
+
66
+ ### 3. `ROBOT_IMAGES` export removed
67
+
68
+ If you were reading from the exported `ROBOT_IMAGES` object directly, import
69
+ the individual variants instead.
70
+
71
+ ```js
72
+ // v1
73
+ import { ROBOT_IMAGES } from 'robot-toast';
74
+ const wave = ROBOT_IMAGES.wave;
75
+
76
+ // v2
77
+ import { wave } from 'robot-toast/robots';
78
+ ```
79
+
80
+ ### 4. `robotVariant` is now opt-in
81
+
82
+ **The biggest behavior change.** In v1, omitting `robotVariant` rendered the
83
+ default robot. In v2, omitting it renders **no robot**.
84
+
85
+ | Value | v1 behavior | v2 behavior |
86
+ |------------------------|-----------------|-----------------|
87
+ | *(omitted)* | default robot | **hidden** |
88
+ | `''` | default robot | **hidden** |
89
+ | `'none'` | hidden | hidden |
90
+ | `'default'` | hidden (as name)| **default robot** |
91
+ | `'wave'` / `'error'` … | built-in lookup | **hidden** |
92
+ | data URL | treated as path | `<img>` rendered |
93
+ | `'/path.png'` | `<img>` rendered| `<img>` rendered |
94
+ | unrecognized string | default robot | **hidden** |
95
+
96
+ **Migration:**
97
+
98
+ ```js
99
+ // v1 — implicit default
100
+ toast({ message: 'Hi' });
101
+
102
+ // v2 — explicit opt-in
103
+ toast({ message: 'Hi', robotVariant: 'default' });
104
+
105
+ // v1 — named built-in
106
+ toast({ message: 'Hi', robotVariant: 'wave' });
107
+
108
+ // v2 — imported data URL
109
+ import { wave } from 'robot-toast/robots';
110
+ toast({ message: 'Hi', robotVariant: wave });
111
+ ```
112
+
113
+ Why the change: the old default pulled every user into bundling the
114
+ built-in SVG even when they never intended a robot. Explicit opt-in plus the
115
+ tree-shakeable `robots` subpath gives you full control over what ships.
116
+
117
+ ### 5. Custom image paths still work unchanged
118
+
119
+ ```js
120
+ toast({ message: 'Hi', robotVariant: '/my-robot.png' }); // unchanged, still works
121
+ ```
122
+
123
+ ---
124
+
125
+ ## What's new
126
+
127
+ ### React hook
128
+
129
+ ```jsx
130
+ import { useRobotToast, useToastOnMount } from 'robot-toast/react';
131
+
132
+ function SaveButton() {
133
+ const toast = useRobotToast();
134
+ return <button onClick={() => toast.success('Saved!')}>Save</button>;
135
+ }
136
+
137
+ function LoadingBanner() {
138
+ useToastOnMount({ message: 'Fetching…', autoClose: false });
139
+ return null;
140
+ }
141
+ ```
142
+
143
+ React is an optional peer dependency — non-React users are unaffected.
144
+
145
+ We deliberately skipped the `<RobotToastProvider>` pattern. The toast manager
146
+ is a module-level singleton, so a provider wouldn't carry any state Context
147
+ doesn't already solve in user code.
148
+
149
+ ### `toast.promise()`
150
+
151
+ ```js
152
+ toast.promise(fetch('/api/save'), {
153
+ loading: 'Saving…',
154
+ success: 'Saved!',
155
+ error: 'Save failed',
156
+ });
157
+ ```
158
+
159
+ Shows a persistent loading toast, then swaps it for a typed success or error
160
+ toast when the promise settles. Callbacks are supported for both `success` and
161
+ `error` to derive the final message from the resolved/rejected value.
162
+
163
+ ### Mobile drag fixes
164
+
165
+ - `touch-action: none` prevents page-scroll fighting the drag.
166
+ - Pointer-move no longer calls `getBoundingClientRect()` every frame —
167
+ wrapper dimensions are cached on pointerdown.
168
+ - Swipe-to-dismiss: drag horizontally past ~50% of the toast's width (or flick
169
+ quickly) to dismiss.
170
+
171
+ ### ARIA
172
+
173
+ - `role="alert"` + `aria-live="assertive"` on `error` and `warning` toasts.
174
+ - `role="status"` + `aria-live="polite"` on everything else.
175
+ - `aria-atomic="true"` on all toasts.
176
+ - `aria-label="Dismiss notification"` + `type="button"` on the close button.
177
+
178
+ ---
179
+
180
+ ## Quick upgrade checklist
181
+
182
+ 1. `npm install robot-toast@^2.0.0`
183
+ 2. **Grep every `toast(…)` call without a `robotVariant`.** If you want the
184
+ default robot to keep appearing, add `robotVariant: 'default'` explicitly.
185
+ Otherwise the toast now shows without a robot.
186
+ 3. Search your code for `robotVariant: '…'` (string literal). For each hit:
187
+ - If it's a built-in name (`'wave'`, `'error'`, etc.): add an import from
188
+ `robot-toast/robots` and replace the string with the imported identifier.
189
+ - If the string was `'head-palm'`, rename to `headPalm`.
190
+ - If the string was `'type'`, rename to `typing`.
191
+ 4. If you used `ROBOT_IMAGES` directly, switch to per-variant imports.
192
+ 5. Custom image paths (`'/foo.png'`) and `'none'` behave identically to v1.