mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-11-14 13:27:13 +00:00
L4 polish for the stacking-layer timeline: - Sub-composition layers group under a slim "Inside: <comp>" header with a green accent, so it reads that restacking there is scoped to that context. - Audio clips render in a distinct bottom lane: separator border, muted row bg, music glyph in the gutter, beat strip — clearly not part of the z-order stack. - During a vertical drag, a drop affordance shows join-vs-insert: an "onto" target highlights the row (join that layer / same z); "between"/"above"/ "below" shows an insertion line (new layer here). New pure helper timelineDropIndicator.ts (+ test) maps placement -> indicator; row-group rendering extracted into TimelineLayerGroupHeader / TimelineLayerGutter / TimelineDropInsertionLine / TimelineDragGhost to keep files under the 600 cap.
34 lines
1.2 KiB
TypeScript
34 lines
1.2 KiB
TypeScript
import type { TimelineLayerDropPlacement } from "./timelineStacking";
|
|
import type { TimelineLayerId } from "./timelineTrackOrder";
|
|
|
|
export type TimelineDropIndicator = { kind: "onto" } | { kind: "line"; edge: "top" | "bottom" };
|
|
|
|
interface ResolveTimelineDropIndicatorInput {
|
|
placement: TimelineLayerDropPlacement | null;
|
|
layerId: TimelineLayerId;
|
|
layerOrder: readonly TimelineLayerId[];
|
|
}
|
|
|
|
export function resolveTimelineDropIndicator({
|
|
placement,
|
|
layerId,
|
|
layerOrder,
|
|
}: ResolveTimelineDropIndicatorInput): TimelineDropIndicator | null {
|
|
if (!placement || !layerOrder.includes(layerId)) return null;
|
|
|
|
switch (placement.type) {
|
|
case "onto":
|
|
return placement.layerId === layerId ? { kind: "onto" } : null;
|
|
case "between":
|
|
if (placement.beforeLayerId === layerId) return { kind: "line", edge: "bottom" };
|
|
if (!layerOrder.includes(placement.beforeLayerId) && placement.afterLayerId === layerId) {
|
|
return { kind: "line", edge: "top" };
|
|
}
|
|
return null;
|
|
case "above":
|
|
return placement.layerId === layerId ? { kind: "line", edge: "top" } : null;
|
|
case "below":
|
|
return placement.layerId === layerId ? { kind: "line", edge: "bottom" } : null;
|
|
}
|
|
}
|