Timeline component with tracks and keyframes for video editing interfaces
npm install @hautechai/webui.timelineTimeline component that provides a 2x2 grid layout for video editing interfaces with tracks and keyframes. Features a draggable playhead for time navigation and combines track visualization with keyframe editing capabilities in a structured timeline layout.
| Parameter | Type | Description |
| -------------------- | ---------------------------------------------------------- | --------------------------------------------------------------------------- |
| height | number | Optional. Height of the timeline component in pixels (default: 250) |
| scale | number | Required. Scale in pixels per second for timeline display |
| duration | number | Required. Total duration in seconds of the full timeline (replaces maxTime) |
| tracks | TimelineTrackData[] | Required. Array of track data with keyframe properties |
| currentTime | number | Optional. Current playhead time position in seconds (default: 0) |
| onSelectTrack | (trackId: string) => void | Optional. Called when a track is selected |
| onSelectKeyframe | (keyframeId: string) => void | Optional. Called when a keyframe is selected |
| onMoveTrack | (trackId: string, start: number, duration: number) => void | Optional. Called when a track is moved or resized |
| onMoveKeyframe | (keyframeId: string, time: number) => void | Optional. Called when a keyframe is moved |
| onRenameTrack | (trackId: string, newTitle: string) => void | Optional. Called when a track is renamed |
| onTimeChange | (time: number) => void | Optional. Called when playhead time changes through user interaction |
| onScaleChange | (scale: number) => void | Optional. Called when user adjusts scale via custom scrollbar |
| onStartMoveTrack | (trackId: string) => void | Optional. Called when track move/resize operation starts |
| onFinishMoveTrack | (trackId: string, start: number, duration: number) => void | Optional. Called when track move/resize operation finishes |
| onStartMoveKeyframe | (keyframeId: string) => void | Optional. Called when keyframe move operation starts |
| onFinishMoveKeyframe | (keyframeId: string, time: number) => void | Optional. Called when keyframe move operation finishes |
| Property | Type | Description |
| ------------- | ------------------ | ------------------------------------------- |
| id | string | Unique identifier for the track |
| title | string | Display title for the track |
| start | number | Start time in seconds |
| duration | number | Duration in seconds |
| selected | boolean | Whether the track is currently selected |
| keyframeProps | KeyframeProperty[] | Array of keyframe properties for this track |
| Property | Type | Description |
| --------- | ---------- | ------------------------------------------- |
| id | string | Unique identifier for the keyframe property |
| label | string | Display label for the keyframe property |
| keyframes | Keyframe[] | Array of keyframes for this property |
| Property | Type | Description |
| -------- | ------- | ------------------------------------------ |
| id | string | Unique identifier for the keyframe |
| time | number | Time position in seconds |
| selected | boolean | Whether the keyframe is currently selected |
``tsx
const tracks = [
{
id: 'track1',
title: 'Video Layer',
start: 0,
duration: 10,
selected: false,
keyframeProps: [
{
id: 'opacity',
label: 'Opacity',
keyframes: [
{ id: 'kf1', time: 2.5, selected: false },
{ id: 'kf2', time: 7.0, selected: true },
],
},
{
id: 'scale',
label: 'Scale',
keyframes: [{ id: 'kf3', time: 1.0, selected: false }],
},
],
},
];
scale={50}
duration={15} // Provide explicit total timeline duration
tracks={tracks}
currentTime={3.2}
onSelectTrack={(trackId) => console.log('Selected track:', trackId)}
onSelectKeyframe={(keyframeId) => console.log('Selected keyframe:', keyframeId)}
onMoveTrack={(trackId, start, duration) => console.log('Moved track:', trackId, 'to', start, duration)}
onMoveKeyframe={(keyframeId, time) => console.log('Moved keyframe:', keyframeId, 'to time:', time)}
onRenameTrack={(trackId, newTitle) => console.log('Renamed track:', trackId, 'to:', newTitle)}
onTimeChange={(time) => console.log('Playhead moved to:', time)}
onScaleChange={(scale) => console.log('Scale changed to:', scale)}
onStartMoveTrack={(trackId) => console.log('Started moving track:', trackId)}
onFinishMoveTrack={(trackId, start, duration) =>
console.log('Finished moving track:', trackId, 'at', start, duration)
}
onStartMoveKeyframe={(keyframeId) => console.log('Started moving keyframe:', keyframeId)}
onFinishMoveKeyframe={(keyframeId, time) => console.log('Finished moving keyframe:', keyframeId, 'at time:', time)}
/>;
``
- 2x2 Grid Layout: Organized with TimelineRuler header, track labels sidebar, and scrollable timeline area
- Draggable Playhead: Interactive time navigation with triangular indicator and vertical line
- Track Visualization: TimelineTrack components for visual track representation
- Keyframe Editing: TimelineTrackKeyframes components with selection and movement capabilities
- Responsive Design: Configurable height and scale with proper sticky positioning
- Theme Integration: Consistent styling using theme variables throughout