mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-07 18:26:17 +00:00
Timeline UI - Highlight clips visible at the playhead in the primary color; others share one neutral color - Minimalist rounded clips, single-color track rows, no gutter icons or superscript labels - Per-track eye toggle and a per-element hide button in the design panel - Ruler zoom fixes: sub-second tick intervals and correct label formatting at high zoom - Sticky gutter so track controls stay visible while scrolling WYSIWYG visibility (data-hidden) - Runtime honors data-hidden (display:none), so hiding affects the render, not just the preview - HTML stays the source of truth; hide state persists and round-trips on reload Split several studio files to stay under the 600-line cap; pure relocations, no behavior change.
93 lines
2.7 KiB
TypeScript
93 lines
2.7 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import {
|
|
getClipHandleOpacity,
|
|
getRenderedTimelineElement,
|
|
getTimelineTrackStyle,
|
|
} from "./timelineTheme";
|
|
import { getTrackStyle } from "./timelineIcons";
|
|
|
|
describe("getTimelineTrackStyle", () => {
|
|
it("uses one neutral clip style for every timeline tag", () => {
|
|
const expectedStyle = {
|
|
clip: "rgba(255,255,255,0.055)",
|
|
clipActive: "rgba(60,230,172,0.16)",
|
|
accent: "#3CE6AC",
|
|
label: "rgba(255,255,255,0.5)",
|
|
};
|
|
|
|
expect(getTimelineTrackStyle("video")).toEqual(expectedStyle);
|
|
expect(getTimelineTrackStyle("audio")).toEqual(expectedStyle);
|
|
expect(getTimelineTrackStyle("custom-tag")).toEqual(expectedStyle);
|
|
expect(getTimelineTrackStyle("video")).toEqual(getTimelineTrackStyle("audio"));
|
|
expect(getTimelineTrackStyle("video")).toEqual(getTimelineTrackStyle("custom-tag"));
|
|
});
|
|
});
|
|
|
|
describe("getTrackStyle", () => {
|
|
it("returns the timeline style only and preserves the empty tag fallback", () => {
|
|
const style = getTrackStyle("");
|
|
expect(style).toEqual(getTimelineTrackStyle("div"));
|
|
expect(Object.keys(style)).not.toContain("icon");
|
|
expect(Object.keys(style)).not.toContain("iconBackground");
|
|
});
|
|
});
|
|
|
|
describe("getClipHandleOpacity", () => {
|
|
it("hides handles at rest", () => {
|
|
expect(getClipHandleOpacity({ isHovered: false, isSelected: false, isDragging: false })).toBe(
|
|
0,
|
|
);
|
|
});
|
|
|
|
it("prioritizes dragging over hover and selection", () => {
|
|
expect(getClipHandleOpacity({ isHovered: true, isSelected: true, isDragging: true })).toBe(
|
|
0.95,
|
|
);
|
|
});
|
|
});
|
|
|
|
describe("getRenderedTimelineElement", () => {
|
|
it("keeps non-dragged clips unchanged", () => {
|
|
const element = { id: "a", tag: "div", start: 1, duration: 2, track: 0 };
|
|
expect(
|
|
getRenderedTimelineElement({
|
|
element,
|
|
draggedElementId: "b",
|
|
previewStart: 2,
|
|
previewTrack: 1,
|
|
}),
|
|
).toEqual(element);
|
|
});
|
|
|
|
it("moves the actual dragged clip to the preview position", () => {
|
|
const element = { id: "a", tag: "div", start: 1, duration: 2, track: 0 };
|
|
expect(
|
|
getRenderedTimelineElement({
|
|
element,
|
|
draggedElementId: "a",
|
|
previewStart: 2.4,
|
|
previewTrack: 3,
|
|
}),
|
|
).toEqual({ ...element, start: 2.4, track: 3 });
|
|
});
|
|
|
|
it("uses key before id when matching the dragged clip", () => {
|
|
const element = {
|
|
id: "Card",
|
|
key: "index.html:.card:1",
|
|
tag: "div",
|
|
start: 1,
|
|
duration: 2,
|
|
track: 0,
|
|
};
|
|
expect(
|
|
getRenderedTimelineElement({
|
|
element,
|
|
draggedElementId: "index.html:.card:1",
|
|
previewStart: 2.4,
|
|
previewTrack: 3,
|
|
}),
|
|
).toEqual({ ...element, start: 2.4, track: 3 });
|
|
});
|
|
});
|