Web: Skeleton-Loading (schimmernde Ladeplatzhalter)

Statt nacktem 'Lädt…'/'Wird geladen…' jetzt geformte, schimmernde
Platzhalter an den zentralen Stellen:
- Neuer Baustein components/Skeleton.jsx (Skeleton/SkeletonLines/CardSkeleton),
  Sweep-Animation, Farben aus CSS-Tokens (Dark-Mode automatisch), respektiert
  prefers-reduced-motion.
- DataTable: bei Erstladung Platzhalterzeilen in Spaltenform (deckt alle
  8 Tabellenseiten). Nachladen mit vorhandenen Zeilen laesst Daten stehen.
- Dashboard-Karten: Zustand-Wrapper + Inline-Diagramm-Lader zeigen
  KPI-/Listen-/Diagramm-Skelette passend zur Kartenform.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-08-04 00:30:25 +02:00
co-authored by Claude Opus 4.8
parent da5934948e
commit e214bb76a9
4 changed files with 126 additions and 17 deletions
+25 -5
View File
@@ -1,6 +1,7 @@
import { useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
import { createPortal } from "react-dom";
import Icon from "./Icon";
import { Skeleton } from "./Skeleton";
/**
* Excel-artige Tabelle in der bestehenden Designsprache: feste Filterzeile je
@@ -394,11 +395,30 @@ export default function DataTable({
</tr>
))}
{displayRows.length === 0 && (
// Während des Ladens NICHT „nichts gefunden" behaupten – die Leer-
// Meldung kommt erst, wenn die Daten wirklich da (und leer) sind.
<tr><td className="empty" colSpan={orderedCols.length}>
{loading ? "Wird geladen…" : empty}
</td></tr>
loading && rows.length === 0 ? (
// Erstladung: schimmernde Platzhalterzeilen in Spaltenform statt
// eines nackten „Wird geladen…". (Beim Nachladen mit bereits
// vorhandenen Zeilen greift dieser Zweig nicht - die Daten
// bleiben stehen.)
Array.from({ length: 8 }, (_, r) => (
<tr key={`skel-${r}`} className="skel-tr" aria-hidden="true">
{orderedCols.map((c, ci) => (
<td key={c.key} className={c.align === "num" ? "num" : ""}>
<Skeleton
w={c.align === "num" ? "40%" : `${[80, 64, 72, 58, 86][(r + ci) % 5]}%`}
style={c.align === "num" ? { marginLeft: "auto" } : undefined}
/>
</td>
))}
</tr>
))
) : (
// Während des Ladens NICHT „nichts gefunden" behaupten – die Leer-
// Meldung kommt erst, wenn die Daten wirklich da (und leer) sind.
<tr><td className="empty" colSpan={orderedCols.length}>
{loading ? "Wird geladen…" : empty}
</td></tr>
)
)}
</tbody>
</table>