feat(#33): Add a global toast/notification component
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
import {defineStore} from "pinia";
|
||||
import {ref} from "vue";
|
||||
|
||||
export type ToastType = 'success' | 'error' | 'info';
|
||||
|
||||
export interface ToastOptions {
|
||||
message: string;
|
||||
title?: string;
|
||||
type?: ToastType;
|
||||
duration?: number;
|
||||
}
|
||||
|
||||
export interface Toast {
|
||||
id: number;
|
||||
message: string;
|
||||
title?: string;
|
||||
type: ToastType;
|
||||
}
|
||||
|
||||
const DEFAULT_DURATION = 5000;
|
||||
|
||||
export const useToastStore = defineStore('toast', () => {
|
||||
const toasts = ref<Toast[]>([]);
|
||||
let nextId = 0;
|
||||
|
||||
const dismiss = (id: number) => {
|
||||
toasts.value = toasts.value.filter(toast => toast.id !== id);
|
||||
};
|
||||
|
||||
const push = (opts: ToastOptions | string): number => {
|
||||
const options = typeof opts === "string" ? {message: opts} : opts;
|
||||
const id = nextId++;
|
||||
toasts.value.push({
|
||||
id,
|
||||
message: options.message,
|
||||
title: options.title,
|
||||
type: options.type ?? 'info',
|
||||
});
|
||||
const duration = options.duration ?? DEFAULT_DURATION;
|
||||
if (duration > 0) {
|
||||
setTimeout(() => dismiss(id), duration);
|
||||
}
|
||||
return id;
|
||||
};
|
||||
|
||||
return {toasts, push, dismiss};
|
||||
});
|
||||
|
||||
interface ToastHelper {
|
||||
(opts: ToastOptions | string): number;
|
||||
success: (message: string) => number;
|
||||
error: (message: string) => number;
|
||||
info: (message: string) => number;
|
||||
}
|
||||
|
||||
export const toast: ToastHelper = Object.assign(
|
||||
(opts: ToastOptions | string): number => useToastStore().push(opts),
|
||||
{
|
||||
success: (message: string): number => useToastStore().push({message, type: 'success'}),
|
||||
error: (message: string): number => useToastStore().push({message, type: 'error'}),
|
||||
info: (message: string): number => useToastStore().push({message, type: 'info'}),
|
||||
},
|
||||
);
|
||||
Reference in New Issue
Block a user