diff --git a/example-web/src/Examples.tsx b/example-web/src/Examples.tsx index 7a8ed1ce..f42fc890 100644 --- a/example-web/src/Examples.tsx +++ b/example-web/src/Examples.tsx @@ -1,6 +1,6 @@ import React, {useState} from 'react'; // @ts-ignore -import {Text, View, StyleSheet} from 'react-native'; +import {Text, View, StyleSheet, ScrollView} from 'react-native'; // @ts-ignore import Slider, {SliderProps} from '@react-native-community/slider'; @@ -201,4 +201,29 @@ export const examples: Props[] = [ return ; }, }, + { + title: 'Slider in horizontal scroll view', + render() { + return ( + + + + + Scroll right, then slide ➔ + + + + ); + }, + }, ]; diff --git a/package/src/RNCSliderNativeComponent.web.tsx b/package/src/RNCSliderNativeComponent.web.tsx index a454ef51..3f6ebe02 100644 --- a/package/src/RNCSliderNativeComponent.web.tsx +++ b/package/src/RNCSliderNativeComponent.web.tsx @@ -69,7 +69,7 @@ const RCTSliderWebComponent = React.forwardRef( const containerSize = React.useRef({width: 0, height: 0}); const containerPositionX = React.useRef(0); const containerRef = forwardedRef || React.createRef(); - const hasBeenResized = React.useRef(false); + const containerPositionInvalidated = React.useRef(false); const [value, setValue] = React.useState(initialValue || minimumValue); const lastInitialValue = React.useRef(); @@ -145,18 +145,36 @@ const RCTSliderWebComponent = React.forwardRef( } }, [initialValue, updateValue, animatedValue]); - const onResize = () => { - hasBeenResized.current = true; - }; React.useEffect(() => { + const invalidateContainerPosition = () => { + containerPositionInvalidated.current = true; + }; + const onDocumentScroll = (e: Event) => { + if ( + containerRef.current && + // Skip the `contains` check if already invalidated + !containerPositionInvalidated.current && + // @ts-ignore + e.target.contains(containerRef.current) + ) { + invalidateContainerPosition(); + } + }; //@ts-ignore - window.addEventListener('resize', onResize); + window.addEventListener('resize', invalidateContainerPosition); + //@ts-ignore + document.addEventListener('scroll', onDocumentScroll, {capture: true}); return () => { //@ts-ignore - window.removeEventListener('resize', onResize); + window.removeEventListener('resize', invalidateContainerPosition); + + //@ts-ignore + document.removeEventListener('scroll', onDocumentScroll, { + capture: true, + }); }; - }, []); + }, [containerRef]); const containerStyle = StyleSheet.compose( { @@ -221,8 +239,8 @@ const RCTSliderWebComponent = React.forwardRef( const getValueFromNativeEvent = (pageX: number) => { const {width = 1} = containerSize.current; - if (hasBeenResized.current) { - hasBeenResized.current = false; + if (containerPositionInvalidated.current) { + containerPositionInvalidated.current = false; updateContainerPositionX(); } const containerX = containerPositionX.current;