import React, { useCallback, useEffect, useState } from "react"; import * as R from "ramda"; import { Appearance, Platform, StyleSheet, TextInput } from "react-native"; import { isFunction } from "@applicaster/zapp-react-native-utils/functionUtils"; import { isWeb } from "@applicaster/zapp-react-native-utils/reactUtils"; import { useIsRTL } from "@applicaster/zapp-react-native-utils/localizationUtils"; import { useAccessibilityManager } from "@applicaster/zapp-react-native-utils/appUtils/accessibilityManager/hooks"; type Props = Partial<{ style: any; onChangeText: any; onChange: any; secureTextEntry: boolean; onEndEditing: any; onBlur: any; onPress: any; additional: any; onKeyDown: any; value: any; }> & TextInput["props"]; function getInitialColorScheme() { try { return Appearance.getColorScheme(); } catch (e) { // skipping appearance on platforms which don't support it } } function TextInputTV(props: Props, ref) { const { onChangeText, onChange, style, secureTextEntry, onEndEditing, onBlur, onPress, additional, } = props; const [colorScheme, setColorScheme] = useState(getInitialColorScheme()); const isRTL = useIsRTL(); const accessibilityManager = useAccessibilityManager({}); const onColorChange = useCallback( ({ colorScheme: color }) => { if (color !== colorScheme) { setColorScheme(color); } }, [colorScheme] ); useEffect(() => { if (Appearance) { const subscription = Appearance.addChangeListener(onColorChange); return () => subscription.remove(); } }, [colorScheme]); const isWebPlatform = isWeb(); const onChangeTextPolyfill = (onChange) => R.compose(onChange, R.path(["target", "value"])); const getOnChangeText = () => { if (isWebPlatform) return undefined; return { onChangeText }; }; const getOnChange = () => { if (isWebPlatform) { if (onChange) return { onChange }; if (onChangeText) { return { onChange: onChangeTextPolyfill(onChangeText) }; } } return undefined; }; const getStyle = () => { if (!style) return undefined; if (isWebPlatform) { if (StyleSheet && isFunction(StyleSheet.flatten)) { const styles = StyleSheet.flatten(style); if (isRTL && !!styles.textAlign) { const textAlign = styles.textAlign === "center" ? styles.textAlign : styles.textAlign === "left" ? "right" : "left"; return { style: { ...styles, textAlign } }; } return { style: styles }; } } return { style }; }; const getSecureTextEntry = () => { if (typeof secureTextEntry === "undefined") return undefined; if (isWebPlatform) { if (secureTextEntry === true) { return { type: "password" }; } return undefined; } return { secureTextEntry }; }; const getOnEndEditing = () => { if (!onEndEditing) return undefined; if (isWebPlatform) { return { onBlur: onBlur || onEndEditing }; } return { onEndEditing }; }; const getOnPress = () => { if (!onPress) return undefined; if (isWebPlatform) { return { onClick: onPress }; } return { onPress }; }; const getProps = () => R.when( R.always(isWebPlatform), R.omit([ "onChangeText", "secureTextEntry", "onEndEditing", "onPress", "placeholderTextColor", ]) )(props); const getAccessibilityProps = () => { return { accessibilityProps: accessibilityManager.getInputAccessibilityProps("Search"), }; }; const inputProps = { ...getProps(), ...getStyle(), ...getOnChange(), ...getOnChangeText(), ...getSecureTextEntry(), ...getOnEndEditing(), ...getOnPress(), ...getAccessibilityProps(), }; if ( Platform.OS === "ios" && Platform.isTV && colorScheme && !inputProps.keyboardAppearance ) { inputProps.keyboardAppearance = colorScheme; } return isWebPlatform ? ( <> {additional ? additional() : null} {/* eslint-disable-next-line react/no-unknown-property */} ) : ( ); } // $FlowFixMe export const TextInputTv = React.forwardRef(TextInputTV);