react-native-surveys
Version:
Build your own forms, surveys and polls for your React Native apps.
212 lines (199 loc) • 4.8 kB
JavaScript
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);