Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Fix next button isn't aligned at bottom in switch to expensify reason form page #47957

Merged
Changes from 1 commit
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
29 changes: 23 additions & 6 deletions src/pages/settings/ExitSurvey/ExitSurveyResponsePage.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type {StackScreenProps} from '@react-navigation/stack';
import React, {useCallback, useEffect} from 'react';
import React, {useCallback, useEffect, useState} from 'react';
import {StatusBar} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import FormProvider from '@components/Form/FormProvider';
import InputWrapper from '@components/Form/InputWrapper';
Expand All @@ -14,6 +15,7 @@ import useKeyboardState from '@hooks/useKeyboardState';
import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import useSafeAreaInsets from '@hooks/useSafeAreaInsets';
import useSafePaddingBottomStyle from '@hooks/useSafePaddingBottomStyle';
import useStyleUtils from '@hooks/useStyleUtils';
import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
Expand Down Expand Up @@ -43,8 +45,11 @@ function ExitSurveyResponsePage({draftResponse, route, navigation}: ExitSurveyRe
const StyleUtils = useStyleUtils();
const {keyboardHeight} = useKeyboardState();
const {windowHeight} = useWindowDimensions();
const {top: safeAreaInsetsTop} = useSafeAreaInsets();
const {top: safeAreaInsetsTop, bottom: safeAreaInsetsBottom} = useSafeAreaInsets();
const safePaddingBottomStyle = useSafePaddingBottomStyle();
const safePaddingBottomStyleValue = 'paddingBottom' in safePaddingBottomStyle ? (safePaddingBottomStyle.paddingBottom as number) : 0;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the recent fix, I add another inset from useStyledSafeAreaInsets to use in the calculation.

The form currently has 3 bottom spacings. 1 from safe area insets (ScreenWrapper), 1 from styled safe area insets,

<FormElement
key={formID}
ref={formContentRef}
style={[style, safeAreaPaddingBottomStyle.paddingBottom ? safeAreaPaddingBottomStyle : styles.pb5]}

and the last 1 is from useSafePaddingBottomStyle.

<FormAlertWrapper
containerStyles={[styles.justifyContentEnd, safePaddingBottomStyle, containerStyles]}

useSafeAreaInsets is added in ScreenWrapper so it won't overlap with this.
image

The other 2 just add additional spacing in 2 different places and 2 different values.

FormAlertWithSubmitButton which uses useSafePaddingBottomStyle adds 20px while FormWrapper uses useStyledSafeAreaInsets with the same value as useSafeAreaInsets but multiplied by 0.7 and fallback to 20px if the bottom inset is not available (for Android).

function getSafeAreaPadding(insets?: EdgeInsets, insetsPercentage: number = variables.safeInsertPercentage): SafeAreaPadding {
return {
paddingTop: insets?.top ?? 0,
paddingBottom: (insets?.bottom ?? 0) * insetsPercentage,

const {inputCallbackRef, inputRef} = useAutoFocusInput();
const [headerTitleHeight, setHeaderTitleHeight] = useState(0);

const {reason, backTo} = route.params;
const {isOffline} = useNetwork({
Expand All @@ -71,7 +76,10 @@ function ExitSurveyResponsePage({draftResponse, route, navigation}: ExitSurveyRe
const textStyle = styles.headerAnonymousFooter;
const baseResponseInputContainerStyle = styles.mt7;
const formMaxHeight = Math.floor(
windowHeight -
// windowHeight doesn't include status bar height in Android, so we need to add it here.
// StatusBar.currentHeight is only available on Android.
windowHeight +
(StatusBar.currentHeight ?? 0) -
keyboardHeight -
safeAreaInsetsTop -
// Minus the height of HeaderWithBackButton
Expand All @@ -81,16 +89,20 @@ function ExitSurveyResponsePage({draftResponse, route, navigation}: ExitSurveyRe
);
const responseInputMaxHeight = NumberUtils.roundDownToLargestMultiple(
formMaxHeight -
safeAreaInsetsBottom -
safePaddingBottomStyleValue -
// Minus the height of the text component
textStyle.lineHeight -
headerTitleHeight -
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One of the reasons the form errors overlaps is because the height of the title here is only a one-line height, but the title could be more than 1 line.

The extra margin value (baseResponseInputContainerStyle.marginTop * 2) calculation below and the vertical margins (40) should be enough to cover the form error, but the form error (Please fix the errors in the form before continuing.) could be more than 1 line too, so I add an extra 20 as the safe value.

// Minus the response input margins (multiplied by 2 to create the effect of margins on top and bottom).
// marginBottom does not work in this case because the TextInput is in a ScrollView and will push the button beneath it out of view,
// so it's maxHeight is what dictates space between it and the button.
baseResponseInputContainerStyle.marginTop * 2 -
// Minus the approximate size of a default button
variables.componentSizeLarge -
// Minus the vertical margins around the form button
40,
40 -
// Minus the extra height for the form error text
20,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use dynamic values for these?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


// Round down to the largest number of full lines
styles.baseTextInput.lineHeight,
Expand Down Expand Up @@ -120,7 +132,12 @@ function ExitSurveyResponsePage({draftResponse, route, navigation}: ExitSurveyRe
{isOffline && <ExitSurveyOffline />}
{!isOffline && (
<>
<Text style={textStyle}>{translate(`exitSurvey.prompts.${reason}`)}</Text>
<Text
style={textStyle}
onLayout={(e) => setHeaderTitleHeight(e.nativeEvent.layout.height)}
>
{translate(`exitSurvey.prompts.${reason}`)}
</Text>
<InputWrapper
InputComponent={TextInput}
inputID={INPUT_IDS.RESPONSE}
Expand Down
Loading