[MM-46562] Add show/hide password function for login screen (#6612)

This commit is contained in:
Tiago Correia
2022-12-23 14:42:34 +00:00
committed by GitHub
parent 413d3c59dd
commit 97a34fc0e0
4 changed files with 87 additions and 44 deletions

View File

@@ -5,12 +5,14 @@
import {debounce} from 'lodash';
import React, {useState, useEffect, useRef, useImperativeHandle, forwardRef, useMemo, useCallback} from 'react';
import {GestureResponderEvent, LayoutChangeEvent, NativeSyntheticEvent, Platform, StyleProp, TargetedEvent, Text, TextInput, TextInputFocusEventData, TextInputProps, TextStyle, TouchableWithoutFeedback, View, ViewStyle} from 'react-native';
import {GestureResponderEvent, LayoutChangeEvent, NativeSyntheticEvent, StyleProp, TargetedEvent, Text, TextInput, TextInputFocusEventData, TextInputProps, TextStyle, TouchableWithoutFeedback, View, ViewStyle} from 'react-native';
import Animated, {useAnimatedStyle, withTiming, Easing} from 'react-native-reanimated';
import CompassIcon from '@components/compass_icon';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import {getLabelPositions, onExecution} from './utils';
const DEFAULT_INPUT_HEIGHT = 48;
const BORDER_DEFAULT_WIDTH = 1;
const BORDER_FOCUSED_WIDTH = 2;
@@ -36,6 +38,9 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
lineHeight: 16,
paddingVertical: 5,
},
input: {
flex: 1,
},
label: {
position: 'absolute',
color: changeOpacity(theme.centerChannelColor, 0.64),
@@ -52,6 +57,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
fontSize: 10,
},
textInput: {
flexDirection: 'row',
fontFamily: 'OpenSans',
fontSize: 16,
paddingTop: 12,
@@ -65,29 +71,6 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
},
}));
const onExecution = (
e: NativeSyntheticEvent<TextInputFocusEventData>,
innerFunc?: () => void,
outerFunc?: ((event: NativeSyntheticEvent<TargetedEvent>) => void),
) => {
innerFunc?.();
outerFunc?.(e);
};
const getLabelPositions = (style: TextStyle, labelStyle: TextStyle, smallLabelStyle: TextStyle) => {
const top: number = style.paddingTop as number || 0;
const bottom: number = style.paddingBottom as number || 0;
const height: number = (style.height as number || (top + bottom) || style.padding as number) || 0;
const textInputFontSize = style.fontSize || 13;
const labelFontSize = labelStyle.fontSize || 16;
const smallLabelFontSize = smallLabelStyle.fontSize || 10;
const fontSizeDiff = textInputFontSize - labelFontSize;
const unfocused = (height * 0.5) + (fontSizeDiff * (Platform.OS === 'android' ? 0.5 : 0.6));
const focused = -(labelFontSize + smallLabelFontSize) * 0.25;
return [unfocused, focused];
};
export type FloatingTextInputRef = {
blur: () => void;
focus: () => void;
@@ -97,6 +80,7 @@ export type FloatingTextInputRef = {
type FloatingTextInputProps = TextInputProps & {
containerStyle?: ViewStyle;
editable?: boolean;
endAdornment?: React.ReactNode;
error?: string;
errorIcon?: string;
isKeyboardInput?: boolean;
@@ -120,6 +104,7 @@ const FloatingTextInput = forwardRef<FloatingTextInputRef, FloatingTextInputProp
editable = true,
error,
errorIcon = 'alert-outline',
endAdornment,
isKeyboardInput = true,
label = '',
labelTextStyle,
@@ -192,7 +177,7 @@ const FloatingTextInput = forwardRef<FloatingTextInputRef, FloatingTextInputProp
return res;
}, [styles, containerStyle, multiline]);
const combinedTextInputStyle = useMemo(() => {
const combinedTextInputContainerStyle = useMemo(() => {
const res: StyleProp<TextStyle> = [styles.textInput];
if (!editable) {
res.push(styles.readOnly);
@@ -253,21 +238,24 @@ const FloatingTextInput = forwardRef<FloatingTextInputRef, FloatingTextInputProp
>
{label}
</Animated.Text>
<TextInput
{...props}
editable={isKeyboardInput && editable}
style={combinedTextInputStyle}
placeholder={placeholder}
placeholderTextColor={styles.label.color}
multiline={multiline}
value={value}
pointerEvents={isKeyboardInput ? 'auto' : 'none'}
onFocus={onTextInputFocus}
onBlur={onTextInputBlur}
ref={inputRef}
underlineColorAndroid='transparent'
testID={testID}
/>
<View style={combinedTextInputContainerStyle}>
<TextInput
{...props}
editable={isKeyboardInput && editable}
style={styles.input}
placeholder={placeholder}
placeholderTextColor={styles.label.color}
multiline={multiline}
value={value}
pointerEvents={isKeyboardInput ? 'auto' : 'none'}
onFocus={onTextInputFocus}
onBlur={onTextInputBlur}
ref={inputRef}
underlineColorAndroid='transparent'
testID={testID}
/>
{endAdornment}
</View>
{Boolean(error) && (
<View style={styles.errorContainer}>
{showErrorIcon && errorIcon &&

View File

@@ -0,0 +1,28 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {NativeSyntheticEvent, Platform, TargetedEvent, TextInputFocusEventData, TextStyle} from 'react-native';
export const onExecution = (
e: NativeSyntheticEvent<TextInputFocusEventData>,
innerFunc?: () => void,
outerFunc?: ((event: NativeSyntheticEvent<TargetedEvent>) => void),
) => {
innerFunc?.();
outerFunc?.(e);
};
export const getLabelPositions = (style: TextStyle, labelStyle: TextStyle, smallLabelStyle: TextStyle) => {
const top: number = style.paddingTop as number || 0;
const bottom: number = style.paddingBottom as number || 0;
const height: number = (style.height as number || (top + bottom) || style.padding as number) || 0;
const textInputFontSize = style.fontSize || 13;
const labelFontSize = labelStyle.fontSize || 16;
const smallLabelFontSize = smallLabelStyle.fontSize || 10;
const fontSizeDiff = textInputFontSize - labelFontSize;
const unfocused = (height * 0.5) + (fontSizeDiff * (Platform.OS === 'android' ? 0.5 : 0.6));
const focused = -(labelFontSize + smallLabelFontSize) * 0.25;
return [unfocused, focused];
};