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 form default behavior #36401

Merged
merged 13 commits into from
Feb 29, 2024
17 changes: 14 additions & 3 deletions src/components/FormElement.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
import type {ForwardedRef} from 'react';
import React, {forwardRef} from 'react';
import React, {forwardRef, useRef} from 'react';
import type {ViewProps} from 'react-native';
import {View} from 'react-native';
import useFormSetup from '@hooks/useFormSetup';
import * as ComponentUtils from '@libs/ComponentUtils';

function FormElement(props: ViewProps, ref: ForwardedRef<View>) {
function FormElement(props: ViewProps, outerRef: ForwardedRef<View>) {
const formRef = useRef<View | null>(null);
useFormSetup(formRef.current);
shubham1206agra marked this conversation as resolved.
Show resolved Hide resolved
return (
<View
role={ComponentUtils.ACCESSIBILITY_ROLE_FORM}
ref={ref}
ref={(ref) => {
formRef.current = ref;
if (typeof outerRef === 'function') {
outerRef(ref);
} else if (outerRef && 'current' in outerRef) {
// eslint-disable-next-line no-param-reassign
outerRef.current = ref;
}
shubham1206agra marked this conversation as resolved.
Show resolved Hide resolved
}}
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
/>
Expand Down
12 changes: 0 additions & 12 deletions src/components/SignInPageForm/index.native.tsx

This file was deleted.

49 changes: 0 additions & 49 deletions src/components/SignInPageForm/index.tsx

This file was deleted.

5 changes: 0 additions & 5 deletions src/components/SignInPageForm/types.ts

This file was deleted.

3 changes: 3 additions & 0 deletions src/hooks/useFormSetup/index.native.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const useFormSetup = () => {};

export default useFormSetup;
33 changes: 33 additions & 0 deletions src/hooks/useFormSetup/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import {useEffect} from 'react';
import type {View} from 'react-native';

const preventFormDefault = (event: SubmitEvent) => {
// When enter is pressed form is submitted to action url (POST /).
// As we are using controlled component, we need to disable it here.
shubham1206agra marked this conversation as resolved.
Show resolved Hide resolved
event.preventDefault();
};

const useFormSetup = (form: View | null) => {
useEffect(() => {
if (!form) {
return;
}
shubham1206agra marked this conversation as resolved.
Show resolved Hide resolved

// This is a safe cast because we know that form is a HTMLFormElement.
const formElement = form as unknown as HTMLFormElement;

// Prevent the browser from applying its own validation, which affects the email input
formElement.setAttribute('novalidate', '');

// Password Managers need these attributes to be able to identify the form elements properly.
formElement.setAttribute('method', 'post');
formElement.setAttribute('action', '/');
formElement.addEventListener('submit', preventFormDefault);

return () => {
formElement.removeEventListener('submit', preventFormDefault);
};
}, [form]);
};

export default useFormSetup;
6 changes: 3 additions & 3 deletions src/pages/signin/SignInPageLayout/SignInPageContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import React from 'react';
import {View} from 'react-native';
import {withSafeAreaInsets} from 'react-native-safe-area-context';
import ExpensifyWordmark from '@components/ExpensifyWordmark';
import FormElement from '@components/FormElement';
import OfflineIndicator from '@components/OfflineIndicator';
import SignInPageForm from '@components/SignInPageForm';
import Text from '@components/Text';
import withLocalize, {withLocalizePropTypes} from '@components/withLocalize';
import useStyleUtils from '@hooks/useStyleUtils';
Expand Down Expand Up @@ -49,7 +49,7 @@ function SignInPageContent(props) {
{/* 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 */}
<View style={[styles.flexGrow1, isSmallScreenWidth ? styles.signInPageContentTopSpacerSmallScreens : styles.signInPageContentTopSpacer]} />
<View style={[styles.flexGrow2, styles.mb8]}>
<SignInPageForm style={[styles.alignSelfStretch]}>
<FormElement style={[styles.alignSelfStretch]}>
<View style={[isSmallScreenWidth ? styles.mb8 : styles.mb15, isSmallScreenWidth ? styles.alignItemsCenter : styles.alignSelfStart]}>
<ExpensifyWordmark />
</View>
Expand All @@ -73,7 +73,7 @@ function SignInPageContent(props) {
) : null}
</View>
{props.children}
</SignInPageForm>
</FormElement>
<View style={[styles.mb8, styles.signInPageWelcomeTextContainer, styles.alignSelfCenter]}>
<OfflineIndicator style={[styles.m0, styles.pl0, styles.alignItemsStart]} />
</View>
Expand Down
Loading