|
13 | 13 | export let vertical = false; |
14 | 14 | export let float = false; |
15 | 15 | export let hover = true; |
| 16 | + export let disabled = false; |
16 | 17 |
|
17 | 18 | // range pips / values props |
18 | 19 | export let pips = false; |
|
359 | 360 | * @param {event} e the event from browser |
360 | 361 | **/ |
361 | 362 | function sliderFocusHandle(e) { |
362 | | - activeHandle = index(e.target); |
363 | | - focus = true; |
| 363 | + if ( !disabled ) { |
| 364 | + activeHandle = index(e.target); |
| 365 | + focus = true; |
| 366 | + } |
364 | 367 | } |
365 | 368 |
|
366 | 369 | /** |
|
369 | 372 | * @param {event} e the event from browser |
370 | 373 | **/ |
371 | 374 | function sliderKeydown(e) { |
372 | | - const handle = index(e.target); |
373 | | - let jump = e.ctrlKey || e.metaKey || e.shiftKey ? step * 10 : step; |
374 | | - let prevent = false; |
375 | | -
|
376 | | - switch (e.key) { |
377 | | - case "PageDown": |
378 | | - jump *= 10; |
379 | | - case "ArrowRight": |
380 | | - case "ArrowUp": |
381 | | - moveHandle(handle, values[handle] + jump); |
382 | | - prevent = true; |
383 | | - break; |
384 | | - case "PageUp": |
385 | | - jump *= 10; |
386 | | - case "ArrowLeft": |
387 | | - case "ArrowDown": |
388 | | - moveHandle(handle, values[handle] - jump); |
389 | | - prevent = true; |
390 | | - break; |
391 | | - case "Home": |
392 | | - moveHandle(handle, min); |
393 | | - prevent = true; |
394 | | - break; |
395 | | - case "End": |
396 | | - moveHandle(handle, max); |
397 | | - prevent = true; |
398 | | - break; |
399 | | - } |
400 | | - if (prevent) { |
401 | | - e.preventDefault(); |
402 | | - 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 | + } |
403 | 408 | } |
404 | 409 | } |
405 | 410 |
|
|
409 | 414 | * @param {event} e the event from browser |
410 | 415 | **/ |
411 | 416 | function sliderInteractStart(e) { |
412 | | - const clientPos = normalisedClient(e); |
413 | | - // set the closest handle as active |
414 | | - focus = true; |
415 | | - handleActivated = true; |
416 | | - handlePressed = true; |
417 | | - activeHandle = getClosestHandle(clientPos); |
418 | | -
|
419 | | - // fire the start event |
420 | | - startValue = previousValue = alignValueToStep(values[activeHandle]); |
421 | | - eStart(); |
422 | | -
|
423 | | - // for touch devices we want the handle to instantly |
424 | | - // move to the position touched for more responsive feeling |
425 | | - if (e.type === "touchstart") { |
426 | | - 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 | + } |
427 | 434 | } |
428 | 435 | } |
429 | 436 |
|
|
458 | 465 | * @param {event} e the event from browser |
459 | 466 | **/ |
460 | 467 | function bodyInteract(e) { |
461 | | - if (handleActivated) { |
462 | | - handleInteract(normalisedClient(e)); |
| 468 | + if ( !disabled ) { |
| 469 | + if (handleActivated) { |
| 470 | + handleInteract(normalisedClient(e)); |
| 471 | + } |
463 | 472 | } |
464 | 473 | } |
465 | 474 |
|
|
470 | 479 | * @param {event} e the event from browser |
471 | 480 | **/ |
472 | 481 | function bodyMouseUp(e) { |
473 | | - const el = e.target; |
474 | | - // this only works if a handle is active, which can |
475 | | - // only happen if there was sliderInteractStart triggered |
476 | | - // on the slider, already |
477 | | - if (handleActivated) { |
478 | | - if (el === slider || slider.contains(el)) { |
479 | | - focus = true; |
480 | | - if (!targetIsHandle(el)) { |
481 | | - 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 | + } |
482 | 493 | } |
| 494 | + // fire the stop event for mouse device |
| 495 | + // when the body is triggered with an active handle |
| 496 | + eStop(); |
483 | 497 | } |
484 | | - // fire the stop event for mouse device |
485 | | - // when the body is triggered with an active handle |
486 | | - eStop(); |
487 | 498 | } |
488 | 499 | handleActivated = false; |
489 | 500 | handlePressed = false; |
|
500 | 511 | } |
501 | 512 |
|
502 | 513 | function bodyKeyDown(e) { |
503 | | - if (e.target === slider || slider.contains(e.target)) { |
504 | | - keyboardActive = true; |
| 514 | + if ( !disabled ) { |
| 515 | + if (e.target === slider || slider.contains(e.target)) { |
| 516 | + keyboardActive = true; |
| 517 | + } |
505 | 518 | } |
506 | 519 | } |
507 | 520 |
|
508 | 521 | function eStart() { |
509 | | - dispatch("start", { |
| 522 | + !disabled && dispatch("start", { |
510 | 523 | activeHandle, |
511 | 524 | value: startValue, |
512 | 525 | values: values.map((v) => alignValueToStep(v)), |
513 | 526 | }); |
514 | 527 | } |
515 | 528 |
|
516 | 529 | function eStop() { |
517 | | - dispatch("stop", { |
| 530 | + !disabled && dispatch("stop", { |
518 | 531 | activeHandle, |
519 | 532 | startValue: startValue, |
520 | 533 | value: values[activeHandle], |
|
523 | 536 | } |
524 | 537 |
|
525 | 538 | function eChange() { |
526 | | - dispatch("change", { |
| 539 | + !disabled && dispatch("change", { |
527 | 540 | activeHandle, |
528 | 541 | startValue: startValue, |
529 | 542 | previousValue: |
|
552 | 565 | border-radius: 100px; |
553 | 566 | height: 0.5em; |
554 | 567 | margin: 1em; |
| 568 | + transition: opacity 0.2s ease; |
555 | 569 | } |
556 | 570 | :global(.rangeSlider, .rangeSlider *) { |
557 | 571 | user-select: none; |
|
702 | 716 | background-color: #4a40d4; |
703 | 717 | background-color: var(--float); |
704 | 718 | } |
| 719 | + :global(.rangeSlider.disabled ) { |
| 720 | + opacity: 0.5; |
| 721 | + } |
| 722 | + :global(.rangeSlider.disabled .rangeNub) { |
| 723 | + background-color: #d7dada; |
| 724 | + background-color: var(--slider); |
| 725 | + } |
705 | 726 | </style> |
706 | 727 |
|
707 | 728 | <div |
708 | 729 | {id} |
709 | 730 | bind:this={slider} |
710 | 731 | class="rangeSlider" |
711 | 732 | class:range |
| 733 | + class:disabled |
712 | 734 | class:vertical |
713 | 735 | class:focus |
714 | 736 | class:min={range === 'min'} |
|
723 | 745 | {#each values as value, index} |
724 | 746 | <span |
725 | 747 | role="slider" |
726 | | - tabindex="0" |
727 | 748 | class="rangeHandle" |
728 | | - class:hoverable={hover} |
| 749 | + class:hoverable={hover && !disabled} |
729 | 750 | class:active={focus && activeHandle === index} |
730 | 751 | class:press={handlePressed && activeHandle === index} |
731 | 752 | on:blur={sliderBlurHandle} |
|
736 | 757 | aria-valuemax={range === true && index === 0 ? values[1] : max} |
737 | 758 | aria-valuenow={value} |
738 | 759 | aria-valuetext="{prefix}{handleFormatter(value)}{suffix}" |
739 | | - aria-orientation={vertical ? 'vertical' : 'horizontal'}> |
| 760 | + aria-orientation={vertical ? 'vertical' : 'horizontal'} |
| 761 | + aria-disabled={disabled} |
| 762 | + {disabled} |
| 763 | + tabindex="{ disabled ? -1 : 0 }" |
| 764 | + > |
740 | 765 | <span class="rangeNub" /> |
741 | 766 | {#if float} |
742 | 767 | <span class="rangeFloat">{prefix}{handleFormatter(value)}{suffix}</span> |
|
766 | 791 | {suffix} |
767 | 792 | {formatter} |
768 | 793 | {focus} |
| 794 | + {disabled} |
769 | 795 | {percentOf} /> |
770 | 796 | {/if} |
771 | 797 | </div> |
|
0 commit comments