feat(fase-16): add Spinner component + unit tests

Fase 16.1 — reusable inline loading indicator. SVG circle with
stroke-dasharray + Tailwind animate-spin (respects motion-reduce).
Sizes: sm=16, md=24, lg=40. Inherits currentColor so it plays nicely
with the Fase 9 theme tokens. Wrapper has role=status + aria-live=polite
and an sr-only m.loading() label (no new Paraglide strings).

vitest.config: resolve.conditions=['browser'] + inline svelte so the
Svelte 5 mount() API resolves to index-client.js instead of the server
entry. Without it the new Spinner.test throws lifecycle_function_unavailable.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-18 13:39:40 +02:00
parent 51e62ecba3
commit f01dc21e74
3 changed files with 125 additions and 1 deletions

View File

@@ -0,0 +1,34 @@
<script lang="ts">
import * as m from '$lib/paraglide/messages';
interface Props {
size?: 'sm' | 'md' | 'lg';
class?: string;
}
let { size = 'md', class: extra = '' }: Props = $props();
const px = $derived(size === 'sm' ? 16 : size === 'lg' ? 40 : 24);
</script>
<div role="status" aria-live="polite" class={extra}>
<svg
data-testid="spinner"
width={px}
height={px}
viewBox="0 0 24 24"
fill="none"
class="animate-spin motion-reduce:animate-none"
>
<circle
cx="12"
cy="12"
r="9"
stroke="currentColor"
stroke-width="2.5"
stroke-linecap="round"
stroke-dasharray="42 14"
opacity="0.75"
/>
</svg>
<span class="sr-only">{m.loading()}</span>
</div>