vue-notifyr 0.1.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/LICENCE ADDED
@@ -0,0 +1,21 @@
1
+ # MIT License
2
+
3
+ Copyright (c) 2025 Rayhan Bapari
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 ADDED
@@ -0,0 +1,226 @@
1
+ # vue-notifyr
2
+
3
+ > Framework-agnostic notification library for **Vue 3**, **Nuxt 3**, and **Laravel Inertia**
4
+
5
+ [![npm version](https://badge.fury.io/js/vue-notifyr.svg)](https://badge.fury.io/js/vue-notifyr)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+ [![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
8
+
9
+ ---
10
+
11
+ ## ✨ Features
12
+
13
+ - 🚀 **Framework-Agnostic**: Core logic works without any framework dependencies
14
+ - ⚡ **Simple API**: `notificationManager.success('Title')`
15
+ - 🎨 **Clean Design**: Modern notification UI with smooth animations
16
+ - 📍 **6 Positions**: top/bottom left/center/right placement
17
+ - ⏳ **Auto-Close**: Configurable timing with progress indicators
18
+ - 🧩 **TypeScript**: Full type safety with strict mode
19
+ - 🌳 **Tree-Shakable**: Import only what you need
20
+ - 🔧 **Multiple Frameworks**: Vue 3, Nuxt 3, Laravel Inertia support
21
+
22
+ ---
23
+
24
+ ## 📦 Installation
25
+
26
+ ```bash
27
+ npm install vue-notifyr
28
+ # or
29
+ yarn add vue-notifyr
30
+ # or
31
+ pnpm add vue-notifyr
32
+ ```
33
+
34
+ ## 🚀 Quick Start
35
+
36
+ ### Vue 3 (Standalone)
37
+
38
+ ```typescript
39
+ import { createApp } from 'vue';
40
+ import App from './App.vue';
41
+ import { createVueNotificationPlugin } from 'vue-notifyr';
42
+ import 'vue-notifyr/style.css';
43
+
44
+ const app = createApp(App);
45
+ app.use(createVueNotificationPlugin());
46
+ app.mount('#app');
47
+ ```
48
+
49
+ ```vue
50
+ <script setup lang="ts">
51
+ import { useNotification } from 'vue-notifyr';
52
+ import NotificationContainer from 'vue-notifyr/vue';
53
+
54
+ const notification = useNotification();
55
+
56
+ const showSuccess = () => {
57
+ notification.success('Operation completed successfully!');
58
+ };
59
+ </script>
60
+
61
+ <template>
62
+ <div>
63
+ <button @click="showSuccess">Show Success</button>
64
+ <NotificationContainer />
65
+ </div>
66
+ </template>
67
+ ```
68
+
69
+ ### Nuxt 3
70
+
71
+ ```typescript
72
+ // nuxt.config.ts
73
+ export default defineNuxtConfig({
74
+ modules: ['vue-notifyr/nuxt'],
75
+ css: ['vue-notifyr/style.css'],
76
+ });
77
+ ```
78
+
79
+ ```vue
80
+ <!-- app.vue -->
81
+ <template>
82
+ <div>
83
+ <NuxtPage />
84
+ <NotificationContainer />
85
+ </div>
86
+ </template>
87
+
88
+ <script setup>
89
+ import { NotificationContainer } from 'vue-notifyr';
90
+ </script>
91
+ ```
92
+
93
+ ```vue
94
+ <!-- pages/index.vue -->
95
+ <script setup lang="ts">
96
+ const notification = useNotification();
97
+
98
+ const handleAction = () => {
99
+ notification.success('Action completed!');
100
+ };
101
+ </script>
102
+
103
+ <template>
104
+ <button @click="handleAction">Do Something</button>
105
+ </template>
106
+ ```
107
+
108
+ ### Laravel Inertia
109
+
110
+ ```typescript
111
+ // app.js
112
+ import { createInertiaApp } from '@inertiajs/vue3';
113
+ import { createVueNotificationPlugin } from 'vue-notifyr';
114
+ import 'vue-notifyr/style.css';
115
+
116
+ createInertiaApp({
117
+ resolve: (name) => require(`./Pages/${name}`),
118
+ setup({ el, App, props, plugin }) {
119
+ createApp({ render: () => h(App, props) })
120
+ .use(plugin)
121
+ .use(createVueNotificationPlugin())
122
+ .mount(el);
123
+ },
124
+ });
125
+ ```
126
+
127
+ ```vue
128
+ <!-- Layout -->
129
+ <template>
130
+ <main>
131
+ <slot />
132
+ </main>
133
+ <NotificationContainer />
134
+ </template>
135
+
136
+ <script setup>
137
+ import { NotificationContainer } from 'vue-notifyr';
138
+ </script>
139
+ ```
140
+
141
+ ## 💬 API Reference
142
+
143
+ ### NotificationManager
144
+
145
+ ```typescript
146
+ import { NotificationManager } from 'vue-notifyr';
147
+
148
+ const manager = new NotificationManager();
149
+
150
+ // Show notifications
151
+ manager.success('Success message');
152
+ manager.error('Error message');
153
+ manager.warning('Warning message');
154
+ manager.info('Info message');
155
+
156
+ // Custom options
157
+ manager.success('Custom notification', {
158
+ position: 'bottom-right',
159
+ autoClose: 5000,
160
+ progress: false,
161
+ });
162
+
163
+ // Set global defaults
164
+ manager.setDefaults({
165
+ position: 'top-right',
166
+ autoClose: 4000,
167
+ });
168
+
169
+ // Manual control
170
+ const notifications = manager.getNotifications();
171
+ manager.remove(notificationId);
172
+ manager.clear();
173
+ ```
174
+
175
+ ### Vue Composable
176
+
177
+ ```typescript
178
+ import { useNotification } from 'vue-notifyr';
179
+
180
+ const notification = useNotification();
181
+
182
+ // All methods available
183
+ notification.success('Success!');
184
+ notification.error('Error!');
185
+ notification.warning('Warning!');
186
+ notification.info('Info!');
187
+ ```
188
+
189
+ ## ⚙️ Configuration Options
190
+
191
+ | Option | Type | Default | Description |
192
+ | ----------- | ------------------------------------------------------------------------------------------------- | -------------- | ------------------------------------------- |
193
+ | `position` | `"top-left" \| "top-center" \| "top-right" \| "bottom-left" \| "bottom-center" \| "bottom-right"` | `"top-center"` | Notification placement |
194
+ | `autoClose` | `number \| false` | `3000` | Auto close delay (ms) or `false` to disable |
195
+ | `progress` | `boolean` | `true` | Show bottom progress bar |
196
+
197
+ ## 🏗️ Architecture
198
+
199
+ ```
200
+ vue-notifyr/
201
+ ├── core/ # Framework-agnostic logic
202
+ │ └── notification-manager.ts
203
+ ├── adapters/ # Framework-specific integrations
204
+ │ ├── vue/
205
+ │ ├── nuxt/
206
+ │ └── inertia/
207
+ ├── composables/ # Vue composables
208
+ ├── components/ # Vue components
209
+ ├── types/ # TypeScript definitions
210
+ └── styles/ # CSS styles
211
+ ```
212
+
213
+ ## 🤝 Contributing
214
+
215
+ We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
216
+
217
+ ## 📄 License
218
+
219
+ MIT License - see [LICENSE](LICENSE) file for details.
220
+
221
+ ## 🙏 Acknowledgments
222
+
223
+ Inspired by Toastr and other notification libraries. Built with modern web technologies.
224
+
225
+ # vue-notifyr
226
+ # vue-notifyr
package/dist/index.cjs ADDED
@@ -0,0 +1,355 @@
1
+ (function (global, factory) {
2
+ typeof exports === 'object' && typeof module !== 'undefined'
3
+ ? factory(exports, require('vue'))
4
+ : typeof define === 'function' && define.amd
5
+ ? define(['exports', 'vue'], factory)
6
+ : ((global = typeof globalThis !== 'undefined' ? globalThis : global || self),
7
+ factory((global.VueNotifyr = {}), global.Vue));
8
+ })(this, function (exports2, vue) {
9
+ 'use strict';
10
+ const DEFAULT_OPTIONS = {
11
+ position: 'top-center',
12
+ autoClose: 3e3,
13
+ progress: true,
14
+ };
15
+ class NotificationManager {
16
+ constructor() {
17
+ this.notifications = [];
18
+ this.options = { ...DEFAULT_OPTIONS };
19
+ this.listeners = {};
20
+ this.idCounter = 1;
21
+ }
22
+ /**
23
+ * Subscribe to an event.
24
+ * @param event - The event name ('notification-added', 'notification-removed', 'notifications-cleared', 'options-changed')
25
+ * @param callback - The callback function
26
+ */
27
+ on(event, callback) {
28
+ if (!this.listeners[event]) {
29
+ this.listeners[event] = [];
30
+ }
31
+ this.listeners[event].push(callback);
32
+ }
33
+ /**
34
+ * Unsubscribe from an event.
35
+ * @param event - The event name
36
+ * @param callback - The callback function to remove
37
+ */
38
+ off(event, callback) {
39
+ if (this.listeners[event]) {
40
+ this.listeners[event] = this.listeners[event].filter((cb) => cb !== callback);
41
+ }
42
+ }
43
+ emit(event, data) {
44
+ if (this.listeners[event]) {
45
+ this.listeners[event].forEach((callback) => callback(data));
46
+ }
47
+ }
48
+ /**
49
+ * Set default options for notifications.
50
+ * @param opts - The options to set as defaults
51
+ */
52
+ setDefaults(opts) {
53
+ this.options = { ...this.options, ...opts };
54
+ this.emit('options-changed', this.options);
55
+ }
56
+ /**
57
+ * Show a notification.
58
+ * @param type - The type of notification
59
+ * @param title - The title/message of the notification
60
+ * @param opts - Optional override options
61
+ */
62
+ show(type, title, opts) {
63
+ const options = { ...this.options, ...(opts || {}) };
64
+ const item = {
65
+ id: this.idCounter++,
66
+ type,
67
+ title,
68
+ options,
69
+ createdAt: Date.now(),
70
+ };
71
+ this.notifications.push(item);
72
+ this.emit('notification-added', item);
73
+ if (options.autoClose !== false && typeof window !== 'undefined') {
74
+ setTimeout(() => this.remove(item.id), options.autoClose);
75
+ }
76
+ }
77
+ /**
78
+ * Remove a notification by ID.
79
+ * @param id - The ID of the notification to remove
80
+ */
81
+ remove(id) {
82
+ const index = this.notifications.findIndex((n) => n.id === id);
83
+ if (index !== -1) {
84
+ const removed = this.notifications.splice(index, 1)[0];
85
+ this.emit('notification-removed', removed);
86
+ }
87
+ }
88
+ /**
89
+ * Clear all notifications.
90
+ */
91
+ clear() {
92
+ const removed = [...this.notifications];
93
+ this.notifications.splice(0);
94
+ this.emit('notifications-cleared', removed);
95
+ }
96
+ /**
97
+ * Get a copy of the current notifications.
98
+ * @returns Array of notification items
99
+ */
100
+ getNotifications() {
101
+ return [...this.notifications];
102
+ }
103
+ /**
104
+ * Get the current default options.
105
+ * @returns The default options
106
+ */
107
+ getOptions() {
108
+ return { ...this.options };
109
+ }
110
+ /**
111
+ * Success notification shorthand.
112
+ * @param title - The title/message
113
+ * @param opts - Optional options
114
+ */
115
+ success(title, opts) {
116
+ this.show('success', title, opts);
117
+ }
118
+ /**
119
+ * Error notification shorthand.
120
+ * @param title - The title/message
121
+ * @param opts - Optional options
122
+ */
123
+ error(title, opts) {
124
+ this.show('error', title, opts);
125
+ }
126
+ /**
127
+ * Warning notification shorthand.
128
+ * @param title - The title/message
129
+ * @param opts - Optional options
130
+ */
131
+ warning(title, opts) {
132
+ this.show('warning', title, opts);
133
+ }
134
+ /**
135
+ * Info notification shorthand.
136
+ * @param title - The title/message
137
+ * @param opts - Optional options
138
+ */
139
+ info(title, opts) {
140
+ this.show('info', title, opts);
141
+ }
142
+ }
143
+ const notificationManager = new NotificationManager();
144
+ function createReactiveNotificationStore(manager = notificationManager) {
145
+ const store = vue.reactive({
146
+ notifications: manager.getNotifications(),
147
+ options: manager.getOptions(),
148
+ });
149
+ manager.on('notification-added', () => {
150
+ store.notifications = manager.getNotifications();
151
+ });
152
+ manager.on('notification-removed', () => {
153
+ store.notifications = manager.getNotifications();
154
+ });
155
+ manager.on('notifications-cleared', () => {
156
+ store.notifications = manager.getNotifications();
157
+ });
158
+ manager.on('options-changed', () => {
159
+ store.options = manager.getOptions();
160
+ });
161
+ return store;
162
+ }
163
+ const notificationStore = createReactiveNotificationStore();
164
+ function useNotificationManager(manager = notificationManager) {
165
+ return {
166
+ success: (title, opts) => manager.success(title, opts),
167
+ error: (title, opts) => manager.error(title, opts),
168
+ warning: (title, opts) => manager.warning(title, opts),
169
+ info: (title, opts) => manager.info(title, opts),
170
+ show: (type, title, opts) => manager.show(type, title, opts),
171
+ remove: (id) => manager.remove(id),
172
+ clear: () => manager.clear(),
173
+ setDefaults: (opts) => manager.setDefaults(opts),
174
+ getNotifications: () => manager.getNotifications(),
175
+ getOptions: () => manager.getOptions(),
176
+ };
177
+ }
178
+ function createVueNotificationPlugin$1(manager = notificationManager) {
179
+ return {
180
+ install(app) {
181
+ app.config.globalProperties.$notificationManager = manager;
182
+ app.provide('notificationManager', manager);
183
+ },
184
+ };
185
+ }
186
+ const _hoisted_1 = ['data-position'];
187
+ const _hoisted_2 = { class: 'notification-content' };
188
+ const _hoisted_3 = { class: 'notification-title' };
189
+ const _hoisted_4 = { class: 'notification-close' };
190
+ const _hoisted_5 = ['onClick'];
191
+ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
192
+ __name: 'NotificationContainer',
193
+ setup(__props) {
194
+ const isClient = vue.ref(false);
195
+ if (typeof window !== 'undefined') {
196
+ isClient.value = true;
197
+ }
198
+ const groups = vue.computed(() => {
199
+ const map = {
200
+ 'top-left': [],
201
+ 'top-center': [],
202
+ 'top-right': [],
203
+ 'bottom-left': [],
204
+ 'bottom-center': [],
205
+ 'bottom-right': [],
206
+ };
207
+ for (const notification of notificationStore.notifications) {
208
+ map[notification.options.position].push(notification);
209
+ }
210
+ return map;
211
+ });
212
+ function removeNotification(id) {
213
+ notificationManager.remove(id);
214
+ }
215
+ return (_ctx, _cache) => {
216
+ return isClient.value
217
+ ? (vue.openBlock(),
218
+ vue.createBlock(
219
+ vue.Teleport,
220
+ {
221
+ key: 0,
222
+ to: 'body',
223
+ },
224
+ [
225
+ (vue.openBlock(true),
226
+ vue.createElementBlock(
227
+ vue.Fragment,
228
+ null,
229
+ vue.renderList(groups.value, (items, pos) => {
230
+ return (
231
+ vue.openBlock(),
232
+ vue.createBlock(
233
+ vue.TransitionGroup,
234
+ {
235
+ key: pos,
236
+ tag: 'div',
237
+ name: 'notification',
238
+ class: 'notification-list',
239
+ 'data-position': pos,
240
+ },
241
+ {
242
+ default: vue.withCtx(() => [
243
+ (vue.openBlock(true),
244
+ vue.createElementBlock(
245
+ vue.Fragment,
246
+ null,
247
+ vue.renderList(items, (notification) => {
248
+ return (
249
+ vue.openBlock(),
250
+ vue.createElementBlock(
251
+ 'article',
252
+ {
253
+ key: notification.id,
254
+ class: vue.normalizeClass([
255
+ 'notification',
256
+ [
257
+ `notification-${notification.type}`,
258
+ {
259
+ 'notification-auto-close':
260
+ notification.options.progress &&
261
+ notification.options.autoClose !== false,
262
+ },
263
+ ],
264
+ ]),
265
+ 'data-position': pos,
266
+ },
267
+ [
268
+ vue.createElementVNode('div', _hoisted_2, [
269
+ vue.createElementVNode(
270
+ 'span',
271
+ _hoisted_3,
272
+ vue.toDisplayString(notification.title),
273
+ 1
274
+ ),
275
+ ]),
276
+ notification.options.progress &&
277
+ notification.options.autoClose !== false
278
+ ? (vue.openBlock(),
279
+ vue.createElementBlock(
280
+ 'div',
281
+ {
282
+ key: 0,
283
+ class: 'notification-progress',
284
+ style: vue.normalizeStyle({
285
+ animationDuration:
286
+ (notification.options.autoClose || 0) + 'ms',
287
+ }),
288
+ },
289
+ null,
290
+ 4
291
+ ))
292
+ : vue.createCommentVNode('', true),
293
+ vue.createElementVNode('div', _hoisted_4, [
294
+ vue.createElementVNode(
295
+ 'button',
296
+ {
297
+ type: 'button',
298
+ onClick: ($event) =>
299
+ removeNotification(notification.id),
300
+ 'aria-label': 'Dismiss notification',
301
+ },
302
+ ' × ',
303
+ 8,
304
+ _hoisted_5
305
+ ),
306
+ ]),
307
+ ],
308
+ 10,
309
+ _hoisted_1
310
+ )
311
+ );
312
+ }),
313
+ 128
314
+ )),
315
+ ]),
316
+ _: 2,
317
+ },
318
+ 1032,
319
+ ['data-position']
320
+ )
321
+ );
322
+ }),
323
+ 128
324
+ )),
325
+ ]
326
+ ))
327
+ : vue.createCommentVNode('', true);
328
+ };
329
+ },
330
+ });
331
+ function useNotification() {
332
+ return useNotificationManager();
333
+ }
334
+ defineNuxtPlugin((nuxtApp) => {
335
+ nuxtApp.vueApp.use(createVueNotificationPlugin(notificationManager));
336
+ });
337
+ function createVueNotificationPlugin(manager) {
338
+ return {
339
+ install(app) {
340
+ app.config.globalProperties.$notificationManager = manager;
341
+ app.provide('notificationManager', manager);
342
+ },
343
+ };
344
+ }
345
+ exports2.NotificationContainer = _sfc_main;
346
+ exports2.NotificationManager = NotificationManager;
347
+ exports2.createReactiveNotificationStore = createReactiveNotificationStore;
348
+ exports2.createVueNotificationPlugin = createVueNotificationPlugin$1;
349
+ exports2.notificationManager = notificationManager;
350
+ exports2.notificationStore = notificationStore;
351
+ exports2.useNotification = useNotification;
352
+ exports2.useNotificationManager = useNotificationManager;
353
+ Object.defineProperty(exports2, Symbol.toStringTag, { value: 'Module' });
354
+ });
355
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sources":["../src/core/notification-manager.ts","../src/adapters/vue/index.ts","../src/adapters/vue/NotificationContainer.vue","../src/composables/useNotification.ts","../src/adapters/nuxt/index.ts"],"sourcesContent":["import type { NotificationType, NotificationOptions, NotificationItem } from '../types';\n\nconst DEFAULT_OPTIONS: Required<NotificationOptions> = {\n position: 'top-center',\n autoClose: 3000,\n progress: true,\n};\n\nexport class NotificationManager {\n private notifications: NotificationItem[] = [];\n private options: Required<NotificationOptions> = { ...DEFAULT_OPTIONS };\n private listeners: { [event: string]: Function[] } = {};\n private idCounter = 1;\n\n /**\n * Subscribe to an event.\n * @param event - The event name ('notification-added', 'notification-removed', 'notifications-cleared', 'options-changed')\n * @param callback - The callback function\n */\n on(event: string, callback: Function): void {\n if (!this.listeners[event]) {\n this.listeners[event] = [];\n }\n this.listeners[event].push(callback);\n }\n\n /**\n * Unsubscribe from an event.\n * @param event - The event name\n * @param callback - The callback function to remove\n */\n off(event: string, callback: Function): void {\n if (this.listeners[event]) {\n this.listeners[event] = this.listeners[event].filter((cb) => cb !== callback);\n }\n }\n\n private emit(event: string, data?: any): void {\n if (this.listeners[event]) {\n this.listeners[event].forEach((callback) => callback(data));\n }\n }\n\n /**\n * Set default options for notifications.\n * @param opts - The options to set as defaults\n */\n setDefaults(opts: NotificationOptions): void {\n this.options = { ...this.options, ...opts };\n this.emit('options-changed', this.options);\n }\n\n /**\n * Show a notification.\n * @param type - The type of notification\n * @param title - The title/message of the notification\n * @param opts - Optional override options\n */\n show(type: NotificationType, title: string, opts?: NotificationOptions): void {\n const options = { ...this.options, ...(opts || {}) };\n const item: NotificationItem = {\n id: this.idCounter++,\n type,\n title,\n options,\n createdAt: Date.now(),\n };\n this.notifications.push(item);\n this.emit('notification-added', item);\n\n if (options.autoClose !== false && typeof window !== 'undefined') {\n setTimeout(() => this.remove(item.id), options.autoClose);\n }\n }\n\n /**\n * Remove a notification by ID.\n * @param id - The ID of the notification to remove\n */\n remove(id: number): void {\n const index = this.notifications.findIndex((n) => n.id === id);\n if (index !== -1) {\n const removed = this.notifications.splice(index, 1)[0];\n this.emit('notification-removed', removed);\n }\n }\n\n /**\n * Clear all notifications.\n */\n clear(): void {\n const removed = [...this.notifications];\n this.notifications.splice(0);\n this.emit('notifications-cleared', removed);\n }\n\n /**\n * Get a copy of the current notifications.\n * @returns Array of notification items\n */\n getNotifications(): NotificationItem[] {\n return [...this.notifications];\n }\n\n /**\n * Get the current default options.\n * @returns The default options\n */\n getOptions(): Required<NotificationOptions> {\n return { ...this.options };\n }\n\n /**\n * Success notification shorthand.\n * @param title - The title/message\n * @param opts - Optional options\n */\n success(title: string, opts?: NotificationOptions): void {\n this.show('success', title, opts);\n }\n\n /**\n * Error notification shorthand.\n * @param title - The title/message\n * @param opts - Optional options\n */\n error(title: string, opts?: NotificationOptions): void {\n this.show('error', title, opts);\n }\n\n /**\n * Warning notification shorthand.\n * @param title - The title/message\n * @param opts - Optional options\n */\n warning(title: string, opts?: NotificationOptions): void {\n this.show('warning', title, opts);\n }\n\n /**\n * Info notification shorthand.\n * @param title - The title/message\n * @param opts - Optional options\n */\n info(title: string, opts?: NotificationOptions): void {\n this.show('info', title, opts);\n }\n}\n\n// Default instance for convenience\nexport const notificationManager = new NotificationManager();\n","import { reactive, watchEffect } from 'vue';\nimport { NotificationManager, notificationManager } from '../../core/notification-manager';\nimport type { NotificationItem, NotificationOptions } from '../../types';\n\nexport interface ReactiveNotificationStore {\n notifications: NotificationItem[];\n options: NotificationOptions;\n}\n\n/**\n * Create a reactive store for Vue that syncs with the NotificationManager.\n * @param manager - The NotificationManager instance (optional, uses default if not provided)\n * @returns Reactive store\n */\nexport function createReactiveNotificationStore(\n manager: NotificationManager = notificationManager\n): ReactiveNotificationStore {\n const store = reactive({\n notifications: manager.getNotifications(),\n options: manager.getOptions(),\n });\n\n // Sync notifications\n manager.on('notification-added', () => {\n store.notifications = manager.getNotifications();\n });\n manager.on('notification-removed', () => {\n store.notifications = manager.getNotifications();\n });\n manager.on('notifications-cleared', () => {\n store.notifications = manager.getNotifications();\n });\n\n // Sync options\n manager.on('options-changed', () => {\n store.options = manager.getOptions();\n });\n\n return store;\n}\n\n// Default reactive store\nexport const notificationStore = createReactiveNotificationStore();\n\n// Vue composable\nexport function useNotificationManager(manager: NotificationManager = notificationManager) {\n return {\n success: (title: string, opts?: NotificationOptions) => manager.success(title, opts),\n error: (title: string, opts?: NotificationOptions) => manager.error(title, opts),\n warning: (title: string, opts?: NotificationOptions) => manager.warning(title, opts),\n info: (title: string, opts?: NotificationOptions) => manager.info(title, opts),\n show: (type: string, title: string, opts?: NotificationOptions) =>\n manager.show(type as any, title, opts),\n remove: (id: number) => manager.remove(id),\n clear: () => manager.clear(),\n setDefaults: (opts: NotificationOptions) => manager.setDefaults(opts),\n getNotifications: () => manager.getNotifications(),\n getOptions: () => manager.getOptions(),\n };\n}\n\n// Vue plugin\nexport function createVueNotificationPlugin(manager: NotificationManager = notificationManager) {\n return {\n install(app: any) {\n app.config.globalProperties.$notificationManager = manager;\n app.provide('notificationManager', manager);\n },\n };\n}\n","<script setup lang=\"ts\">\nimport { computed, ref } from 'vue';\nimport { notificationStore } from './index';\nimport { notificationManager } from '../../core/notification-manager';\nimport type { NotificationItem, NotificationPosition } from '../../types';\n\nconst isClient = ref(false);\n\nif (typeof window !== 'undefined') {\n isClient.value = true;\n}\n\nconst groups = computed<Record<NotificationPosition, NotificationItem[]>>(() => {\n const map: Record<NotificationPosition, NotificationItem[]> = {\n 'top-left': [],\n 'top-center': [],\n 'top-right': [],\n 'bottom-left': [],\n 'bottom-center': [],\n 'bottom-right': [],\n };\n for (const notification of notificationStore.notifications) {\n map[notification.options.position].push(notification);\n }\n return map;\n});\n\nfunction removeNotification(id: number) {\n notificationManager.remove(id);\n}\n</script>\n\n<template>\n <Teleport v-if=\"isClient\" to=\"body\">\n <TransitionGroup\n v-for=\"(items, pos) in groups\"\n :key=\"pos\"\n tag=\"div\"\n name=\"notification\"\n class=\"notification-list\"\n :data-position=\"pos\"\n >\n <article\n v-for=\"notification in items\"\n :key=\"notification.id\"\n class=\"notification\"\n :class=\"[\n `notification-${notification.type}`,\n {\n 'notification-auto-close':\n notification.options.progress && notification.options.autoClose !== false,\n },\n ]\"\n :data-position=\"pos\"\n >\n <div class=\"notification-content\">\n <span class=\"notification-title\">{{ notification.title }}</span>\n </div>\n\n <div\n v-if=\"notification.options.progress && notification.options.autoClose !== false\"\n class=\"notification-progress\"\n :style=\"{ animationDuration: (notification.options.autoClose || 0) + 'ms' }\"\n ></div>\n\n <div class=\"notification-close\">\n <button\n type=\"button\"\n @click=\"removeNotification(notification.id)\"\n aria-label=\"Dismiss notification\"\n >\n ×\n </button>\n </div>\n </article>\n </TransitionGroup>\n </Teleport>\n</template>\n","import { useNotificationManager } from '../adapters/vue';\n\n/**\n * Vue composable for notification management.\n * Provides a clean API to show notifications in Vue components.\n *\n * @returns Notification manager API\n */\nexport function useNotification() {\n return useNotificationManager();\n}\n","import { notificationManager } from '../../core/notification-manager';\n\n/**\n * Nuxt plugin for notification management.\n * Integrates the notification manager into Nuxt applications.\n */\nexport default defineNuxtPlugin((nuxtApp) => {\n nuxtApp.vueApp.use(createVueNotificationPlugin(notificationManager));\n});\n\n/**\n * Create Vue plugin for Nuxt (internal use).\n */\nfunction createVueNotificationPlugin(manager: any) {\n return {\n install(app: any) {\n app.config.globalProperties.$notificationManager = manager;\n app.provide('notificationManager', manager);\n },\n };\n}\n\n// Re-export Vue adapter functions for convenience\nexport { useNotificationManager, createReactiveNotificationStore, notificationStore } from '../vue';\n"],"names":["reactive","createVueNotificationPlugin","ref","computed","_createBlock","_Teleport","_openBlock","_createElementBlock","_Fragment","_renderList","_TransitionGroup","_createElementVNode","_toDisplayString","_normalizeStyle"],"mappings":"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"}