From b8c0c868a7d69ca10d8e2eb6771b72502ffd27c1 Mon Sep 17 00:00:00 2001 From: Huu Le <20178761+huult@users.noreply.github.com> Date: Mon, 6 Jan 2025 13:00:44 +0700 Subject: [PATCH 1/3] fix navigate to detail page on enter for highlighted item --- src/CONST.ts | 3 +++ .../Search/SearchRouter/SearchRouter.tsx | 9 ++++++++- .../Search/SearchRouter/SearchRouterInput.tsx | 19 +++++++++++++++++++ .../SelectionList/BaseSelectionList.tsx | 15 +++++++++++++-- src/components/SelectionList/types.ts | 1 + 5 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index 2d70c9355651..4da9cabada43 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -731,6 +731,9 @@ const CONST = { SHIFT: { DEFAULT: 'shift', }, + ENTER: { + DEFAULT: 'enter', + }, }, KEYBOARD_SHORTCUTS: { SEARCH: { diff --git a/src/components/Search/SearchRouter/SearchRouter.tsx b/src/components/Search/SearchRouter/SearchRouter.tsx index 4b800b637712..015b880fca72 100644 --- a/src/components/Search/SearchRouter/SearchRouter.tsx +++ b/src/components/Search/SearchRouter/SearchRouter.tsx @@ -283,7 +283,14 @@ function SearchRouter({onRouterClose, shouldHideInputCaret}: SearchRouterProps) isFullWidth={shouldUseNarrowLayout} onSearchQueryChange={onSearchQueryChange} onSubmit={() => { - submitSearch(textInputValue); + const focusedOption = listRef.current?.getFocusedOption(); + + if (!focusedOption) { + submitSearch(textInputValue); + return; + } + + onListItemPress(focusedOption); }} caretHidden={shouldHideInputCaret} routerListRef={listRef} diff --git a/src/components/Search/SearchRouter/SearchRouterInput.tsx b/src/components/Search/SearchRouter/SearchRouterInput.tsx index 3c80b3e9168e..7ad7c43acc5e 100644 --- a/src/components/Search/SearchRouter/SearchRouterInput.tsx +++ b/src/components/Search/SearchRouter/SearchRouterInput.tsx @@ -9,6 +9,7 @@ import type {BaseTextInputRef} from '@components/TextInput/BaseTextInput/types'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; +import getPlatform from '@libs/getPlatform'; import shouldDelayFocus from '@libs/shouldDelayFocus'; import variables from '@styles/variables'; import CONST from '@src/CONST'; @@ -123,6 +124,24 @@ function SearchRouterInput( }} isLoading={!!isSearchingForReports} ref={ref} + onKeyPress={(event) => { + const isWebPlatform = getPlatform() === CONST.PLATFORM.WEB; + + // Exit early if not on the web platform + if (!isWebPlatform) { + return; + } + + const isEnterKey = event.nativeEvent.key.toLowerCase() === CONST.PLATFORM_SPECIFIC_KEYS.ENTER.DEFAULT; + + // Exit if the pressed key is not Enter + if (!isEnterKey) { + return; + } + + // Perform the submit action + onSubmit(); + }} /> {!!rightComponent && {rightComponent}} diff --git a/src/components/SelectionList/BaseSelectionList.tsx b/src/components/SelectionList/BaseSelectionList.tsx index dabcaf90e4b2..ec717f5e4892 100644 --- a/src/components/SelectionList/BaseSelectionList.tsx +++ b/src/components/SelectionList/BaseSelectionList.tsx @@ -396,13 +396,23 @@ function BaseSelectionList( } }; - const selectFocusedOption = () => { + const getFocusedOption = useCallback(() => { const focusedOption = focusedIndex !== -1 ? flattenedSections.allOptions.at(focusedIndex) : undefined; if (!focusedOption || (focusedOption.isDisabled && !focusedOption.isSelected)) { return; } + return focusedOption; + }, [flattenedSections.allOptions, focusedIndex]); + + const selectFocusedOption = () => { + const focusedOption = getFocusedOption(); + + if (!focusedOption) { + return; + } + selectRow(focusedOption); }; @@ -734,12 +744,13 @@ function BaseSelectionList( isTextInputFocusedRef.current = isTextInputFocused; }, []); - useImperativeHandle(ref, () => ({scrollAndHighlightItem, clearInputAfterSelect, updateAndScrollToFocusedIndex, updateExternalTextInputFocus, scrollToIndex}), [ + useImperativeHandle(ref, () => ({scrollAndHighlightItem, clearInputAfterSelect, updateAndScrollToFocusedIndex, updateExternalTextInputFocus, scrollToIndex, getFocusedOption}), [ scrollAndHighlightItem, clearInputAfterSelect, updateAndScrollToFocusedIndex, updateExternalTextInputFocus, scrollToIndex, + getFocusedOption, ]); /** Selects row when pressing Enter */ diff --git a/src/components/SelectionList/types.ts b/src/components/SelectionList/types.ts index 3774821ce35f..19c47414b089 100644 --- a/src/components/SelectionList/types.ts +++ b/src/components/SelectionList/types.ts @@ -641,6 +641,7 @@ type SelectionListHandle = { scrollToIndex: (index: number, animated?: boolean) => void; updateAndScrollToFocusedIndex: (newFocusedIndex: number) => void; updateExternalTextInputFocus: (isTextInputFocused: boolean) => void; + getFocusedOption: () => ListItem | undefined; }; type ItemLayout = { From e5e0ea0ab98d2de8d36c20e5915cb9ca6aa1b74c Mon Sep 17 00:00:00 2001 From: Huu Le <20178761+huult@users.noreply.github.com> Date: Mon, 6 Jan 2025 14:21:38 +0700 Subject: [PATCH 2/3] fix eslint --- src/components/Search/SearchRouter/SearchRouter.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/Search/SearchRouter/SearchRouter.tsx b/src/components/Search/SearchRouter/SearchRouter.tsx index 015b880fca72..b02b457794ec 100644 --- a/src/components/Search/SearchRouter/SearchRouter.tsx +++ b/src/components/Search/SearchRouter/SearchRouter.tsx @@ -122,7 +122,11 @@ function SearchRouter({onRouterClose, shouldHideInputCaret}: SearchRouterProps) } if (reportForContextualSearch.isPolicyExpenseChat) { roomType = CONST.SEARCH.DATA_TYPES.EXPENSE; - autocompleteID = reportForContextualSearch.policyID ?? ''; + if (reportForContextualSearch.policyID) { + autocompleteID = reportForContextualSearch.policyID; + } else { + autocompleteID = ''; + } } additionalSections.push({ From 080216a6d14ef377c824d52f2c594462422692b7 Mon Sep 17 00:00:00 2001 From: Huu Le <20178761+huult@users.noreply.github.com> Date: Tue, 7 Jan 2025 09:34:22 +0700 Subject: [PATCH 3/3] add SearchInputOnKeyPress handler --- .../Search/SearchRouter/SearchRouterInput.tsx | 21 ++----------------- .../SearchInputOnKeyPress/index.native.ts | 5 +++++ src/libs/SearchInputOnKeyPress/index.ts | 16 ++++++++++++++ 3 files changed, 23 insertions(+), 19 deletions(-) create mode 100644 src/libs/SearchInputOnKeyPress/index.native.ts create mode 100644 src/libs/SearchInputOnKeyPress/index.ts diff --git a/src/components/Search/SearchRouter/SearchRouterInput.tsx b/src/components/Search/SearchRouter/SearchRouterInput.tsx index 7ad7c43acc5e..3eae84d1e401 100644 --- a/src/components/Search/SearchRouter/SearchRouterInput.tsx +++ b/src/components/Search/SearchRouter/SearchRouterInput.tsx @@ -9,7 +9,7 @@ import type {BaseTextInputRef} from '@components/TextInput/BaseTextInput/types'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; -import getPlatform from '@libs/getPlatform'; +import handleKeyPress from '@libs/SearchInputOnKeyPress'; import shouldDelayFocus from '@libs/shouldDelayFocus'; import variables from '@styles/variables'; import CONST from '@src/CONST'; @@ -124,24 +124,7 @@ function SearchRouterInput( }} isLoading={!!isSearchingForReports} ref={ref} - onKeyPress={(event) => { - const isWebPlatform = getPlatform() === CONST.PLATFORM.WEB; - - // Exit early if not on the web platform - if (!isWebPlatform) { - return; - } - - const isEnterKey = event.nativeEvent.key.toLowerCase() === CONST.PLATFORM_SPECIFIC_KEYS.ENTER.DEFAULT; - - // Exit if the pressed key is not Enter - if (!isEnterKey) { - return; - } - - // Perform the submit action - onSubmit(); - }} + onKeyPress={handleKeyPress(onSubmit)} /> {!!rightComponent && {rightComponent}} diff --git a/src/libs/SearchInputOnKeyPress/index.native.ts b/src/libs/SearchInputOnKeyPress/index.native.ts new file mode 100644 index 000000000000..3621eba63d8e --- /dev/null +++ b/src/libs/SearchInputOnKeyPress/index.native.ts @@ -0,0 +1,5 @@ +import type {NativeSyntheticEvent, TextInputKeyPressEventData} from 'react-native'; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +const handleKeyPress = (onSubmit: () => void) => (event: NativeSyntheticEvent) => {}; +export default handleKeyPress; diff --git a/src/libs/SearchInputOnKeyPress/index.ts b/src/libs/SearchInputOnKeyPress/index.ts new file mode 100644 index 000000000000..f5283719eab3 --- /dev/null +++ b/src/libs/SearchInputOnKeyPress/index.ts @@ -0,0 +1,16 @@ +import type {NativeSyntheticEvent, TextInputKeyPressEventData} from 'react-native'; +import CONST from '@src/CONST'; + +function handleKeyPress(onSubmit: () => void) { + return (event: NativeSyntheticEvent) => { + const isEnterKey = event.nativeEvent.key.toLowerCase() === CONST.PLATFORM_SPECIFIC_KEYS.ENTER.DEFAULT; + + if (!isEnterKey) { + return; + } + + onSubmit(); + }; +} + +export default handleKeyPress;