import React from "react"; /** * Inhaltsspalte einer Seite. * 24 px Außenabstand, 16 px Rasterabstand: entspricht dem 8-px-System * aus den UI-Guidelines (internal ≤ external). * * Unter `sm` sind 24 px Rand ein Achtel der Fensterbreite: Der Rand kostet * dort mehr Platz, als er Ruhe bringt. Deshalb 16 px, der nächste Wert der * Skala, nicht ein neuer. */ export function PageContainer({ children }: { children: React.ReactNode }) { return
{children}
; } /** Standard-Raster für eine Kartenreihe. */ export function Raster({ spalten, /** * Karten oben ausrichten statt auf gleiche Hoehe strecken. * Gleiche Hoehe ist richtig, wenn alle Karten dieselbe Struktur haben * (KPI-Reihe). Sobald ein Chart mit fester Hoehe neben einer Tabelle steht, * erzeugt Strecken nur Weissraum. */ obenBuendig = false, children, }: { /** Spaltenzahl auf großen Bildschirmen. */ spalten: 2 | 3 | 4 | 5; obenBuendig?: boolean; children: React.ReactNode; }) { /** * Jede Leiter beginnt einspaltig. Zwei Spalten sind bei 375 px rund 155 px * je Karte: darin bricht ein Währungswert zwischen Betrag und Euro-Zeichen * um, und die Karte wird höher statt schmaler. * * Wann die erste Verdopplung kommt, hängt am Inhalt, nicht an der Zielzahl: * Die Leitern 4 und 5 tragen KPI-Karten (kurzer Wert, feste Höhe) und * verdoppeln bei `sm`, wo die Seitenleiste noch ausgefahren ist und die * volle Fensterbreite zur Verfügung steht. Die Leitern 2 und 3 tragen * Diagramme und Tabellen, die halbiert erst ab `md` lesbar bleiben. * * Keine Leiter erhöht bei `md`: Dort kommt die Seitenleiste zurück und * nimmt 240 px weg, die Karten würden schmaler statt breiter. * * Ab 1024 px ist jede Leiter identisch zum abgenommenen Stand. */ const klassen: Record = { 2: "grid grid-cols-1 gap-4 md:grid-cols-2", 3: "grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-3", 4: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4", 5: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5", }; return (
{children}
); } /** * Eine Zeile aus Diagrammkarten. * * Bewusst Flexbox und kein Raster. Karten lassen sich ueber das Menü * ausblenden; `ChartCard` gibt dann `null` zurueck. In einem Raster mit festen * Spalten bleibt an dieser Stelle eine Luecke stehen, und die Nachbarkarte * behaelt ihre zwei Drittel. Im Flexbereich verteilen die verbliebenen Karten * den Platz unter sich neu, ohne dass jemand mitzaehlen muesste, wie viele * gerade sichtbar sind. * * `[&>*]:flex-1` gibt jeder Karte denselben Anteil und ist zugleich das * Sicherheitsnetz: Ohne eigene Breitenangabe schrumpfte ein Flexkind auf seine * Inhaltsbreite, und ein Diagramm mit `ResponsiveContainer` faellt dann in sich * zusammen. * * Eine breitere Karte bekommt `xl:flex-[2]!` mit. Das Ausrufezeichen ist noetig * und kein Reflex: `[&>*]:flex-1` erzeugt den Selektor `.zeile > *`, und der * ist spezifischer als eine Klasse am Kind. Ohne `!` gewinnt die Zeilenregel, * und aus zwei Dritteln zu einem Drittel wird die Haelfte zur Haelfte. Genau * das ist beim Umbau hier passiert und wurde durch Nachmessen gefunden. * * `min-w-0` ist Pflicht: Ohne das nimmt ein Flexkind seine Inhaltsbreite als * Untergrenze, und ein Diagramm mit langer Achsenbeschriftung drueckt die * Zeile ueber den Rand. */ export function ChartReihe({ /** Ab welcher Breite die Karten nebeneinander stehen. */ umbruch = "xl", /** * Gleiche Hoehe fuer alle Karten der Zeile. Nur richtig, wenn sie dieselbe * Bauart haben (zwei Listen, zwei Diagramme). Sonst oben buendig, * siehe docs/DESIGN-SYSTEM.md, Abschnitt "Kartenhoehen in einer Zeile". */ gleichHoch = false, children, }: { umbruch?: "lg" | "xl"; gleichHoch?: boolean; children: React.ReactNode; }) { const klassen = umbruch === "lg" ? `flex flex-col gap-4 lg:flex-row ${gleichHoch ? "lg:items-stretch" : "lg:items-start"} [&>*]:min-w-0 lg:[&>*]:flex-1` : `flex flex-col gap-4 xl:flex-row ${gleichHoch ? "xl:items-stretch" : "xl:items-start"} [&>*]:min-w-0 xl:[&>*]:flex-1`; return
{children}
; }