From fe878dc037d442d763c526060eb82c16e5de2158 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Sat, 13 Jan 2024 18:28:06 +0530 Subject: [PATCH 01/20] fix submit behavior on native devices --- src/components/Form/FormProvider.js | 20 ++++++++++++++++++-- src/components/Form/FormWrapper.js | 8 +++----- src/components/Form/InputWrapper.js | 11 ++++++++++- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/components/Form/FormProvider.js b/src/components/Form/FormProvider.js index 50b24e368fc6..361a0f096f8d 100644 --- a/src/components/Form/FormProvider.js +++ b/src/components/Form/FormProvider.js @@ -238,7 +238,7 @@ const FormProvider = forwardRef( })); const registerInput = useCallback( - (inputID, propsToParse = {}) => { + (inputID, shouldSubmitEdit, propsToParse = {}) => { const newRef = inputRefs.current[inputID] || propsToParse.ref || createRef(); if (inputRefs.current[inputID] !== newRef) { inputRefs.current[inputID] = newRef; @@ -256,6 +256,20 @@ const FormProvider = forwardRef( inputValues[inputID] = _.isUndefined(propsToParse.defaultValue) ? getInitialValueByType(propsToParse.valueType) : propsToParse.defaultValue; } + // If the input is a submit editing input, we need to set the onSubmitEditing prop + // to the submit function of the form + const onSubmitEditingObject = shouldSubmitEdit + ? { + onSubmitEditing: (e) => { + submit(); + if (!propsToParse.onSubmitEditing) { + return; + } + propsToParse.onSubmitEditing(e); + }, + } + : {}; + const errorFields = lodashGet(formState, 'errorFields', {}); const fieldErrorMessage = _.chain(errorFields[inputID]) @@ -268,6 +282,8 @@ const FormProvider = forwardRef( return { ...propsToParse, + returnKeyType: shouldSubmitEdit ? 'go' : propsToParse.returnKeyType, + ...onSubmitEditingObject, ref: typeof propsToParse.ref === 'function' ? (node) => { @@ -365,7 +381,7 @@ const FormProvider = forwardRef( }, }; }, - [draftValues, formID, errors, formState, hasServerError, inputValues, onValidate, setTouchedInput, shouldValidateOnBlur, shouldValidateOnChange], + [draftValues, inputValues, formState, errors, submit, setTouchedInput, shouldValidateOnBlur, onValidate, hasServerError, shouldValidateOnChange, formID], ); const value = useMemo(() => ({registerInput}), [registerInput]); diff --git a/src/components/Form/FormWrapper.js b/src/components/Form/FormWrapper.js index da34262a8af8..af31e0b6f70a 100644 --- a/src/components/Form/FormWrapper.js +++ b/src/components/Form/FormWrapper.js @@ -1,10 +1,9 @@ import PropTypes from 'prop-types'; import React, {useCallback, useMemo, useRef} from 'react'; -import {Keyboard, ScrollView, StyleSheet} from 'react-native'; +import {Keyboard, ScrollView, StyleSheet, View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; import FormAlertWithSubmitButton from '@components/FormAlertWithSubmitButton'; -import FormSubmit from '@components/FormSubmit'; import refPropTypes from '@components/refPropTypes'; import SafeAreaConsumer from '@components/SafeAreaConsumer'; import ScrollViewWithContext from '@components/ScrollViewWithContext'; @@ -107,11 +106,10 @@ function FormWrapper(props) { const scrollViewContent = useCallback( (safeAreaPaddingBottomStyle) => ( - {children} {isSubmitButtonVisible && ( @@ -155,7 +153,7 @@ function FormWrapper(props) { disablePressOnEnter /> )} - + ), [ children, diff --git a/src/components/Form/InputWrapper.js b/src/components/Form/InputWrapper.js index 9a31210195c4..7f49660478ff 100644 --- a/src/components/Form/InputWrapper.js +++ b/src/components/Form/InputWrapper.js @@ -16,8 +16,17 @@ const defaultProps = { valueType: 'string', }; +const canUseSubmitEditing = (multiline, autoGrowHeight, submitOnEnter) => { + const isMultiline = multiline || autoGrowHeight; + if (!isMultiline) { + return true; + } + return Boolean(submitOnEnter); +}; + function InputWrapper(props) { const {InputComponent, inputID, forwardedRef, ...rest} = props; + const shouldSubmitEdit = canUseSubmitEditing(rest.multiline, rest.autoGrowHeight, rest.submitOnEnter); const {registerInput} = useContext(FormContext); // There are inputs that dont have onBlur methods, to simulate the behavior of onBlur in e.g. checkbox, we had to // use different methods like onPress. This introduced a problem that inputs that have the onBlur method were @@ -25,7 +34,7 @@ function InputWrapper(props) { // For now this side effect happened only in `TextInput` components. const shouldSetTouchedOnBlurOnly = InputComponent === TextInput; // eslint-disable-next-line react/jsx-props-no-spreading - return ; + return ; } InputWrapper.propTypes = propTypes; From 36301d1fa489e2965b0dd09c55b6bcc01c3a66f6 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Sat, 13 Jan 2024 18:32:14 +0530 Subject: [PATCH 02/20] remove unused logic --- src/components/FormSubmit/index.native.tsx | 18 ---- src/components/FormSubmit/index.tsx | 86 ------------------- src/components/FormSubmit/types.ts | 13 --- .../TextInput/BaseTextInput/index.native.tsx | 4 - .../TextInput/BaseTextInput/index.tsx | 4 - 5 files changed, 125 deletions(-) delete mode 100644 src/components/FormSubmit/index.native.tsx delete mode 100644 src/components/FormSubmit/index.tsx delete mode 100644 src/components/FormSubmit/types.ts diff --git a/src/components/FormSubmit/index.native.tsx b/src/components/FormSubmit/index.native.tsx deleted file mode 100644 index 5eae7b51d988..000000000000 --- a/src/components/FormSubmit/index.native.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import React from 'react'; -import {View} from 'react-native'; -import type {FormSubmitProps, FormSubmitRef} from './types'; - -function FormSubmit({style, children}: FormSubmitProps, ref: FormSubmitRef) { - return ( - - {children} - - ); -} - -FormSubmit.displayName = 'FormSubmit'; - -export default React.forwardRef(FormSubmit); diff --git a/src/components/FormSubmit/index.tsx b/src/components/FormSubmit/index.tsx deleted file mode 100644 index 2ccd006bf322..000000000000 --- a/src/components/FormSubmit/index.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import type {KeyboardEvent} from 'react'; -import React, {useEffect} from 'react'; -import {View} from 'react-native'; -import * as ComponentUtils from '@libs/ComponentUtils'; -import isEnterWhileComposition from '@libs/KeyboardShortcut/isEnterWhileComposition'; -import CONST from '@src/CONST'; -import type {FormSubmitProps, FormSubmitRef} from './types'; - -function FormSubmit({children, onSubmit, style}: FormSubmitProps, ref: FormSubmitRef) { - /** - * Calls the submit callback when ENTER is pressed on a form element. - */ - const submitForm = (event: KeyboardEvent) => { - // ENTER is pressed with modifier key or during text composition, do not submit the form - if (event.shiftKey || event.key !== CONST.KEYBOARD_SHORTCUTS.ENTER.shortcutKey || isEnterWhileComposition(event)) { - return; - } - - const eventTarget = event.target as HTMLElement; - - const tagName = eventTarget?.tagName ?? ''; - - // ENTER is pressed on INPUT or SELECT element, call the submit callback. - if (tagName === 'INPUT' || tagName === 'SELECT') { - onSubmit(); - return; - } - - // Pressing Enter on TEXTAREA element adds a new line. When `dataset.submitOnEnter` prop is passed, call the submit callback. - if (tagName === 'TEXTAREA' && (eventTarget?.dataset?.submitOnEnter ?? 'false') === 'true') { - event.preventDefault(); - onSubmit(); - return; - } - - // ENTER is pressed on checkbox element, call the submit callback. - if (eventTarget?.role === 'checkbox') { - onSubmit(); - } - }; - - const preventDefaultFormBehavior = (e: SubmitEvent) => e.preventDefault(); - - useEffect(() => { - if (!(ref && 'current' in ref)) { - return; - } - - const form = ref.current as HTMLFormElement | null; - - if (!form) { - return; - } - - // Prevent the browser from applying its own validation, which affects the email input - form.setAttribute('novalidate', ''); - - form.addEventListener('submit', preventDefaultFormBehavior); - - return () => { - if (!form) { - return; - } - - form.removeEventListener('submit', preventDefaultFormBehavior); - }; - }, [ref]); - - return ( - // React-native-web prevents event bubbling on TextInput for key presses - // https://github.com/necolas/react-native-web/blob/fa47f80d34ee6cde2536b2a2241e326f84b633c4/packages/react-native-web/src/exports/TextInput/index.js#L272 - // Thus use capture phase. - - {children} - - ); -} - -FormSubmit.displayName = 'FormSubmitWithRef'; - -export default React.forwardRef(FormSubmit); diff --git a/src/components/FormSubmit/types.ts b/src/components/FormSubmit/types.ts deleted file mode 100644 index 722a3fbf746e..000000000000 --- a/src/components/FormSubmit/types.ts +++ /dev/null @@ -1,13 +0,0 @@ -import type {ForwardedRef} from 'react'; -import type React from 'react'; -import type {StyleProp, View, ViewStyle} from 'react-native'; - -type FormSubmitProps = { - children: React.ReactNode; - onSubmit: () => void; - style?: StyleProp; -}; - -type FormSubmitRef = ForwardedRef; - -export type {FormSubmitProps, FormSubmitRef}; diff --git a/src/components/TextInput/BaseTextInput/index.native.tsx b/src/components/TextInput/BaseTextInput/index.native.tsx index d19d835d68bb..a31aa0073bdc 100644 --- a/src/components/TextInput/BaseTextInput/index.native.tsx +++ b/src/components/TextInput/BaseTextInput/index.native.tsx @@ -50,7 +50,6 @@ function BaseTextInput( hint = '', onInputChange = () => {}, shouldDelayFocus = false, - submitOnEnter = false, multiline = false, shouldInterceptSwipe = false, autoCorrect = true, @@ -363,9 +362,6 @@ function BaseTextInput( selection={inputProps.selection} readOnly={isReadOnly} defaultValue={defaultValue} - // FormSubmit Enter key handler does not have access to direct props. - // `dataset.submitOnEnter` is used to indicate that pressing Enter on this input should call the submit callback. - dataSet={{submitOnEnter: isMultiline && submitOnEnter}} /> {inputProps.isLoading && ( {}, shouldDelayFocus = false, - submitOnEnter = false, multiline = false, shouldInterceptSwipe = false, autoCorrect = true, @@ -383,9 +382,6 @@ function BaseTextInput( selection={inputProps.selection} readOnly={isReadOnly} defaultValue={defaultValue} - // FormSubmit Enter key handler does not have access to direct props. - // `dataset.submitOnEnter` is used to indicate that pressing Enter on this input should call the submit callback. - dataSet={{submitOnEnter: isMultiline && submitOnEnter}} /> {inputProps.isLoading && ( Date: Sat, 13 Jan 2024 18:46:28 +0530 Subject: [PATCH 03/20] small bug fix --- src/components/Form/FormProvider.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/Form/FormProvider.js b/src/components/Form/FormProvider.js index 361a0f096f8d..6ffe63892a01 100644 --- a/src/components/Form/FormProvider.js +++ b/src/components/Form/FormProvider.js @@ -270,6 +270,8 @@ const FormProvider = forwardRef( } : {}; + const isMultiline = propsToParse.multiline || propsToParse.autoGrowHeight; + const errorFields = lodashGet(formState, 'errorFields', {}); const fieldErrorMessage = _.chain(errorFields[inputID]) @@ -283,6 +285,7 @@ const FormProvider = forwardRef( return { ...propsToParse, returnKeyType: shouldSubmitEdit ? 'go' : propsToParse.returnKeyType, + blurOnSubmit: (isMultiline && shouldSubmitEdit) || propsToParse.blurOnSubmit, ...onSubmitEditingObject, ref: typeof propsToParse.ref === 'function' From 8d51fa2ff527f1d494e224f62aae59af3034c7af Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Tue, 16 Jan 2024 18:18:04 +0530 Subject: [PATCH 04/20] make submitOnEnter use consistent --- src/pages/EditRequestDescriptionPage.js | 4 ++-- src/pages/iou/MoneyRequestDescriptionPage.js | 4 ++-- src/pages/iou/request/step/IOURequestStepDescription.js | 4 ++-- src/pages/tasks/NewTaskDescriptionPage.js | 4 ++-- src/pages/tasks/NewTaskDetailsPage.js | 4 ++-- src/pages/tasks/TaskDescriptionPage.js | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/pages/EditRequestDescriptionPage.js b/src/pages/EditRequestDescriptionPage.js index 9b2a9e465746..b459c17a3ee3 100644 --- a/src/pages/EditRequestDescriptionPage.js +++ b/src/pages/EditRequestDescriptionPage.js @@ -9,7 +9,7 @@ import ScreenWrapper from '@components/ScreenWrapper'; import TextInput from '@components/TextInput'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; -import * as Browser from '@libs/Browser'; +import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import updateMultilineInputRange from '@libs/updateMultilineInputRange'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -77,7 +77,7 @@ function EditRequestDescriptionPage({defaultDescription, onSubmit}) { }} autoGrowHeight containerStyles={[styles.autoGrowHeightMultilineInput]} - submitOnEnter={!Browser.isMobile()} + submitOnEnter={!canUseTouchScreen()} /> diff --git a/src/pages/iou/MoneyRequestDescriptionPage.js b/src/pages/iou/MoneyRequestDescriptionPage.js index fe3100b8c3bd..d98eed9c7727 100644 --- a/src/pages/iou/MoneyRequestDescriptionPage.js +++ b/src/pages/iou/MoneyRequestDescriptionPage.js @@ -12,8 +12,8 @@ import ScreenWrapper from '@components/ScreenWrapper'; import TextInput from '@components/TextInput'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; +import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import * as IOU from '@libs/actions/IOU'; -import * as Browser from '@libs/Browser'; import * as MoneyRequestUtils from '@libs/MoneyRequestUtils'; import Navigation from '@libs/Navigation/Navigation'; import updateMultilineInputRange from '@libs/updateMultilineInputRange'; @@ -142,7 +142,7 @@ function MoneyRequestDescriptionPage({iou, route, selectedTab}) { }} autoGrowHeight containerStyles={[styles.autoGrowHeightMultilineInput]} - submitOnEnter={!Browser.isMobile()} + submitOnEnter={!canUseTouchScreen()} /> diff --git a/src/pages/iou/request/step/IOURequestStepDescription.js b/src/pages/iou/request/step/IOURequestStepDescription.js index 849f3276667e..8eb060c925ca 100644 --- a/src/pages/iou/request/step/IOURequestStepDescription.js +++ b/src/pages/iou/request/step/IOURequestStepDescription.js @@ -8,7 +8,7 @@ import TextInput from '@components/TextInput'; import transactionPropTypes from '@components/transactionPropTypes'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; -import * as Browser from '@libs/Browser'; +import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import compose from '@libs/compose'; import Navigation from '@libs/Navigation/Navigation'; import updateMultilineInputRange from '@libs/updateMultilineInputRange'; @@ -107,7 +107,7 @@ function IOURequestStepDescription({ autoGrowHeight containerStyles={[styles.autoGrowHeightMultilineInput]} inputStyle={[styles.verticalAlignTop]} - submitOnEnter={!Browser.isMobile()} + submitOnEnter={!canUseTouchScreen()} /> diff --git a/src/pages/tasks/NewTaskDescriptionPage.js b/src/pages/tasks/NewTaskDescriptionPage.js index b11e7c163755..06c8ed97bb48 100644 --- a/src/pages/tasks/NewTaskDescriptionPage.js +++ b/src/pages/tasks/NewTaskDescriptionPage.js @@ -11,7 +11,7 @@ import TextInput from '@components/TextInput'; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import useAutoFocusInput from '@hooks/useAutoFocusInput'; import useThemeStyles from '@hooks/useThemeStyles'; -import * as Browser from '@libs/Browser'; +import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import compose from '@libs/compose'; import Navigation from '@libs/Navigation/Navigation'; import updateMultilineInputRange from '@libs/updateMultilineInputRange'; @@ -79,7 +79,7 @@ function NewTaskDescriptionPage(props) { updateMultilineInputRange(el); }} autoGrowHeight - submitOnEnter={!Browser.isMobile()} + submitOnEnter={!canUseTouchScreen()} containerStyles={[styles.autoGrowHeightMultilineInput]} /> diff --git a/src/pages/tasks/NewTaskDetailsPage.js b/src/pages/tasks/NewTaskDetailsPage.js index 3dab58dfad04..b2a76eb07ce3 100644 --- a/src/pages/tasks/NewTaskDetailsPage.js +++ b/src/pages/tasks/NewTaskDetailsPage.js @@ -11,7 +11,7 @@ import TextInput from '@components/TextInput'; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import useAutoFocusInput from '@hooks/useAutoFocusInput'; import useThemeStyles from '@hooks/useThemeStyles'; -import * as Browser from '@libs/Browser'; +import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import compose from '@libs/compose'; import * as ErrorUtils from '@libs/ErrorUtils'; import Navigation from '@libs/Navigation/Navigation'; @@ -111,7 +111,7 @@ function NewTaskDetailsPage(props) { label={props.translate('newTaskPage.descriptionOptional')} accessibilityLabel={props.translate('newTaskPage.descriptionOptional')} autoGrowHeight - submitOnEnter={!Browser.isMobile()} + submitOnEnter={!canUseTouchScreen()} containerStyles={[styles.autoGrowHeightMultilineInput]} defaultValue={parser.htmlToMarkdown(parser.replace(taskDescription))} value={taskDescription} diff --git a/src/pages/tasks/TaskDescriptionPage.js b/src/pages/tasks/TaskDescriptionPage.js index 3a6999d4408a..10205c65eacf 100644 --- a/src/pages/tasks/TaskDescriptionPage.js +++ b/src/pages/tasks/TaskDescriptionPage.js @@ -15,7 +15,7 @@ import TextInput from '@components/TextInput'; import withCurrentUserPersonalDetails from '@components/withCurrentUserPersonalDetails'; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; -import * as Browser from '@libs/Browser'; +import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import compose from '@libs/compose'; import Navigation from '@libs/Navigation/Navigation'; import * as ReportUtils from '@libs/ReportUtils'; @@ -126,7 +126,7 @@ function TaskDescriptionPage(props) { updateMultilineInputRange(inputRef.current); }} autoGrowHeight - submitOnEnter={!Browser.isMobile()} + submitOnEnter={!canUseTouchScreen()} containerStyles={[styles.autoGrowHeightMultilineInput]} /> From 3854a9a7d0e78fd4969768ac5d2f805b096089d4 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Tue, 16 Jan 2024 18:19:05 +0530 Subject: [PATCH 05/20] fix prettier --- src/pages/iou/MoneyRequestDescriptionPage.js | 2 +- src/pages/iou/request/step/IOURequestStepDescription.js | 2 +- src/pages/tasks/NewTaskDescriptionPage.js | 2 +- src/pages/tasks/NewTaskDetailsPage.js | 2 +- src/pages/tasks/TaskDescriptionPage.js | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/pages/iou/MoneyRequestDescriptionPage.js b/src/pages/iou/MoneyRequestDescriptionPage.js index d98eed9c7727..7d3c31ca12ba 100644 --- a/src/pages/iou/MoneyRequestDescriptionPage.js +++ b/src/pages/iou/MoneyRequestDescriptionPage.js @@ -12,8 +12,8 @@ import ScreenWrapper from '@components/ScreenWrapper'; import TextInput from '@components/TextInput'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; -import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import * as IOU from '@libs/actions/IOU'; +import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import * as MoneyRequestUtils from '@libs/MoneyRequestUtils'; import Navigation from '@libs/Navigation/Navigation'; import updateMultilineInputRange from '@libs/updateMultilineInputRange'; diff --git a/src/pages/iou/request/step/IOURequestStepDescription.js b/src/pages/iou/request/step/IOURequestStepDescription.js index 8eb060c925ca..7473239d92b5 100644 --- a/src/pages/iou/request/step/IOURequestStepDescription.js +++ b/src/pages/iou/request/step/IOURequestStepDescription.js @@ -8,8 +8,8 @@ import TextInput from '@components/TextInput'; import transactionPropTypes from '@components/transactionPropTypes'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; -import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import compose from '@libs/compose'; +import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import Navigation from '@libs/Navigation/Navigation'; import updateMultilineInputRange from '@libs/updateMultilineInputRange'; import * as IOU from '@userActions/IOU'; diff --git a/src/pages/tasks/NewTaskDescriptionPage.js b/src/pages/tasks/NewTaskDescriptionPage.js index 06c8ed97bb48..7620afaf2dc8 100644 --- a/src/pages/tasks/NewTaskDescriptionPage.js +++ b/src/pages/tasks/NewTaskDescriptionPage.js @@ -11,8 +11,8 @@ import TextInput from '@components/TextInput'; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import useAutoFocusInput from '@hooks/useAutoFocusInput'; import useThemeStyles from '@hooks/useThemeStyles'; -import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import compose from '@libs/compose'; +import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import Navigation from '@libs/Navigation/Navigation'; import updateMultilineInputRange from '@libs/updateMultilineInputRange'; import * as Task from '@userActions/Task'; diff --git a/src/pages/tasks/NewTaskDetailsPage.js b/src/pages/tasks/NewTaskDetailsPage.js index b2a76eb07ce3..adf26820f7b9 100644 --- a/src/pages/tasks/NewTaskDetailsPage.js +++ b/src/pages/tasks/NewTaskDetailsPage.js @@ -11,8 +11,8 @@ import TextInput from '@components/TextInput'; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import useAutoFocusInput from '@hooks/useAutoFocusInput'; import useThemeStyles from '@hooks/useThemeStyles'; -import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import compose from '@libs/compose'; +import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import * as ErrorUtils from '@libs/ErrorUtils'; import Navigation from '@libs/Navigation/Navigation'; import * as Task from '@userActions/Task'; diff --git a/src/pages/tasks/TaskDescriptionPage.js b/src/pages/tasks/TaskDescriptionPage.js index 10205c65eacf..db8974632ab7 100644 --- a/src/pages/tasks/TaskDescriptionPage.js +++ b/src/pages/tasks/TaskDescriptionPage.js @@ -15,8 +15,8 @@ import TextInput from '@components/TextInput'; import withCurrentUserPersonalDetails from '@components/withCurrentUserPersonalDetails'; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; -import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import compose from '@libs/compose'; +import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import Navigation from '@libs/Navigation/Navigation'; import * as ReportUtils from '@libs/ReportUtils'; import StringUtils from '@libs/StringUtils'; From b0ad3787dfd3a8f9b8f74f23f20d6a91fcd854ba Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Wed, 17 Jan 2024 18:50:20 +0530 Subject: [PATCH 06/20] added props to custom components --- src/components/AddressSearch/index.tsx | 4 ++++ src/components/AddressSearch/types.ts | 6 ++++++ src/components/RoomNameInput/index.js | 4 +++- src/components/RoomNameInput/index.native.js | 4 +++- src/components/RoomNameInput/roomNameInputPropTypes.js | 8 ++++++++ 5 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/components/AddressSearch/index.tsx b/src/components/AddressSearch/index.tsx index 89e87eeebe54..ddaecf94dbbd 100644 --- a/src/components/AddressSearch/index.tsx +++ b/src/components/AddressSearch/index.tsx @@ -42,6 +42,8 @@ function AddressSearch( onBlur, onInputChange, onPress, + onSubmitEditing, + returnKeyType, predefinedPlaces = [], preferredLocale, renamedInputKeys = { @@ -380,6 +382,8 @@ function AddressSearch( defaultValue, inputID, shouldSaveDraft, + returnKeyType, + onSubmitEditing, onFocus: () => { setIsFocused(true); }, diff --git a/src/components/AddressSearch/types.ts b/src/components/AddressSearch/types.ts index 8016f1b2ea39..75d6464cd992 100644 --- a/src/components/AddressSearch/types.ts +++ b/src/components/AddressSearch/types.ts @@ -63,6 +63,12 @@ type AddressSearchProps = { /** A callback function when an address has been auto-selected */ onPress?: (props: OnPressProps) => void; + /** On submit editing handler provided by the FormProvider */ + onSubmitEditing?: () => void; + + /** Return key type provided to the TextInput */ + returnKeyType?: string; + /** Customize the TextInput container */ containerStyles?: StyleProp; diff --git a/src/components/RoomNameInput/index.js b/src/components/RoomNameInput/index.js index 61f004a47b96..e3c5a86ff945 100644 --- a/src/components/RoomNameInput/index.js +++ b/src/components/RoomNameInput/index.js @@ -6,7 +6,7 @@ import * as RoomNameInputUtils from '@libs/RoomNameInputUtils'; import CONST from '@src/CONST'; import * as roomNameInputPropTypes from './roomNameInputPropTypes'; -function RoomNameInput({isFocused, autoFocus, disabled, errorText, forwardedRef, value, onBlur, onChangeText, onInputChange, shouldDelayFocus}) { +function RoomNameInput({isFocused, autoFocus, disabled, errorText, forwardedRef, value, onBlur, onChangeText, onInputChange, onSubmitEditing, returnKeyType, shouldDelayFocus}) { const {translate} = useLocalize(); const [selection, setSelection] = useState(); @@ -52,6 +52,8 @@ function RoomNameInput({isFocused, autoFocus, disabled, errorText, forwardedRef, value={value.substring(1)} // Since the room name always starts with a prefix, we omit the first character to avoid displaying it twice. selection={selection} onSelectionChange={(event) => setSelection(event.nativeEvent.selection)} + onSubmitEditing={onSubmitEditing} + returnKeyType={returnKeyType} errorText={errorText} autoCapitalize="none" onBlur={(event) => isFocused && onBlur(event)} diff --git a/src/components/RoomNameInput/index.native.js b/src/components/RoomNameInput/index.native.js index a2c09996ad34..bae347fca3d2 100644 --- a/src/components/RoomNameInput/index.native.js +++ b/src/components/RoomNameInput/index.native.js @@ -7,7 +7,7 @@ import * as RoomNameInputUtils from '@libs/RoomNameInputUtils'; import CONST from '@src/CONST'; import * as roomNameInputPropTypes from './roomNameInputPropTypes'; -function RoomNameInput({isFocused, autoFocus, disabled, errorText, forwardedRef, value, onBlur, onChangeText, onInputChange, shouldDelayFocus}) { +function RoomNameInput({isFocused, autoFocus, disabled, errorText, forwardedRef, value, onBlur, onChangeText, onInputChange, onSubmitEditing, returnKeyType, shouldDelayFocus}) { const {translate} = useLocalize(); /** @@ -42,6 +42,8 @@ function RoomNameInput({isFocused, autoFocus, disabled, errorText, forwardedRef, maxLength={CONST.REPORT.MAX_ROOM_NAME_LENGTH} keyboardType={keyboardType} // this is a bit hacky solution to a RN issue https://github.com/facebook/react-native/issues/27449 onBlur={(event) => isFocused && onBlur(event)} + onSubmitEditing={onSubmitEditing} + returnKeyType={returnKeyType} autoFocus={isFocused && autoFocus} autoCapitalize="none" shouldDelayFocus={shouldDelayFocus} diff --git a/src/components/RoomNameInput/roomNameInputPropTypes.js b/src/components/RoomNameInput/roomNameInputPropTypes.js index 60be8430b056..6d88c0e62793 100644 --- a/src/components/RoomNameInput/roomNameInputPropTypes.js +++ b/src/components/RoomNameInput/roomNameInputPropTypes.js @@ -17,6 +17,12 @@ const propTypes = { /** A ref forwarded to the TextInput */ forwardedRef: refPropTypes, + /** On submit editing handler provided by the FormProvider */ + onSubmitEditing: PropTypes.func, + + /** Return key type provided to the TextInput */ + returnKeyType: PropTypes.string, + /** The ID used to uniquely identify the input in a Form */ inputID: PropTypes.string, @@ -39,6 +45,8 @@ const defaultProps = { disabled: false, errorText: '', forwardedRef: () => {}, + onSubmitEditing: () => {}, + returnKeyType: undefined, inputID: undefined, onBlur: () => {}, From 93f21dae4c3a1d936e302fe30eea49e361f38c98 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Mon, 22 Jan 2024 12:29:03 +0530 Subject: [PATCH 07/20] switch to form element instead of view --- src/components/Form/FormWrapper.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/components/Form/FormWrapper.js b/src/components/Form/FormWrapper.js index 0d468dbcd0d2..f95b7f7eb801 100644 --- a/src/components/Form/FormWrapper.js +++ b/src/components/Form/FormWrapper.js @@ -1,9 +1,10 @@ import PropTypes from 'prop-types'; import React, {useCallback, useMemo, useRef} from 'react'; -import {Keyboard, ScrollView, StyleSheet, View} from 'react-native'; +import {Keyboard, ScrollView, StyleSheet} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; import FormAlertWithSubmitButton from '@components/FormAlertWithSubmitButton'; +import FormElement from '@components/FormElement'; import refPropTypes from '@components/refPropTypes'; import SafeAreaConsumer from '@components/SafeAreaConsumer'; import ScrollViewWithContext from '@components/ScrollViewWithContext'; @@ -110,7 +111,7 @@ function FormWrapper(props) { const scrollViewContent = useCallback( (safeAreaPaddingBottomStyle) => ( - )} - + ), [ children, From 4848e99953ac4c0fcdbfc278cdbf657a5a29f4f6 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Mon, 22 Jan 2024 19:13:09 +0530 Subject: [PATCH 08/20] adjustment according to recommendations --- src/components/Form/FormProvider.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Form/FormProvider.js b/src/components/Form/FormProvider.js index f4118912c8f9..246b19dcd932 100644 --- a/src/components/Form/FormProvider.js +++ b/src/components/Form/FormProvider.js @@ -271,6 +271,7 @@ const FormProvider = forwardRef( } propsToParse.onSubmitEditing(e); }, + returnKeyType: 'go', } : {}; @@ -288,7 +289,6 @@ const FormProvider = forwardRef( return { ...propsToParse, - returnKeyType: shouldSubmitEdit ? 'go' : propsToParse.returnKeyType, blurOnSubmit: (isMultiline && shouldSubmitEdit) || propsToParse.blurOnSubmit, ...onSubmitEditingObject, ref: From 55bb4d2220a16229788ee154f67ac638af88775e Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Tue, 23 Jan 2024 19:52:38 +0530 Subject: [PATCH 09/20] changes according to recommendation --- src/components/Form/InputWrapper.js | 16 ++++++++++++---- src/pages/EditRequestDescriptionPage.js | 3 +-- src/pages/iou/MoneyRequestDescriptionPage.js | 3 +-- .../request/step/IOURequestStepDescription.js | 3 +-- src/pages/tasks/NewTaskDescriptionPage.js | 3 +-- src/pages/tasks/NewTaskDetailsPage.js | 3 +-- src/pages/tasks/TaskDescriptionPage.js | 3 +-- 7 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/components/Form/InputWrapper.js b/src/components/Form/InputWrapper.js index 7f49660478ff..71f9a3273164 100644 --- a/src/components/Form/InputWrapper.js +++ b/src/components/Form/InputWrapper.js @@ -2,6 +2,7 @@ import PropTypes from 'prop-types'; import React, {forwardRef, useContext} from 'react'; import refPropTypes from '@components/refPropTypes'; import TextInput from '@components/TextInput'; +import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import FormContext from './FormContext'; const propTypes = { @@ -9,24 +10,31 @@ const propTypes = { inputID: PropTypes.string.isRequired, valueType: PropTypes.string, forwardedRef: refPropTypes, + + /** Whether the input allows the form to be submitted when the user presses enter. + * This is useful for inputs that are not multiline and don't have a submit button by default. + * This property is ignored on mobile devices as they don't have a shift + enter key to create a newline. + */ + inputAllowsSubmit: PropTypes.bool, }; const defaultProps = { forwardedRef: undefined, valueType: 'string', + inputAllowsSubmit: false, }; -const canUseSubmitEditing = (multiline, autoGrowHeight, submitOnEnter) => { +const canUseSubmitEditing = (multiline, autoGrowHeight, inputAllowsSubmit) => { const isMultiline = multiline || autoGrowHeight; if (!isMultiline) { return true; } - return Boolean(submitOnEnter); + return Boolean(inputAllowsSubmit) && !canUseTouchScreen(); }; function InputWrapper(props) { - const {InputComponent, inputID, forwardedRef, ...rest} = props; - const shouldSubmitEdit = canUseSubmitEditing(rest.multiline, rest.autoGrowHeight, rest.submitOnEnter); + const {InputComponent, inputID, forwardedRef, inputAllowsSubmit, ...rest} = props; + const shouldSubmitEdit = canUseSubmitEditing(rest.multiline, rest.autoGrowHeight, inputAllowsSubmit); const {registerInput} = useContext(FormContext); // There are inputs that dont have onBlur methods, to simulate the behavior of onBlur in e.g. checkbox, we had to // use different methods like onPress. This introduced a problem that inputs that have the onBlur method were diff --git a/src/pages/EditRequestDescriptionPage.js b/src/pages/EditRequestDescriptionPage.js index b459c17a3ee3..d64cee3c5dc3 100644 --- a/src/pages/EditRequestDescriptionPage.js +++ b/src/pages/EditRequestDescriptionPage.js @@ -9,7 +9,6 @@ import ScreenWrapper from '@components/ScreenWrapper'; import TextInput from '@components/TextInput'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; -import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import updateMultilineInputRange from '@libs/updateMultilineInputRange'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -77,7 +76,7 @@ function EditRequestDescriptionPage({defaultDescription, onSubmit}) { }} autoGrowHeight containerStyles={[styles.autoGrowHeightMultilineInput]} - submitOnEnter={!canUseTouchScreen()} + inputAllowsSubmit /> diff --git a/src/pages/iou/MoneyRequestDescriptionPage.js b/src/pages/iou/MoneyRequestDescriptionPage.js index 7d3c31ca12ba..74fe27af9dfd 100644 --- a/src/pages/iou/MoneyRequestDescriptionPage.js +++ b/src/pages/iou/MoneyRequestDescriptionPage.js @@ -13,7 +13,6 @@ import TextInput from '@components/TextInput'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import * as IOU from '@libs/actions/IOU'; -import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import * as MoneyRequestUtils from '@libs/MoneyRequestUtils'; import Navigation from '@libs/Navigation/Navigation'; import updateMultilineInputRange from '@libs/updateMultilineInputRange'; @@ -142,7 +141,7 @@ function MoneyRequestDescriptionPage({iou, route, selectedTab}) { }} autoGrowHeight containerStyles={[styles.autoGrowHeightMultilineInput]} - submitOnEnter={!canUseTouchScreen()} + inputAllowsSubmit /> diff --git a/src/pages/iou/request/step/IOURequestStepDescription.js b/src/pages/iou/request/step/IOURequestStepDescription.js index 7473239d92b5..fe0f65f9ea3b 100644 --- a/src/pages/iou/request/step/IOURequestStepDescription.js +++ b/src/pages/iou/request/step/IOURequestStepDescription.js @@ -9,7 +9,6 @@ import transactionPropTypes from '@components/transactionPropTypes'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import compose from '@libs/compose'; -import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import Navigation from '@libs/Navigation/Navigation'; import updateMultilineInputRange from '@libs/updateMultilineInputRange'; import * as IOU from '@userActions/IOU'; @@ -107,7 +106,7 @@ function IOURequestStepDescription({ autoGrowHeight containerStyles={[styles.autoGrowHeightMultilineInput]} inputStyle={[styles.verticalAlignTop]} - submitOnEnter={!canUseTouchScreen()} + inputAllowsSubmit /> diff --git a/src/pages/tasks/NewTaskDescriptionPage.js b/src/pages/tasks/NewTaskDescriptionPage.js index 7620afaf2dc8..e1d8945fe58f 100644 --- a/src/pages/tasks/NewTaskDescriptionPage.js +++ b/src/pages/tasks/NewTaskDescriptionPage.js @@ -12,7 +12,6 @@ import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import useAutoFocusInput from '@hooks/useAutoFocusInput'; import useThemeStyles from '@hooks/useThemeStyles'; import compose from '@libs/compose'; -import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import Navigation from '@libs/Navigation/Navigation'; import updateMultilineInputRange from '@libs/updateMultilineInputRange'; import * as Task from '@userActions/Task'; @@ -79,7 +78,7 @@ function NewTaskDescriptionPage(props) { updateMultilineInputRange(el); }} autoGrowHeight - submitOnEnter={!canUseTouchScreen()} + inputAllowsSubmit containerStyles={[styles.autoGrowHeightMultilineInput]} /> diff --git a/src/pages/tasks/NewTaskDetailsPage.js b/src/pages/tasks/NewTaskDetailsPage.js index adf26820f7b9..29d84ad60b8b 100644 --- a/src/pages/tasks/NewTaskDetailsPage.js +++ b/src/pages/tasks/NewTaskDetailsPage.js @@ -12,7 +12,6 @@ import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import useAutoFocusInput from '@hooks/useAutoFocusInput'; import useThemeStyles from '@hooks/useThemeStyles'; import compose from '@libs/compose'; -import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import * as ErrorUtils from '@libs/ErrorUtils'; import Navigation from '@libs/Navigation/Navigation'; import * as Task from '@userActions/Task'; @@ -111,7 +110,7 @@ function NewTaskDetailsPage(props) { label={props.translate('newTaskPage.descriptionOptional')} accessibilityLabel={props.translate('newTaskPage.descriptionOptional')} autoGrowHeight - submitOnEnter={!canUseTouchScreen()} + inputAllowsSubmit containerStyles={[styles.autoGrowHeightMultilineInput]} defaultValue={parser.htmlToMarkdown(parser.replace(taskDescription))} value={taskDescription} diff --git a/src/pages/tasks/TaskDescriptionPage.js b/src/pages/tasks/TaskDescriptionPage.js index db8974632ab7..453f55e5a89d 100644 --- a/src/pages/tasks/TaskDescriptionPage.js +++ b/src/pages/tasks/TaskDescriptionPage.js @@ -16,7 +16,6 @@ import withCurrentUserPersonalDetails from '@components/withCurrentUserPersonalD import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import compose from '@libs/compose'; -import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import Navigation from '@libs/Navigation/Navigation'; import * as ReportUtils from '@libs/ReportUtils'; import StringUtils from '@libs/StringUtils'; @@ -126,7 +125,7 @@ function TaskDescriptionPage(props) { updateMultilineInputRange(inputRef.current); }} autoGrowHeight - submitOnEnter={!canUseTouchScreen()} + inputAllowsSubmit containerStyles={[styles.autoGrowHeightMultilineInput]} /> From ae03b0997a1bafd38dd9b83f4076578ee61af1a8 Mon Sep 17 00:00:00 2001 From: Jakub Trzebiatowski Date: Tue, 30 Jan 2024 12:29:58 +0100 Subject: [PATCH 10/20] Compute the component-specific input registration params --- src/components/Form/FormProvider.tsx | 31 +++----- src/components/Form/InputWrapper.tsx | 71 +++++++++++++++---- src/components/Form/types.ts | 12 ++-- src/pages/EditRequestDescriptionPage.js | 2 +- src/pages/iou/MoneyRequestDescriptionPage.js | 2 +- .../request/step/IOURequestStepDescription.js | 2 +- src/pages/tasks/NewTaskDescriptionPage.js | 2 +- src/pages/tasks/NewTaskDetailsPage.js | 2 +- src/pages/tasks/TaskDescriptionPage.js | 2 +- 9 files changed, 77 insertions(+), 49 deletions(-) diff --git a/src/components/Form/FormProvider.tsx b/src/components/Form/FormProvider.tsx index ebe1102d52a4..e163c4a7d2d5 100644 --- a/src/components/Form/FormProvider.tsx +++ b/src/components/Form/FormProvider.tsx @@ -205,7 +205,7 @@ function FormProvider( })); const registerInput = useCallback( - (inputID: keyof Form, shouldSubmitEdit: boolean, inputProps: TInputProps): TInputProps => { + (inputID: keyof Form, shouldSubmitForm: boolean, inputProps: TInputProps): TInputProps => { const newRef: MutableRefObject = inputRefs.current[inputID] ?? inputProps.ref ?? createRef(); if (inputRefs.current[inputID] !== newRef) { inputRefs.current[inputID] = newRef; @@ -222,24 +222,6 @@ function FormProvider( inputValues[inputID] = inputProps.defaultValue ?? getInitialValueByType(inputProps.valueType); } - // If the input is a submit editing input, we need to set the onSubmitEditing prop - // to the submit function of the form - const onSubmitEditingObject = shouldSubmitEdit - ? { - onSubmitEditing: (event: NativeSyntheticEvent) => { - submit(); - if (!inputProps.onSubmitEditing) { - return; - } - inputProps.onSubmitEditing(event); - }, - returnKeyType: 'go', - } - : {}; - - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - const isMultiline = inputProps.multiline || inputProps.autoGrowHeight; - const errorFields = formState?.errorFields?.[inputID] ?? {}; const fieldErrorMessage = Object.keys(errorFields) @@ -251,9 +233,14 @@ function FormProvider( return { ...inputProps, - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - blurOnSubmit: (isMultiline && shouldSubmitEdit) || inputProps.blurOnSubmit, - ...onSubmitEditingObject, + ...(shouldSubmitForm && { + onSubmitEditing: (event: NativeSyntheticEvent) => { + submit(); + + inputProps.onSubmitEditing?.(event); + }, + returnKeyType: 'go', + }), ref: typeof inputRef === 'function' ? (node: BaseInputProps) => { diff --git a/src/components/Form/InputWrapper.tsx b/src/components/Form/InputWrapper.tsx index 68c3f8639e5d..6266a799b128 100644 --- a/src/components/Form/InputWrapper.tsx +++ b/src/components/Form/InputWrapper.tsx @@ -6,27 +6,68 @@ import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import FormContext from './FormContext'; import type {InputWrapperProps, ValidInputs} from './types'; -const canUseSubmitEditing = (inputAllowsSubmit: boolean, multiline?: boolean, autoGrowHeight?: boolean) => { - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - const isMultiline = multiline || autoGrowHeight; - if (!isMultiline) { - return true; +function computeComponentSpecificRegistrationParams({ + InputComponent, + shouldSubmitForm, + multiline, + autoGrowHeight, + blurOnSubmit +}: InputWrapperProps): { + readonly shouldSubmitForm: boolean, + readonly blurOnSubmit: boolean | undefined, + readonly shouldSetTouchedOnBlurOnly: boolean, +} { + if (InputComponent === TextInput) { + const isEffectivelyMultiline = Boolean(multiline ?? autoGrowHeight); + + // We calculate the effective requested value of `shouldSubmitForm`, assuming that the default value should be + // `true` for single-line inputs and `false` for multi-line inputs. + const shouldSubmitFormOrDefault = shouldSubmitForm ?? !isEffectivelyMultiline; + + // If the user can use the hardware keyboard, they have access to an alternative way of inserting a new line + // (like a Shift+Enter keyboard shortcut). For simplicity, we assume that when there's no touch screen, it's a + // desktop setup with a keyboard. + const canUseHardwareKeyboard = !canUseTouchScreen(); + + // We want to avoid a situation when the user can't insert a new line. For single line inputs, it's not a + // problem. For multi-line inputs, ensure there are alternative ways to add a newline. + const canInputSubmitForm = isEffectivelyMultiline ? canUseHardwareKeyboard : true; + + // We only honor the provided property if it's reasonable on this platform + const shouldReallySubmitForm = canInputSubmitForm && shouldSubmitFormOrDefault; + + return { + // There are inputs that don't have onBlur methods, to simulate the behavior of onBlur in e.g. checkbox, we had to + // use different methods like onPress. This introduced a problem that inputs that have the onBlur method were + // calling some methods too early or twice, so we had to add this check to prevent that side effect. + // For now this side effect happened only in `TextInput` components. + shouldSetTouchedOnBlurOnly: true, + blurOnSubmit: (isEffectivelyMultiline && shouldReallySubmitForm) || blurOnSubmit, + shouldSubmitForm: shouldReallySubmitForm, + }; } - return inputAllowsSubmit && !canUseTouchScreen(); -}; -function InputWrapper({InputComponent, inputID, inputAllowsSubmit = false, valueType = 'string', ...rest}: InputWrapperProps, ref: ForwardedRef) { + return { + shouldSetTouchedOnBlurOnly: false, + // Forward the originally provided value + blurOnSubmit, + shouldSubmitForm: false, + }; +} + +function InputWrapper(props: InputWrapperProps, ref: ForwardedRef) { + const {InputComponent, inputID, valueType = 'string', ...rest} = props; const {registerInput} = useContext(FormContext); - const shouldSubmitEdit = canUseSubmitEditing(inputAllowsSubmit, rest.multiline, rest.autoGrowHeight); - // There are inputs that don't have onBlur methods, to simulate the behavior of onBlur in e.g. checkbox, we had to - // use different methods like onPress. This introduced a problem that inputs that have the onBlur method were - // calling some methods too early or twice, so we had to add this check to prevent that side effect. - // For now this side effect happened only in `TextInput` components. - const shouldSetTouchedOnBlurOnly = InputComponent === TextInput; + + const { + shouldSetTouchedOnBlurOnly, + blurOnSubmit, + shouldSubmitForm, + } = computeComponentSpecificRegistrationParams(props); // TODO: Sometimes we return too many props with register input, so we need to consider if it's better to make the returned type more general and disregard the issue, or we would like to omit the unused props somehow. // eslint-disable-next-line react/jsx-props-no-spreading, @typescript-eslint/no-explicit-any - return ; + return ; } InputWrapper.displayName = 'InputWrapper'; diff --git a/src/components/Form/types.ts b/src/components/Form/types.ts index 366759c7d85f..7377d06a1447 100644 --- a/src/components/Form/types.ts +++ b/src/components/Form/types.ts @@ -51,11 +51,11 @@ type InputWrapperProps = Omit InputComponent: TInput; inputID: string; - /** Whether the input allows the form to be submitted when the user presses enter. - * This is useful for inputs that are not multiline and don't have a submit button by default. - * This property is ignored on mobile devices as they don't have a shift + enter key to create a newline. - */ - inputAllowsSubmit?: boolean; + /** + * Should the containing form be submitted when this input is submitted itself? + * Currently, meaningful only for text inputs. + */ + shouldSubmitForm?: boolean; }; type ExcludeDraft = T extends `${string}Draft` ? never : T; @@ -96,7 +96,7 @@ type FormProps = { footerContent?: ReactNode; }; -type RegisterInput = (inputID: keyof Form, shouldSubmitEdit: boolean, inputProps: TInputProps) => TInputProps; +type RegisterInput = (inputID: keyof Form, shouldSubmitForm: boolean, inputProps: TInputProps) => TInputProps; type InputRefs = Record>; diff --git a/src/pages/EditRequestDescriptionPage.js b/src/pages/EditRequestDescriptionPage.js index d64cee3c5dc3..61cecaee929b 100644 --- a/src/pages/EditRequestDescriptionPage.js +++ b/src/pages/EditRequestDescriptionPage.js @@ -76,7 +76,7 @@ function EditRequestDescriptionPage({defaultDescription, onSubmit}) { }} autoGrowHeight containerStyles={[styles.autoGrowHeightMultilineInput]} - inputAllowsSubmit + shouldSubmitForm /> diff --git a/src/pages/iou/MoneyRequestDescriptionPage.js b/src/pages/iou/MoneyRequestDescriptionPage.js index 74fe27af9dfd..a66ae8031a68 100644 --- a/src/pages/iou/MoneyRequestDescriptionPage.js +++ b/src/pages/iou/MoneyRequestDescriptionPage.js @@ -141,7 +141,7 @@ function MoneyRequestDescriptionPage({iou, route, selectedTab}) { }} autoGrowHeight containerStyles={[styles.autoGrowHeightMultilineInput]} - inputAllowsSubmit + shouldSubmitForm /> diff --git a/src/pages/iou/request/step/IOURequestStepDescription.js b/src/pages/iou/request/step/IOURequestStepDescription.js index fe0f65f9ea3b..e5ef86f15285 100644 --- a/src/pages/iou/request/step/IOURequestStepDescription.js +++ b/src/pages/iou/request/step/IOURequestStepDescription.js @@ -106,7 +106,7 @@ function IOURequestStepDescription({ autoGrowHeight containerStyles={[styles.autoGrowHeightMultilineInput]} inputStyle={[styles.verticalAlignTop]} - inputAllowsSubmit + shouldSubmitForm /> diff --git a/src/pages/tasks/NewTaskDescriptionPage.js b/src/pages/tasks/NewTaskDescriptionPage.js index e1d8945fe58f..4d84cac90537 100644 --- a/src/pages/tasks/NewTaskDescriptionPage.js +++ b/src/pages/tasks/NewTaskDescriptionPage.js @@ -78,7 +78,7 @@ function NewTaskDescriptionPage(props) { updateMultilineInputRange(el); }} autoGrowHeight - inputAllowsSubmit + shouldSubmitForm containerStyles={[styles.autoGrowHeightMultilineInput]} /> diff --git a/src/pages/tasks/NewTaskDetailsPage.js b/src/pages/tasks/NewTaskDetailsPage.js index 29d84ad60b8b..4f4f2560a0d9 100644 --- a/src/pages/tasks/NewTaskDetailsPage.js +++ b/src/pages/tasks/NewTaskDetailsPage.js @@ -110,7 +110,7 @@ function NewTaskDetailsPage(props) { label={props.translate('newTaskPage.descriptionOptional')} accessibilityLabel={props.translate('newTaskPage.descriptionOptional')} autoGrowHeight - inputAllowsSubmit + shouldSubmitForm containerStyles={[styles.autoGrowHeightMultilineInput]} defaultValue={parser.htmlToMarkdown(parser.replace(taskDescription))} value={taskDescription} diff --git a/src/pages/tasks/TaskDescriptionPage.js b/src/pages/tasks/TaskDescriptionPage.js index 453f55e5a89d..3547827b173f 100644 --- a/src/pages/tasks/TaskDescriptionPage.js +++ b/src/pages/tasks/TaskDescriptionPage.js @@ -125,7 +125,7 @@ function TaskDescriptionPage(props) { updateMultilineInputRange(inputRef.current); }} autoGrowHeight - inputAllowsSubmit + shouldSubmitForm containerStyles={[styles.autoGrowHeightMultilineInput]} /> From 23ee2949b732f5a46f756538d309940614b79768 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Wed, 31 Jan 2024 18:01:59 +0530 Subject: [PATCH 11/20] minor fixes to logic --- src/components/Form/InputWrapper.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/Form/InputWrapper.tsx b/src/components/Form/InputWrapper.tsx index 6266a799b128..e20d30fae87b 100644 --- a/src/components/Form/InputWrapper.tsx +++ b/src/components/Form/InputWrapper.tsx @@ -18,11 +18,13 @@ function computeComponentSpecificRegistrationParams( readonly shouldSetTouchedOnBlurOnly: boolean, } { if (InputComponent === TextInput) { - const isEffectivelyMultiline = Boolean(multiline ?? autoGrowHeight); + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + const isEffectivelyMultiline = Boolean(multiline || autoGrowHeight); // We calculate the effective requested value of `shouldSubmitForm`, assuming that the default value should be // `true` for single-line inputs and `false` for multi-line inputs. - const shouldSubmitFormOrDefault = shouldSubmitForm ?? !isEffectivelyMultiline; + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + const shouldSubmitFormOrDefault = shouldSubmitForm || !isEffectivelyMultiline; // If the user can use the hardware keyboard, they have access to an alternative way of inserting a new line // (like a Shift+Enter keyboard shortcut). For simplicity, we assume that when there's no touch screen, it's a From 18fa42a5b5a0ee8e7292eeaca93b4b894d9fe148 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Wed, 31 Jan 2024 18:15:26 +0530 Subject: [PATCH 12/20] adding custom component to the list --- src/components/Form/InputWrapper.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/Form/InputWrapper.tsx b/src/components/Form/InputWrapper.tsx index e20d30fae87b..3cbb55aa8588 100644 --- a/src/components/Form/InputWrapper.tsx +++ b/src/components/Form/InputWrapper.tsx @@ -2,6 +2,8 @@ import type {ForwardedRef} from 'react'; import React, {forwardRef, useContext} from 'react'; import type {AnimatedTextInputRef} from '@components/RNTextInput'; import TextInput from '@components/TextInput'; +import AddressSearch from '@components/AddressSearch'; +import RoomNameInput from '@components/RoomNameInput'; import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import FormContext from './FormContext'; import type {InputWrapperProps, ValidInputs} from './types'; @@ -17,7 +19,8 @@ function computeComponentSpecificRegistrationParams( readonly blurOnSubmit: boolean | undefined, readonly shouldSetTouchedOnBlurOnly: boolean, } { - if (InputComponent === TextInput) { + const validTextInputComponents = [TextInput, AddressSearch, RoomNameInput] as TInput[]; + if (validTextInputComponents.includes(InputComponent)) { // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing const isEffectivelyMultiline = Boolean(multiline || autoGrowHeight); From f6f53391cbf83e21acad594d441a564edbdc5843 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Wed, 31 Jan 2024 18:16:11 +0530 Subject: [PATCH 13/20] fix lint --- src/components/Form/FormProvider.tsx | 2 +- src/components/Form/InputWrapper.tsx | 18 +++++++----------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/components/Form/FormProvider.tsx b/src/components/Form/FormProvider.tsx index e163c4a7d2d5..ba0f823fdbad 100644 --- a/src/components/Form/FormProvider.tsx +++ b/src/components/Form/FormProvider.tsx @@ -1,7 +1,7 @@ import lodashIsEqual from 'lodash/isEqual'; import type {ForwardedRef, MutableRefObject, ReactNode} from 'react'; -import type { NativeSyntheticEvent, TextInputSubmitEditingEventData } from 'react-native'; import React, {createRef, forwardRef, useCallback, useImperativeHandle, useMemo, useRef, useState} from 'react'; +import type {NativeSyntheticEvent, TextInputSubmitEditingEventData} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import * as ValidationUtils from '@libs/ValidationUtils'; diff --git a/src/components/Form/InputWrapper.tsx b/src/components/Form/InputWrapper.tsx index 3cbb55aa8588..f7a3fbb0a2ac 100644 --- a/src/components/Form/InputWrapper.tsx +++ b/src/components/Form/InputWrapper.tsx @@ -1,9 +1,9 @@ import type {ForwardedRef} from 'react'; import React, {forwardRef, useContext} from 'react'; -import type {AnimatedTextInputRef} from '@components/RNTextInput'; -import TextInput from '@components/TextInput'; import AddressSearch from '@components/AddressSearch'; +import type {AnimatedTextInputRef} from '@components/RNTextInput'; import RoomNameInput from '@components/RoomNameInput'; +import TextInput from '@components/TextInput'; import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import FormContext from './FormContext'; import type {InputWrapperProps, ValidInputs} from './types'; @@ -13,11 +13,11 @@ function computeComponentSpecificRegistrationParams( shouldSubmitForm, multiline, autoGrowHeight, - blurOnSubmit + blurOnSubmit, }: InputWrapperProps): { - readonly shouldSubmitForm: boolean, - readonly blurOnSubmit: boolean | undefined, - readonly shouldSetTouchedOnBlurOnly: boolean, + readonly shouldSubmitForm: boolean; + readonly blurOnSubmit: boolean | undefined; + readonly shouldSetTouchedOnBlurOnly: boolean; } { const validTextInputComponents = [TextInput, AddressSearch, RoomNameInput] as TInput[]; if (validTextInputComponents.includes(InputComponent)) { @@ -64,11 +64,7 @@ function InputWrapper(props: InputWrapperProps Date: Thu, 1 Feb 2024 14:57:45 +0530 Subject: [PATCH 14/20] minor fix to extra property passed --- src/components/Form/InputWrapper.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/components/Form/InputWrapper.tsx b/src/components/Form/InputWrapper.tsx index f7a3fbb0a2ac..1fe648d026c6 100644 --- a/src/components/Form/InputWrapper.tsx +++ b/src/components/Form/InputWrapper.tsx @@ -21,8 +21,7 @@ function computeComponentSpecificRegistrationParams( } { const validTextInputComponents = [TextInput, AddressSearch, RoomNameInput] as TInput[]; if (validTextInputComponents.includes(InputComponent)) { - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - const isEffectivelyMultiline = Boolean(multiline || autoGrowHeight); + const isEffectivelyMultiline = Boolean(multiline) || Boolean(autoGrowHeight); // We calculate the effective requested value of `shouldSubmitForm`, assuming that the default value should be // `true` for single-line inputs and `false` for multi-line inputs. @@ -61,7 +60,7 @@ function computeComponentSpecificRegistrationParams( } function InputWrapper(props: InputWrapperProps, ref: ForwardedRef) { - const {InputComponent, inputID, valueType = 'string', ...rest} = props; + const {InputComponent, inputID, valueType = 'string', shouldSubmitForm: propShouldSubmitForm, ...rest} = props; const {registerInput} = useContext(FormContext); const {shouldSetTouchedOnBlurOnly, blurOnSubmit, shouldSubmitForm} = computeComponentSpecificRegistrationParams(props); From daf46917f77afe16384471f7fe3d8b7e833df51b Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Thu, 1 Feb 2024 15:55:58 +0530 Subject: [PATCH 15/20] adjusted according to recommendations --- src/components/Form/InputWrapper.tsx | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/components/Form/InputWrapper.tsx b/src/components/Form/InputWrapper.tsx index 1fe648d026c6..4cfe6b3892a2 100644 --- a/src/components/Form/InputWrapper.tsx +++ b/src/components/Form/InputWrapper.tsx @@ -23,22 +23,15 @@ function computeComponentSpecificRegistrationParams( if (validTextInputComponents.includes(InputComponent)) { const isEffectivelyMultiline = Boolean(multiline) || Boolean(autoGrowHeight); - // We calculate the effective requested value of `shouldSubmitForm`, assuming that the default value should be - // `true` for single-line inputs and `false` for multi-line inputs. - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - const shouldSubmitFormOrDefault = shouldSubmitForm || !isEffectivelyMultiline; - // If the user can use the hardware keyboard, they have access to an alternative way of inserting a new line // (like a Shift+Enter keyboard shortcut). For simplicity, we assume that when there's no touch screen, it's a // desktop setup with a keyboard. const canUseHardwareKeyboard = !canUseTouchScreen(); - // We want to avoid a situation when the user can't insert a new line. For single line inputs, it's not a - // problem. For multi-line inputs, ensure there are alternative ways to add a newline. - const canInputSubmitForm = isEffectivelyMultiline ? canUseHardwareKeyboard : true; - - // We only honor the provided property if it's reasonable on this platform - const shouldReallySubmitForm = canInputSubmitForm && shouldSubmitFormOrDefault; + // We want to avoid a situation when the user can't insert a new line. For single-line inputs, it's not a problem and we + // force-enable form submission. For multi-line inputs, ensure that it was requested to enable form submission for this specific + // input and that alternative ways exist to add a new line. + const shouldReallySubmitForm = isEffectivelyMultiline ? Boolean(shouldSubmitForm) && canUseHardwareKeyboard : true; return { // There are inputs that don't have onBlur methods, to simulate the behavior of onBlur in e.g. checkbox, we had to From b12a5267ecc166f129ea3ab2a9ecb90d2e05309f Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Thu, 1 Feb 2024 15:56:46 +0530 Subject: [PATCH 16/20] minor adjustment --- src/components/Form/InputWrapper.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/Form/InputWrapper.tsx b/src/components/Form/InputWrapper.tsx index 4cfe6b3892a2..bd4bb6a1bf13 100644 --- a/src/components/Form/InputWrapper.tsx +++ b/src/components/Form/InputWrapper.tsx @@ -19,8 +19,9 @@ function computeComponentSpecificRegistrationParams( readonly blurOnSubmit: boolean | undefined; readonly shouldSetTouchedOnBlurOnly: boolean; } { - const validTextInputComponents = [TextInput, AddressSearch, RoomNameInput] as TInput[]; - if (validTextInputComponents.includes(InputComponent)) { + const textInputBasedComponents = [TextInput, AddressSearch, RoomNameInput] as TInput[]; + + if (textInputBasedComponents.includes(InputComponent)) { const isEffectivelyMultiline = Boolean(multiline) || Boolean(autoGrowHeight); // If the user can use the hardware keyboard, they have access to an alternative way of inserting a new line From 3124cb9bed3af28b75d300b75d6dd6961a0257f1 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Thu, 8 Feb 2024 15:23:29 +0530 Subject: [PATCH 17/20] removed the support of AddressSearch from keyboardsubmit --- src/components/AddressSearch/index.tsx | 4 ---- src/components/AddressSearch/types.ts | 6 ------ src/components/Form/InputWrapper.tsx | 3 +-- 3 files changed, 1 insertion(+), 12 deletions(-) diff --git a/src/components/AddressSearch/index.tsx b/src/components/AddressSearch/index.tsx index ddaecf94dbbd..89e87eeebe54 100644 --- a/src/components/AddressSearch/index.tsx +++ b/src/components/AddressSearch/index.tsx @@ -42,8 +42,6 @@ function AddressSearch( onBlur, onInputChange, onPress, - onSubmitEditing, - returnKeyType, predefinedPlaces = [], preferredLocale, renamedInputKeys = { @@ -382,8 +380,6 @@ function AddressSearch( defaultValue, inputID, shouldSaveDraft, - returnKeyType, - onSubmitEditing, onFocus: () => { setIsFocused(true); }, diff --git a/src/components/AddressSearch/types.ts b/src/components/AddressSearch/types.ts index 75d6464cd992..8016f1b2ea39 100644 --- a/src/components/AddressSearch/types.ts +++ b/src/components/AddressSearch/types.ts @@ -63,12 +63,6 @@ type AddressSearchProps = { /** A callback function when an address has been auto-selected */ onPress?: (props: OnPressProps) => void; - /** On submit editing handler provided by the FormProvider */ - onSubmitEditing?: () => void; - - /** Return key type provided to the TextInput */ - returnKeyType?: string; - /** Customize the TextInput container */ containerStyles?: StyleProp; diff --git a/src/components/Form/InputWrapper.tsx b/src/components/Form/InputWrapper.tsx index bd4bb6a1bf13..47fcdd52839e 100644 --- a/src/components/Form/InputWrapper.tsx +++ b/src/components/Form/InputWrapper.tsx @@ -1,6 +1,5 @@ import type {ForwardedRef} from 'react'; import React, {forwardRef, useContext} from 'react'; -import AddressSearch from '@components/AddressSearch'; import type {AnimatedTextInputRef} from '@components/RNTextInput'; import RoomNameInput from '@components/RoomNameInput'; import TextInput from '@components/TextInput'; @@ -19,7 +18,7 @@ function computeComponentSpecificRegistrationParams( readonly blurOnSubmit: boolean | undefined; readonly shouldSetTouchedOnBlurOnly: boolean; } { - const textInputBasedComponents = [TextInput, AddressSearch, RoomNameInput] as TInput[]; + const textInputBasedComponents = [TextInput, RoomNameInput] as TInput[]; if (textInputBasedComponents.includes(InputComponent)) { const isEffectivelyMultiline = Boolean(multiline) || Boolean(autoGrowHeight); From b500950ced9cd0a38b79ae3b44f6c326167bedb2 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Thu, 8 Feb 2024 15:25:59 +0530 Subject: [PATCH 18/20] removed the old prop --- .../TextInput/BaseTextInput/baseTextInputPropTypes.js | 4 ---- src/components/TextInput/BaseTextInput/types.ts | 3 --- 2 files changed, 7 deletions(-) diff --git a/src/components/TextInput/BaseTextInput/baseTextInputPropTypes.js b/src/components/TextInput/BaseTextInput/baseTextInputPropTypes.js index 78f06b4075e0..ecd07499dec7 100644 --- a/src/components/TextInput/BaseTextInput/baseTextInputPropTypes.js +++ b/src/components/TextInput/BaseTextInput/baseTextInputPropTypes.js @@ -89,9 +89,6 @@ const propTypes = { /** Whether we should wait before focusing the TextInput, useful when using transitions */ shouldDelayFocus: PropTypes.bool, - /** Indicate whether pressing Enter on multiline input is allowed to submit the form. */ - submitOnEnter: PropTypes.bool, - /** Indicate whether input is multiline */ multiline: PropTypes.bool, @@ -132,7 +129,6 @@ const defaultProps = { prefixCharacter: '', onInputChange: () => {}, shouldDelayFocus: false, - submitOnEnter: false, icon: null, shouldUseDefaultValue: false, multiline: false, diff --git a/src/components/TextInput/BaseTextInput/types.ts b/src/components/TextInput/BaseTextInput/types.ts index 01400adb0440..2e22485a2350 100644 --- a/src/components/TextInput/BaseTextInput/types.ts +++ b/src/components/TextInput/BaseTextInput/types.ts @@ -88,9 +88,6 @@ type CustomBaseTextInputProps = { /** Whether we should wait before focusing the TextInput, useful when using transitions */ shouldDelayFocus?: boolean; - /** Indicate whether pressing Enter on multiline input is allowed to submit the form. */ - submitOnEnter?: boolean; - /** Indicate whether input is multiline */ multiline?: boolean; From 29518878a201c2ed36c333bf662a0179961d201b Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Thu, 8 Feb 2024 15:38:45 +0530 Subject: [PATCH 19/20] adjusted type --- src/components/Form/InputWrapper.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Form/InputWrapper.tsx b/src/components/Form/InputWrapper.tsx index 47fcdd52839e..621a448c5ac9 100644 --- a/src/components/Form/InputWrapper.tsx +++ b/src/components/Form/InputWrapper.tsx @@ -18,7 +18,7 @@ function computeComponentSpecificRegistrationParams( readonly blurOnSubmit: boolean | undefined; readonly shouldSetTouchedOnBlurOnly: boolean; } { - const textInputBasedComponents = [TextInput, RoomNameInput] as TInput[]; + const textInputBasedComponents: ValidInputs[] = [TextInput, RoomNameInput]; if (textInputBasedComponents.includes(InputComponent)) { const isEffectivelyMultiline = Boolean(multiline) || Boolean(autoGrowHeight); From 326cd6164ac78ef98af364d7c50d195037756842 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Thu, 8 Feb 2024 15:39:47 +0530 Subject: [PATCH 20/20] making textInputBasedComponents global to file --- src/components/Form/InputWrapper.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Form/InputWrapper.tsx b/src/components/Form/InputWrapper.tsx index 621a448c5ac9..fc9d1773c5d8 100644 --- a/src/components/Form/InputWrapper.tsx +++ b/src/components/Form/InputWrapper.tsx @@ -7,6 +7,8 @@ import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import FormContext from './FormContext'; import type {InputWrapperProps, ValidInputs} from './types'; +const textInputBasedComponents: ValidInputs[] = [TextInput, RoomNameInput]; + function computeComponentSpecificRegistrationParams({ InputComponent, shouldSubmitForm, @@ -18,8 +20,6 @@ function computeComponentSpecificRegistrationParams( readonly blurOnSubmit: boolean | undefined; readonly shouldSetTouchedOnBlurOnly: boolean; } { - const textInputBasedComponents: ValidInputs[] = [TextInput, RoomNameInput]; - if (textInputBasedComponents.includes(InputComponent)) { const isEffectivelyMultiline = Boolean(multiline) || Boolean(autoGrowHeight);