import React, { FC, useState, useCallback, useRef, } from 'react'; import assert from 'assert'; import { useTranslation } from 'react-i18next'; import { IFocusable } from '~/client/interfaces/focusable'; import AppContainer from '~/client/services/AppContainer'; import { IPageWithSearchMeta } from '~/interfaces/search'; import { useCurrentPagePath } from '~/stores/context'; import { useGlobalSearchFormRef } from '~/stores/ui'; import SearchForm from '../SearchForm'; import { withUnstatedContainers } from '../UnstatedUtils'; type Props = { appContainer: AppContainer, dropup?: boolean, } const GlobalSearch: FC = (props: Props) => { const { appContainer, dropup } = props; const { t } = useTranslation(); const globalSearchFormRef = useRef(null); useGlobalSearchFormRef(globalSearchFormRef); const [text, setText] = useState(''); const [isScopeChildren, setScopeChildren] = useState(appContainer.getConfig().isSearchScopeChildrenAsDefault); const [isFocused, setFocused] = useState(false); const { data: currentPagePath } = useCurrentPagePath(); 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) { window.location.href = `/${page._id}`; } }, []); 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); window.location.href = url.href; }, [currentPagePath, isScopeChildren, text]); const scopeLabel = isScopeChildren ? t('header_search_box.label.This tree') : t('header_search_box.label.All pages'); const isSearchServiceReachable = appContainer.getConfig().isSearchServiceReachable; const isIndicatorShown = !isFocused && (text.length === 0); return (
setFocused(false)} onFocus={() => setFocused(true)} onInputChange={text => setText(text)} onSubmit={search} /> { isIndicatorShown && ( / ) }
); }; /** * Wrapper component for using unstated */ const GlobalSearchWrapper = withUnstatedContainers(GlobalSearch, [AppContainer]); export default GlobalSearchWrapper;