ga-toasts 2.0.0 → 2.1.1
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 +68 -8
- package/dist/ga-toasts.css +61 -7
- package/dist/ga-toasts.global.js +1 -555
- package/dist/index.cjs +1117 -1389
- package/dist/index.d.cts +118 -45
- package/dist/index.d.ts +118 -45
- package/dist/index.js +1117 -1390
- package/package.json +20 -6
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ Modern, accessible, **dependency-free** toast notifications for the web.
|
|
|
16
16
|
- 🧵 **Framework-agnostic** — use it in React, Vue, Svelte, plain HTML, or on the server (SSR-safe no-op).
|
|
17
17
|
- 🟦 **First-class TypeScript** — types ship in the box.
|
|
18
18
|
|
|
19
|
-
**Live demo:** https://
|
|
19
|
+
**Live demo:** https://gatoasts.vercel.app/
|
|
20
20
|
|
|
21
21
|
---
|
|
22
22
|
|
|
@@ -207,26 +207,86 @@ const handle: ToastHandle = toast.show(opts);
|
|
|
207
207
|
|
|
208
208
|
---
|
|
209
209
|
|
|
210
|
-
##
|
|
210
|
+
## Configuration & theming
|
|
211
211
|
|
|
212
|
-
|
|
212
|
+
Everything is configurable. Tune the default toaster with `toast.configure(...)` / `toast.theme(...)`, or mint fully **isolated** toasters with `createToaster(config)` — each with its own theme, defaults, icons, and mount root.
|
|
213
213
|
|
|
214
|
-
```
|
|
215
|
-
|
|
214
|
+
```js
|
|
215
|
+
import { toast, createToaster } from 'ga-toasts';
|
|
216
|
+
|
|
217
|
+
// Configure the default (global) toaster:
|
|
218
|
+
toast.configure({
|
|
219
|
+
defaults: { position: 'bottom-center', duration: 6000 },
|
|
220
|
+
durations: { error: 10000, success: 2500 }, // per-type auto-close
|
|
221
|
+
theme: { accent: '#ff5c8a', radius: 8, density: 'compact' },
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
// …or a shorthand for just the theme (tokens or a preset name):
|
|
225
|
+
toast.theme('minimal');
|
|
226
|
+
toast.theme({ preset: 'minimal', accent: '#ff5c8a', progress: 'ring' });
|
|
227
|
+
|
|
228
|
+
// An independent toaster (own theme + defaults + DOM root, e.g. shadow DOM):
|
|
229
|
+
const brandToast = createToaster({
|
|
230
|
+
theme: { accent: brand.primary, radius: 6, font: brand.font },
|
|
231
|
+
defaults: { position: 'top-center' },
|
|
232
|
+
root: document.querySelector('#app'),
|
|
233
|
+
});
|
|
216
234
|
```
|
|
217
235
|
|
|
218
|
-
|
|
236
|
+
### Presets
|
|
237
|
+
|
|
238
|
+
`soft` (default) · `solid` · `minimal` · `sharp` · `material`. Use as `theme: 'minimal'` or `theme: { preset: 'minimal', …overrides }`.
|
|
239
|
+
|
|
240
|
+
### Theme tokens
|
|
241
|
+
|
|
242
|
+
| Token | Type | Notes |
|
|
243
|
+
|---|---|---|
|
|
244
|
+
| `accent` | color | Primary accent (also the `primary` type). |
|
|
245
|
+
| `colors` | `{ [type]: color }` | Per-type accent colors. |
|
|
246
|
+
| `radius` · `width` · `gap` · `edge` | number \| string | Numbers → px. |
|
|
247
|
+
| `font` | string | Font stack. |
|
|
248
|
+
| `density` | `compact` · `comfortable` · `spacious` | Padding + type scale. |
|
|
249
|
+
| `elevation` | `flat` · `raised` · `floating` | Shadow depth. |
|
|
250
|
+
| `surface` | `glass` · `solid` · `outline` | Card background style. |
|
|
251
|
+
| `accentEdge` | number | Colored leading bar width (0 = none). |
|
|
252
|
+
| `progress` | `bar` · `ring` · `none` | Countdown style (`ring` = circular). |
|
|
253
|
+
| `text` · `textSoft` · `textMuted` · `border` · `shadow` · `chip` · `ease` | | Fine-grained overrides. |
|
|
254
|
+
| `dark` | `Partial<ThemeTokens>` | Overrides applied under the dark theme. |
|
|
255
|
+
|
|
256
|
+
Theme tokens are written as scoped CSS custom properties, so **dark mode still wins** where you don't override it.
|
|
257
|
+
|
|
258
|
+
### Escape hatches (total control)
|
|
259
|
+
|
|
260
|
+
```js
|
|
261
|
+
createToaster({
|
|
262
|
+
icons: { success: '<svg>…</svg>', close: '<svg>…</svg>' }, // swap icons (null hides one)
|
|
263
|
+
render: (opts, { id, close }) => myToastElement(opts), // replace the DOM entirely
|
|
264
|
+
injectStyles: false, // headless — ship your own CSS (or import 'ga-toasts/style.css')
|
|
265
|
+
styleNonce: nonce, // strict-CSP nonce on the injected <style>
|
|
266
|
+
stack: { maxVisible: 5, peek: 12, gap: 12, expand: 'always', newestOnTop: true },
|
|
267
|
+
});
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### CSS variables
|
|
271
|
+
|
|
272
|
+
You can also theme purely in CSS — every value is a namespaced `--gat-*` variable:
|
|
219
273
|
|
|
220
274
|
```css
|
|
221
275
|
.ga-toast-container {
|
|
222
276
|
--gat-radius: 12px;
|
|
223
277
|
--gat-width: 420px;
|
|
224
278
|
--gat-success: #10b981;
|
|
225
|
-
--gat-error: #ef4444;
|
|
226
|
-
--gat-info: #3b82f6;
|
|
227
279
|
}
|
|
228
280
|
```
|
|
229
281
|
|
|
282
|
+
### Dark mode
|
|
283
|
+
|
|
284
|
+
Toggle with an attribute or class on any ancestor (or let it follow the OS):
|
|
285
|
+
|
|
286
|
+
```html
|
|
287
|
+
<html data-ga-theme="dark"> <!-- or class="ga-theme-dark" -->
|
|
288
|
+
```
|
|
289
|
+
|
|
230
290
|
---
|
|
231
291
|
|
|
232
292
|
## Accessibility
|
package/dist/ga-toasts.css
CHANGED
|
@@ -14,6 +14,13 @@
|
|
|
14
14
|
--gat-gap: 14px;
|
|
15
15
|
--gat-edge: 22px;
|
|
16
16
|
|
|
17
|
+
/* Density (padding + type scale) and the optional leading accent bar — all
|
|
18
|
+
driven by the theme() token API; these are the comfortable defaults. */
|
|
19
|
+
--gat-pad-y: 12px;
|
|
20
|
+
--gat-pad-x: 16px;
|
|
21
|
+
--gat-font-size: 0.875rem;
|
|
22
|
+
--gat-accent-edge: 0px;
|
|
23
|
+
|
|
17
24
|
--gat-font: "Inter", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
|
|
18
25
|
Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
19
26
|
|
|
@@ -46,8 +53,8 @@
|
|
|
46
53
|
[data-ga-theme="dark"] .ga-toast-container,
|
|
47
54
|
.ga-theme-dark .ga-toast-container,
|
|
48
55
|
.ga-toast-container.ga-theme-dark {
|
|
49
|
-
--gat-surface: rgba(
|
|
50
|
-
--gat-surface-solid: #
|
|
56
|
+
--gat-surface: rgba(30, 34, 44, 0.72);
|
|
57
|
+
--gat-surface-solid: #22262f;
|
|
51
58
|
--gat-border: rgba(255, 255, 255, 0.09);
|
|
52
59
|
--gat-ring: rgba(255, 255, 255, 0.06);
|
|
53
60
|
--gat-highlight: rgba(255, 255, 255, 0.07);
|
|
@@ -130,7 +137,7 @@
|
|
|
130
137
|
flex-direction: row;
|
|
131
138
|
align-items: flex-start;
|
|
132
139
|
gap: 11px;
|
|
133
|
-
padding:
|
|
140
|
+
padding: var(--gat-pad-y, 12px) var(--gat-pad-x, 16px);
|
|
134
141
|
color: var(--gat-text);
|
|
135
142
|
background: var(--gat-surface-solid);
|
|
136
143
|
border: none;
|
|
@@ -147,7 +154,7 @@
|
|
|
147
154
|
box-shadow 0.2s ease;
|
|
148
155
|
will-change: transform, opacity;
|
|
149
156
|
overflow: hidden;
|
|
150
|
-
font-size: 0.875rem;
|
|
157
|
+
font-size: var(--gat-font-size, 0.875rem);
|
|
151
158
|
line-height: 1.5;
|
|
152
159
|
-webkit-font-smoothing: antialiased;
|
|
153
160
|
text-align: start;
|
|
@@ -175,11 +182,38 @@
|
|
|
175
182
|
-webkit-backdrop-filter: blur(16px) saturate(160%);
|
|
176
183
|
}
|
|
177
184
|
|
|
178
|
-
/*
|
|
179
|
-
|
|
185
|
+
/* Outline surface preset — transparent card with a defined hairline edge. */
|
|
186
|
+
.ga-toast-outline {
|
|
187
|
+
background: transparent;
|
|
188
|
+
border: 1px solid var(--gat-border);
|
|
189
|
+
box-shadow: var(--gat-shadow);
|
|
190
|
+
backdrop-filter: none;
|
|
191
|
+
-webkit-backdrop-filter: none;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/* Optional leading accent bar (theme token `accentEdge`; 0 = hidden). Painted
|
|
195
|
+
as an inset pseudo so it never shifts layout or gets clipped oddly. */
|
|
196
|
+
.ga-toast::before {
|
|
197
|
+
content: "";
|
|
198
|
+
position: absolute;
|
|
199
|
+
inset-block: 0;
|
|
200
|
+
inset-inline-start: 0;
|
|
201
|
+
width: var(--gat-accent-edge, 0px);
|
|
202
|
+
background: var(--gat-accent, var(--gat-info));
|
|
203
|
+
pointer-events: none;
|
|
204
|
+
}
|
|
180
205
|
|
|
181
206
|
.ga-toast-hide { pointer-events: none; }
|
|
182
207
|
|
|
208
|
+
/* While a horizontal swipe-to-dismiss is in progress, don't let the drag
|
|
209
|
+
paint a text selection. Text is fully selectable at rest. */
|
|
210
|
+
.ga-toast-swiping,
|
|
211
|
+
.ga-toast-swiping * {
|
|
212
|
+
user-select: none;
|
|
213
|
+
-webkit-user-select: none;
|
|
214
|
+
cursor: grabbing;
|
|
215
|
+
}
|
|
216
|
+
|
|
183
217
|
/* Per-type accent colors. */
|
|
184
218
|
.ga-toast-success { --gat-accent: var(--gat-success); }
|
|
185
219
|
.ga-toast-error { --gat-accent: var(--gat-error); }
|
|
@@ -220,6 +254,26 @@
|
|
|
220
254
|
|
|
221
255
|
.ga-toast-spinner { animation: ga-toast-spin 0.8s linear infinite; }
|
|
222
256
|
|
|
257
|
+
/* ---- Circular countdown ring (theme progress: 'ring') ---- */
|
|
258
|
+
.ga-toast-icon-ring { position: relative; width: 2rem; height: 2rem; margin-top: 0; }
|
|
259
|
+
.ga-toast-icon-ring > svg:not(.ga-toast-ring) { width: 1.1rem; height: 1.1rem; }
|
|
260
|
+
.ga-toast-ring {
|
|
261
|
+
position: absolute;
|
|
262
|
+
inset: 0;
|
|
263
|
+
width: 100% !important;
|
|
264
|
+
height: 100% !important;
|
|
265
|
+
transform: rotate(-90deg); /* start the sweep at 12 o'clock */
|
|
266
|
+
overflow: visible;
|
|
267
|
+
}
|
|
268
|
+
.ga-toast-ring-track { fill: none; stroke: var(--gat-chip); stroke-width: 2.4; }
|
|
269
|
+
.ga-toast-ring-bar {
|
|
270
|
+
fill: none;
|
|
271
|
+
stroke: var(--gat-accent, var(--gat-info));
|
|
272
|
+
stroke-width: 2.4;
|
|
273
|
+
stroke-linecap: round;
|
|
274
|
+
/* stroke-dasharray / -dashoffset are driven inline by the engine's timer. */
|
|
275
|
+
}
|
|
276
|
+
|
|
223
277
|
/* Icons draw themselves in on mount (skipped under reduced motion). */
|
|
224
278
|
@media (prefers-reduced-motion: no-preference) {
|
|
225
279
|
.ga-toast-icon .ga-ic-ring {
|
|
@@ -468,7 +522,7 @@
|
|
|
468
522
|
.ga-toast-xs { padding: 10px 13px; font-size: 0.78rem; }
|
|
469
523
|
.ga-toast-xs .ga-toast-icon svg { width: 1.05rem; height: 1.05rem; }
|
|
470
524
|
.ga-toast-xs .ga-toast-message { font-size: 0.78rem; }
|
|
471
|
-
.ga-toast-sm { padding:
|
|
525
|
+
.ga-toast-sm { padding: 11px 14px; gap: 9px; }
|
|
472
526
|
.ga-toast-lg { padding: 18px 20px; }
|
|
473
527
|
.ga-toast-lg .ga-toast-title { font-size: 1rem; }
|
|
474
528
|
.ga-toast-lg .ga-toast-message { font-size: 0.95rem; }
|