E2EE Group Finance Management
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

137 lines
2.7 KiB

<style>
#footer {
position: fixed;
bottom: 0;
width: 100%;
z-index: 20;
}
#toast-box {
display: flex;
justify-content: space-around;
align-items: center;
flex-direction: row;
width: 50%;
max-width: 500px;
margin: 1em auto;
cursor: pointer;
border-radius: 5px;
font-weight: 700;
padding: 0.5rem 1rem;
font-size: 1rem;
color: var(--c2);
background-color: white;
box-shadow: 0 0.25em 0.25em 0 rgba(65, 65, 65, 0.35);
border: 3px solid greenyellow;
}
span.icon {
font-size: 1.5em;
}
div p {
text-align: center;
}
#toast-box.removed {
border-color: var(--red);
}
#toast-box.created {
border-color: var(--green);
}
#toast-box.updated {
border-color: navy;
}
#toast-box.warning {
border-color: gold;
}
.pulse-anim {
animation: pulse 0.25s ease-in-out;
}
@keyframes pulse {
0% {
scale: 1;
}
50% {
scale: 1.1;
}
}
</style>
<script>
import { onMount, onDestroy } from "svelte";
import { toast } from "@app/stores";
import { fly } from "svelte/transition";
import { cubicInOut } from "svelte/easing";
import type { IToast } from "@app/types/store.types";
export let displayTime = 3000;
let timeoutId: number;
let oldToast: IToast;
let toastElement: HTMLElement;
let toastUnsubscribe: () => void;
onMount(() => {
toastUnsubscribe = toast.subscribe((x: IToast) =>
onToastChange(x, displayTime),
);
});
const onToastChange = (newToast: IToast, ms: number) => {
// Pulse the toast to regain user attention when the toast is the same
if (oldToast && oldToast.content == newToast.content) {
toastElement.classList.remove("pulse-anim");
// Invalidate the DOM to re-render
void toastElement.offsetWidth;
toastElement.classList.add("pulse-anim");
}
if (newToast.content && ms > 0) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
clearToast();
}, ms);
oldToast = newToast;
}
};
const clearToast = () => {
toast.reset();
};
onDestroy(() => {
clearTimeout(timeoutId);
toastUnsubscribe();
});
</script>
{#if $toast.content}
<div
id="footer"
transition:fly="{{ y: 100, duration: 250, easing: cubicInOut }}"
on:close
>
<div
bind:this="{toastElement}"
id="toast-box"
class="{$toast.style}"
role="alert"
on:click="{() => clearToast()}"
>
{#if $toast.style == "warning"}
<span class="icon">⚠️</span>
<p>{$toast.content}</p>
<span class="icon">⚠️</span>
{:else}
<p>{$toast.content}</p>
{/if}
</div>
</div>
{/if}