dimensionlab-website/src/lib/ui/components/ModuleCard.svelte
2026-06-19 04:21:57 +02:00

104 lines
2.3 KiB
Svelte

<script lang="ts">
import type { UiModuleBlock } from "../types";
import IconGlyph from "./IconGlyph.svelte";
const generatedId = $props.id();
let { module }: { module: UiModuleBlock } = $props();
let titleId = $derived(`${generatedId}-title`);
let ariaLabel = $derived(module.title ? undefined : module.label || module.id);
</script>
<aside
class="module-card"
data-severity={module.severity || "neutral"}
data-model-id={module.id}
aria-labelledby={module.title ? titleId : undefined}
aria-label={ariaLabel}
>
<div>
{#if module.title}
<h2 id={titleId}>{module.title}</h2>
{/if}
{#if module.value}
<strong>{module.value}</strong>
{/if}
{#if module.detail || module.label}
<p>{module.detail || module.label}</p>
{/if}
</div>
{#if module.icon}
<IconGlyph name={module.icon} size="lg" />
{/if}
</aside>
<style>
.module-card {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
gap: 0.5rem;
align-items: start;
min-width: 0;
min-height: 4.15rem;
border: var(--ui-border);
background: rgba(6, 8, 7, 0.82);
padding: 0.5rem;
}
h2,
p {
margin: 0;
}
h2 {
color: var(--ui-color-muted);
font-size: 0.56rem;
line-height: 1;
text-transform: uppercase;
}
strong {
display: block;
margin-top: 0.15rem;
font-family: var(--ui-font-display);
font-size: clamp(1.25rem, 1.75vw, 1.72rem);
line-height: 0.82;
overflow-wrap: anywhere;
}
p {
margin-top: 0.2rem;
color: var(--ui-color-muted);
font-size: 0.49rem;
line-height: 1.05;
overflow: hidden;
text-overflow: ellipsis;
text-transform: uppercase;
white-space: nowrap;
}
.module-card[data-severity="ok"] :global(.icon-glyph) {
background: var(--ui-color-accent);
color: #050605;
}
.module-card[data-severity="warning"] {
border-color: color-mix(in srgb, var(--ui-color-warning), transparent 42%);
color: var(--ui-color-warning);
}
.module-card[data-severity="danger"] {
border-color: color-mix(in srgb, var(--ui-color-danger), transparent 32%);
color: var(--ui-color-danger);
}
.module-card[data-severity="stale"],
.module-card[data-severity="unavailable"] {
color: var(--ui-color-stale);
}
.module-card[data-severity="loading"] {
color: var(--ui-color-accent);
}
</style>