From 2a2fd78d3bc991eb1b7da5050d0befc2c14d83d9 Mon Sep 17 00:00:00 2001 From: qowevisa Date: Sat, 2 Nov 2024 18:42:29 +0200 Subject: [PATCH] Add Toasts notifications --- src/lib/components/Toast.svelte | 66 ++++++++++++++++++++++++++++++ src/lib/components/Toasts.svelte | 32 +++++++++++++++ src/lib/components/store.ts | 70 ++++++++++++++++++++++++++++++++ src/lib/icons/CloseIcon.svelte | 18 ++++++++ src/lib/icons/ErrorIcon.svelte | 19 +++++++++ src/lib/icons/InfoIcon.svelte | 18 ++++++++ src/lib/icons/SuccessIcon.svelte | 18 ++++++++ 7 files changed, 241 insertions(+) create mode 100644 src/lib/components/Toast.svelte create mode 100644 src/lib/components/Toasts.svelte create mode 100644 src/lib/components/store.ts create mode 100644 src/lib/icons/CloseIcon.svelte create mode 100644 src/lib/icons/ErrorIcon.svelte create mode 100644 src/lib/icons/InfoIcon.svelte create mode 100644 src/lib/icons/SuccessIcon.svelte diff --git a/src/lib/components/Toast.svelte b/src/lib/components/Toast.svelte new file mode 100644 index 0000000..9d6a9ed --- /dev/null +++ b/src/lib/components/Toast.svelte @@ -0,0 +1,66 @@ + + + + + diff --git a/src/lib/components/Toasts.svelte b/src/lib/components/Toasts.svelte new file mode 100644 index 0000000..379c894 --- /dev/null +++ b/src/lib/components/Toasts.svelte @@ -0,0 +1,32 @@ + + +{#if $toasts} +
+ {#each $toasts as toast (toast.id)} + dismissToast(toast.id)}>{toast.message} + {/each} +
+{/if} + + diff --git a/src/lib/components/store.ts b/src/lib/components/store.ts new file mode 100644 index 0000000..07ad73c --- /dev/null +++ b/src/lib/components/store.ts @@ -0,0 +1,70 @@ +import { writable } from "svelte/store"; + +interface ToastNotification { + id: number; + type: "info" | "success" | "error" | "warning"; + dismissible: boolean; + timeout: number; + message: string; +} + +export const toasts = writable([]); + +interface InternalToast { + type: "info" | "success" | "error" | "warning"; + dismissible: boolean; + timeout: number; + message: string; +} + +const addToast = (toast: InternalToast) => { + // Create a unique ID so we can easily find/remove it + // if it is dismissible/has a timeout. + const id = Math.floor(Math.random() * 10000); + + // Setup some sensible defaults for a toast. + const defaults = { + id, + type: "info", + dismissible: true, + timeout: 3000, + }; + + // Push the toast to the top of the list of toasts + toasts.update((all) => [{ ...defaults, ...toast }, ...all]); + + // If toast is dismissible, dismiss it after "timeout" amount of time. + if (toast.timeout) setTimeout(() => dismissToast(id), toast.timeout); +}; + +export const dismissToast = (id: number) => { + toasts.update((all) => all.filter((t) => t.id !== id)); +}; + +export const addSuccessToast = (message: string, dismissible: boolean = false, timeout: number = 1000) => { + addToast({ + type: "success", + dismissible, + timeout, + message, + }) +} + +export const addErrorToast = (message: string, dismissible: boolean = false, timeout: number = 1000) => { + addToast({ + type: "error", + dismissible, + timeout, + message, + }) +} + +export const addInfoToast = (message: string, dismissible: boolean = false, timeout: number = 1000) => { + addToast({ + type: "error", + dismissible, + timeout, + message, + }) +} + diff --git a/src/lib/icons/CloseIcon.svelte b/src/lib/icons/CloseIcon.svelte new file mode 100644 index 0000000..2911de3 --- /dev/null +++ b/src/lib/icons/CloseIcon.svelte @@ -0,0 +1,18 @@ + + + diff --git a/src/lib/icons/ErrorIcon.svelte b/src/lib/icons/ErrorIcon.svelte new file mode 100644 index 0000000..059d916 --- /dev/null +++ b/src/lib/icons/ErrorIcon.svelte @@ -0,0 +1,19 @@ + + + diff --git a/src/lib/icons/InfoIcon.svelte b/src/lib/icons/InfoIcon.svelte new file mode 100644 index 0000000..d39711b --- /dev/null +++ b/src/lib/icons/InfoIcon.svelte @@ -0,0 +1,18 @@ + + + diff --git a/src/lib/icons/SuccessIcon.svelte b/src/lib/icons/SuccessIcon.svelte new file mode 100644 index 0000000..18a7b93 --- /dev/null +++ b/src/lib/icons/SuccessIcon.svelte @@ -0,0 +1,18 @@ + + +