mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-11 06:30:03 +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.
62 lines
1.9 KiB
TypeScript
62 lines
1.9 KiB
TypeScript
import { Eye, EyeSlash } from "@phosphor-icons/react";
|
|
import { Music } from "../../icons/SystemIcons";
|
|
import type { TimelineTheme } from "./timelineTheme";
|
|
import { GUTTER } from "./timelineLayout";
|
|
|
|
interface TimelineLayerGutterProps {
|
|
isAudio: boolean;
|
|
isTrackHidden: boolean;
|
|
rowTrack: number;
|
|
theme: TimelineTheme;
|
|
onToggleHidden: () => void;
|
|
}
|
|
|
|
export function TimelineLayerGutter({
|
|
isAudio,
|
|
isTrackHidden,
|
|
rowTrack,
|
|
theme,
|
|
onToggleHidden,
|
|
}: TimelineLayerGutterProps) {
|
|
return (
|
|
<div
|
|
className="sticky left-0 z-[12] flex-shrink-0 flex flex-col items-center justify-center gap-0.5"
|
|
style={{
|
|
width: GUTTER,
|
|
background: theme.gutterBackground,
|
|
borderRight: `1px solid ${theme.gutterBorder}`,
|
|
}}
|
|
>
|
|
{isAudio && (
|
|
<Music
|
|
size={12}
|
|
weight="fill"
|
|
aria-hidden="true"
|
|
style={{ color: theme.textSecondary, opacity: 0.7 }}
|
|
/>
|
|
)}
|
|
<button
|
|
type="button"
|
|
aria-label={isTrackHidden ? `Show track ${rowTrack}` : `Hide track ${rowTrack}`}
|
|
title={isTrackHidden ? `Show track ${rowTrack}` : `Hide track ${rowTrack}`}
|
|
className={`flex h-6 w-6 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] ${
|
|
isTrackHidden ? "text-[#3CE6AC] hover:text-white" : "text-white/35 hover:text-white/75"
|
|
}`}
|
|
onPointerDown={(e) => {
|
|
e.stopPropagation();
|
|
}}
|
|
onClick={(e) => {
|
|
e.stopPropagation();
|
|
onToggleHidden();
|
|
}}
|
|
>
|
|
{isTrackHidden ? (
|
|
<EyeSlash size={14} weight="bold" aria-hidden="true" />
|
|
) : (
|
|
<Eye size={14} weight="bold" aria-hidden="true" />
|
|
)}
|
|
</button>
|
|
</div>
|
|
);
|
|
}
|