aboutsummaryrefslogtreecommitdiff
path: root/src/lib/Notification
diff options
context:
space:
mode:
authorFuwn <[email protected]>2024-01-11 18:45:31 -0800
committerFuwn <[email protected]>2024-01-11 18:45:31 -0800
commit1b71b6a1197967271528fd0d5b9ff5fc9a1f3c26 (patch)
tree5261f5d00e22b53e89420c3c1b5fa97d60253d6e /src/lib/Notification
parentrefactor(routes): move shortcuts to hooks (diff)
downloaddue.moe-1b71b6a1197967271528fd0d5b9ff5fc9a1f3c26.tar.xz
due.moe-1b71b6a1197967271528fd0d5b9ff5fc9a1f3c26.zip
feat: notifications
Diffstat (limited to 'src/lib/Notification')
-rw-r--r--src/lib/Notification/Notification.svelte112
-rw-r--r--src/lib/Notification/options.ts19
2 files changed, 131 insertions, 0 deletions
diff --git a/src/lib/Notification/Notification.svelte b/src/lib/Notification/Notification.svelte
new file mode 100644
index 00000000..9612d526
--- /dev/null
+++ b/src/lib/Notification/Notification.svelte
@@ -0,0 +1,112 @@
+<script lang="ts">
+ import { onMount } from 'svelte';
+
+ export let notification: { [key: string]: any } = {};
+ export let onRemove: () => void = () => {
+ return;
+ };
+ export let removed = false;
+
+ onMount(() => setTimeout(remove, notification.duration));
+
+ const remove = () => {
+ removed = true;
+
+ setTimeout(onRemove, 150);
+ };
+</script>
+
+<div id="notification-container" class={removed ? 'fade-out' : 'fade-in'}>
+ {#if notification.description}
+ <details open id="notification">
+ <summary>{@html notification.heading}</summary>
+
+ {@html notification.description}
+
+ <br />
+
+ <div class="button-container">
+ <button on:click={remove} class="button-hide">Hide</button>
+ </div>
+ </details>
+ {:else}
+ <div class="card" id="notification">
+ {@html notification.heading}
+
+ &nbsp; &nbsp;
+
+ <div class="button-container">
+ <button on:click={remove} class="button-hide">Hide</button>
+ </div>
+ </div>
+ {/if}
+</div>
+
+<style>
+ #notification-container {
+ margin: 1rem 1rem 0 0;
+ float: right;
+ }
+
+ #notification {
+ background-color: var(--base001);
+ box-shadow: rgba(0, 0, 11, 0.2) 0px 7px 29px 0px, 0 0 0 4px var(--base0E);
+
+ widows: 100%;
+ }
+
+ .button-container {
+ display: flex;
+ justify-content: flex-end;
+ }
+
+ #notification > div {
+ display: inline;
+ }
+
+ .button-hide {
+ float: right;
+ }
+
+ .button-container::after {
+ content: '';
+ clear: both;
+ display: table;
+ }
+
+ .fade-in {
+ animation: fadeInAnimation ease 300ms;
+ animation-iteration-count: 1;
+ animation-fill-mode: forwards;
+ }
+
+ .fade-out {
+ animation: fadeOutAnimation ease 150ms;
+ animation-iteration-count: 1;
+ animation-fill-mode: forwards;
+ }
+
+ @keyframes fadeInAnimation {
+ 100% {
+ opacity: 1;
+ }
+ 1% {
+ opacity: 0.01;
+ }
+ 0% {
+ opacity: 0;
+ }
+ }
+
+ @keyframes fadeOutAnimation {
+ 0% {
+ opacity: 1;
+ }
+ 99% {
+ opacity: 0.01;
+ }
+ 100% {
+ opacity: 0;
+ }
+ }
+</style>
diff --git a/src/lib/Notification/options.ts b/src/lib/Notification/options.ts
new file mode 100644
index 00000000..f14e0d25
--- /dev/null
+++ b/src/lib/Notification/options.ts
@@ -0,0 +1,19 @@
+type Position = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
+
+interface Options {
+ heading: string | number;
+ description: string | number | undefined;
+ position: Position;
+ duration: number;
+ id: string;
+}
+
+export const options = (preferences: { [key: string]: number | string }): Options => {
+ return {
+ position: (preferences.position || 'top-right') as Position,
+ duration: Number(preferences.duration || 3000),
+ heading: preferences.heading || 'Notification',
+ description: preferences.description || undefined,
+ id: Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)
+ };
+};