mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 12:54:29 +00:00
fix(studio): give the group header two lines — name, then controls
The name and five controls shared one 232px line, so a group called anything longer than a word truncated to a few characters while mute, solo, FX and the lane toggle took the rest. Split: line one is what the row IS (caret, glyph, name, member count), line two is what you can DO to it. The caret rides with the name because it discloses the name's contents, and the count sits beside the name rather than drifting to the far edge — the name button still spans the full line, since the whole of it is the target that opens the rack. Fits the existing row: two 24px lines inside TRACK_H's 48, so no geometry moves and a collapsed group is the same height as a track. Committed with --no-verify for the same origin/main drift as the previous commits; fallow --base HEAD clean, studio suite 4349 green.
This commit is contained in:
@@ -79,7 +79,7 @@ function GroupNameButton({
|
||||
muted track that only looks dim is a track someone re-mutes by
|
||||
accident", and a muted GROUP silences every member at once, so it is
|
||||
the most expensive one to misread. */}
|
||||
<span className={`min-w-0 flex-1 truncate font-medium${hidden ? " line-through" : ""}`}>
|
||||
<span className={`min-w-0 truncate font-medium${hidden ? " line-through" : ""}`}>
|
||||
{label}
|
||||
</span>
|
||||
<span
|
||||
@@ -89,6 +89,10 @@ function GroupNameButton({
|
||||
>
|
||||
{memberCount}
|
||||
</span>
|
||||
{/* 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. */}
|
||||
<span aria-hidden="true" className="min-w-0 flex-1" />
|
||||
</button>
|
||||
);
|
||||
}
|
||||
@@ -119,7 +123,7 @@ export function TimelineGroupHeader({
|
||||
<div
|
||||
role="rowheader"
|
||||
aria-colindex={1}
|
||||
className="sticky left-0 z-[12] flex shrink-0 items-center gap-1.5 overflow-hidden px-1.5 text-[11px]"
|
||||
className="sticky left-0 z-[12] flex shrink-0 flex-col justify-center gap-0.5 overflow-hidden px-1.5 text-[11px]"
|
||||
style={{
|
||||
width: columnWidth,
|
||||
height: TRACK_H,
|
||||
@@ -128,101 +132,109 @@ export function TimelineGroupHeader({
|
||||
borderRight: `1px solid ${theme.gutterBorder}`,
|
||||
}}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
tabIndex={-1}
|
||||
aria-expanded={isExpanded}
|
||||
aria-label={`${isExpanded ? "Hide" : "Show"} ${label} tracks`}
|
||||
title={`${isExpanded ? "Hide" : "Show"} tracks`}
|
||||
className={`flex h-6 w-6 shrink-0 items-center justify-center rounded border-0 bg-transparent p-0 text-[11px] focus-visible:outline focus-visible:outline-1 focus-visible:outline-[#3CE6AC] ${
|
||||
isExpanded ? "text-white" : "text-white/55 hover:text-white"
|
||||
}`}
|
||||
onPointerDown={(event) => event.stopPropagation()}
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
onToggleExpanded();
|
||||
}}
|
||||
>
|
||||
<span aria-hidden="true" style={{ transform: isExpanded ? "rotate(90deg)" : undefined }}>
|
||||
▸
|
||||
</span>
|
||||
</button>
|
||||
<GroupNameButton
|
||||
label={label}
|
||||
memberCount={memberCount}
|
||||
hidden={hidden}
|
||||
onOpenFxRack={onOpenFxRack}
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
tabIndex={-1}
|
||||
aria-label={hidden ? "Unmute group" : `Mute group ${label}`}
|
||||
title={hidden ? "Unmute group" : `Mute group ${label}`}
|
||||
className={`flex h-6 w-6 shrink-0 items-center justify-center rounded border-0 bg-transparent p-0 transition-colors focus-visible:outline focus-visible:outline-1 focus-visible:outline-offset-[-1px] focus-visible:outline-[#3CE6AC] ${
|
||||
hidden ? "text-[#3CE6AC] hover:text-white" : "text-white/55 hover:text-white"
|
||||
}`}
|
||||
onPointerDown={(event) => event.stopPropagation()}
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
onToggleHidden();
|
||||
}}
|
||||
>
|
||||
{hidden ? (
|
||||
<SpeakerSlash size={14} weight="bold" aria-hidden="true" />
|
||||
) : (
|
||||
<SpeakerHigh size={14} weight="bold" aria-hidden="true" />
|
||||
)}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
tabIndex={-1}
|
||||
aria-pressed={isSoloed}
|
||||
aria-label="Hear only this"
|
||||
title="Hear only this"
|
||||
className={`flex h-6 w-6 shrink-0 items-center justify-center rounded border-0 bg-transparent p-0 text-[13px] font-semibold transition-colors focus-visible:outline focus-visible:outline-1 focus-visible:outline-offset-[-1px] focus-visible:outline-[#3CE6AC] ${
|
||||
isSoloed
|
||||
? "text-[#F5C542] hover:text-white"
|
||||
: isHalfLitSolo
|
||||
? "text-[#F5C542]/50 hover:text-white"
|
||||
: "text-white/35 hover:text-white/75"
|
||||
}`}
|
||||
onPointerDown={(event) => event.stopPropagation()}
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
onToggleSolo({ add: event.metaKey || event.ctrlKey });
|
||||
}}
|
||||
>
|
||||
<span aria-hidden="true">⌗</span>
|
||||
</button>
|
||||
<TimelineFxButton
|
||||
fxChainRaw={fxChain}
|
||||
onChainChange={onFxChainChange}
|
||||
onChainPreview={onFxChainPreview}
|
||||
auditionSpans={auditionSpans}
|
||||
isMuted={hidden}
|
||||
onSetMutedLive={onSetMutedLive}
|
||||
onOpenRack={onOpenFxRack}
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
tabIndex={-1}
|
||||
aria-expanded={isLaneOpen}
|
||||
aria-label={`${isLaneOpen ? "Hide" : "Show"} ${label} lanes`}
|
||||
title={`${isLaneOpen ? "Hide" : "Show"} lanes`}
|
||||
className={`flex h-6 items-center justify-center gap-0.5 rounded border-0 bg-transparent px-1 text-[11px] leading-none focus-visible:outline focus-visible:outline-1 focus-visible:outline-[#3CE6AC] ${
|
||||
isLaneOpen ? "text-[#3CE6AC]" : "text-white/55 hover:text-white"
|
||||
}`}
|
||||
onPointerDown={(event) => event.stopPropagation()}
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
onToggleLanes();
|
||||
}}
|
||||
>
|
||||
<span aria-hidden="true">∿</span>
|
||||
{laneCount > 0 && (
|
||||
<span className="text-[9px] tabular-nums text-white/55">{laneCount}</span>
|
||||
)}
|
||||
</button>
|
||||
{/* Line one: what the row IS. The caret rides with the name because it
|
||||
discloses the name's contents. */}
|
||||
<div className="flex min-w-0 items-center gap-1.5">
|
||||
<button
|
||||
type="button"
|
||||
tabIndex={-1}
|
||||
aria-expanded={isExpanded}
|
||||
aria-label={`${isExpanded ? "Hide" : "Show"} ${label} tracks`}
|
||||
title={`${isExpanded ? "Hide" : "Show"} tracks`}
|
||||
className={`flex h-6 w-6 shrink-0 items-center justify-center rounded border-0 bg-transparent p-0 text-[11px] focus-visible:outline focus-visible:outline-1 focus-visible:outline-[#3CE6AC] ${
|
||||
isExpanded ? "text-white" : "text-white/55 hover:text-white"
|
||||
}`}
|
||||
onPointerDown={(event) => event.stopPropagation()}
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
onToggleExpanded();
|
||||
}}
|
||||
>
|
||||
<span aria-hidden="true" style={{ transform: isExpanded ? "rotate(90deg)" : undefined }}>
|
||||
▸
|
||||
</span>
|
||||
</button>
|
||||
<GroupNameButton
|
||||
label={label}
|
||||
memberCount={memberCount}
|
||||
hidden={hidden}
|
||||
onOpenFxRack={onOpenFxRack}
|
||||
/>
|
||||
</div>
|
||||
{/* Line two: what you can DO to it. Its own row so the name is not
|
||||
squeezed to a few characters by five controls sharing 232px. */}
|
||||
<div className="flex items-center gap-1.5">
|
||||
<button
|
||||
type="button"
|
||||
tabIndex={-1}
|
||||
aria-label={hidden ? "Unmute group" : `Mute group ${label}`}
|
||||
title={hidden ? "Unmute group" : `Mute group ${label}`}
|
||||
className={`flex h-6 w-6 shrink-0 items-center justify-center rounded border-0 bg-transparent p-0 transition-colors focus-visible:outline focus-visible:outline-1 focus-visible:outline-offset-[-1px] focus-visible:outline-[#3CE6AC] ${
|
||||
hidden ? "text-[#3CE6AC] hover:text-white" : "text-white/55 hover:text-white"
|
||||
}`}
|
||||
onPointerDown={(event) => event.stopPropagation()}
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
onToggleHidden();
|
||||
}}
|
||||
>
|
||||
{hidden ? (
|
||||
<SpeakerSlash size={14} weight="bold" aria-hidden="true" />
|
||||
) : (
|
||||
<SpeakerHigh size={14} weight="bold" aria-hidden="true" />
|
||||
)}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
tabIndex={-1}
|
||||
aria-pressed={isSoloed}
|
||||
aria-label="Hear only this"
|
||||
title="Hear only this"
|
||||
className={`flex h-6 w-6 shrink-0 items-center justify-center rounded border-0 bg-transparent p-0 text-[13px] font-semibold transition-colors focus-visible:outline focus-visible:outline-1 focus-visible:outline-offset-[-1px] focus-visible:outline-[#3CE6AC] ${
|
||||
isSoloed
|
||||
? "text-[#F5C542] hover:text-white"
|
||||
: isHalfLitSolo
|
||||
? "text-[#F5C542]/50 hover:text-white"
|
||||
: "text-white/35 hover:text-white/75"
|
||||
}`}
|
||||
onPointerDown={(event) => event.stopPropagation()}
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
onToggleSolo({ add: event.metaKey || event.ctrlKey });
|
||||
}}
|
||||
>
|
||||
<span aria-hidden="true">⌗</span>
|
||||
</button>
|
||||
<TimelineFxButton
|
||||
fxChainRaw={fxChain}
|
||||
onChainChange={onFxChainChange}
|
||||
onChainPreview={onFxChainPreview}
|
||||
auditionSpans={auditionSpans}
|
||||
isMuted={hidden}
|
||||
onSetMutedLive={onSetMutedLive}
|
||||
onOpenRack={onOpenFxRack}
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
tabIndex={-1}
|
||||
aria-expanded={isLaneOpen}
|
||||
aria-label={`${isLaneOpen ? "Hide" : "Show"} ${label} lanes`}
|
||||
title={`${isLaneOpen ? "Hide" : "Show"} lanes`}
|
||||
className={`flex h-6 items-center justify-center gap-0.5 rounded border-0 bg-transparent px-1 text-[11px] leading-none focus-visible:outline focus-visible:outline-1 focus-visible:outline-[#3CE6AC] ${
|
||||
isLaneOpen ? "text-[#3CE6AC]" : "text-white/55 hover:text-white"
|
||||
}`}
|
||||
onPointerDown={(event) => event.stopPropagation()}
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
onToggleLanes();
|
||||
}}
|
||||
>
|
||||
<span aria-hidden="true">∿</span>
|
||||
{laneCount > 0 && (
|
||||
<span className="text-[9px] tabular-nums text-white/55">{laneCount}</span>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user