| Author: | ej-kon |
|---|---|
| Views Total: | 47 views |
| Official Page: | Go to website |
| Last Update: | September 1, 2025 |
| License: | MIT |
Preview:
Description:
DoubleRange is a vanilla JavaScript library that creates customizable, dual-thumb range sliders with full keyboard navigation, touch support, and ARIA compliance.
It can be used to help you implement professional-grade range sliders without external dependencies while maintaining accessibility standards.
Features:
- Lightweight and dependency-free: Only 12KB minified with no external dependencies.
- Full accessibility support: ARIA compliant with complete keyboard and screen reader compatibility.
- Touch and mobile ready: Native touch event handling for mobile devices.
- Programmatic API: Methods like
setFrom(),setTo(),update(), anddestroy()for complete control. - Memory leak prevention: Automatic cleanup with on-demand event listeners.
- Customizable styling: CSS variables and custom selectors for complete visual control.
- Before-change hooks:
beforeFromChangeandbeforeToChangecallbacks for validation.
Use cases:
- E-commerce Price Filters: The most obvious and common use case. Allow users to select a minimum and maximum price to narrow down product listings.
- Data Visualization Dashboards: Filter data within a specific range, such as a date range for a chart or a value range in a large dataset.
- Booking and Reservation Systems: Let users select a time window for appointments, rentals, or hotel stays.
- Web Application Settings: Configure settings that require a range, like setting a “do not disturb” time window or adjusting sensitivity levels in an analytics tool.
How to use it:
1. Install & download.
# NPM $ npm install @ej-kon/double-range
2. Load the double-range’s JavaScript and CSS files in the document.
<link rel="stylesheet" href="double-range.min.css"> <script src="double-range.min.js"></script>
3. Create a slider container element and initialize it with JavaScript:
<div id="priceSlider"></div>
const formatterFn = (v) => `$ ${v}`;
const callbackFn = (from,to) => {console.log(`example1 from:${from} to:${to}`)};
const slider = DoubleRange.create({
selector: "#priceSlider",
min: 30,
max: 500,
from: 100,
to: 400,
step: 1,
label: 'Example 1',
formatter: formatterFn,
delay: 300,
callback: callbackFn
});4. If your markup is rendered server-side or you prefer an HTML-first approach, you can initialize the slider on an existing structure using the new DoubleRange() constructor.
<div id="priceSlider">
<div class="double-range">
<div role="group" aria-label="Double Range">
<aside class="start point"></aside>
<aside class="min limit">0</aside>
<label for="doubleRange1-from" class="from"><span>20</span></label>
<div class="track" role="none">
<div class="thumb from"
id="doubleRange1-from" role="slider" tabindex="0"
aria-orientation="horizontal"
aria-valuemin="0" aria-valuemax="100" aria-valuenow="20" aria-valuetext="$20">
</div>
<div class="thumb to"
id="doubleRange1-to" role="slider" tabindex="0"
aria-orientation="horizontal"
aria-valuemin="0" aria-valuemax="100" aria-valuenow="80" aria-valuetext="$80">
</div>
<div class="range-bar"></div>
</div>
<label for="doubleRange1-to" class="to"><span>80</span></label>
<aside class="max limit">100</aside>
<aside class="end point"></aside>
</div>
</div>
</div>5. All configuration options.
selector(string): CSS selector for the container element.min(number): The minimum possible value of the range.max(number): The maximum possible value of the range.from(number): The initial selected value for the lower thumb.to(number): The initial selected value for the upper thumb.step(number): The increment value for each movement of the thumbs.label(string, optional): An ARIA label for the slider group, improving accessibility.formatter(function, optional): A function to format the displayed values. It receives the raw value and should return a string.callback(function, optional): A function that is called after a value changes. It receivesfromandtoas arguments.delay(number, optional): A debounce delay in milliseconds for thecallbackfunction to prevent it from firing too frequently.beforeFromChange(function, optional): A hook function that runs before thefromvalue changes. Must returntrueto allow the change orfalseto prevent it.beforeToChange(function, optional): A hook function that runs before thetovalue changes. Must returntrueto allow the change orfalseto prevent it.
const slider = DoubleRange.create({
selector: "#priceSlider",
min: 30,
max: 500,
from: 100,
to: 400,
step: 1,
label: 'Example 1',
formatter: formatterFn,
delay: 300,
callback: callbackFn
});6. The returned slider instance has several useful methods for programmatic control:
setFrom(value, fireCallback?): Sets the lower thumb’s value.fireCallback(boolean, defaulttrue) determines if the callback should be triggered.setTo(value, fireCallback?): Sets the upper thumb’s value.fireCallback(boolean, defaulttrue) determines if the callback should be triggered.getFrom(): Returns the current numeric value of the lower thumb.getTo(): Returns the current numeric value of the upper thumb.setMin(min, fireCallback?): Updates the minimum bound of the entire range.setMax(max, fireCallback?): Updates the maximum bound of the entire range.getMin(): Returns the current minimum bound of the range.getMax(): Returns the current maximum bound of the range.update(config, fireCallback?): Bulk updates multiple slider properties at once (min,max,from,to).getRange(): Returns an object with the current range:{ from: number, to: number }.destroy(): Removes all event listeners and observers to prevent memory leaks.
7. The slider dispatches a custom range-change event on its container element whenever the values change. This is useful for integrating with other parts of your application declaratively.
document.getElementById('priceSlider').addEventListener('range-change', (e) => {
const { from, to } = e.detail;
console.log('Range changed via event:', from, to);
});FAQs
Q: Can I prevent users from setting invalid ranges programmatically?
A: Yes, use the beforeFromChange and beforeToChange hooks. These functions receive the proposed new value and must return true to allow the change or false to prevent it. This works for both user interactions and programmatic updates.
Q: How do I handle the slider in responsive layouts?
A: The slider automatically adapts to its container width. We recommend wrapping it in a flexible container and using CSS media queries to adjust thumb sizes and spacing for smaller screens. The touch targets remain accessible even on mobile devices.
Q: How does the library handle decimal step values?
A: Decimal steps work correctly, but be aware of JavaScript floating-point precision issues. For financial applications, consider using integer values (cents instead of dollars) and formatting them in your display logic.
Q: Is there a way to snap thumbs to specific values?
A: The step parameter handles basic snapping. For custom snap points, use the before-change hooks to round values to your preferred snap positions before allowing the change.







