Skip to content

Instantly share code, notes, and snippets.

@alanfoandrade
Created November 3, 2020 12:36
Show Gist options
  • Save alanfoandrade/4f7bbd6598a793dba770cc96b729d5b9 to your computer and use it in GitHub Desktop.
Save alanfoandrade/4f7bbd6598a793dba770cc96b729d5b9 to your computer and use it in GitHub Desktop.
import React, {
useState,
useCallback,
useEffect,
useRef,
useImperativeHandle,
forwardRef,
} from 'react';
import { TextInputProps } from 'react-native';
import { useField } from '@unform/core';
import { Container, TextInput, Icon } from './styles';
interface IInputProps extends TextInputProps {
name: string;
icon: string;
containerStyle?: Record<string, unknown>;
}
interface IInputValueReference {
value: string;
}
interface IInputRef {
focus(): void;
}
const Input: React.RefForwardingComponent<IInputRef, IInputProps> = (
{ name, icon, containerStyle = {}, ...rest },
ref,
) => {
// eslint-disable-next-line
const inputElementRef = useRef<any>(null);
const { registerField, defaultValue = '', fieldName, error } = useField(name);
const inputValueRef = useRef<IInputValueReference>({ value: defaultValue });
const [isFocused, setIsFocused] = useState(false);
const [isFilled, setIsFilled] = useState(false);
const handleInputFocus = useCallback(() => {
setIsFocused(true);
}, []);
const handleInputBlur = useCallback(() => {
setIsFocused(false);
setIsFilled(!!inputValueRef.current.value);
}, []);
useImperativeHandle(ref, () => ({
focus() {
inputElementRef.current.focus();
},
}));
useEffect(() => {
registerField<string>({
name: fieldName,
ref: inputValueRef.current,
path: 'value',
// eslint-disable-next-line
setValue(_: any, value) {
inputValueRef.current.value = value;
inputElementRef.current.setNativeProps({ text: value });
},
// eslint-disable-next-line
clearValue(_: any) {
inputValueRef.current.value = '';
inputElementRef.current.clear();
},
});
}, [fieldName, registerField]);
return (
<Container style={containerStyle} isFocused={isFocused} isErrored={!!error}>
<Icon
name={icon}
size={20}
color={isFocused || isFilled ? '#ff9000' : '#666360'}
/>
<TextInput
ref={inputElementRef}
keyboardAppearance="dark"
placeholderTextColor="#666360"
defaultValue={defaultValue}
onFocus={handleInputFocus}
onBlur={handleInputBlur}
onChangeText={(value) => {
inputValueRef.current.value = value;
}}
{...rest}
/>
</Container>
);
};
export default forwardRef(Input);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment