Lib: Implement site loading indicator
This commit is contained in:
62
src/lib/components/LoadingIndicator.svelte
Normal file
62
src/lib/components/LoadingIndicator.svelte
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
<!-- https://www.sveltelab.dev/dc0nf9id4ust2vw -->
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { navigating } from "$app/stores";
|
||||||
|
|
||||||
|
let loading: string = $state("no");
|
||||||
|
let percentage: number = $state(0);
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
if ($navigating) {
|
||||||
|
loading = "yes";
|
||||||
|
} else {
|
||||||
|
loading = "closing";
|
||||||
|
setTimeout(() => {
|
||||||
|
loading = "no";
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
if (loading === "closing") {
|
||||||
|
percentage = 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const load = (_node: HTMLElement) => {
|
||||||
|
let timeout: NodeJS.Timeout;
|
||||||
|
const handle = () => {
|
||||||
|
if (percentage < 0.7) {
|
||||||
|
percentage += Math.random() * 0.3;
|
||||||
|
|
||||||
|
// Let's call ourselves recursively to fill the loading bar
|
||||||
|
timeout = setTimeout(handle, Math.random() * 1000);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
handle();
|
||||||
|
|
||||||
|
return {
|
||||||
|
destroy() {
|
||||||
|
clearTimeout(timeout);
|
||||||
|
percentage = 0;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if loading !== "no"}
|
||||||
|
<div
|
||||||
|
class="fixed inset-0 bottom-auto z-50 h-1 bg-error-500"
|
||||||
|
use:load
|
||||||
|
style:--percentage={percentage}
|
||||||
|
></div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
div {
|
||||||
|
transform-origin: left;
|
||||||
|
transform: scaleX(calc(var(--percentage) * 100%));
|
||||||
|
transition: transform 250ms;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user