fix(editor): stop unified toolbar controls overlapping on a narrow bar

The top bar packs three zones onto one row: the view-mode toggle, the editor
actions (Compile/Run/Stop/...), and the canvas controls (board selector,
Serial, Scope, zoom, Add) portaled in from SimulatorCanvas. The editor zone
was flex:1 min-width:0 while the canvas zone was fixed-width, so when the bar
narrowed - mainly when the right-docked AI chat opens - the editor zone shrank
below its own buttons and painted them over the board selector / Serial /
Scope. The existing collapse logic was keyed to the viewport (@media 768px),
so it never fired on a wide screen with the chat open.

Make the shared bar a container-query context and collapse every zone by the
bar's own width instead of the viewport: view-mode labels drop to icons first,
then Serial/Scope/Add labels and the board selector ellipsizes, then the
component count and finally the zoom buttons (wheel-zoom still works). Floor
the editor zone at its collapsed content width so it can never underflow and
overlap; past that the lower-priority canvas controls yield toward the right
edge instead. Verified across bar widths 660-1140px with the AI chat open:
overlap eliminated, dropdown menus still render un-clipped.
This commit is contained in:
David Montero 2026-07-03 07:32:14 +02:00
parent 7f65cd65bf
commit 3934cbc0f8
3 changed files with 70 additions and 2 deletions

View File

@ -169,6 +169,23 @@ body {
background: #252526; background: #252526;
border-bottom: 1px solid #333; border-bottom: 1px solid #333;
min-height: 38px; min-height: 38px;
/* Query container so every zone (view-mode toggle, editor toolbar, canvas
controls) can collapse based on the *shared bar's own width* which is
what shrinks when the right-docked AI chat opens instead of the viewport
width. Prevents the canvas controls (board selector, Serial, Scope) from
overlapping the editor Run/Compile buttons on a narrow bar. `layout`
containment (implied) does not clip: the overflow/run dropdowns still
render below the bar. */
container-type: inline-size;
container-name: unified-toolbar;
}
/* Collapse the Code/Both/Circuit labels to icon-only first (biggest fixed
block in the bar) as the shared bar narrows. */
@container unified-toolbar (max-width: 1140px) {
.view-mode-toggle .vm-label {
display: none;
}
} }
.unified-toolbar-explorer-toggle { .unified-toolbar-explorer-toggle {
@ -177,7 +194,11 @@ body {
.unified-toolbar-editor { .unified-toolbar-editor {
flex: 1 1 auto; flex: 1 1 auto;
min-width: 0; /* Floor the editor zone at its fully-collapsed content width so it can never
shrink *under* its own buttons and paint them over the adjacent canvas
controls. Below this floor the (lower-priority) canvas controls get pushed
toward the right edge instead of overlapping never the other way. */
min-width: 280px;
display: flex; display: flex;
} }

View File

@ -398,6 +398,53 @@
} }
} }
/* Narrow shared toolbar (desktop, AI chat open)
When the canvas header is portaled into the unified top toolbar, it shares
one row with the editor actions. As that *bar* narrows (mainly when the
right-docked AI chat opens), collapse the canvas controls the same way the
mobile block does but keyed to the bar's own width via a container query,
not the viewport, so it triggers on a wide screen with the chat open too.
Priority: labels -> icons, then drop the non-interactive count, then the
zoom buttons (mouse-wheel zoom still works). Mirrors the thresholds the
editor toolbar and view-mode toggle collapse at, so the whole bar degrades
together and nothing overlaps. */
@container unified-toolbar (max-width: 1010px) {
.canvas-serial-btn {
padding: 0 8px;
font-size: 0; /* hide "Serial" / "Scope" text, keep the icon */
}
.canvas-serial-btn svg {
width: 18px;
height: 18px;
}
.add-component-btn {
padding: 0 9px;
font-size: 0; /* hide "Add" text, keep the icon */
}
.add-component-btn svg {
width: 18px;
height: 18px;
}
.board-selector {
max-width: 120px;
text-overflow: ellipsis;
overflow: hidden;
}
}
@container unified-toolbar (max-width: 905px) {
.component-count {
display: none;
}
.board-selector {
max-width: 96px;
}
}
@container unified-toolbar (max-width: 835px) {
.zoom-controls {
display: none; /* mouse-wheel / trackpad zoom still available */
}
}
/* ── WiFi / BLE status badges ─────────────────────────────────────────── */ /* ── WiFi / BLE status badges ─────────────────────────────────────────── */
.canvas-wifi-badge, .canvas-wifi-badge,
.canvas-ble-badge { .canvas-ble-badge {

View File

@ -480,7 +480,7 @@ export const EditorPage: React.FC = () => {
> >
<path d={m.path} /> <path d={m.path} />
</svg> </svg>
<span>{m.label}</span> <span className="vm-label">{m.label}</span>
</button> </button>
))} ))}
</div> </div>