Demos

Drag the handle, or focus the slider and use the arrow keys, to reveal more of either side.

Usage

Use a compare slider when the difference between two states is the point: results before and after a change, a light and dark theme, an old and new design. Both views share the same frame, so they should be the same size and line up. For more than two views, use tabs or a carousel.

Import it from @workspace/ui/components/compare-slider.

Anatomy

  • CompareSlider — The root. Holds the position and has the slider role.
  • CompareSliderBefore — The first view, shown on the left (or top when vertical).
  • CompareSliderAfter — The second view, shown on the right (or bottom when vertical).
  • CompareSliderHandle — The divider and grip. Pass children to replace the default grip.
  • CompareSliderLabel — A badge pinned to a corner. CompareSliderBefore and CompareSliderAfter render one for you when you pass label.

Notes

  • Give the root a height, or a parent with a height for the vertical orientation. The views fill it absolutely.
  • Give the root an aria-label so screen readers know what is being compared. Passing label to a view also names it for assistive technology.
  • The arrow keys move the handle by step. Page Up, Page Down and Shift with an arrow move it by ten steps, and Home and End jump to either edge.
  • value is a percentage from 0 to 100: 0 shows all of the after view, 100 shows all of the before view.

Examples

Vertical

Set orientation="vertical" to stack the views and drag up and down.

Follow pointer

Set interaction="hover" to move the divider with the pointer, without dragging. The grip is hidden in this mode.

Controlled

Pass value and onValueChange to drive the position from your own state.

Props

These are the props you set most often. Unlisted props pass through to the underlying element.

CompareSlider

PropTypeDefaultDescription
valuenumber—Controlled position, from 0 to 100.
defaultValuenumber50Starting position when uncontrolled.
onValueChange(value: number) => void—Called when the position changes.
stepnumber1How far the arrow keys move the handle.
interaction"drag" or "hover""drag"Drag the handle, or follow the pointer.
orientation"horizontal" or "vertical""horizontal"Direction the divider moves.
renderReactElement or function—Replaces the root div with your own element.
classNamestring—Classes merged onto the root.

CompareSliderBefore and CompareSliderAfter

PropTypeDefaultDescription
labelstring—Shows a corner label and names the view for screen readers.
classNamestring—Classes merged onto the view.

CompareSliderLabel

PropTypeDefaultDescription
side"before" or "after"—Which corner to pin the label to.