Skip to content

Commit

Permalink
fix(web): invalidate position on ancestor scroll (#472)
Browse files Browse the repository at this point in the history
* fix(web): invalidate position on ancestor scroll

Fixes #471. Added a test case to `example-web`.

* Use const isAlreadyInvalidated instead of a comment

Co-authored-by: Bartosz Klonowski <70535775+BartoszKlonowski@users.noreply.github.com>
  • Loading branch information
motiz88 and BartoszKlonowski committed Jan 13, 2023
1 parent 297eee6 commit ccb2d42
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 10 deletions.
27 changes: 26 additions & 1 deletion example-web/src/Examples.tsx
Original file line number Diff line number Diff line change
@@ -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';

Expand Down Expand Up @@ -201,4 +201,29 @@ export const examples: Props[] = [
return <SliderExample disabled value={0.6} />;
},
},
{
title: 'Slider in horizontal scroll view',
render() {
return (
<ScrollView
horizontal
style={{
paddingVertical: 50,
borderStyle: 'dotted',
borderWidth: 1,
flexDirection: 'row',
width: 300,
}}
contentContainerStyle={{ overflowX: 'scroll' }}
>
<View style={{ width: 400, paddingLeft: 100 }}>
<SliderExample maximumValue={100} />
<Text style={{ textAlign: 'right', width: 200 }}>
Scroll right, then slide ➔
</Text>
</View>
</ScrollView>
);
},
},
];
36 changes: 27 additions & 9 deletions package/src/RNCSliderNativeComponent.web.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,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<number>();
const animationValues = React.useRef<AnimationValues>({
Expand Down Expand Up @@ -166,18 +166,36 @@ const RCTSliderWebComponent = React.forwardRef(
}
}, [initialValue, updateValue, animationValues]);

const onResize = () => {
hasBeenResized.current = true;
};
React.useEffect(() => {
const invalidateContainerPosition = () => {
containerPositionInvalidated.current = true;
};
const onDocumentScroll = (e: Event) => {
const isAlreadyInvalidated = !containerPositionInvalidated.current;
if (
isAlreadyInvalidated &&
containerRef.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(
{
Expand Down Expand Up @@ -242,8 +260,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;
Expand Down

0 comments on commit ccb2d42

Please sign in to comment.