import type { MouseEvent as ReactMouseEvent } from 'react'; import type { ElementRef, FC } from '../../lib/teact/teact'; import { memo, useEffect, useRef, } from '../../lib/teact/teact'; import { IS_TAURI } from '../../util/browser/globalEnvironment'; import buildClassName from '../../util/buildClassName'; import useFlag from '../../hooks/useFlag'; import useInputFocusOnOpen from '../../hooks/useInputFocusOnOpen'; import useLang from '../../hooks/useLang'; import useLastCallback from '../../hooks/useLastCallback'; import useOldLang from '../../hooks/useOldLang'; import Icon from '../common/icons/Icon'; import Button from './Button'; import Loading from './Loading'; import Transition from './Transition'; import './SearchInput.scss'; type OwnProps = { ref?: ElementRef; children?: React.ReactNode; resultsItemSelector?: string; className?: string; inputId?: string; value?: string; focused?: boolean; isLoading?: boolean; spinnerColor?: 'yellow'; spinnerBackgroundColor?: 'light'; placeholder?: string; disabled?: boolean; autoComplete?: string; canClose?: boolean; autoFocusSearch?: boolean; hasUpButton?: boolean; hasDownButton?: boolean; teactExperimentControlled?: boolean; withBackIcon?: boolean; onChange: (value: string) => void; onStartBackspace?: NoneToVoidFunction; onReset?: NoneToVoidFunction; onFocus?: NoneToVoidFunction; onBlur?: NoneToVoidFunction; onClick?: (e: ReactMouseEvent) => void; onUpClick?: (event: React.MouseEvent) => void; onDownClick?: (event: React.MouseEvent) => void; onSpinnerClick?: NoneToVoidFunction; onEnter?: NoneToVoidFunction; }; const SearchInput: FC = ({ ref, children, resultsItemSelector, value, inputId, className, focused, isLoading = false, spinnerColor, spinnerBackgroundColor, placeholder, disabled, autoComplete, canClose, autoFocusSearch, hasUpButton, hasDownButton, teactExperimentControlled, withBackIcon, onChange, onStartBackspace, onReset, onFocus, onBlur, onClick, onUpClick, onDownClick, onSpinnerClick, onEnter, }) => { let inputRef = useRef(); if (ref) { inputRef = ref; } const [isInputFocused, markInputFocused, unmarkInputFocused] = useFlag(focused); useInputFocusOnOpen(inputRef, autoFocusSearch, unmarkInputFocused); useEffect(() => { if (!inputRef.current) { return; } if (focused) { inputRef.current.focus(); } else { inputRef.current.blur(); } }, [focused, placeholder]); // Trick for setting focus when selecting a contact to search for const oldLang = useOldLang(); const lang = useLang(); function handleChange(event: React.ChangeEvent) { const { currentTarget } = event; onChange(currentTarget.value); if (!isInputFocused) { handleFocus(); } } function handleFocus() { markInputFocused(); onFocus?.(); } function handleBlur() { unmarkInputFocused(); onBlur?.(); } const handleKeyDown = useLastCallback((e: React.KeyboardEvent) => { if (e.key === 'Enter') { if (onEnter) { e.preventDefault(); onEnter(); return; } if (resultsItemSelector) { const element = document.querySelector(resultsItemSelector) as HTMLElement; if (element) { element.focus(); } } } if (resultsItemSelector && e.key === 'ArrowDown') { const element = document.querySelector(resultsItemSelector) as HTMLElement; if (element) { element.focus(); } } if (e.key === 'Backspace' && e.currentTarget.selectionStart === 0 && e.currentTarget.selectionEnd === 0) { onStartBackspace?.(); } }); return (
{isLoading && !withBackIcon ? ( ) : withBackIcon ? ( ) : ( )}
{children}
{hasUpButton && (
); }; export default memo(SearchInput);