forked from tsai/budibase
17 changed files with 163 additions and 139 deletions
@ -0,0 +1,14 @@ |
|||||
|
import { writable } from 'svelte/store' |
||||
|
|
||||
|
export const notificationStore = writable() |
||||
|
|
||||
|
export function send(message, type = 'default', timeout) { |
||||
|
notificationStore.set({ type, message, timeout }) |
||||
|
} |
||||
|
|
||||
|
export const notifier = { |
||||
|
danger: msg => send(msg, "danger"), |
||||
|
warning: msg => send(msg, "warning"), |
||||
|
info: msg => send(msg, "info"), |
||||
|
success: msg => send(msg, "success") |
||||
|
} |
||||
@ -1,77 +0,0 @@ |
|||||
<script context="module"> |
|
||||
import UIKit from "uikit" |
|
||||
|
|
||||
export function showAppNotification({ message, status }) { |
|
||||
UIKit.notification({ |
|
||||
message: ` |
|
||||
<div class="message-container"> |
|
||||
<div class="information-icon">🤯</div> |
|
||||
<span class="notification-message"> |
|
||||
${message} |
|
||||
</span> |
|
||||
<button class="hoverable refresh-page-button" onclick="window.location.reload()">Refresh Page</button> |
|
||||
</div> |
|
||||
`, |
|
||||
status, |
|
||||
timeout: 100000, |
|
||||
}) |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style> |
|
||||
:global(.information-icon) { |
|
||||
font-size: 24px; |
|
||||
margin-right: 8px; |
|
||||
} |
|
||||
|
|
||||
:global(.uk-nofi) { |
|
||||
display: grid; |
|
||||
grid-template-columns: 40px 1fr auto; |
|
||||
grid-gap: 5px; |
|
||||
align-items: center; |
|
||||
} |
|
||||
|
|
||||
:global(.message-container) { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
} |
|
||||
|
|
||||
:global(.uk-notification) { |
|
||||
width: 50% !important; |
|
||||
left: 0 !important; |
|
||||
right: 0 !important; |
|
||||
margin-right: auto !important; |
|
||||
margin-left: auto !important; |
|
||||
border-radius: 10px; |
|
||||
} |
|
||||
|
|
||||
:global(.uk-notification-message) { |
|
||||
border-radius: 5px; |
|
||||
} |
|
||||
|
|
||||
:global(.uk-notification-message:hover .uk-notification-close) { |
|
||||
visibility: hidden; |
|
||||
} |
|
||||
|
|
||||
:global(.uk-notification-message-danger) { |
|
||||
background: var(--ink-light) !important; |
|
||||
color: #fff !important; |
|
||||
font-family: Roboto; |
|
||||
font-size: 16px !important; |
|
||||
} |
|
||||
|
|
||||
:global(.refresh-page-button) { |
|
||||
font-size: 14px; |
|
||||
border-radius: 3px; |
|
||||
border: none; |
|
||||
padding: 8px 16px; |
|
||||
color: var(--ink); |
|
||||
background: #ffffff; |
|
||||
margin-left: 20px; |
|
||||
} |
|
||||
|
|
||||
:global(.refresh-page-button):hover { |
|
||||
background: var(--grey-light); |
|
||||
} |
|
||||
</style> |
|
||||
@ -0,0 +1,119 @@ |
|||||
|
<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> |
||||
Loading…
Reference in new issue