|
@@ -1,11 +1,11 @@
|
|
|
-import React, { FC, ReactNode, useState } from 'react';
|
|
|
|
|
|
|
+import React, { FC, ReactNode, useState, useRef } from 'react';
|
|
|
import {
|
|
import {
|
|
|
TextInput,
|
|
TextInput,
|
|
|
Text,
|
|
Text,
|
|
|
View,
|
|
View,
|
|
|
InputModeOptions,
|
|
InputModeOptions,
|
|
|
NativeSyntheticEvent,
|
|
NativeSyntheticEvent,
|
|
|
- TextInputFocusEventData,
|
|
|
|
|
|
|
+ FocusEvent,
|
|
|
TouchableOpacity,
|
|
TouchableOpacity,
|
|
|
Linking,
|
|
Linking,
|
|
|
Platform
|
|
Platform
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
import { styling } from './style';
|
|
import { styling } from './style';
|
|
|
import { Colors } from 'src/theme';
|
|
import { Colors } from 'src/theme';
|
|
|
import { GOOGLE_MAP_PLACES_APIKEY } from 'src/constants';
|
|
import { GOOGLE_MAP_PLACES_APIKEY } from 'src/constants';
|
|
|
|
|
+import { Ionicons } from '@expo/vector-icons';
|
|
|
|
|
|
|
|
type Props = {
|
|
type Props = {
|
|
|
placeholder?: string;
|
|
placeholder?: string;
|
|
@@ -23,7 +24,7 @@ type Props = {
|
|
|
isFocused?: (boolean: boolean) => void;
|
|
isFocused?: (boolean: boolean) => void;
|
|
|
value?: string;
|
|
value?: string;
|
|
|
active?: boolean;
|
|
active?: boolean;
|
|
|
- onBlur?: (e: NativeSyntheticEvent<TextInputFocusEventData>) => void;
|
|
|
|
|
|
|
+ onBlur?: (e: NativeSyntheticEvent<FocusEvent>) => void;
|
|
|
formikError?: string | boolean;
|
|
formikError?: string | boolean;
|
|
|
icon?: ReactNode;
|
|
icon?: ReactNode;
|
|
|
multiline?: boolean;
|
|
multiline?: boolean;
|
|
@@ -121,9 +122,81 @@ export const Input: FC<Props> = ({
|
|
|
autoFocus
|
|
autoFocus
|
|
|
}) => {
|
|
}) => {
|
|
|
const [focused, setFocused] = useState(false);
|
|
const [focused, setFocused] = useState(false);
|
|
|
|
|
+ const [showPassword, setShowPassword] = useState(false);
|
|
|
|
|
+ const justToggledRef = useRef(false);
|
|
|
|
|
|
|
|
const styles = styling(focused);
|
|
const styles = styling(focused);
|
|
|
|
|
|
|
|
|
|
+ if (isPrivate) {
|
|
|
|
|
+ return (
|
|
|
|
|
+ <View>
|
|
|
|
|
+ {header ? <Text style={styles.text}>{header}</Text> : null}
|
|
|
|
|
+ <View
|
|
|
|
|
+ style={[
|
|
|
|
|
+ [styles.wrapper, formikError ? styles.inputError : null, { backgroundColor }],
|
|
|
|
|
+ { flexDirection: 'row', alignItems: 'center' },
|
|
|
|
|
+ { height: height ?? 44 }
|
|
|
|
|
+ ]}
|
|
|
|
|
+ >
|
|
|
|
|
+ <TextInput
|
|
|
|
|
+ value={value}
|
|
|
|
|
+ onChangeText={(text) => {
|
|
|
|
|
+ if (justToggledRef.current) {
|
|
|
|
|
+ if (text === '') {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (value && !text.startsWith(value)) {
|
|
|
|
|
+ justToggledRef.current = false;
|
|
|
|
|
+ if (onChange) {
|
|
|
|
|
+ onChange(value + text);
|
|
|
|
|
+ }
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ justToggledRef.current = false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (onChange) {
|
|
|
|
|
+ onChange(text);
|
|
|
|
|
+ }
|
|
|
|
|
+ }}
|
|
|
|
|
+ secureTextEntry={!showPassword}
|
|
|
|
|
+ placeholder={placeholder}
|
|
|
|
|
+ placeholderTextColor={Colors.LIGHT_GRAY}
|
|
|
|
|
+ onFocus={() => setFocused(true)}
|
|
|
|
|
+ onBlur={(e) => {
|
|
|
|
|
+ setFocused(false);
|
|
|
|
|
+ if (onBlur) onBlur(e);
|
|
|
|
|
+ }}
|
|
|
|
|
+ style={[
|
|
|
|
|
+ { height: '100%', flex: 1, color: Colors.BLACK, padding: 10 }
|
|
|
|
|
+ ]}
|
|
|
|
|
+ />
|
|
|
|
|
+ <TouchableOpacity
|
|
|
|
|
+ style={styles.clearIcon}
|
|
|
|
|
+ onPress={() => {
|
|
|
|
|
+ const next = !showPassword;
|
|
|
|
|
+ if (!next) {
|
|
|
|
|
+ justToggledRef.current = true;
|
|
|
|
|
+ }
|
|
|
|
|
+ setShowPassword(next);
|
|
|
|
|
+ }}
|
|
|
|
|
+ activeOpacity={0.7}
|
|
|
|
|
+ hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
|
|
|
|
|
+ >
|
|
|
|
|
+ <Ionicons
|
|
|
|
|
+ name={showPassword ? 'eye-outline' : 'eye-off-outline'}
|
|
|
|
|
+ size={20}
|
|
|
|
|
+ color={Colors.TEXT_GRAY}
|
|
|
|
|
+ />
|
|
|
|
|
+ </TouchableOpacity>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ {formikError ? <Text style={styles.errorText}>{formikError}</Text> : null}
|
|
|
|
|
+ </View>
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
return (
|
|
return (
|
|
|
<View>
|
|
<View>
|
|
|
{header ? <Text style={styles.text}>{header}</Text> : null}
|
|
{header ? <Text style={styles.text}>{header}</Text> : null}
|
|
@@ -164,7 +237,7 @@ export const Input: FC<Props> = ({
|
|
|
editable={editable}
|
|
editable={editable}
|
|
|
value={value}
|
|
value={value}
|
|
|
inputMode={inputMode ?? 'text'}
|
|
inputMode={inputMode ?? 'text'}
|
|
|
- secureTextEntry={isPrivate ?? false}
|
|
|
|
|
|
|
+ secureTextEntry={false}
|
|
|
placeholder={placeholder}
|
|
placeholder={placeholder}
|
|
|
placeholderTextColor={Colors.LIGHT_GRAY}
|
|
placeholderTextColor={Colors.LIGHT_GRAY}
|
|
|
onChangeText={onChange}
|
|
onChangeText={onChange}
|