import { StyleConstants } from '@utils/styles/constants' import layoutAnimation from '@utils/styles/layoutAnimation' import { useTheme } from '@utils/styles/ThemeManager' import React, { Dispatch, SetStateAction, useEffect, useRef, useState } from 'react' import { Platform, TextInput, TextInputProps, View } from 'react-native' import Animated, { useAnimatedStyle, withTiming } from 'react-native-reanimated' import { ComponentEmojis, EmojisButton, EmojisList } from './Emojis' import EmojisContext from './Emojis/helpers/EmojisContext' import CustomText from './Text' export interface Props { autoFocus?: boolean title?: string multiline?: boolean emoji?: boolean value?: string setValue: | Dispatch> | Dispatch> options?: Omit< TextInputProps, | 'autoFocus' | 'onFocus' | 'onBlur' | 'style' | 'onChangeText' | 'onSelectionChange' | 'keyboardAppearance' | 'textAlignVertical' > } const Input: React.FC = ({ autoFocus = true, title, multiline = false, emoji = false, value, setValue, options }) => { const { colors, mode } = useTheme() const animateTitle = useAnimatedStyle(() => { if (value) { return { fontSize: withTiming(StyleConstants.Font.Size.S), paddingHorizontal: withTiming(StyleConstants.Spacing.XS), left: withTiming(StyleConstants.Spacing.S), top: withTiming(-(StyleConstants.Font.Size.S / 2) - 2), backgroundColor: withTiming(colors.backgroundDefault) } } else { return { fontSize: withTiming(StyleConstants.Font.Size.M), paddingHorizontal: withTiming(0), left: withTiming(StyleConstants.Spacing.S), top: withTiming(StyleConstants.Spacing.S + 1), backgroundColor: withTiming(colors.backgroundDefaultTransparent) } } }, [mode, value]) const selectionRange = useRef<{ start: number; end: number }>( value ? { start: value.length, end: value.length } : { start: 0, end: 0 } ) const [inputFocused, setInputFocused] = useState(false) useEffect(() => { layoutAnimation() }, [inputFocused]) return ( {({ emojisDispatch }) => ( setInputFocused(true)} onBlur={() => { setInputFocused(false) emojisDispatch({ type: 'activate', payload: false }) }} style={{ flex: 1, fontSize: StyleConstants.Font.Size.M, color: colors.primaryDefault, minHeight: Platform.OS === 'ios' && multiline ? StyleConstants.Font.LineHeight.M * 5 : undefined }} onChangeText={setValue} onSelectionChange={({ nativeEvent: { selection } }) => (selectionRange.current = selection) } value={value} {...(multiline && { multiline, numberOfLines: Platform.OS === 'android' ? 5 : undefined })} keyboardAppearance={mode} textAlignVertical='top' {...options} /> )} {title ? ( {title} ) : null} {options?.maxLength && value?.length ? ( {value?.length} / {options.maxLength} ) : null} {inputFocused ? : null} ) } export default Input