feat: use mulShdSpin circular loader, smaller height, grow animation on load

This commit is contained in:
2026-01-25 18:07:17 -05:00
parent 87848d6eea
commit c998e2cdbb

View File

@@ -98,29 +98,70 @@
</div>
<!-- Performance Telemetry -->
<style>
.telemetry-loader {
color: hsl(var(--color-primary));
font-size: 8px;
width: 1em;
height: 1em;
border-radius: 50%;
position: relative;
text-indent: -9999em;
animation: mulShdSpin 1.3s infinite linear;
transform: translateZ(0);
}
@keyframes mulShdSpin {
0%, 100% {
box-shadow: 0 -3em 0 0.2em, 2em -2em 0 0em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 0;
}
12.5% {
box-shadow: 0 -3em 0 0, 2em -2em 0 0.2em, 3em 0 0 0, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
}
25% {
box-shadow: 0 -3em 0 -0.5em, 2em -2em 0 0, 3em 0 0 0.2em, 2em 2em 0 0, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
}
37.5% {
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 0, 2em 2em 0 0.2em, 0 3em 0 0em, -2em 2em 0 -1em, -3em 0em 0 -1em, -2em -2em 0 -1em;
}
50% {
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 0em, 0 3em 0 0.2em, -2em 2em 0 0, -3em 0em 0 -1em, -2em -2em 0 -1em;
}
62.5% {
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 0, -2em 2em 0 0.2em, -3em 0 0 0, -2em -2em 0 -1em;
}
75% {
box-shadow: 0em -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0.2em, -2em -2em 0 0;
}
87.5% {
box-shadow: 0em -3em 0 0, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0, -2em -2em 0 0.2em;
}
}
@keyframes telemetryGrow {
from { transform: scale(0.98); opacity: 0; }
to { transform: scale(1); opacity: 1; }
}
.telemetry-grow {
animation: telemetryGrow 0.4s ease-out forwards;
}
</style>
<section
wire:poll.120s="stats"
x-data="{ chartsLoaded: false, loadingProgress: 0 }"
@proxmox-all-stats-loaded.window="chartsLoaded = true"
@proxmox-chart-loaded.window="loadingProgress = Math.min(100, loadingProgress + 25)"
class="relative bg-background-secondary border border-neutral rounded-2xl shadow-sm overflow-hidden"
:class="chartsLoaded ? 'p-6 space-y-6' : 'p-4'"
class="relative bg-background-secondary border border-neutral rounded-2xl shadow-sm overflow-hidden transition-all duration-500 ease-out"
:class="chartsLoaded ? 'p-6 space-y-6' : 'p-3'"
>
<!-- Loading State - compact, grows when loaded -->
<div
x-ref="loadingOverlay"
x-init="$watch('chartsLoaded', value => { if(value) setTimeout(() => $refs.loadingOverlay.style.display = 'none', 300); })"
x-bind:class="chartsLoaded ? 'opacity-0 h-0 py-0' : 'opacity-100 py-8'"
class="flex flex-col items-center justify-center transition-all duration-500 ease-out overflow-hidden"
x-init="$watch('chartsLoaded', value => { if(value) setTimeout(() => $refs.loadingOverlay.style.display = 'none', 500); })"
x-bind:class="chartsLoaded ? 'opacity-0 h-0 py-0' : 'opacity-100 py-4'"
class="flex items-center justify-center transition-all duration-500 ease-out overflow-hidden"
>
<div class="flex items-center gap-4">
<!-- Circular Loading Spinner -->
<div class="relative w-10 h-10">
<svg class="w-10 h-10 animate-spin" viewBox="0 0 40 40" fill="none">
<circle cx="20" cy="20" r="16" stroke="currentColor" stroke-width="3" class="text-neutral/30"/>
<path d="M20 4 A16 16 0 0 1 36 20" stroke="currentColor" stroke-width="3" stroke-linecap="round" class="text-primary"/>
</svg>
</div>
<div class="telemetry-loader"></div>
<!-- Loading text -->
<div>
<p class="text-base/80 font-medium text-sm">Loading Telemetry</p>
@@ -130,7 +171,7 @@
</div>
<div
x-bind:class="chartsLoaded ? 'opacity-100 max-h-[5000px]' : 'opacity-0 max-h-0 overflow-hidden'"
x-bind:class="chartsLoaded ? 'telemetry-grow' : 'opacity-0 max-h-0 overflow-hidden'"
class="transition-all duration-500 ease-out"
>
<div class="flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between">