82 lines
1.9 KiB
Svelte
82 lines
1.9 KiB
Svelte
<script lang="ts">
|
|
import type { Health } from '$ui/stores/servers.js';
|
|
import { statusPresentation, statusShapes, type StatusTone } from '$ui/status.js';
|
|
|
|
interface Props {
|
|
health?: Health;
|
|
state?: string;
|
|
tone?: StatusTone;
|
|
size?: 'sm' | 'md';
|
|
label?: string | null;
|
|
}
|
|
|
|
let { health = 'offline', state, tone, size = 'md', label = null }: Props = $props();
|
|
const presentation = $derived(statusPresentation(state ?? health));
|
|
const resolvedTone = $derived(tone ?? presentation.tone);
|
|
const shape = $derived(statusShapes[resolvedTone]);
|
|
</script>
|
|
|
|
<span
|
|
class="pip s-{size} t-{resolvedTone} shape-{shape}"
|
|
role={label ? 'img' : undefined}
|
|
aria-label={label ?? undefined}
|
|
aria-hidden={label ? undefined : true}
|
|
></span>
|
|
|
|
<style>
|
|
.pip {
|
|
display: inline-flex;
|
|
flex-shrink: 0;
|
|
box-sizing: border-box;
|
|
}
|
|
.s-sm {
|
|
width: 10px;
|
|
height: 10px;
|
|
}
|
|
.s-md {
|
|
width: 12px;
|
|
height: 12px;
|
|
}
|
|
.t-online {
|
|
color: var(--state-online);
|
|
}
|
|
.t-warning {
|
|
color: var(--state-warning);
|
|
}
|
|
.t-danger {
|
|
color: var(--state-danger);
|
|
}
|
|
.t-info {
|
|
color: var(--state-info);
|
|
}
|
|
.t-neutral {
|
|
color: var(--state-neutral);
|
|
}
|
|
.shape-circle {
|
|
border-radius: 50%;
|
|
background: currentColor;
|
|
}
|
|
.shape-square {
|
|
border-radius: 2px;
|
|
background: currentColor;
|
|
}
|
|
.shape-triangle {
|
|
background: currentColor;
|
|
clip-path: polygon(50% 0, 100% 100%, 0 100%);
|
|
}
|
|
.shape-hollow,
|
|
.shape-ring {
|
|
border: 2px solid currentColor;
|
|
border-radius: 50%;
|
|
}
|
|
.shape-ring {
|
|
border-right-color: transparent;
|
|
animation: status-spin 1s linear infinite;
|
|
}
|
|
@keyframes status-spin {
|
|
to {
|
|
transform: rotate(360deg);
|
|
}
|
|
}
|
|
</style>
|