From be71b59523d55e8fa4dd1bede724999ee4360672 Mon Sep 17 00:00:00 2001 From: Vance Ingalls Date: Wed, 19 Aug 2026 20:30:22 -0700 Subject: [PATCH] feat(studio): one-line group header, matching the track headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The group row now reads like every other gutter row: caret, then the name and its member count, then every control anchored to the right edge — FX and the automation toggle in one right-aligned group, sharing the same column as a member track's own. Same reasoning as the track headers a commit ago. The second line existed to keep five controls from squeezing the label, but the name truncates on its own and the controls are `shrink-0`, so they hold the edge and the name gives way instead. Two things had to give for `ml-auto` to work: - `GroupNameButton` lost its `flex-1`, and with it the spacer span that used to eat the slack to keep the count beside the name. The row's control group owns the slack now; leaving either in place pushed the controls — and the count, which rides inside that button — off the edge. - The name button gained `h-6`. At its natural 17px it centred 4px lower than the 24px buttons beside it, so the four controls sat on three different baselines. All four now measure top 12, height 24. Nothing asserted this header's shape, so the group side had none of the protection the track side got: the test checks three children, the controls in an `ml-auto` group, and the count NOT in it. Co-Authored-By: Claude Opus 5 (1M context) --- .../player/components/TimelineGroupHeader.tsx | 69 +++++++++---------- .../components/TimelineGroupRow.test.tsx | 26 +++++++ 2 files changed, 60 insertions(+), 35 deletions(-) diff --git a/packages/studio/src/player/components/TimelineGroupHeader.tsx b/packages/studio/src/player/components/TimelineGroupHeader.tsx index b36fdd7ea..64a1fa941 100644 --- a/packages/studio/src/player/components/TimelineGroupHeader.tsx +++ b/packages/studio/src/player/components/TimelineGroupHeader.tsx @@ -52,7 +52,10 @@ function GroupNameButton({ tabIndex={-1} aria-label={`Open ${label} effects`} title="Open effects" - className="flex min-w-0 flex-1 items-center gap-1.5 rounded border-0 bg-transparent p-0 text-left text-[11px] text-white hover:text-[#3CE6AC] focus-visible:outline focus-visible:outline-1 focus-visible:outline-[#3CE6AC]" + // No `flex-1`: the row's control group owns the slack now (`ml-auto`), so + // claiming it here would push the controls off the right edge — and the + // count with them, since it rides inside this button. + className="flex h-6 min-w-0 items-center gap-1.5 rounded border-0 bg-transparent p-0 text-left text-[11px] text-white hover:text-[#3CE6AC] focus-visible:outline focus-visible:outline-1 focus-visible:outline-[#3CE6AC]" onPointerDown={(event) => event.stopPropagation()} onClick={(event) => { event.stopPropagation(); @@ -70,10 +73,6 @@ function GroupNameButton({ > {memberCount} - {/* Eats the slack so the count sits beside the name rather than drifting - to the far edge, while the button itself stays full width — the whole - name line is the target that opens the rack. */} -