feather-toast-vue 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.
@@ -0,0 +1,3 @@
1
+ {
2
+ "recommendations": ["Vue.volar"]
3
+ }
package/README.md ADDED
@@ -0,0 +1,286 @@
1
+ # πŸͺΆ Feather Toast
2
+
3
+ A lightweight, smooth Vue 3 toast notification plugin with minimalist design and buttery animations.
4
+
5
+ ---
6
+
7
+ ## ✨ Features
8
+
9
+ | Feature | Description |
10
+ |---------|-------------|
11
+ | 🎨 **6 Variants** | `default` · `success` · `error` · `warning` · `info` · `loading` |
12
+ | πŸ“ **6 Positions** | `top-right` Β· `top-left` Β· `top-center` Β· `bottom-right` Β· `bottom-left` Β· `bottom-center` |
13
+ | 🌊 **Smooth Animations** | Spring-based slide + fade + scale with `cubic-bezier(0.16, 1, 0.3, 1)` |
14
+ | πŸ‘† **Swipe to Dismiss** | Horizontal swipe gesture with snap-back |
15
+ | ⏸️ **Hover Pause** | Auto-dismiss timer pauses accurately on hover |
16
+ | πŸ”„ **Promise API** | `toast.promise()` β€” loading β†’ success / error |
17
+ | ⚑ **Action Button** | Optional inline action on any toast |
18
+ | 🧩 **Vue Plugin** | One-line install with `app.use(ToastPlugin)` |
19
+ | πŸ“¦ **Zero Dependencies** | Only Vue 3 β€” no Tailwind, no UI library |
20
+ | πŸ”’ **TypeScript** | Fully typed API |
21
+ | β™Ώ **Accessible** | `aria-live`, `role="alert"`, `prefers-reduced-motion` support |
22
+
23
+ ---
24
+
25
+ ## πŸ“¦ Installation
26
+
27
+ ```bash
28
+ npm install feather-toast
29
+ ```
30
+
31
+ ### Setup
32
+
33
+ ```ts
34
+ // main.ts
35
+ import { createApp } from 'vue'
36
+ import App from './App.vue'
37
+ import { ToastPlugin } from 'feather-toast/plugins/toast'
38
+ import 'feather-toast/assets/toast.css'
39
+
40
+ const app = createApp(App)
41
+ app.use(ToastPlugin)
42
+ app.mount('#app')
43
+ ```
44
+
45
+ Add `<ToastContainer />` once to your root layout:
46
+
47
+ ```vue
48
+ <!-- App.vue -->
49
+ <template>
50
+ <router-view />
51
+ <ToastContainer />
52
+ </template>
53
+ ```
54
+
55
+ ---
56
+
57
+ ## πŸš€ Usage
58
+
59
+ ### Basic
60
+
61
+ ```ts
62
+ import { useToast } from 'feather-toast/composables/useToast'
63
+
64
+ const { toast } = useToast()
65
+
66
+ toast({
67
+ title: 'Event Created',
68
+ description: 'Your event has been scheduled.',
69
+ })
70
+ ```
71
+
72
+ ### Variants
73
+
74
+ ```ts
75
+ toast.success({ title: 'Saved', description: 'Changes applied.' })
76
+ toast.error({ title: 'Error', description: 'Something went wrong.' })
77
+ toast.warning({ title: 'Warning', description: 'Disk space is low.' })
78
+ toast.info({ title: 'Info', description: 'Version 2.4 is available.' })
79
+ toast.loading({ title: 'Uploading...', description: 'Please wait.' })
80
+ ```
81
+
82
+ ### Custom Position
83
+
84
+ ```ts
85
+ toast.success({
86
+ title: 'Saved',
87
+ position: 'top-center', // default: 'bottom-right'
88
+ })
89
+ ```
90
+
91
+ ### Promise API
92
+
93
+ Automatically transitions `loading β†’ success` or `loading β†’ error`:
94
+
95
+ ```ts
96
+ toast.promise(
97
+ fetch('/api/projects', { method: 'POST' }),
98
+ {
99
+ loading: {
100
+ title: 'Creating project...',
101
+ description: 'Setting up your workspace.',
102
+ },
103
+ success: (data) => ({
104
+ title: `"${data.name}" created`,
105
+ description: 'Your project is ready.',
106
+ }),
107
+ error: (err) => ({
108
+ title: 'Failed to create project',
109
+ description: err instanceof Error ? err.message : 'Unknown error.',
110
+ }),
111
+ }
112
+ )
113
+ ```
114
+
115
+ ### Action Button
116
+
117
+ ```ts
118
+ toast({
119
+ title: 'Message archived',
120
+ description: 'Moved to archive.',
121
+ action: {
122
+ label: 'Undo',
123
+ onClick: () => {
124
+ toast.success({ title: 'Restored', description: 'Message moved back to inbox.' })
125
+ },
126
+ },
127
+ })
128
+ ```
129
+
130
+ ### Dismiss
131
+
132
+ ```ts
133
+ // Dismiss by ID
134
+ const id = toast.loading({ title: 'Working...' })
135
+ toast.dismiss(id)
136
+
137
+ // Dismiss all
138
+ toast.dismissAll()
139
+ ```
140
+
141
+ ---
142
+
143
+ ## πŸ“ API Reference
144
+
145
+ ### `useToast()`
146
+
147
+ ```ts
148
+ const { toast, toasts, dismiss, dismissAll } = useToast()
149
+ ```
150
+
151
+ | Property | Type | Description |
152
+ |----------|------|-------------|
153
+ | `toast(options)` | `(options: ToastOptions) => string` | Show a default toast, returns its ID |
154
+ | `toast.success(options)` | `Function` | Success variant |
155
+ | `toast.error(options)` | `Function` | Error variant |
156
+ | `toast.warning(options)` | `Function` | Warning variant |
157
+ | `toast.info(options)` | `Function` | Info variant |
158
+ | `toast.loading(options)` | `Function` | Loading variant β€” no auto-dismiss |
159
+ | `toast.promise(promise, opts)` | `Function` | Promise-based toast flow |
160
+ | `toast.dismiss(id)` | `Function` | Dismiss a specific toast by ID |
161
+ | `toast.dismissAll()` | `Function` | Dismiss all active toasts |
162
+ | `toasts` | `Ref<Toast[]>` | Reactive list of all active toasts |
163
+
164
+ ---
165
+
166
+ ### `ToastOptions`
167
+
168
+ ```ts
169
+ interface ToastOptions {
170
+ title?: string
171
+ description?: string
172
+ variant?: 'default' | 'success' | 'error' | 'warning' | 'info' | 'loading'
173
+ position?: 'top-right' | 'top-left' | 'top-center'
174
+ | 'bottom-right' | 'bottom-left' | 'bottom-center'
175
+ duration?: number // ms Β· default: 5000 Β· loading: Infinity
176
+ dismissible?: boolean // default: true (false for loading)
177
+ action?: {
178
+ label: string
179
+ onClick: () => void
180
+ }
181
+ }
182
+ ```
183
+
184
+ ---
185
+
186
+ ### Positions
187
+
188
+ ```
189
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
190
+ β”‚ top-left β”‚ top-center β”‚ top-right β”‚
191
+ β”‚ β”‚ β”‚ β”‚
192
+ β”‚ β”‚ β”‚ β”‚
193
+ β”‚ bot-left β”‚ bot-center β”‚ bot-right β”‚
194
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
195
+ ```
196
+
197
+ ---
198
+
199
+ ## 🎨 Design System
200
+
201
+ ### Color Tokens
202
+
203
+ | Token | Value | Usage |
204
+ |-------|-------|-------|
205
+ | `--toast-bg` | `#ffffff` | Card background |
206
+ | `--toast-border` | `#e4e4e7` | Card border |
207
+ | `--toast-text` | `#18181b` | Title text |
208
+ | `--toast-text-muted` | `#71717a` | Description text |
209
+ | `--toast-shadow` | `0 2px 8px rgba(0,0,0,0.06)` | Card elevation |
210
+ | `--toast-radius` | `10px` | Card border radius |
211
+ | `--toast-width` | `360px` | Card width |
212
+
213
+ ### Icon Accent Colors
214
+
215
+ | Variant | Color | Hex |
216
+ |---------|-------|-----|
217
+ | Success | 🟒 Green | `#16a34a` |
218
+ | Error | πŸ”΄ Red | `#dc2626` |
219
+ | Warning | 🟑 Amber | `#d97706` |
220
+ | Info | πŸ”΅ Blue | `#2563eb` |
221
+ | Loading | ⚫ Gray | `#71717a` |
222
+
223
+ ### Customization via CSS Variables
224
+
225
+ ```css
226
+ /* Override in your global CSS */
227
+ :root {
228
+ --toast-bg: #ffffff;
229
+ --toast-border: #e4e4e7;
230
+ --toast-text: #18181b;
231
+ --toast-text-muted: #71717a;
232
+ --toast-radius: 10px;
233
+ --toast-width: 360px;
234
+ --toast-gap: 8px;
235
+ --toast-shadow: 0 2px 8px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.04);
236
+ }
237
+ ```
238
+
239
+ ---
240
+
241
+ ## 🎬 Animation Spec
242
+
243
+ | Phase | Duration | Easing |
244
+ |-------|----------|--------|
245
+ | **Enter** | 400ms | `cubic-bezier(0.16, 1, 0.3, 1)` β€” spring |
246
+ | **Exit** | 220ms | `cubic-bezier(0.4, 0, 1, 1)` β€” snappy |
247
+ | **Sibling reflow** | 350ms | `cubic-bezier(0.16, 1, 0.3, 1)` β€” spring |
248
+ | **Swipe snap-back** | 360ms | `cubic-bezier(0.16, 1, 0.3, 1)` β€” spring |
249
+
250
+ ---
251
+
252
+ ## πŸ“ File Structure
253
+
254
+ ```
255
+ src/
256
+ β”œβ”€β”€ assets/
257
+ β”‚ └── toast.css # All styles & animations
258
+ β”œβ”€β”€ components/
259
+ β”‚ β”œβ”€β”€ Toast.vue # Individual toast card
260
+ β”‚ └── ToastContainer.vue # Positional viewport manager
261
+ β”œβ”€β”€ composables/
262
+ β”‚ └── useToast.ts # Reactive toast API
263
+ β”œβ”€β”€ plugins/
264
+ β”‚ └── toast.ts # Vue plugin (app.use)
265
+ β”œβ”€β”€ types/
266
+ β”‚ └── toast.ts # TypeScript interfaces
267
+ └── main.ts # App entry point
268
+ ```
269
+
270
+ ---
271
+
272
+ ## πŸ“Š Bundle Size
273
+
274
+ | File | Raw | Gzipped |
275
+ |------|-----|---------|
276
+ | JS (all files) | ~12 KB | ~4 KB |
277
+ | CSS | ~6 KB | ~2 KB |
278
+ | **Total** | **~18 KB** | **~6 KB** |
279
+
280
+ Zero external dependencies beyond Vue 3.
281
+
282
+ ---
283
+
284
+ ## πŸ“„ License
285
+
286
+ MIT Β© feather-toast
package/desktop.ini ADDED
@@ -0,0 +1,2 @@
1
+ [.ShellClassInfo]
2
+ LocalizedResourceName=@vue-toast,0
package/env.d.ts ADDED
@@ -0,0 +1 @@
1
+ /// <reference types="vite/client" />
package/index.html ADDED
@@ -0,0 +1,15 @@
1
+ <!DOCTYPE html>
2
+ <html lang="">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>πŸͺΆ</text></svg>">
7
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
8
+ <title>feather-toast demo</title>
9
+ </head>
10
+
11
+ <body>
12
+ <div id="app"></div>
13
+ <script type="module" src="/src/main.ts"></script>
14
+ </body>
15
+ </html>
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "feather-toast-vue",
3
+ "version": "1.0.0",
4
+ "description": "A lightweight, smooth Vue 3 toast notification plugin",
5
+ "homepage": "https://zin-ix.github.io/feather-toast/",
6
+ "type": "module",
7
+ "scripts": {
8
+ "dev": "vite",
9
+ "build": "npm-run-all type-check build-only",
10
+ "build-only": "vite build",
11
+ "preview": "vite preview",
12
+ "type-check": "vue-tsc --build",
13
+ "deploy": "npm run build && gh-pages -d dist"
14
+ },
15
+ "dependencies": {
16
+ "vue": "^3.5.32"
17
+ },
18
+ "devDependencies": {
19
+ "@tsconfig/node24": "^24.0.4",
20
+ "@types/node": "^24.12.2",
21
+ "@vitejs/plugin-vue": "^6.0.6",
22
+ "@vue/tsconfig": "^0.9.1",
23
+ "gh-pages": "^6.3.0",
24
+ "npm-run-all2": "^8.0.4",
25
+ "typescript": "~6.0.0",
26
+ "vite": "^8.0.8",
27
+ "vite-plugin-vue-devtools": "^8.1.1",
28
+ "vue-tsc": "^3.2.6"
29
+ },
30
+ "engines": {
31
+ "node": "^20.19.0 || >=22.12.0"
32
+ }
33
+ }
Binary file