| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- import React, {
- useState, useCallback, useEffect,
- } from 'react';
- import Downshift, { type DownshiftState, type StateChangeOptions } from 'downshift';
- import { useRouter } from 'next/router';
- import { Modal, ModalBody } from 'reactstrap';
- import type { DownshiftItem } from '../interfaces/downshift';
- import { useSearchModal } from '../stores/search';
- import { SearchForm } from './SearchForm';
- import { SearchHelp } from './SearchHelp';
- import { SearchMethodMenuItem } from './SearchMethodMenuItem';
- import { SearchResultMenuItem } from './SearchResultMenuItem';
- const SearchModal = (): JSX.Element => {
- const [searchKeyword, setSearchKeyword] = useState('');
- const { data: searchModalData, close: closeSearchModal } = useSearchModal();
- const router = useRouter();
- const changeSearchTextHandler = useCallback((searchText: string) => {
- setSearchKeyword(searchText);
- }, []);
- const selectSearchMenuItemHandler = useCallback((selectedItem: DownshiftItem) => {
- router.push(selectedItem.url);
- closeSearchModal();
- }, [closeSearchModal, router]);
- const submitHandler = useCallback(() => {
- router.push(`/_search?q=${searchKeyword}`);
- closeSearchModal();
- }, [closeSearchModal, router, searchKeyword]);
- const stateReducer = (state: DownshiftState<DownshiftItem>, changes: StateChangeOptions<DownshiftItem>) => {
- // Do not update highlightedIndex on mouse hover
- if (changes.type === Downshift.stateChangeTypes.itemMouseEnter) {
- return {
- ...changes,
- highlightedIndex: state.highlightedIndex,
- };
- }
- return changes;
- };
- useEffect(() => {
- if (!searchModalData?.isOpened) {
- setSearchKeyword('');
- }
- }, [searchModalData?.isOpened]);
- return (
- <Modal size="lg" isOpen={searchModalData?.isOpened ?? false} toggle={closeSearchModal}>
- <ModalBody>
- <Downshift
- onSelect={selectSearchMenuItemHandler}
- stateReducer={stateReducer}
- defaultIsOpen
- >
- {({
- getRootProps,
- getInputProps,
- getItemProps,
- getMenuProps,
- highlightedIndex,
- }) => (
- <div {...getRootProps({}, { suppressRefError: true })}>
- <div className="text-muted d-flex justify-content-center align-items-center p-1">
- <span className="material-symbols-outlined fs-4 me-3">search</span>
- <SearchForm
- searchKeyword={searchKeyword}
- onChange={changeSearchTextHandler}
- onSubmit={submitHandler}
- getInputProps={getInputProps}
- />
- <button
- type="button"
- className="btn border-0 d-flex justify-content-center p-0"
- onClick={closeSearchModal}
- >
- <span className="material-symbols-outlined fs-4 ms-3">close</span>
- </button>
- </div>
- <ul {...getMenuProps()} className="list-unstyled">
- <div className="border-top mt-3 mb-2" />
- <SearchMethodMenuItem
- activeIndex={highlightedIndex}
- searchKeyword={searchKeyword}
- getItemProps={getItemProps}
- />
- <div className="border-top mt-2 mb-2" />
- <SearchResultMenuItem
- activeIndex={highlightedIndex}
- searchKeyword={searchKeyword}
- getItemProps={getItemProps}
- />
- </ul>
- </div>
- )}
- </Downshift>
- <SearchHelp />
- </ModalBody>
- </Modal>
- );
- };
- export default SearchModal;
|