Skip to content

UI: Slider Component #275

@mihar-22

Description

@mihar-22

Blocked by:

Usage

React

<Slider.Root defaultValue={50} min={0} max={100}>
  <Slider.Track>
    <Slider.Indicator />
    <Slider.Thumb />
  </Slider.Track>
</Slider.Root>
<Slider.Root defaultValue={50} min={0} max={100}>
  <Slider.Track>
    <Slider.Indicator />
    <Slider.Thumb />
  </Slider.Track>
  <Slider.Preview>
    <Slider.Value />
  </Slider.Preview>
</Slider.Root>
<Slider.Root defaultValue={50} min={0} max={100} orientation="vertical">
  <Slider.Track>
    <Slider.Indicator />
    <Slider.Thumb />
  </Slider.Track>
</Slider.Root>

HTML

<media-slider value="50" min="0" max="100">
  <div class="track">
    <div class="indicator"></div>
    <div class="thumb"></div>
  </div>
</media-slider>
<media-slider value="50" min="0" max="100">
  <div class="track">
    <div class="indicator"></div>
    <div class="thumb"></div>
  </div>
  <media-slider-preview>
    <media-slider-value></media-slider-value>
  </media-slider-preview>
</media-slider>

API

Slider.Root

Groups all parts of the slider.

Props

Prop Type Default Description
value number Controlled value
defaultValue number 0 Uncontrolled initial value
min number 0 Minimum value
max number 100 Maximum value
step number 1 Step increment for value changes
keyStep number 1 Step increment for keyboard navigation
shiftKeyMultiplier number 10 Multiplier applied when shift key is held
orientation 'horizontal' | 'vertical' 'horizontal' Slider orientation
disabled boolean false Whether slider should ignore user interaction

Callbacks

Callback Type Description
onValueChange (value: number) => void Fires when value changes during interaction
onValueCommit (value: number) => void Fires when interaction ends (pointerup, keyup)
onDragStart () => void Fires when drag interaction begins
onDragEnd () => void Fires when drag interaction ends

State

Property Type Description
value number Current value
dragging boolean Whether thumb is being dragged
pointing boolean Whether pointer is over slider
focused boolean Whether slider has keyboard focus

Data Attributes

Attribute Description
data-dragging Present while the user is dragging
data-pointing Present while pointer is over slider
data-focused Present while slider has keyboard focus
data-orientation Indicates orientation (horizontal or vertical)
data-disabled Present when slider is disabled

CSS Variables

Variable Description
--slider-value Current value (raw number)
--slider-fill Fill percentage (0% to 100%)
--slider-pointer Pointer position percentage (0% to 100%)

Slider.Track

Contains the indicator and thumb. Represents the entire range of the slider.

Data Attributes

Inherits all data attributes from Slider.Root.

Slider.Indicator

Visualizes the current value. Width/height driven by --slider-fill.

Data Attributes

Inherits all data attributes from Slider.Root.

Slider.Thumb

The draggable part at the tip of the indicator. Contains a visually hidden <input type="range"> for accessibility.

Props

Prop Type Default Description
getAriaLabel () => string Function returning aria-label for the input
getAriaValueText (value: number) => string Function returning aria-valuetext for the input

Data Attributes

Inherits all data attributes from Slider.Root.

Slider.Preview

Container for preview content displayed on hover. Positioned relative to pointer.

Props

Prop Type Default Description
offset number 0 Offset from pointer position in px

Data Attributes

Attribute Description
data-visible Present when preview is visible (pointing or dragging)

Slider.Value

Displays the current or pointer value.

Props

Prop Type Default Description
type 'current' | 'pointer' 'pointer' Which value to display

<media-slider> (HTML)

Attributes

Attribute Type Default Description
value number 0 Current value
min number 0 Minimum value
max number 100 Maximum value
step number 1 Step increment
key-step number 1 Keyboard step increment
shift-key-multiplier number 10 Multiplier when shift key is held
orientation 'horizontal' | 'vertical' 'horizontal' Slider orientation
disabled boolean false Whether slider should ignore interaction

<media-slider-preview> (HTML)

Attributes

Attribute Type Default Description
offset number 0 Offset from pointer in px

<media-slider-value> (HTML)

Attributes

Attribute Type Default Description
type 'current' | 'pointer' 'pointer' Which value to display

Tasks

Core (@videojs/core)

  • Define SliderProps interface
  • Define SliderCallbacks interface
  • Define SliderState interface
  • Implement SliderCore class
  • Implement drag interaction handling
  • Implement keyboard navigation
  • Implement pointer tracking for preview

DOM (@videojs/dom)

  • Implement getSliderRootProps(params) function
  • Implement getSliderTrackProps(params) function
  • Implement getSliderIndicatorProps(params) function
  • Implement getSliderThumbProps(params) function
  • Implement getSliderPreviewProps(params) function
  • Implement getSliderValueProps(params) function
  • Define SliderDataAttributes interface
  • Define SliderCssVars interface

React (@videojs/react)

  • Implement Slider.Root component
  • Implement Slider.Track component
  • Implement Slider.Indicator component
  • Implement Slider.Thumb component
  • Implement Slider.Preview component
  • Implement Slider.Value component
  • Implement useSlider(options) hook

HTML (@videojs/html)

  • Implement SliderElement element
  • Implement SliderPreviewElement element
  • Implement SliderValueElement element

Testing

  • Core unit tests
  • Test drag interactions
  • Test keyboard navigation
  • Test pointer tracking
  • Add conformance test suite
  • Add React conformance test
  • Add HTML conformance test

Documentation

  • Create /docs/react/components/slider page
  • Create /docs/html/components/slider page

Design Notes

Keyboard Navigation

Key Action
ArrowRight / ArrowUp Increase by keyStep
ArrowLeft / ArrowDown Decrease by keyStep
Shift + Arrow Increase/decrease by keyStep * shiftKeyMultiplier
Home Set to min
End Set to max

CSS-Driven Styling

The root element sets CSS variables. Children consume them for layout:

.indicator {
  width: var(--slider-fill);
}

.thumb {
  left: var(--slider-fill);
  transform: translateX(-50%);
}

.preview {
  left: var(--slider-pointer);
}

[data-orientation="vertical"] .indicator {
  height: var(--slider-fill);
  width: 100%;
}

Pointer Tracking

While hovering or dragging, --slider-pointer updates to reflect pointer position. This enables preview positioning without JavaScript layout.

Accessibility

Slider contains a visually hidden <input type="range"> for screen reader support.

Extensibility

VolumeSlider and TimeSlider extend this base:

class VolumeSliderCore extends SliderCore {
  constructor(audio: AudioFeature) {
    super({ min: 0, max: 1, step: 0.01 });
    // Connect to audio state...
  }
}

class TimeSliderCore extends SliderCore {
  constructor(time: TimeFeature) {
    super({ min: 0, max: time.state.duration, step: 1 });
    // Connect to time state...
  }
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions