Skip to content

Commit

Permalink
add show password toggle to secureTextInput
Browse files Browse the repository at this point in the history
  • Loading branch information
anthony-hull committed Nov 29, 2021
1 parent 5249e8c commit c96e703
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 21 deletions.
15 changes: 15 additions & 0 deletions assets/images/eye-disabled.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
65 changes: 44 additions & 21 deletions src/components/ExpensiTextInput/BaseExpensiTextInput.js
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;
Expand All @@ -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() {
Expand Down Expand Up @@ -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);
Expand All @@ -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 && <View style={styles.expensiTextInputLabelBackground} />}
<ExpensiTextInputLabel
label={this.props.label}
Expand All @@ -181,25 +189,40 @@ class BaseExpensiTextInput extends Component {
/>
</>
) : null}
<TextInput
ref={(ref) => {
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}
/>
<View style={[styles.flexRow]}>
<TextInput
ref={(ref) => {
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 && (
<Pressable
accessibilityRole="button"
style={styles.secureInputEyeButton}
onPress={this.togglePasswordVisibility}
>
<Icon
src={this.state.passwordHidden ? Expensicons.Eye : Expensicons.EyeDisabled}
fill={themeColors.icon}
/>
</Pressable>
)}
</View>
</View>
</TouchableWithoutFeedback>
</View>
Expand Down
2 changes: 2 additions & 0 deletions src/components/Icon/Expensicons.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -86,6 +87,7 @@ export {
Emoji,
Exclamation,
Eye,
EyeDisabled,
ExpensifyCard,
Gallery,
Gear,
Expand Down
18 changes: 18 additions & 0 deletions src/styles/styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,7 @@ const styles = {
componentHeightLarge: {
height: variables.componentSizeLarge,
},

expensiTextInputContainer: {
flex: 1,
borderWidth: 1,
Expand All @@ -593,6 +594,7 @@ const styles = {
backgroundColor: themeColors.componentBG,
overflow: 'hidden',
},

expensiTextInputLabel: {
position: 'absolute',
left: 11.5,
Expand All @@ -602,6 +604,7 @@ const styles = {
fontFamily: fontFamily.GTA,
width: '100%',
},

expensiTextInputLabelBackground: {
position: 'absolute',
top: 0,
Expand All @@ -611,16 +614,19 @@ const styles = {
borderTopRightRadius: variables.componentBorderRadiusNormal,
borderTopLeftRadius: variables.componentBorderRadiusNormal,
},

expensiTextInputLabelDesktop: {
transformOrigin: 'left center',
},

expensiTextInputLabelTransformation: (translateY, translateX, scale) => ({
transform: [
{translateY},
{translateX},
{scale},
],
}),

expensiTextInput: {
fontFamily: fontFamily.GTA,
fontSize: variables.fontSizeNormal,
Expand All @@ -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,
Expand Down
3 changes: 3 additions & 0 deletions web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
outline: 0;
box-shadow: 0px 0px 0px 1px #0185ff;
}
::-ms-reveal {
display: none;
}
</style>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
<link rel="shortcut icon" id="favicon" href="/favicon.png">
Expand Down

0 comments on commit c96e703

Please sign in to comment.