diff --git a/assets/images/eye-disabled.svg b/assets/images/eye-disabled.svg
new file mode 100644
index 000000000000..804a36c63777
--- /dev/null
+++ b/assets/images/eye-disabled.svg
@@ -0,0 +1,15 @@
+
+
+
diff --git a/src/components/ExpensiTextInput/BaseExpensiTextInput.js b/src/components/ExpensiTextInput/BaseExpensiTextInput.js
index 3462064303f1..f22b84d24f23 100644
--- a/src/components/ExpensiTextInput/BaseExpensiTextInput.js
+++ b/src/components/ExpensiTextInput/BaseExpensiTextInput.js
@@ -1,13 +1,15 @@
import _ from 'underscore';
import React, {Component} from 'react';
import {
- Animated, TextInput, View, TouchableWithoutFeedback,
+ Animated, TextInput, View, TouchableWithoutFeedback, Pressable,
} from 'react-native';
import Str from 'expensify-common/lib/str';
import ExpensiTextInputLabel from './ExpensiTextInputLabel';
import {propTypes, defaultProps} from './baseExpensiTextInputPropTypes';
import themeColors from '../../styles/themes/default';
import styles from '../../styles/styles';
+import Icon from '../Icon';
+import * as Expensicons from '../Icon/Expensicons';
import InlineErrorText from '../InlineErrorText';
const ACTIVE_LABEL_TRANSLATE_Y = -12;
@@ -31,6 +33,7 @@ class BaseExpensiTextInput extends Component {
labelTranslateX: new Animated.Value(activeLabel
? ACTIVE_LABEL_TRANSLATE_X(props.translateX) : INACTIVE_LABEL_TRANSLATE_X),
labelScale: new Animated.Value(activeLabel ? ACTIVE_LABEL_SCALE : INACTIVE_LABEL_SCALE),
+ passwordHidden: props.secureTextEntry,
};
this.input = null;
@@ -39,6 +42,7 @@ class BaseExpensiTextInput extends Component {
this.onFocus = this.onFocus.bind(this);
this.onBlur = this.onBlur.bind(this);
this.setValue = this.setValue.bind(this);
+ this.togglePasswordVisibility = this.togglePasswordVisibility.bind(this);
}
componentDidMount() {
@@ -145,6 +149,10 @@ class BaseExpensiTextInput extends Component {
]).start();
}
+ togglePasswordVisibility() {
+ this.setState(prevState => ({passwordHidden: !prevState.passwordHidden}));
+ }
+
render() {
const inputProps = _.omit(this.props, _.keys(propTypes));
const hasLabel = Boolean(this.props.label.length);
@@ -167,7 +175,7 @@ class BaseExpensiTextInput extends Component {
{hasLabel ? (
<>
{/* Adding this background to the label only for multiline text input,
- to prevent text overlaping with label when scrolling */}
+ to prevent text overlapping with label when scrolling */}
{this.props.multiline && }
>
) : null}
- {
- if (typeof this.props.innerRef === 'function') { this.props.innerRef(ref); }
- this.input = ref;
- }}
- // eslint-disable-next-line
- {...inputProps}
- value={this.props.value}
- placeholder={(this.state.isFocused || !this.props.label) ? this.props.placeholder : null}
- placeholderTextColor={themeColors.placeholderText}
- underlineColorAndroid="transparent"
- style={[this.props.inputStyle, !hasLabel && styles.pv0]}
- multiline={this.props.multiline}
- onFocus={this.onFocus}
- onBlur={this.onBlur}
- onChangeText={this.setValue}
- onPressOut={this.props.onPress}
- translateX={this.props.translateX}
- />
+
+ {
+ if (typeof this.props.innerRef === 'function') { this.props.innerRef(ref); }
+ this.input = ref;
+ }}
+ // eslint-disable-next-line
+ {...inputProps}
+ value={this.props.value}
+ placeholder={(this.state.isFocused || !this.props.label) ? this.props.placeholder : null}
+ placeholderTextColor={themeColors.placeholderText}
+ underlineColorAndroid="transparent"
+ style={[this.props.inputStyle, styles.flex1, styles.w100, !hasLabel && styles.pv0, this.props.secureTextEntry && styles.expensiTextInputWithIcon]}
+ multiline={this.props.multiline}
+ onFocus={this.onFocus}
+ onBlur={this.onBlur}
+ onChangeText={this.setValue}
+ secureTextEntry={this.state.passwordHidden}
+ onPressOut={this.props.onPress}
+ translateX={this.props.translateX}
+ />
+ {this.props.secureTextEntry && (
+
+
+
+ )}
+
diff --git a/src/components/Icon/Expensicons.js b/src/components/Icon/Expensicons.js
index 973b61081149..27483e9cd6eb 100644
--- a/src/components/Icon/Expensicons.js
+++ b/src/components/Icon/Expensicons.js
@@ -21,6 +21,7 @@ import Download from '../../../assets/images/download.svg';
import Emoji from '../../../assets/images/emoji.svg';
import Exclamation from '../../../assets/images/exclamation.svg';
import Eye from '../../../assets/images/eye.svg';
+import EyeDisabled from '../../../assets/images/eye-disabled.svg';
import ExpensifyCard from '../../../assets/images/expensifycard.svg';
import Gallery from '../../../assets/images/gallery.svg';
import Gear from '../../../assets/images/gear.svg';
@@ -86,6 +87,7 @@ export {
Emoji,
Exclamation,
Eye,
+ EyeDisabled,
ExpensifyCard,
Gallery,
Gear,
diff --git a/src/styles/styles.js b/src/styles/styles.js
index c7ec40e0ee57..05851fc694f8 100644
--- a/src/styles/styles.js
+++ b/src/styles/styles.js
@@ -583,6 +583,7 @@ const styles = {
componentHeightLarge: {
height: variables.componentSizeLarge,
},
+
expensiTextInputContainer: {
flex: 1,
borderWidth: 1,
@@ -593,6 +594,7 @@ const styles = {
backgroundColor: themeColors.componentBG,
overflow: 'hidden',
},
+
expensiTextInputLabel: {
position: 'absolute',
left: 11.5,
@@ -602,6 +604,7 @@ const styles = {
fontFamily: fontFamily.GTA,
width: '100%',
},
+
expensiTextInputLabelBackground: {
position: 'absolute',
top: 0,
@@ -611,9 +614,11 @@ const styles = {
borderTopRightRadius: variables.componentBorderRadiusNormal,
borderTopLeftRadius: variables.componentBorderRadiusNormal,
},
+
expensiTextInputLabelDesktop: {
transformOrigin: 'left center',
},
+
expensiTextInputLabelTransformation: (translateY, translateX, scale) => ({
transform: [
{translateY},
@@ -621,6 +626,7 @@ const styles = {
{scale},
],
}),
+
expensiTextInput: {
fontFamily: fontFamily.GTA,
fontSize: variables.fontSizeNormal,
@@ -632,11 +638,23 @@ const styles = {
borderRadius: variables.componentBorderRadiusNormal,
zIndex: -1,
},
+
+ expensiTextInputWithIcon: {
+ paddingRight: 8,
+ },
+
expensiTextInputDesktop: addOutlineWidth({}, 0),
+
expensiTextInputAndroid: left => ({
padding: 0,
left,
}),
+
+ secureInputEyeButton: {
+ paddingRight: 11.5,
+ justifyContent: 'center',
+ },
+
textInput: {
backgroundColor: themeColors.componentBG,
borderRadius: variables.componentBorderRadiusNormal,
diff --git a/web/index.html b/web/index.html
index 58ef693a1a1b..f685f2b379f2 100644
--- a/web/index.html
+++ b/web/index.html
@@ -40,6 +40,9 @@
outline: 0;
box-shadow: 0px 0px 0px 1px #0185ff;
}
+ ::-ms-reveal {
+ display: none;
+ }