Skip to content

Commit 5530ea2

Browse files
authored
Merge pull request #12848 from Expensify/tgolen-fix-signin-keyboard-avoiding
Fix the keyboard overlapping buttons on the sign in form
2 parents b48ded2 + bbba5e5 commit 5530ea2

File tree

8 files changed

+75
-121
lines changed

8 files changed

+75
-121
lines changed

src/components/FormAlertWithSubmitButton.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ const defaultProps = {
5353

5454
const FormAlertWithSubmitButton = props => (
5555
<FormAlertWrapper
56-
containerStyles={[styles.mh5, styles.mb5, styles.flex1, styles.justifyContentEnd, ...props.containerStyles]}
56+
containerStyles={[styles.mh5, styles.mb5, styles.justifyContentEnd, ...props.containerStyles]}
5757
isAlertVisible={props.isAlertVisible}
5858
isMessageHtml={props.isMessageHtml}
5959
message={props.message}

src/components/withWindowDimensions.js

+7
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ const windowDimensionsPropTypes = {
1818

1919
// Is the window width narrow, like on a tablet device?
2020
isMediumScreenWidth: PropTypes.bool.isRequired,
21+
22+
// Is the window width wide, like on a browser or desktop?
23+
isLargeScreenWidth: PropTypes.bool.isRequired,
2124
};
2225

2326
const windowDimensionsProviderPropTypes = {
@@ -35,6 +38,7 @@ class WindowDimensionsProvider extends React.Component {
3538
const isSmallScreenWidth = initialDimensions.width <= variables.mobileResponsiveWidthBreakpoint;
3639
const isMediumScreenWidth = initialDimensions.width > variables.mobileResponsiveWidthBreakpoint
3740
&& initialDimensions.width <= variables.tabletResponsiveWidthBreakpoint;
41+
const isLargeScreenWidth = !isSmallScreenWidth && !isMediumScreenWidth;
3842

3943
this.dimensionsEventListener = null;
4044

@@ -43,6 +47,7 @@ class WindowDimensionsProvider extends React.Component {
4347
windowWidth: initialDimensions.width,
4448
isSmallScreenWidth,
4549
isMediumScreenWidth,
50+
isLargeScreenWidth,
4651
};
4752
}
4853

@@ -67,11 +72,13 @@ class WindowDimensionsProvider extends React.Component {
6772
const {window} = newDimensions;
6873
const isSmallScreenWidth = window.width <= variables.mobileResponsiveWidthBreakpoint;
6974
const isMediumScreenWidth = !isSmallScreenWidth && window.width <= variables.tabletResponsiveWidthBreakpoint;
75+
const isLargeScreenWidth = !isSmallScreenWidth && !isMediumScreenWidth;
7076
this.setState({
7177
windowHeight: window.height,
7278
windowWidth: window.width,
7379
isSmallScreenWidth,
7480
isMediumScreenWidth,
81+
isLargeScreenWidth,
7582
});
7683
}
7784

src/pages/signin/ResendValidationForm.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ const ResendValidationForm = (props) => {
7373
{!_.isEmpty(props.account.message) && (
7474

7575
// DotIndicatorMessage mostly expects onyxData errors so we need to mock an object so that the messages looks similar to prop.account.errors
76-
<DotIndicatorMessage style={[styles.mb5]} type="success" messages={{0: props.account.message}} />
76+
<DotIndicatorMessage style={[styles.mb5, styles.flex0]} type="success" messages={{0: props.account.message}} />
7777
)}
7878
{!_.isEmpty(props.account.errors) && (
7979
<DotIndicatorMessage style={[styles.mb5]} type="error" messages={props.account.errors} />

src/pages/signin/SignInPageLayout/SignInPageContent.js

+49-65
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,17 @@
11
import React from 'react';
2-
import {ScrollView, View} from 'react-native';
2+
import {View, TouchableWithoutFeedback, Keyboard} from 'react-native';
33
import PropTypes from 'prop-types';
44
import {withSafeAreaInsets} from 'react-native-safe-area-context';
55
import styles from '../../../styles/styles';
66
import variables from '../../../styles/variables';
7-
import KeyboardAvoidingView from '../../../components/KeyboardAvoidingView';
87
import ExpensifyCashLogo from '../../../components/ExpensifyCashLogo';
98
import Text from '../../../components/Text';
109
import TermsAndLicenses from '../TermsAndLicenses';
1110
import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize';
1211
import SignInPageForm from '../../../components/SignInPageForm';
1312
import compose from '../../../libs/compose';
14-
import scrollViewContentContainerStyles from './signInPageStyles';
1513
import withKeyboardState from '../../../components/withKeyboardState';
1614
import withWindowDimensions, {windowDimensionsPropTypes} from '../../../components/withWindowDimensions';
17-
import * as StyleUtils from '../../../styles/StyleUtils';
1815

1916
const propTypes = {
2017
/** The children to show inside the layout */
@@ -31,71 +28,58 @@ const propTypes = {
3128
...windowDimensionsPropTypes,
3229
};
3330

34-
const SignInPageContent = props => (
35-
<ScrollView
36-
keyboardShouldPersistTaps="handled"
37-
showsVerticalScrollIndicator={false}
38-
style={[
39-
styles.h100,
40-
!props.isSmallScreenWidth && styles.alignSelfCenter,
41-
!props.isSmallScreenWidth && styles.signInPageWideLeftContainer,
42-
]}
43-
contentContainerStyle={[
44-
scrollViewContentContainerStyles,
45-
styles.alignItemsCenter,
46-
!props.isSmallScreenWidth && styles.ph6,
47-
]}
48-
>
49-
<View style={[styles.flex1, styles.flexRow]}>
50-
<View style={[
51-
styles.flex1,
52-
styles.signInPageNarrowContentContainer,
53-
]}
54-
>
55-
<SignInPageForm style={[
31+
const SignInPageContent = (props) => {
32+
const dismissKeyboardWhenTappedOutsideOfInput = () => {
33+
// This prop comes from withKeyboardState
34+
if (!props.isShown) {
35+
return;
36+
}
37+
Keyboard.dismiss();
38+
};
39+
40+
return (
41+
<TouchableWithoutFeedback onPress={dismissKeyboardWhenTappedOutsideOfInput}>
42+
<View
43+
style={[
5644
styles.flex1,
57-
styles.alignSelfStretch,
58-
props.isSmallScreenWidth ? styles.ph5 : styles.ph4,
45+
styles.signInPageLeftContainer,
46+
!props.isSmallScreenWidth && styles.signInPageLeftContainerWide,
5947
]}
60-
>
61-
<KeyboardAvoidingView
62-
behavior="position"
63-
style={[
64-
StyleUtils.getModalPaddingStyles({
65-
shouldAddBottomSafeAreaPadding: true,
66-
modalContainerStylePaddingBottom: 20,
67-
safeAreaPaddingBottom: props.insets.bottom,
68-
}),
69-
props.isSmallScreenWidth ? styles.signInPageNarrowContentMargin : {},
70-
!props.isMediumScreenWidth || (props.isMediumScreenWidth && props.windowHeight < variables.minHeightToShowGraphics) ? styles.signInPageWideLeftContentMargin : {},
71-
styles.mb3,
72-
]}
73-
>
74-
<View style={[
75-
styles.componentHeightLarge,
76-
...(props.isSmallScreenWidth ? [styles.mb2] : [styles.mt6, styles.mb5]),
77-
]}
78-
>
79-
<ExpensifyCashLogo
80-
width={variables.componentSizeLarge}
81-
height={variables.componentSizeLarge}
82-
/>
83-
</View>
84-
{props.shouldShowWelcomeText && (
85-
<Text style={[styles.mv5, styles.textLabel, styles.h3]}>
86-
{props.welcomeText}
87-
</Text>
88-
)}
89-
{props.children}
90-
</KeyboardAvoidingView>
91-
</SignInPageForm>
92-
<View style={[styles.mb5, styles.alignSelfCenter, styles.ph5]}>
93-
<TermsAndLicenses />
48+
>
49+
<View style={[styles.flex1, styles.alignSelfCenter, styles.signInPageWelcomeFormContainer]}>
50+
{/* This empty view creates margin on the top of the sign in form which will shrink and grow depending on if the keyboard is open or not */}
51+
<View style={[styles.flexGrow1, styles.signInPageContentTopSpacer]} />
52+
53+
<View style={[styles.flexGrow2]}>
54+
<SignInPageForm style={[styles.alignSelfStretch]}>
55+
<View style={[
56+
styles.componentHeightLarge,
57+
...(props.isSmallScreenWidth ? [styles.mb2] : [styles.mt6, styles.mb5]),
58+
]}
59+
>
60+
<ExpensifyCashLogo
61+
width={variables.componentSizeLarge}
62+
height={variables.componentSizeLarge}
63+
/>
64+
</View>
65+
{props.shouldShowWelcomeText && (
66+
<View style={[styles.signInPageWelcomeTextContainer]}>
67+
<Text style={[styles.mv5, styles.textLabel, styles.h3]}>
68+
{props.welcomeText}
69+
</Text>
70+
</View>
71+
)}
72+
{props.children}
73+
</SignInPageForm>
74+
</View>
75+
<View style={[styles.mv5]}>
76+
<TermsAndLicenses />
77+
</View>
9478
</View>
9579
</View>
96-
</View>
97-
</ScrollView>
98-
);
80+
</TouchableWithoutFeedback>
81+
);
82+
};
9983

10084
SignInPageContent.propTypes = propTypes;
10185
SignInPageContent.displayName = 'SignInPageContent';

src/pages/signin/SignInPageLayout/index.js

+1-10
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import PropTypes from 'prop-types';
44
import SignInPageContent from './SignInPageContent';
55
import withWindowDimensions, {windowDimensionsPropTypes} from '../../../components/withWindowDimensions';
66
import styles from '../../../styles/styles';
7-
import variables from '../../../styles/variables';
87
import SignInPageGraphics from './SignInPageGraphics';
98

109
const propTypes = {
@@ -25,29 +24,21 @@ const SignInPageLayout = (props) => {
2524
let containerStyles = [styles.flex1, styles.signInPageInner];
2625
let contentContainerStyles = [styles.flex1, styles.flexRow];
2726

28-
const isLongMediumScreenWidth = props.isMediumScreenWidth && props.windowHeight >= variables.minHeightToShowGraphics;
29-
3027
if (props.isSmallScreenWidth) {
3128
containerStyles = [styles.flex1];
3229
contentContainerStyles = [styles.flex1];
33-
} else if (isLongMediumScreenWidth) {
34-
containerStyles = [styles.dFlex, styles.signInPageInner, styles.flexColumnReverse, styles.justifyContentBetween];
35-
contentContainerStyles = [styles.flex1];
3630
}
3731

3832
return (
3933
<View style={containerStyles}>
40-
{isLongMediumScreenWidth && (
41-
<SignInPageGraphics />
42-
)}
4334
<View style={contentContainerStyles}>
4435
<SignInPageContent
4536
welcomeText={props.welcomeText}
4637
shouldShowWelcomeText={props.shouldShowWelcomeText}
4738
>
4839
{props.children}
4940
</SignInPageContent>
50-
{!props.isSmallScreenWidth && !isLongMediumScreenWidth && (
41+
{!props.isSmallScreenWidth && (
5142
<SignInPageGraphics />
5243
)}
5344
</View>

src/styles/styles.js

+12-39
Original file line numberDiff line numberDiff line change
@@ -898,60 +898,33 @@ const styles = {
898898
flex: 1,
899899
},
900900

901-
signInPageLogo: {
902-
height: variables.componentSizeLarge,
903-
marginBottom: 24,
904-
},
905-
906901
signInPageInner: {
907902
marginLeft: 'auto',
908903
marginRight: 'auto',
909904
height: '100%',
910905
width: '100%',
911906
},
912907

913-
signInPageInnerNative: {
914-
width: '100%',
915-
},
916-
917-
signInPageHeroHeading: {
918-
fontFamily: fontFamily.EXP_NEUE,
919-
fontWeight: fontWeightBold,
920-
fontSize: variables.fontSizeHero,
921-
color: themeColors.appBG,
922-
lineHeight: variables.lineHeightHero,
923-
},
924-
925-
signInPageHeroDescription: {
926-
fontFamily: fontFamily.EXP_NEUE,
927-
fontSize: variables.fontSizeNormal,
928-
color: themeColors.appBG,
929-
},
930-
931-
signInPageFormContainer: {
932-
maxWidth: 295,
933-
width: '100%',
934-
},
935-
936-
signInPageNarrowContentContainer: {
937-
maxWidth: 335,
908+
signInPageContentTopSpacer: {
909+
maxHeight: 132,
910+
minHeight: 24,
938911
},
939912

940-
signInPageNarrowContentMargin: {
941-
marginTop: '40%',
913+
signInPageLeftContainer: {
914+
paddingLeft: 40,
915+
paddingRight: 40,
942916
},
943917

944-
signInPageWideLeftContainer: {
945-
width: 375,
946-
maxWidth: 375,
918+
signInPageLeftContainerWide: {
919+
maxWidth: 360,
947920
},
948921

949-
signInPageWideLeftContentMargin: {
950-
marginTop: '44.5%',
922+
signInPageWelcomeFormContainer: {
923+
maxWidth: 300,
951924
},
952925

953-
signInPageWideHeroContent: {
954-
maxWidth: 400,
926+
signInPageWelcomeTextContainer: {
927+
width: 300,
955928
},
956929

957930
changeExpensifyLoginLinkContainer: {

src/styles/utilities/flex.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,6 @@ export default {
3636
flexDirection: 'column',
3737
},
3838

39-
flexColumnReverse: {
40-
flexDirection: 'column-reverse',
41-
},
42-
4339
justifyContentCenter: {
4440
justifyContent: 'center',
4541
},
@@ -108,6 +104,10 @@ export default {
108104
flexGrow: 1,
109105
},
110106

107+
flexGrow2: {
108+
flexGrow: 2,
109+
},
110+
111111
flexGrow4: {
112112
flexGrow: 4,
113113
},

src/styles/variables.js

-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ export default {
6666
tooltipzIndex: 10050,
6767
gutterWidth: 16,
6868
popoverMenuShadow: '0px 4px 12px 0px rgba(0, 0, 0, 0.06)',
69-
minHeightToShowGraphics: 854, // Login form layout breaks below this height due to insufficient space to show the form and graphics
7069
optionRowHeight: 64,
7170
optionRowHeightCompact: 52,
7271
optionsListSectionHeaderHeight: getValueUsingPixelRatio(54, 60),

0 commit comments

Comments
 (0)