-
Notifications
You must be signed in to change notification settings - Fork 1
/
ScrollViewOffset.tsx
47 lines (41 loc) · 1.58 KB
/
ScrollViewOffset.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// React-Native Android doesn't support contentOffset prop
// (see: https://github.com/facebook/react-native/issues/6849)
//
// So this component waits until after render, calls scrollTo(props.contentOffset), then makes itself visible
//
// Also adds a new prop — `startAtEnd (boolean, default: false)` — to set the initial scroll position to the end.
// Note: `startAtEnd` overrides the `contentOffset` prop.
//
// Supports all other props from the default ScrollView.
//
// Use this component in place of ScrollView for cross-compatibility.
//
import React, { MutableRefObject, ReactNode, useEffect, useRef, useState } from 'react'
import { InteractionManager, ScrollView, ScrollViewProps, View } from 'react-native'
function ScrollViewOffset(props: ScrollViewProps & { children: ReactNode; startAtEnd?: boolean }) {
const scrollViewRef: MutableRefObject<ScrollView | null> = useRef(null)
const [opacity, setOpacity] = useState(0)
// Scroll to end after init render
useEffect(() => {
InteractionManager.runAfterInteractions(() => {
if (props.startAtEnd) {
scrollViewRef.current!.scrollToEnd({ animated: false })
} else if (props.contentOffset) {
scrollViewRef.current!.scrollTo({
...props.contentOffset,
animated: false,
})
}
// Then make visible, to avoid jumping
setTimeout(() => {
setOpacity(1)
}, 1)
})
}, [props.contentOffset, props.startAtEnd])
return (
<View style={{ opacity }}>
<ScrollView {...props} ref={scrollViewRef} />
</View>
)
}
export default ScrollViewOffset