react-snackbar-glass 0.0.0-stage β 1.0.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/CHANGELOG.md +23 -0
- package/LICENSE +21 -0
- package/README.md +213 -2
- package/dist/index.cjs +967 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.css +615 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.cts +229 -0
- package/dist/index.d.ts +229 -0
- package/dist/index.js +961 -0
- package/dist/index.js.map +1 -0
- package/dist/styles.css +615 -0
- package/package.json +67 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [1.0.0] - 2026-10-28
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Initial public release.
|
|
13
|
+
- `SnackbarProvider`, `useSnackbar`, `useSnackbarStore` and a headless
|
|
14
|
+
`createSnackbarStore` + `SnackbarHost` pair.
|
|
15
|
+
- Seven variants (`neutral`, `success`, `error`, `warning`, `info`, `loading`,
|
|
16
|
+
`custom`), glass/solid tones and four sizes.
|
|
17
|
+
- Six screen placements with queueing and `maxVisible` stacking.
|
|
18
|
+
- Promise-aware `promise()` flows with loading, success, error and mapper
|
|
19
|
+
content.
|
|
20
|
+
- Swipe-to-dismiss, pause on hover/focus/hidden document, countdown hairline.
|
|
21
|
+
- Accessible live regions, keyboard-reachable actions, reduced-motion support.
|
|
22
|
+
- Token-driven CSS theming via `--prs-*` custom properties.
|
|
23
|
+
- ESM, CJS and TypeScript declarations with zero runtime dependencies.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 react-snackbar-glass contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,214 @@
|
|
|
1
|
-
#
|
|
1
|
+
# react-snackbar-glass
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A premium, glassmorphic snackbar system for React β queueing, promise-aware
|
|
4
|
+
states, swipe-to-dismiss and token-driven theming with **zero runtime
|
|
5
|
+
dependencies**.
|
|
6
|
+
|
|
7
|
+
- πͺ **Glass or solid** surfaces, `xs` β `lg` sizes, six screen corners
|
|
8
|
+
- β³ **Promise aware** β one call moves a snackbar through loading β success β error
|
|
9
|
+
- π **Swipe to dismiss**, hover/focus/document-hidden pause, countdown hairline
|
|
10
|
+
- βΏ **Accessible** β polite/assertive live regions, keyboard reachable actions, `prefers-reduced-motion`
|
|
11
|
+
- π§© **Typed** β written in TypeScript, ships ESM + CJS + `.d.ts`
|
|
12
|
+
- πͺΆ **Tiny** β React is the only peer dependency
|
|
13
|
+
- π₯οΈ **SSR safe** β no `window` access during render
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install react-snackbar-glass
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Import the stylesheet once in your app entry point:
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import 'react-snackbar-glass/styles.css';
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Quick start
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
import { SnackbarProvider, useSnackbar } from 'react-snackbar-glass';
|
|
31
|
+
import 'react-snackbar-glass/styles.css';
|
|
32
|
+
|
|
33
|
+
export default function App() {
|
|
34
|
+
return (
|
|
35
|
+
<SnackbarProvider position="bottom-right" theme="auto">
|
|
36
|
+
<Dashboard />
|
|
37
|
+
</SnackbarProvider>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function Dashboard() {
|
|
42
|
+
const snackbar = useSnackbar();
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<button onClick={() => snackbar.success('Saved to your workspace.')}>
|
|
46
|
+
Save
|
|
47
|
+
</button>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## API
|
|
53
|
+
|
|
54
|
+
### `useSnackbar()`
|
|
55
|
+
|
|
56
|
+
| Method | Description |
|
|
57
|
+
| --- | --- |
|
|
58
|
+
| `show(options)` | Queue a fully customised snackbar, returns its `id`. |
|
|
59
|
+
| `update(id, options)` | Patch an existing snackbar in place; timers restart if `duration` changes. |
|
|
60
|
+
| `dismiss(id?, reason?)` | Close one snackbar (or the oldest) and report a close reason. |
|
|
61
|
+
| `dismissAll(reason?)` | Close every visible snackbar. |
|
|
62
|
+
| `success / error / warning / info / neutral / loading / custom(message, options?)` | Variant presets. |
|
|
63
|
+
| `promise(promise, messages, options?)` | Drive a single snackbar through loading, success and error. |
|
|
64
|
+
| `store` | Escape hatch: the underlying store for subscriptions and advanced updates. |
|
|
65
|
+
|
|
66
|
+
### Promise-aware flows
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
const snackbar = useSnackbar();
|
|
70
|
+
|
|
71
|
+
snackbar.promise(deploy(), {
|
|
72
|
+
loading: { title: 'Deploying', message: 'Uploading assetsβ¦' },
|
|
73
|
+
success: { title: 'Deployed', message: 'Build #4821 is live.' },
|
|
74
|
+
error: (error) => ({
|
|
75
|
+
title: 'Deployment failed',
|
|
76
|
+
message: error instanceof Error ? error.message : 'Something went wrong.',
|
|
77
|
+
action: { label: 'View logs' },
|
|
78
|
+
}),
|
|
79
|
+
});
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
`success` and `error` can be plain content, full options, or a mapper that
|
|
83
|
+
receives the resolved value / rejection reason.
|
|
84
|
+
|
|
85
|
+
### Sticky snackbars with in-place updates
|
|
86
|
+
|
|
87
|
+
```tsx
|
|
88
|
+
const id = snackbar.show({
|
|
89
|
+
variant: 'loading',
|
|
90
|
+
title: 'Uploading assets',
|
|
91
|
+
message: '42% Β· 8 of 19 files',
|
|
92
|
+
duration: null,
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// laterβ¦
|
|
96
|
+
snackbar.update(id, {
|
|
97
|
+
variant: 'success',
|
|
98
|
+
title: 'Upload complete',
|
|
99
|
+
message: '19 assets are ready to use.',
|
|
100
|
+
duration: 4200,
|
|
101
|
+
});
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Actions and undo windows
|
|
105
|
+
|
|
106
|
+
```tsx
|
|
107
|
+
snackbar.show({
|
|
108
|
+
message: 'Project archived.',
|
|
109
|
+
duration: 7000,
|
|
110
|
+
action: {
|
|
111
|
+
label: 'Undo',
|
|
112
|
+
onClick: () => restoreProject(),
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Action handlers may return a promise: the button shows a pending state and
|
|
118
|
+
the snackbar only closes after the handler settles (`closeOnClick`, default
|
|
119
|
+
`true`).
|
|
120
|
+
|
|
121
|
+
## `<SnackbarProvider>` props
|
|
122
|
+
|
|
123
|
+
| Prop | Type | Default | Description |
|
|
124
|
+
| --- | --- | --- | --- |
|
|
125
|
+
| `position` | `SnackbarPosition` | `'bottom-right'` | Default corner for new snackbars. |
|
|
126
|
+
| `duration` | `number \| null` | `5000` | Auto-dismiss delay in ms. `null`/`0`/`Infinity` = persistent. |
|
|
127
|
+
| `tone` | `'glass' \| 'solid'` | `'glass'` | Surface treatment. |
|
|
128
|
+
| `size` | `'xs' \| 'sm' \| 'md' \| 'lg'` | `'md'` | Card density/width. |
|
|
129
|
+
| `theme` | `'light' \| 'dark' \| 'auto'` | `'auto'` | Color scheme. |
|
|
130
|
+
| `maxVisible` | `number` | `3` | Simultaneously visible cards per corner. |
|
|
131
|
+
| `dismissible` | `boolean` | `true` | Show the close button. |
|
|
132
|
+
| `progress` | `boolean` | `true` | Show the countdown hairline. |
|
|
133
|
+
| `pauseOnHover` | `boolean` | `true` | Freeze the timer while hovered. |
|
|
134
|
+
| `pauseOnFocus` | `boolean` | `true` | Freeze the timer while focus is inside. |
|
|
135
|
+
| `pauseOnDocumentHidden` | `boolean` | `true` | Pause when the tab is hidden. |
|
|
136
|
+
| `swipeToDismiss` | `boolean` | `true` | Drag/flick a card to dismiss. |
|
|
137
|
+
| `swipeThreshold` | `number` | `88` | Drag distance (px) that triggers dismissal. |
|
|
138
|
+
| `store` | `SnackbarStore` | β | Bring your own store (tests, SSR, multiple apps). |
|
|
139
|
+
| `offset` / `gap` / `width` | `number` | `20` / `12` / `384` | Layout tuning in px. |
|
|
140
|
+
| `icons` / `closeIcon` / `closeLabel` / `regionLabel` | β | β | Icon and a11y overrides. |
|
|
141
|
+
| `container` | `HTMLElement \| () => HTMLElement \| null` | `document.body` | Portal target. |
|
|
142
|
+
| `dir` | `'ltr' \| 'rtl'` | inherited | Text direction. |
|
|
143
|
+
| `zIndex` | `number` | `2147483000` | Host stacking context. |
|
|
144
|
+
|
|
145
|
+
## `SnackbarOptions`
|
|
146
|
+
|
|
147
|
+
`id`, `title`, `message`, `variant`, `duration`, `position`, `icon`,
|
|
148
|
+
`action`, `dismissible`, `progress`, `tone`, `size`, `className`, `style`,
|
|
149
|
+
`onOpen`, `onClose`.
|
|
150
|
+
|
|
151
|
+
Reusing an `id` updates (or revives) the existing snackbar instead of stacking
|
|
152
|
+
a duplicate β ideal for progress-style flows.
|
|
153
|
+
|
|
154
|
+
## Theming
|
|
155
|
+
|
|
156
|
+
Colors, radii, blur and motion are CSS custom properties on `.prs-root`
|
|
157
|
+
(and per-card inline styles). Override globally:
|
|
158
|
+
|
|
159
|
+
```css
|
|
160
|
+
:root {
|
|
161
|
+
--prs-accent: #8b5cf6;
|
|
162
|
+
--prs-radius: 16px;
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Or scope a single snackbar:
|
|
167
|
+
|
|
168
|
+
```tsx
|
|
169
|
+
snackbar.custom('Added to collection.', {
|
|
170
|
+
style: { '--prs-accent': '#f472b6', '--prs-solid': '#be185d' },
|
|
171
|
+
});
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Store-only usage
|
|
175
|
+
|
|
176
|
+
```tsx
|
|
177
|
+
import { createSnackbarStore, SnackbarHost } from 'react-snackbar-glass';
|
|
178
|
+
|
|
179
|
+
const store = createSnackbarStore({ position: 'top-center' });
|
|
180
|
+
|
|
181
|
+
function App() {
|
|
182
|
+
return (
|
|
183
|
+
<>
|
|
184
|
+
<button onClick={() => store.show({ message: 'Hi there' })}>Notify</button>
|
|
185
|
+
<SnackbarHost store={store} />
|
|
186
|
+
</>
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Server-side rendering
|
|
192
|
+
|
|
193
|
+
`SnackbarProvider` and `SnackbarHost` render nothing until mounted, and the
|
|
194
|
+
store returns a stable server snapshot. No `window` access during render, so
|
|
195
|
+
the components are safe in Next.js, Remix and other SSR frameworks.
|
|
196
|
+
|
|
197
|
+
## Requirements
|
|
198
|
+
|
|
199
|
+
- React 18 or 19
|
|
200
|
+
- Modern evergreen browsers (CSS `backdrop-filter` degrades gracefully)
|
|
201
|
+
|
|
202
|
+
## Development
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
npm install
|
|
206
|
+
npm run dev # demo playground (Vite)
|
|
207
|
+
npm run typecheck
|
|
208
|
+
npm test
|
|
209
|
+
npm run build # ESM + CJS + d.ts + styles
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## License
|
|
213
|
+
|
|
214
|
+
MIT
|