Search.tsx 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import React, { useRef } from 'react';
  2. import { useDebouncedCallback } from 'use-debounce';
  3. import Input from 'components/common/Input/Input';
  4. import { useSearchParams } from 'react-router-dom';
  5. import CloseIcon from 'components/common/Icons/CloseIcon';
  6. import styled from 'styled-components';
  7. interface SearchProps {
  8. placeholder?: string;
  9. disabled?: boolean;
  10. onChange?: (value: string) => void;
  11. value?: string;
  12. }
  13. const IconButtonWrapper = styled.span.attrs(() => ({
  14. role: 'button',
  15. tabIndex: '0',
  16. }))`
  17. height: 16px !important;
  18. display: inline-block;
  19. &:hover {
  20. cursor: pointer;
  21. }
  22. `;
  23. const Search: React.FC<SearchProps> = ({
  24. placeholder = 'Search',
  25. disabled = false,
  26. value,
  27. onChange,
  28. }) => {
  29. const [searchParams, setSearchParams] = useSearchParams();
  30. const ref = useRef<HTMLInputElement>(null);
  31. const handleChange = useDebouncedCallback((e) => {
  32. if (ref.current != null) {
  33. ref.current.value = e.target.value;
  34. }
  35. if (onChange) {
  36. onChange(e.target.value);
  37. } else {
  38. searchParams.set('q', e.target.value);
  39. if (searchParams.get('page')) {
  40. searchParams.set('page', '1');
  41. }
  42. setSearchParams(searchParams);
  43. }
  44. }, 500);
  45. const clearSearchValue = () => {
  46. if (searchParams.get('q')) {
  47. searchParams.set('q', '');
  48. setSearchParams(searchParams);
  49. }
  50. if (ref.current != null) {
  51. ref.current.value = '';
  52. }
  53. };
  54. return (
  55. <Input
  56. type="text"
  57. placeholder={placeholder}
  58. onChange={handleChange}
  59. defaultValue={value || searchParams.get('q') || ''}
  60. inputSize="M"
  61. disabled={disabled}
  62. ref={ref}
  63. search
  64. clearIcon={
  65. <IconButtonWrapper onClick={clearSearchValue}>
  66. <CloseIcon />
  67. </IconButtonWrapper>
  68. }
  69. />
  70. );
  71. };
  72. export default Search;