custom notifications solution
This commit is contained in:
parent
01d7f80e7b
commit
2c764a787c
|
@ -4,7 +4,7 @@
|
|||
import { Router, basepath } from "@sveltech/routify"
|
||||
import { routes } from "../routify/routes"
|
||||
import { store, initialise } from "builderStore"
|
||||
import NotificationDisplay from "components/common/Notification.svelte";
|
||||
import NotificationDisplay from "components/common/Notification/NotificationDisplay.svelte";
|
||||
|
||||
$basepath = "/_builder"
|
||||
</script>
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
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) {
|
||||
notificationStore.set({ type, message, timeout })
|
||||
export function send(message, type = 'default') {
|
||||
notificationStore.update(state => {
|
||||
state.notifications = [...state.notifications, { id: generate(), type, message }]
|
||||
return state
|
||||
})
|
||||
}
|
||||
|
||||
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