Limeplay - Open Source Video Player UI ComponentsLimeplay

Timeline Control

Slider control to control the media timeline. Composed with timeline state control

Installation

Install the component

npx shadcn add @limeplay/timeline-control

Add Event & Action Bridge

Import the useTimelineStates hook in your existing PlayerHooks component.

components/limeplay/player-hooks.tsx
import React from "react"

import { useShakaPlayer } from "@/hooks/limeplay/use-shaka-player"
import { useTimelineStates } from "@/hooks/limeplay/use-timeline"

export const PlayerHooks = React.memo(() => {
  useShakaPlayer()
  useTimelineStates() 

  return null
})

Add the Store States

lib/create-media-store.ts
import { createPlayerStore, PlayerStore } from "@/hooks/limeplay/use-player"
import {
  createTimelineStore,
  TimelineStore,
} from "@/hooks/limeplay/use-timeline"


export type TypeMediaStore = PlayerStore & TimelineStore & {} 

export function createMediaStore(initProps?: Partial<CreateMediaStoreProps>) {
  const mediaStore = create<TypeMediaStore>()((...etc) => ({
    ...createPlayerStore(...etc),
    ...createTimelineStore(...etc),
    ...initProps,
  }))
  return mediaStore
}

Example Usage

  1. Compose the timeline slider and handle states
components/player/timeline-control.tsx
import { useMediaStore } from "@/components/limeplay/media-provider"
import * as TimelineSlider from "@/components/limeplay/timeline-control"
import { Duration, HoverTime } from "@/components/limeplay/timeline-labels"

export function TimelineSliderControl() {
  return (
    <div className="relative w-full grow">
      <TimelineSlider.Root className="focus-area -focus-area-x-2 -focus-area-y-14">
        <TimelineSlider.Track className="overflow-hidden">
          <TimelineSlider.Progress />
          <TimelineSlider.Buffered variant="combined" />
        </TimelineSlider.Track>
        {/* Thumb to Seek */}
        <TimelineSlider.Thumb
          showWithHover
          className={"absolute h-8 w-px rounded-full bg-lp-accent/60"}
        />
        {/* Custom Thumb */}
        <TimelineSlider.Thumb
          showWithHover
          className={
            "top-auto! bottom-[calc(100%+16px)] flex h-auto w-fit bg-transparent text-xs font-medium"
          }
        >
          <HoverTime />
          <Duration className="text-lp-accent/60" />
        </TimelineSlider.Thumb>
      </TimelineSlider.Root>
    </div>
  )
}
  1. Use the component in your player.
components/player/bottom-controls.tsx
<TimelineSliderControl />

Understanding

The Timeline Control implements a highly composable seek slider following the Event & Action Bridge pattern:

  • Event Bridge: useTimelineStates() updates currentTime, duration, progress, and buffered ranges via polling (default 500ms)
  • Action Bridge: Components use useTimeline() to call seek() which updates media.currentTime

Live Stream Support

Timeline automatically handles live streams:

  • Uses Shaka Player's seekRange() for proper DVR seeking
  • Displays live latency
  • Adjusts progress calculation for sliding window

Accessibility

  • ARIA Slider: aria-label="Timeline Slider"
  • Keyboard Navigation: Focus and arrow key support
  • Screen Reader: Announces time changes
  • Visual Focus: Clear focus indicators

Components

Timeline is built with multiple composable parts.

Root

Main slider container with built-in click/drag seek handling.

API Reference

Prop

Type

Thumb

Draggable handle and/or hover preview.

API Reference

Prop

Type

Buffered

Shows buffered ranges. Supports 3 variants: default, combined, from-zero.

API Reference

Prop

Type

Track

Visual track representing full duration. Extends SliderPrimitive.Track props.

Progress

Filled indicator showing playback progress.

On this page