// Copyright 2021 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only import React, { useEffect, useRef } from 'react'; import type { ConversationType, ShowConversationType, } from '../state/ducks/conversations'; import type { LocalizerType } from '../types/Util'; import { Avatar, AvatarSize } from './Avatar'; import { SearchInput } from './SearchInput'; import { usePrevious } from '../hooks/usePrevious'; type PropsType = { clearConversationSearch: () => void; clearSearch: () => void; disabled?: boolean; i18n: LocalizerType; onEnterKeyDown?: ( clearSearch: () => void, showConversation: ShowConversationType ) => void; searchConversation?: ConversationType; searchTerm: string; showConversation: ShowConversationType; startSearchCounter: number; updateSearchTerm: (searchTerm: string) => void; }; export function LeftPaneSearchInput({ clearConversationSearch, clearSearch, disabled, i18n, onEnterKeyDown, searchConversation, searchTerm, showConversation, startSearchCounter, updateSearchTerm, }: PropsType): JSX.Element { const inputRef = useRef(null); const prevSearchConversationId = usePrevious( undefined, searchConversation?.id ); const prevSearchCounter = usePrevious(startSearchCounter, startSearchCounter); useEffect(() => { // When user chooses to search in a given conversation we focus the field for them if ( searchConversation && searchConversation.id !== prevSearchConversationId ) { inputRef.current?.focus(); } // When user chooses to start a new search, we focus the field if (startSearchCounter !== prevSearchCounter) { inputRef.current?.select(); } }, [ prevSearchConversationId, prevSearchCounter, searchConversation, startSearchCounter, ]); const changeValue = (nextSearchTerm: string) => { if (!nextSearchTerm) { if (searchConversation) { clearConversationSearch(); } else { clearSearch(); } return; } if (updateSearchTerm) { updateSearchTerm(nextSearchTerm); } }; const clearAndFocus = () => { clearSearch(); inputRef.current?.focus(); }; const label = searchConversation ? i18n('icu:searchIn') : i18n('icu:search'); return ( { if (!searchConversation && !searchTerm) { clearSearch(); } }} onKeyDown={event => { if (onEnterKeyDown && event.key === 'Enter') { onEnterKeyDown(clearSearch, showConversation); event.preventDefault(); event.stopPropagation(); } }} onChange={event => { changeValue(event.currentTarget.value); }} onClear={() => { if (searchConversation && searchTerm) { changeValue(''); } else { clearAndFocus(); } }} ref={inputRef} placeholder={label} value={searchTerm} > {searchConversation && ( // Clicking the non-X part of the pill should focus the input but have a normal // cursor. This effectively simulates `pointer-events: none` while still // letting us change the cursor. // eslint-disable-next-line max-len // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
{ inputRef.current?.focus(); }} >
)}
); }