diff --git a/src/components/Explore/ExploreV2/screens/UniversalSearch.tsx b/src/components/Explore/ExploreV2/screens/UniversalSearch.tsx index 8ffe931af..6aa53e885 100644 --- a/src/components/Explore/ExploreV2/screens/UniversalSearch.tsx +++ b/src/components/Explore/ExploreV2/screens/UniversalSearch.tsx @@ -60,6 +60,7 @@ const UniversalSearch = ( ) => { const [taxonText, setTaxonText] = useState( "" ); const [locationText, setLocationText] = useState( "" ); + const [filledFromSelection, setFilledFromSelection] = useState( false ); // The debounced value that actually drives the autocomplete query. Cleared on // selection so a chosen suggestion doesn't re-trigger a result list. const { @@ -77,11 +78,20 @@ const UniversalSearch = ( ) => { const handleTaxonTextChange = useCallback( ( text: string ) => { setTaxonText( text ); + setFilledFromSelection( false ); debounceQuery( text ); }, [debounceQuery] ); + const handleTaxonFocus = useCallback( ( ) => { + if ( !filledFromSelection ) { return; } + setTaxonText( "" ); + setFilledFromSelection( false ); + setQueryImmediately( "" ); + }, [filledFromSelection, setQueryImmediately] ); + const handleSelect = useCallback( ( subject: ExploreV2Subject ) => { setTaxonText( subjectToText( subject, commonNameIsPrimary ) ); + setFilledFromSelection( true ); setQueryImmediately( "" ); dispatch( { type: EXPLORE_V2_ACTION.SET_SUBJECT, subject } ); locationInputRef.current?.focus( ); @@ -90,6 +100,7 @@ const UniversalSearch = ( ) => { const handleReset = useCallback( ( ) => { setTaxonText( "" ); setLocationText( "" ); + setFilledFromSelection( false ); setQueryImmediately( "" ); }, [setQueryImmediately] ); @@ -145,6 +156,7 @@ const UniversalSearch = ( ) => { className="flex-1 ml-2 text-md font-Lato-Regular" numberOfLines={1} onChangeText={handleTaxonTextChange} + onFocus={handleTaxonFocus} placeholder={t( "Search-for-species-user-or-project" )} placeholderTextColor={colors.mediumGray} testID="UniversalSearch.taxonInput" diff --git a/tests/unit/components/Explore/ExploreV2/screens/UniversalSearch.test.js b/tests/unit/components/Explore/ExploreV2/screens/UniversalSearch.test.js index dbd80fa48..9892c785a 100644 --- a/tests/unit/components/Explore/ExploreV2/screens/UniversalSearch.test.js +++ b/tests/unit/components/Explore/ExploreV2/screens/UniversalSearch.test.js @@ -179,6 +179,27 @@ describe( "UniversalSearch screen", ( ) => { expect( screen.getByDisplayValue( "carrieseltzer" ) ).toBeTruthy( ); } ); + it( "clears the field but keeps the subject when tapping back in after a selection", ( ) => { + useUniversalSearch.mockReturnValue( { + results: MIXED_RESULTS, + isLoading: false, + refetch: jest.fn( ), + } ); + renderComponent( ); + + typeQuery( "ver" ); + fireEvent.press( screen.getByTestId( "UniversalSearchResult.user.7" ) ); + expect( screen.getByDisplayValue( "carrieseltzer" ) ).toBeTruthy( ); + + mockDispatch.mockClear( ); + fireEvent( screen.getByTestId( "UniversalSearch.taxonInput" ), "focus" ); + + // the field is cleared for a fresh search... + expect( screen.queryByDisplayValue( "carrieseltzer" ) ).toBeNull( ); + // ...but the committed subject persists (only Reset / a new selection clears it) + expect( mockDispatch ).not.toHaveBeenCalledWith( { type: "CLEAR_SUBJECT" } ); + } ); + it( "navigates to Advanced Search", ( ) => { renderComponent( );