fix(canvas): collapse the Camera/Mic buttons to icon-only when the toolbar is cramped
With the AI chat docked, the canvas header ran out of room and the Camera and Microphone buttons overlapped the icons before them (visible as "…Camera" colliding on a XIAO-S3-Sense board). Serial and Scope already collapse to icon-only via the `@container unified-toolbar` query (font-size: 0 hides the label, the fixed-size SVG stays), but Camera/Mic carried their layout in INLINE styles, and an inline font-size beats the class rule so the query could never reach them. Move the two toggles' static layout into a shared `.canvas-cam-mic-btn` class (only state-driven styles — background, border, colour, the pulse animation — stay inline) and add that class to the same collapse rules as Serial, in both the container query and the mobile media query. Also drop the header button gap from 8px to 4px once the toolbar is narrow so all four (Serial/Camera/Mic/Scope) pack in without overlapping. Side effect: the toggles now share Serial's 28px height, so the toolbar row lines up (they were a touch shorter before).
This commit is contained in:
parent
b8c2b56df2
commit
fb8086c205
|
|
@ -111,11 +111,14 @@ export const CameraToggle: React.FC<CameraToggleProps> = ({ boardId, maxFrameByt
|
|||
// starving without frames. Never while the sim is stopped — the
|
||||
// button is not asking for anything then. Solid border once
|
||||
// streaming or asking.
|
||||
className={
|
||||
// Static layout is in .canvas-cam-mic-btn so the toolbar @container
|
||||
// query can collapse the label to icon-only (an inline font-size would
|
||||
// beat it). Only state-driven styles stay inline below.
|
||||
className={`canvas-cam-mic-btn${
|
||||
running && boardId && status !== 'streaming' && status !== 'requesting'
|
||||
? 'velxio-btn-ants'
|
||||
: undefined
|
||||
}
|
||||
? ' velxio-btn-ants'
|
||||
: ''
|
||||
}`}
|
||||
style={{
|
||||
// backgroundColor, NOT the background shorthand: inline shorthand
|
||||
// would wipe the class's background-image and kill the ants.
|
||||
|
|
@ -123,13 +126,7 @@ export const CameraToggle: React.FC<CameraToggleProps> = ({ boardId, maxFrameByt
|
|||
border: `1px solid ${
|
||||
isOn ? '#3fb950' : status === 'requesting' ? '#555' : 'transparent'
|
||||
}`,
|
||||
borderRadius: 4,
|
||||
padding: '4px 10px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 6,
|
||||
color,
|
||||
fontSize: 13,
|
||||
cursor: boardId ? 'pointer' : 'not-allowed',
|
||||
// Inline only while requesting. 'none' here would OVERRIDE the
|
||||
// .velxio-btn-ants class animation (inline beats class), which is
|
||||
|
|
|
|||
|
|
@ -62,18 +62,16 @@ export const MicrophoneToggle: React.FC<MicrophoneToggleProps> = ({ boardId }) =
|
|||
onClick={handleClick}
|
||||
disabled={!boardId || status === 'requesting'}
|
||||
title={tooltip}
|
||||
// Static layout is in .canvas-cam-mic-btn so the toolbar @container
|
||||
// query can collapse the label to icon-only (an inline font-size would
|
||||
// beat it). Only state-driven styles stay inline.
|
||||
className="canvas-cam-mic-btn"
|
||||
style={{
|
||||
backgroundColor: isOn ? 'rgba(63,185,80,0.15)' : 'transparent',
|
||||
border: `1px solid ${
|
||||
isOn ? '#3fb950' : status === 'requesting' ? '#555' : 'transparent'
|
||||
}`,
|
||||
borderRadius: 4,
|
||||
padding: '4px 10px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 6,
|
||||
color,
|
||||
fontSize: 13,
|
||||
cursor: boardId ? 'pointer' : 'not-allowed',
|
||||
animation:
|
||||
status === 'requesting' ? 'velxio-pulse 1s ease-in-out infinite' : undefined,
|
||||
|
|
|
|||
|
|
@ -105,6 +105,24 @@
|
|||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* ── Camera / Microphone toggles ─────────────────────
|
||||
Static layout for the CameraToggle / MicrophoneToggle buttons. It lives
|
||||
in a class (not inline) so the same @container query that collapses the
|
||||
Serial/Scope buttons to icon-only can reach these too — an inline
|
||||
font-size would beat the class and the label could never collapse.
|
||||
State-driven styles (background, border, colour, pulse animation) stay
|
||||
inline on the button. */
|
||||
.canvas-cam-mic-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 0 10px;
|
||||
height: 28px;
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* ── Serial Monitor button ───────────────────────── */
|
||||
.canvas-serial-btn {
|
||||
display: flex;
|
||||
|
|
@ -383,6 +401,12 @@
|
|||
height: 18px;
|
||||
}
|
||||
|
||||
.canvas-cam-mic-btn {
|
||||
padding: 0 6px;
|
||||
gap: 0;
|
||||
font-size: 0; /* icon-only on narrow viewports too */
|
||||
}
|
||||
|
||||
.add-component-btn {
|
||||
padding: 0 8px;
|
||||
font-size: 0; /* hide text, show icon only */
|
||||
|
|
@ -426,6 +450,12 @@
|
|||
editor toolbar and view-mode toggle collapse at, so the whole bar degrades
|
||||
together and nothing overlaps. */
|
||||
@container unified-toolbar (max-width: 1010px) {
|
||||
/* Pack the toolbar buttons tighter once the AI chat steals horizontal
|
||||
room, so Serial/Camera/Mic/Scope stop overlapping. */
|
||||
.canvas-header-left,
|
||||
.canvas-header-right {
|
||||
gap: 4px;
|
||||
}
|
||||
.canvas-serial-btn {
|
||||
padding: 0 8px;
|
||||
font-size: 0; /* hide "Serial" / "Scope" text, keep the icon */
|
||||
|
|
@ -434,6 +464,13 @@
|
|||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
/* Same collapse as Serial: hide the "Camera" / "Mic" label, keep the icon.
|
||||
gap: 0 drops the now-empty icon-to-label space. */
|
||||
.canvas-cam-mic-btn {
|
||||
padding: 0 8px;
|
||||
gap: 0;
|
||||
font-size: 0;
|
||||
}
|
||||
.add-component-btn {
|
||||
padding: 0 9px;
|
||||
font-size: 0; /* hide "Add" text, keep the icon */
|
||||
|
|
|
|||
Loading…
Reference in New Issue