writeClipFxChain(singleAudioClip, next, false)}
- onChainPreview={(next) => writeClipFxChain(singleAudioClip, next, true)}
- // Muted, an audition is silent — so the hover lifts the mute on
- // the running graph and puts it back on the way out, the same
- // borrow-and-return it already does with the playhead.
- auditionSpans={[singleAudioClip]}
- isMuted={isTrackHidden}
- onSetMutedLive={(muted) =>
- onSetElementAttributeLive?.(singleAudioClip, "data-hidden", muted ? "" : null)
- }
- onOpenRack={() => openClipFxRack(singleAudioClip)}
- />
- )}
{/* The rack shelf is `audio-fx-rack`; the group-pointer variant WRITES
a group, so it needs `audio-groups` too — without it a user outside
that canary could create a group and then have no UI to manage it. */}
diff --git a/packages/studio/src/player/components/TimelineTrackPlainHeader.tsx b/packages/studio/src/player/components/TimelineTrackPlainHeader.tsx
index e5dacfcd9..19a404569 100644
--- a/packages/studio/src/player/components/TimelineTrackPlainHeader.tsx
+++ b/packages/studio/src/player/components/TimelineTrackPlainHeader.tsx
@@ -1,3 +1,4 @@
+import type React from "react";
import { Eye, EyeSlash, SpeakerHigh, SpeakerSlash } from "@phosphor-icons/react";
import { isCanaryEnabled } from "../../telemetry/canary";
import { Music } from "../../icons/SystemIcons";
@@ -72,6 +73,7 @@ export function PlainTrackHeader({
isSoloed,
onToggleSolo,
onToggleTrackHidden,
+ trailing,
}: {
trackNumber: number;
trackDisplayNumber: number | null;
@@ -84,41 +86,52 @@ export function PlainTrackHeader({
isGroupMuted: boolean;
isSoloed: boolean;
onToggleSolo?: (options?: { add?: boolean }) => void;
+ /** Trailing controls that belong on the control line — the FX entry points,
+ * which the caller owns because only it knows the clip they act on. */
+ trailing?: React.ReactNode;
}) {
return (
<>
- {isAudioTrack && (
-
- )}
- {showTrackLabel && (
-
- {trackLabel}
-
- )}
- {showTrackLabel && }
- {/* Not on an audio track. The control is the old visibility eye, and on
+ {/* Line one: what the row IS. Line two (below) is what you can do to it —
+ the same split the group header uses, for the same reason: a name and
+ four controls sharing 232px truncated the name to a few characters. */}
+
+ {isAudioTrack && (
+
+ )}
+ {showTrackLabel && (
+
+ {trackLabel}
+
+ )}
+ {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. */}
-
- {isAudioTrack && isCanaryEnabled("audio-track-mute") && onToggleSolo && (
-
- )}
+
+ {isAudioTrack && isCanaryEnabled("audio-track-mute") && onToggleSolo && (
+
+ )}
+ {trailing}
+
>
);
}