mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-10 22:20:14 +00:00
docs(studio): document timeline keyboard navigation (#3031)
* feat(studio): expose timeline treegrid semantics * feat(studio): coordinate logical timeline focus * feat(studio): add timeline keyboard controls * docs(studio): document timeline keyboard navigation
This commit is contained in:
@@ -16,6 +16,7 @@ import {
|
||||
} from "./trackHeaderLaneState";
|
||||
import { valueReadout } from "./trackHeaderLaneValues";
|
||||
import { trackDisplaySuffix } from "./timelineTrackDisplay";
|
||||
import { timelineLogicalRowCellId, timelinePropertyRowId } from "./timelineNavigationIdentity";
|
||||
|
||||
interface TimelineTrackHeaderProps {
|
||||
/** The track's real key: a FRACTIONAL z-order sort value. Routes callbacks;
|
||||
@@ -41,6 +42,7 @@ interface TimelineTrackHeaderProps {
|
||||
currentTime: number;
|
||||
isTrackHidden: boolean;
|
||||
isAudioTrack: boolean;
|
||||
rovingTargetId?: string | null;
|
||||
theme: TimelineTheme;
|
||||
onToggleClipExpanded: () => void;
|
||||
onToggleTrackHidden: TimelineEditCallbacks["onToggleTrackHidden"];
|
||||
@@ -191,6 +193,7 @@ function PropertyGroupNavigation({
|
||||
}
|
||||
|
||||
function PropertyGroupHeaderRow({
|
||||
lanesId,
|
||||
lane,
|
||||
laneIndex,
|
||||
isLastLane,
|
||||
@@ -201,7 +204,9 @@ function PropertyGroupHeaderRow({
|
||||
columnWidth,
|
||||
onTogglePropertyGroupKeyframe,
|
||||
onSeek,
|
||||
rovingTargetId = null,
|
||||
}: {
|
||||
lanesId: string;
|
||||
lane: TimelinePropertyLane;
|
||||
laneIndex: number;
|
||||
isLastLane: boolean;
|
||||
@@ -212,7 +217,9 @@ function PropertyGroupHeaderRow({
|
||||
columnWidth: number;
|
||||
onTogglePropertyGroupKeyframe?: TimelineEditCallbacks["onTogglePropertyGroupKeyframe"];
|
||||
onSeek?: (time: number) => void;
|
||||
rovingTargetId: string | null;
|
||||
}) {
|
||||
const elementId = expandedElement.key ?? expandedElement.id;
|
||||
const { navigation, values, label, toggleTarget } = resolveLaneHeaderState(
|
||||
lane,
|
||||
currentTime,
|
||||
@@ -221,6 +228,10 @@ function PropertyGroupHeaderRow({
|
||||
|
||||
return (
|
||||
<div
|
||||
id={timelineLogicalRowCellId(lanesId, timelinePropertyRowId(elementId, lane.group), "header")}
|
||||
data-timeline-focus-id={timelinePropertyRowId(elementId, lane.group)}
|
||||
data-timeline-element-id={elementId}
|
||||
tabIndex={rovingTargetId === timelinePropertyRowId(elementId, lane.group) ? 0 : -1}
|
||||
data-property-group={lane.group}
|
||||
data-timeline-lane-top={getTimelineLaneTop(laneIndex)}
|
||||
className="absolute left-0 flex items-center gap-1 overflow-hidden px-1.5 text-[10px] text-white/65"
|
||||
@@ -298,6 +309,7 @@ export function TimelineTrackHeader({
|
||||
onToggleTrackHidden,
|
||||
onTogglePropertyGroupKeyframe,
|
||||
onSeek,
|
||||
rovingTargetId = null,
|
||||
}: TimelineTrackHeaderProps) {
|
||||
const clipPercentage = keyframeClip
|
||||
? ((currentTime - keyframeClip.start) / keyframeClip.duration) * 100
|
||||
@@ -314,6 +326,8 @@ export function TimelineTrackHeader({
|
||||
|
||||
return (
|
||||
<div
|
||||
role="rowheader"
|
||||
aria-colindex={1}
|
||||
className={`sticky left-0 z-[12] shrink-0 ${
|
||||
!isKeyframeLayer
|
||||
? showTrackLabel
|
||||
@@ -374,6 +388,7 @@ export function TimelineTrackHeader({
|
||||
lanes.map((lane, laneIndex) => (
|
||||
<PropertyGroupHeaderRow
|
||||
key={lane.group}
|
||||
lanesId={lanesId}
|
||||
lane={lane}
|
||||
laneIndex={laneIndex}
|
||||
isLastLane={laneIndex === lanes.length - 1}
|
||||
@@ -384,6 +399,7 @@ export function TimelineTrackHeader({
|
||||
columnWidth={showTrackLabel ? LABEL_COL_W : contentOrigin}
|
||||
onTogglePropertyGroupKeyframe={onTogglePropertyGroupKeyframe}
|
||||
onSeek={onSeek}
|
||||
rovingTargetId={rovingTargetId}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
|
||||
Reference in New Issue
Block a user