import React, { useEffect, useRef, useState } from 'react'; import { Pressable, StyleSheet, View } from 'react-native'; import { Logger } from '../../utils/Log'; import { Strings } from '../../resources/localization/Strings'; import { setSearchQuery } from '../../store/search/searchSlice'; import { BackButtonHandler, IBackButtonHandlerProps, } from '../common/BackButtonHandler'; import { useDebounce } from '../common/hooks/useDebounce'; import Icon from 'react-native-vector-icons/Ionicons'; import { useRoute } from '@react-navigation/native'; import { useAppDispatch } from '../../store/hooks'; import { TextInput } from 'react-native-paper'; const logger = new Logger('SearchBar'); /** * This is the Props interface for the Contacts Class * * @interface ISearchBarProps * @field {(value: boolean, searchQuery: string): void} onSearchUpdated handle when the search is on updated. * @field {(): void} onCancelSearch handle when canceling the search operation. */ interface ISearchBarProps extends IBackButtonHandlerProps { onSearchUpdated(value: boolean, searchQuery: string): void; onCancelSearch(): void; rightElement?: React.ReactElement; leftIcon?: React.ReactElement; rightIcon?: React.ReactElement; } /** * @module * @name SearchBarView * @version SDKVERSION * @public * @description * This Component is used for showing the search text bar, and this is where the search query is handled */ export const SearchBarInput: React.FunctionComponent = ({ onSearchUpdated, onCancelSearch, registerBackButtonHandler, rightElement, leftIcon, rightIcon }) => { const dispatch = useAppDispatch(); const inputWidth = rightElement ? '85%' : '95%'; const currentRoute = useRoute(); const searchInput = useRef(); const [searchBarState, setSearchBarState] = useState({ searchMode: false, intermediateSearchQuery: '', }); const debounceSearchQuery = useDebounce( searchBarState.intermediateSearchQuery, 1000 ); const didStartSearch = searchBarState.searchMode && searchBarState.intermediateSearchQuery.length !== 0; useEffect(() => { logger.debug(`denouncedSearchQuery changed ${debounceSearchQuery}`); dispatch(setSearchQuery(debounceSearchQuery)); }, [debounceSearchQuery, didStartSearch]); const onSearchQueryChanged = (text: string) => { setSearchBarState({ ...searchBarState, intermediateSearchQuery: text, searchMode: true, }); onSearchUpdated( searchBarState.searchMode, searchBarState.intermediateSearchQuery ); }; const clearSearchInput = () => { if (searchInput.current) { searchInput.current.clear(); } setSearchBarState({ ...searchBarState, intermediateSearchQuery: '', searchMode: false, }); onSearchUpdated( searchBarState.searchMode, searchBarState.intermediateSearchQuery ); }; const cancelSearch = () => { clearSearchInput(); onCancelSearch(); // To handle routing in the app }; const onBackButtonPressed = () => { logger.info('onBackButtonPressed handled by searchBar:'); if (searchBarState.searchMode && currentRoute.name === 'ContactInformation') { return false; // Handled by the home component. } if (searchBarState.searchMode) { cancelSearch(); return true; } return false; }; const renderLeftIcon = () => { if (leftIcon) { return leftIcon; } return ; }; const renderRightIcon = () => { if (rightIcon) { return rightIcon; } if (didStartSearch) { return ( ); } return <>; }; return ( renderLeftIcon()} />} right={ renderRightIcon()} />} onChangeText={onSearchQueryChanged} ref={searchInput} /> {rightElement} ); }; const styles = StyleSheet.create({ searchBarContainer: { display: 'flex', flexDirection: 'row', justifyContent: 'space-evenly', }, searchInput: { borderRadius: 10, paddingVertical: 6, paddingHorizontal: 8, width: '95%', height: 30, backgroundColor: '#fff' } });