custom notifications solution
This commit is contained in:
parent
01d7f80e7b
commit
2c764a787c
|
@ -4,7 +4,7 @@
|
||||||
import { Router, basepath } from "@sveltech/routify"
|
import { Router, basepath } from "@sveltech/routify"
|
||||||
import { routes } from "../routify/routes"
|
import { routes } from "../routify/routes"
|
||||||
import { store, initialise } from "builderStore"
|
import { store, initialise } from "builderStore"
|
||||||
import NotificationDisplay from "components/common/Notification.svelte";
|
import NotificationDisplay from "components/common/Notification/NotificationDisplay.svelte";
|
||||||
|
|
||||||
$basepath = "/_builder"
|
$basepath = "/_builder"
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
import { writable } from 'svelte/store'
|
import { writable } from 'svelte/store'
|
||||||
|
import { generate } from "shortid"
|
||||||
|
|
||||||
export const notificationStore = writable()
|
export const notificationStore = writable({
|
||||||
|
notifications: []
|
||||||
|
})
|
||||||
|
|
||||||
export function send(message, type = 'default', timeout) {
|
export function send(message, type = 'default') {
|
||||||
notificationStore.set({ type, message, timeout })
|
notificationStore.update(state => {
|
||||||
|
state.notifications = [...state.notifications, { id: generate(), type, message }]
|
||||||
|
return state
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const notifier = {
|
export const notifier = {
|
||||||
|
|
|
@ -1,119 +0,0 @@
|
||||||
<script>
|
|
||||||
import { notificationStore } from "builderStore/store/notifications"
|
|
||||||
import { onMount, onDestroy } from "svelte"
|
|
||||||
import { fade } from "svelte/transition"
|
|
||||||
|
|
||||||
export let themes = {
|
|
||||||
danger: "#bb2124",
|
|
||||||
success: "#22bb33",
|
|
||||||
warning: "#f0ad4e",
|
|
||||||
info: "#5bc0de",
|
|
||||||
default: "#aaaaaa",
|
|
||||||
}
|
|
||||||
|
|
||||||
export let timeout = 3000
|
|
||||||
|
|
||||||
let count = 0
|
|
||||||
let notifications = []
|
|
||||||
let unsubscribe
|
|
||||||
|
|
||||||
function createToast(msg, theme, to) {
|
|
||||||
const background = themes[theme] || themes["default"]
|
|
||||||
const id = count
|
|
||||||
notifications = [
|
|
||||||
{
|
|
||||||
id,
|
|
||||||
msg,
|
|
||||||
background,
|
|
||||||
timeout: to || timeout,
|
|
||||||
width: "100%",
|
|
||||||
},
|
|
||||||
...notifications,
|
|
||||||
]
|
|
||||||
setTimeout(() => removeNotification(id), to || timeout)
|
|
||||||
count = count + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
unsubscribe = notificationStore.subscribe(value => {
|
|
||||||
if (!value) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
createToast(value.message, value.type, value.timeout)
|
|
||||||
notificationStore.set()
|
|
||||||
})
|
|
||||||
|
|
||||||
onDestroy(unsubscribe)
|
|
||||||
|
|
||||||
function removeNotification(id) {
|
|
||||||
notifications = notifications.filter(t => t.id != id)
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<ul class="notifications">
|
|
||||||
{#each notifications as toast (toast.id)}
|
|
||||||
<li class="toast" style="background: {toast.background};" out:fade>
|
|
||||||
<div class="content">{toast.msg}</div>
|
|
||||||
</li>
|
|
||||||
{/each}
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
:global(.notifications) {
|
|
||||||
width: 40vw;
|
|
||||||
list-style: none;
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
padding: 0;
|
|
||||||
z-index: 9999;
|
|
||||||
}
|
|
||||||
|
|
||||||
:global(.notifications) > .toast {
|
|
||||||
position: relative;
|
|
||||||
margin: 10px;
|
|
||||||
min-width: 40vw;
|
|
||||||
position: relative;
|
|
||||||
animation: animate-in 350ms forwards;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
:global(.notifications) > .toast > .content {
|
|
||||||
padding: 10px;
|
|
||||||
display: block;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
:global(.notifications) > .toast:before,
|
|
||||||
:global(.notifications) > .toast:after {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
z-index: -1;
|
|
||||||
top: 50%;
|
|
||||||
bottom: 0;
|
|
||||||
left: 10px;
|
|
||||||
right: 10px;
|
|
||||||
border-radius: 100px / 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:global(.notifications) > .toast:after {
|
|
||||||
right: 10px;
|
|
||||||
left: auto;
|
|
||||||
transform: skew(8deg) rotate(3deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes animate-in {
|
|
||||||
0% {
|
|
||||||
width: 0;
|
|
||||||
opacity: 0;
|
|
||||||
transform: scale(1.15) translateY(20px);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
width: 40vw;
|
|
||||||
opacity: 1;
|
|
||||||
transform: scale(1) translateY(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
<script>
|
||||||
|
import { notificationStore } from "builderStore/store/notifications"
|
||||||
|
import { onMount, onDestroy } from "svelte"
|
||||||
|
import { fade } from "svelte/transition"
|
||||||
|
|
||||||
|
export let themes = {
|
||||||
|
danger: "#E26D69",
|
||||||
|
success: "#84C991",
|
||||||
|
warning: "#f0ad4e",
|
||||||
|
info: "#5bc0de",
|
||||||
|
default: "#aaaaaa",
|
||||||
|
}
|
||||||
|
|
||||||
|
export let timeout = 3000
|
||||||
|
|
||||||
|
$: if ($notificationStore.notifications.length) {
|
||||||
|
setTimeout(() => {
|
||||||
|
notificationStore.update(state => {
|
||||||
|
state.notifications.shift();
|
||||||
|
state.notifications = state.notifications
|
||||||
|
return state;
|
||||||
|
})
|
||||||
|
}, timeout)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<ul class="notifications">
|
||||||
|
{#each $notificationStore.notifications as notification (notification.id)}
|
||||||
|
<li class="toast" style="background: {themes[notification.type]};" transition:fade>
|
||||||
|
<div class="content">{notification.message}</div>
|
||||||
|
{#if notification.icon}
|
||||||
|
<i class={notification.icon} />
|
||||||
|
{/if}
|
||||||
|
</li>
|
||||||
|
{/each}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.notifications {
|
||||||
|
width: 40vw;
|
||||||
|
list-style: none;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
padding: 0;
|
||||||
|
z-index: 9999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toast {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
padding: 10px;
|
||||||
|
display: block;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
</style>
|
Loading…
Reference in New Issue