index.tsx 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import React, { useRef, useEffect, MutableRefObject } from 'react';
  2. import { useTranslation } from 'react-i18next';
  3. import Button from '../Button';
  4. import Portal from '../Portal';
  5. import Loading from '../Loading';
  6. import {
  7. Wrapper,
  8. InputWrapper,
  9. Input,
  10. ResultInfo,
  11. ArrowButton,
  12. LoadingWrapper,
  13. } from './styled';
  14. type Props = {
  15. matchesTotal: number;
  16. current: number;
  17. onEnter: (val: string) => void;
  18. onPrev: () => void;
  19. onNext: () => void;
  20. isActive: boolean;
  21. isProcessing: boolean;
  22. close: () => void;
  23. };
  24. const Search: React.FC<Props> = ({
  25. matchesTotal = 0,
  26. current = 0,
  27. onPrev,
  28. onNext,
  29. onEnter,
  30. isActive = false,
  31. isProcessing = false,
  32. close,
  33. }: Props) => {
  34. const { t } = useTranslation('toolbar');
  35. const inputRef = useRef() as MutableRefObject<HTMLInputElement>;
  36. const handleKeyDown = (e: React.KeyboardEvent): void => {
  37. if (e.keyCode === 13 && inputRef.current.value) {
  38. onEnter(inputRef.current.value);
  39. }
  40. };
  41. useEffect(() => {
  42. if (isActive) {
  43. inputRef.current.focus();
  44. } else {
  45. inputRef.current.value = '';
  46. }
  47. }, [isActive]);
  48. return (
  49. <Portal>
  50. <Wrapper open={isActive}>
  51. <InputWrapper>
  52. <Input
  53. ref={inputRef}
  54. placeholder={t('searchDocument')}
  55. onKeyDown={handleKeyDown}
  56. />
  57. <ResultInfo>
  58. {isProcessing ? (
  59. <LoadingWrapper>
  60. <Loading />
  61. </LoadingWrapper>
  62. ) : (
  63. ''
  64. )}
  65. {matchesTotal ? `${current} / ${matchesTotal}` : ''}
  66. </ResultInfo>
  67. </InputWrapper>
  68. <ArrowButton variant="top" onClick={onPrev} />
  69. <ArrowButton variant="bottom" onClick={onNext} />
  70. <Button
  71. appearance="primary"
  72. style={{ marginLeft: '16px' }}
  73. onClick={close}
  74. >
  75. {t('close')}
  76. </Button>
  77. </Wrapper>
  78. </Portal>
  79. );
  80. };
  81. export default Search;