123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- import { InputAdornment, makeStyles, TextField } from '@material-ui/core';
- import { useRef, FC, useState, useEffect, useMemo } from 'react';
- import { useTranslation } from 'react-i18next';
- import { useSearchParams } from 'react-router-dom';
- import Icons from '../icons/Icons';
- import { SearchType } from './Types';
- const useSearchStyles = makeStyles(theme => ({
- wrapper: {
- display: 'flex',
- },
- input: {
- backgroundColor: '#fff',
- borderRadius: '4px',
- padding: theme.spacing(1),
- width: '240px',
- border: '1px solid #e9e9ed',
- fontSize: '14px',
- transition: 'all 0.2s',
- '& .MuiAutocomplete-endAdornment': {
- right: theme.spacing(0.5),
- },
- '& .MuiInput-underline:before': {
- border: 'none',
- },
- '& .MuiInput-underline:after': {
- border: 'none',
- },
- /**
- * when input focus
- * 1. change parent wrapper border color
- * 2. hide input start search icon
- */
- '&:focus-within': {
- border: `1px solid ${theme.palette.primary.main}`,
- '& $searchIcon': {
- width: 0,
- },
- },
- },
- textfield: {
- padding: 0,
- height: '16px',
- '&:focus': {
- caretColor: theme.palette.primary.main,
- },
- },
- searchIcon: {
- color: theme.palette.attuGrey.main,
- cursor: 'pointer',
- fontSize: '20px',
- width: (props: { searched: boolean }) => `${props.searched ? 0 : '20px'}`,
- transition: 'width 0.2s',
- },
- clearIcon: {
- color: theme.palette.primary.main,
- cursor: 'pointer',
- },
- iconWrapper: {
- opacity: (props: { searched: boolean }) => `${props.searched ? 1 : 0}`,
- transition: 'opacity 0.2s',
- },
- searchWrapper: {
- display: 'flex',
- justifyContent: 'center',
- alignItems: 'center',
- },
- }));
- const SearchInput: FC<SearchType> = props => {
- const { searchText = '', onClear = () => {}, onSearch = () => {} } = props;
- const [searchParams, setSearchParams] = useSearchParams();
- const [searchValue, setSearchValue] = useState<string>(searchText || '');
- const searched = useMemo(() => searchValue !== '', [searchValue]);
- const classes = useSearchStyles({ searched });
- const { t: commonTrans } = useTranslation();
- const inputRef = useRef<any>(null);
- const handleSearch = (value: string) => {
- onSearch(value);
- };
- useEffect(() => {
- searchParams[searchValue ? 'set' : 'delete']('search', searchValue);
- setSearchParams(searchParams);
- handleSearch(searchValue);
- }, [searchValue]);
- return (
- <div className={classes.wrapper}>
- <TextField
- inputRef={inputRef}
- variant="standard"
- classes={{ root: classes.input }}
- InputProps={{
- disableUnderline: true,
- classes: { input: classes.textfield },
- endAdornment: (
- <InputAdornment position="end">
- <span
- data-testid="clear-icon"
- className={`flex-center ${classes.iconWrapper}`}
- onClick={e => {
- setSearchValue('');
- inputRef.current.focus();
- onClear();
- }}
- >
- {Icons.clear({ classes: { root: classes.clearIcon } })}
- </span>
- </InputAdornment>
- ),
- startAdornment: (
- <InputAdornment position="start">
- <span
- className={classes.searchWrapper}
- onClick={() => handleSearch(searchValue)}
- >
- {Icons.search({ classes: { root: classes.searchIcon } })}
- </span>
- </InputAdornment>
- ),
- }}
- onChange={e => {
- const value = e.target.value.trim();
- setSearchValue(value);
- if (value === '') {
- onClear();
- }
- }}
- onKeyPress={e => {
- if (e.key === 'Enter') {
- // Do code here
- handleSearch(searchValue);
- e.preventDefault();
- }
- }}
- value={searchValue || ''}
- placeholder={commonTrans('search')}
- />
- </div>
- );
- };
- export default SearchInput;
|