Replaces ad-hoc "Loading…" text and bare empty messages with two
shared feedback primitives that carry subtle lucide icons, consistent
muted-foreground/destructive tones, and a11y signaling (role=status,
aria-busy, role=alert on destructive empties). Loading copy gains
context ("Loading photos/folders/heaps/metadata…") and the right-
sidebar idle state moves from a "ⓘ" glyph to a MousePointerClick
icon. SkeletonGrid stays as the initial-grid loader.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
40 lines
1.1 KiB
Svelte
40 lines
1.1 KiB
Svelte
<!--
|
|
Tiny "Loading…" indicator: spinner + label. Use this for in-flight queries
|
|
in sidebars, popovers, and right rails. For the initial photo-grid load,
|
|
use SkeletonGrid instead (layout-preserving).
|
|
-->
|
|
<script lang="ts">
|
|
import { Loader2 } from 'lucide-svelte';
|
|
|
|
interface Props {
|
|
label?: string;
|
|
size?: 'sm' | 'default';
|
|
align?: 'left' | 'center';
|
|
srOnly?: boolean;
|
|
polite?: boolean;
|
|
}
|
|
|
|
let {
|
|
label = 'Loading…',
|
|
size = 'default',
|
|
align = 'left',
|
|
srOnly = false,
|
|
polite = true
|
|
}: Props = $props();
|
|
|
|
const textSize = $derived(size === 'sm' ? 'text-[11px]' : 'text-xs');
|
|
const iconSize = $derived(size === 'sm' ? 'h-3 w-3' : 'h-3.5 w-3.5');
|
|
const padding = $derived(size === 'sm' ? 'px-3 py-2' : 'px-3 py-2');
|
|
const justify = $derived(align === 'center' ? 'justify-center' : 'justify-start');
|
|
</script>
|
|
|
|
<p
|
|
role="status"
|
|
aria-busy="true"
|
|
aria-live={polite ? 'polite' : 'off'}
|
|
class="flex items-center gap-1.5 {padding} {textSize} {justify} text-muted-foreground"
|
|
>
|
|
<Loader2 class="{iconSize} animate-spin" aria-hidden="true" />
|
|
<span class={srOnly ? 'sr-only' : ''}>{label}</span>
|
|
</p>
|