From 40aaf0f79c9c16f34bf3713ae8c55ebc7ec05b81 Mon Sep 17 00:00:00 2001 From: dragnoir Date: Mon, 20 May 2024 20:29:09 +0100 Subject: [PATCH 1/8] progress.. --- src/components/SelectionList/BaseListItem.tsx | 7 + src/components/SelectionList/UserListItem.tsx | 179 +++++++++--------- .../BaseTextInputWithCurrencySymbol.tsx | 8 + src/hooks/useMouseContext.tsx | 21 ++ 4 files changed, 127 insertions(+), 88 deletions(-) create mode 100644 src/hooks/useMouseContext.tsx diff --git a/src/components/SelectionList/BaseListItem.tsx b/src/components/SelectionList/BaseListItem.tsx index 5876e476afa2..90b3c66c6a4e 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,6 +37,7 @@ function BaseListItem({ const theme = useTheme(); const styles = useThemeStyles(); const {hovered, bind} = useHover(); + const {isMouseDownOnInput} = useMouseContext(); const pressableRef = useRef(null); @@ -67,6 +69,11 @@ function BaseListItem({ {...bind} ref={pressableRef} onPress={(e) => { + if (isMouseDownOnInput) { + e.stopPropagation(); // Preventing the click action + console.log('Click prevented due to mouse down on input'); + return; + } if (shouldPreventEnterKeySubmit && e && 'key' in e && e.key === CONST.KEYBOARD_SHORTCUTS.ENTER.shortcutKey) { return; } diff --git a/src/components/SelectionList/UserListItem.tsx b/src/components/SelectionList/UserListItem.tsx index a517a9f1ca15..255909a10752 100644 --- a/src/components/SelectionList/UserListItem.tsx +++ b/src/components/SelectionList/UserListItem.tsx @@ -9,6 +9,7 @@ import SubscriptAvatar from '@components/SubscriptAvatar'; import Text from '@components/Text'; import TextWithTooltip from '@components/TextWithTooltip'; import useLocalize from '@hooks/useLocalize'; +import {MouseProvider} from '@hooks/useMouseContext'; import useStyleUtils from '@hooks/useStyleUtils'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -49,97 +50,99 @@ function UserListItem({ }, [item, onCheckboxPress, onSelectRow]); return ( - - {translate('workspace.people.invitedBySecondaryLogin', {secondaryLogin: item.invitedSecondaryLogin})} - - ) : undefined - } - keyForList={item.keyForList} - onFocus={onFocus} - shouldSyncFocus={shouldSyncFocus} - > - {(hovered?: boolean) => ( - <> - {canSelectMultiple && ( - - - {item.isSelected && ( - - )} - - - )} - {!!item.icons && - (item.shouldShowSubscript ? ( - - ) : ( - - ))} - - - {!!item.alternateText && ( + + + {translate('workspace.people.invitedBySecondaryLogin', {secondaryLogin: item.invitedSecondaryLogin})} + + ) : undefined + } + keyForList={item.keyForList} + onFocus={onFocus} + shouldSyncFocus={shouldSyncFocus} + > + {(hovered?: boolean) => ( + <> + {canSelectMultiple && ( + + + {item.isSelected && ( + + )} + + + )} + {!!item.icons && + (item.shouldShowSubscript ? ( + + ) : ( + + ))} + - )} - - {!!item.rightElement && item.rightElement} - - )} - + {!!item.alternateText && ( + + )} + + {!!item.rightElement && item.rightElement} + + )} + + ); } diff --git a/src/components/TextInputWithCurrencySymbol/BaseTextInputWithCurrencySymbol.tsx b/src/components/TextInputWithCurrencySymbol/BaseTextInputWithCurrencySymbol.tsx index 3e7c5f0bc414..dc8c91227646 100644 --- a/src/components/TextInputWithCurrencySymbol/BaseTextInputWithCurrencySymbol.tsx +++ b/src/components/TextInputWithCurrencySymbol/BaseTextInputWithCurrencySymbol.tsx @@ -3,6 +3,7 @@ import type {NativeSyntheticEvent, TextInputSelectionChangeEventData} from 'reac import AmountTextInput from '@components/AmountTextInput'; import CurrencySymbolButton from '@components/CurrencySymbolButton'; import useLocalize from '@hooks/useLocalize'; +import {useMouseContext} from '@hooks/useMouseContext'; import useThemeStyles from '@hooks/useThemeStyles'; import * as CurrencyUtils from '@libs/CurrencyUtils'; import * as MoneyRequestUtils from '@libs/MoneyRequestUtils'; @@ -32,6 +33,8 @@ function BaseTextInputWithCurrencySymbol( const isCurrencySymbolLTR = CurrencyUtils.isCurrencySymbolLTR(selectedCurrencyCode); const styles = useThemeStyles(); + const {setMouseDown, setMouseUp} = useMouseContext(); + const currencySymbolButton = !hideCurrencySymbol && ( { + setMouseDown(); + console.log('mousedown'); + }} + onMouseUp={setMouseUp} // eslint-disable-next-line react/jsx-props-no-spreading {...rest} /> diff --git a/src/hooks/useMouseContext.tsx b/src/hooks/useMouseContext.tsx new file mode 100644 index 000000000000..0e0dbda55248 --- /dev/null +++ b/src/hooks/useMouseContext.tsx @@ -0,0 +1,21 @@ +import React, {createContext, useContext, useState} from 'react'; + +// Create a context with default values and handlers +const MouseContext = createContext({ + isMouseDownOnInput: false, + setMouseDown: () => {}, + setMouseUp: () => {}, +}); + +// Context provider component +export const MouseProvider = ({children}) => { + const [isMouseDownOnInput, setIsMouseDownOnInput] = useState(false); + + const setMouseDown = () => setIsMouseDownOnInput(true); + const setMouseUp = () => setIsMouseDownOnInput(false); + + return {children}; +}; + +// Custom hook to use the mouse context +export const useMouseContext = () => useContext(MouseContext); From 3f7fb920963b24686e5f26c01303b4cac4bc710a Mon Sep 17 00:00:00 2001 From: dragnoir Date: Tue, 21 May 2024 10:39:27 +0100 Subject: [PATCH 2/8] fix mouse leave --- src/components/MoneyRequestAmountInput.tsx | 18 +- .../MoneyRequestConfirmationList.tsx | 23 ++- src/components/SelectionList/BaseListItem.tsx | 13 +- src/components/SelectionList/UserListItem.tsx | 179 +++++++++--------- .../BaseTextInputWithCurrencySymbol.tsx | 8 - 5 files changed, 130 insertions(+), 111 deletions(-) diff --git a/src/components/MoneyRequestAmountInput.tsx b/src/components/MoneyRequestAmountInput.tsx index 9acd73beadba..00fdfcb55cf1 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'; @@ -246,6 +247,20 @@ function MoneyRequestAmountInput( const formattedAmount = MoneyRequestUtils.replaceAllDigits(currentAmount, toLocaleDigit); + const {setMouseDown, setMouseUp} = useMouseContext(); + const handleMouseDown = (e: React.MouseEvent) => { + e.stopPropagation(); + // eslint-disable-next-line no-console + console.log('mouse down on TextInputWithCurrencySymbol'); + setMouseDown(); + }; + const handleMouseUp = (e: React.MouseEvent) => { + e.stopPropagation(); + // eslint-disable-next-line no-console + console.log('mouse up on TextInputWithCurrencySymbol'); + setMouseUp(); + }; + return ( event.stopPropagation()} + onMouseDown={handleMouseDown} + onMouseUp={handleMouseUp} /> ); } diff --git a/src/components/MoneyRequestConfirmationList.tsx b/src/components/MoneyRequestConfirmationList.tsx index 33f1258e60c7..91b43aeafd52 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'; @@ -1225,16 +1226,18 @@ function MoneyRequestConfirmationList({ ); return ( - - sections={sections} - ListItem={UserListItem} - onSelectRow={navigateToReportOrUserDetail} - canSelectMultiple={false} - shouldPreventDefaultFocusOnSelectRow - footerContent={footerContent} - listFooterContent={listFooterContent} - containerStyle={[styles.flexBasisAuto]} - /> + + + sections={sections} + ListItem={UserListItem} + onSelectRow={navigateToReportOrUserDetail} + 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 90b3c66c6a4e..dd5962f9e0ef 100644 --- a/src/components/SelectionList/BaseListItem.tsx +++ b/src/components/SelectionList/BaseListItem.tsx @@ -44,6 +44,14 @@ function BaseListItem({ // Sync focus on an item useSyncFocus(pressableRef, Boolean(isFocused), shouldSyncFocus); + const {setMouseUp} = useMouseContext(); + const handleMouseUp = (e: React.MouseEvent) => { + e.stopPropagation(); + // eslint-disable-next-line no-console + console.log('mouse up on BaseListItem'); + setMouseUp(); + }; + const rightHandSideComponentRender = () => { if (canSelectMultiple || !rightHandSideComponent) { return null; @@ -70,7 +78,8 @@ function BaseListItem({ ref={pressableRef} onPress={(e) => { if (isMouseDownOnInput) { - e.stopPropagation(); // Preventing the click action + e?.stopPropagation(); // Preventing the click action + // eslint-disable-next-line no-console console.log('Click prevented due to mouse down on input'); return; } @@ -89,6 +98,8 @@ function BaseListItem({ id={keyForList ?? ''} style={pressableStyle} onFocus={onFocus} + onMouseUp={handleMouseUp} + onMouseLeave={handleMouseUp} > {typeof children === 'function' ? children(hovered) : children} diff --git a/src/components/SelectionList/UserListItem.tsx b/src/components/SelectionList/UserListItem.tsx index 255909a10752..a517a9f1ca15 100644 --- a/src/components/SelectionList/UserListItem.tsx +++ b/src/components/SelectionList/UserListItem.tsx @@ -9,7 +9,6 @@ import SubscriptAvatar from '@components/SubscriptAvatar'; import Text from '@components/Text'; import TextWithTooltip from '@components/TextWithTooltip'; import useLocalize from '@hooks/useLocalize'; -import {MouseProvider} from '@hooks/useMouseContext'; import useStyleUtils from '@hooks/useStyleUtils'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -50,99 +49,97 @@ function UserListItem({ }, [item, onCheckboxPress, onSelectRow]); return ( - - - {translate('workspace.people.invitedBySecondaryLogin', {secondaryLogin: item.invitedSecondaryLogin})} - - ) : undefined - } - keyForList={item.keyForList} - onFocus={onFocus} - shouldSyncFocus={shouldSyncFocus} - > - {(hovered?: boolean) => ( - <> - {canSelectMultiple && ( - - - {item.isSelected && ( - - )} - - - )} - {!!item.icons && - (item.shouldShowSubscript ? ( - - ) : ( - - ))} - - + {translate('workspace.people.invitedBySecondaryLogin', {secondaryLogin: item.invitedSecondaryLogin})} + + ) : undefined + } + keyForList={item.keyForList} + onFocus={onFocus} + shouldSyncFocus={shouldSyncFocus} + > + {(hovered?: boolean) => ( + <> + {canSelectMultiple && ( + + + {item.isSelected && ( + + )} + + + )} + {!!item.icons && + (item.shouldShowSubscript ? ( + + ) : ( + - {!!item.alternateText && ( - - )} - - {!!item.rightElement && item.rightElement} - - )} - - + ))} + + + {!!item.alternateText && ( + + )} + + {!!item.rightElement && item.rightElement} + + )} + ); } diff --git a/src/components/TextInputWithCurrencySymbol/BaseTextInputWithCurrencySymbol.tsx b/src/components/TextInputWithCurrencySymbol/BaseTextInputWithCurrencySymbol.tsx index dc8c91227646..3e7c5f0bc414 100644 --- a/src/components/TextInputWithCurrencySymbol/BaseTextInputWithCurrencySymbol.tsx +++ b/src/components/TextInputWithCurrencySymbol/BaseTextInputWithCurrencySymbol.tsx @@ -3,7 +3,6 @@ import type {NativeSyntheticEvent, TextInputSelectionChangeEventData} from 'reac import AmountTextInput from '@components/AmountTextInput'; import CurrencySymbolButton from '@components/CurrencySymbolButton'; import useLocalize from '@hooks/useLocalize'; -import {useMouseContext} from '@hooks/useMouseContext'; import useThemeStyles from '@hooks/useThemeStyles'; import * as CurrencyUtils from '@libs/CurrencyUtils'; import * as MoneyRequestUtils from '@libs/MoneyRequestUtils'; @@ -33,8 +32,6 @@ function BaseTextInputWithCurrencySymbol( const isCurrencySymbolLTR = CurrencyUtils.isCurrencySymbolLTR(selectedCurrencyCode); const styles = useThemeStyles(); - const {setMouseDown, setMouseUp} = useMouseContext(); - const currencySymbolButton = !hideCurrencySymbol && ( { - setMouseDown(); - console.log('mousedown'); - }} - onMouseUp={setMouseUp} // eslint-disable-next-line react/jsx-props-no-spreading {...rest} /> From bb768a43e4ee7b2f308da6549290e1e4fe0e0451 Mon Sep 17 00:00:00 2001 From: dragnoir Date: Thu, 30 May 2024 10:34:05 +0100 Subject: [PATCH 3/8] lint --- .../MoneyRequestConfirmationList.tsx | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/components/MoneyRequestConfirmationList.tsx b/src/components/MoneyRequestConfirmationList.tsx index a153044db21c..c0a71665f317 100755 --- a/src/components/MoneyRequestConfirmationList.tsx +++ b/src/components/MoneyRequestConfirmationList.tsx @@ -1230,17 +1230,17 @@ 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]} + /> ); } From fd90cede839adf644cda9979b61e5ad448190337 Mon Sep 17 00:00:00 2001 From: dragnoir Date: Thu, 30 May 2024 11:13:03 +0100 Subject: [PATCH 4/8] fix ts --- .../TextInputWithCurrencySymbol/types.ts | 5 ++++ src/hooks/useMouseContext.tsx | 27 ++++++++++++++----- 2 files changed, 26 insertions(+), 6 deletions(-) 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 index 0e0dbda55248..5a1dc3d8a106 100644 --- a/src/hooks/useMouseContext.tsx +++ b/src/hooks/useMouseContext.tsx @@ -1,21 +1,36 @@ -import React, {createContext, useContext, useState} from 'react'; +import type {ReactNode} from 'react'; +import React, {createContext, useContext, useMemo, useState} from 'react'; + +type MouseContextProps = { + isMouseDownOnInput: boolean; + setMouseDown: () => void; + setMouseUp: () => void; +}; // Create a context with default values and handlers -const MouseContext = createContext({ +const MouseContext = createContext({ isMouseDownOnInput: false, setMouseDown: () => {}, setMouseUp: () => {}, }); +type MouseProviderProps = { + children: ReactNode; +}; + // Context provider component -export const MouseProvider = ({children}) => { +function MouseProvider({children}: MouseProviderProps) { const [isMouseDownOnInput, setIsMouseDownOnInput] = useState(false); const setMouseDown = () => setIsMouseDownOnInput(true); const setMouseUp = () => setIsMouseDownOnInput(false); - return {children}; -}; + const value = useMemo(() => ({isMouseDownOnInput, setMouseDown, setMouseUp}), [isMouseDownOnInput]); + + return {children}; +} // Custom hook to use the mouse context -export const useMouseContext = () => useContext(MouseContext); +const useMouseContext = () => useContext(MouseContext); + +export {MouseProvider, useMouseContext}; From c0701b36f7eaedba723d181d18e0f2b843457236 Mon Sep 17 00:00:00 2001 From: dragnoir Date: Thu, 30 May 2024 12:58:54 +0100 Subject: [PATCH 5/8] remove console.log --- src/components/MoneyRequestAmountInput.tsx | 4 ---- src/components/SelectionList/BaseListItem.tsx | 4 ---- 2 files changed, 8 deletions(-) diff --git a/src/components/MoneyRequestAmountInput.tsx b/src/components/MoneyRequestAmountInput.tsx index 2626035a43d1..071f2b8745c0 100644 --- a/src/components/MoneyRequestAmountInput.tsx +++ b/src/components/MoneyRequestAmountInput.tsx @@ -262,14 +262,10 @@ function MoneyRequestAmountInput( const {setMouseDown, setMouseUp} = useMouseContext(); const handleMouseDown = (e: React.MouseEvent) => { e.stopPropagation(); - // eslint-disable-next-line no-console - console.log('mouse down on TextInputWithCurrencySymbol'); setMouseDown(); }; const handleMouseUp = (e: React.MouseEvent) => { e.stopPropagation(); - // eslint-disable-next-line no-console - console.log('mouse up on TextInputWithCurrencySymbol'); setMouseUp(); }; diff --git a/src/components/SelectionList/BaseListItem.tsx b/src/components/SelectionList/BaseListItem.tsx index 9d51c795afe1..92c9bf03efaa 100644 --- a/src/components/SelectionList/BaseListItem.tsx +++ b/src/components/SelectionList/BaseListItem.tsx @@ -47,8 +47,6 @@ function BaseListItem({ const {setMouseUp} = useMouseContext(); const handleMouseUp = (e: React.MouseEvent) => { e.stopPropagation(); - // eslint-disable-next-line no-console - console.log('mouse up on BaseListItem'); setMouseUp(); }; @@ -79,8 +77,6 @@ function BaseListItem({ onPress={(e) => { if (isMouseDownOnInput) { e?.stopPropagation(); // Preventing the click action - // eslint-disable-next-line no-console - console.log('Click prevented due to mouse down on input'); return; } if (shouldPreventEnterKeySubmit && e && 'key' in e && e.key === CONST.KEYBOARD_SHORTCUTS.ENTER.shortcutKey) { From f715455fcaae5caa8e9a0fd20f84af7ab2fa0362 Mon Sep 17 00:00:00 2001 From: dragnoir Date: Thu, 30 May 2024 18:03:42 +0100 Subject: [PATCH 6/8] removce comments --- src/hooks/useMouseContext.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/hooks/useMouseContext.tsx b/src/hooks/useMouseContext.tsx index 5a1dc3d8a106..6af09ce3fd46 100644 --- a/src/hooks/useMouseContext.tsx +++ b/src/hooks/useMouseContext.tsx @@ -7,7 +7,6 @@ type MouseContextProps = { setMouseUp: () => void; }; -// Create a context with default values and handlers const MouseContext = createContext({ isMouseDownOnInput: false, setMouseDown: () => {}, @@ -18,7 +17,6 @@ type MouseProviderProps = { children: ReactNode; }; -// Context provider component function MouseProvider({children}: MouseProviderProps) { const [isMouseDownOnInput, setIsMouseDownOnInput] = useState(false); From af76e428be9bff323d19257968578a318fb927df Mon Sep 17 00:00:00 2001 From: dragnoir Date: Thu, 30 May 2024 18:04:53 +0100 Subject: [PATCH 7/8] remove comment --- src/hooks/useMouseContext.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hooks/useMouseContext.tsx b/src/hooks/useMouseContext.tsx index 6af09ce3fd46..84889c4b59cd 100644 --- a/src/hooks/useMouseContext.tsx +++ b/src/hooks/useMouseContext.tsx @@ -28,7 +28,6 @@ function MouseProvider({children}: MouseProviderProps) { return {children}; } -// Custom hook to use the mouse context const useMouseContext = () => useContext(MouseContext); export {MouseProvider, useMouseContext}; From 01f3ae81e5d203e5c9609eaaed9230f28e64696f Mon Sep 17 00:00:00 2001 From: dragnoir Date: Thu, 30 May 2024 18:05:44 +0100 Subject: [PATCH 8/8] fix code --- src/components/SelectionList/BaseListItem.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/SelectionList/BaseListItem.tsx b/src/components/SelectionList/BaseListItem.tsx index 92c9bf03efaa..591e2c294b83 100644 --- a/src/components/SelectionList/BaseListItem.tsx +++ b/src/components/SelectionList/BaseListItem.tsx @@ -37,14 +37,12 @@ function BaseListItem({ const theme = useTheme(); const styles = useThemeStyles(); const {hovered, bind} = useHover(); - const {isMouseDownOnInput} = useMouseContext(); + const {isMouseDownOnInput, setMouseUp} = useMouseContext(); const pressableRef = useRef(null); // Sync focus on an item useSyncFocus(pressableRef, Boolean(isFocused), shouldSyncFocus); - - const {setMouseUp} = useMouseContext(); const handleMouseUp = (e: React.MouseEvent) => { e.stopPropagation(); setMouseUp();