|
12 | 12 | export let values = [(max + min) / 2]; |
13 | 13 | export let vertical = false; |
14 | 14 | export let float = false; |
| 15 | + export let reversed = false; |
15 | 16 | export let hoverable = true; |
16 | 17 | export let disabled = false; |
17 | 18 |
|
|
142 | 143 | return parseFloat(aligned.toFixed(precision)); |
143 | 144 | }; |
144 | 145 |
|
| 146 | + /** |
| 147 | + * the orientation of the handles/pips based on the |
| 148 | + * input values of vertical and reversed |
| 149 | + **/ |
| 150 | + $: orientationStart = vertical ? reversed ? 'top' : 'bottom' : reversed ? 'right' : 'left'; |
| 151 | + $: orientationEnd = vertical ? reversed ? 'bottom' : 'top' : reversed ? 'left' : 'right'; |
| 152 | +
|
145 | 153 | /** |
146 | 154 | * helper func to get the index of an element in it's DOM container |
147 | 155 | * @param {object} el dom object reference we want the index of |
|
219 | 227 | // of the slider, as it may have changed size |
220 | 228 | const dims = getSliderDimensions(); |
221 | 229 | // calculate the interaction position, percent and value |
222 | | - let hPos = 0; |
223 | | - let hPercent = 0; |
224 | | - let hVal = 0; |
| 230 | + let handlePos = 0; |
| 231 | + let handlePercent = 0; |
| 232 | + let handleVal = 0; |
225 | 233 | if (vertical) { |
226 | | - hPos = clientPos.clientY - dims.top; |
227 | | - hPercent = (hPos / dims.height) * 100; |
228 | | - hVal = ((max - min) / 100) * hPercent + min; |
| 234 | + handlePos = clientPos.clientY - dims.top; |
| 235 | + handlePercent = (handlePos / dims.height) * 100; |
| 236 | + handlePercent = reversed ? handlePercent : 100 - handlePercent; |
229 | 237 | } else { |
230 | | - hPos = clientPos.clientX - dims.left; |
231 | | - hPercent = (hPos / dims.width) * 100; |
232 | | - hVal = ((max - min) / 100) * hPercent + min; |
| 238 | + handlePos = clientPos.clientX - dims.left; |
| 239 | + handlePercent = (handlePos / dims.width) * 100; |
| 240 | + handlePercent = reversed ? 100 - handlePercent : handlePercent; |
233 | 241 | } |
| 242 | + handleVal = ((max - min) / 100) * handlePercent + min; |
234 | 243 |
|
235 | 244 | let closest; |
236 | 245 |
|
237 | 246 | // if we have a range, and the handles are at the same |
238 | 247 | // position, we want a simple check if the interaction |
239 | 248 | // value is greater than return the second handle |
240 | 249 | if (range === true && values[0] === values[1]) { |
241 | | - if (hVal > values[1]) { |
| 250 | + if (handleVal > values[1]) { |
242 | 251 | return 1; |
243 | 252 | } else { |
244 | 253 | return 0; |
|
248 | 257 | // to the interaction value |
249 | 258 | } else { |
250 | 259 | closest = values.indexOf( |
251 | | - [...values].sort((a, b) => Math.abs(hVal - a) - Math.abs(hVal - b))[0] |
| 260 | + [...values].sort((a, b) => Math.abs(handleVal - a) - Math.abs(handleVal - b))[0] |
252 | 261 | ); |
253 | 262 | } |
254 | 263 | return closest; |
|
272 | 281 | if (vertical) { |
273 | 282 | handlePos = clientPos.clientY - dims.top; |
274 | 283 | handlePercent = (handlePos / dims.height) * 100; |
275 | | - handleVal = ((max - min) / 100) * handlePercent + min; |
| 284 | + handlePercent = reversed ? handlePercent : 100 - handlePercent; |
276 | 285 | } else { |
277 | 286 | handlePos = clientPos.clientX - dims.left; |
278 | 287 | handlePercent = (handlePos / dims.width) * 100; |
279 | | - handleVal = ((max - min) / 100) * handlePercent + min; |
| 288 | + handlePercent = reversed ? 100 - handlePercent : handlePercent; |
280 | 289 | } |
| 290 | + handleVal = ((max - min) / 100) * handlePercent + min; |
281 | 291 | // move handle to the value |
282 | 292 | moveHandle(activeHandle, handleVal); |
283 | 293 | } |
|
616 | 626 | height: 1.4em; |
617 | 627 | width: 1.4em; |
618 | 628 | top: 0.25em; |
619 | | - left: 0.25em; |
| 629 | + bottom: auto; |
620 | 630 | transform: translateY(-50%) translateX(-50%); |
621 | 631 | z-index: 2; |
622 | 632 | } |
| 633 | + :global(.rangeSlider.reversed .rangeHandle) { |
| 634 | + transform: translateY(-50%) translateX(50%); |
| 635 | + } |
| 636 | + :global(.rangeSlider.vertical .rangeHandle) { |
| 637 | + left: 0.25em; |
| 638 | + top: auto; |
| 639 | + transform: translateY(50%) translateX(-50%); |
| 640 | + } |
| 641 | + :global(.rangeSlider.vertical.reversed .rangeHandle) { |
| 642 | + transform: translateY(-50%) translateX(-50%); |
| 643 | + } |
623 | 644 | :global(.rangeSlider .rangeNub), |
624 | 645 | :global(.rangeSlider .rangeHandle:before) { |
625 | 646 | position: absolute; |
|
629 | 650 | border-radius: 10em; |
630 | 651 | height: 100%; |
631 | 652 | width: 100%; |
632 | | - transition: all 0.2s ease; |
| 653 | + transition: box-shadow 0.2s ease; |
633 | 654 | } |
634 | 655 | :global(.rangeSlider .rangeHandle:before) { |
635 | 656 | content: ""; |
|
660 | 681 | :global(.rangeSlider.range .rangeHandle:nth-of-type(2) .rangeNub) { |
661 | 682 | transform: rotate(45deg); |
662 | 683 | } |
| 684 | + :global(.rangeSlider.range.reversed .rangeHandle:nth-of-type(1) .rangeNub) { |
| 685 | + transform: rotate(45deg); |
| 686 | + } |
| 687 | + :global(.rangeSlider.range.reversed .rangeHandle:nth-of-type(2) .rangeNub) { |
| 688 | + transform: rotate(-135deg); |
| 689 | + } |
663 | 690 | :global(.rangeSlider.range.vertical .rangeHandle:nth-of-type(1) .rangeNub) { |
664 | | - transform: rotate(-45deg); |
| 691 | + transform: rotate(135deg); |
665 | 692 | } |
666 | 693 | :global(.rangeSlider.range.vertical .rangeHandle:nth-of-type(2) .rangeNub) { |
| 694 | + transform: rotate(-45deg); |
| 695 | + } |
| 696 | + :global(.rangeSlider.range.vertical.reversed .rangeHandle:nth-of-type(1) .rangeNub) { |
| 697 | + transform: rotate(-45deg); |
| 698 | + } |
| 699 | + :global(.rangeSlider.range.vertical.reversed .rangeHandle:nth-of-type(2) .rangeNub) { |
667 | 700 | transform: rotate(135deg); |
668 | 701 | } |
669 | 702 | :global(.rangeSlider .rangeFloat) { |
|
753 | 786 | class:disabled |
754 | 787 | class:hoverable |
755 | 788 | class:vertical |
| 789 | + class:reversed |
756 | 790 | class:focus |
757 | 791 | class:min={range === 'min'} |
758 | 792 | class:max={range === 'max'} |
|
773 | 807 | on:blur={sliderBlurHandle} |
774 | 808 | on:focus={sliderFocusHandle} |
775 | 809 | on:keydown={sliderKeydown} |
776 | | - style="{vertical ? 'top' : 'left'}: {$springPositions[index]}%; z-index: {activeHandle === index ? 3 : 2};" |
| 810 | + style="{orientationStart}: {$springPositions[index]}%; z-index: {activeHandle === index ? 3 : 2};" |
777 | 811 | aria-valuemin={range === true && index === 1 ? values[0] : min} |
778 | 812 | aria-valuemax={range === true && index === 0 ? values[1] : max} |
779 | 813 | aria-valuenow={value} |
|
794 | 828 | {#if range} |
795 | 829 | <span |
796 | 830 | class="rangeBar" |
797 | | - style="{vertical ? 'top' : 'left'}: {rangeStart($springPositions)}%; {vertical ? 'bottom' : 'right'}: |
798 | | - {rangeEnd($springPositions)}%;" /> |
| 831 | + style="{orientationStart}: {rangeStart($springPositions)}%; |
| 832 | + {orientationEnd}: {rangeEnd($springPositions)}%;" /> |
799 | 833 | {/if} |
800 | 834 | {#if pips} |
801 | 835 | <RangePips |
|
805 | 839 | {step} |
806 | 840 | {range} |
807 | 841 | {vertical} |
| 842 | + {reversed} |
| 843 | + {orientationStart} |
| 844 | + {orientationEnd} |
808 | 845 | {hoverable} |
809 | 846 | {disabled} |
810 | 847 | {all} |
|
0 commit comments