"use client"; import React from "react"; import { FeatherDownload, FeatherEyeOff, FeatherInfo, FeatherMoreHorizontal, } from "@subframe/core"; import { useWidgets } from "../../context/WidgetContext"; import { useToast } from "../../context/ToastContext"; /** * Rahmen für jede Visualisierung (COMP-09). * * Enthält die einzige "echte" Interaktionslogik des Prototyps: * Über das ⋯-Menü lässt sich die Karte ausblenden; sie taucht dann in der * Filterleiste zum Wiedereinblenden auf. Der Zustand ist persistiert. */ export function ChartCard({ id, titel, untertitel, hinweis, aktion, legende, children, className = "", }: { /** Stabile ID — Schlüssel für Ausblenden/Einblenden. */ id: string; titel: string; untertitel?: string; /** Erklärt die Kennzahl; erscheint als Tooltip am (i). */ hinweis?: string; aktion?: React.ReactNode; legende?: React.ReactNode; children: React.ReactNode; className?: string; }) { const { istSichtbar, verstecke } = useWidgets(); const { zeigeToast } = useToast(); const [menuOffen, setMenuOffen] = React.useState(false); const menu = React.useRef(null); const ausloeser = React.useRef(null); React.useEffect(() => { if (!menuOffen) return; const schliesse = (event: MouseEvent) => { if (!menu.current?.contains(event.target as Node)) setMenuOffen(false); }; // Escape schliesst und gibt den Fokus an den Ausloeser zurueck — sonst // landet die Tastaturbedienung nach dem Schliessen am Seitenanfang. const taste = (event: KeyboardEvent) => { if (event.key === "Escape") { setMenuOffen(false); ausloeser.current?.focus(); } }; document.addEventListener("mousedown", schliesse); document.addEventListener("keydown", taste); return () => { document.removeEventListener("mousedown", schliesse); document.removeEventListener("keydown", taste); }; }, [menuOffen]); if (!istSichtbar(id)) return null; return (

{titel}

{hinweis ? ( ) : null}
{untertitel ? (

{untertitel}

) : null}
{aktion} {menuOffen ? (
) : null}
{legende ?
{legende}
: null} {/* justify-center: Karten einer Zeile sind gleich hoch, aber nicht gleich voll. Eine Karte mit einem Balken neben einer mit einem Diagramm über 400 px bekommt den Überschuss oben und unten je zur Hälfte, statt ihn unten abzuladen. Der Inhalt behält seine natürliche Höhe — die Karte wächst weiter mit, wenn mehr hineinkommt. */}
{children}
); }