npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@hautechai/webui.timeline

v1.0.13

Published

Timeline component with tracks and keyframes for video editing interfaces

Downloads

82

Readme

Timeline

Purpose

Timeline 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.

Parameters

| 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 |

TimelineTrackData Interface

| 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 |

KeyframeProperty Interface

| 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 |

Keyframe Interface

| Property | Type | Description | | -------- | ------- | ------------------------------------------ | | id | string | Unique identifier for the keyframe | | time | number | Time position in seconds | | selected | boolean | Whether the keyframe is currently selected |

Usage Example

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 }],
            },
        ],
    },
];

<Timeline
    height={300}
    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)}
/>;

Features

  • 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