GuardRateLeaderboard / src /lib /components /Transition.svelte
Anton Malykhin
feat: integrate bucket-backed leaderboard data
c6afb12
Raw
History Blame Contribute Delete
1.03 kB
<script lang="ts">
import type { Snippet } from 'svelte';
import { prefersReducedMotion } from 'svelte/motion';
import { fade } from 'svelte/transition';
import { Spinner } from '$lib/components/ui/spinner';
type Props = {
children: Snippet;
url: string;
loading?: boolean;
};
let { children, url, loading = false }: Props = $props();
const fadeDuration = $derived(prefersReducedMotion.current ? 0 : 200);
</script>
<div class="relative min-h-[calc(100dvh-var(--app-header-height))]" aria-busy={loading}>
{#key url}
<div
class="flex min-h-[calc(100dvh-var(--app-header-height))] flex-col"
in:fade={{ duration: fadeDuration }}
>
{@render children?.()}
</div>
{/key}
{#if loading}
<div
class="fixed inset-x-0 bottom-0 z-40 flex items-center justify-center bg-background/70 backdrop-blur-[2px]"
style:top="var(--app-header-height)"
in:fade={{ duration: fadeDuration }}
out:fade={{ duration: fadeDuration }}
>
<Spinner class="size-8 text-primary" />
</div>
{/if}
</div>