diff --git a/src/pages/signin/LoginForm/BaseLoginForm.js b/src/pages/signin/LoginForm/BaseLoginForm.js
index de2f2900c58d..1ac12dca0a09 100644
--- a/src/pages/signin/LoginForm/BaseLoginForm.js
+++ b/src/pages/signin/LoginForm/BaseLoginForm.js
@@ -245,6 +245,15 @@ function LoginForm(props) {
isInputFocused() {
return input.current && input.current.isFocused();
},
+ clearDataAndFocus(clearLogin = true) {
+ if (!input.current) {
+ return;
+ }
+ if (clearLogin) {
+ Session.clearSignInData();
+ }
+ input.current.focus();
+ },
}));
const formErrorText = useMemo(() => (formError ? translate(formError) : ''), [formError, translate]);
diff --git a/src/pages/signin/LoginForm/index.js b/src/pages/signin/LoginForm/index.js
index 91aba70a866f..e861100c25fe 100644
--- a/src/pages/signin/LoginForm/index.js
+++ b/src/pages/signin/LoginForm/index.js
@@ -1,18 +1,24 @@
import PropTypes from 'prop-types';
import React from 'react';
+import refPropTypes from '@components/refPropTypes';
import BaseLoginForm from './BaseLoginForm';
const propTypes = {
/** Function used to scroll to the top of the page */
scrollPageToTop: PropTypes.func,
+
+ /** A reference so we can expose clearDataAndFocus */
+ innerRef: refPropTypes,
};
const defaultProps = {
scrollPageToTop: undefined,
+ innerRef: () => {},
};
-function LoginForm(props) {
+function LoginForm({innerRef, ...props}) {
return (
@@ -23,4 +29,14 @@ LoginForm.displayName = 'LoginForm';
LoginForm.propTypes = propTypes;
LoginForm.defaultProps = defaultProps;
-export default LoginForm;
+const LoginFormWithRef = React.forwardRef((props, ref) => (
+
+));
+
+LoginFormWithRef.displayName = 'LoginFormWithRef';
+
+export default LoginFormWithRef;
diff --git a/src/pages/signin/LoginForm/index.native.js b/src/pages/signin/LoginForm/index.native.js
index 87258e69165f..3187faac8127 100644
--- a/src/pages/signin/LoginForm/index.native.js
+++ b/src/pages/signin/LoginForm/index.native.js
@@ -1,17 +1,23 @@
import PropTypes from 'prop-types';
import React, {useEffect, useRef} from 'react';
+import _ from 'underscore';
+import refPropTypes from '@components/refPropTypes';
import AppStateMonitor from '@libs/AppStateMonitor';
import BaseLoginForm from './BaseLoginForm';
const propTypes = {
/** Function used to scroll to the top of the page */
scrollPageToTop: PropTypes.func,
+
+ /** A reference so we can expose clearDataAndFocus */
+ innerRef: refPropTypes,
};
const defaultProps = {
scrollPageToTop: undefined,
+ innerRef: () => {},
};
-function LoginForm(props) {
+function LoginForm({innerRef, ...props}) {
const loginFormRef = useRef();
const {scrollPageToTop} = props;
@@ -36,7 +42,15 @@ function LoginForm(props) {
(loginFormRef.current = ref)}
+ ref={(ref) => {
+ loginFormRef.current = ref;
+ if (typeof innerRef === 'function') {
+ innerRef(ref);
+ } else if (innerRef && _.has(innerRef, 'current')) {
+ // eslint-disable-next-line no-param-reassign
+ innerRef.current = ref;
+ }
+ }}
/>
);
}
@@ -45,4 +59,14 @@ LoginForm.displayName = 'LoginForm';
LoginForm.propTypes = propTypes;
LoginForm.defaultProps = defaultProps;
-export default LoginForm;
+const LoginFormWithRef = React.forwardRef((props, ref) => (
+
+));
+
+LoginFormWithRef.displayName = 'LoginFormWithRef';
+
+export default LoginFormWithRef;
diff --git a/src/pages/signin/SignInPage.js b/src/pages/signin/SignInPage.js
index 8cb0ef9907af..9d5b51d667ff 100644
--- a/src/pages/signin/SignInPage.js
+++ b/src/pages/signin/SignInPage.js
@@ -140,6 +140,7 @@ function SignInPageInner({credentials, account, isInModal, activeClients, prefer
const shouldShowSmallScreen = isSmallScreenWidth || isInModal;
const safeAreaInsets = useSafeAreaInsets();
const signInPageLayoutRef = useRef();
+ const loginFormRef = useRef();
/** This state is needed to keep track of if user is using recovery code instead of 2fa code,
* and we need it here since welcome text(`welcomeText`) also depends on it */
const [isUsingRecoveryCode, setIsUsingRecoveryCode] = useState(false);
@@ -242,6 +243,11 @@ function SignInPageInner({credentials, account, isInModal, activeClients, prefer
Log.warn('SignInPage in unexpected state!');
}
+ const navigateFocus = () => {
+ signInPageLayoutRef.current.scrollPageToTop();
+ loginFormRef.current.clearDataAndFocus();
+ };
+
return (
// Bottom SafeAreaView is removed so that login screen svg displays correctly on mobile.
// The SVG should flow under the Home Indicator on iOS.
@@ -253,10 +259,12 @@ function SignInPageInner({credentials, account, isInModal, activeClients, prefer
shouldShowWelcomeText={shouldShowWelcomeText}
ref={signInPageLayoutRef}
shouldShowSmallScreen={shouldShowSmallScreen}
+ navigateFocus={navigateFocus}
>
{/* LoginForm must use the isVisible prop. This keeps it mounted, but visually hidden
so that password managers can access the values. Conditionally rendering this component will break this feature. */}
{
- scrollPageToTop();
-
- // We need to clear sign in data in case the user is already in the ValidateCodeForm or PasswordForm pages
- Session.clearSignInData();
-};
-
-const columns = ({scrollPageToTop}) => [
+const columns = ({navigateFocus}) => [
{
translationPath: 'footer.features',
rows: [
@@ -135,11 +127,11 @@ const columns = ({scrollPageToTop}) => [
translationPath: 'footer.getStarted',
rows: [
{
- onPress: () => navigateHome(scrollPageToTop),
+ onPress: () => navigateFocus(),
translationPath: 'footer.createAccount',
},
{
- onPress: () => navigateHome(scrollPageToTop),
+ onPress: () => navigateFocus(),
translationPath: 'footer.logIn',
},
],
@@ -172,7 +164,7 @@ function Footer(props) {
) : null}
- {_.map(columns({scrollPageToTop: props.scrollPageToTop}), (column, i) => (
+ {_.map(columns({navigateFocus: props.navigateFocus}), (column, i) => (
-
+
@@ -179,7 +179,7 @@ function SignInPageLayout(props) {