import React, { useState, useCallback, useRef } from 'react'; import assert from 'assert'; import { useTranslation } from 'next-i18next'; import { useRouter } from 'next/router'; import { IFocusable } from '~/client/interfaces/focusable'; import { IPageWithSearchMeta } from '~/interfaces/search'; import { useIsSearchScopeChildrenAsDefault, useIsSearchServiceReachable, } from '~/stores/context'; import { useCurrentPagePath } from '~/stores/page'; import { useGlobalSearchFormRef } from '~/stores/ui'; import SearchForm from '../SearchForm'; import styles from './GlobalSearch.module.scss'; export type GlobalSearchProps = { dropup?: boolean, } export const GlobalSearch = (props: GlobalSearchProps): JSX.Element => { const { t } = useTranslation('commons'); const { dropup } = props; const router = useRouter(); const globalSearchFormRef = useRef(null); useGlobalSearchFormRef(globalSearchFormRef); const { data: isSearchServiceReachable } = useIsSearchServiceReachable(); const { data: isSearchScopeChildrenAsDefault } = useIsSearchScopeChildrenAsDefault(); const { data: currentPagePath } = useCurrentPagePath(); const [text, setText] = useState(''); const [isScopeChildren, setScopeChildren] = useState(isSearchScopeChildrenAsDefault); const [isFocused, setFocused] = useState(false); const gotoPage = useCallback((data: IPageWithSearchMeta[]) => { assert(data.length > 0); const page = data[0].data; // should be single page selected // navigate to page if (page != null) { router.push(`/${page._id}`); } }, [router]); const search = useCallback(() => { const url = new URL(window.location.href); url.pathname = '/_search'; // construct search query let q = text; if (isScopeChildren) { q += ` prefix:${currentPagePath ?? window.location.pathname}`; } url.searchParams.append('q', q); router.push(url.href); }, [currentPagePath, isScopeChildren, router, text]); const scopeLabel = isScopeChildren ? t('header_search_box.label.This tree') : t('header_search_box.label.All pages'); const isIndicatorShown = !isFocused && (text.length === 0); if (isScopeChildren == null || isSearchServiceReachable == null) { return <>; } return (
setFocused(false)} onFocus={() => setFocused(true)} onInputChange={text => setText(text)} onSubmit={search} /> { isIndicatorShown && ( / ) }
); };