ui(editor): one control height and one blue across the toolbar strip

Every control in the unified strip is now 28px tall: tb-btn (was 30),
Libraries (was 26), the C++/MicroPython select (was ~22), the board
selector, Serial/Scope, canvas icon buttons, zoom and Add (all were 32).
The explorer toggle moves inside the Code/Both/Circuit segmented group
as its first segment, and every active-segment blue is the Libraries
blue (var(--color-action-primary)) instead of the hardcoded #0e639c.

The editor zone's overlap floor becomes min-width: max-content — the
hardcoded 280px sat below the real content width, letting the console
button paint over the board selector when the docked chat narrowed the
bar. Now the zone can never shrink under its buttons; flex-wrap moves
the canvas controls to a second line instead. Also closes the gap
between the logo and the File menu (header gap 16->6, menubar
margin-left 14->2).
This commit is contained in:
David Montero Crespo 2026-07-31 00:46:08 +02:00
parent 697a9de4f4
commit e9053f73fe
6 changed files with 61 additions and 42 deletions

View File

@ -194,17 +194,15 @@ body {
}
}
.unified-toolbar-explorer-toggle {
border-bottom: none;
}
.unified-toolbar-editor {
flex: 1 1 auto;
/* 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;
/* Floor the editor zone at its own content width so it can never shrink
*under* its buttons and paint them over the adjacent canvas controls
(a hardcoded 280px floor sat below the real content width, letting the
console button overlap the board selector with the chat docked). When
the row genuinely cannot fit, the bar's flex-wrap moves the canvas
controls to a second line instead never an overlap. */
min-width: max-content;
display: flex;
}
@ -518,6 +516,12 @@ body {
align-items: center;
}
/* Logo and the File menu read as one menubar the marketing-header 16px
gap left a hole between them in the editor. */
.app-header--with-toolbar .header-left {
gap: 6px;
}
.app-header--with-toolbar .header-content {
align-items: stretch;
}

View File

@ -6,7 +6,7 @@
display: flex;
align-items: center;
gap: 2px;
margin-left: 14px;
margin-left: 2px;
}
.emb-root {

View File

@ -58,8 +58,10 @@
/* ── Icon buttons ───────────────────────────────── */
.tb-btn {
width: 30px;
height: 30px;
/* 28px the one control height across the whole editor strip (view-mode
segments, Libraries, language select, canvas controls all match). */
width: 28px;
height: 28px;
display: flex;
align-items: center;
justify-content: center;
@ -121,7 +123,7 @@
display: flex;
align-items: center;
gap: 4px;
height: 26px;
height: 28px;
padding: 0 8px 0 7px;
border: none;
border-radius: 5px;

View File

@ -1445,8 +1445,10 @@ export const EditorToolbar = ({
color: '#ccc',
border: '1px solid #444',
borderRadius: 4,
padding: '2px 4px',
fontSize: 11,
height: 28,
alignSelf: 'center',
padding: '0 6px',
fontSize: 12,
cursor: 'pointer',
outline: 'none',
marginRight: 4,

View File

@ -87,7 +87,7 @@
font-weight: 500;
cursor: pointer;
transition: border-color 0.15s;
height: 32px;
height: 28px;
appearance: none;
-webkit-appearance: none;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' fill='none'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23888' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
@ -111,7 +111,7 @@
align-items: center;
gap: 5px;
padding: 0 10px;
height: 32px;
height: 28px;
background: transparent;
border: 1px solid #3a4a5a;
border-radius: 5px;
@ -142,8 +142,8 @@
display: flex;
align-items: center;
justify-content: center;
width: 32px;
height: 32px;
width: 28px;
height: 28px;
background: transparent;
border: 1px solid #3a4a5a;
border-radius: 5px;
@ -182,7 +182,7 @@
align-items: center;
gap: 5px;
padding: 0 10px;
height: 32px;
height: 28px;
background: var(--color-action-primary);
color: #fff;
border: none;

View File

@ -402,26 +402,8 @@ export const EditorPage: React.FC = () => {
const unifiedToolbar = !isMobile ? (
<div className="unified-toolbar">
<button
className="explorer-toggle-btn unified-toolbar-explorer-toggle"
onClick={() => setExplorerOpen((v) => !v)}
title={explorerOpen ? t('editor.menu.hideExplorer', 'Hide file explorer') : t('editor.menu.showExplorer', 'Show file explorer')}
>
<svg
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z" />
</svg>
</button>
{/* View-mode toggle: Code / Both / Circuit. Lets users hide a
pane to give the right-docked AI chat more breathing room.
{/* View-mode toggle: explorer | Code / Both / Circuit one
segmented group so the four pane switches read as one control.
Hidden on mobile there's already a code/circuit toggle in
the mobile bottom-nav. */}
<div
@ -430,7 +412,7 @@ export const EditorPage: React.FC = () => {
className="view-mode-toggle"
style={{
display: 'flex',
// Never squeezed below its three buttons: flexbox used to crush
// Never squeezed below its buttons: flexbox used to crush
// this block to a third of its width and clip two of them.
flexShrink: 0,
gap: 1,
@ -442,6 +424,35 @@ export const EditorPage: React.FC = () => {
margin: '0 6px',
}}
>
<button
onClick={() => setExplorerOpen((v) => !v)}
aria-pressed={explorerOpen}
title={explorerOpen ? t('editor.menu.hideExplorer', 'Hide file explorer') : t('editor.menu.showExplorer', 'Show file explorer')}
style={{
background: explorerOpen ? 'var(--color-action-primary)' : 'transparent',
color: explorerOpen ? 'white' : '#aaa',
border: 'none',
height: 28,
padding: '0 10px',
display: 'flex',
alignItems: 'center',
cursor: 'pointer',
}}
>
<svg
width="13"
height="13"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z" />
</svg>
</button>
<div style={{ width: 1, background: '#3c3c3c', alignSelf: 'stretch' }} />
{(
[
{ key: 'code', label: t('editor.shell.code'), path: 'M16 18l6-6-6-6M8 6l-6 6 6 6' },
@ -454,7 +465,7 @@ export const EditorPage: React.FC = () => {
onClick={() => setViewMode(m.key)}
aria-pressed={viewMode === m.key}
style={{
background: viewMode === m.key ? '#0e639c' : 'transparent',
background: viewMode === m.key ? 'var(--color-action-primary)' : 'transparent',
color: viewMode === m.key ? 'white' : '#aaa',
border: 'none',
height: 28,