78 lines
2.3 KiB
Svelte
78 lines
2.3 KiB
Svelte
<!--
|
|
Component: Loader
|
|
Displays a loading spinner with an optional message.
|
|
-->
|
|
<script lang="ts">
|
|
import { fade } from 'svelte/transition';
|
|
|
|
interface Props {
|
|
/**
|
|
* Icon size (in pixels)
|
|
* @default 20
|
|
*/
|
|
size?: number;
|
|
/**
|
|
* Additional classes for container
|
|
*/
|
|
class?: string;
|
|
/**
|
|
* Message text
|
|
* @default analyzing_data
|
|
*/
|
|
message?: string;
|
|
}
|
|
|
|
let { size = 20, class: className = '', message = 'analyzing_data' }: Props = $props();
|
|
</script>
|
|
|
|
<div
|
|
class="absolute inset-x-0 inset-y-0 flex items-center justify-center gap-4 {className}"
|
|
in:fade={{ duration: 300 }}
|
|
out:fade={{ duration: 300 }}
|
|
>
|
|
<div style:width="{size}px" style:height="{size}px">
|
|
<svg class="stroke-gray-900 stroke-1" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
<g transform="translate(12, 12)">
|
|
<!-- Four corner brackets rotating -->
|
|
<g>
|
|
<path
|
|
d="M -8 -8 L -4 -8 M -8 -8 L -8 -4"
|
|
stroke="currentColor"
|
|
stroke-width="1"
|
|
stroke-linecap="round"
|
|
/>
|
|
<path
|
|
d="M 8 -8 L 4 -8 M 8 -8 L 8 -4"
|
|
stroke="currentColor"
|
|
stroke-width="1"
|
|
stroke-linecap="round"
|
|
/>
|
|
<path
|
|
d="M -8 8 L -4 8 M -8 8 L -8 4"
|
|
stroke="currentColor"
|
|
stroke-width="1"
|
|
stroke-linecap="round"
|
|
/>
|
|
<path d="M 8 8 L 4 8 M 8 8 L 8 4" stroke="currentColor" stroke-width="1" stroke-linecap="round" />
|
|
|
|
<animateTransform
|
|
attributeName="transform"
|
|
type="rotate"
|
|
from="0"
|
|
to="360"
|
|
dur="3s"
|
|
repeatCount="indefinite"
|
|
/>
|
|
</g>
|
|
</g>
|
|
</svg>
|
|
</div>
|
|
<!-- Divider -->
|
|
<div class="w-px h-3 bg-gray-400/50"></div>
|
|
|
|
<!-- Message -->
|
|
<span class="font-mono text-[10px] uppercase tracking-[0.2em] text-gray-600 font-medium">
|
|
{message}
|
|
</span>
|
|
</div>
|