slider refactored with liverefs

This commit is contained in:
nklhrstv 2020-03-06 14:43:00 +02:00
parent d0e8f8c0ab
commit 8412c22e64
2 changed files with 30 additions and 24 deletions

View file

@ -7,9 +7,9 @@ const useLiveRef = require('stremio/common/useLiveRef');
const styles = require('./styles');
const Slider = ({ className, value, minimumValue, maximumValue, onSlide, onComplete }) => {
minimumValue = minimumValue !== null && !isNaN(minimumValue) && isFinite(minimumValue) ? minimumValue : 0;
maximumValue = maximumValue !== null && !isNaN(maximumValue) && isFinite(maximumValue) ? maximumValue : 100;
value = value !== null && !isNaN(value) && value >= minimumValue && value <= maximumValue ? value : 0;
const minimumValueRef = useLiveRef(minimumValue !== null && !isNaN(minimumValue) ? minimumValue : 0, [minimumValue]);
const maximumValueRef = useLiveRef(maximumValue !== null && !isNaN(maximumValue) ? maximumValue : 100, [maximumValue]);
const valueRef = useLiveRef(value !== null && !isNaN(value) ? Math.min(maximumValueRef.current, Math.max(minimumValueRef.current, value)) : 0, [minimumValue, maximumValue, value]);
const onSlideRef = useLiveRef(onSlide, [onSlide]);
const onCompleteRef = useLiveRef(onComplete, [onComplete]);
const sliderContainerRef = React.useRef(null);
@ -20,11 +20,9 @@ const Slider = ({ className, value, minimumValue, maximumValue, onSlide, onCompl
return 0;
}
const minimumValue = parseInt(sliderContainerRef.current.getAttribute('aria-valuemin'));
const maximumValue = parseInt(sliderContainerRef.current.getAttribute('aria-valuemax'));
const { x: sliderX, width: sliderWidth } = sliderContainerRef.current.getBoundingClientRect();
const thumbStart = Math.min(Math.max(mouseX - sliderX, 0), sliderWidth);
const value = (thumbStart / sliderWidth) * (maximumValue - minimumValue) + minimumValue;
const value = (thumbStart / sliderWidth) * (maximumValueRef.current - minimumValueRef.current) + minimumValueRef.current;
return value;
}, []);
const retainThumb = React.useCallback(() => {
@ -42,17 +40,16 @@ const Slider = ({ className, value, minimumValue, maximumValue, onSlide, onCompl
const classIndex = classList.indexOf(styles['active-slider-within']);
if (classIndex !== -1) {
classList.splice(classIndex, 1);
document.documentElement.className = classnames(classList);
}
document.documentElement.className = classnames(classList);
}, []);
const onBlur = React.useCallback(() => {
const value = parseInt(sliderContainerRef.current.getAttribute('aria-valuenow'));
if (typeof onSlideRef.current === 'function') {
onSlideRef.current(value);
onSlideRef.current(valueRef.current);
}
if (typeof onCompleteRef.current === 'function') {
onCompleteRef.current(value);
onCompleteRef.current(valueRef.current);
}
releaseThumb();
@ -85,22 +82,19 @@ const Slider = ({ className, value, minimumValue, maximumValue, onSlide, onCompl
retainThumb();
}, []);
React.useEffect(() => {
React.useLayoutEffect(() => {
if (!routeFocused) {
releaseThumb();
}
}, [routeFocused]);
React.useEffect(() => {
React.useLayoutEffect(() => {
return () => {
releaseThumb();
};
}, []);
const thumbPosition = React.useMemo(() => {
return Math.max(0, Math.min(1, (value - minimumValue) / (maximumValue - minimumValue)));
}, [value, minimumValue, maximumValue]);
const thumbPosition = Math.max(0, Math.min(1, (valueRef.current - minimumValueRef.current) / (maximumValueRef.current - minimumValueRef.current)));
return (
<div ref={sliderContainerRef} className={classnames(className, styles['slider-container'])} aria-valuenow={value} aria-valuemin={minimumValue} aria-valuemax={maximumValue} onMouseDown={onMouseDown}>
<div ref={sliderContainerRef} className={classnames(className, styles['slider-container'])} onMouseDown={onMouseDown}>
<div className={styles['layer']}>
<div className={styles['track']} />
</div>

View file

@ -1,3 +1,5 @@
@import (reference) '~stremio-colors/dist/less/stremio-colors.less';
html.active-slider-within {
cursor: grabbing;
@ -12,15 +14,25 @@ html.active-slider-within {
overflow: visible;
cursor: pointer;
&:hover, &:global(.active) {
.track-before {
background-color: @color-primary-light5;
}
}
&:global(.disabled) {
pointer-events: none;
.track, .track-before {
background-color: var(--color-surfacedark);
.track {
background-color: @color-surface-dark5;
}
.track-before {
background-color: @color-surface;
}
.thumb {
fill: var(--color-surfacedark);
fill: @color-surface;
}
}
@ -40,13 +52,13 @@ html.active-slider-within {
.track {
flex: 1;
height: var(--track-size, 0.5rem);
background-color: var(--color-backgroundlighter);
background-color: @color-primary-dark3;
}
.track-before {
flex: none;
height: var(--track-size, 0.5rem);
background-color: var(--color-primary);
background-color: @color-primary-light3;
}
.thumb {
@ -54,6 +66,6 @@ html.active-slider-within {
width: var(--thumb-size, 1.5rem);
height: var(--thumb-size, 1.5rem);
transform: translateX(-50%);
fill: var(--color-surfacelighter);
fill: @color-surface-light5;
}
}