import * as React from 'react'; import * as ReactDOM from 'react-dom'; import { Link } from 'bisheng/router'; import classNames from 'classnames'; import { Helmet } from 'react-helmet-async'; import canUseDom from 'rc-util/lib/Dom/canUseDom'; import { Input, Tooltip, Typography } from 'antd'; import { SearchOutlined } from '@ant-design/icons'; import { DocSearchProps, useDocSearchKeyboardEvents, DocSearchModalProps } from '@docsearch/react'; import '@docsearch/css'; import { SharedProps } from './interface'; import { IAlgoliaConfig, transformHitUrl } from './algolia-config'; import './SearchBar.less'; const { Text } = Typography; export interface SearchBarProps extends SharedProps { onTriggerFocus?: (focus: boolean) => void; responsive: null | 'narrow' | 'crowded'; algoliaConfig: IAlgoliaConfig; router: any; } let SearchModal: React.FC | null = null; const Hit: DocSearchProps['hitComponent'] = ({ hit, children }) => { const toUrl = React.useMemo(() => transformHitUrl(hit.url), [hit.url]); return {children}; }; const CTRL_KEY = 'Ctrl'; const CMD_KEY = '⌘'; function isAppleDevice() { return /(mac|iphone|ipod|ipad)/i.test(navigator.platform); } /** * Recompose for algolia DocSearch Component Inspiring by * * - [@docusaurus-theme-search-algolia](https://docusaurus.io/docs/api/themes/@docusaurus/theme-search-algolia) * - [DocSearchModal Docs](https://autocomplete-experimental.netlify.app/docs/DocSearchModal) */ const SearchBar = ({ isZhCN, responsive, onTriggerFocus, algoliaConfig, router, }: SearchBarProps) => { const [isInputFocus, setInputFocus] = React.useState(false); const [inputSearch, setInputSearch] = React.useState(''); const [isModalOpen, setModalOpen] = React.useState(false); const [searchModalQuery, setSearchModalQuery] = React.useState(''); const searchPlaceholder = isZhCN ? '在 ant.design 中搜索' : 'Search in ant.design'; const searchInputPlaceholder = isZhCN ? '搜索' : 'Search'; const triggerSearchModalImport = React.useCallback(() => { if (SearchModal) { return Promise.resolve(); } return import('@docsearch/react/modal').then(({ DocSearchModal }) => { SearchModal = DocSearchModal; }); }, []); const handleInputFocus = React.useCallback((focus: boolean) => { setInputFocus(focus); onTriggerFocus?.(focus); }, []); const handleInputChange = React.useCallback((event: React.ChangeEvent) => { triggerSearchModalImport(); setInputSearch(event.target.value); }, []); const searchModalContainer = React.useMemo(() => { if (!canUseDom()) { return; } const id = 'antd_algolia_search_modal'; let searchModalContainer$ = document.querySelector(`#${id}`); if (!searchModalContainer$) { const containerDiv = document.createElement('div'); containerDiv.id = id; document.body.appendChild(containerDiv); searchModalContainer$ = containerDiv; } return searchModalContainer$; }, []); const handleModalOpen = React.useCallback(() => { triggerSearchModalImport().then(() => { handleInputFocus(true); setModalOpen(true); }); }, []); const handleModalClose = React.useCallback(() => { // clear search value in SearchModal setSearchModalQuery(''); setModalOpen(false); }, []); useDocSearchKeyboardEvents({ isOpen: isModalOpen, onOpen: handleModalOpen, onClose: handleModalClose, }); const searchParameters = React.useMemo(() => algoliaConfig.getSearchParams(isZhCN), [isZhCN]); const navigator = React.useRef({ navigate({ itemUrl }: { itemUrl: string }) { router.push(itemUrl); }, }).current; return ( ); }; export default SearchBar;