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:
34
apps/web/src/lib/components/Spinner.svelte
Normal file
34
apps/web/src/lib/components/Spinner.svelte
Normal 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>
|
||||
Reference in New Issue
Block a user