55 lines
1.3 KiB
Svelte
55 lines
1.3 KiB
Svelte
<script lang="ts">
|
|
import { ExclamationCircle } from 'svelte-heros-v2';
|
|
import { fly } from 'svelte/transition';
|
|
import { onDestroy } from 'svelte';
|
|
|
|
let { children, timeout = 2000, show = false } = $props();
|
|
|
|
let progressValue = $state(100);
|
|
let intervalClear: ReturnType<typeof setInterval> | undefined = $state();
|
|
|
|
function startTimout() {
|
|
intervalClear = setInterval(() => {
|
|
if (++progressValue > 100) {
|
|
clearInterval(intervalClear);
|
|
show = false;
|
|
progressValue = 100;
|
|
}
|
|
}, timeout / 100);
|
|
}
|
|
|
|
$effect(() => {
|
|
if (!show) return;
|
|
progressValue = 0;
|
|
startTimout();
|
|
});
|
|
|
|
onDestroy(() => clearInterval(intervalClear));
|
|
</script>
|
|
|
|
{#if show && progressValue !== 0}
|
|
<div
|
|
in:fly={{ x: 0, duration: 200 }}
|
|
out:fly={{ x: 400, duration: 400 }}
|
|
class="toast"
|
|
onmouseenter={() => {
|
|
clearInterval(intervalClear);
|
|
progressValue = 1;
|
|
}}
|
|
onmouseleave={startTimout}
|
|
role="alert"
|
|
>
|
|
<div class="alert alert-error border-none relative text-gray-900 overflow-hidden">
|
|
<div class="flex gap-2 z-10">
|
|
<ExclamationCircle />
|
|
{@render children()}
|
|
</div>
|
|
<progress
|
|
class="progress progress-error absolute bottom-0 h-[3px] w-full bg-[rgba(0,0,0,0.6)]"
|
|
value={progressValue}
|
|
max="100"
|
|
></progress>
|
|
</div>
|
|
</div>
|
|
{/if}
|