import Fuse from 'fuse.js' import React, { Fragment, useCallback, useEffect, useState } from 'react' import { Search as SearchIcon } from 'react-feather' import { SearchIndex, SearchItem } from '../utils/search' import { Dialog, Transition, Combobox } from '@headlessui/react' import { useRouter } from 'next/router' export interface SearchProps { index: SearchIndex } interface SearchResultProps { result: Fuse.FuseResult selected: boolean active: boolean } const SearchResult: React.FunctionComponent = (props) => { const excerpt = (s: string) => { if (s.length < 100) { return <>{s} } else { return <>{s.substring(0, 100)}… } } const bg_for = (s: string) => { const bg = 'p-1 rounded bg-opacity-20 ' if (s === 'var') { return bg + 'bg-blue-500' } if (s === 'config') { return bg + 'bg-green-500' } if (s === 'lua') { return bg + 'bg-red-500' } return bg } const selection = props.active ? 'bg-slate-300 dark:bg-slate-700' : '' return (
{props.result.item.name}
{props.result.item.kind}

{excerpt(props.result.item.desc)}

) } const Search: React.FunctionComponent = (props) => { const router = useRouter() const [searchText, setSearchText] = useState('') const [selected, setSelected] = useState< Fuse.FuseResult | undefined >(undefined) const [searchResults, setSearchResults] = useState< Fuse.FuseResult[] >([]) const [fuse, setFuse] = useState(() => { const options: Fuse.IFuseOptions = {} return new Fuse( props.index.list, options, Fuse.parseIndex(props.index.index) ) }) const [isOpen, setIsOpen] = useState(false) const handleKeyPress = useCallback( (event: KeyboardEvent) => { if (event.key == '/' && !isOpen) { setIsOpen(true) event.preventDefault() } }, [isOpen] ) useEffect(() => { document.addEventListener('keydown', handleKeyPress) return () => { document.removeEventListener('keydown', handleKeyPress) } }, [handleKeyPress]) const setSearch = (value: string) => { setSearchText(value) const searchResult = fuse.search(value) setSearchResults(searchResult) } const onChange = (value?: Fuse.FuseResult) => { if (value) { if (value.item.kind === 'var') { router.push(`/variables#${value.item.name}`, undefined, { scroll: false, }) } if (value.item.kind === 'config') { router.push(`/config_settings#${value.item.name}`, undefined, { scroll: false, }) } if (value.item.kind === 'lua') { router.push(`/lua#${value.item.name}`, undefined, { scroll: false }) } setIsOpen(false) } } const closeModal = () => { setIsOpen(false) } const openModal = () => { setIsOpen(true) } return ( <>
setSearch(e.target.value)} />
{searchResults.length === 0 && searchText !== '' ? (
No results.
) : ( searchResults.map((r) => ( {({ selected, active }) => ( )} )) )}
) } export default Search