Slider
A versatile range slider component with optional increment/decrement buttons, perfect for audio parameter control.
Demo
Interactive Example
Volume75%
Frequency440 Hz
PanC
Features
- Continuous value control with min/max/step
- Optional +/- increment buttons
- Label and value display
- Custom value formatting
- Disabled state support
- Full accessibility (ARIA labels, keyboard support)
- Completely customizable styling
Import
tsx
import { Slider } from '@mode-7/mod';
import '@mode-7/mod/dist/index.css'; // Optional default stylesProps
| Prop | Type | Default | Description |
|---|---|---|---|
value | number | Required | Current slider value |
onChange | (value: number) => void | Required | Value change callback |
min | number | 0 | Minimum value |
max | number | 100 | Maximum value |
step | number | 1 | Step increment |
label | string | - | Optional label text |
unit | string | '' | Unit suffix (e.g., "Hz", "%") |
formatValue | (value: number) => string | - | Custom value formatter |
showButtons | boolean | true | Show +/- buttons |
disabled | boolean | false | Disable the slider |
className | string | '' | Container class |
labelClassName | string | '' | Label class |
valueClassName | string | '' | Value display class |
controlClassName | string | '' | Control wrapper class |
buttonClassName | string | '' | Button class |
inputClassName | string | '' | Range input class |
Usage
Basic Usage
tsx
import { Slider } from '@mode-7/mod';
import { useState } from 'react';
function MyComponent() {
const [volume, setVolume] = useState(50);
return (
<Slider
value={volume}
onChange={setVolume}
min={0}
max={100}
label="Volume"
unit="%"
/>
);
}Without Buttons
tsx
<Slider
value={value}
onChange={setValue}
showButtons={false}
label="Pan"
min={-1}
max={1}
step={0.01}
/>With Custom Formatting
tsx
<Slider
value={frequency}
onChange={setFrequency}
min={20}
max={20000}
step={1}
label="Frequency"
formatValue={(val) => {
if (val >= 1000) {
return `${(val / 1000).toFixed(1)} kHz`;
}
return `${val.toFixed(0)} Hz`;
}}
/>Logarithmic Scale
For parameters like frequency that work better on a logarithmic scale:
tsx
import { useState } from 'react';
function LogSlider() {
const [frequency, setFrequency] = useState(440);
// Convert linear slider position to logarithmic frequency
const minLog = Math.log(20);
const maxLog = Math.log(20000);
const scale = (maxLog - minLog) / 100;
const handleChange = (position: number) => {
const freq = Math.exp(minLog + scale * position);
setFrequency(freq);
};
const position = (Math.log(frequency) - minLog) / scale;
return (
<Slider
value={position}
onChange={handleChange}
min={0}
max={100}
label="Frequency"
formatValue={() => `${frequency.toFixed(0)} Hz`}
/>
);
}With Tailwind Styling
tsx
<Slider
value={value}
onChange={setValue}
label="Gain"
unit=" dB"
className="w-full p-2"
labelClassName="text-gray-400 text-xs uppercase tracking-wide"
valueClassName="text-emerald-500 text-xs font-mono"
buttonClassName="bg-gray-800 hover:bg-gray-700 border-gray-600 text-gray-400 hover:text-emerald-500"
inputClassName="accent-emerald-500"
/>Disabled State
tsx
<Slider
value={value}
onChange={setValue}
label="Locked Parameter"
disabled={true}
/>Multiple Sliders
tsx
function EQControls() {
const [low, setLow] = useState(0);
const [mid, setMid] = useState(0);
const [high, setHigh] = useState(0);
return (
<div className="eq-controls">
<Slider
value={low}
onChange={setLow}
min={-12}
max={12}
step={0.1}
label="Low"
unit=" dB"
/>
<Slider
value={mid}
onChange={setMid}
min={-12}
max={12}
step={0.1}
label="Mid"
unit=" dB"
/>
<Slider
value={high}
onChange={setHigh}
min={-12}
max={12}
step={0.1}
label="High"
unit=" dB"
/>
</div>
);
}CSS Classes
The Slider component uses the following CSS classes:
.modui-slider- Container element.modui-slider-header- Header with label and value.modui-slider-label- Label text.modui-slider-value- Value display.modui-slider-control- Control wrapper (input + buttons).modui-slider-button- Button elements (both + and -).modui-slider-button-minus- Decrement button.modui-slider-button-plus- Increment button.modui-slider-input- Range input element
Styling Examples
Custom Theme
css
.modui-slider {
padding: 0.75rem;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 8px;
}
.modui-slider-label {
color: rgba(255, 255, 255, 0.9);
text-transform: uppercase;
letter-spacing: 0.05em;
}
.modui-slider-value {
color: white;
font-weight: bold;
}
.modui-slider-button {
background: rgba(255, 255, 255, 0.2);
border: 1px solid rgba(255, 255, 255, 0.3);
color: white;
}
.modui-slider-button:hover:not(:disabled) {
background: rgba(255, 255, 255, 0.3);
border-color: rgba(255, 255, 255, 0.5);
}
.modui-slider-input::-webkit-slider-thumb {
background: white;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
}Minimal Style
css
.modui-slider {
width: 100%;
}
.modui-slider-header {
margin-bottom: 0.25rem;
}
.modui-slider-label,
.modui-slider-value {
font-size: 10px;
color: #666;
}
.modui-slider-button {
display: none; /* Hide buttons for minimal look */
}
.modui-slider-input {
height: 2px;
background: #e0e0e0;
border: none;
}
.modui-slider-input::-webkit-slider-thumb {
width: 12px;
height: 12px;
background: #333;
box-shadow: none;
}Accessibility
The Slider component includes:
aria-labelattributes for screen readers- Keyboard support (arrow keys work on the range input)
- Proper
disabledstate handling - Focus indicators
- Semantic button elements with
type="button"
