import React, { useCallback, useMemo, useState } from 'react'; import { I18nManager, StyleProp, StyleSheet, Text, TextInput, TextInputFocusEvent, TextInputProps, View, ViewStyle, } from 'react-native'; import { useTheme } from '../../../contexts'; import { Checkmark } from '../../../icons/checkmark-1'; import { InfoTooltip } from '../../../icons/info'; import { primitives } from '../../../theme'; import { IconRenderer } from '../Button'; export type InputProps = TextInputProps & { title?: string; description?: string; variant: 'outline' | 'ghost'; LeadingIcon?: IconRenderer; TrailingIcon?: IconRenderer; state?: 'default' | 'error' | 'success'; helperText?: boolean; errorMessage?: string; successMessage?: string; infoText?: string; containerStyle?: StyleProp; }; export const Input = ({ title, description, variant = 'outline', LeadingIcon, TrailingIcon, editable = true, state = 'default', helperText = true, errorMessage, successMessage, infoText, onFocus, onBlur, containerStyle, ...props }: InputProps) => { const [isFocused, setIsFocused] = useState(false); const { theme: { semantics }, } = useTheme(); const styles = useStyles(); const isRTL = I18nManager.isRTL; const LeftIcon = isRTL ? TrailingIcon : LeadingIcon; const RightIcon = isRTL ? LeadingIcon : TrailingIcon; const handleFocus = useCallback( (e: TextInputFocusEvent) => { setIsFocused(true); onFocus?.(e); }, [onFocus], ); const handleBlur = useCallback( (e: TextInputFocusEvent) => { setIsFocused(false); onBlur?.(e); }, [onBlur], ); return ( {title ? {title} : null} {description ? {description} : null} {LeftIcon ? ( ) : null} {RightIcon ? ( ) : null} {helperText ? ( {state === 'success' ? ( ) : ( )} {state === 'error' ? errorMessage : state === 'success' ? successMessage : infoText} ) : null} ); }; const useStyles = () => { const { theme: { semantics }, } = useTheme(); return useMemo(() => { return StyleSheet.create({ container: { gap: primitives.spacingXs, }, title: { color: semantics.textPrimary, fontSize: primitives.typographyFontSizeMd, fontWeight: primitives.typographyFontWeightSemiBold, lineHeight: primitives.typographyLineHeightNormal, textAlign: 'left', }, description: { color: semantics.textTertiary, fontSize: primitives.typographyFontSizeSm, fontWeight: primitives.typographyFontWeightRegular, lineHeight: primitives.typographyLineHeightNormal, textAlign: 'left', }, inputContainer: { alignItems: 'center', flexDirection: 'row', gap: primitives.spacingXs, paddingHorizontal: primitives.spacingMd, paddingVertical: primitives.spacingSm, borderRadius: primitives.radiusLg, borderColor: semantics.borderCoreDefault, minHeight: 48, }, textInput: { flex: 1, fontSize: primitives.typographyFontSizeMd, lineHeight: primitives.typographyLineHeightNormal, fontWeight: primitives.typographyFontWeightRegular, color: semantics.inputTextDefault, paddingVertical: 0, // android is adding extra padding so we remove it textAlign: I18nManager.isRTL ? 'right' : 'left', }, helperContainer: { alignItems: 'center', flexDirection: 'row', gap: primitives.spacingXs, }, helperText: { color: semantics.textTertiary, fontSize: primitives.typographyFontSizeSm, fontWeight: primitives.typographyFontWeightRegular, lineHeight: primitives.typographyLineHeightNormal, textAlign: 'left', }, }); }, [semantics]); };