React Compound Slider: Crafting Seamless Sliding Experiences
React Compound Slider is a powerful and flexible library that allows developers to create customizable slider components in React applications. It provides a set of low-level components that can be composed to build complex slider interfaces with multiple handles, custom styles, and various interaction modes. Whether you’re building a simple range selector or a sophisticated multi-handle slider, React Compound Slider offers the tools to bring your vision to life.
Key Features
React Compound Slider comes packed with a variety of features that make it stand out:
- Compound Component API: Leverages React’s composition model for ultimate flexibility.
- Multiple Handles: Support for sliders with any number of handles.
- Custom Styles: Full control over the appearance of your sliders.
- Keyboard Accessibility: Built-in keyboard navigation for improved usability.
- Touch Support: Seamless interaction on touch devices.
- Vertical and Horizontal Orientations: Create sliders in both directions.
- Customizable Step Sizes: Define precise increments for value changes.
- React Hooks Support: Modern API for easier integration with functional components.
Getting Started
To begin using React Compound Slider in your project, you’ll need to install it first. You can do this using either npm or yarn.
Using npm:
npm install react-compound-slider
Using yarn:
yarn add react-compound-slider
Basic Usage
Let’s start with a simple example to demonstrate how to create a basic slider using React Compound Slider.
Creating a Simple Slider
Here’s how you can create a basic horizontal slider:
import React from 'react';
import { Slider, Rail, Handles, Tracks } from 'react-compound-slider';
const SimpleSlider: React.FC = () => {
const sliderStyle: React.CSSProperties = {
position: 'relative',
width: '100%',
height: 80,
};
const railStyle: React.CSSProperties = {
position: 'absolute',
width: '100%',
height: 10,
marginTop: 35,
borderRadius: 5,
backgroundColor: '#8B9CB6',
};
return (
<Slider
rootStyle={sliderStyle}
domain={[0, 100]}
values={[50]}
>
<Rail>
{({ getRailProps }) => (
<div style={railStyle} {...getRailProps()} />
)}
</Rail>
<Handles>
{({ handles, getHandleProps }) => (
<div className="slider-handles">
{handles.map(({ id, value, percent }) => (
<div
key={id}
style={{
position: 'absolute',
marginLeft: -15,
marginTop: 25,
zIndex: 2,
width: 30,
height: 30,
border: 0,
textAlign: 'center',
cursor: 'pointer',
borderRadius: '50%',
backgroundColor: '#2C4870',
color: '#fff',
left: `${percent}%`,
}}
{...getHandleProps(id)}
>
<div style={{ fontFamily: 'Roboto', fontSize: 11, marginTop: -35 }}>
{value}
</div>
</div>
))}
</div>
)}
</Handles>
<Tracks right={false}>
{({ tracks, getTrackProps }) => (
<div className="slider-tracks">
{tracks.map(({ id, source, target }) => (
<div
key={id}
style={{
position: 'absolute',
height: 10,
zIndex: 1,
marginTop: 35,
backgroundColor: '#546C91',
borderRadius: 5,
cursor: 'pointer',
left: `${source.percent}%`,
width: `${target.percent - source.percent}%`,
}}
{...getTrackProps()}
/>
))}
</div>
)}
</Tracks>
</Slider>
);
};
export default SimpleSlider;
This example creates a horizontal slider with a single handle. The Slider
component wraps the entire slider structure. The Rail
component represents the full length of the slider, while Handles
creates the draggable handle. The Tracks
component fills the area between the start of the slider and the current handle position.
Advanced Usage
Now that we’ve covered the basics, let’s explore some more advanced features of React Compound Slider.
Multi-Handle Slider
Creating a slider with multiple handles is straightforward with React Compound Slider. Here’s an example of a range slider with two handles:
import React from 'react';
import { Slider, Rail, Handles, Tracks, Ticks } from 'react-compound-slider';
const MultiHandleSlider: React.FC = () => {
const sliderStyle: React.CSSProperties = {
position: 'relative',
width: '100%',
height: 80,
};
const railStyle: React.CSSProperties = {
position: 'absolute',
width: '100%',
height: 10,
marginTop: 35,
borderRadius: 5,
backgroundColor: '#8B9CB6',
};
return (
<Slider
rootStyle={sliderStyle}
domain={[0, 100]}
values={[20, 60]}
step={1}
mode={2}
>
<Rail>
{({ getRailProps }) => (
<div style={railStyle} {...getRailProps()} />
)}
</Rail>
<Handles>
{({ handles, getHandleProps }) => (
<div className="slider-handles">
{handles.map(({ id, value, percent }) => (
<div
key={id}
style={{
position: 'absolute',
marginLeft: -15,
marginTop: 25,
zIndex: 2,
width: 30,
height: 30,
border: 0,
textAlign: 'center',
cursor: 'pointer',
borderRadius: '50%',
backgroundColor: '#2C4870',
color: '#fff',
left: `${percent}%`,
}}
{...getHandleProps(id)}
>
<div style={{ fontFamily: 'Roboto', fontSize: 11, marginTop: -35 }}>
{value}
</div>
</div>
))}
</div>
)}
</Handles>
<Tracks left={false} right={false}>
{({ tracks, getTrackProps }) => (
<div className="slider-tracks">
{tracks.map(({ id, source, target }) => (
<div
key={id}
style={{
position: 'absolute',
height: 10,
zIndex: 1,
marginTop: 35,
backgroundColor: '#546C91',
borderRadius: 5,
cursor: 'pointer',
left: `${source.percent}%`,
width: `${target.percent - source.percent}%`,
}}
{...getTrackProps()}
/>
))}
</div>
)}
</Tracks>
<Ticks count={5}>
{({ ticks }) => (
<div className="slider-ticks">
{ticks.map(tick => (
<div
key={tick.id}
style={{
position: 'absolute',
marginTop: 52,
marginLeft: -10,
width: 20,
height: 20,
textAlign: 'center',
left: `${tick.percent}%`,
}}
>
<div style={{ fontSize: 10, fontFamily: 'Arial' }}>{tick.value}</div>
</div>
))}
</div>
)}
</Ticks>
</Slider>
);
};
export default MultiHandleSlider;
In this example, we’ve added a second handle and included tick marks for better visual reference. The mode={2}
prop ensures that the handles can cross each other, which is typical for range selectors.
Vertical Slider
React Compound Slider also supports vertical sliders. Here’s how you can create one:
import React from 'react';
import { Slider, Rail, Handles, Tracks } from 'react-compound-slider';
const VerticalSlider: React.FC = () => {
const sliderStyle: React.CSSProperties = {
position: 'relative',
height: '400px',
width: 80,
};
const railStyle: React.CSSProperties = {
position: 'absolute',
width: 10,
height: '100%',
marginLeft: 35,
borderRadius: 5,
backgroundColor: '#8B9CB6',
};
return (
<Slider
vertical
rootStyle={sliderStyle}
domain={[0, 100]}
values={[50]}
step={1}
>
<Rail>
{({ getRailProps }) => (
<div style={railStyle} {...getRailProps()} />
)}
</Rail>
<Handles>
{({ handles, getHandleProps }) => (
<div className="slider-handles">
{handles.map(({ id, value, percent }) => (
<div
key={id}
style={{
position: 'absolute',
marginLeft: 25,
marginTop: -15,
zIndex: 2,
width: 30,
height: 30,
border: 0,
textAlign: 'center',
cursor: 'pointer',
borderRadius: '50%',
backgroundColor: '#2C4870',
color: '#fff',
bottom: `${percent}%`,
}}
{...getHandleProps(id)}
>
<div style={{ fontFamily: 'Roboto', fontSize: 11, marginTop: 35 }}>
{value}
</div>
</div>
))}
</div>
)}
</Handles>
<Tracks right={false}>
{({ tracks, getTrackProps }) => (
<div className="slider-tracks">
{tracks.map(({ id, source, target }) => (
<div
key={id}
style={{
position: 'absolute',
width: 10,
zIndex: 1,
marginLeft: 35,
backgroundColor: '#546C91',
borderRadius: 5,
cursor: 'pointer',
bottom: `${source.percent}%`,
height: `${target.percent - source.percent}%`,
}}
{...getTrackProps()}
/>
))}
</div>
)}
</Tracks>
</Slider>
);
};
export default VerticalSlider;
The key differences here are the vertical
prop on the Slider
component and the adjusted styles to accommodate the vertical layout.
Customizing Behavior
React Compound Slider offers various props to customize the behavior of your sliders. Here are some examples:
Step Size
You can control the step size of the slider using the step
prop:
<Slider
domain={[0, 100]}
values={[50]}
step={5}
>
{/* ... */}
</Slider>
This will make the slider move in increments of 5.
Disabled State
To disable a slider, you can use the disabled
prop:
<Slider
domain={[0, 100]}
values={[50]}
disabled={true}
>
{/* ... */}
</Slider>
Custom Handle Rendering
You can customize the appearance of handles by providing your own render function:
<Handles>
{({ handles, getHandleProps }) => (
<div className="slider-handles">
{handles.map(({ id, value, percent }) => (
<button
key={id}
style={{
position: 'absolute',
left: `${percent}%`,
transform: 'translate(-50%, -50%)',
cursor: 'pointer',
padding: '5px',
borderRadius: '50%',
backgroundColor: '#4CAF50',
color: 'white',
border: 'none',
}}
{...getHandleProps(id)}
>
{value}
</button>
))}
</div>
)}
</Handles>
This example renders the handles as circular buttons with the current value displayed inside.
Wrapping Up
React Compound Slider provides a powerful and flexible way to create customizable slider components in React applications. Its compound component structure allows for granular control over every aspect of the slider, from appearance to behavior.
By leveraging the library’s various components like Rail
, Handles
, Tracks
, and Ticks
, developers can create sliders that range from simple single-handle implementations to complex multi-handle, multi-track designs. The ability to customize styles, handle rendering, and interaction modes makes it suitable for a wide range of use cases.
Whether you’re building a simple volume control or a complex data range selector, React Compound Slider offers the tools and flexibility to bring your slider designs to life. With its support for both horizontal and vertical orientations, touch devices, and keyboard accessibility, it ensures that your sliders are not only functional but also user-friendly across different platforms and input methods.
As you continue to explore React Compound Slider, you’ll discover even more ways to tailor your sliders to your specific needs,