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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@molecule/app-feature-video-scrubber-react

v1.0.1

Published

Frame-accurate video scrubber — timeline strip with thumbnail filmstrip, playhead, frame-by-frame stepping, and keyboard scrubbing; composes with @molecule/app-feature-video-timeline-react

Readme

@molecule/app-feature-video-scrubber-react

Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit src/index.ts JSDoc, not this file.

Frame-accurate video scrubber for video-editor — timeline strip with thumbnail filmstrip, vertical playhead, frame-by-frame keyboard stepping (Shift = ±1 second), and an optional frame-number readout.

Composes well with <VideoTimeline> from @molecule/app-feature-video-timeline-react — the scrubber shows preview thumbnails and frame-precision controls; the timeline shows multi-track structure.

Exports <VideoScrubber>, the Thumbnail and VideoScrubberProps types, the default constants, and the pure helpers timeToFrame, frameToTime, snapTimeToFrame, computeFilmstripTicks, selectClosestThumbnail, and formatFrameNumber.

Quick Start

import { VideoScrubber } from '@molecule/app-feature-video-scrubber-react'

;<VideoScrubber
  duration={60}
  currentTime={3.2}
  fps={24}
  thumbnails={[
    { time: 0, src: 'data:image/png;base64,...' },
    { time: 5, src: 'data:image/png;base64,...' },
    { time: 10, src: 'data:image/png;base64,...' },
  ]}
  onSeek={(t) => setCurrentTime(t)}
/>

Type

feature

Installation

npm install @molecule/app-feature-video-scrubber-react @molecule/app-react @molecule/app-ui react
npm install -D @types/react

API

Interfaces

Thumbnail

One pre-computed thumbnail at a given time. The scrubber renders a filmstrip row of thumbnails by picking, for each visible tick, the provided thumbnail whose time is closest. Hosts can supply as few or as many thumbnails as they like; gaps are filled by repeating the nearest neighbour.

interface Thumbnail {
  /** Time of this thumbnail in seconds. */
  time: number
  /** Image source URL (data: URL or fetched blob URL). */
  src: string
}

VideoScrubberProps

Props for <VideoScrubber>. Frame-accurate scrubber widget pairing a thumbnail filmstrip with a click-to-seek playhead, frame-step keyboard controls, and an optional frame-number readout.

interface VideoScrubberProps {
  /** Total media duration in seconds. */
  duration: number
  /** Current playhead time in seconds. */
  currentTime: number
  /** Frames-per-second used for snapping + frame-step keyboard. Defaults to 24. */
  fps?: number
  /** Pre-computed thumbnails. The scrubber picks the closest one per filmstrip tick. */
  thumbnails?: Thumbnail[]
  /** Called with the seek time (snapped to the nearest frame). */
  onSeek?: (time: number) => void
  /** Whether to show the frame-number readout. Defaults to `true`. */
  showFrameNumber?: boolean
  /** Number of filmstrip cells to render. Defaults to 12. */
  thumbnailCount?: number
  /** Filmstrip cell height in px. Defaults to 48. */
  thumbnailHeight?: number
  /** Optional id for the root element (useful for label associations). */
  id?: string
  /** Extra classes merged onto the root element. */
  className?: string
}

Functions

computeFilmstripTicks(duration, count)

Compute evenly-spaced filmstrip ticks across [0, duration]. Each tick has a time (in seconds) and a position (0..1) for layout via left: position * 100%. The first tick is at time 0; the last tick is at time duration (or 0 if duration <= 0).

function computeFilmstripTicks(
  duration: number,
  count: number,
): { time: number; position: number }[]
  • duration — Total duration in seconds.
  • count — Number of ticks. Coerced into [1, 1000].

Returns: Array of { time, position } ticks (length === clamped count).

formatFrameNumber(frame)

Format a frame index for the readout display — fixed-width-friendly with a leading hash for clarity.

function formatFrameNumber(frame: number): string
  • frame — Frame index.

Returns: The display string (e.g. #42).

frameToTime(frame, fps)

Convert a frame index back to a time in seconds.

function frameToTime(frame: number, fps: number): number
  • frame — Frame index (any integer >= 0).
  • fps — Frame rate. Must be > 0.

Returns: Time in seconds.

selectClosestThumbnail(thumbnails, targetTime)

Pick the thumbnail whose time is closest to a target time. Ties break toward the earlier thumbnail. Returns undefined only when the input list is empty.

function selectClosestThumbnail(thumbnails: Thumbnail[], targetTime: number): Thumbnail | undefined
  • thumbnails — Available thumbnails (any order).
  • targetTime — The target time in seconds.

Returns: The closest thumbnail, or undefined if thumbnails is empty.

snapTimeToFrame(time, fps, duration)

Snap a continuous time value to the nearest frame boundary, then clamp into [0, duration]. This is what the scrubber emits via onSeek for click-anywhere scrubbing.

function snapTimeToFrame(time: number, fps: number, duration: number): number
  • time — Candidate time in seconds.
  • fps — Frame rate. Must be > 0.
  • duration — Maximum time in seconds (clamp upper bound).

Returns: Frame-snapped, clamped time in seconds.

timeToFrame(time, fps)

Convert a continuous time in seconds to a frame index, given a frame rate. The result is rounded to the nearest integer (i.e. snapped to the closest frame boundary).

function timeToFrame(time: number, fps: number): number
  • time — Time in seconds.
  • fps — Frame rate. Must be > 0.

Returns: Integer frame index (>= 0).

VideoScrubber(props)

Frame-accurate video scrubber. Renders an evenly-spaced filmstrip of thumbnail images, a vertical playhead, and an optional frame-number readout. Click anywhere on the strip to seek (snapped to the nearest frame); use ←/→ arrows to step ±1 frame, or Shift+←/→ to step ±1 second. All onSeek calls receive frame-snapped times.

Composes well with <VideoTimeline> from @molecule/app-feature-video-timeline-react — the scrubber shows preview thumbnails and frame-precision controls; the timeline shows multi-track structure.

function VideoScrubber(props: VideoScrubberProps): JSX.Element
  • props — Component props.

Returns: The scrubber element.

Constants

DEFAULT_FPS

Default frame rate (24fps — feature-film standard).

const DEFAULT_FPS: 24

DEFAULT_THUMBNAIL_COUNT

Default number of filmstrip cells.

const DEFAULT_THUMBNAIL_COUNT: 12

DEFAULT_THUMBNAIL_HEIGHT

Default filmstrip cell height in px.

const DEFAULT_THUMBNAIL_HEIGHT: 48

Injection Notes

Requirements

Peer dependencies:

  • @molecule/app-react ^1.0.1
  • @molecule/app-ui ^1.0.1
  • react ^18.0.0 || ^19.0.0

Runtime Dependencies

  • @molecule/app-react
  • @molecule/app-ui
  • react

onSeek is always called with frame-snapped times. Click anywhere on the filmstrip to seek; press the strip with keyboard focus and use arrows for ±1 frame, Shift+arrows for ±1 second, PageUp/PageDown for ±10 frames, Home/End to jump to start/end.

Translations

Translation strings are provided by @molecule/app-locales-feature-video-scrubber.