Skip to content

Repository files navigation

React Compare Slider

Compare two components side-by-side or top-to-toe.

Example

Features

  • Supports responsive images and any other React components (picture, video, canvas, iframe, etc.)
  • Supports landscape and portrait orientations
  • Accessible with screen reader and keyboard support out of the box
  • Simple API
  • Unopinionated and fully customizable, optionally use your own components and styles
  • Responsive and fluid with intrinsic sizing
  • Teeny-tiny, zero dependencies, tree-shakeable
  • Type safe

Demos

Usage

Install

npm install react-compare-slider
# or
yarn add react-compare-slider
# or
pnpm add react-compare-slider

Basic Image Usage

You may use ReactCompareSliderImage to render images or use your own custom components.

import { ReactCompareSlider, ReactCompareSliderImage } from 'react-compare-slider';

export const Example = () => {
  return (
    <ReactCompareSlider
      itemOne={<ReactCompareSliderImage src="..." srcSet="..." alt="Image one" />}
      itemTwo={<ReactCompareSliderImage src="..." srcSet="..." alt="Image two" />}
    />
  );
};

Props

Prop Type Required Default Description
boundsPadding string 0px Padding to limit the slideable bounds on the X-axis (landscape) or Y-axis (portrait).
browsingContext globalThis globalThis Context to bind events to (useful for iframes).
changePositionOnHover boolean false Whether the slider should follow the pointer on hover.
clip all|itemOne|itemTwo all Whether to clip itemOne, itemTwo or all items.
defaultPosition number 50 Initial percentage position of divide (0-100).
disabled boolean false Whether to disable slider movement (items are still interactable).
handle ReactNode undefined Custom handle component.
itemOne ReactNode ✓ undefined First component to show in slider.
itemTwo ReactNode ✓ undefined Second component to show in slider.
keyboardIncrement number|`${number}%` 5% Percentage or pixel amount to move when the slider handle is focused and keyboard arrow is pressed.
onlyHandleDraggable boolean true for touch devices, false for non-touch devices Whether to only change position when handle is interacted with (useful for touch devices).
onPositionChange (position: number) => void undefined Callback on position change, returns current position percentage as argument.
portrait boolean false Whether to use portrait orientation.
transition string '0.15s ease-out'|'none' Shorthand CSS transition property to apply to handle movement. This is automatically none for users with the prefers-reduced-motion: reduced preference.

API docs for more information.

Advanced Usage

You can also construct your own slider for more granular control.

import * as Slider from 'react-compare-slider/components';
import { useReactCompareSlider } from 'react-compare-slider/hooks';

export const Example = () => {
  // Access to state and event bindings of the slider.
  const sliderProps = useReactCompareSlider({ portrait: true });

  return (
    <Slider.Provider {...sliderProps}>
      <Slider.Root>
        <Slider.Item item="itemOne">
          <Slider.Image
            src="https://raw.githubusercontent.com/nerdyman/stuff/main/libs/react-compare-slider/demo-images/lady-1.png"
            alt="Image one"
          />
        </Slider.Item>
        <Slider.Item item="itemTwo">
          <Slider.Image
            src="https://raw.githubusercontent.com/nerdyman/stuff/main/libs/react-compare-slider/demo-images/lady-2.png"
            alt="Image two"
          />
        </Slider.Item>
        <Slider.HandleRoot>
          <Slider.Handle />
        </Slider.HandleRoot>
      </Slider.Root>
    </Slider.Provider>
};

See the Components API docs for more information.

About

A slider component to compare any two React components in landscape or portrait orientation. It supports custom images, videos... and everything else.

Topics

Resources

Contributing

Stars

382 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Used by

Contributors

Languages