fix(timeline): restore visible track row height

This commit is contained in:
webadderall
2026-04-27 16:52:15 +10:00
parent 15cd2f15a3
commit 19a09cf37f
4 changed files with 27 additions and 3 deletions
@@ -63,6 +63,8 @@ import TimelineWrapper from "./TimelineWrapper";
import {
getTimelineContentMinHeightPx,
getTimelineRowsMinHeightPx,
getTimelineViewportStretchFactor,
TIMELINE_AXIS_HEIGHT_PX,
} from "./timelineLayout";
import { type AudioPeaksData, useAudioPeaks } from "./useAudioPeaks";
import { buildInteractionZoomSuggestions } from "./zoomSuggestionUtils";
@@ -709,13 +711,14 @@ function Timeline({
const timelineRowCount = 2 + annotationRowIds.length + audioRowIds.length;
const timelineRowsMinHeightPx = getTimelineRowsMinHeightPx(timelineRowCount);
const timelineContentMinHeightPx = getTimelineContentMinHeightPx(timelineRowCount);
const timelineViewportStretchFactor = getTimelineViewportStretchFactor(timelineRowCount);
return (
<div
ref={setRefs}
style={{
...style,
minHeight: `max(100%, ${timelineContentMinHeightPx}px)`,
height: `max(100%, ${timelineContentMinHeightPx}px, calc(${TIMELINE_AXIS_HEIGHT_PX}px + (100% - ${TIMELINE_AXIS_HEIGHT_PX}px) * ${timelineViewportStretchFactor}))`,
}}
className="select-none bg-editor-bg relative cursor-pointer group flex flex-col"
onClick={handleTimelineClick}
@@ -2059,7 +2062,7 @@ const TimelineEditor = forwardRef<TimelineEditorHandle, TimelineEditorProps>(
}
return (
<div className="flex-1 min-h-0 flex flex-col bg-editor-bg overflow-auto">
<div className="flex-1 min-h-0 flex flex-col bg-editor-bg overflow-hidden">
{hideToolbar ? null : (
<div className="flex items-center gap-2 px-4 py-2 border-b border-foreground/10 bg-editor-panel">
<div className="flex items-center gap-1">
@@ -375,7 +375,7 @@ export default function TimelineWrapper({
autoScroll={{ enabled: false }}
resizeHandleWidth={28}
>
<div className="relative min-h-full">
<div className="relative h-full min-h-0">
{children}
{/* Floating tooltip shown during drag/resize */}
<div
@@ -2,8 +2,10 @@ import { describe, expect, it } from "vitest";
import {
getTimelineContentMinHeightPx,
getTimelineRowsMinHeightPx,
getTimelineViewportStretchFactor,
TIMELINE_AXIS_HEIGHT_PX,
TIMELINE_ROW_MIN_HEIGHT_PX,
TIMELINE_VISIBLE_ROW_COUNT,
} from "./timelineLayout";
describe("timelineLayout", () => {
@@ -28,4 +30,12 @@ describe("timelineLayout", () => {
TIMELINE_AXIS_HEIGHT_PX + 2 * TIMELINE_ROW_MIN_HEIGHT_PX,
);
});
it("stretches content height to keep a two-row viewport", () => {
expect(TIMELINE_VISIBLE_ROW_COUNT).toBe(2);
expect(getTimelineViewportStretchFactor(2)).toBe(1);
expect(getTimelineViewportStretchFactor(4)).toBe(2);
expect(getTimelineViewportStretchFactor(5)).toBe(2.5);
expect(getTimelineViewportStretchFactor(0)).toBe(1);
});
});
@@ -1,5 +1,6 @@
export const TIMELINE_AXIS_HEIGHT_PX = 32;
export const TIMELINE_ROW_MIN_HEIGHT_PX = 28;
export const TIMELINE_VISIBLE_ROW_COUNT = 2;
function normalizeRowCount(rowCount: number) {
if (!Number.isFinite(rowCount)) {
@@ -16,3 +17,13 @@ export function getTimelineRowsMinHeightPx(rowCount: number) {
export function getTimelineContentMinHeightPx(rowCount: number) {
return TIMELINE_AXIS_HEIGHT_PX + getTimelineRowsMinHeightPx(rowCount);
}
export function getTimelineViewportStretchFactor(rowCount: number) {
const normalizedRowCount = normalizeRowCount(rowCount);
if (normalizedRowCount <= 0) {
return 1;
}
return Math.max(1, normalizedRowCount / TIMELINE_VISIBLE_ROW_COUNT);
}