@rosadorito/vue-toast 0.0.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 +311 -0
- package/dist/components/Toast/Toast.vue.d.ts +10 -0
- package/dist/components/Toast/Toast.vue.d.ts.map +1 -0
- package/dist/components/Toast/index.d.ts +4 -0
- package/dist/components/Toast/index.d.ts.map +1 -0
- package/dist/composables/useToast.d.ts +20 -0
- package/dist/composables/useToast.d.ts.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/types/index.d.ts +18 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/vue-toast.css +1 -0
- package/dist/vue-toast.es.js +233 -0
- package/dist/vue-toast.es.js.map +1 -0
- package/dist/vue-toast.umd.js +2 -0
- package/dist/vue-toast.umd.js.map +1 -0
- package/package.json +77 -0
package/README.md
ADDED
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
# Vue Toast
|
|
2
|
+
|
|
3
|
+
A lightweight, customizable toast notification library for Vue 3.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- ๐จ **Multiple toast types**: Success, Error, Warning, Info, and Default
|
|
8
|
+
- ๐ **Flexible positioning**: 6 different positions (top/bottom-left/center/right)
|
|
9
|
+
- โฑ๏ธ **Auto-dismiss**: Configurable duration with auto-removal
|
|
10
|
+
- ๐ฏ **Programmatic API**: Use via composable or global plugin
|
|
11
|
+
- โฟ **Accessible**: ARIA labels and proper semantic markup
|
|
12
|
+
- ๐ฑ **Responsive**: Works on mobile and desktop
|
|
13
|
+
- ๐จ **Customizable**: Style with CSS custom properties
|
|
14
|
+
- ๐งช **TypeScript**: Full TypeScript support
|
|
15
|
+
- ๐ณ **Tree-shakable**: Only import what you need
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install vue-toast
|
|
21
|
+
# or
|
|
22
|
+
yarn add vue-toast
|
|
23
|
+
# or
|
|
24
|
+
pnpm add vue-toast
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
28
|
+
|
|
29
|
+
### As a Plugin (Global)
|
|
30
|
+
|
|
31
|
+
```javascript
|
|
32
|
+
import { createApp } from 'vue'
|
|
33
|
+
import App from './App.vue'
|
|
34
|
+
import VueToast from 'vue-toast'
|
|
35
|
+
|
|
36
|
+
const app = createApp(App)
|
|
37
|
+
app.use(VueToast)
|
|
38
|
+
app.mount('#app')
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Now you can use it anywhere in your components:
|
|
42
|
+
|
|
43
|
+
```vue
|
|
44
|
+
<template>
|
|
45
|
+
<button @click="showToast">Show Toast</button>
|
|
46
|
+
</template>
|
|
47
|
+
|
|
48
|
+
<script setup>
|
|
49
|
+
const showToast = () => {
|
|
50
|
+
// Using global $toast
|
|
51
|
+
this.$toast.success('Operation completed successfully!')
|
|
52
|
+
|
|
53
|
+
// Or with options
|
|
54
|
+
this.$toast.error('Something went wrong!', {
|
|
55
|
+
duration: 3000,
|
|
56
|
+
position: 'top-center',
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
</script>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Using Composables (Recommended)
|
|
63
|
+
|
|
64
|
+
```vue
|
|
65
|
+
<template>
|
|
66
|
+
<div>
|
|
67
|
+
<button @click="showSuccess">Success</button>
|
|
68
|
+
<button @click="showError">Error</button>
|
|
69
|
+
|
|
70
|
+
<!-- Render toasts -->
|
|
71
|
+
<div v-for="(toasts, position) in groupedToasts" :key="position">
|
|
72
|
+
<VueToast
|
|
73
|
+
v-for="(toast, index) in toasts"
|
|
74
|
+
:key="toast.id"
|
|
75
|
+
:toast="toast"
|
|
76
|
+
:index="index"
|
|
77
|
+
:total="toasts.length"
|
|
78
|
+
@close="removeToast(toast.id)"
|
|
79
|
+
/>
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
</template>
|
|
83
|
+
|
|
84
|
+
<script setup>
|
|
85
|
+
import { VueToast, useToast } from 'vue-toast'
|
|
86
|
+
|
|
87
|
+
const {
|
|
88
|
+
success,
|
|
89
|
+
error,
|
|
90
|
+
warning,
|
|
91
|
+
info,
|
|
92
|
+
addToast,
|
|
93
|
+
removeToast,
|
|
94
|
+
groupedToasts
|
|
95
|
+
} = useToast()
|
|
96
|
+
|
|
97
|
+
const showSuccess = () => {
|
|
98
|
+
success('Operation completed!', {
|
|
99
|
+
duration: 3000,
|
|
100
|
+
position: 'bottom-right',
|
|
101
|
+
})
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const showError = () => {
|
|
105
|
+
error('Something went wrong!', {
|
|
106
|
+
duration: 5000,
|
|
107
|
+
dismissible: false,
|
|
108
|
+
})
|
|
109
|
+
}
|
|
110
|
+
</script>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## API Reference
|
|
114
|
+
|
|
115
|
+
### Toast Options
|
|
116
|
+
|
|
117
|
+
| Option | Type | Default | Description |
|
|
118
|
+
|--------|------|---------|-------------|
|
|
119
|
+
| `message` | `string` | **Required** | The message to display |
|
|
120
|
+
| `type` | `'success' \| 'error' \| 'warning' \| 'info' \| 'default'` | `'default'` | Toast type |
|
|
121
|
+
| `duration` | `number` | `5000` | Duration in milliseconds (0 for no auto-dismiss) |
|
|
122
|
+
| `position` | `ToastPosition` | `'top-right'` | Position on screen |
|
|
123
|
+
| `dismissible` | `boolean` | `true` | Whether to show close button |
|
|
124
|
+
| `id` | `string` | Auto-generated | Unique identifier |
|
|
125
|
+
| `onClose` | `() => void` | - | Callback when toast closes |
|
|
126
|
+
| `onClick` | `() => void` | - | Callback when toast is clicked |
|
|
127
|
+
|
|
128
|
+
### Toast Positions
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
type ToastPosition =
|
|
132
|
+
| 'top-left'
|
|
133
|
+
| 'top-center'
|
|
134
|
+
| 'top-right'
|
|
135
|
+
| 'bottom-left'
|
|
136
|
+
| 'bottom-center'
|
|
137
|
+
| 'bottom-right'
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### useToast() Composables
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
const {
|
|
144
|
+
// State
|
|
145
|
+
toasts, // Array of all toasts
|
|
146
|
+
groupedToasts, // Toasts grouped by position
|
|
147
|
+
|
|
148
|
+
// Methods
|
|
149
|
+
addToast, // Add a toast with custom options
|
|
150
|
+
removeToast, // Remove a toast by id
|
|
151
|
+
clearToasts, // Remove all toasts
|
|
152
|
+
|
|
153
|
+
// Convenience methods
|
|
154
|
+
success, // Add success toast
|
|
155
|
+
error, // Add error toast
|
|
156
|
+
warning, // Add warning toast
|
|
157
|
+
info, // Add info toast
|
|
158
|
+
} = useToast(defaultPosition?: ToastPosition)
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Global Plugin API
|
|
162
|
+
|
|
163
|
+
When installed as a plugin, `$toast` is available on Vue instances:
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
// In Options API
|
|
167
|
+
this.$toast.success('Message')
|
|
168
|
+
|
|
169
|
+
// In Composition API setup()
|
|
170
|
+
import { getCurrentInstance } from 'vue'
|
|
171
|
+
|
|
172
|
+
const instance = getCurrentInstance()
|
|
173
|
+
instance?.proxy?.$toast.success('Message')
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Methods available on `$toast`:
|
|
177
|
+
- `success(message, options?)`
|
|
178
|
+
- `error(message, options?)`
|
|
179
|
+
- `warning(message, options?)`
|
|
180
|
+
- `info(message, options?)`
|
|
181
|
+
- `add(options)`
|
|
182
|
+
|
|
183
|
+
## Styling
|
|
184
|
+
|
|
185
|
+
### CSS Custom Properties
|
|
186
|
+
|
|
187
|
+
You can customize the appearance using CSS custom properties:
|
|
188
|
+
|
|
189
|
+
```css
|
|
190
|
+
:root {
|
|
191
|
+
--vue-toast-border-radius: 6px;
|
|
192
|
+
--vue-toast-padding: 12px 16px;
|
|
193
|
+
--vue-toast-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
194
|
+
--vue-toast-font-size: 14px;
|
|
195
|
+
--vue-toast-line-height: 1.4;
|
|
196
|
+
--vue-toast-box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/* Type-specific colors */
|
|
200
|
+
.vue-toast--success {
|
|
201
|
+
--vue-toast-border-color: #10b981;
|
|
202
|
+
--vue-toast-bg-color: #f0fdf4;
|
|
203
|
+
--vue-toast-text-color: #065f46;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
.vue-toast--error {
|
|
207
|
+
--vue-toast-border-color: #ef4444;
|
|
208
|
+
--vue-toast-bg-color: #fef2f2;
|
|
209
|
+
--vue-toast-text-color: #991b1b;
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Overriding Styles
|
|
214
|
+
|
|
215
|
+
You can override the default styles by targeting the component classes:
|
|
216
|
+
|
|
217
|
+
```css
|
|
218
|
+
.vue-toast {
|
|
219
|
+
/* Your custom styles */
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.vue-toast__close {
|
|
223
|
+
/* Custom close button styles */
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## TypeScript
|
|
228
|
+
|
|
229
|
+
Full TypeScript support is included. Import types as needed:
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
import type { ToastOptions, ToastPosition, ToastType } from 'vue-toast'
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Examples
|
|
236
|
+
|
|
237
|
+
### Multiple Toasts with Different Positions
|
|
238
|
+
|
|
239
|
+
```vue
|
|
240
|
+
<template>
|
|
241
|
+
<div>
|
|
242
|
+
<button @click="addTopLeft">Top Left</button>
|
|
243
|
+
<button @click="addBottomCenter">Bottom Center</button>
|
|
244
|
+
|
|
245
|
+
<div v-for="(toasts, position) in groupedToasts" :key="position">
|
|
246
|
+
<VueToast
|
|
247
|
+
v-for="(toast, index) in toasts"
|
|
248
|
+
:key="toast.id"
|
|
249
|
+
:toast="toast"
|
|
250
|
+
:index="index"
|
|
251
|
+
:total="toasts.length"
|
|
252
|
+
@close="removeToast(toast.id)"
|
|
253
|
+
/>
|
|
254
|
+
</div>
|
|
255
|
+
</div>
|
|
256
|
+
</template>
|
|
257
|
+
|
|
258
|
+
<script setup>
|
|
259
|
+
import { useToast } from 'vue-toast'
|
|
260
|
+
|
|
261
|
+
const { addToast, removeToast, groupedToasts } = useToast()
|
|
262
|
+
|
|
263
|
+
const addTopLeft = () => {
|
|
264
|
+
addToast({
|
|
265
|
+
message: 'Top left notification',
|
|
266
|
+
type: 'info',
|
|
267
|
+
position: 'top-left',
|
|
268
|
+
duration: 3000,
|
|
269
|
+
})
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
const addBottomCenter = () => {
|
|
273
|
+
addToast({
|
|
274
|
+
message: 'Bottom center warning',
|
|
275
|
+
type: 'warning',
|
|
276
|
+
position: 'bottom-center',
|
|
277
|
+
duration: 5000,
|
|
278
|
+
})
|
|
279
|
+
}
|
|
280
|
+
</script>
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Toast with Callbacks
|
|
284
|
+
|
|
285
|
+
```javascript
|
|
286
|
+
const showToastWithCallback = () => {
|
|
287
|
+
addToast({
|
|
288
|
+
message: 'Click me!',
|
|
289
|
+
type: 'success',
|
|
290
|
+
onClick: () => {
|
|
291
|
+
console.log('Toast clicked!')
|
|
292
|
+
// Navigate or perform action
|
|
293
|
+
},
|
|
294
|
+
onClose: () => {
|
|
295
|
+
console.log('Toast closed')
|
|
296
|
+
// Cleanup or tracking
|
|
297
|
+
},
|
|
298
|
+
})
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
## Browser Support
|
|
303
|
+
|
|
304
|
+
- Chrome 60+
|
|
305
|
+
- Firefox 60+
|
|
306
|
+
- Safari 12+
|
|
307
|
+
- Edge 79+
|
|
308
|
+
|
|
309
|
+
## License
|
|
310
|
+
|
|
311
|
+
MIT
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ToastComponentProps } from '../../types';
|
|
2
|
+
declare const _default: import('vue').DefineComponent<ToastComponentProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
|
|
3
|
+
close: (id?: string | undefined) => any;
|
|
4
|
+
click: () => any;
|
|
5
|
+
}, string, import('vue').PublicProps, Readonly<ToastComponentProps> & Readonly<{
|
|
6
|
+
onClose?: ((id?: string | undefined) => any) | undefined;
|
|
7
|
+
onClick?: (() => any) | undefined;
|
|
8
|
+
}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
|
|
9
|
+
export default _default;
|
|
10
|
+
//# sourceMappingURL=Toast.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Toast.vue.d.ts","sourceRoot":"","sources":["../../../src/components/Toast/Toast.vue"],"names":[],"mappings":"AAyCA;AAgQA,OAAO,KAAK,EAAE,mBAAmB,EAAa,MAAM,SAAS,CAAA;;;;;;;;AAyJ7D,wBAQG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Toast/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,aAAa,CAAA;AAE/B,OAAO,EAAE,KAAK,EAAE,CAAA;AAChB,eAAe,KAAK,CAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Ref } from 'vue';
|
|
2
|
+
import { ToastOptions, ToastPosition } from '../types';
|
|
3
|
+
interface ToastInstance extends ToastOptions {
|
|
4
|
+
id: string;
|
|
5
|
+
timer?: ReturnType<typeof setTimeout>;
|
|
6
|
+
}
|
|
7
|
+
export declare function useToast(defaultPosition?: ToastPosition): {
|
|
8
|
+
toasts: Ref<ToastInstance[], ToastInstance[]>;
|
|
9
|
+
groupedToasts: import('vue').ComputedRef<Record<string, ToastInstance[]>>;
|
|
10
|
+
addToast: (options: ToastOptions) => string;
|
|
11
|
+
removeToast: (id: string) => void;
|
|
12
|
+
clearToasts: () => void;
|
|
13
|
+
success: (message: string, options?: Omit<ToastOptions, "message" | "type">) => string;
|
|
14
|
+
error: (message: string, options?: Omit<ToastOptions, "message" | "type">) => string;
|
|
15
|
+
warning: (message: string, options?: Omit<ToastOptions, "message" | "type">) => string;
|
|
16
|
+
info: (message: string, options?: Omit<ToastOptions, "message" | "type">) => string;
|
|
17
|
+
};
|
|
18
|
+
export type UseToastReturn = ReturnType<typeof useToast>;
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=useToast.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useToast.d.ts","sourceRoot":"","sources":["../../src/composables/useToast.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,KAAK,GAAG,EAAE,MAAM,KAAK,CAAA;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAE1D,UAAU,aAAc,SAAQ,YAAY;IAC1C,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,CAAC,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAA;CACtC;AAED,wBAAgB,QAAQ,CAAC,eAAe,GAAE,aAA2B;;;wBAKxC,YAAY;sBAqBd,MAAM;;uBA6BL,MAAM,YAAW,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,MAAM,CAAC;qBAQzD,MAAM,YAAW,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,MAAM,CAAC;uBAQrD,MAAM,YAAW,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,MAAM,CAAC;oBAQ1D,MAAM,YAAW,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,MAAM,CAAC;EAqC/E;AAED,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAA"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { App } from 'vue';
|
|
2
|
+
import { default as Toast } from './components/Toast';
|
|
3
|
+
import { useToast } from './composables/useToast';
|
|
4
|
+
import { ToastOptions, ToastPosition, ToastType } from './types';
|
|
5
|
+
export { Toast, useToast };
|
|
6
|
+
export type { ToastOptions, ToastPosition, ToastType };
|
|
7
|
+
declare const VueToast: {
|
|
8
|
+
install: (app: App, pluginOptions?: {
|
|
9
|
+
defaultPosition?: ToastPosition;
|
|
10
|
+
}) => void;
|
|
11
|
+
};
|
|
12
|
+
export default VueToast;
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,KAAK,CAAA;AAC9B,OAAO,KAAK,MAAM,oBAAoB,CAAA;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAErE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAA;AAC1B,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,CAAA;AAEtD,QAAA,MAAM,QAAQ;mBACG,GAAG,kBAAkB;QAAE,eAAe,CAAC,EAAE,aAAa,CAAA;KAAE;CA0BxE,CAAA;AAED,eAAe,QAAQ,CAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type ToastType = 'success' | 'error' | 'warning' | 'info' | 'default';
|
|
2
|
+
export type ToastPosition = 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';
|
|
3
|
+
export interface ToastOptions {
|
|
4
|
+
id?: string;
|
|
5
|
+
type?: ToastType;
|
|
6
|
+
message: string;
|
|
7
|
+
duration?: number;
|
|
8
|
+
position?: ToastPosition;
|
|
9
|
+
dismissible?: boolean;
|
|
10
|
+
onClose?: () => void;
|
|
11
|
+
onClick?: () => void;
|
|
12
|
+
}
|
|
13
|
+
export interface ToastComponentProps {
|
|
14
|
+
toast: ToastOptions;
|
|
15
|
+
index: number;
|
|
16
|
+
total: number;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAAA;AAE5E,MAAM,MAAM,aAAa,GACrB,UAAU,GACV,YAAY,GACZ,WAAW,GACX,aAAa,GACb,eAAe,GACf,cAAc,CAAA;AAElB,MAAM,WAAW,YAAY;IAC3B,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,aAAa,CAAA;IACxB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,YAAY,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.vue-toast[data-v-38db861e]{position:relative;display:flex;align-items:center;justify-content:space-between;min-width:300px;max-width:500px;padding:12px 16px;margin-bottom:8px;border-radius:6px;box-shadow:0 4px 12px #00000026;background-color:#fff;color:#333;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;font-size:14px;line-height:1.4;animation:toast-slide-in-38db861e .3s ease-out;transition:transform .2s ease,opacity .2s ease;z-index:calc(1000 + var(--toast-index));cursor:pointer}.vue-toast[data-v-38db861e]:hover{transform:translateY(-1px);box-shadow:0 6px 16px #0003}.vue-toast--success[data-v-38db861e]{border-left:4px solid #10b981;background-color:#f0fdf4;color:#065f46}.vue-toast--error[data-v-38db861e]{border-left:4px solid #ef4444;background-color:#fef2f2;color:#991b1b}.vue-toast--warning[data-v-38db861e]{border-left:4px solid #f59e0b;background-color:#fffbeb;color:#92400e}.vue-toast--info[data-v-38db861e]{border-left:4px solid #3b82f6;background-color:#eff6ff;color:#1e40af}.vue-toast--default[data-v-38db861e]{border-left:4px solid #6b7280;background-color:#f9fafb;color:#374151}.vue-toast__content[data-v-38db861e]{flex:1;margin-right:8px}.vue-toast__message[data-v-38db861e]{word-break:break-word}.vue-toast__close[data-v-38db861e]{flex-shrink:0;background:none;border:none;padding:4px;margin-left:8px;cursor:pointer;color:inherit;opacity:.7;border-radius:4px;transition:opacity .2s ease,background-color .2s ease}.vue-toast__close[data-v-38db861e]:hover{opacity:1;background-color:#0000001a}.vue-toast__close[data-v-38db861e]:focus{outline:2px solid currentColor;outline-offset:2px}.vue-toast__close-icon[data-v-38db861e]{display:block}.vue-toast--topleft[data-v-38db861e]{position:fixed;top:20px;left:20px}.vue-toast--topcenter[data-v-38db861e]{position:fixed;top:20px;left:50%;transform:translate(-50%)}.vue-toast--topright[data-v-38db861e]{position:fixed;top:20px;right:20px}.vue-toast--bottomleft[data-v-38db861e]{position:fixed;bottom:20px;left:20px}.vue-toast--bottomcenter[data-v-38db861e]{position:fixed;bottom:20px;left:50%;transform:translate(-50%)}.vue-toast--bottomright[data-v-38db861e]{position:fixed;bottom:20px;right:20px}@keyframes toast-slide-in-38db861e{0%{opacity:0;transform:translateY(-20px)}to{opacity:1;transform:translateY(0)}}@media(max-width:640px){.vue-toast[data-v-38db861e]{min-width:calc(100vw - 40px);max-width:calc(100vw - 40px);margin-left:20px;margin-right:20px}.vue-toast--topleft[data-v-38db861e],.vue-toast--topcenter[data-v-38db861e],.vue-toast--topright[data-v-38db861e]{top:10px}.vue-toast--bottomleft[data-v-38db861e],.vue-toast--bottomcenter[data-v-38db861e],.vue-toast--bottomright[data-v-38db861e]{bottom:10px}}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { defineComponent, computed, openBlock, createElementBlock, normalizeStyle, normalizeClass, createElementVNode, toDisplayString, withModifiers, createCommentVNode, ref, onUnmounted } from "vue";
|
|
2
|
+
const _hoisted_1 = ["aria-label"];
|
|
3
|
+
const _hoisted_2 = { class: "vue-toast__content" };
|
|
4
|
+
const _hoisted_3 = { class: "vue-toast__message" };
|
|
5
|
+
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
6
|
+
__name: "Toast",
|
|
7
|
+
props: {
|
|
8
|
+
toast: {},
|
|
9
|
+
index: {},
|
|
10
|
+
total: {}
|
|
11
|
+
},
|
|
12
|
+
emits: ["close", "click"],
|
|
13
|
+
setup(__props, { emit: __emit }) {
|
|
14
|
+
const props = __props;
|
|
15
|
+
const emit = __emit;
|
|
16
|
+
const positionClass = computed(() => {
|
|
17
|
+
const position = props.toast.position || "top-right";
|
|
18
|
+
return position.replace("-", "");
|
|
19
|
+
});
|
|
20
|
+
const toastStyle = computed(() => ({
|
|
21
|
+
"--toast-index": props.index,
|
|
22
|
+
"--toast-total": props.total
|
|
23
|
+
}));
|
|
24
|
+
const ariaLabel = computed(() => {
|
|
25
|
+
const type = props.toast.type || "default";
|
|
26
|
+
const typeLabels = {
|
|
27
|
+
success: "Success notification",
|
|
28
|
+
error: "Error notification",
|
|
29
|
+
warning: "Warning notification",
|
|
30
|
+
info: "Information notification",
|
|
31
|
+
default: "Notification"
|
|
32
|
+
};
|
|
33
|
+
return typeLabels[type];
|
|
34
|
+
});
|
|
35
|
+
const handleClose = () => {
|
|
36
|
+
emit("close", props.toast.id);
|
|
37
|
+
};
|
|
38
|
+
const handleClick = () => {
|
|
39
|
+
if (props.toast.onClick) {
|
|
40
|
+
props.toast.onClick();
|
|
41
|
+
}
|
|
42
|
+
emit("click");
|
|
43
|
+
};
|
|
44
|
+
return (_ctx, _cache) => {
|
|
45
|
+
return openBlock(), createElementBlock("div", {
|
|
46
|
+
class: normalizeClass([
|
|
47
|
+
"vue-toast",
|
|
48
|
+
`vue-toast--${__props.toast.type || "default"}`,
|
|
49
|
+
`vue-toast--${positionClass.value}`,
|
|
50
|
+
{ "vue-toast--dismissible": __props.toast.dismissible }
|
|
51
|
+
]),
|
|
52
|
+
style: normalizeStyle(toastStyle.value),
|
|
53
|
+
onClick: handleClick,
|
|
54
|
+
role: "alert",
|
|
55
|
+
"aria-live": "polite",
|
|
56
|
+
"aria-label": ariaLabel.value
|
|
57
|
+
}, [
|
|
58
|
+
createElementVNode("div", _hoisted_2, [
|
|
59
|
+
createElementVNode("span", _hoisted_3, toDisplayString(__props.toast.message), 1)
|
|
60
|
+
]),
|
|
61
|
+
__props.toast.dismissible ? (openBlock(), createElementBlock("button", {
|
|
62
|
+
key: 0,
|
|
63
|
+
class: "vue-toast__close",
|
|
64
|
+
onClick: withModifiers(handleClose, ["stop"]),
|
|
65
|
+
"aria-label": "Close notification"
|
|
66
|
+
}, [..._cache[0] || (_cache[0] = [
|
|
67
|
+
createElementVNode("svg", {
|
|
68
|
+
class: "vue-toast__close-icon",
|
|
69
|
+
viewBox: "0 0 24 24",
|
|
70
|
+
width: "16",
|
|
71
|
+
height: "16",
|
|
72
|
+
fill: "none",
|
|
73
|
+
stroke: "currentColor",
|
|
74
|
+
"stroke-width": "2",
|
|
75
|
+
"stroke-linecap": "round",
|
|
76
|
+
"stroke-linejoin": "round"
|
|
77
|
+
}, [
|
|
78
|
+
createElementVNode("line", {
|
|
79
|
+
x1: "18",
|
|
80
|
+
y1: "6",
|
|
81
|
+
x2: "6",
|
|
82
|
+
y2: "18"
|
|
83
|
+
}),
|
|
84
|
+
createElementVNode("line", {
|
|
85
|
+
x1: "6",
|
|
86
|
+
y1: "6",
|
|
87
|
+
x2: "18",
|
|
88
|
+
y2: "18"
|
|
89
|
+
})
|
|
90
|
+
], -1)
|
|
91
|
+
])])) : createCommentVNode("", true)
|
|
92
|
+
], 14, _hoisted_1);
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
const _export_sfc = (sfc, props) => {
|
|
97
|
+
const target = sfc.__vccOpts || sfc;
|
|
98
|
+
for (const [key, val] of props) {
|
|
99
|
+
target[key] = val;
|
|
100
|
+
}
|
|
101
|
+
return target;
|
|
102
|
+
};
|
|
103
|
+
const Toast = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-38db861e"]]);
|
|
104
|
+
function useToast(defaultPosition = "top-right") {
|
|
105
|
+
const toasts = ref([]);
|
|
106
|
+
const generateId = () => `toast-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
107
|
+
const addToast = (options) => {
|
|
108
|
+
const id = options.id || generateId();
|
|
109
|
+
const toast = {
|
|
110
|
+
...options,
|
|
111
|
+
id,
|
|
112
|
+
position: options.position || defaultPosition,
|
|
113
|
+
duration: options.duration ?? 5e3,
|
|
114
|
+
dismissible: options.dismissible ?? true
|
|
115
|
+
};
|
|
116
|
+
toasts.value.push(toast);
|
|
117
|
+
if (toast.duration && toast.duration > 0) {
|
|
118
|
+
toast.timer = setTimeout(() => {
|
|
119
|
+
removeToast(id);
|
|
120
|
+
}, toast.duration);
|
|
121
|
+
}
|
|
122
|
+
return id;
|
|
123
|
+
};
|
|
124
|
+
const removeToast = (id) => {
|
|
125
|
+
const index = toasts.value.findIndex((t) => t.id === id);
|
|
126
|
+
if (index === -1) return;
|
|
127
|
+
const toast = toasts.value[index];
|
|
128
|
+
if (toast.timer) {
|
|
129
|
+
clearTimeout(toast.timer);
|
|
130
|
+
}
|
|
131
|
+
if (toast.onClose) {
|
|
132
|
+
toast.onClose();
|
|
133
|
+
}
|
|
134
|
+
toasts.value.splice(index, 1);
|
|
135
|
+
};
|
|
136
|
+
const clearToasts = () => {
|
|
137
|
+
toasts.value.forEach((toast) => {
|
|
138
|
+
if (toast.timer) {
|
|
139
|
+
clearTimeout(toast.timer);
|
|
140
|
+
}
|
|
141
|
+
if (toast.onClose) {
|
|
142
|
+
toast.onClose();
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
toasts.value = [];
|
|
146
|
+
};
|
|
147
|
+
const success = (message, options = {}) => {
|
|
148
|
+
return addToast({
|
|
149
|
+
...options,
|
|
150
|
+
message,
|
|
151
|
+
type: "success"
|
|
152
|
+
});
|
|
153
|
+
};
|
|
154
|
+
const error = (message, options = {}) => {
|
|
155
|
+
return addToast({
|
|
156
|
+
...options,
|
|
157
|
+
message,
|
|
158
|
+
type: "error"
|
|
159
|
+
});
|
|
160
|
+
};
|
|
161
|
+
const warning = (message, options = {}) => {
|
|
162
|
+
return addToast({
|
|
163
|
+
...options,
|
|
164
|
+
message,
|
|
165
|
+
type: "warning"
|
|
166
|
+
});
|
|
167
|
+
};
|
|
168
|
+
const info = (message, options = {}) => {
|
|
169
|
+
return addToast({
|
|
170
|
+
...options,
|
|
171
|
+
message,
|
|
172
|
+
type: "info"
|
|
173
|
+
});
|
|
174
|
+
};
|
|
175
|
+
const groupedToasts = computed(() => {
|
|
176
|
+
const groups = {};
|
|
177
|
+
toasts.value.forEach((toast) => {
|
|
178
|
+
const position = toast.position || defaultPosition;
|
|
179
|
+
if (!groups[position]) {
|
|
180
|
+
groups[position] = [];
|
|
181
|
+
}
|
|
182
|
+
groups[position].push(toast);
|
|
183
|
+
});
|
|
184
|
+
return groups;
|
|
185
|
+
});
|
|
186
|
+
onUnmounted(() => {
|
|
187
|
+
clearToasts();
|
|
188
|
+
});
|
|
189
|
+
return {
|
|
190
|
+
toasts,
|
|
191
|
+
groupedToasts,
|
|
192
|
+
addToast,
|
|
193
|
+
removeToast,
|
|
194
|
+
clearToasts,
|
|
195
|
+
success,
|
|
196
|
+
error,
|
|
197
|
+
warning,
|
|
198
|
+
info
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
const VueToast = {
|
|
202
|
+
install: (app, pluginOptions) => {
|
|
203
|
+
app.component("VueToast", Toast);
|
|
204
|
+
app.config.globalProperties.$toast = {
|
|
205
|
+
success: (message, options) => {
|
|
206
|
+
const { success } = useToast((options == null ? void 0 : options.position) || (pluginOptions == null ? void 0 : pluginOptions.defaultPosition));
|
|
207
|
+
return success(message, options);
|
|
208
|
+
},
|
|
209
|
+
error: (message, options) => {
|
|
210
|
+
const { error } = useToast((options == null ? void 0 : options.position) || (pluginOptions == null ? void 0 : pluginOptions.defaultPosition));
|
|
211
|
+
return error(message, options);
|
|
212
|
+
},
|
|
213
|
+
warning: (message, options) => {
|
|
214
|
+
const { warning } = useToast((options == null ? void 0 : options.position) || (pluginOptions == null ? void 0 : pluginOptions.defaultPosition));
|
|
215
|
+
return warning(message, options);
|
|
216
|
+
},
|
|
217
|
+
info: (message, options) => {
|
|
218
|
+
const { info } = useToast((options == null ? void 0 : options.position) || (pluginOptions == null ? void 0 : pluginOptions.defaultPosition));
|
|
219
|
+
return info(message, options);
|
|
220
|
+
},
|
|
221
|
+
add: (options) => {
|
|
222
|
+
const { addToast } = useToast(options.position);
|
|
223
|
+
return addToast(options);
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
export {
|
|
229
|
+
Toast,
|
|
230
|
+
VueToast as default,
|
|
231
|
+
useToast
|
|
232
|
+
};
|
|
233
|
+
//# sourceMappingURL=vue-toast.es.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vue-toast.es.js","sources":["../src/components/Toast/Toast.vue","../src/composables/useToast.ts","../src/index.ts"],"sourcesContent":["<template>\n <div\n :class=\"[\n 'vue-toast',\n `vue-toast--${toast.type || 'default'}`,\n `vue-toast--${positionClass}`,\n { 'vue-toast--dismissible': toast.dismissible }\n ]\"\n :style=\"toastStyle\"\n @click=\"handleClick\"\n role=\"alert\"\n aria-live=\"polite\"\n :aria-label=\"ariaLabel\"\n >\n <div class=\"vue-toast__content\">\n <span class=\"vue-toast__message\">{{ toast.message }}</span>\n </div>\n \n <button\n v-if=\"toast.dismissible\"\n class=\"vue-toast__close\"\n @click.stop=\"handleClose\"\n aria-label=\"Close notification\"\n >\n <svg\n class=\"vue-toast__close-icon\"\n viewBox=\"0 0 24 24\"\n width=\"16\"\n height=\"16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n </button>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport type { ToastComponentProps, ToastType } from '@/types'\n\nconst props = defineProps<ToastComponentProps>()\n\nconst emit = defineEmits<{\n close: [id?: string]\n click: []\n}>()\n\nconst positionClass = computed(() => {\n const position = props.toast.position || 'top-right'\n return position.replace('-', '')\n})\n\nconst toastStyle = computed(() => ({\n '--toast-index': props.index,\n '--toast-total': props.total,\n}))\n\nconst ariaLabel = computed(() => {\n const type = props.toast.type || 'default'\n const typeLabels: Record<ToastType, string> = {\n success: 'Success notification',\n error: 'Error notification',\n warning: 'Warning notification',\n info: 'Information notification',\n default: 'Notification',\n }\n return typeLabels[type]\n})\n\nconst handleClose = () => {\n emit('close', props.toast.id)\n}\n\nconst handleClick = () => {\n if (props.toast.onClick) {\n props.toast.onClick()\n }\n emit('click')\n}\n</script>\n\n<style scoped>\n.vue-toast {\n position: relative;\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-width: 300px;\n max-width: 500px;\n padding: 12px 16px;\n margin-bottom: 8px;\n border-radius: 6px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n background-color: white;\n color: #333;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n font-size: 14px;\n line-height: 1.4;\n animation: toast-slide-in 0.3s ease-out;\n transition: transform 0.2s ease, opacity 0.2s ease;\n z-index: calc(1000 + var(--toast-index));\n cursor: pointer;\n}\n\n.vue-toast:hover {\n transform: translateY(-1px);\n box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2);\n}\n\n.vue-toast--success {\n border-left: 4px solid #10b981;\n background-color: #f0fdf4;\n color: #065f46;\n}\n\n.vue-toast--error {\n border-left: 4px solid #ef4444;\n background-color: #fef2f2;\n color: #991b1b;\n}\n\n.vue-toast--warning {\n border-left: 4px solid #f59e0b;\n background-color: #fffbeb;\n color: #92400e;\n}\n\n.vue-toast--info {\n border-left: 4px solid #3b82f6;\n background-color: #eff6ff;\n color: #1e40af;\n}\n\n.vue-toast--default {\n border-left: 4px solid #6b7280;\n background-color: #f9fafb;\n color: #374151;\n}\n\n.vue-toast__content {\n flex: 1;\n margin-right: 8px;\n}\n\n.vue-toast__message {\n word-break: break-word;\n}\n\n.vue-toast__close {\n flex-shrink: 0;\n background: none;\n border: none;\n padding: 4px;\n margin-left: 8px;\n cursor: pointer;\n color: inherit;\n opacity: 0.7;\n border-radius: 4px;\n transition: opacity 0.2s ease, background-color 0.2s ease;\n}\n\n.vue-toast__close:hover {\n opacity: 1;\n background-color: rgba(0, 0, 0, 0.1);\n}\n\n.vue-toast__close:focus {\n outline: 2px solid currentColor;\n outline-offset: 2px;\n}\n\n.vue-toast__close-icon {\n display: block;\n}\n\n/* Position classes */\n.vue-toast--topleft {\n position: fixed;\n top: 20px;\n left: 20px;\n}\n\n.vue-toast--topcenter {\n position: fixed;\n top: 20px;\n left: 50%;\n transform: translateX(-50%);\n}\n\n.vue-toast--topright {\n position: fixed;\n top: 20px;\n right: 20px;\n}\n\n.vue-toast--bottomleft {\n position: fixed;\n bottom: 20px;\n left: 20px;\n}\n\n.vue-toast--bottomcenter {\n position: fixed;\n bottom: 20px;\n left: 50%;\n transform: translateX(-50%);\n}\n\n.vue-toast--bottomright {\n position: fixed;\n bottom: 20px;\n right: 20px;\n}\n\n/* Animation */\n@keyframes toast-slide-in {\n from {\n opacity: 0;\n transform: translateY(-20px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n/* Responsive */\n@media (max-width: 640px) {\n .vue-toast {\n min-width: calc(100vw - 40px);\n max-width: calc(100vw - 40px);\n margin-left: 20px;\n margin-right: 20px;\n }\n \n .vue-toast--topleft,\n .vue-toast--topcenter,\n .vue-toast--topright {\n top: 10px;\n }\n \n .vue-toast--bottomleft,\n .vue-toast--bottomcenter,\n .vue-toast--bottomright {\n bottom: 10px;\n }\n}\n</style>","import { ref, computed, onUnmounted, type Ref } from 'vue'\nimport type { ToastOptions, ToastPosition } from '@/types'\n\ninterface ToastInstance extends ToastOptions {\n id: string\n timer?: ReturnType<typeof setTimeout>\n}\n\nexport function useToast(defaultPosition: ToastPosition = 'top-right') {\n const toasts: Ref<ToastInstance[]> = ref([])\n\n const generateId = () => `toast-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`\n\n const addToast = (options: ToastOptions) => {\n const id = options.id || generateId()\n const toast: ToastInstance = {\n ...options,\n id,\n position: options.position || defaultPosition,\n duration: options.duration ?? 5000,\n dismissible: options.dismissible ?? true,\n }\n\n toasts.value.push(toast)\n\n if (toast.duration && toast.duration > 0) {\n toast.timer = setTimeout(() => {\n removeToast(id)\n }, toast.duration)\n }\n\n return id\n }\n\n const removeToast = (id: string) => {\n const index = toasts.value.findIndex(t => t.id === id)\n if (index === -1) return\n\n const toast = toasts.value[index]\n \n if (toast.timer) {\n clearTimeout(toast.timer)\n }\n\n if (toast.onClose) {\n toast.onClose()\n }\n\n toasts.value.splice(index, 1)\n }\n\n const clearToasts = () => {\n toasts.value.forEach(toast => {\n if (toast.timer) {\n clearTimeout(toast.timer)\n }\n if (toast.onClose) {\n toast.onClose()\n }\n })\n toasts.value = []\n }\n\n const success = (message: string, options: Omit<ToastOptions, 'message' | 'type'> = {}) => {\n return addToast({\n ...options,\n message,\n type: 'success',\n })\n }\n\n const error = (message: string, options: Omit<ToastOptions, 'message' | 'type'> = {}) => {\n return addToast({\n ...options,\n message,\n type: 'error',\n })\n }\n\n const warning = (message: string, options: Omit<ToastOptions, 'message' | 'type'> = {}) => {\n return addToast({\n ...options,\n message,\n type: 'warning',\n })\n }\n\n const info = (message: string, options: Omit<ToastOptions, 'message' | 'type'> = {}) => {\n return addToast({\n ...options,\n message,\n type: 'info',\n })\n }\n\n const groupedToasts = computed(() => {\n const groups: Record<string, ToastInstance[]> = {}\n \n toasts.value.forEach(toast => {\n const position = toast.position || defaultPosition\n if (!groups[position]) {\n groups[position] = []\n }\n groups[position].push(toast)\n })\n\n return groups\n })\n\n onUnmounted(() => {\n clearToasts()\n })\n\n return {\n toasts,\n groupedToasts,\n addToast,\n removeToast,\n clearToasts,\n success,\n error,\n warning,\n info,\n }\n}\n\nexport type UseToastReturn = ReturnType<typeof useToast>","import { type App } from 'vue'\nimport Toast from './components/Toast'\nimport { useToast } from './composables/useToast'\nimport type { ToastOptions, ToastPosition, ToastType } from './types'\n\nexport { Toast, useToast }\nexport type { ToastOptions, ToastPosition, ToastType }\n\nconst VueToast = {\n install: (app: App, pluginOptions?: { defaultPosition?: ToastPosition }) => {\n app.component('VueToast', Toast)\n \n app.config.globalProperties.$toast = {\n success: (message: string, options?: Omit<ToastOptions, 'message' | 'type'>) => {\n const { success } = useToast(options?.position || pluginOptions?.defaultPosition)\n return success(message, options)\n },\n error: (message: string, options?: Omit<ToastOptions, 'message' | 'type'>) => {\n const { error } = useToast(options?.position || pluginOptions?.defaultPosition)\n return error(message, options)\n },\n warning: (message: string, options?: Omit<ToastOptions, 'message' | 'type'>) => {\n const { warning } = useToast(options?.position || pluginOptions?.defaultPosition)\n return warning(message, options)\n },\n info: (message: string, options?: Omit<ToastOptions, 'message' | 'type'>) => {\n const { info } = useToast(options?.position || pluginOptions?.defaultPosition)\n return info(message, options)\n },\n add: (options: ToastOptions) => {\n const { addToast } = useToast(options.position)\n return addToast(options)\n },\n }\n },\n}\n\nexport default VueToast"],"names":["_createElementBlock","_normalizeClass","_createElementVNode","_toDisplayString"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("vue")):"function"==typeof define&&define.amd?define(["exports","vue"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).VueToast={},e.Vue)}(this,function(e,t){"use strict";const o=["aria-label"],s={class:"vue-toast__content"},i={class:"vue-toast__message"},n=((e,t)=>{const o=e.__vccOpts||e;for(const[s,i]of t)o[s]=i;return o})(t.defineComponent({__name:"Toast",props:{toast:{},index:{},total:{}},emits:["close","click"],setup(e,{emit:n}){const a=e,l=n,r=t.computed(()=>(a.toast.position||"top-right").replace("-","")),u=t.computed(()=>({"--toast-index":a.index,"--toast-total":a.total})),c=t.computed(()=>({success:"Success notification",error:"Error notification",warning:"Warning notification",info:"Information notification",default:"Notification"}[a.toast.type||"default"])),d=()=>{l("close",a.toast.id)},p=()=>{a.toast.onClick&&a.toast.onClick(),l("click")};return(n,a)=>(t.openBlock(),t.createElementBlock("div",{class:t.normalizeClass(["vue-toast",`vue-toast--${e.toast.type||"default"}`,`vue-toast--${r.value}`,{"vue-toast--dismissible":e.toast.dismissible}]),style:t.normalizeStyle(u.value),onClick:p,role:"alert","aria-live":"polite","aria-label":c.value},[t.createElementVNode("div",s,[t.createElementVNode("span",i,t.toDisplayString(e.toast.message),1)]),e.toast.dismissible?(t.openBlock(),t.createElementBlock("button",{key:0,class:"vue-toast__close",onClick:t.withModifiers(d,["stop"]),"aria-label":"Close notification"},[...a[0]||(a[0]=[t.createElementVNode("svg",{class:"vue-toast__close-icon",viewBox:"0 0 24 24",width:"16",height:"16",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"},[t.createElementVNode("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),t.createElementVNode("line",{x1:"6",y1:"6",x2:"18",y2:"18"})],-1)])])):t.createCommentVNode("",!0)],14,o))}}),[["__scopeId","data-v-38db861e"]]);function a(e="top-right"){const o=t.ref([]),s=t=>{const s=t.id||`toast-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,n={...t,id:s,position:t.position||e,duration:t.duration??5e3,dismissible:t.dismissible??!0};return o.value.push(n),n.duration&&n.duration>0&&(n.timer=setTimeout(()=>{i(s)},n.duration)),s},i=e=>{const t=o.value.findIndex(t=>t.id===e);if(-1===t)return;const s=o.value[t];s.timer&&clearTimeout(s.timer),s.onClose&&s.onClose(),o.value.splice(t,1)},n=()=>{o.value.forEach(e=>{e.timer&&clearTimeout(e.timer),e.onClose&&e.onClose()}),o.value=[]},a=t.computed(()=>{const t={};return o.value.forEach(o=>{const s=o.position||e;t[s]||(t[s]=[]),t[s].push(o)}),t});return t.onUnmounted(()=>{n()}),{toasts:o,groupedToasts:a,addToast:s,removeToast:i,clearToasts:n,success:(e,t={})=>s({...t,message:e,type:"success"}),error:(e,t={})=>s({...t,message:e,type:"error"}),warning:(e,t={})=>s({...t,message:e,type:"warning"}),info:(e,t={})=>s({...t,message:e,type:"info"})}}const l={install:(e,t)=>{e.component("VueToast",n),e.config.globalProperties.$toast={success:(e,o)=>{const{success:s}=a((null==o?void 0:o.position)||(null==t?void 0:t.defaultPosition));return s(e,o)},error:(e,o)=>{const{error:s}=a((null==o?void 0:o.position)||(null==t?void 0:t.defaultPosition));return s(e,o)},warning:(e,o)=>{const{warning:s}=a((null==o?void 0:o.position)||(null==t?void 0:t.defaultPosition));return s(e,o)},info:(e,o)=>{const{info:s}=a((null==o?void 0:o.position)||(null==t?void 0:t.defaultPosition));return s(e,o)},add:e=>{const{addToast:t}=a(e.position);return t(e)}}}};e.Toast=n,e.default=l,e.useToast=a,Object.defineProperties(e,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
|
|
2
|
+
//# sourceMappingURL=vue-toast.umd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vue-toast.umd.js","sources":["../src/components/Toast/Toast.vue","../src/composables/useToast.ts","../src/index.ts"],"sourcesContent":["<template>\n <div\n :class=\"[\n 'vue-toast',\n `vue-toast--${toast.type || 'default'}`,\n `vue-toast--${positionClass}`,\n { 'vue-toast--dismissible': toast.dismissible }\n ]\"\n :style=\"toastStyle\"\n @click=\"handleClick\"\n role=\"alert\"\n aria-live=\"polite\"\n :aria-label=\"ariaLabel\"\n >\n <div class=\"vue-toast__content\">\n <span class=\"vue-toast__message\">{{ toast.message }}</span>\n </div>\n \n <button\n v-if=\"toast.dismissible\"\n class=\"vue-toast__close\"\n @click.stop=\"handleClose\"\n aria-label=\"Close notification\"\n >\n <svg\n class=\"vue-toast__close-icon\"\n viewBox=\"0 0 24 24\"\n width=\"16\"\n height=\"16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n </button>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport type { ToastComponentProps, ToastType } from '@/types'\n\nconst props = defineProps<ToastComponentProps>()\n\nconst emit = defineEmits<{\n close: [id?: string]\n click: []\n}>()\n\nconst positionClass = computed(() => {\n const position = props.toast.position || 'top-right'\n return position.replace('-', '')\n})\n\nconst toastStyle = computed(() => ({\n '--toast-index': props.index,\n '--toast-total': props.total,\n}))\n\nconst ariaLabel = computed(() => {\n const type = props.toast.type || 'default'\n const typeLabels: Record<ToastType, string> = {\n success: 'Success notification',\n error: 'Error notification',\n warning: 'Warning notification',\n info: 'Information notification',\n default: 'Notification',\n }\n return typeLabels[type]\n})\n\nconst handleClose = () => {\n emit('close', props.toast.id)\n}\n\nconst handleClick = () => {\n if (props.toast.onClick) {\n props.toast.onClick()\n }\n emit('click')\n}\n</script>\n\n<style scoped>\n.vue-toast {\n position: relative;\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-width: 300px;\n max-width: 500px;\n padding: 12px 16px;\n margin-bottom: 8px;\n border-radius: 6px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n background-color: white;\n color: #333;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n font-size: 14px;\n line-height: 1.4;\n animation: toast-slide-in 0.3s ease-out;\n transition: transform 0.2s ease, opacity 0.2s ease;\n z-index: calc(1000 + var(--toast-index));\n cursor: pointer;\n}\n\n.vue-toast:hover {\n transform: translateY(-1px);\n box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2);\n}\n\n.vue-toast--success {\n border-left: 4px solid #10b981;\n background-color: #f0fdf4;\n color: #065f46;\n}\n\n.vue-toast--error {\n border-left: 4px solid #ef4444;\n background-color: #fef2f2;\n color: #991b1b;\n}\n\n.vue-toast--warning {\n border-left: 4px solid #f59e0b;\n background-color: #fffbeb;\n color: #92400e;\n}\n\n.vue-toast--info {\n border-left: 4px solid #3b82f6;\n background-color: #eff6ff;\n color: #1e40af;\n}\n\n.vue-toast--default {\n border-left: 4px solid #6b7280;\n background-color: #f9fafb;\n color: #374151;\n}\n\n.vue-toast__content {\n flex: 1;\n margin-right: 8px;\n}\n\n.vue-toast__message {\n word-break: break-word;\n}\n\n.vue-toast__close {\n flex-shrink: 0;\n background: none;\n border: none;\n padding: 4px;\n margin-left: 8px;\n cursor: pointer;\n color: inherit;\n opacity: 0.7;\n border-radius: 4px;\n transition: opacity 0.2s ease, background-color 0.2s ease;\n}\n\n.vue-toast__close:hover {\n opacity: 1;\n background-color: rgba(0, 0, 0, 0.1);\n}\n\n.vue-toast__close:focus {\n outline: 2px solid currentColor;\n outline-offset: 2px;\n}\n\n.vue-toast__close-icon {\n display: block;\n}\n\n/* Position classes */\n.vue-toast--topleft {\n position: fixed;\n top: 20px;\n left: 20px;\n}\n\n.vue-toast--topcenter {\n position: fixed;\n top: 20px;\n left: 50%;\n transform: translateX(-50%);\n}\n\n.vue-toast--topright {\n position: fixed;\n top: 20px;\n right: 20px;\n}\n\n.vue-toast--bottomleft {\n position: fixed;\n bottom: 20px;\n left: 20px;\n}\n\n.vue-toast--bottomcenter {\n position: fixed;\n bottom: 20px;\n left: 50%;\n transform: translateX(-50%);\n}\n\n.vue-toast--bottomright {\n position: fixed;\n bottom: 20px;\n right: 20px;\n}\n\n/* Animation */\n@keyframes toast-slide-in {\n from {\n opacity: 0;\n transform: translateY(-20px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n/* Responsive */\n@media (max-width: 640px) {\n .vue-toast {\n min-width: calc(100vw - 40px);\n max-width: calc(100vw - 40px);\n margin-left: 20px;\n margin-right: 20px;\n }\n \n .vue-toast--topleft,\n .vue-toast--topcenter,\n .vue-toast--topright {\n top: 10px;\n }\n \n .vue-toast--bottomleft,\n .vue-toast--bottomcenter,\n .vue-toast--bottomright {\n bottom: 10px;\n }\n}\n</style>","import { ref, computed, onUnmounted, type Ref } from 'vue'\nimport type { ToastOptions, ToastPosition } from '@/types'\n\ninterface ToastInstance extends ToastOptions {\n id: string\n timer?: ReturnType<typeof setTimeout>\n}\n\nexport function useToast(defaultPosition: ToastPosition = 'top-right') {\n const toasts: Ref<ToastInstance[]> = ref([])\n\n const generateId = () => `toast-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`\n\n const addToast = (options: ToastOptions) => {\n const id = options.id || generateId()\n const toast: ToastInstance = {\n ...options,\n id,\n position: options.position || defaultPosition,\n duration: options.duration ?? 5000,\n dismissible: options.dismissible ?? true,\n }\n\n toasts.value.push(toast)\n\n if (toast.duration && toast.duration > 0) {\n toast.timer = setTimeout(() => {\n removeToast(id)\n }, toast.duration)\n }\n\n return id\n }\n\n const removeToast = (id: string) => {\n const index = toasts.value.findIndex(t => t.id === id)\n if (index === -1) return\n\n const toast = toasts.value[index]\n \n if (toast.timer) {\n clearTimeout(toast.timer)\n }\n\n if (toast.onClose) {\n toast.onClose()\n }\n\n toasts.value.splice(index, 1)\n }\n\n const clearToasts = () => {\n toasts.value.forEach(toast => {\n if (toast.timer) {\n clearTimeout(toast.timer)\n }\n if (toast.onClose) {\n toast.onClose()\n }\n })\n toasts.value = []\n }\n\n const success = (message: string, options: Omit<ToastOptions, 'message' | 'type'> = {}) => {\n return addToast({\n ...options,\n message,\n type: 'success',\n })\n }\n\n const error = (message: string, options: Omit<ToastOptions, 'message' | 'type'> = {}) => {\n return addToast({\n ...options,\n message,\n type: 'error',\n })\n }\n\n const warning = (message: string, options: Omit<ToastOptions, 'message' | 'type'> = {}) => {\n return addToast({\n ...options,\n message,\n type: 'warning',\n })\n }\n\n const info = (message: string, options: Omit<ToastOptions, 'message' | 'type'> = {}) => {\n return addToast({\n ...options,\n message,\n type: 'info',\n })\n }\n\n const groupedToasts = computed(() => {\n const groups: Record<string, ToastInstance[]> = {}\n \n toasts.value.forEach(toast => {\n const position = toast.position || defaultPosition\n if (!groups[position]) {\n groups[position] = []\n }\n groups[position].push(toast)\n })\n\n return groups\n })\n\n onUnmounted(() => {\n clearToasts()\n })\n\n return {\n toasts,\n groupedToasts,\n addToast,\n removeToast,\n clearToasts,\n success,\n error,\n warning,\n info,\n }\n}\n\nexport type UseToastReturn = ReturnType<typeof useToast>","import { type App } from 'vue'\nimport Toast from './components/Toast'\nimport { useToast } from './composables/useToast'\nimport type { ToastOptions, ToastPosition, ToastType } from './types'\n\nexport { Toast, useToast }\nexport type { ToastOptions, ToastPosition, ToastType }\n\nconst VueToast = {\n install: (app: App, pluginOptions?: { defaultPosition?: ToastPosition }) => {\n app.component('VueToast', Toast)\n \n app.config.globalProperties.$toast = {\n success: (message: string, options?: Omit<ToastOptions, 'message' | 'type'>) => {\n const { success } = useToast(options?.position || pluginOptions?.defaultPosition)\n return success(message, options)\n },\n error: (message: string, options?: Omit<ToastOptions, 'message' | 'type'>) => {\n const { error } = useToast(options?.position || pluginOptions?.defaultPosition)\n return error(message, options)\n },\n warning: (message: string, options?: Omit<ToastOptions, 'message' | 'type'>) => {\n const { warning } = useToast(options?.position || pluginOptions?.defaultPosition)\n return warning(message, options)\n },\n info: (message: string, options?: Omit<ToastOptions, 'message' | 'type'>) => {\n const { info } = useToast(options?.position || pluginOptions?.defaultPosition)\n return info(message, options)\n },\n add: (options: ToastOptions) => {\n const { addToast } = useToast(options.position)\n return addToast(options)\n },\n }\n },\n}\n\nexport default VueToast"],"names":["props","__props","emit","__emit","positionClass","computed","toast","position","replace","toastStyle","index","total","ariaLabel","success","error","warning","info","default","type","handleClose","id","handleClick","onClick","_createElementBlock","class","_normalizeClass","value","dismissible","style","role","_createElementVNode","_hoisted_2","_hoisted_3","_toDisplayString","message","viewBox","width","height","fill","stroke","x1","y1","x2","y2","useToast","defaultPosition","toasts","ref","addToast","options","Date","now","Math","random","toString","substr","duration","push","timer","setTimeout","removeToast","findIndex","t","clearTimeout","onClose","splice","clearToasts","forEach","groupedToasts","groups","onUnmounted","VueToast","install","app","pluginOptions","component","Toast","config","globalProperties","$toast","add"],"mappings":"uhBA8CA,MAAMA,EAAQC,EAERC,EAAOC,EAKPC,EAAgBC,EAAAA,SAAS,KACZL,EAAMM,MAAMC,UAAY,aACzBC,QAAQ,IAAK,KAGzBC,EAAaJ,EAAAA,SAAS,KAAA,CAC1B,gBAAiBL,EAAMU,MACvB,gBAAiBV,EAAMW,SAGnBC,EAAYP,EAAAA,SAAS,KAEqB,CAC5CQ,QAAS,uBACTC,MAAO,qBACPC,QAAS,uBACTC,KAAM,2BACNC,QAAS,gBANEjB,EAAMM,MAAMY,MAAQ,aAW7BC,EAAc,KAClBjB,EAAK,QAASF,EAAMM,MAAMc,KAGtBC,EAAc,KACdrB,EAAMM,MAAMgB,SACdtB,EAAMM,MAAMgB,UAEdpB,EAAK,sCAlFLqB,EAAAA,mBAsCM,MAAA,CArCHC,MAAKC,EAAAA,eAAA,aAA2C,cAAAxB,EAAAK,MAAMY,MAAI,0BAAqCd,EAAAsB,QAAmD,CAAA,yBAAAzB,EAAAK,MAAMqB,eAMxJC,uBAAOnB,EAAAiB,OACPJ,QAAOD,EACRQ,KAAK,QACL,YAAU,SACT,aAAYjB,EAAAc,QAEbI,EAAAA,mBAEM,MAFNC,EAEM,CADJD,EAAAA,mBAA2D,OAA3DE,EAA2DC,EAAAA,gBAAvBhC,EAAAK,MAAM4B,SAAO,KAI3CjC,EAAAK,MAAMqB,2BADdJ,EAAAA,mBAoBS,SAAA,OAlBPC,MAAM,mBACLF,wBAAYH,EAAW,CAAA,SACxB,aAAW,uCAEXW,EAAAA,mBAaM,MAAA,CAZJN,MAAM,wBACNW,QAAQ,YACRC,MAAM,KACNC,OAAO,KACPC,KAAK,OACLC,OAAO,eACP,eAAa,IACb,iBAAe,QACf,kBAAgB,UAEhBT,EAAAA,mBAA2C,OAAA,CAArCU,GAAG,KAAKC,GAAG,IAAIC,GAAG,IAAIC,GAAG,OAC/Bb,EAAAA,mBAA2C,OAAA,CAArCU,GAAG,IAAIC,GAAG,IAAIC,GAAG,KAAKC,GAAG,2FC5BhC,SAASC,EAASC,EAAiC,aACxD,MAAMC,EAA+BC,EAAAA,IAAI,IAInCC,EAAYC,IAChB,MAAM7B,EAAK6B,EAAQ7B,IAHI,SAAS8B,KAAKC,SAASC,KAAKC,SAASC,SAAS,IAAIC,OAAO,EAAG,KAI7EjD,EAAuB,IACxB2C,EACH7B,KACAb,SAAU0C,EAAQ1C,UAAYsC,EAC9BW,SAAUP,EAAQO,UAAY,IAC9B7B,YAAasB,EAAQtB,cAAe,GAWtC,OARAmB,EAAOpB,MAAM+B,KAAKnD,GAEdA,EAAMkD,UAAYlD,EAAMkD,SAAW,IACrClD,EAAMoD,MAAQC,WAAW,KACvBC,EAAYxC,IACXd,EAAMkD,WAGJpC,GAGHwC,EAAexC,IACnB,MAAMV,EAAQoC,EAAOpB,MAAMmC,UAAUC,GAAKA,EAAE1C,KAAOA,GACnD,IAAc,IAAVV,EAAc,OAElB,MAAMJ,EAAQwC,EAAOpB,MAAMhB,GAEvBJ,EAAMoD,OACRK,aAAazD,EAAMoD,OAGjBpD,EAAM0D,SACR1D,EAAM0D,UAGRlB,EAAOpB,MAAMuC,OAAOvD,EAAO,IAGvBwD,EAAc,KAClBpB,EAAOpB,MAAMyC,QAAQ7D,IACfA,EAAMoD,OACRK,aAAazD,EAAMoD,OAEjBpD,EAAM0D,SACR1D,EAAM0D,YAGVlB,EAAOpB,MAAQ,IAmCX0C,EAAgB/D,EAAAA,SAAS,KAC7B,MAAMgE,EAA0C,CAAA,EAUhD,OARAvB,EAAOpB,MAAMyC,QAAQ7D,IACnB,MAAMC,EAAWD,EAAMC,UAAYsC,EAC9BwB,EAAO9D,KACV8D,EAAO9D,GAAY,IAErB8D,EAAO9D,GAAUkD,KAAKnD,KAGjB+D,IAOT,OAJAC,EAAAA,YAAY,KACVJ,MAGK,CACLpB,SACAsB,gBACApB,WACAY,cACAM,cACArD,QAxDc,CAACqB,EAAiBe,EAAkD,CAAA,IAC3ED,EAAS,IACXC,EACHf,UACAhB,KAAM,YAqDRJ,MAjDY,CAACoB,EAAiBe,EAAkD,CAAA,IACzED,EAAS,IACXC,EACHf,UACAhB,KAAM,UA8CRH,QA1Cc,CAACmB,EAAiBe,EAAkD,CAAA,IAC3ED,EAAS,IACXC,EACHf,UACAhB,KAAM,YAuCRF,KAnCW,CAACkB,EAAiBe,EAAkD,CAAA,IACxED,EAAS,IACXC,EACHf,UACAhB,KAAM,SAiCZ,CCpHA,MAAMqD,EAAW,CACfC,QAAS,CAACC,EAAUC,KAClBD,EAAIE,UAAU,WAAYC,GAE1BH,EAAII,OAAOC,iBAAiBC,OAAS,CACnClE,QAAS,CAACqB,EAAiBe,KACzB,MAAMpC,QAAEA,GAAY+B,GAAS,MAAAK,OAAA,EAAAA,EAAS1C,kBAAYmE,WAAe7B,kBACjE,OAAOhC,EAAQqB,EAASe,IAE1BnC,MAAO,CAACoB,EAAiBe,KACvB,MAAMnC,MAAEA,GAAU8B,GAAS,MAAAK,OAAA,EAAAA,EAAS1C,kBAAYmE,WAAe7B,kBAC/D,OAAO/B,EAAMoB,EAASe,IAExBlC,QAAS,CAACmB,EAAiBe,KACzB,MAAMlC,QAAEA,GAAY6B,GAAS,MAAAK,OAAA,EAAAA,EAAS1C,kBAAYmE,WAAe7B,kBACjE,OAAO9B,EAAQmB,EAASe,IAE1BjC,KAAM,CAACkB,EAAiBe,KACtB,MAAMjC,KAAEA,GAAS4B,GAAS,MAAAK,OAAA,EAAAA,EAAS1C,kBAAYmE,WAAe7B,kBAC9D,OAAO7B,EAAKkB,EAASe,IAEvB+B,IAAM/B,IACJ,MAAMD,SAAEA,GAAaJ,EAASK,EAAQ1C,UACtC,OAAOyC,EAASC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rosadorito/vue-toast",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "A lightweight, customizable toast notification library for Vue 3",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/vue-toast.umd.js",
|
|
7
|
+
"module": "./dist/vue-toast.es.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"private": false,
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/vue-toast.es.js",
|
|
14
|
+
"require": "./dist/vue-toast.umd.js"
|
|
15
|
+
},
|
|
16
|
+
"./style.css": "./dist/style.css",
|
|
17
|
+
"./dist/*": "./dist/*"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"dev": "vite --config examples/vite.config.js",
|
|
24
|
+
"build": "vue-tsc --noEmit && vite build",
|
|
25
|
+
"preview": "vite preview --config examples/vite.config.js",
|
|
26
|
+
"test": "vitest",
|
|
27
|
+
"test:ui": "vitest --ui",
|
|
28
|
+
"test:coverage": "vitest --coverage",
|
|
29
|
+
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
|
|
30
|
+
"type-check": "vue-tsc --noEmit",
|
|
31
|
+
"prepublishOnly": "npm run build",
|
|
32
|
+
"build:examples": "vite build --config examples/vite.config.js"
|
|
33
|
+
},
|
|
34
|
+
"keywords": [
|
|
35
|
+
"vue",
|
|
36
|
+
"vue3",
|
|
37
|
+
"toast",
|
|
38
|
+
"notification",
|
|
39
|
+
"component-library",
|
|
40
|
+
"ui",
|
|
41
|
+
"alert"
|
|
42
|
+
],
|
|
43
|
+
"author": "",
|
|
44
|
+
"license": "MIT",
|
|
45
|
+
"repository": {
|
|
46
|
+
"type": "git",
|
|
47
|
+
"url": "git+https://github.com/yourusername/vue-toast.git"
|
|
48
|
+
},
|
|
49
|
+
"bugs": {
|
|
50
|
+
"url": "https://github.com/yourusername/vue-toast/issues"
|
|
51
|
+
},
|
|
52
|
+
"homepage": "https://github.com/yourusername/vue-toast#readme",
|
|
53
|
+
"packageManager": "pnpm@10.30.1",
|
|
54
|
+
"dependencies": {
|
|
55
|
+
"vue": "^3.5.32"
|
|
56
|
+
},
|
|
57
|
+
"peerDependencies": {
|
|
58
|
+
"vue": "^3.5.0"
|
|
59
|
+
},
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"@types/node": "^22.10.6",
|
|
62
|
+
"@vitejs/plugin-vue": "^5.2.1",
|
|
63
|
+
"@vue/eslint-config-typescript": "^14.2.0",
|
|
64
|
+
"@vue/test-utils": "^2.4.6",
|
|
65
|
+
"@vue/tsconfig": "^0.6.0",
|
|
66
|
+
"eslint": "^9.17.0",
|
|
67
|
+
"eslint-plugin-vue": "^9.30.0",
|
|
68
|
+
"jsdom": "^26.0.0",
|
|
69
|
+
"terser": "^5.46.1",
|
|
70
|
+
"typescript": "^5.7.3",
|
|
71
|
+
"vite": "^6.0.11",
|
|
72
|
+
"vite-plugin-dts": "^4.3.0",
|
|
73
|
+
"vitest": "^2.1.8",
|
|
74
|
+
"vue-tsc": "^2.1.10"
|
|
75
|
+
},
|
|
76
|
+
"sideEffects": false
|
|
77
|
+
}
|