// Inhalts-Panel „Attribute" — die Attribut-Palette (Vectorworks-Stil) für die // aktuelle Auswahl. Zeigt die EFFEKTIV aufgelösten Stift-/Füll-Eigenschaften des // ersten selektierten Elements und erlaubt das direkte Bearbeiten (Farbe, // Strichstärke, Füllschraffur). // // Vordergrund/Hintergrund/Strichstärke/Schraffur tragen je einen 3-Optionen- // Quellen-Dropdown: „Nach Ebene" (die LayerCategory erzwingt den Wert), „Nach // Bauteil" (erbt vom Component-Manager, heutiges Default-Verhalten) oder // „eigener Wert" (expliziter Override, gewinnt immer). Das Eingabe-Element // (Farb-Swatch/mm-Zahlenfeld/Schraffur-Dropdown) erscheint NUR bei „eigener // Wert"; ein Wechsel auf „Nach Ebene"/„Nach Bauteil" löscht den Wert wieder // (siehe host.ts: onSetSelection{Foreground,Background,StrokeWeight,Hatch}Source). // // Daten/Handler kommen ausschließlich über usePanelHost (kein Prop-Drilling). // Es werden NUR Eigenschaften angeboten, die der Host-Kontrakt tatsächlich // setzen kann — keine Stubs/Fake-Setter (Konvention wire-dont-stub). Felder ohne // echten Setter (Linienstil) werden read-only/informativ gezeigt; Felder, die // das Modell gar nicht trägt (Deckkraft, Caps, Schlagschatten), werden bewusst // weggelassen, um die Palette ehrlich und schlank zu halten. // // DOSSIER-Tabellen-Look: KEINE wiederholten Feld-Labels pro Zeile — ein kompaktes // Label→Wert-Grid. Bezeichner englisch, UI-Text/Kommentare deutsch (CONVENTIONS.md). // Alle sichtbaren Texte über t(...). import type { ReactNode } from "react"; import { t } from "../i18n"; import { formatM, wallTypeLabel } from "../model/types"; import { PEN_WEIGHTS } from "../model/types"; import type { AttributeSource } from "../model/types"; import { usePanelHost } from "./host"; import { Dropdown } from "../ui/Dropdown"; import { ColorHexField } from "../ui/ColorHexField"; // Element-spezifische Attribut-Abschnitte (Wand/Decke/Öffnung/Treppe/Raum) — // aus ObjectInfoPanel hierher verschoben (Ribbon Phase 3: ObjectInfo trägt nur // noch Bezugspunkt + Masse). import { WallSection, CeilingSection, RoofSection, OpeningSection, StairSection, RoomSection, ExtrudedSolidSection, ColumnSection, SectionLineSection, } from "./ObjectInfoPanel"; /** UI-Zustand des 3-Optionen-Quellen-Dropdowns (nicht 1:1 das Modell-Feld: * „custom" ist abgeleitet aus „ist ein expliziter Wert gesetzt?", nicht * selbst gespeichert). */ type UiSource = "layer" | "object" | "custom"; /** Leitet den UI-Quellen-Zustand ab: ein gesetzter Wert gewinnt immer („eigener * Wert"), sonst das rohe Source-Feld (`undefined` ⇒ „Nach Bauteil", Default). */ function uiSourceOf(hasValue: boolean, raw: AttributeSource | undefined): UiSource { return hasValue ? "custom" : raw ?? "object"; } export function AttributesPanel() { const host = usePanelHost(); const sel = host.selection; const { project } = host; // Wandtyp-/Deckentyp-Wahl für das NEUE Bauteil (was gezeichnet wird) — früher // in der Werkzeug-Sidebar (ToolsPanel), seit deren Entfernung hier. Erscheint // nur bei aktivem Wand-/Decken-Werkzeug (unabhängig von einer Auswahl); Wand und // Decke teilen sich denselben Aufbau-Typ (WallType) + Host-State. const drawingComponent = host.activeTool === "wall" || host.activeTool === "ceiling"; const typeSection = drawingComponent ? ( <>