Files
crumbs-original/src/lib/components/SyncIndicator.svelte
T
Frederic CabassutandClaude Opus 4.6 eb18242f5a style: unify color system and add retro card shadows
Replace hardcoded colors (gray-500, #b44, red-300/red-50/red-600,
green-600) with CSS variables for theme consistency. Add --destructive,
--error-*, --success-*, and --card-shadow variables to :root. Soften
default card borders from --border to --border-subtle and add 8-bit
style hard-offset shadows with hover effects. Apply accent-color for
themed checkboxes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 23:12:36 +01:00

58 lines
1.7 KiB
Svelte

<script lang="ts">
import { onMount, onDestroy } from 'svelte';
import { getSyncStatus, onSyncStatusChange, type SyncStatus } from '$lib/sync/client.js';
import CloudCheck from 'lucide-svelte/icons/cloud-check';
import CloudSync from 'lucide-svelte/icons/cloud-sync';
import CloudOff from 'lucide-svelte/icons/cloud-off';
import CloudAlert from 'lucide-svelte/icons/cloud-alert';
let status: SyncStatus = $state(getSyncStatus());
let displayStatus: SyncStatus = $state(getSyncStatus());
let minDisplayTimeout: ReturnType<typeof setTimeout> | undefined;
let pendingStatus: SyncStatus | undefined;
function applyStatus(s: SyncStatus) {
if (displayStatus === s) return;
if (minDisplayTimeout) {
pendingStatus = s;
return;
}
displayStatus = s;
minDisplayTimeout = setTimeout(() => {
minDisplayTimeout = undefined;
if (pendingStatus !== undefined && pendingStatus !== displayStatus) {
applyStatus(pendingStatus);
pendingStatus = undefined;
}
}, 300);
}
let unsubscribe: (() => void) | undefined;
onMount(() => {
unsubscribe = onSyncStatusChange((s) => {
status = s;
applyStatus(s);
});
});
onDestroy(() => {
unsubscribe?.();
if (minDisplayTimeout) clearTimeout(minDisplayTimeout);
});
</script>
<div class="flex items-center" title="Sync status: {status}" data-testid="sync-indicator">
{#if displayStatus === 'synced'}
<CloudCheck class="h-5 w-5 text-[var(--primary)]" />
{:else if displayStatus === 'syncing'}
<CloudSync class="h-5 w-5 text-[var(--primary)] opacity-60" />
{:else if displayStatus === 'offline'}
<CloudOff class="h-5 w-5 text-[var(--text-muted)]" />
{:else}
<CloudAlert class="h-5 w-5 text-[var(--destructive)]" />
{/if}
</div>