TopBar OCS-Stil: kleine Wortmarke + Quick-Access-Icons (alle Datei-/Export-Aktionen), Zeile auf 26px, Burger-Menu raus

This commit is contained in:
2026-07-05 18:37:18 +02:00
parent 033cabe80f
commit 4e3b074f5c
2 changed files with 155 additions and 68 deletions
+55 -9
View File
@@ -157,9 +157,9 @@ body {
.topbar { .topbar {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 10px; gap: 8px;
padding: 0 14px; padding: 0 10px;
height: 40px; height: 26px;
border-bottom: 1px solid var(--line); border-bottom: 1px solid var(--line);
/* Oberleiste auf Ebene 1 (angehoben über dem App-Grund) + weicher Schatten /* Oberleiste auf Ebene 1 (angehoben über dem App-Grund) + weicher Schatten
nach unten → trennt sich klar von der Zeichenfläche (Tiefe). */ nach unten → trennt sich klar von der Zeichenfläche (Tiefe). */
@@ -555,10 +555,12 @@ body {
line-height: 1; line-height: 1;
} }
.brand-word { .brand-word {
font-weight: 800; font-weight: 700;
font-size: 15px; font-size: 12px;
letter-spacing: -0.01em; letter-spacing: -0.01em;
text-transform: lowercase;
color: var(--ink); color: var(--ink);
white-space: nowrap;
} }
.brand-dot { .brand-dot {
color: var(--accent); color: var(--accent);
@@ -5322,8 +5324,8 @@ body {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
width: 28px; width: 26px;
height: 28px; height: 22px;
padding: 0; padding: 0;
border: none; border: none;
background: transparent; background: transparent;
@@ -5367,17 +5369,61 @@ body {
border: none; border: none;
background: transparent; background: transparent;
color: var(--muted); color: var(--muted);
font-size: 11px; font-size: 10.5px;
font-weight: 600; font-weight: 600;
letter-spacing: 0.04em; letter-spacing: 0.04em;
text-transform: uppercase; text-transform: uppercase;
padding: 0 12px; padding: 0 10px;
display: flex; display: flex;
align-items: center; align-items: center;
cursor: pointer; cursor: pointer;
border-bottom: 2px solid transparent; border-bottom: 2px solid transparent;
transition: color 0.12s, border-color 0.12s; transition: color 0.12s, border-color 0.12s;
} }
/* Quick-Access-Leiste (OCS-Stil) — kleine Icon-Knöpfe in der TopBar-Zeile. */
.tb-qa {
display: inline-flex;
align-items: center;
gap: 1px;
flex: 0 0 auto;
}
.tb-qa-btn {
display: inline-flex;
align-items: center;
justify-content: center;
width: 22px;
height: 22px;
padding: 0;
border: none;
background: transparent;
border-radius: 4px;
color: var(--muted);
cursor: pointer;
transition: background 0.12s, color 0.12s;
}
.tb-qa-btn:hover:not(:disabled) {
background: var(--panel-2);
color: var(--label);
}
.tb-qa-btn.active {
background: var(--accent-dim);
color: var(--accent);
}
.tb-qa-btn:disabled {
opacity: 0.35;
cursor: not-allowed;
}
.tb-qa-btn .tb-ico {
font-size: 16px;
}
.tb-qa-sep {
width: 1px;
height: 15px;
background: var(--line);
margin: 0 3px;
flex: 0 0 auto;
}
.ribbon-tab:hover { .ribbon-tab:hover {
color: var(--label); color: var(--label);
} }
+97 -56
View File
@@ -865,45 +865,100 @@ function touchedParagraphs(doc: RichTextDoc, range: TextRange | null): number[]
* Icon-Pillen im Zoom-Bereich, jetzt gebündelt hinter einem Menü, damit die * Icon-Pillen im Zoom-Bereich, jetzt gebündelt hinter einem Menü, damit die
* Leiste ruhiger bleibt (GTK-Burger-Stil). * Leiste ruhiger bleibt (GTK-Burger-Stil).
*/ */
function AppMenu({ /** Ein kleiner Icon-Knopf der Quick-Access-Leiste (OCS-Stil). */
function QaButton({
icon,
label,
onClick,
disabled,
active,
}: {
icon: string;
label: string;
onClick: () => void;
disabled?: boolean;
active?: boolean;
}) {
return (
<button
type="button"
className={`tb-qa-btn${active ? " active" : ""}`}
onClick={onClick}
disabled={disabled}
aria-pressed={active}
aria-label={label}
title={label}
>
<TbIcon name={icon} />
</button>
);
}
/** Kleiner Trenner in der Quick-Access-Leiste. */
function QaSep() {
return <span className="tb-qa-sep" aria-hidden="true" />;
}
/**
* Quick-Access-Leiste (OCS-Stil) — alle früheren Datei-Burger-Aktionen plus
* Ressourcen/Einstellungen als kleine Icon-Knöpfe direkt in der TopBar-Zeile.
* Ersetzt das Burger-Menü (`AppMenu`). Rein gesteuert über Callbacks (i18n via t).
*/
function QuickAccess({
onOpenProject,
onSaveProject,
onImport, onImport,
onExportPdf, onExportPdf,
onExportDxf, onExportDxf,
onExportSchedule, onExportSchedule,
onSaveProject, onToggleResources,
onOpenProject,
onOpenSettings, onOpenSettings,
resourcesOpen,
exportEnabled, exportEnabled,
}: { }: {
onOpenProject: () => void;
onSaveProject: () => void;
onImport: () => void; onImport: () => void;
onExportPdf: () => void; onExportPdf: () => void;
onExportDxf: () => void; onExportDxf: () => void;
onExportSchedule: () => void; onExportSchedule: () => void;
onSaveProject: () => void; onToggleResources: () => void;
onOpenProject: () => void;
onOpenSettings: () => void; onOpenSettings: () => void;
resourcesOpen: boolean;
exportEnabled: boolean; exportEnabled: boolean;
}) { }) {
const items: DropdownItem[] = [
{ label: t("file.save"), onSelect: onSaveProject },
{ label: t("file.open"), onSelect: onOpenProject },
{ divider: true },
{ label: t("file.import"), onSelect: onImport },
{ divider: true },
{ label: t("file.exportPdf"), onSelect: onExportPdf, disabled: !exportEnabled },
{ label: t("file.exportDxf"), onSelect: onExportDxf, disabled: !exportEnabled },
{ label: t("file.exportSchedule"), onSelect: onExportSchedule },
{ divider: true },
{ label: t("topbar.settings"), onSelect: onOpenSettings },
];
return ( return (
<Dropdown <div className="tb-qa" role="toolbar" aria-label={t("file.menu")}>
items={items} <QaButton icon="folder_open" label={t("file.open")} onClick={onOpenProject} />
placeholder="" <QaButton icon="save" label={t("file.save")} onClick={onSaveProject} />
title={t("file.menu")} <QaSep />
triggerClassName="tb-burger" <QaButton icon="download" label={t("file.import")} onClick={onImport} />
triggerSuffix={<TbIcon name="menu" />} <QaButton
icon="picture_as_pdf"
label={t("file.exportPdf")}
onClick={onExportPdf}
disabled={!exportEnabled}
/> />
<QaButton
icon="output"
label={t("file.exportDxf")}
onClick={onExportDxf}
disabled={!exportEnabled}
/>
<QaButton
icon="table_view"
label={t("file.exportSchedule")}
onClick={onExportSchedule}
/>
<QaSep />
<QaButton
icon="widgets"
label={t("topbar.resources")}
onClick={onToggleResources}
active={resourcesOpen}
/>
<QaButton icon="settings" label={t("topbar.settings")} onClick={onOpenSettings} />
</div>
); );
} }
@@ -1235,53 +1290,39 @@ export function TopBar({
return ( return (
<header className="topbar" ref={headerRef}> <header className="topbar" ref={headerRef}>
{/* Marke (DOSSIER-Wortmarke) + Settings/Ressourcen-Icons daneben, {/* Kleine Wortmarke „dossier" (OCS-Stil, klein/kleingeschrieben) + Quick-
gestapelt wie im Rhino-Plugin (ToolbarApp.jsx: Wortmarke links, Access-Leiste: alle Datei-/Export-Aktionen + Ressourcen/Einstellungen
rechts daneben ein schmaler Icon-Stapel). */} als kleine Icons direkt in der Zeile (ersetzt das Burger-Menü). */}
<div className="tb-brandgroup"> <div className="tb-brandgroup">
<div className="brand">
<span className="brand-word"> <span className="brand-word">
DOSSIER<span className="brand-dot">.</span> dossier<span className="brand-dot">.</span>
</span> </span>
<span className="tag">{t("brand.tag")}</span>
</div>
<div className="tb-brandicons">
<button
type="button"
className={`tb-brandicon${resourcesOpen ? " active" : ""}`}
onClick={onToggleResources}
aria-pressed={resourcesOpen}
aria-label={t("topbar.resources")}
title={`${t("topbar.resources")}${t("topbar.resources.hint")}`}
>
<TbIcon name="widgets" />
</button>
</div>
</div> </div>
<QuickAccess
onOpenProject={onOpenProject}
onSaveProject={onSaveProject}
onImport={onImport}
onExportPdf={onExportPdf}
onExportDxf={onExportDxf}
onExportSchedule={onExportSchedule}
onToggleResources={onToggleResources}
onOpenSettings={onOpenSettings}
resourcesOpen={resourcesOpen}
exportEnabled={zoomEnabled}
/>
<Sep /> <Sep />
{/* Ribbon-Tab-Reiter (2D/3D/BIM/Text/Ansichten) — sitzen in dieser Zeile, {/* Ribbon-Tab-Reiter (2D/3D/BIM/Text/Ansichten) — sitzen in dieser Zeile,
der Ribbon-Inhalt folgt darunter (RibbonBar). So gibt es nur ZWEI der Ribbon-Inhalt folgt darunter (RibbonBar). So gibt es nur ZWEI
Bänder: diese schmale Leiste (Chrome + Tabs) und den Inhalt. Die Text-/ Bänder: diese schmale Leiste (Chrome + Tabs) und den Inhalt. */}
Font-Formatierung liegt jetzt im „Text"-Tab (nicht mehr hier). */}
<RibbonTabs tab={ribbonTab} onTab={onRibbonTab} /> <RibbonTabs tab={ribbonTab} onTab={onRibbonTab} />
{/* Rechte Gruppe: Layout-Menü · Projektname · Datei-Burger (ganz rechts, {/* Rechte Gruppe: Layout-Menü · Projektname · Fensterknöpfe. Datei-/Export-
GTK-Stil) — Ressourcen sitzt jetzt bei der Marke (s. o.). */} Aktionen liegen jetzt in der Quick-Access-Leiste links (kein Burger). */}
<div className="topbar-right"> <div className="topbar-right">
{layoutMenu} {layoutMenu}
<span className="project-name">{project.name}</span> <span className="project-name">{project.name}</span>
<AppMenu
onImport={onImport}
onExportPdf={onExportPdf}
onExportDxf={onExportDxf}
onExportSchedule={onExportSchedule}
onSaveProject={onSaveProject}
onOpenProject={onOpenProject}
onOpenSettings={onOpenSettings}
exportEnabled={zoomEnabled}
/>
<WindowControls /> <WindowControls />
</div> </div>
</header> </header>