Skip to content

fix: Overlap for long passwords and show/hide button in Password Auth Screen Issue #: 5614 #5621

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
56 changes: 39 additions & 17 deletions src/common/PasswordInput.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
/* @flow strict-local */
import React, { useState, useCallback } from 'react';
import type { Node } from 'react';
import { View } from 'react-native';
import { View, Pressable } from 'react-native';

import { Icon } from './Icons';
import Input from './Input';
import type { Props as InputProps } from './Input';
import { BRAND_COLOR, createStyleSheet } from '../styles';
import ZulipTextIntl from './ZulipTextIntl';
import Touchable from './Touchable';
import { BRAND_COLOR, HIGHLIGHT_COLOR, createStyleSheet } from '../styles';
import { TranslationContext } from '../boot/TranslationProvider';

const styles = createStyleSheet({
showPasswordButton: {
position: 'absolute',
right: 0,
top: 0,
bottom: 0,
justifyContent: 'center',
marginLeft: 8,
},
showPasswordButtonText: {
margin: 8,
color: BRAND_COLOR,
passwordTextInput: {
flex: 1,
},
passwordInputView: {
flexDirection: 'row',
alignItems: 'center',
},
});

Expand All @@ -37,18 +36,41 @@ type Props = $ReadOnly<$Diff<InputProps,
* All props are passed through to `Input`. See `Input` for descriptions.
*/
export default function PasswordInput(props: Props): Node {
const _ = React.useContext(TranslationContext);

const [isHidden, setIsHidden] = useState<boolean>(true);

const handleShow = useCallback(() => {
setIsHidden(prevIsHidden => !prevIsHidden);
}, []);

return (
<View>
<Input {...props} secureTextEntry={isHidden} autoCorrect={false} autoCapitalize="none" />
<Touchable style={styles.showPasswordButton} onPress={handleShow}>
<ZulipTextIntl style={styles.showPasswordButtonText} text={isHidden ? 'show' : 'hide'} />
</Touchable>
<View style={styles.passwordInputView}>
<Input
{...props}
secureTextEntry={isHidden}
autoCorrect={false}
autoCapitalize="none"
style={styles.passwordTextInput}
/>
<Pressable
// 24 (icon size) + 12 + 12 = 48px min touch target:
// https://material.io/design/usability/accessibility.html#layout-and-typography
hitSlop={12}
style={styles.showPasswordButton}
onPress={handleShow}
accessibilityLabel={_('Show password')}
accessibilityRole="switch"
accessibilityState={{ checked: !isHidden }}
>
{({ pressed }) => (
<Icon
color={pressed ? HIGHLIGHT_COLOR : BRAND_COLOR}
name={isHidden ? 'eye-off' : 'eye'}
size={24}
/>
)}
</Pressable>
</View>
);
}
2 changes: 1 addition & 1 deletion static/translations/messages_en.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"Show password": "Show password",
"Quote and reply": "Quote and reply",
"{username} [said]({link_to_message}):": "{username} [said]({link_to_message}):",
"[Quoting…]": "[Quoting…]",
Expand Down Expand Up @@ -279,7 +280,6 @@
"Stream settings": "Stream settings",
"Failed to show stream settings": "Failed to show stream settings",
"show": "show",
"hide": "hide",
"Debug": "Debug",
"Administrators": "Administrators",
"Normal users": "Normal users",
Expand Down