mirror of
https://github.com/BradNut/svelte-library
synced 2025-09-08 17:40:21 +00:00
Adding duration, ids, error and info styling to Toast messages.
This commit is contained in:
parent
39d2fab7bf
commit
32b7a187e0
4 changed files with 62 additions and 36 deletions
|
|
@ -2,23 +2,21 @@
|
||||||
import { fly, fade } from 'svelte/transition';
|
import { fly, fade } from 'svelte/transition';
|
||||||
import { flip } from 'svelte/animate';
|
import { flip } from 'svelte/animate';
|
||||||
import Portal from '../Portal.svelte';
|
import Portal from '../Portal.svelte';
|
||||||
import { toast } from './toast';
|
|
||||||
import ToastMessage from './ToastMessage.svelte';
|
import ToastMessage from './ToastMessage.svelte';
|
||||||
|
import { toast } from './toast';
|
||||||
export let duration = 1000;
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Portal>
|
<Portal>
|
||||||
<div class="toast-wrapper">
|
<div class="toast-wrapper">
|
||||||
{#each $toast as message (message)}
|
{#each $toast as message (message.id)}
|
||||||
<div
|
<div
|
||||||
on:click={toast.remove}
|
on:click={() => toast.remove(message.id)}
|
||||||
animate:flip
|
|
||||||
out:fade
|
|
||||||
in:fly={{ opacity: 0, x: 100 }}
|
in:fly={{ opacity: 0, x: 100 }}
|
||||||
class="toast"
|
out:fade
|
||||||
|
animate:flip
|
||||||
|
class={`toast ${message.type.toLowerCase()}`}
|
||||||
>
|
>
|
||||||
<ToastMessage {message} {duration} />
|
<ToastMessage {message} />
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -32,10 +30,18 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.toast {
|
.toast {
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
|
color: white;
|
||||||
|
background: var(--toast-background, #625df5);
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
border-radius: 15px;
|
border-radius: 15px;
|
||||||
background: white;
|
|
||||||
box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.3);
|
box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.toast.error {
|
||||||
|
background: var(--toast-error-background, #e54b4b);
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,32 @@
|
||||||
<script>
|
<script>
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { toast } from './toast';
|
|
||||||
import { tweened } from 'svelte/motion';
|
import { tweened } from 'svelte/motion';
|
||||||
|
import { toast } from './toast';
|
||||||
|
export let message;
|
||||||
|
|
||||||
export let message = '';
|
let progress = tweened(100, { duration: message.duration });
|
||||||
export let duration = 1000;
|
|
||||||
|
|
||||||
let progress = tweened(100, { duration });
|
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
await progress.set(0);
|
await progress.set(0);
|
||||||
toast.remove();
|
toast.remove(message.id);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div style={`width: ${$progress}%; height: 10px; background: green;`} />
|
<div class="progress" style={`width: ${$progress}%;`} />
|
||||||
<p>{message}</p>
|
<p>{message.message}</p>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
.progress {
|
||||||
|
height: 8px;
|
||||||
|
background: white;
|
||||||
|
opacity: 0.3;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,28 @@
|
||||||
import { writable } from "svelte/store";
|
import { writable } from 'svelte/store';
|
||||||
|
|
||||||
|
// Custom store
|
||||||
const newToast = () => {
|
const newToast = () => {
|
||||||
const { subscribe, update } = writable([]);
|
const { subscribe, update } = writable([]);
|
||||||
|
|
||||||
function send(message) {
|
|
||||||
update((state) => {
|
|
||||||
return [...state, message];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function remove() {
|
function send(message, { duration = 2000, type = 'INFO' } = {}) {
|
||||||
update((state) => {
|
const id = Math.floor(Math.random() * 1000);
|
||||||
let [first, ...rest] = state;
|
const newMessage = {
|
||||||
return [...rest];
|
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();
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,12 @@
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
<Toast duration={3000} />
|
<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> -->
|
<!-- <button on:click={() => (isModalOpen = true)}>Open Modal Form</button> -->
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue