Kontextmenü-/Editor-State aus App.tsx in useContextMenuState() extrahiert

Bündelt layerClipboard, menu, editor, nativeLayerSettingsCode,
stampEditorRoomId und editTextId in einem eigenen Hook (Teil der
laufenden App.tsx-Verkleinerung).
This commit is contained in:
2026-07-21 19:31:19 +02:00
parent 85f386a496
commit 476f31ccad
3 changed files with 66 additions and 23 deletions
+15 -23
View File
@@ -154,7 +154,7 @@ import type {
} from "./tools/types"; } from "./tools/types";
import { ContextMenu } from "./ui/ContextMenu"; import { ContextMenu } from "./ui/ContextMenu";
import { buildMenuItems, menuTitle } from "./menus/contextMenu"; import { buildMenuItems, menuTitle } from "./menus/contextMenu";
import type { MenuState } from "./menus/contextMenu"; import { useContextMenuState } from "./menus/useContextMenuState";
import { InlineEditor } from "./views/InlineEditor"; import { InlineEditor } from "./views/InlineEditor";
import { Content } from "./views/viewportContent"; import { Content } from "./views/viewportContent";
import { useDialogState } from "./state/useDialogState"; import { useDialogState } from "./state/useDialogState";
@@ -237,12 +237,6 @@ import { deriveDrawings } from "./DrawingTabs";
* • "plan" — Rechtsklick im Grundriss (optional getroffene Wand). * • "plan" — Rechtsklick im Grundriss (optional getroffene Wand).
* • "viewport" — Rechtsklick im 3D (optional getroffene Wand). * • "viewport" — Rechtsklick im 3D (optional getroffene Wand).
*/ */
/** Offener Inline-Editor (aus einem Menüpunkt). `x/y` = Anker in Viewport-Px. */
type EditorState =
| { kind: "layer"; code: string; x: number; y: number }
| { kind: "level"; id: string; x: number; y: number }
| null;
/** /**
* GUI-Werkzeug → Befehlsname der Engine. Die Zeichen-Werkzeuge der Palette sind * GUI-Werkzeug → Befehlsname der Engine. Die Zeichen-Werkzeuge der Palette sind
* in Wahrheit Engine-Befehle: ein Klick auf das Werkzeug startet diesen Befehl * in Wahrheit Engine-Befehle: ein Klick auf das Werkzeug startet diesen Befehl
@@ -549,22 +543,20 @@ export default function App() {
const setSelectedContextObjectIds = useStore((s) => s.setSelectedContextObjectIds); const setSelectedContextObjectIds = useStore((s) => s.setSelectedContextObjectIds);
// ── Kontextmenüs (transienter UI-State, bleibt lokal) ───────────────────── // ── Kontextmenüs (transienter UI-State, bleibt lokal) ─────────────────────
// Eigenschaften-Zwischenablage des Ebenen-Kontextmenüs (Farbe + Linienstärke). const {
const [layerClipboard, setLayerClipboard] = useState<{ layerClipboard,
color: string; setLayerClipboard,
lw: number; menu,
} | null>(null); setMenu,
// Offenes Kontextmenü (genau eines) — Quelle bestimmt die Einträge. editor,
const [menu, setMenu] = useState<MenuState>(null); setEditor,
// Offener Inline-Editor (Ebene bzw. Geschoss) — aus einem Menüpunkt geöffnet. nativeLayerSettingsCode,
const [editor, setEditor] = useState<EditorState>(null); setNativeLayerSettingsCode,
// Welcher Ebenen-Code aktuell im nativen Ebeneneinstellungs-Fenster offen stampEditorRoomId,
// ist (Tauri) — Pendant zu `editor?.kind === "layer"` im Browser-Fallback. setStampEditorRoomId,
const [nativeLayerSettingsCode, setNativeLayerSettingsCode] = useState<string | null>(null); editTextId,
// Offener Raum-Stempel-Editor (Rich-Text) — per Doppelklick/Button geöffnet. setEditTextId,
const [stampEditorRoomId, setStampEditorRoomId] = useState<string | null>(null); } = useContextMenuState();
// Text-Inhalt-Editor: Id des per Doppelklick bearbeiteten Text-2D-Elements.
const [editTextId, setEditTextId] = useState<string | null>(null);
// Beim Geschosswechsel die Wand-Auswahl + offene Overlays zurücksetzen (die // Beim Geschosswechsel die Wand-Auswahl + offene Overlays zurücksetzen (die
// Wände eines anderen Geschosses sind eine andere Menge). Der Ansichtswechsel // Wände eines anderen Geschosses sind eine andere Menge). Der Ansichtswechsel
+6
View File
@@ -22,6 +22,12 @@ export type MenuState =
| { kind: "viewport"; wallId: string | null; x: number; y: number } | { kind: "viewport"; wallId: string | null; x: number; y: number }
| null; | null;
/** Offener Inline-Editor (aus einem Menüpunkt). `x/y` = Anker in Viewport-Px. */
export type EditorState =
| { kind: "layer"; code: string; x: number; y: number }
| { kind: "level"; id: string; x: number; y: number }
| null;
/** Titel des Kontextmenüs je Quelle (Ebenenname / Geschossname / Wand/Ansicht). */ /** Titel des Kontextmenüs je Quelle (Ebenenname / Geschossname / Wand/Ansicht). */
export function menuTitle(menu: NonNullable<MenuState>, project: Project): string { export function menuTitle(menu: NonNullable<MenuState>, project: Project): string {
switch (menu.kind) { switch (menu.kind) {
+45
View File
@@ -0,0 +1,45 @@
// Transienter UI-State der Kontextmenüs/Inline-Editoren — bleibt lokal (kein
// Store-Slice: keine Undo/Redo-Relevanz). Bündelt nur die useState-
// Deklarationen; die Reset-Effekte (Geschoss-/Ansichtswechsel) bleiben in
// App(), da sie zusammen mit globalem Auswahl-State aus dem Store laufen.
//
// Extrahiert aus App.tsx. Bezeichner englisch, Kommentare deutsch (CONVENTIONS.md).
import { useState } from "react";
import type { EditorState, MenuState } from "./contextMenu";
export function useContextMenuState() {
// Eigenschaften-Zwischenablage des Ebenen-Kontextmenüs (Farbe + Linienstärke).
const [layerClipboard, setLayerClipboard] = useState<{
color: string;
lw: number;
} | null>(null);
// Offenes Kontextmenü (genau eines) — Quelle bestimmt die Einträge.
const [menu, setMenu] = useState<MenuState>(null);
// Offener Inline-Editor (Ebene bzw. Geschoss) — aus einem Menüpunkt geöffnet.
const [editor, setEditor] = useState<EditorState>(null);
// Welcher Ebenen-Code aktuell im nativen Ebeneneinstellungs-Fenster offen
// ist (Tauri) — Pendant zu `editor?.kind === "layer"` im Browser-Fallback.
const [nativeLayerSettingsCode, setNativeLayerSettingsCode] = useState<string | null>(
null,
);
// Offener Raum-Stempel-Editor (Rich-Text) — per Doppelklick/Button geöffnet.
const [stampEditorRoomId, setStampEditorRoomId] = useState<string | null>(null);
// Text-Inhalt-Editor: Id des per Doppelklick bearbeiteten Text-2D-Elements.
const [editTextId, setEditTextId] = useState<string | null>(null);
return {
layerClipboard,
setLayerClipboard,
menu,
setMenu,
editor,
setEditor,
nativeLayerSettingsCode,
setNativeLayerSettingsCode,
stampEditorRoomId,
setStampEditorRoomId,
editTextId,
setEditTextId,
};
}