Ribbon: Text-Formatierung in eigenen Text-Tab; TopBar-Zeile auf 40px verschlankt
This commit is contained in:
+7
-21
@@ -122,14 +122,8 @@ export interface TopBarProps {
|
||||
/** Projekt aus einer Datei laden. */
|
||||
onOpenProject: () => void;
|
||||
|
||||
// ── Text-Gruppe (Stempel-/Text-Formatierung) ───────────────────────────────
|
||||
/**
|
||||
* Ziel der Text-Formatierung: `null` = nichts Text-artiges selektiert (die
|
||||
* Controls setzen nur Defaults für neuen Text). Sonst das aktuell selektierte
|
||||
* Rich-Text-Dokument (z. B. Raumstempel) samt optionalem Bereich und einem
|
||||
* Setter. Ist `range` `null`, wirken Aktionen auf das GANZE Doc.
|
||||
*/
|
||||
textTarget: TextTarget | null;
|
||||
// Die Text-/Font-Formatierung (TextGroup) liegt jetzt im „Text"-Ribbon-Tab
|
||||
// (App reicht sie via RibbonBar.tabContent), nicht mehr in dieser Leiste.
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -507,7 +501,7 @@ const TEXT_SIZES: number[] = [8, 9, 10, 11, 12, 14, 18, 24, 36, 48];
|
||||
* `textTarget` gesetzt, tragen die Zeile-2-Pillen einen Akzent-Rand und alle
|
||||
* Aktionen wirken auf `textTarget.doc` via `textTarget.apply`.
|
||||
*/
|
||||
function TextGroup({
|
||||
export function TextGroup({
|
||||
textTarget,
|
||||
}: {
|
||||
textTarget: TextTarget | null;
|
||||
@@ -1218,7 +1212,6 @@ export function TopBar({
|
||||
onImport,
|
||||
onSaveProject,
|
||||
onOpenProject,
|
||||
textTarget,
|
||||
}: TopBarProps) {
|
||||
// Dezente Scrollleiste: die Oberleiste scrollt horizontal (overflow-x). Statt
|
||||
// der prägnanten Standard-Leiste blenden wir eine eigene, sehr ruhige Leiste
|
||||
@@ -1268,19 +1261,12 @@ export function TopBar({
|
||||
|
||||
<Sep />
|
||||
|
||||
{/* Ribbon-Tab-Reiter (2D/3D/BIM/Ansichten) — sitzen in dieser Zeile, der
|
||||
Ribbon-Inhalt folgt darunter (RibbonBar). So gibt es nur ZWEI Bänder:
|
||||
diese Leiste (Chrome + Tabs) und den Inhalt. */}
|
||||
{/* Ribbon-Tab-Reiter (2D/3D/BIM/Text/Ansichten) — sitzen in dieser Zeile,
|
||||
der Ribbon-Inhalt folgt darunter (RibbonBar). So gibt es nur ZWEI
|
||||
Bänder: diese schmale Leiste (Chrome + Tabs) und den Inhalt. Die Text-/
|
||||
Font-Formatierung liegt jetzt im „Text"-Tab (nicht mehr hier). */}
|
||||
<RibbonTabs tab={ribbonTab} onTab={onRibbonTab} />
|
||||
|
||||
<Sep />
|
||||
|
||||
{/* Text-Gruppe (kontextabhängig) — Stil/Schrift/Grösse + B/I/U · L/C/R +
|
||||
Zeilenhöhe. Formatiert das aktuelle Text-Ziel (Raumstempel) live. Bleibt
|
||||
in der schmalen globalen Leiste, weil sie eine kontextuelle Formatier-
|
||||
Steuerung ist (kein Ansichts-/Ausgabe-Element). */}
|
||||
<TextGroup textTarget={textTarget} />
|
||||
|
||||
{/* Rechte Gruppe: Layout-Menü · Projektname · Datei-Burger (ganz rechts,
|
||||
GTK-Stil) — Ressourcen sitzt jetzt bei der Marke (s. o.). */}
|
||||
<div className="topbar-right">
|
||||
|
||||
@@ -35,11 +35,12 @@ export interface RibbonBarProps {
|
||||
/** Engine-Befehl starten (Ändern-Gruppe u. a.). */
|
||||
onRunCommand: (name: string) => void;
|
||||
/**
|
||||
* Reicher Inhalt des „Ansichten"-Tabs (aus der TopBar gemergte Ansichts-/Zoom-/
|
||||
* Darstellungs-Steuerung, `ViewRibbonTab`). Von App geliefert, damit dessen
|
||||
* Setter/State dort bleiben. Fehlt er, zeigt der Tab den Leer-Hinweis.
|
||||
* Reicher Custom-Inhalt je Tab (statt datengetriebener Item-Gruppen) — z. B.
|
||||
* „Ansichten" (`ViewRibbonTab`) und „Text" (`TextGroup`). Von App geliefert,
|
||||
* damit deren Setter/State dort bleiben. Ein Tab ohne Custom-Inhalt und ohne
|
||||
* Gruppen zeigt den Leer-Hinweis.
|
||||
*/
|
||||
viewsContent?: ReactNode;
|
||||
tabContent?: Partial<Record<RibbonTabId, ReactNode>>;
|
||||
}
|
||||
|
||||
/** Aktivierungs-/Highlight-Kontext, den jeder Button-Typ braucht. */
|
||||
@@ -121,6 +122,7 @@ export function RibbonTabs({
|
||||
|
||||
export function RibbonBar(props: RibbonBarProps) {
|
||||
const current = RIBBON_TABS.find((tt) => tt.id === props.tab) ?? RIBBON_TABS[0];
|
||||
const custom = props.tabContent?.[current.id];
|
||||
const ctx: ButtonCtx = {
|
||||
activeTool: props.activeTool,
|
||||
activeCommand: props.activeCommand,
|
||||
@@ -131,11 +133,11 @@ export function RibbonBar(props: RibbonBarProps) {
|
||||
|
||||
return (
|
||||
<div className="ribbon">
|
||||
{/* Inhalt des aktiven Tabs. Der „Ansichten"-Tab trägt reichen Custom-Inhalt
|
||||
(ViewRibbonTab) statt der datengetriebenen Item-Gruppen. */}
|
||||
{/* Inhalt des aktiven Tabs. Tabs mit reichem Custom-Inhalt („Ansichten",
|
||||
„Text") rendern diesen statt der datengetriebenen Item-Gruppen. */}
|
||||
<div className="ribbon-body">
|
||||
{current.id === "views" && props.viewsContent ? (
|
||||
props.viewsContent
|
||||
{custom ? (
|
||||
custom
|
||||
) : current.groups.length === 0 ? (
|
||||
<div className="ribbon-empty">{t("ribbon.empty")}</div>
|
||||
) : (
|
||||
|
||||
@@ -28,7 +28,7 @@ export interface RibbonGroup {
|
||||
}
|
||||
|
||||
/** Kennung eines Ribbon-Tabs (fest, für Tab-State + i18n). */
|
||||
export type RibbonTabId = "2d" | "3d" | "bim" | "views";
|
||||
export type RibbonTabId = "2d" | "3d" | "bim" | "text" | "views";
|
||||
|
||||
/** Ein Ribbon-Tab: Beschriftung + gruppierte Elemente. */
|
||||
export interface RibbonTab {
|
||||
@@ -97,6 +97,12 @@ export const RIBBON_TABS: RibbonTab[] = [
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
// Custom-Inhalt: die Text-/Font-Formatierung (TextGroup), via tabContent.
|
||||
id: "text",
|
||||
labelKey: "ribbon.tab.text",
|
||||
groups: [],
|
||||
},
|
||||
{
|
||||
id: "views",
|
||||
labelKey: "ribbon.tab.views",
|
||||
|
||||
Reference in New Issue
Block a user