Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ multiline | bool | `false` | If true, it will allow multiline text input
height | number | `undefined` | A number representing the initial height of the textInput
autoGrow | bool | `false` | If true enables autogrow of the textInput
underlineColorAndroid | string | `rgba(0,0,0,0)` | This sets the default underline color on Android to transparent ([Issue #1](https://github.com/evblurbs/react-native-md-textinput/issues/1)).
secureTextAllowUnmask | bool | `false` | This allows the secure password area to be unmasked.
secureTextAllowUnmaskIconOn | element | `false` | This is the icon that is displayed when secureTextAllowUnmask is true
secureTextAllowUnmaskIconOff | element | `false` | This is the icon that is displayed when secureTextAllowUnmask is true and the user has clicked the secureTextAllowUnmaskIconOn element

### Style Overrides

Expand Down
68 changes: 57 additions & 11 deletions lib/TextField.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';
import React, {Component, PropTypes} from "react";
import {View, TextInput, StyleSheet} from "react-native";
import {View, TouchableWithoutFeedback, TextInput, Text, StyleSheet} from "react-native";

import Underline from './Underline';
import FloatingLabel from './FloatingLabel';
Expand All @@ -11,7 +11,8 @@ export default class TextField extends Component {
this.state = {
isFocused: false,
text: props.value,
height: props.height
height: props.height,
isUnmasked: false
};
}
focus() {
Expand All @@ -37,6 +38,9 @@ export default class TextField extends Component {
this.setState({height: nextProps.height});
}
}
toggleSecureMask(){
this.setState({'isUnmasked': !this.state.isUnmasked})
}
render() {
let {
label,
Expand All @@ -59,18 +63,32 @@ export default class TextField extends Component {
height,
autoGrow,
multiline,
secureTextEntry,
secureTextAllowUnmask,
secureTextAllowUnmaskIconOn,
secureTextAllowUnmaskIconOff,
...props
} = this.props;

const textInputComposedStyles = [dense ? styles.denseTextInput : styles.textInput, {
color: textColor
}, (this.state.isFocused && textFocusColor) ? {
color: textFocusColor
} : {}, (!this.state.isFocused && textBlurColor) ? {
color: textBlurColor
} : {}, inputStyle, this.state.height ? {height: this.state.height} : {}]

return (
<View style={[dense ? styles.denseWrapper : styles.wrapper, this.state.height ? {height: undefined}: {}, wrapperStyle]} ref="wrapper">
<View style={[styles.row, styles.flex]}>
{
this.props.symbol && this.props.value ?
<Text style={[textInputComposedStyles, styles.symbol]}>{this.props.symbol}</Text>
: null
}
<View style={styles.flex}>
<TextInput
style={[dense ? styles.denseTextInput : styles.textInput, {
color: textColor
}, (this.state.isFocused && textFocusColor) ? {
color: textFocusColor
} : {}, (!this.state.isFocused && textBlurColor) ? {
color: textBlurColor
} : {}, inputStyle, this.state.height ? {height: this.state.height} : {}]}
style={[textInputComposedStyles]}
multiline={multiline}
onFocus={() => {
this.setState({isFocused: true});
Expand All @@ -96,8 +114,18 @@ export default class TextField extends Component {
}}
ref="input"
value={this.state.text}
secureTextEntry={secureTextEntry && secureTextAllowUnmask ? !this.state.isUnmasked : props.secureTextEntry}
{...props}
/>
</View>
{
secureTextEntry && secureTextAllowUnmask ?
<TouchableWithoutFeedback onPress={this.toggleSecureMask.bind(this)}>
<View style={{opacity: !this.state.text.length ? 0.38 : 0.54}}>{!this.state.isUnmasked ? secureTextAllowUnmaskIconOn : secureTextAllowUnmaskIconOff}</View>
</TouchableWithoutFeedback >
: null
}
</View>
<Underline
ref="underline"
highlightColor={highlightColor}
Expand Down Expand Up @@ -141,7 +169,11 @@ TextField.propTypes = {
labelStyle: PropTypes.object,
multiline: PropTypes.bool,
autoGrow: PropTypes.bool,
height: PropTypes.oneOfType([PropTypes.oneOf(undefined), PropTypes.number])
height: PropTypes.oneOfType([PropTypes.oneOf(undefined), PropTypes.number]),
symbol: PropTypes.string,
secureTextAllowUnmask: PropTypes.bool,
secureTextAllowUnmaskIconOn: PropTypes.element,
secureTextAllowUnmaskIconOff: PropTypes.element
};

TextField.defaultProps = {
Expand All @@ -154,10 +186,17 @@ TextField.defaultProps = {
underlineColorAndroid: 'rgba(0,0,0,0)',
multiline: false,
autoGrow: false,
height: undefined
height: undefined,
secureTextIsUnmasked: false
};

const styles = StyleSheet.create({
flex: {
flex: 1
},
row: {
flexDirection: 'row'
},
wrapper: {
height: 72,
paddingTop: 30,
Expand All @@ -182,5 +221,12 @@ const styles = StyleSheet.create({
lineHeight: 24,
paddingBottom: 3,
textAlignVertical: 'top'
},
symbol: {
textAlignVertical: 'auto',
lineHeight: undefined,
height: undefined,
position: 'relative',
bottom: -10
}
});