import React, { forwardRef, useContext, useImperativeHandle, useRef, useState, } from 'react'; import { NativeSyntheticEvent, TextInput, TextInputFocusEventData, TouchableOpacity, View, } from 'react-native'; import { useComponentId } from '../Application'; import { Icon } from '../Icon'; import { exportFontFamily, useScaleSize } from '../Text'; import { Spacing } from '../Consts'; import { ErrorView, FloatingView, getBorderColor, getSizeStyle, RenderTrailing, } from './common'; import { InputProps } from './index'; import styles from './styles'; import SystemTextInput from './SystemTextInput'; import { ApplicationContext, ComponentContext, MiniAppContext, } from '../Context'; /** * Input default component */ const Input = forwardRef( ( { value, onChangeText, floatingValue, floatingIcon, size = 'small', placeholder, onBlur, onFocus, errorMessage, trailing, trailingColor, onPressTrailing, disabled = false, floatingIconColor, required = false, errorSpacing, loading = false, leadingIcon, leadingIconColor, fontWeight, secureTextEntry, keyboardType, style, params, hintText, editable = true, onPressFloatingIcon, onPressLeadingIcon, showClearIcon = true, defaultValue, ...props }: InputProps, ref, ) => { const { theme } = useContext(ApplicationContext); const context = useContext(MiniAppContext); const scaledFontSize = useScaleSize(14); const scaleHeight = useScaleSize(size === 'small' ? 48 : 56, 1.1); const [focused, setFocused] = useState(false); const haveValue = !!value || !!defaultValue; const inputRef = useRef(null); const componentName = 'Input'; const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false; const { componentId } = useComponentId( `${componentName}/${placeholder}`, props.accessibilityLabel, ); const onClearText = () => { inputRef?.current?.clear(); inputRef.current?.setNativeProps({ text: '' }); _onChangeText(''); }; const _onChangeText = (text: string) => { onChangeText?.(text); }; const _onFocus = (e: NativeSyntheticEvent) => { setFocused(true); onFocus?.(e); }; const _onBlur = (e: NativeSyntheticEvent) => { setFocused(false); onBlur?.(e); }; const _setText = (text: string) => { inputRef?.current?.setNativeProps({ text }); _onChangeText(text); }; useImperativeHandle(ref, () => { return { clear: onClearText, focus: () => inputRef.current?.focus(), blur: () => inputRef.current?.blur(), setText: _setText, }; }); /** * Render input view */ const renderInputView = () => { const disabledColor = theme.colors.text.disable; const secure = secureTextEntry; let textColor = theme.colors.text.default; let placeholderColor = theme.colors.text.hint; let iconTintColor = trailingColor; if (disabled) { textColor = disabledColor; placeholderColor = disabledColor; iconTintColor = disabledColor; } return ( {!!leadingIcon && ( )} {showClearIcon && focused && haveValue && ( )} ); }; let inputState = 'active'; if (value && value?.length > 0) { inputState = 'filled'; } if (errorMessage && errorMessage?.length > 0) { inputState = 'error'; } if (disabled) { inputState = 'disabled'; } return ( {renderInputView()} ); }, ); export default Input;