1import { H2 } from '@expo/html-elements';
2import * as React from 'react';
3import { ActivityIndicator, StyleSheet, View, ScrollView } from 'react-native';
4import { WebView } from 'react-native-webview';
5
6interface MessageEvent {
7  nativeEvent: {
8    data: string;
9  };
10}
11
12const injectedJavaScript = `window.ReactNativeWebView.postMessage(JSON.stringify(window.location));`;
13
14export default function WebViewScreen() {
15  return (
16    <ScrollView style={{ flex: 1 }} contentContainerStyle={{ flex: 1 }}>
17      <WebViewRemoteSource />
18      <WebViewInlineSource />
19    </ScrollView>
20  );
21}
22
23WebViewScreen.navigationOptions = {
24  title: 'WebView',
25};
26
27function WebViewRemoteSource() {
28  const [isLoading, setLoading] = React.useState(true);
29
30  return (
31    <View style={styles.container}>
32      <H2 style={styles.header}>Remote Source</H2>
33      <WebView
34        source={{ uri: 'https://expo.dev/' }}
35        onLoadEnd={() => setLoading(false)}
36        onMessage={({ nativeEvent: { data } }: MessageEvent) => {
37          console.log('Got a message from WebView: ', JSON.parse(data));
38        }}
39        injectedJavaScript={injectedJavaScript}
40      />
41      {isLoading && <ActivityIndicator style={StyleSheet.absoluteFill} />}
42    </View>
43  );
44}
45
46function WebViewInlineSource() {
47  return (
48    <View style={styles.container}>
49      <H2 style={styles.header}>Inline Source</H2>
50      <WebView
51        style={{ width: '100%', height: 250 }}
52        source={{
53          html: `
54    <h2>You can always use a WebView if you need to!</h2>
55    <p>
56      <h4>But don't the other components above seem like better building blocks for most of your UI?</h4>
57      <input type="text" placeholder="Disagree? why?" />
58      <input type="submit">
59    </p>
60    <p>
61      <a href="https://expo.dev">expo.dev</a>
62    </p>
63  `,
64        }}
65      />
66    </View>
67  );
68}
69
70const styles = StyleSheet.create({
71  container: {
72    flex: 1,
73    minHeight: '50%',
74    overflow: 'hidden',
75  },
76  header: {
77    marginLeft: 8,
78  },
79});
80