Adding duration, ids, error and info styling to Toast messages.

This commit is contained in:
Bradley Shellnut 2021-07-29 10:50:22 -07:00
parent 39d2fab7bf
commit 32b7a187e0
4 changed files with 62 additions and 36 deletions

View file

@ -2,23 +2,21 @@
import { fly, fade } from 'svelte/transition';
import { flip } from 'svelte/animate';
import Portal from '../Portal.svelte';
import { toast } from './toast';
import ToastMessage from './ToastMessage.svelte';
export let duration = 1000;
import { toast } from './toast';
</script>
<Portal>
<div class="toast-wrapper">
{#each $toast as message (message)}
{#each $toast as message (message.id)}
<div
on:click={toast.remove}
animate:flip
out:fade
on:click={() => toast.remove(message.id)}
in:fly={{ opacity: 0, x: 100 }}
class="toast"
out:fade
animate:flip
class={`toast ${message.type.toLowerCase()}`}
>
<ToastMessage {message} {duration} />
<ToastMessage {message} />
</div>
{/each}
</div>
@ -32,10 +30,18 @@
}
.toast {
overflow: hidden;
position: relative;
margin-bottom: 1rem;
color: white;
background: var(--toast-background, #625df5);
padding: 20px;
border-radius: 15px;
background: white;
box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.3);
}
.toast.error {
background: var(--toast-error-background, #e54b4b);
color: black;
}
</style>

View file

@ -1,23 +1,32 @@
<script>
import { onMount } from 'svelte';
import { toast } from './toast';
import { tweened } from 'svelte/motion';
import { toast } from './toast';
export let message;
export let message = '';
export let duration = 1000;
let progress = tweened(100, { duration });
let progress = tweened(100, { duration: message.duration });
onMount(async () => {
await progress.set(0);
toast.remove();
toast.remove(message.id);
});
</script>
<div style={`width: ${$progress}%; height: 10px; background: green;`} />
<p>{message}</p>
<div class="progress" style={`width: ${$progress}%;`} />
<p>{message.message}</p>
<style>
.progress {
height: 8px;
background: white;
opacity: 0.3;
position: absolute;
top: 0;
left: 0;
right: 0;
}
p {
margin: 0;
}

View file

@ -1,22 +1,28 @@
import { writable } from "svelte/store";
import { writable } from 'svelte/store';
// Custom store
const newToast = () => {
const { subscribe, update } = writable([]);
function send(message) {
update((state) => {
return [...state, message];
});
}
const { subscribe, update } = writable([]);
function remove() {
update((state) => {
let [first, ...rest] = state;
return [...rest];
});
}
function send(message, { duration = 2000, type = 'INFO' } = {}) {
const id = Math.floor(Math.random() * 1000);
const newMessage = {
id,
duration,
type,
message
};
update((store) => [...store, newMessage]);
}
return { subscribe, send, remove };
}
function remove(id) {
update((store) => {
let newStore = store.filter((item) => item.id !== id);
return [...newStore];
});
}
export const toast = newToast();
return { subscribe, send, remove };
};
export const toast = newToast();

View file

@ -27,7 +27,12 @@
</Modal>
<Toast duration={3000} />
<button on:click={() => toast.send('New Message' + Math.random())}>New Toast</button>
<button on:click={() => toast.send('NEW MESSAGE!')}>New Toast</button>
<button on:click={() => toast.send('NEW MESSAGE!', { duration: 3000 })}>3000 Duration</button>
<button on:click={() => toast.send('Error MESSAGE!', { duration: 5000, type: 'ERROR' })}
>Error Message</button
>
<!-- <button on:click={() => (isModalOpen = true)}>Open Modal Form</button> -->