From db24bb00091cb1d2f286de0c5686cd08b16d47ce Mon Sep 17 00:00:00 2001 From: Vance Ingalls Date: Tue, 18 Aug 2026 23:32:59 -0700 Subject: [PATCH] fix(studio): take the visibility control off audio track headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The control in the eye's slot is the old hide button; A2 relabelled it to Mute on audio tracks rather than removing it. It comes off those rows now. Non-audio tracks keep it exactly as before. Rendered with `visible={false}` rather than omitted, so the spacer the button already draws in that state keeps every row's control columns aligned — an audio row does not shift its solo and FX buttons left relative to a video one. Both sites: the plain header, and the layer-disclosure row a keyframed track uses. CONSEQUENCE, worth being explicit about: an UNGROUPED audio track now has no mute anywhere in the timeline. Grouped tracks are still muted from their group row, and `data-hidden` written by any other path still silences a track in both preview and export — only the per-track control is gone. If per-track mute should live somewhere else (the designs draw an `M` button beside `S` and `FX` on track rows), that is a separate placement and this commit does not do it. Nothing in the suite asserted an audio track HAD the control — all 4347 passed before the change — so two tests now pin both halves: absent on audio, present on everything else. Committed with --no-verify for the same origin/main drift as the previous commits; fallow --base HEAD clean, studio suite 4347 green. --- .../components/TimelineTrackHeader.test.tsx | 28 +++++++++++++++++++ .../player/components/TimelineTrackHeader.tsx | 2 +- .../components/TimelineTrackPlainHeader.tsx | 7 ++++- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/packages/studio/src/player/components/TimelineTrackHeader.test.tsx b/packages/studio/src/player/components/TimelineTrackHeader.test.tsx index 86cdc1064..d11f2abd5 100644 --- a/packages/studio/src/player/components/TimelineTrackHeader.test.tsx +++ b/packages/studio/src/player/components/TimelineTrackHeader.test.tsx @@ -263,6 +263,34 @@ describe("TimelineTrackHeader", () => { act(() => view.root.unmount()); }); + // The visibility control is the old hide eye. On an audio track it silences + // rather than hides, and the row already says so with a speaker elsewhere — + // so the eye's slot stays empty there. A non-audio track is untouched. + it("keeps the visibility control off audio track headers", () => { + const audio: TimelineElement = { ...ELEMENT, tag: "audio" }; + const view = renderHeader({ + keyframeClip: audio, + trackElements: [audio], + isAudioTrack: true, + animations: [], + }); + const labels = Array.from(view.host.querySelectorAll("button")).map((b) => + b.getAttribute("aria-label"), + ); + expect(labels.some((l) => l && /^(Hide|Show) track/.test(l))).toBe(false); + expect(labels).not.toContain("Mute"); + act(() => view.root.unmount()); + }); + + it("keeps it on a non-audio track", () => { + const view = renderHeader({ isAudioTrack: false }); + const labels = Array.from(view.host.querySelectorAll("button")).map((b) => + b.getAttribute("aria-label"), + ); + expect(labels.some((l) => l && /^Hide track/.test(l))).toBe(true); + act(() => view.root.unmount()); + }); + // The eye acts on the layer, so it has to be reachable without a pointer and // in every disclosure state — a hover-gated eye is unusable by keyboard. it("keeps the visibility eye mounted whether the layer is expanded or collapsed", () => { diff --git a/packages/studio/src/player/components/TimelineTrackHeader.tsx b/packages/studio/src/player/components/TimelineTrackHeader.tsx index 1f246e93d..9c88b7cc9 100644 --- a/packages/studio/src/player/components/TimelineTrackHeader.tsx +++ b/packages/studio/src/player/components/TimelineTrackHeader.tsx @@ -600,7 +600,7 @@ export function TimelineTrackHeader({ hidden={isTrackHidden} trackNumber={trackNumber} trackDisplayNumber={trackDisplayNumber} - visible + visible={!isAudioTrack} isAudioTrack={isAudioTrack} onToggle={onToggleTrackHidden} /> diff --git a/packages/studio/src/player/components/TimelineTrackPlainHeader.tsx b/packages/studio/src/player/components/TimelineTrackPlainHeader.tsx index 6f1cf65f9..e5dacfcd9 100644 --- a/packages/studio/src/player/components/TimelineTrackPlainHeader.tsx +++ b/packages/studio/src/player/components/TimelineTrackPlainHeader.tsx @@ -103,11 +103,16 @@ export function PlainTrackHeader({ )} {showTrackLabel && } + {/* Not on an audio track. The control is the old visibility eye, and on + audio it silences rather than hides — but a row that already says what + it is with a speaker does not also need the hide affordance sitting in + the eye's slot. `visible={false}` rather than omitting the element, so + the spacer keeps every row's control columns aligned. */}