Просмотр исходного кода

Merge pull request #8287 from weseek/feat/135835-search-form

feat: Display form in search modal
Yuki Takei 2 лет назад
Родитель
Сommit
c404546c48

+ 57 - 0
apps/app/src/features/search/client/components/SearchForm.tsx

@@ -0,0 +1,57 @@
+import React, {
+  useCallback, useRef, useEffect,
+} from 'react';
+
+type Props = {
+  searchKeyword: string,
+  onChangeSearchText?: (text: string) => void,
+  onClickClearButton?: () => void,
+}
+export const SearchForm = (props: Props): JSX.Element => {
+  const {
+    searchKeyword, onChangeSearchText, onClickClearButton,
+  } = props;
+
+  const inputRef = useRef<HTMLInputElement>(null);
+
+  const changeSearchTextHandler = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
+    if (onChangeSearchText != null) {
+      onChangeSearchText(e.target.value);
+    }
+  }, [onChangeSearchText]);
+
+  const clickClearButtonHandler = useCallback(() => {
+    if (onClickClearButton != null) {
+      onClickClearButton();
+    }
+  }, [onClickClearButton]);
+
+  useEffect(() => {
+    if (inputRef.current != null) {
+      inputRef.current.focus();
+    }
+  });
+
+  return (
+    <div className="text-muted d-flex justify-content-center align-items-center ps-1">
+      <span className="material-symbols-outlined fs-4 me-3">search</span>
+
+      <input
+        ref={inputRef}
+        type="text"
+        className="form-control"
+        placeholder="Search..."
+        value={searchKeyword}
+        onChange={(e) => { changeSearchTextHandler(e) }}
+      />
+
+      <button
+        type="button"
+        className="btn border-0 d-flex justify-content-center p-0"
+        onClick={clickClearButtonHandler}
+      >
+        <span className="material-symbols-outlined fs-4 ms-3">close</span>
+      </button>
+    </div>
+  );
+};

+ 27 - 10
apps/app/src/features/search/client/components/SearchModal.tsx

@@ -1,25 +1,42 @@
-import React from 'react';
+import React, {
+  useState, useCallback, useEffect,
+} from 'react';
 
-import {
-  Modal,
-  ModalHeader,
-  ModalBody,
-} from 'reactstrap';
+import { Modal, ModalBody } from 'reactstrap';
 
 import { useSearchModal } from '../stores/search';
 
+import { SearchForm } from './SearchForm';
 import { SearchHelp } from './SearchHelp';
 
 const SearchModal = (): JSX.Element => {
   const { data: searchModalData, close: closeSearchModal } = useSearchModal();
 
+  const [searchKeyword, setSearchKeyword] = useState('');
+
+  const changeSearchTextHandler = useCallback((searchText: string) => {
+    setSearchKeyword(searchText);
+  }, []);
+
+  const clickClearButtonHandler = useCallback(() => {
+    setSearchKeyword('');
+  }, []);
+
+  useEffect(() => {
+    if (!searchModalData?.isOpened) {
+      setSearchKeyword('');
+    }
+  }, [searchModalData?.isOpened]);
+
   return (
     <Modal size="lg" isOpen={searchModalData?.isOpened ?? false} toggle={closeSearchModal}>
-      <ModalHeader>
-        header
-      </ModalHeader>
-
       <ModalBody>
+        <SearchForm
+          searchKeyword={searchKeyword}
+          onChangeSearchText={changeSearchTextHandler}
+          onClickClearButton={clickClearButtonHandler}
+        />
+        <div className="border-top mt-4 mb-3" />
         <SearchHelp />
       </ModalBody>
     </Modal>