Scrub Bar
A time bar for any media timeline: played and buffered, markers like keyframe times, and the time under the pointer.
In use
Inside the Video Studio's player, marking where each keyframe landed. Generate a clip to see it.
Your image will appear here
Your image will appear here
Your image will appear here
Your image will appear here

Paint over what to change. Tab reaches the marks: arrow keys move one, Enter edits its note, Delete removes it.
Your video will appear here
Installation
pnpm dlx shadcn@latest add https://mgp.paukraft.com/r/scrub-bar.jsonScrubBar
Not tied to a <video>: pass in its time and seek on change. The Video Player wires it for you; useMediaState does for any other clip.
| Prop | Type | Default |
|---|---|---|
| value | numberThe time, in seconds. Or defaultValue, uncontrolled. | — |
| duration | numberLength of the timeline, in seconds. Disabled while 0. | — |
| onValueChange | (seconds: number) => voidCalled as the handle moves: seek here. | — |
| onValueCommit | (seconds: number) => voidCalled when a drag ends, a press lands or a key steps. | — |
| buffered | TimeRange[]Loaded spans as [start, end] seconds, drawn behind progress. | — |
| step / largeStep | numberWhat the arrow keys and Shift + arrows step by, in seconds. Dragging snaps to step. | FRAME / 1 |
| format | (seconds: number) => stringLabels the hover time and the handle for screen readers. | formatTime |
| children | ReactNodeGo on the track, e.g. markers. | — |
Parts
| Prop | Type | Default |
|---|---|---|
| ScrubBarRoot | Base UI Slider.Root propsThe timeline and its pointer, without layers. | — |
| ScrubBarTrack | Slider.Track propsThe bar; thickens on hover. | — |
| ScrubBarProgress | Slider.Indicator propsThe track up to the value. | — |
| ScrubBarBuffered | { ranges: TimeRange[] }What the media has loaded. | — |
| ScrubBarRange | { start: number; end: number }A span of the track, e.g. a trim range. | — |
| ScrubBarMarker | { time: number }A notch, e.g. where a keyframe lands. | — |
| ScrubBarThumb | Slider.Thumb propsThe handle. On hover devices it shows while the bar is used. | — |
| ScrubBarHover | <span> propsThe time under the pointer, above it. | — |
| useScrubBar | () => { duration, hover, format, toPercent }For your own layers. | — |
Helpers
| Prop | Type | Default |
|---|---|---|
| formatTime | (seconds: number, span?: number) => stringm:ss, with tenths when span, e.g. the duration, is under a minute: "0:07.5", "1:04". | — |
| FRAME | number1/24: one frame at 24 fps. | — |
