From e214bb76a90e612e2d77db5107e6322c9351642b Mon Sep 17 00:00:00 2001 From: Scarriffle Date: Tue, 4 Aug 2026 00:30:25 +0200 Subject: [PATCH] Web: Skeleton-Loading (schimmernde Ladeplatzhalter) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- web/src/components/DataTable.jsx | 30 +++++++++++++--- web/src/components/Skeleton.jsx | 61 ++++++++++++++++++++++++++++++++ web/src/dashboard/cards.jsx | 25 ++++++------- web/src/styles.css | 27 ++++++++++++++ 4 files changed, 126 insertions(+), 17 deletions(-) create mode 100644 web/src/components/Skeleton.jsx diff --git a/web/src/components/DataTable.jsx b/web/src/components/DataTable.jsx index ccd6a13..c5108e9 100644 --- a/web/src/components/DataTable.jsx +++ b/web/src/components/DataTable.jsx @@ -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({ ))} {displayRows.length === 0 && ( - // Während des Ladens NICHT „nichts gefunden" behaupten – die Leer- - // Meldung kommt erst, wenn die Daten wirklich da (und leer) sind. - - {loading ? "Wird geladen…" : empty} - + 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) => ( + + {orderedCols.map((c, ci) => ( + + + + ))} + + )) + ) : ( + // Während des Ladens NICHT „nichts gefunden" behaupten – die Leer- + // Meldung kommt erst, wenn die Daten wirklich da (und leer) sind. + + {loading ? "Wird geladen…" : empty} + + ) )} diff --git a/web/src/components/Skeleton.jsx b/web/src/components/Skeleton.jsx new file mode 100644 index 0000000..82688c9 --- /dev/null +++ b/web/src/components/Skeleton.jsx @@ -0,0 +1,61 @@ +/** + * Schimmernde Ladeplatzhalter ("Skeleton"). Nur CSS-Tokens (--surface-2 / + * --border), passt sich daher automatisch an Hell/Dunkel an. Reine Deko, deshalb + * durchgehend aria-hidden – Screenreader sollen keine leeren Balken vorlesen. + */ + +/** Eine einzelne schimmernde Leiste. Breite/Höhe als px oder CSS-Wert ("60%"). */ +export function Skeleton({ w, h = 14, radius, className = "", style }) { + return ( +