diff --git a/src/components/MoneyRequestAmountInput.tsx b/src/components/MoneyRequestAmountInput.tsx index 48f81923a663..071f2b8745c0 100644 --- a/src/components/MoneyRequestAmountInput.tsx +++ b/src/components/MoneyRequestAmountInput.tsx @@ -2,6 +2,7 @@ import type {ForwardedRef} from 'react'; import React, {useCallback, useEffect, useImperativeHandle, useRef, useState} from 'react'; import type {NativeSyntheticEvent, StyleProp, TextInputSelectionChangeEventData, TextStyle, ViewStyle} from 'react-native'; import useLocalize from '@hooks/useLocalize'; +import {useMouseContext} from '@hooks/useMouseContext'; import * as Browser from '@libs/Browser'; import * as CurrencyUtils from '@libs/CurrencyUtils'; import getOperatingSystem from '@libs/getOperatingSystem'; @@ -258,6 +259,16 @@ function MoneyRequestAmountInput( const formattedAmount = MoneyRequestUtils.replaceAllDigits(currentAmount, toLocaleDigit); + const {setMouseDown, setMouseUp} = useMouseContext(); + const handleMouseDown = (e: React.MouseEvent) => { + e.stopPropagation(); + setMouseDown(); + }; + const handleMouseUp = (e: React.MouseEvent) => { + e.stopPropagation(); + setMouseUp(); + }; + return ( event.stopPropagation()} + onMouseDown={handleMouseDown} + onMouseUp={handleMouseUp} /> ); } diff --git a/src/components/MoneyRequestConfirmationList.tsx b/src/components/MoneyRequestConfirmationList.tsx index b18a98b13304..c0a71665f317 100755 --- a/src/components/MoneyRequestConfirmationList.tsx +++ b/src/components/MoneyRequestConfirmationList.tsx @@ -9,6 +9,7 @@ import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; import useDebouncedState from '@hooks/useDebouncedState'; import useLocalize from '@hooks/useLocalize'; +import {MouseProvider} from '@hooks/useMouseContext'; import useNetwork from '@hooks/useNetwork'; import usePermissions from '@hooks/usePermissions'; import usePrevious from '@hooks/usePrevious'; @@ -1228,17 +1229,19 @@ function MoneyRequestConfirmationList({ ); return ( - - sections={sections} - ListItem={UserListItem} - onSelectRow={navigateToReportOrUserDetail} - shouldDebounceRowSelect - canSelectMultiple={false} - shouldPreventDefaultFocusOnSelectRow - footerContent={footerContent} - listFooterContent={listFooterContent} - containerStyle={[styles.flexBasisAuto]} - /> + + + sections={sections} + ListItem={UserListItem} + onSelectRow={navigateToReportOrUserDetail} + shouldDebounceRowSelect + canSelectMultiple={false} + shouldPreventDefaultFocusOnSelectRow + footerContent={footerContent} + listFooterContent={listFooterContent} + containerStyle={[styles.flexBasisAuto]} + /> + ); } diff --git a/src/components/SelectionList/BaseListItem.tsx b/src/components/SelectionList/BaseListItem.tsx index f5e565504354..591e2c294b83 100644 --- a/src/components/SelectionList/BaseListItem.tsx +++ b/src/components/SelectionList/BaseListItem.tsx @@ -5,6 +5,7 @@ import * as Expensicons from '@components/Icon/Expensicons'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; import PressableWithFeedback from '@components/Pressable/PressableWithFeedback'; import useHover from '@hooks/useHover'; +import {useMouseContext} from '@hooks/useMouseContext'; import useSyncFocus from '@hooks/useSyncFocus'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -36,11 +37,16 @@ function BaseListItem({ const theme = useTheme(); const styles = useThemeStyles(); const {hovered, bind} = useHover(); + const {isMouseDownOnInput, setMouseUp} = useMouseContext(); const pressableRef = useRef(null); // Sync focus on an item useSyncFocus(pressableRef, Boolean(isFocused), shouldSyncFocus); + const handleMouseUp = (e: React.MouseEvent) => { + e.stopPropagation(); + setMouseUp(); + }; const rightHandSideComponentRender = () => { if (canSelectMultiple || !rightHandSideComponent) { @@ -67,6 +73,10 @@ function BaseListItem({ {...bind} ref={pressableRef} onPress={(e) => { + if (isMouseDownOnInput) { + e?.stopPropagation(); // Preventing the click action + return; + } if (shouldPreventEnterKeySubmit && e && 'key' in e && e.key === CONST.KEYBOARD_SHORTCUTS.ENTER.shortcutKey) { return; } @@ -82,6 +92,8 @@ function BaseListItem({ id={keyForList ?? ''} style={pressableStyle} onFocus={onFocus} + onMouseUp={handleMouseUp} + onMouseLeave={handleMouseUp} tabIndex={item.tabIndex} > diff --git a/src/components/TextInputWithCurrencySymbol/types.ts b/src/components/TextInputWithCurrencySymbol/types.ts index c09f392028b8..c83a7b9579ab 100644 --- a/src/components/TextInputWithCurrencySymbol/types.ts +++ b/src/components/TextInputWithCurrencySymbol/types.ts @@ -37,6 +37,11 @@ type TextInputWithCurrencySymbolProps = { */ onMouseDown?: ((e: React.MouseEvent) => void) | undefined; + /** + * Callback that is called when the text input is pressed up + */ + onMouseUp?: ((e: React.MouseEvent) => void) | undefined; + /** Whether the currency symbol is pressable */ isCurrencyPressable: boolean; diff --git a/src/hooks/useMouseContext.tsx b/src/hooks/useMouseContext.tsx new file mode 100644 index 000000000000..84889c4b59cd --- /dev/null +++ b/src/hooks/useMouseContext.tsx @@ -0,0 +1,33 @@ +import type {ReactNode} from 'react'; +import React, {createContext, useContext, useMemo, useState} from 'react'; + +type MouseContextProps = { + isMouseDownOnInput: boolean; + setMouseDown: () => void; + setMouseUp: () => void; +}; + +const MouseContext = createContext({ + isMouseDownOnInput: false, + setMouseDown: () => {}, + setMouseUp: () => {}, +}); + +type MouseProviderProps = { + children: ReactNode; +}; + +function MouseProvider({children}: MouseProviderProps) { + const [isMouseDownOnInput, setIsMouseDownOnInput] = useState(false); + + const setMouseDown = () => setIsMouseDownOnInput(true); + const setMouseUp = () => setIsMouseDownOnInput(false); + + const value = useMemo(() => ({isMouseDownOnInput, setMouseDown, setMouseUp}), [isMouseDownOnInput]); + + return {children}; +} + +const useMouseContext = () => useContext(MouseContext); + +export {MouseProvider, useMouseContext};