Skip to content

Commit 894269e

Browse files
committed
Merge branch 'min-max-zero-#20' into main
2 parents 75fedca + 9d5b4d6 commit 894269e

File tree

7 files changed

+712
-564
lines changed

7 files changed

+712
-564
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ prop | type | default | description
103103
**rest** | `Boolean`/`String` | `false` | Whether to show a pip or label for the all other values. Use `rest='label'` to show a label value
104104
**prefix** | `String` | `""` | A string to prefix to all displayed values
105105
**suffix** | `String` | `""` | A string to suffix to all displayed values
106+
**disabled** | `Boolean` | `false` | Determine if the slider is disabled, or enabled _(only disables interactions, and events)_
106107
**formatter** | `Function` | `(v) => v` | A function to re-format values before they are displayed
107108
**handleFormatter** | `Function` | `formatter` | A function to re-format values on the handle/float before they are displayed. Defaults to the same function given to the `formatter` property
108109
**springValues** | `Object` | `{ stiffness: 0.15, damping: 0.4 }` | Svelte spring physics object to change the behaviour of the handle when moving

dist/svelte-range-slider-pips.js

Lines changed: 273 additions & 220 deletions
Large diffs are not rendered by default.

dist/svelte-range-slider-pips.mjs

Lines changed: 273 additions & 220 deletions
Large diffs are not rendered by default.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "svelte-range-slider-pips",
3-
"version": "1.6.1",
3+
"version": "1.7.0",
44
"svelte": "src/index.js",
55
"module": "dist/svelte-range-slider-pips.mjs",
66
"main": "dist/svelte-range-slider-pips.js",

src/RangeSlider.svelte

