1import { H3 } from '@expo/html-elements';
2import * as React from 'react';
3import {
4  Platform,
5  ScrollView,
6  StyleSheet,
7  Image,
8  Text,
9  TouchableOpacity,
10  useWindowDimensions,
11  View,
12  RefreshControl,
13} from 'react-native';
14
15import Button from '../components/Button';
16import TitleSwitch from '../components/TitledSwitch';
17
18export default function ScrollViewScreen() {
19  const [isHorizontal, setHorizontal] = React.useState(true);
20  const [isEnabled, setEnabled] = React.useState(true);
21  const [isRefreshing, setRefreshing] = React.useState(false);
22  const [removeClippedSubviews, setRemoveClippedSubviews] = React.useState(false);
23  const scrollView = React.useRef<ScrollView>(null);
24  const axis = isHorizontal ? 'x' : 'y';
25  const { width } = useWindowDimensions();
26  const isMobile = width <= 640;
27  const imageStyle = {
28    width,
29    height: width / 2,
30  };
31
32  React.useEffect(() => {
33    let timeout: any;
34    if (isRefreshing) {
35      timeout = setTimeout(() => setRefreshing(false), 2000);
36    }
37    return () => {
38      clearTimeout(timeout);
39    };
40  }, [isRefreshing]);
41
42  const onRefresh = () => {
43    setRefreshing(true);
44  };
45  const items = React.useMemo(() => [...Array(20)].map((_, i) => `Item ${i}`), []);
46  return (
47    <ScrollView
48      style={{ flex: 1 }}
49      removeClippedSubviews={removeClippedSubviews}
50      keyboardShouldPersistTaps="handled"
51      keyboardDismissMode="on-drag"
52      refreshControl={<RefreshControl refreshing={isRefreshing} onRefresh={onRefresh} />}>
53      <View style={{ flex: 1, paddingHorizontal: isMobile ? 8 : 12 }}>
54        <TitleSwitch
55          title="Remove Clipped Subviews"
56          value={removeClippedSubviews}
57          setValue={setRemoveClippedSubviews}
58        />
59        <TitleSwitch title="Is Horizontal" value={isHorizontal} setValue={setHorizontal} />
60        <TitleSwitch title="Is Enabled" value={isEnabled} setValue={setEnabled} />
61        <ScrollView
62          onScroll={() => {
63            console.log('onScroll!');
64          }}
65          scrollEventThrottle={200}
66          scrollEnabled={isEnabled}
67          nestedScrollEnabled
68          horizontal={isHorizontal}
69          ref={scrollView}
70          style={styles.scrollView}>
71          {items.map((title: string, index: number) => (
72            <Item key={index}>{title}</Item>
73          ))}
74        </ScrollView>
75        <H3>Scroll to</H3>
76        <View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
77          <Button
78            title="Start"
79            style={{ flex: 1 }}
80            onPress={() => {
81              if (scrollView.current) {
82                scrollView.current.scrollTo({ [axis]: 0 });
83              }
84            }}
85          />
86          <Button
87            title="100px"
88            style={{ flex: 1 }}
89            onPress={() => {
90              if (scrollView.current) {
91                scrollView.current.scrollTo({ [axis]: 100 });
92              }
93            }}
94          />
95          <Button
96            title="End"
97            style={{ flex: 1 }}
98            onPress={() => {
99              if (scrollView.current) {
100                scrollView.current.scrollToEnd({ animated: true });
101              }
102            }}
103          />
104        </View>
105        <Button
106          title="Flash scroll indicators (web only)"
107          style={{ marginTop: 8 }}
108          disabled={Platform.OS !== 'web'}
109          onPress={() => {
110            if (scrollView.current) {
111              scrollView.current.flashScrollIndicators();
112            }
113          }}
114        />
115      </View>
116      <H3 style={{ marginHorizontal: 8 }}>Pagination</H3>
117
118      <ScrollView pagingEnabled directionalLockEnabled horizontal style={{ marginBottom: 8 }}>
119        <Image
120          source={require('../../assets/images/example1.jpg')}
121          style={imageStyle}
122          resizeMode="cover"
123        />
124        <Image
125          source={require('../../assets/images/example2.jpg')}
126          style={imageStyle}
127          resizeMode="cover"
128        />
129        <Image
130          source={require('../../assets/images/example3.jpg')}
131          style={imageStyle}
132          resizeMode="cover"
133        />
134      </ScrollView>
135    </ScrollView>
136  );
137}
138
139ScrollViewScreen.navigationOptions = {
140  title: 'ScrollView',
141};
142
143function Item(props: { children: React.ReactNode }) {
144  return (
145    <TouchableOpacity style={styles.item}>
146      <Text style={{ fontSize: 16 }}>{props.children}</Text>
147    </TouchableOpacity>
148  );
149}
150
151const styles = StyleSheet.create({
152  scrollView: {
153    backgroundColor: '#eeeeee',
154    height: 300,
155    flex: 1,
156    maxHeight: 300,
157  },
158  text: {
159    fontSize: 16,
160    fontWeight: 'bold',
161    paddingVertical: 8,
162  },
163  item: {
164    margin: 5,
165    padding: 8,
166    backgroundColor: '#cccccc',
167    borderRadius: 3,
168    minWidth: 96,
169    maxHeight: 96,
170  },
171});
172