32 lines
727 B
Svelte
32 lines
727 B
Svelte
<script lang="ts">
|
|
type ImageStatus = 'loading' | 'loaded' | 'error';
|
|
import type { HTMLImgAttributes } from 'svelte/elements';
|
|
|
|
let { src, fallback, ...props }: HTMLImgAttributes & { fallback?: string } = $props();
|
|
let status: ImageStatus = $state('loading');
|
|
let useFallback = $state(false);
|
|
|
|
const currentSrc = $derived(useFallback && fallback ? fallback : src);
|
|
</script>
|
|
|
|
{#if status === 'loading'}
|
|
<div class="h-full w-full animate-pulse bg-gray-800"></div>
|
|
{/if}
|
|
|
|
<img
|
|
src={currentSrc}
|
|
hidden={status === 'loading'}
|
|
onload={() => {
|
|
status = 'loaded';
|
|
}}
|
|
onerror={() => {
|
|
if (!useFallback && fallback) {
|
|
useFallback = true;
|
|
status = 'loading';
|
|
} else {
|
|
status = 'error';
|
|
}
|
|
}}
|
|
{...props}
|
|
/>
|