@dennykuo/glass-toast 0.1.0 → 0.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/CHANGELOG.md +44 -0
- package/README.md +142 -76
- package/README.zh-TW.md +229 -0
- package/dist/auto.d.cts +1 -0
- package/dist/auto.js +2 -3
- package/dist/glass-toast.css +1 -1
- package/dist/glass-toast.css.d.ts +1 -0
- package/dist/glass-toast.js +1 -2
- package/dist/glass-toast.umd.cjs +2 -1
- package/dist/glass-toast.umd.js +2 -0
- package/dist/icons.d.cts +7 -0
- package/dist/index.d.cts +1 -0
- package/dist/toast-GM0D-R2d.js +312 -0
- package/dist/toast.d.cts +97 -0
- package/dist/toast.d.ts +11 -4
- package/package.json +38 -18
- package/dist/toast-Bh3vjjkJ.js +0 -237
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.2 (2026-11-15)
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Pass an open native `dialog` to show and announce a toast inside it. Closing the dialog clears its toasts.
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- Retry actions run once at a time. Async actions keep the toast open while pending and allow a retry after failure.
|
|
12
|
+
- Toast stacks scroll on short screens so older actions and close buttons remain reachable.
|
|
13
|
+
- Non-finite durations use the default, and large durations are capped at the browser timer limit.
|
|
14
|
+
- Calling `show()` without a DOM returns a no-op dismiss function.
|
|
15
|
+
- The default jsDelivr link serves a browser JavaScript file while CommonJS keeps its existing entry.
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- Pages deploys after a clean install from npm and verifies the live docs, CDN examples, and demo after deployment.
|
|
20
|
+
|
|
21
|
+
## 0.1.1 (2026-11-14)
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- Added a [Traditional Chinese documentation site](https://dennykuo.github.io/glass-toast/) and an [interactive demo](https://dennykuo.github.io/glass-toast/demo.html), with links from both READMEs.
|
|
26
|
+
- Added `register({ closeLabel })` to localize the close button's accessible name. The default is `Close`.
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
|
|
30
|
+
- Closing a notification preserves focus when the user moves it elsewhere during the exit animation.
|
|
31
|
+
- Improved action button text contrast in dark mode and when hovering over an error action in light mode.
|
|
32
|
+
- Long action labels wrap on narrow screens, leaving room for the message and close button. The close icon is easier to see in light mode.
|
|
33
|
+
- Clearing or evicting notifications cancels their timers. Clearing all notifications restores focus to the trigger when focus was inside a toast and the trigger is still available.
|
|
34
|
+
- Screen reader messages update separate live regions while the visible buttons remain available for interaction.
|
|
35
|
+
- Added CommonJS type declarations for the main entry point so TypeScript can resolve types from both ESM and CommonJS.
|
|
36
|
+
- Added a declaration for the stylesheet entry so strict TypeScript projects can import it without a global CSS shim.
|
|
37
|
+
|
|
38
|
+
### Changed
|
|
39
|
+
|
|
40
|
+
- The supported Node.js range for the package and development tools is now `^22.13.0 || >=24.0.0`.
|
|
41
|
+
|
|
42
|
+
## 0.1.0 (2026-10-08)
|
|
43
|
+
|
|
44
|
+
- Initial stable npm release of the dependency-free toast library, with ESM and UMD builds, TypeScript declarations, and a standalone stylesheet.
|
package/README.md
CHANGED
|
@@ -1,61 +1,70 @@
|
|
|
1
1
|
# @dennykuo/glass-toast
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**English** | [繁體中文](README.zh-TW.md)
|
|
4
4
|
|
|
5
|
-
-
|
|
6
|
-
- 3 個位置(top-right / bottom-right / bottom-center),各自獨立堆疊容器
|
|
7
|
-
- 毛玻璃外殼(backdrop-filter + 多層陰影),dismiss 時堆疊平滑坍縮回流
|
|
8
|
-
- hover **與鍵盤焦點**皆暫停自動消失(含進度條同步暫停);`Esc` 關閉聚焦中的 toast、關閉後焦點交還觸發者(WCAG 2.2.1)
|
|
9
|
-
- 內建 dark 外觀(**深色毛玻璃 + 淺字**,保留玻璃身分、避免夜間眩光),自動命中 `prefers-color-scheme` / `[data-theme="dark"]` / `.dark` 三種慣例
|
|
10
|
-
- `prefers-reduced-motion` 完整降級(純淡入、無位移、無 glow;倒數進度條保留,仍提供時間指示)
|
|
11
|
-
- a11y:`role="status"`(一般)/ `role="alert"`(error)+ 對應 `aria-live`(error 為 assertive,其餘 polite),圖示對藥丸底達 ≥3:1 對比
|
|
12
|
-
- 內嵌 `action` 按鈕(如「重試」);error 未指定時停留較久(10s),同位置最多同時 4 則、超量自動收合最舊
|
|
13
|
-
- SPA 友善:容器與樣式在 body/head 被替換後自動重建(Astro ViewTransitions 實測)
|
|
5
|
+
[Documentation (繁體中文)](https://dennykuo.github.io/glass-toast/) · [Interactive demo](https://dennykuo.github.io/glass-toast/demo.html)
|
|
14
6
|
|
|
15
|
-
|
|
7
|
+
Glassmorphism toast notifications — vanilla JS, zero runtime dependencies, no Tailwind or framework required. Works out of the box.
|
|
8
|
+
|
|
9
|
+
- 4 variants (success / error / warning / info): colored icon pill, entrance glow-ring pulse, and a countdown progress bar
|
|
10
|
+
- 3 positions (top-right / bottom-right / bottom-center), each with its own stacking container
|
|
11
|
+
- Frosted-glass shell (`backdrop-filter` + layered shadows); the stack collapses smoothly when a toast is dismissed
|
|
12
|
+
- Auto-dismiss and the progress bar pause on hover and keyboard focus. Press `Esc` to close the focused toast.
|
|
13
|
+
- Built-in dark appearance (**dark frosted glass with light text** — keeps the glass look without a glaring white card at night), picked up automatically from `prefers-color-scheme`, `[data-theme="dark"]`, or `.dark`
|
|
14
|
+
- Full `prefers-reduced-motion` support (plain fade, no movement, no glow; the countdown bar stays because it conveys remaining time)
|
|
15
|
+
- Separate live regions announce regular messages as `status` and errors as `alert`. Localize the close button’s accessible name with `closeLabel`.
|
|
16
|
+
- Inline `action` button (e.g. "Retry"); errors stay longer by default (10 s); at most 4 toasts per position, the oldest one closes when a fifth arrives
|
|
17
|
+
- SPA-friendly: containers and styles are rebuilt automatically after `<body>` / `<head>` swaps (tested with Astro View Transitions)
|
|
18
|
+
|
|
19
|
+
## Install
|
|
16
20
|
|
|
17
21
|
```bash
|
|
18
|
-
npm install @dennykuo/glass-toast
|
|
22
|
+
npm install @dennykuo/glass-toast@0.1.2
|
|
19
23
|
```
|
|
20
24
|
|
|
21
|
-
##
|
|
25
|
+
## Quick start
|
|
22
26
|
|
|
23
|
-
### 1.
|
|
27
|
+
### 1. Side-effect entry (simplest)
|
|
24
28
|
|
|
25
29
|
```js
|
|
26
30
|
import '@dennykuo/glass-toast/auto';
|
|
27
31
|
|
|
28
|
-
//
|
|
29
|
-
toast.success('
|
|
30
|
-
toast.error('
|
|
32
|
+
// Styles are injected and window.toast is ready
|
|
33
|
+
toast.success('Saved');
|
|
34
|
+
toast.error('Connection failed', { position: 'bottom-center' });
|
|
31
35
|
```
|
|
32
36
|
|
|
33
|
-
|
|
37
|
+
`/auto` is an ES module. CommonJS can load it with `require()` on supported Node versions (22.13+ within 22.x, or 24+). It sets up the global and injects styles when a browser DOM is present.
|
|
38
|
+
|
|
39
|
+
### 2. Named imports (tree-shakable, no globals)
|
|
34
40
|
|
|
35
41
|
```js
|
|
36
42
|
import { success, show } from '@dennykuo/glass-toast';
|
|
37
43
|
|
|
38
|
-
success('
|
|
39
|
-
show('
|
|
44
|
+
success('Saved'); // styles are injected on first use
|
|
45
|
+
show('Custom', { type: 'warning', duration: 8000 });
|
|
40
46
|
```
|
|
41
47
|
|
|
42
|
-
|
|
48
|
+
With an explicit stylesheet (recommended for CSP / SSR):
|
|
43
49
|
|
|
44
50
|
```js
|
|
45
51
|
import '@dennykuo/glass-toast/style.css';
|
|
46
52
|
import { register, success } from '@dennykuo/glass-toast';
|
|
47
53
|
|
|
48
|
-
register({ global: false, injectStyles: false }); //
|
|
49
|
-
success('
|
|
54
|
+
register({ global: false, injectStyles: false }); // turn off auto-injection
|
|
55
|
+
success('Saved');
|
|
50
56
|
```
|
|
51
57
|
|
|
52
|
-
### 3. `<script>`
|
|
58
|
+
### 3. `<script>` tag (UMD, global `GlassToast`)
|
|
53
59
|
|
|
54
60
|
```html
|
|
55
|
-
<script src="https://unpkg.com/@dennykuo/glass-toast"></script>
|
|
61
|
+
<script src="https://unpkg.com/@dennykuo/glass-toast@0.1.2"></script>
|
|
62
|
+
<!-- Or use jsDelivr
|
|
63
|
+
<script src="https://cdn.jsdelivr.net/npm/@dennykuo/glass-toast@0.1.2"></script>
|
|
64
|
+
-->
|
|
56
65
|
<script>
|
|
57
|
-
GlassToast.register(); //
|
|
58
|
-
toast.info('
|
|
66
|
+
GlassToast.register(); // sets window.toast and injects styles
|
|
67
|
+
toast.info('Hello');
|
|
59
68
|
</script>
|
|
60
69
|
```
|
|
61
70
|
|
|
@@ -63,101 +72,158 @@ success('儲存成功');
|
|
|
63
72
|
|
|
64
73
|
### `show(message, options?) => dismiss`
|
|
65
74
|
|
|
66
|
-
|
|
75
|
+
Returns a function that closes the toast. The shortcuts `success` / `error` / `warning` / `info` have the same signature (minus `type`).
|
|
67
76
|
|
|
68
|
-
| option |
|
|
77
|
+
| option | type | default | description |
|
|
69
78
|
|---|---|---|---|
|
|
70
|
-
| `type` | `'success' \| 'error' \| 'warning' \| 'info'` | `'info'` |
|
|
71
|
-
| `position` | `'top-right' \| 'bottom-right' \| 'bottom-center'` | `'top-right'` |
|
|
72
|
-
| `persistent` | `boolean` | `false` | `true
|
|
73
|
-
| `duration` | `number` | `
|
|
74
|
-
| `action` | `{ label, onClick }` | — |
|
|
79
|
+
| `type` | `'success' \| 'error' \| 'warning' \| 'info'` | `'info'` | Variant |
|
|
80
|
+
| `position` | `'top-right' \| 'bottom-right' \| 'bottom-center'` | `'top-right'` | Where the toast appears |
|
|
81
|
+
| `persistent` | `boolean` | `false` | When `true`, the toast never auto-dismisses and shows no progress bar |
|
|
82
|
+
| `duration` | `number` | `10000` for `error`, `5500` otherwise | Non-finite values use the default. Finite values ≤ 0 mean `persistent`. Positive values are capped at 2,147,483,647 ms. |
|
|
83
|
+
| `action` | `{ label, onClick }` | — | Runs once at a time and closes the toast on success. Without an explicit finite `duration`, action toasts are persistent. |
|
|
84
|
+
| `dialog` | `HTMLDialogElement` | — | Shows and announces the toast inside an open native dialog. Closing the dialog clears its toasts. |
|
|
75
85
|
|
|
76
|
-
|
|
86
|
+
Messages are written with `textContent` and never parsed as HTML, so any string is safe (`action.label` too).
|
|
77
87
|
|
|
78
88
|
```js
|
|
79
89
|
import { error } from '@dennykuo/glass-toast';
|
|
80
90
|
|
|
81
|
-
error('
|
|
82
|
-
action: { label: '
|
|
91
|
+
error('Upload failed. Retry?', {
|
|
92
|
+
action: { label: 'Retry', onClick: () => retryUpload() },
|
|
83
93
|
});
|
|
84
94
|
```
|
|
85
95
|
|
|
96
|
+
Return the Promise from `onClick` to pause the countdown until the request settles. If the callback throws or rejects, the library logs the error and lets the user retry. Handle any user-facing error details in your application.
|
|
97
|
+
|
|
98
|
+
On short screens, scroll the stack to reach older toasts. Tabbing to a button brings it into view.
|
|
99
|
+
|
|
86
100
|
### `dismissAll(options?)`
|
|
87
101
|
|
|
88
|
-
|
|
102
|
+
Clears every toast. **By default it only clears; later `show()` calls work as usual.** Pass `{ suppress: true }` to also block later toasts — useful when a session expires and you hard-navigate to the login page, so nothing flashes between the redirect and unload. A full page reload unblocks automatically; in an SPA without a reload, call `resume()`:
|
|
89
103
|
|
|
90
104
|
```js
|
|
91
|
-
dismissAll(); //
|
|
92
|
-
dismissAll({ suppress: true }); //
|
|
93
|
-
resume(); // SPA
|
|
105
|
+
dismissAll(); // clear only (default)
|
|
106
|
+
dismissAll({ suppress: true }); // clear and block later show() calls (before a hard navigation)
|
|
107
|
+
resume(); // unblock manually in an SPA
|
|
94
108
|
```
|
|
95
109
|
|
|
96
110
|
### `register(options?) => api`
|
|
97
111
|
|
|
98
|
-
|
|
112
|
+
Sets up the global and injects styles (the `/auto` entry is the same as calling this with no options).
|
|
99
113
|
|
|
100
|
-
| option |
|
|
114
|
+
| option | default | description |
|
|
101
115
|
|---|---|---|
|
|
102
|
-
| `global` | `true` |
|
|
103
|
-
| `injectStyles` | `true` | `false`
|
|
104
|
-
| `target` | `window` |
|
|
116
|
+
| `global` | `true` | Assign the API to `target.toast` |
|
|
117
|
+
| `injectStyles` | `true` | `false` turns off automatic style injection entirely |
|
|
118
|
+
| `target` | `window` | Object that receives the global |
|
|
119
|
+
| `closeLabel` | `'Close'` | The close button's `aria-label`; set it to your UI language, e.g. `register({ closeLabel: 'Schließen' })` |
|
|
105
120
|
|
|
106
121
|
### `ensureStyles()`
|
|
107
122
|
|
|
108
|
-
|
|
123
|
+
Injects the styles idempotently. `show()` does a cheap re-check every time, so it also recovers if an SPA navigation removes the injected `<style>` from `<head>`. No-op during SSR (no `document`).
|
|
109
124
|
|
|
110
|
-
##
|
|
125
|
+
## Theming (CSS variables)
|
|
111
126
|
|
|
112
|
-
|
|
127
|
+
All colors go through `--gt-*` custom properties scoped to `.glass-toast`, so nothing leaks onto `:root`. Override them in your own stylesheet:
|
|
113
128
|
|
|
114
129
|
```css
|
|
115
130
|
.glass-toast { --gt-text: #333; --gt-radius: 0.5rem; }
|
|
116
131
|
.glass-toast--success { --gt-icon: #0a7d4f; --gt-ring: 10, 125, 79; }
|
|
117
132
|
```
|
|
118
133
|
|
|
119
|
-
|
|
|
134
|
+
| variable | default (light) | description |
|
|
120
135
|
|---|---|---|
|
|
121
|
-
| `--gt-bg` | `rgba(255,255,255,.8)` |
|
|
122
|
-
| `--gt-bg-opaque` | `rgba(255,255,255,.96)` | backdrop-filter
|
|
123
|
-
| `--gt-border` | `rgba(229,231,235,.4)` |
|
|
124
|
-
| `--gt-text` | `#4a5565` |
|
|
125
|
-
| `--gt-blur` | `24px` |
|
|
126
|
-
| `--gt-radius` | `1rem` |
|
|
127
|
-
| `--gt-shadow` |
|
|
128
|
-
| `--gt-close-*` |
|
|
129
|
-
| `--gt-focus-ring` | `#2563eb
|
|
130
|
-
| `--gt-action-*` |
|
|
131
|
-
| `--gt-pill-bg` / `--gt-icon` / `--gt-bar` |
|
|
132
|
-
| `--gt-ring` |
|
|
136
|
+
| `--gt-bg` | `rgba(255,255,255,.8)` | Shell background |
|
|
137
|
+
| `--gt-bg-opaque` | `rgba(255,255,255,.96)` | Fallback background when `backdrop-filter` is unsupported |
|
|
138
|
+
| `--gt-border` | `rgba(229,231,235,.4)` | Shell border |
|
|
139
|
+
| `--gt-text` | `#4a5565` | Message text |
|
|
140
|
+
| `--gt-blur` | `24px` | Frosted-glass blur radius |
|
|
141
|
+
| `--gt-radius` | `1rem` | Shell corner radius |
|
|
142
|
+
| `--gt-shadow` | layered shadow | Shell shadow (the glow ring is drawn on top) |
|
|
143
|
+
| `--gt-close-*` | grays | Close button bg / border / text (plus `-hover` versions) |
|
|
144
|
+
| `--gt-focus-ring` | `#2563eb` (dark: `#93c5fd`) | Focus-visible ring for the close and action buttons |
|
|
145
|
+
| `--gt-action-*` | follows the appearance | Action button bg / border / text (plus `-bg-hover`); light mode uses variant-colored text (error uses red-700), dark mode uses message text and a neutral hover background |
|
|
146
|
+
| `--gt-pill-bg` / `--gt-icon` / `--gt-bar` | per variant | Icon pill / icon color / progress bar |
|
|
147
|
+
| `--gt-ring` | per variant | Glow-ring color as an `R, G, B` triplet (fed to `el.animate()`) |
|
|
133
148
|
|
|
134
|
-
### Dark
|
|
149
|
+
### Dark appearance
|
|
135
150
|
|
|
136
|
-
dark
|
|
151
|
+
Dark mode is **dark frosted glass** (a low-luminance translucent background, `rgba(28,28,30,.72)`, with light text) — it keeps the glass look without a glaring white card at night. Variant pills and icons reuse the light values. The shell, close button and focus ring are overridden; action buttons use the message text color and a neutral hover background so small text stays legible.
|
|
137
152
|
|
|
138
|
-
|
|
153
|
+
It applies when any of these is true (an explicit `data-theme="light"` or `.light` on the page wins over the OS setting):
|
|
139
154
|
|
|
140
155
|
1. `@media (prefers-color-scheme: dark)`
|
|
141
156
|
2. `<html data-theme="dark">`
|
|
142
|
-
3. `<html class="dark"
|
|
157
|
+
3. `<html class="dark">` (Tailwind convention)
|
|
158
|
+
|
|
159
|
+
All dark overrides use `:where()` to keep the same specificity as the base rules, so your overrides never have to fight the package's selectors.
|
|
143
160
|
|
|
144
|
-
|
|
161
|
+
## CSP / SSR notes
|
|
145
162
|
|
|
146
|
-
|
|
163
|
+
Use `persistent: true` for important messages or actions available only in the toast, or provide another way to access them after it closes. See [WCAG 2.2.1 Timing Adjustable](https://www.w3.org/WAI/WCAG22/Understanding/timing-adjustable.html).
|
|
147
164
|
|
|
148
|
-
-
|
|
149
|
-
-
|
|
150
|
-
- SSR
|
|
165
|
+
- Strict CSP (no inline `<style>`): import `'@dennykuo/glass-toast/style.css'` explicitly and call `register({ injectStyles: false })`
|
|
166
|
+
- Already loading the stylesheet yourself and want to avoid a duplicate: add a `data-glass-toast` attribute to your `<link>` / `<style>` and auto-injection will detect it and skip
|
|
167
|
+
- SSR: `show()` returns a no-op dismiss function when no DOM is available. Call it on the client to display a toast.
|
|
168
|
+
|
|
169
|
+
Pass the open `dialog` element to keep the toast and its controls inside a native modal. An unopened or detached dialog produces no toast.
|
|
170
|
+
|
|
171
|
+
```js
|
|
172
|
+
import { error } from '@dennykuo/glass-toast';
|
|
173
|
+
|
|
174
|
+
const dialog = document.querySelector('#upload-dialog');
|
|
175
|
+
dialog.showModal();
|
|
176
|
+
error('Upload failed', { dialog, persistent: true });
|
|
177
|
+
```
|
|
151
178
|
|
|
152
|
-
##
|
|
179
|
+
## Development
|
|
180
|
+
|
|
181
|
+
Use Node 24 (`nvm use`; CI reads `.nvmrc`). Node 22.13+ is also supported on the 22.x line.
|
|
153
182
|
|
|
154
183
|
```bash
|
|
155
|
-
npm
|
|
156
|
-
|
|
157
|
-
npm run
|
|
158
|
-
npm
|
|
184
|
+
npm ci --ignore-scripts # install from the lockfile without dependency lifecycle scripts
|
|
185
|
+
npx playwright install chromium firefox webkit # one-time browser setup
|
|
186
|
+
npm run dev # docs site: / docs, /demo.html interactive playground
|
|
187
|
+
npm test # vitest + jsdom (includes documentation coverage guards)
|
|
188
|
+
npm run test:browser # Chromium, Firefox, and WebKit at desktop and mobile widths
|
|
189
|
+
npm run lint # ESLint, including docs scripts
|
|
190
|
+
npm run build # dist/: ESM + UMD + CSS + .d.ts / .d.cts
|
|
191
|
+
npm run check:package # lint the tarball and type-check the README examples against it
|
|
192
|
+
npm run build:docs # dist-docs/: static docs site (relative paths, ready for GitHub Pages)
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
The docs site lives entirely in `docs/` (the site content is currently in Traditional Chinese):
|
|
196
|
+
|
|
197
|
+
```
|
|
198
|
+
docs/
|
|
199
|
+
index.html Docs (home page)
|
|
200
|
+
demo.html Interactive playground
|
|
201
|
+
partials/ Shared HTML fragments, inserted at build time by vite.config.js
|
|
202
|
+
site.css Shared styles
|
|
203
|
+
index.js Docs page interactions
|
|
204
|
+
demo.js Demo page interactions
|
|
205
|
+
site.js Shared scripts
|
|
206
|
+
public/appearance.js Restores appearance before the page is painted
|
|
207
|
+
scrollspy.js Table-of-contents scroll sync (pure function, test/scrollspy.test.js)
|
|
208
|
+
vite.config.js Docs site config (picked up automatically by `vite docs`)
|
|
159
209
|
```
|
|
160
210
|
|
|
211
|
+
Pages sit flat in the `docs/` root, so links inside partials always use `./`. The package name and version come from `package.json` via `%PKG_NAME%` and friends.
|
|
212
|
+
|
|
213
|
+
CI checks pushes to `main` and `develop`, plus pull requests. On `main`, CI installs the exact public npm version into a fresh project before deploying the docs. If deployment is skipped because the version is unpublished, run **CI** on `main` after publishing. After deployment, CI opens the live docs and verifies the version, CDN scripts, and the demo retry action. CI also checks the version in both READMEs.
|
|
214
|
+
|
|
215
|
+
The development-only `minimatch` override selects v11 while ESLint still requests v10,
|
|
216
|
+
to address [GHSA-g3hv-75wg-m249](https://github.com/isaacs/minimatch/security/advisories/GHSA-g3hv-75wg-m249).
|
|
217
|
+
Its file selection, ignore patterns, and error reporting have been checked with this project.
|
|
218
|
+
Revisit the override when updating ESLint; remove it once upstream dependencies include the fix.
|
|
219
|
+
|
|
220
|
+
Documentation coverage is guarded by tests that scan the source for the public API, the `show()` / `register()` options, and every `--gt-*` variable:
|
|
221
|
+
|
|
222
|
+
- `test/docs.test.js` checks that `docs/index.html` has a matching `data-doc` entry for each
|
|
223
|
+
- `test/readme.test.js` checks that both `README.md` and `README.zh-TW.md` mention every export and option, and link to each other
|
|
224
|
+
|
|
225
|
+
When you add an API, update all of them.
|
|
226
|
+
|
|
161
227
|
## License
|
|
162
228
|
|
|
163
229
|
MIT © Denny
|
package/README.zh-TW.md
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# @dennykuo/glass-toast
|
|
2
|
+
|
|
3
|
+
[English](README.md) | **繁體中文**
|
|
4
|
+
|
|
5
|
+
[文件站](https://dennykuo.github.io/glass-toast/) · [互動 Demo](https://dennykuo.github.io/glass-toast/demo.html)
|
|
6
|
+
|
|
7
|
+
毛玻璃質感的 toast 通知元件 — vanilla JS、零 runtime 相依、不需要 Tailwind 或任何框架,開箱即用。
|
|
8
|
+
|
|
9
|
+
- 4 種變體(success / error / warning / info):彩色圖示藥丸 + 進場 glow ring 脈衝 + 倒數進度條
|
|
10
|
+
- 3 個位置(top-right / bottom-right / bottom-center),各自獨立堆疊容器
|
|
11
|
+
- 毛玻璃外殼(backdrop-filter + 多層陰影),dismiss 時堆疊平滑坍縮回流
|
|
12
|
+
- 滑鼠移上或鍵盤焦點進入時暫停倒數,按 `Esc` 可關閉聚焦中的通知。
|
|
13
|
+
- 內建 dark 外觀(**深色毛玻璃 + 淺字**,保留玻璃身分、避免夜間眩光),自動命中 `prefers-color-scheme` / `[data-theme="dark"]` / `.dark` 三種慣例
|
|
14
|
+
- `prefers-reduced-motion` 完整降級(純淡入、無位移、無 glow;倒數進度條保留,仍提供時間指示)
|
|
15
|
+
- a11y:`role="status"`(一般)/ `role="alert"`(error)+ 對應 `aria-live`(error 為 assertive,其餘 polite),圖示對藥丸底達 ≥3:1 對比;關閉按鈕名稱可用 `closeLabel` 在地化
|
|
16
|
+
- 內嵌 `action` 按鈕(如「重試」);error 未指定時停留較久(10s),同位置最多同時 4 則、超量自動收合最舊
|
|
17
|
+
- SPA 友善:容器與樣式在 body/head 被替換後自動重建(Astro ViewTransitions 實測)
|
|
18
|
+
|
|
19
|
+
## 安裝
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install @dennykuo/glass-toast@0.1.2
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## 快速開始
|
|
26
|
+
|
|
27
|
+
### 1. side-effect 入口(最省事)
|
|
28
|
+
|
|
29
|
+
```js
|
|
30
|
+
import '@dennykuo/glass-toast/auto';
|
|
31
|
+
|
|
32
|
+
// 樣式已注入、window.toast 已掛載
|
|
33
|
+
toast.success('儲存成功');
|
|
34
|
+
toast.error('連線失敗', { position: 'bottom-center' });
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
`/auto` 是 ES 模組。在支援的 Node 版本(22.x 自 22.13 起,或 24 以上),CommonJS 也可以用 `require()` 載入。有瀏覽器 DOM 時才會掛載全域與注入樣式。
|
|
38
|
+
|
|
39
|
+
### 2. 具名 import(可 tree-shake、不碰 window)
|
|
40
|
+
|
|
41
|
+
```js
|
|
42
|
+
import { success, show } from '@dennykuo/glass-toast';
|
|
43
|
+
|
|
44
|
+
success('儲存成功'); // 首次使用時自動注入樣式
|
|
45
|
+
show('自訂', { type: 'warning', duration: 8000 });
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
搭配顯式樣式(正規做法,CSP / SSR 友善):
|
|
49
|
+
|
|
50
|
+
```js
|
|
51
|
+
import '@dennykuo/glass-toast/style.css';
|
|
52
|
+
import { register, success } from '@dennykuo/glass-toast';
|
|
53
|
+
|
|
54
|
+
register({ global: false, injectStyles: false }); // 停用自動注入
|
|
55
|
+
success('儲存成功');
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### 3. `<script>` 直接引入(UMD,全域 `GlassToast`)
|
|
59
|
+
|
|
60
|
+
```html
|
|
61
|
+
<script src="https://unpkg.com/@dennykuo/glass-toast@0.1.2"></script>
|
|
62
|
+
<!-- 也可以改用 jsDelivr
|
|
63
|
+
<script src="https://cdn.jsdelivr.net/npm/@dennykuo/glass-toast@0.1.2"></script>
|
|
64
|
+
-->
|
|
65
|
+
<script>
|
|
66
|
+
GlassToast.register(); // 掛 window.toast + 注入樣式
|
|
67
|
+
toast.info('哈囉');
|
|
68
|
+
</script>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## API
|
|
72
|
+
|
|
73
|
+
### `show(message, options?) => dismiss`
|
|
74
|
+
|
|
75
|
+
回傳手動關閉函式。快捷方法 `success` / `error` / `warning` / `info` 同簽名(省略 `type`)。
|
|
76
|
+
|
|
77
|
+
| option | 型別 | 預設 | 說明 |
|
|
78
|
+
|---|---|---|---|
|
|
79
|
+
| `type` | `'success' \| 'error' \| 'warning' \| 'info'` | `'info'` | 變體 |
|
|
80
|
+
| `position` | `'top-right' \| 'bottom-right' \| 'bottom-center'` | `'top-right'` | 顯示位置 |
|
|
81
|
+
| `persistent` | `boolean` | `false` | `true` 時不自動消失、無進度條 |
|
|
82
|
+
| `duration` | `number` | `error` 為 `10000`、其餘 `5500` | 非有限值使用預設。有指定有限值時,≤ 0 視為 `persistent`,正值上限為 2,147,483,647 毫秒。 |
|
|
83
|
+
| `action` | `{ label, onClick }` | — | 一次執行一個操作,成功後關閉。未指定有限的 `duration` 時,通知會持續顯示。 |
|
|
84
|
+
| `dialog` | `HTMLDialogElement` | — | 在已開啟的原生對話框內顯示與宣告通知。關閉對話框會清除其中的通知。 |
|
|
85
|
+
|
|
86
|
+
訊息走 `textContent`,不解析 HTML,塞什麼字串都安全(`action.label` 亦然)。
|
|
87
|
+
|
|
88
|
+
```js
|
|
89
|
+
import { error } from '@dennykuo/glass-toast';
|
|
90
|
+
|
|
91
|
+
error('上傳失敗,是否重試?', {
|
|
92
|
+
action: { label: '重試', onClick: () => retryUpload() },
|
|
93
|
+
});
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
`onClick` 回傳 Promise 時,通知會暫停倒數,等操作成功才關閉。回呼拋錯或 Promise 被拒絕時,套件會把錯誤記到 console 並允許重試。應用程式可自行向使用者顯示失敗原因。
|
|
97
|
+
|
|
98
|
+
短螢幕上可捲動堆疊查看較早的通知。使用 Tab 聚焦按鈕時,瀏覽器會將它捲入可見範圍。
|
|
99
|
+
|
|
100
|
+
### `dismissAll(options?)`
|
|
101
|
+
|
|
102
|
+
清空所有 toast。**預設只清空、不影響後續 `show()`**。若要鎖住後續 toast(供「session 過期 → 硬導航登入頁」情境,避免 redirect 與 unload 之間閃現新 toast)傳 `{ suppress: true }`;整頁重載後自動解鎖,SPA 不重載時用 `resume()` 解鎖:
|
|
103
|
+
|
|
104
|
+
```js
|
|
105
|
+
dismissAll(); // 只清空(預設)
|
|
106
|
+
dismissAll({ suppress: true }); // 清空並鎖住後續 show()(硬導航前)
|
|
107
|
+
resume(); // SPA 不重載時手動解鎖
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### `register(options?) => api`
|
|
111
|
+
|
|
112
|
+
掛載全域 + 注入樣式(`/auto` 入口等價於無參數呼叫本函式)。
|
|
113
|
+
|
|
114
|
+
| option | 預設 | 說明 |
|
|
115
|
+
|---|---|---|
|
|
116
|
+
| `global` | `true` | 掛 `target.toast` |
|
|
117
|
+
| `injectStyles` | `true` | `false` 時全面停用自動樣式注入 |
|
|
118
|
+
| `target` | `window` | 全域掛載目標 |
|
|
119
|
+
| `closeLabel` | `'Close'` | 關閉按鈕的 `aria-label`;非英語介面請換成在地語言,例如 `register({ closeLabel: '關閉通知' })` |
|
|
120
|
+
|
|
121
|
+
### `ensureStyles()`
|
|
122
|
+
|
|
123
|
+
冪等注入樣式(`show()` 每次都會 cheap re-check,SPA 換頁把 `<head>` 注入的樣式拔掉也會自我修復)。SSR(無 `document`)為 no-op。
|
|
124
|
+
|
|
125
|
+
## 樣式客製(CSS 變數)
|
|
126
|
+
|
|
127
|
+
所有顏色走 `--gt-*` custom properties,scope 在 `.glass-toast` 上、不污染 `:root`。在你的 stylesheet 覆蓋即可:
|
|
128
|
+
|
|
129
|
+
```css
|
|
130
|
+
.glass-toast { --gt-text: #333; --gt-radius: 0.5rem; }
|
|
131
|
+
.glass-toast--success { --gt-icon: #0a7d4f; --gt-ring: 10, 125, 79; }
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
| 變數 | 預設(light) | 說明 |
|
|
135
|
+
|---|---|---|
|
|
136
|
+
| `--gt-bg` | `rgba(255,255,255,.8)` | 外殼底色 |
|
|
137
|
+
| `--gt-bg-opaque` | `rgba(255,255,255,.96)` | backdrop-filter 不支援時的後備底色 |
|
|
138
|
+
| `--gt-border` | `rgba(229,231,235,.4)` | 外殼邊線 |
|
|
139
|
+
| `--gt-text` | `#4a5565` | 訊息文字 |
|
|
140
|
+
| `--gt-blur` | `24px` | 毛玻璃模糊半徑 |
|
|
141
|
+
| `--gt-radius` | `1rem` | 外殼圓角 |
|
|
142
|
+
| `--gt-shadow` | 多層陰影 | 外殼陰影(glow ring 疊加其上) |
|
|
143
|
+
| `--gt-close-*` | gray 系 | 關閉鈕 bg / border / text(含 `-hover`) |
|
|
144
|
+
| `--gt-focus-ring` | `#2563eb`(dark `#93c5fd`) | 關閉鈕 / action 鈕 focus-visible ring |
|
|
145
|
+
| `--gt-action-*` | 隨外觀調整 | action 鈕 bg / border / text(含 `-bg-hover`);淺色使用變體文字色(error 為 red-700),深色使用訊息文字色與中性 hover 底色 |
|
|
146
|
+
| `--gt-pill-bg` / `--gt-icon` / `--gt-bar` | 依變體 | 圖示藥丸底 / 圖示色 / 進度條色 |
|
|
147
|
+
| `--gt-ring` | 依變體 | glow ring 的 `R, G, B` 三元組(餵給 `el.animate()`) |
|
|
148
|
+
|
|
149
|
+
### Dark 外觀
|
|
150
|
+
|
|
151
|
+
dark 為**深色毛玻璃**(低亮度半透明底 `rgba(28,28,30,.72)` + 淺字),保留玻璃身分、避免夜間白卡眩光;變體藥丸/圖示沿用 base。除外殼、關閉鈕與 focus ring 外,action 改用訊息文字色與中性 hover 底色,維持小字的可讀性。
|
|
152
|
+
|
|
153
|
+
以下三種慣例任一成立即套用(頁面明示 `data-theme="light"` / `.light` 時 OS 深色讓路):
|
|
154
|
+
|
|
155
|
+
1. `@media (prefers-color-scheme: dark)`
|
|
156
|
+
2. `<html data-theme="dark">`
|
|
157
|
+
3. `<html class="dark">`(Tailwind 慣例)
|
|
158
|
+
|
|
159
|
+
dark 覆寫全部走 `:where()` 壓成與 base 相同的 specificity,你的覆蓋規則永遠不需要跟套件比權重。
|
|
160
|
+
|
|
161
|
+
## CSP / SSR 註記
|
|
162
|
+
|
|
163
|
+
若通知是取得重要訊息或執行操作的唯一方式,請使用 `persistent: true`,或另外提供可在通知關閉後使用的管道。參考 [WCAG 2.2.1 計時可調整](https://www.w3.org/WAI/WCAG22/Understanding/timing-adjustable.html)。
|
|
164
|
+
|
|
165
|
+
- 嚴格 CSP(禁 inline `<style>`):改顯式 `import '@dennykuo/glass-toast/style.css'` + `register({ injectStyles: false })`
|
|
166
|
+
- 已自行載入 style.css 且想避免重複注入:在你的 `<link>` / `<style>` 加 `data-glass-toast` 屬性即可被偵測跳過
|
|
167
|
+
- SSR:沒有 DOM 時,`show()` 回傳空的關閉函式。要顯示通知請在瀏覽器呼叫。
|
|
168
|
+
|
|
169
|
+
使用原生 modal 時,可傳入已開啟的 `dialog`,讓通知和按鈕留在對話框內。傳入尚未開啟或已從頁面移除的對話框時,不會顯示通知。
|
|
170
|
+
|
|
171
|
+
```js
|
|
172
|
+
import { error } from '@dennykuo/glass-toast';
|
|
173
|
+
|
|
174
|
+
const dialog = document.querySelector('#upload-dialog');
|
|
175
|
+
dialog.showModal();
|
|
176
|
+
error('上傳失敗', { dialog, persistent: true });
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## 開發
|
|
180
|
+
|
|
181
|
+
建議使用 Node 24(`nvm use`;CI 讀取 `.nvmrc`)。22.x 系列最低為 Node 22.13。
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
npm ci --ignore-scripts # 依 lockfile 安裝,不執行依賴的生命週期腳本
|
|
185
|
+
npx playwright install chromium firefox webkit # 首次安裝瀏覽器
|
|
186
|
+
npm run dev # 文件站:/ 文件、/demo.html 互動 playground
|
|
187
|
+
npm test # vitest + jsdom(含文件覆蓋率守門)
|
|
188
|
+
npm run test:browser # Chromium、Firefox、WebKit,涵蓋桌機與手機寬度
|
|
189
|
+
npm run lint # ESLint,含文件站腳本
|
|
190
|
+
npm run build # dist/:ESM + UMD + CSS + .d.ts / .d.cts
|
|
191
|
+
npm run check:package # 檢查 tarball 並用乾淨安裝驗證 README 範例型別
|
|
192
|
+
npm run build:docs # dist-docs/:文件站靜態檔(相對路徑,可直接部署到 GitHub Pages)
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
文件站整個放在 `docs/`:
|
|
196
|
+
|
|
197
|
+
```
|
|
198
|
+
docs/
|
|
199
|
+
index.html 文件(首頁)
|
|
200
|
+
demo.html 互動 playground
|
|
201
|
+
partials/ 共用 HTML 片段,由 vite.config.js 在建置時插入
|
|
202
|
+
site.css 共用樣式
|
|
203
|
+
index.js 文件首頁互動
|
|
204
|
+
demo.js Demo 互動
|
|
205
|
+
site.js 共用腳本
|
|
206
|
+
public/appearance.js 首次繪製前套用外觀
|
|
207
|
+
scrollspy.js 文件目錄的捲動同步判斷(純函式,test/scrollspy.test.js)
|
|
208
|
+
vite.config.js 文件站設定(vite docs 自動讀取)
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
頁面一律平放在 `docs/` 根目錄,partial 裡的站內連結都寫 `./`;套件名稱與版本以 `%PKG_NAME%` 等從 `package.json` 帶入。
|
|
212
|
+
|
|
213
|
+
CI 檢查 `main`、`develop` 的推送和 PR。`main` 會先在乾淨專案從公開 npm 安裝指定版本,再部署文件站。若因版本未發布而略過部署,發布後可在 `main` 手動執行 **CI**。部署完成後,CI 會打開正式站驗證版號、CDN 腳本和 Demo 的重試操作,並在檢查階段核對兩份 README 的版號。
|
|
214
|
+
|
|
215
|
+
開發依賴暫以 `minimatch` override 選用 v11,處理 ESLint 仍要求 v10 時的
|
|
216
|
+
[GHSA-g3hv-75wg-m249](https://github.com/isaacs/minimatch/security/advisories/GHSA-g3hv-75wg-m249)。
|
|
217
|
+
已核對本專案的檔案選取、忽略規則與錯誤偵測。後續更新 ESLint 時需重新檢查,
|
|
218
|
+
待上游直接採用修補版後移除 override。
|
|
219
|
+
|
|
220
|
+
文件覆蓋率由測試守門,從原始碼掃出公開 API、`show()` / `register()` 選項與所有 `--gt-*` 變數:
|
|
221
|
+
|
|
222
|
+
- `test/docs.test.js`:逐一確認 `docs/index.html` 有對應的 `data-doc` 條目
|
|
223
|
+
- `test/readme.test.js`:確認 `README.md`(英文)與 `README.zh-TW.md` 都提到每個 export 與選項,且互相連結
|
|
224
|
+
|
|
225
|
+
新增 API 時記得每一份都要補。
|
|
226
|
+
|
|
227
|
+
## License
|
|
228
|
+
|
|
229
|
+
MIT © Denny
|
package/dist/auto.d.cts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./toast.cjs";
|
package/dist/auto.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { a as e, c as t, i as n, l as r, n as i, o as a, r as o, s, t as c } from "./toast-
|
|
2
|
-
|
|
1
|
+
import { a as e, c as t, i as n, l as r, n as i, o as a, r as o, s, t as c } from "./toast-GM0D-R2d.js";
|
|
2
|
+
// src/auto.js
|
|
3
3
|
e();
|
|
4
|
-
//#endregion
|
|
5
4
|
export { c as dismissAll, i as ensureStyles, o as error, n as info, e as register, a as resume, s as show, t as success, r as warning };
|
package/dist/glass-toast.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.glass-toast-container,.glass-toast,.glass-toast *{box-sizing:border-box}.glass-toast-container{z-index:2147483647;pointer-events:none;flex-direction:column;gap:.75rem;display:flex;position:fixed}.glass-toast-container--top-right{align-items:flex-end;top:
|
|
1
|
+
.glass-toast-container,.glass-toast,.glass-toast *{box-sizing:border-box}.glass-toast-announcer{clip-path:inset(50%);white-space:nowrap;width:1px;height:1px;position:absolute;overflow:hidden}.glass-toast-container{width:min(26rem,100%);max-height:100dvh;padding:1rem;padding-top:max(1rem, env(safe-area-inset-top));padding-right:max(1rem, env(safe-area-inset-right));padding-bottom:max(1rem, env(safe-area-inset-bottom));padding-left:max(1rem, env(safe-area-inset-left));scrollbar-width:none;z-index:2147483647;pointer-events:none;flex-direction:column;gap:.75rem;display:flex;position:fixed;overflow:auto}.glass-toast-container[data-scrollable]{pointer-events:auto}.glass-toast-container--top-right{align-items:flex-end;top:0;right:0}.glass-toast-container--bottom-right{align-items:flex-end;bottom:0;right:0}.glass-toast-container--bottom-center{align-items:center;bottom:0;left:50%;transform:translate(-50%)}.glass-toast{--gt-bg:#fffc;--gt-bg-opaque:#fffffff5;--gt-border:#e5e7eb66;--gt-text:#4a5565;--gt-blur:24px;--gt-radius:1rem;--gt-shadow:0 4px 24px -4px #00000014, 0 1px 2px #0000000a;--gt-close-bg:#f9fafb;--gt-close-border:#e5e7eb;--gt-close-text:#667085;--gt-close-bg-hover:#f3f4f6;--gt-close-border-hover:#d1d5dc;--gt-close-text-hover:#4a5565;--gt-focus-ring:#2563eb;pointer-events:auto;background-color:var(--gt-bg);width:24rem;max-width:calc(100vw - 2rem);backdrop-filter:blur(var(--gt-blur));border:1px solid var(--gt-border);border-radius:var(--gt-radius);box-shadow:var(--gt-shadow);grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:.75rem;padding:.875rem 1rem;display:grid;position:relative;overflow:hidden}.glass-toast-container>.glass-toast{flex:none;max-width:100%}@supports not (backdrop-filter:blur(1px)){.glass-toast{background-color:var(--gt-bg-opaque)}}.glass-toast--success{--gt-pill-bg:#d0fae5;--gt-icon:#047857;--gt-bar:#00bb7f;--gt-ring:16, 185, 129}.glass-toast--error{--gt-pill-bg:#ffe2e2;--gt-icon:#dc2626;--gt-action-text:#b91c1c;--gt-bar:#ff6568;--gt-ring:239, 68, 68}.glass-toast--warning{--gt-pill-bg:#fef3c6;--gt-icon:#b45309;--gt-bar:#fcbb00;--gt-ring:245, 158, 11}.glass-toast--info{--gt-pill-bg:#e2eaf1;--gt-icon:#3a5b7a;--gt-bar:#6f92ad;--gt-ring:76, 112, 144}.glass-toast--animated{transition:all .28s cubic-bezier(0,0,.2,1)}.glass-toast--leaving{transition-timing-function:cubic-bezier(.4,0,1,1)}.glass-toast--enter,.glass-toast--faded{opacity:0}.glass-toast--enter[data-position=top-right],.glass-toast--enter[data-position=bottom-right]{transform:translate(2rem)}.glass-toast--enter[data-position=bottom-center]{transform:translateY(2rem)}.glass-toast__icon{background-color:var(--gt-pill-bg);width:1.75rem;height:1.75rem;color:var(--gt-icon);border-radius:.5rem;flex-shrink:0;justify-content:center;align-items:center;display:flex}.glass-toast__icon svg{flex-shrink:0;width:18px;height:18px;display:block}.glass-toast__message{min-width:0;color:var(--gt-text);overflow-wrap:anywhere;-webkit-line-clamp:5;line-clamp:5;-webkit-box-orient:vertical;margin:0;font-size:.9375rem;line-height:1.625;display:-webkit-box;overflow:hidden}.glass-toast__action{border:1px solid var(--gt-action-border,var(--gt-border));background-color:var(--gt-action-bg,transparent);min-width:0;max-width:100%;min-height:2rem;color:var(--gt-action-text,var(--gt-icon));font:inherit;overflow-wrap:anywhere;cursor:pointer;appearance:none;border-radius:.5rem;grid-area:2/2;place-self:center start;padding:.3125rem .75rem;font-size:.8125rem;font-weight:600;line-height:1.25;transition:background-color .15s cubic-bezier(.4,0,.2,1),border-color .15s cubic-bezier(.4,0,.2,1)}.glass-toast__action:hover{background-color:var(--gt-action-bg-hover,var(--gt-pill-bg))}.glass-toast__action[aria-disabled=true]{cursor:progress}.glass-toast__action:focus-visible{outline:2px solid var(--gt-focus-ring);outline-offset:2px}.glass-toast__close{border:1px solid var(--gt-close-border);background-color:var(--gt-close-bg);width:2rem;height:2rem;color:var(--gt-close-text);font:inherit;cursor:pointer;appearance:none;border-radius:9999px;grid-area:1/-2;justify-content:center;align-self:center;align-items:center;padding:0;transition:all .15s cubic-bezier(.4,0,.2,1);display:flex}.glass-toast__close:hover{background-color:var(--gt-close-bg-hover);border-color:var(--gt-close-border-hover);color:var(--gt-close-text-hover)}.glass-toast__close:focus-visible{outline:2px solid var(--gt-focus-ring);outline-offset:2px}.glass-toast__close svg{width:.875rem;height:.875rem;display:block}.glass-toast__bar{background-color:var(--gt-bar);opacity:.4;border-radius:9999px;height:2px;position:absolute;bottom:0;left:0}@media (width>=768px){.glass-toast__message{font-size:14px}.glass-toast:has(.glass-toast__action){grid-template-columns:auto minmax(0,1fr) minmax(0,35%) auto}.glass-toast:has(.glass-toast__action) .glass-toast__action{grid-area:1/3}}@media (prefers-color-scheme:dark){:where(:root:not([data-theme=light]):not(.light)) .glass-toast{--gt-bg:#1c1c1eb8;--gt-bg-opaque:#1c1c1eeb;--gt-border:#ffffff1a;--gt-text:#e5e7eb;--gt-close-bg:#ffffff0f;--gt-close-border:#ffffff1f;--gt-close-text:#cbd5e1;--gt-close-bg-hover:#ffffff1f;--gt-close-border-hover:#ffffff38;--gt-close-text-hover:#f1f5f9;--gt-focus-ring:#93c5fd;--gt-action-text:var(--gt-text);--gt-action-bg-hover:var(--gt-close-bg-hover)}}:where([data-theme=dark],.dark) .glass-toast{--gt-bg:#1c1c1eb8;--gt-bg-opaque:#1c1c1eeb;--gt-border:#ffffff1a;--gt-text:#e5e7eb;--gt-close-bg:#ffffff0f;--gt-close-border:#ffffff1f;--gt-close-text:#cbd5e1;--gt-close-bg-hover:#ffffff1f;--gt-close-border-hover:#ffffff38;--gt-close-text-hover:#f1f5f9;--gt-focus-ring:#93c5fd;--gt-action-text:var(--gt-text);--gt-action-bg-hover:var(--gt-close-bg-hover)}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/glass-toast.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export { c as dismissAll, i as ensureStyles, o as error, n as info, e as register, a as resume, s as show, t as success, r as warning };
|
|
1
|
+
export { t as dismissAll, n as ensureStyles, r as error, i as info, a as register, o as resume, s as show, c as success, l as warning } from "./toast-GM0D-R2d.js";
|