From 13b8f8cb370f330f1b3c4c00e3bddc3279f34c8b Mon Sep 17 00:00:00 2001 From: "Rushat Gabhane (via MelvinBot)" Date: Mon, 9 Mar 2026 02:33:43 +0000 Subject: [PATCH 1/2] Remove disableKeyboard and preventDefault workarounds from DatePicker Instead of using disableKeyboard and event.preventDefault() to prevent cursor/keyboard when clicking the DatePicker, use readOnly on the TextInput and skip focus in BaseTextInput when the input is readOnly. Also change the DatePicker role from PRESENTATION to COMBOBOX for better screen reader semantics. Co-authored-by: Rushat Gabhane --- src/components/DatePicker/index.tsx | 18 ++++++------------ .../implementation/index.native.tsx | 2 +- .../BaseTextInput/implementation/index.tsx | 2 +- 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/src/components/DatePicker/index.tsx b/src/components/DatePicker/index.tsx index fea272ce5de2..70a3706a5314 100644 --- a/src/components/DatePicker/index.tsx +++ b/src/components/DatePicker/index.tsx @@ -1,6 +1,5 @@ import {format, setYear} from 'date-fns'; import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react'; -import type {GestureResponderEvent} from 'react-native'; import {InteractionManager, View} from 'react-native'; import TextInput from '@components/TextInput'; import type {BaseTextInputRef} from '@components/TextInput/BaseTextInput/types'; @@ -71,15 +70,10 @@ function DatePicker({ }); }, [windowHeight]); - const handlePress = useCallback( - (event?: GestureResponderEvent | KeyboardEvent) => { - // This makes sure that cursor does not appear in the TextInput when we open the DatePicker - event?.preventDefault(); - calculatePopoverPosition(); - setIsModalVisible(true); - }, - [calculatePopoverPosition], - ); + const handlePress = useCallback(() => { + calculatePopoverPosition(); + setIsModalVisible(true); + }, [calculatePopoverPosition]); const closeDatePicker = useCallback(() => { textInputRef.current?.blur(); @@ -139,7 +133,7 @@ function DatePicker({ iconContainerStyle={styles.pr0} label={label} accessibilityLabel={label} - role={CONST.ROLE.PRESENTATION} + role={CONST.ROLE.COMBOBOX} value={selectedDate} placeholder={placeholder ?? translate('common.dateFormat')} errorText={errorText} @@ -151,7 +145,7 @@ function DatePicker({ onClearInput={handleClear} forwardedFSClass={forwardedFSClass} autoComplete={autoComplete} - disableKeyboard + readOnly /> diff --git a/src/components/TextInput/BaseTextInput/implementation/index.native.tsx b/src/components/TextInput/BaseTextInput/implementation/index.native.tsx index 7bd7d1b169f0..cd774811786d 100644 --- a/src/components/TextInput/BaseTextInput/implementation/index.native.tsx +++ b/src/components/TextInput/BaseTextInput/implementation/index.native.tsx @@ -173,7 +173,7 @@ function BaseTextInput({ inputProps.onPress?.(event); - if ('isDefaultPrevented' in event && !event?.isDefaultPrevented()) { + if ('isDefaultPrevented' in event && !event?.isDefaultPrevented() && !isReadOnly) { input.current?.focus(); } }; diff --git a/src/components/TextInput/BaseTextInput/implementation/index.tsx b/src/components/TextInput/BaseTextInput/implementation/index.tsx index 0adb1eaa6049..d3c829a4e87a 100644 --- a/src/components/TextInput/BaseTextInput/implementation/index.tsx +++ b/src/components/TextInput/BaseTextInput/implementation/index.tsx @@ -192,7 +192,7 @@ function BaseTextInput({ inputProps.onPress?.(event); - if ('isDefaultPrevented' in event && !event?.isDefaultPrevented()) { + if ('isDefaultPrevented' in event && !event?.isDefaultPrevented() && !isReadOnly) { input.current?.focus(); } }; From 1fb1d3c4c9c5dd22a23dce3ac76bc80ea92a47aa Mon Sep 17 00:00:00 2001 From: "Rushat Gabhane (via MelvinBot)" Date: Mon, 9 Mar 2026 02:47:01 +0000 Subject: [PATCH 2/2] Fix: Move isReadOnly declaration before its first usage Fixes no-use-before-define ESLint error by moving the isReadOnly const declaration above the onPress function that references it. Co-authored-by: Rushat Gabhane --- .../TextInput/BaseTextInput/implementation/index.native.tsx | 3 ++- .../TextInput/BaseTextInput/implementation/index.tsx | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/TextInput/BaseTextInput/implementation/index.native.tsx b/src/components/TextInput/BaseTextInput/implementation/index.native.tsx index cd774811786d..7c51ca4bd8fb 100644 --- a/src/components/TextInput/BaseTextInput/implementation/index.native.tsx +++ b/src/components/TextInput/BaseTextInput/implementation/index.native.tsx @@ -166,6 +166,8 @@ function BaseTextInput({ setIsFocused(false); }; + const isReadOnly = inputProps.readOnly ?? inputProps.disabled; + const onPress = (event?: GestureResponderEvent | KeyboardEvent) => { if (!!inputProps.disabled || !event) { return; @@ -256,7 +258,6 @@ function BaseTextInput({ }, []); const shouldAddPaddingBottom = isMultiline || (autoGrowHeight && !isAutoGrowHeightMarkdown && textInputHeight > variables.componentSizeLarge); - const isReadOnly = inputProps.readOnly ?? inputProps.disabled; // Disabling this line for safeness as nullish coalescing works only if the value is undefined or null, and errorText can be an empty string // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing const inputHelpText = errorText || hint; diff --git a/src/components/TextInput/BaseTextInput/implementation/index.tsx b/src/components/TextInput/BaseTextInput/implementation/index.tsx index d3c829a4e87a..2fcc33378632 100644 --- a/src/components/TextInput/BaseTextInput/implementation/index.tsx +++ b/src/components/TextInput/BaseTextInput/implementation/index.tsx @@ -185,6 +185,8 @@ function BaseTextInput({ setIsFocused(false); }; + const isReadOnly = inputProps.readOnly ?? inputProps.disabled; + const onPress = (event?: GestureResponderEvent | KeyboardEvent) => { if (!!inputProps.disabled || !event) { return; @@ -293,7 +295,6 @@ function BaseTextInput({ const shouldAddPaddingBottom = isMultiline || (autoGrowHeight && !isAutoGrowHeightMarkdown && textInputHeight > variables.componentSizeLarge); const hasLabel = !!label?.length; - const isReadOnly = inputProps.readOnly ?? inputProps.disabled; // Disabling this line for safeness as nullish coalescing works only if the value is undefined or null, and errorText can be an empty string // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing const inputHelpText = errorText || hint;