UNPKG

react-native-surveys

Version:

Build your own forms, surveys and polls for your React Native apps.

212 lines (199 loc) 4.8 kB
import React, { memo, useMemo, useEffect, useState } from "react"; import { Animated, Dimensions, Easing, Platform, StyleSheet, Text, TouchableOpacity, View } from "react-native"; import { getStatusBarHeight } from "../../utils/status-bar-height"; import { CloseIcon } from "../../assets/icons"; import { colors } from "../../theme"; const { width, height } = Dimensions.get("window"); const HEADER_HEIGHT = 49; const NativeFormsWebView = ({ onClose, onSend, children, extraData, name, email }) => { const opacityAnimation = useMemo(() => new Animated.Value(0), []); const translateAnimation = useMemo(() => new Animated.Value(height), []); const [formTitle, setFormTitle] = useState(""); const statusBarHeight = getStatusBarHeight(); let source = Object.assign({}, children.props.source); if (source.uri) { let formAddress = source.uri; if (name) { formAddress += formAddress.indexOf("?") > -1 ? `&name=${name}` : `?name=${name}`; } if (email) { formAddress += formAddress.indexOf("?") > -1 ? `&email=${email}` : `?name=${email}`; } if (extraData && typeof extraData === "object") { try { formAddress += formAddress.indexOf("?") > -1 ? `&extraData=${JSON.stringify(extraData)}` : `?name=${JSON.stringify(extraData)}`; } catch (e) { console.error("Invalid extraData prop.", e); } } source.uri = formAddress; } useEffect(() => { Animated.parallel([ Animated.timing(opacityAnimation, { toValue: 1, duration: 250, easing: Easing.out(Easing.quad) }), Animated.timing(translateAnimation, { toValue: 0, duration: 500, easing: Easing.out(Easing.quad) }) ]).start(); }, [opacityAnimation, translateAnimation]); const containerHeight = { height: height - HEADER_HEIGHT - statusBarHeight }; const headerPadding = { marginTop: statusBarHeight }; const onMessage = ({ nativeEvent: state }) => { if (state.data) { const event = JSON.parse(state.data); if (event.nf_event && event.nf_event.event === "form_fetched") { const form = JSON.parse(event.nf_event.form) || {}; setFormTitle(form.label); } if (event.nf_event && event.nf_event.event === "form_send") { const form = JSON.parse(event.nf_event.form) || {}; onSend(form); } } }; return React.createElement( Animated.View, { style: [ { opacity: opacityAnimation, transform: [ { translateY: translateAnimation } ] }, styles.overlay ] }, React.createElement( View, { style: [styles.header, headerPadding] }, React.createElement( Text, { style: styles.name, numberOfLines: 1, ellipsizeMode: "head" }, formTitle ), React.createElement( TouchableOpacity, { onPress: onClose, style: styles.closeButton }, React.createElement(CloseIcon, { size: 22 }) ) ), React.createElement( View, { style: [containerHeight, styles.container] }, children ? React.cloneElement(children, { onMessage, source, style: { flex: 1, width: width } }) : React.createElement( Text, null, "You forgot to provide WebView component." ) ) ); }; const styles = StyleSheet.create({ overlay: { position: Platform.OS === "web" ? "fixed" : "absolute", overflow: "scroll", height, width, top: 0, left: 0, right: 0, bottom: 0, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "flex-start", backgroundColor: "white", zIndex: 900000, elevation: 9 }, container: { backgroundColor: "white", alignItems: "center", justifyContent: "center", width: "100%" }, header: { display: "flex", width: "100%", flexDirection: "row", alignItems: "center", paddingHorizontal: 16, paddingVertical: 13, borderBottomColor: colors.border, borderBottomWidth: 1, borderStyle: "solid", zIndex: 9 }, name: { color: colors.primary, fontWeight: "bold", fontSize: 15, flex: 1 }, closeButton: { display: "flex", alignItems: "center", justifyContent: "center" } }); NativeFormsWebView.defaultProps = { onClose: () => {}, onSend: () => {} }; export default memo(NativeFormsWebView);