All files / components/search index.tsx

100% Statements 17/17
100% Branches 4/4
100% Functions 6/6
100% Lines 16/16

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69                            4x       6x   6x   6x 2x   2x   2x     6x 1x   1x     6x   6x 5x   5x 5x       6x                                            
import { FormEvent, useEffect, useRef, useState } from 'react';
 
import { events } from 'app';
import { Events } from 'types';
 
import { Select } from './select';
import * as S from './styles';
import { debounce } from 'utils';
 
export type SearchProps = {
  label?: string;
  placeholder?: string;
};
 
const Search = ({
  label = 'Explore by',
  placeholder = 'Ex: Luke',
}: SearchProps) => {
  const inputRef = useRef<HTMLInputElement>(null);
 
  const [error, setError] = useState('');
 
  const handleSearch = () => {
    const { value } = inputRef.current!;
 
    setError('');
 
    events.search.make({ search: value });
  };
 
  const handleSubmit = (e: FormEvent) => {
    e.preventDefault();
 
    handleSearch();
  };
 
  const handleError = (event: CustomEvent<string>) => setError(event.detail);
 
  useEffect(() => {
    events.on(Events.SEARCH_ERROR, handleError);
 
    return () => {
      events.off(Events.SEARCH_ERROR, handleError);
    };
  }, []);
 
  return (
    <S.Container onSubmit={handleSubmit} aria-label="form">
      {!!error && <S.Error>{error}</S.Error>}
 
      <S.Label htmlFor="search">
        {label}
 
        <S.InputWrapper>
          <Select />
          <S.Input
            id="search"
            ref={inputRef}
            placeholder={placeholder}
            onInput={debounce(handleSearch)}
          />
        </S.InputWrapper>
      </S.Label>
    </S.Container>
  );
};
 
export { Search };