Lines changed: 118 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
export let vertical = false;
1414
export let float = false;
1515
export let hover = true;
16+
export let disabled = false;
1617
1718
// range pips / values props
1819
export let pips = false;
@@ -50,21 +51,26 @@
5051
5152
// copy the initial values in to a spring function which
5253
// will update every time the values array is modified
53-
let springPositions = spring(
54-
values.map((v) =>
55-
parseFloat((((v - min) / (max - min)) * 100).toFixed(precision))
56-
),
57-
springValues
58-
);
59-
60-
// check the values array, and trim it if needed (range)
61-
// and clamp the values to the steps and boundaries set up in the slider
62-
$: values = trimRange(values).map((v) => alignValueToStep(v));
63-
64-
// update the spring function so that movement can happen in the UI
54+
let springPositions;
55+
6556
$: {
66-
springPositions.set(values.map((v) => percentOf(v)));
67-
}
57+
// check that "values" is an array, or set it as array
58+
// to prevent any errors in springs, or range trimming
59+
if ( !Array.isArray( values ) ) {
60+
values = [(max + min) / 2];
61+
console.error( "'values' prop should be an Array (https://github.com/simeydotme/svelte-range-slider-pips#slider-props)" );
62+
}
63+
// trim the range as needed
64+
values = trimRange(values);
65+
// clamp the values to the steps and boundaries set up in the slider
66+
values = values.map((v) => alignValueToStep(v));
67+
// update the spring function so that movement can happen in the UI
68+
if ( springPositions ) {
69+
springPositions.set(values.map((v) => percentOf(v)));
70+
} else {
71+
springPositions = spring( values.map((v) => percentOf(v)), springValues );
72+
}
73+
};
6874
6975
/**
7076
* take in a value, and then calculate that value's percentage
@@ -167,7 +173,9 @@
167173
168174
/**
169175
* trim the values array based on whether the property
170-
* for 'range' is 'min', 'max', or truthy.
176+
* for 'range' is 'min', 'max', or truthy. This is because we
177+
* do not want more than one handle for a min/max range, and we do
178+
* not want more than two handles for a true range.
171179
* @param {array} values the input values for the rangeSlider
172180
* @return {array} the range array for creating a rangeSlider
173181
**/
@@ -352,8 +360,10 @@
352360
* @param {event} e the event from browser
353361
**/
354362
function sliderFocusHandle(e) {
355-
activeHandle = index(e.target);
356-
focus = true;
363+
if ( !disabled ) {
364+
activeHandle = index(e.target);
365+
focus = true;
366+
}
357367
}
358368
359369
/**
@@ -362,37 +372,39 @@
362372
* @param {event} e the event from browser
363373
**/
364374
function sliderKeydown(e) {
365-
const handle = index(e.target);
366-
let jump = e.ctrlKey || e.metaKey || e.shiftKey ? step * 10 : step;
367-
let prevent = false;
368-
369-
switch (e.key) {
370-
case "PageDown":
371-
jump *= 10;
372-
case "ArrowRight":
373-
case "ArrowUp":
374-
moveHandle(handle, values[handle] + jump);
375-
prevent = true;
376-
break;
377-
case "PageUp":
378-
jump *= 10;
379-
case "ArrowLeft":
380-
case "ArrowDown":
381-
moveHandle(handle, values[handle] - jump);
382-
prevent = true;
383-
break;
384-
case "Home":
385-
moveHandle(handle, min);
386-
prevent = true;
387-
break;
388-
case "End":
389-
moveHandle(handle, max);
390-
prevent = true;
391-
break;
392-
}
393-
if (prevent) {
394-
e.preventDefault();
395-
e.stopPropagation();
375+
if ( !disabled ) {
376+
const handle = index(e.target);
377+
let jump = e.ctrlKey || e.metaKey || e.shiftKey ? step * 10 : step;
378+
let prevent = false;
379+
380+
switch (e.key) {
381+
case "PageDown":
382+
jump *= 10;
383+
case "ArrowRight":
384+
case "ArrowUp":
385+
moveHandle(handle, values[handle] + jump);
386+
prevent = true;
387+
break;
388+
case "PageUp":
389+
jump *= 10;
390+
case "ArrowLeft":
391+
case "ArrowDown":
392+
moveHandle(handle, values[handle] - jump);
393+
prevent = true;
394+
break;
395+
case "Home":
396+
moveHandle(handle, min);
397+
prevent = true;
398+
break;
399+
case "End":
400+
moveHandle(handle, max);
401+
prevent = true;
402+
break;
403+
}
404+
if (prevent) {
405+
e.preventDefault();
406+
e.stopPropagation();
407+
}
396408
}
397409
}
398410
@@ -402,21 +414,23 @@
402414
* @param {event} e the event from browser
403415
**/
404416
function sliderInteractStart(e) {
405-
const clientPos = normalisedClient(e);
406-
// set the closest handle as active
407-
focus = true;
408-
handleActivated = true;
409-
handlePressed = true;
410-
activeHandle = getClosestHandle(clientPos);
411-
412-
// fire the start event
413-
startValue = previousValue = alignValueToStep(values[activeHandle]);
414-
eStart();
415-
416-
// for touch devices we want the handle to instantly
417-
// move to the position touched for more responsive feeling
418-
if (e.type === "touchstart") {
419-
handleInteract(clientPos);
417+
if ( !disabled ) {
418+
const clientPos = normalisedClient(e);
419+
// set the closest handle as active
420+
focus = true;
421+
handleActivated = true;
422+
handlePressed = true;
423+
activeHandle = getClosestHandle(clientPos);
424+
425+
// fire the start event
426+
startValue = previousValue = alignValueToStep(values[activeHandle]);
427+
eStart();
428+
429+
// for touch devices we want the handle to instantly
430+
// move to the position touched for more responsive feeling
431+
if (e.type === "touchstart") {
432+
handleInteract(clientPos);
433+
}
420434
}
421435
}
422436
@@ -451,8 +465,10 @@
451465
* @param {event} e the event from browser
452466
**/
453467
function bodyInteract(e) {
454-
if (handleActivated) {
455-
handleInteract(normalisedClient(e));
468+
if ( !disabled ) {
469+
if (handleActivated) {
470+
handleInteract(normalisedClient(e));
471+
}
456472
}
457473
}
458474
@@ -463,20 +479,22 @@
463479
* @param {event} e the event from browser
464480
**/
465481
function bodyMouseUp(e) {
466-
const el = e.target;
467-
// this only works if a handle is active, which can
468-
// only happen if there was sliderInteractStart triggered
469-
// on the slider, already
470-
if (handleActivated) {
471-
if (el === slider || slider.contains(el)) {
472-
focus = true;
473-
if (!targetIsHandle(el)) {
474-
handleInteract(normalisedClient(e));
482+
if ( !disabled ) {
483+
const el = e.target;
484+
// this only works if a handle is active, which can
485+
// only happen if there was sliderInteractStart triggered
486+
// on the slider, already
487+
if (handleActivated) {
488+
if (el === slider || slider.contains(el)) {
489+
focus = true;
490+
if (!targetIsHandle(el)) {
491+
handleInteract(normalisedClient(e));
492+
}
475493
}
494+
// fire the stop event for mouse device
495+
// when the body is triggered with an active handle
496+
eStop();
476497
}
477-
// fire the stop event for mouse device
478-
// when the body is triggered with an active handle
479-
eStop();
480498
}
481499
handleActivated = false;
482500
handlePressed = false;
@@ -493,21 +511,23 @@
493511
}
494512
495513
function bodyKeyDown(e) {
496-
if (e.target === slider || slider.contains(e.target)) {
497-
keyboardActive = true;
514+
if ( !disabled ) {
515+
if (e.target === slider || slider.contains(e.target)) {
516+
keyboardActive = true;
517+
}
498518
}
499519
}
500520
501521
function eStart() {
502-
dispatch("start", {
522+
!disabled && dispatch("start", {
503523
activeHandle,
504524
value: startValue,
505525
values: values.map((v) => alignValueToStep(v)),
506526
});
507527
}
508528
509529
function eStop() {
510-
dispatch("stop", {
530+
!disabled && dispatch("stop", {
511531
activeHandle,
512532
startValue: startValue,
513533
value: values[activeHandle],
@@ -516,7 +536,7 @@
516536
}
517537
518538
function eChange() {
519-
dispatch("change", {
539+
!disabled && dispatch("change", {
520540
activeHandle,
521541
startValue: startValue,
522542
previousValue:
@@ -545,6 +565,7 @@
545565
border-radius: 100px;
546566
height: 0.5em;
547567
margin: 1em;
568+
transition: opacity 0.2s ease;
548569
}
549570
:global(.rangeSlider, .rangeSlider *) {
550571
user-select: none;
@@ -695,13 +716,21 @@
695716
background-color: #4a40d4;
696717
background-color: var(--float);
697718
}
719+
:global(.rangeSlider.disabled ) {
720+
opacity: 0.5;
721+
}
722+
:global(.rangeSlider.disabled .rangeNub) {
723+
background-color: #d7dada;
724+
background-color: var(--slider);
725+
}
698726
</style>
699727

700728
<div
701729
{id}
702730
bind:this={slider}
703731
class="rangeSlider"
704732
class:range
733+
class:disabled
705734
class:vertical
706735
class:focus
707736
class:min={range === 'min'}
@@ -716,9 +745,8 @@
716745
{#each values as value, index}
717746
<span
718747
role="slider"
719-
tabindex="0"
720748
class="rangeHandle"
721-
class:hoverable={hover}
749+
class:hoverable={hover && !disabled}
722750
class:active={focus && activeHandle === index}
723751
class:press={handlePressed && activeHandle === index}
724752
on:blur={sliderBlurHandle}
@@ -729,7 +757,11 @@
729757
aria-valuemax={range === true && index === 0 ? values[1] : max}
730758
aria-valuenow={value}
731759
aria-valuetext="{prefix}{handleFormatter(value)}{suffix}"
732-
aria-orientation={vertical ? 'vertical' : 'horizontal'}>
760+
aria-orientation={vertical ? 'vertical' : 'horizontal'}
761+
aria-disabled={disabled}
762+
{disabled}
763+
tabindex="{ disabled ? -1 : 0 }"
764+
>
733765
<span class="rangeNub" />
734766
{#if float}
735767
<span class="rangeFloat">{prefix}{handleFormatter(value)}{suffix}</span>
@@ -759,6 +791,7 @@
759791
{suffix}
760792
{formatter}
761793
{focus}
794+
{disabled}
762795
{percentOf} />
763796
{/if}
764797
</div>

0 commit comments

Comments
 (0)