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

Improve search experience by opening modal on re-search action

maeshinshin 2 лет назад
Родитель
Сommit
7adf36f7cc

+ 2 - 6
apps/app/src/components/SearchPage/SearchControl.tsx

@@ -7,8 +7,7 @@ import { useTranslation } from 'next-i18next';
 import { SORT_AXIS, SORT_ORDER } from '~/interfaces/search';
 import type { ISearchConditions, ISearchConfigurations } from '~/stores/search';
 
-import SearchForm from '../SearchForm';
-
+import SearchModalTriggerinput from './SearchModalTriggerInput';
 import SearchOptionModal from './SearchOptionModal';
 import SortControl from './SortControl';
 
@@ -88,11 +87,8 @@ const SearchControl = React.memo((props: Props): JSX.Element => {
     <div className="shadow-sm">
       <div className="grw-search-page-nav d-flex py-3 align-items-center">
         <div className="flex-grow-1 mx-4">
-          <SearchForm
-            isSearchServiceReachable={isSearchServiceReachable}
+          <SearchModalTriggerinput
             keywordOnInit={keyword}
-            disableIncrementalSearch
-            onSubmit={searchFormSubmittedHandler}
           />
         </div>
       </div>

+ 61 - 0
apps/app/src/components/SearchPage/SearchModalTriggerInput.tsx

@@ -0,0 +1,61 @@
+import type {
+  ForwardRefRenderFunction,
+} from 'react';
+import React, {
+  forwardRef, useCallback, useRef,
+} from 'react';
+
+// import type { TypeaheadRef } from 'react-bootstrap-typeahead';
+
+import type { IFocusable } from '~/client/interfaces/focusable';
+import type { TypeaheadProps } from '~/client/interfaces/react-bootstrap-typeahead';
+
+import { useSearchModal } from '../../features/search/client/stores/search';
+
+type Props = TypeaheadProps & {
+  keywordOnInit: string,
+};
+
+const SearchModalTriggerinput: ForwardRefRenderFunction<IFocusable, Props> = (props: Props) => {
+  const { keywordOnInit } = props;
+
+  /*
+  const inputRef : React.RefObject<HTMLInputElement> = React.createRef();
+
+  const blurFromSearchModalTriggerinput = () => {
+    const instance = inputRef.current;
+    if (instance != null) {
+      instance.blur();
+    }
+  };
+  */
+
+  const { open: openSearchModal } = useSearchModal();
+
+  const inputClickHandler = useCallback(() => {
+    openSearchModal(keywordOnInit);
+    // blurFromSearchModalTriggerinput();
+  }, [openSearchModal, keywordOnInit]);
+
+  return (
+    <div>
+      <input
+        className="form-control"
+        // ref={input}
+        type="input"
+        data-testid="open-search-modal-button"
+        value={keywordOnInit}
+        onClick={inputClickHandler}
+        readOnly
+      />
+    </div>
+  );
+};
+
+const ForwardedSearchTypeahead = forwardRef(SearchModalTriggerinput);
+
+ForwardedSearchTypeahead.defaultProps = {
+  keywordOnInit: '',
+};
+
+export default ForwardedSearchTypeahead;

+ 5 - 2
apps/app/src/features/search/client/components/SearchModal.tsx

@@ -49,10 +49,13 @@ const SearchModal = (): JSX.Element => {
   };
 
   useEffect(() => {
-    if (!searchModalData?.isOpened) {
+    if (!searchModalData?.isOpened || typeof searchModalData?.searchKeyword === 'undefined') {
       setSearchKeyword('');
     }
-  }, [searchModalData?.isOpened]);
+    else {
+      setSearchKeyword(searchModalData.searchKeyword);
+    }
+  }, [searchModalData?.isOpened, searchModalData?.searchKeyword]);
 
   return (
     <Modal size="lg" isOpen={searchModalData?.isOpened ?? false} toggle={closeSearchModal} data-testid="search-modal">

+ 13 - 5
apps/app/src/features/search/client/stores/search.ts

@@ -1,22 +1,30 @@
-import { SWRResponse } from 'swr';
+import type { SWRResponse } from 'swr';
 
 import { useStaticSWR } from '~/stores/use-static-swr';
 
 type SearchModalStatus = {
   isOpened: boolean,
+  searchKeyword: string,
 }
 
 type SearchModalUtils = {
-  open(): void
+  open(keywordOnInit?: string): void
   close(): void
 }
 export const useSearchModal = (status?: SearchModalStatus): SWRResponse<SearchModalStatus, Error> & SearchModalUtils => {
-  const initialStatus = { isOpened: false };
+  const initialStatus = { searchKeyword: '', isOpened: false };
   const swrResponse = useStaticSWR<SearchModalStatus, Error>('SearchModal', status, { fallbackData: initialStatus });
 
   return {
     ...swrResponse,
-    open: () => swrResponse.mutate({ isOpened: true }),
-    close: () => swrResponse.mutate({ isOpened: false }),
+    open: (keywordOnInit?: string) => {
+      if (typeof keywordOnInit !== 'undefined') {
+        swrResponse.mutate({ isOpened: true, searchKeyword: keywordOnInit });
+      }
+      else {
+        swrResponse.mutate({ isOpened: true, searchKeyword: '' });
+      }
+    },
+    close: () => swrResponse.mutate({ isOpened: false, searchKeyword: '' }),
   };
 };