import { useState, useRef, useEffect } from 'react' import Link from 'next/link' import { useRouter } from 'next/router' import algoliasearch from 'algoliasearch/lite'; import { useHotkeys } from 'react-hotkeys-hook' import { InstantSearch, connectHits, connectHighlight, connectSearchBox } from 'react-instantsearch-dom' import config from 'site/freesewing.config.js' const searchClient = algoliasearch(config.algolia.app, config.algolia.key) const Hits = props => { // When we hit enter in the text field, we want to navigate to the result // which means we must make the result links available in the input somehow // so let's stuff them in a data attribute const links = props.hits.map(hit => hit.page) props.input.current.setAttribute('data-links', JSON.stringify(links)) return props.hits.map((hit, index) => ( )) } const CustomHits = connectHits(Hits); const Highlight = ({ highlight, attribute, hit, snippet=false }) => { const parsedHit = highlight({ highlightProperty: snippet ? '_snippetResult' : '_highlightResult', attribute, hit, }); return parsedHit.map((part, index) => part.isHighlighted ? {part.value} : {part.value} ) } const CustomHighlight = connectHighlight(Highlight); const Hit = props => (
{props.hit?._highlightResult?.title ? : props.hit.title } {props.hit.page.split('/')[1]} {props.hit?._snippetResult?.body && ( )} {props.hit?._highlightResult?.page && ( )}
) // We use this for trapping ctrl-c let prev const handleInputKeydown = (evt, setSearch, setActive, active, router) => { if (evt.key === 'Escape') setSearch(false) if (evt.key === 'ArrowDown') setActive(act => act + 1) if (evt.key === 'ArrowUp') setActive(act => act - 1) if (evt.key === 'Enter') { // Trigger navigation if (evt?.target?.dataset?.links) { router.push(JSON.parse(evt.target.dataset.links)[active]) setSearch(false) } } } const SearchBox = props => { const input = useRef(null) const router = useRouter() useHotkeys('ctrl+x', () => { input.current.value = '' }) if (input.current && props.active < 0) input.current.focus() const { currentRefinement, isSearchStalled, refine, setSearch, setActive } = props return (
evt.preventDefault()}>
refine(event.currentTarget.value)} onKeyDown={(evt) => handleInputKeydown(evt, setSearch, setActive, props.active, router)} className="input lg:input-lg input-bordered input-neutral w-full pr-16" placeholder='Type to search' />
{ input.current && input.current.value.length > 0 && }
) } const CustomSearchBox = connectSearchBox(SearchBox); const Search = props => { const [active, setActive] = useState(0) useHotkeys('esc', () => props.setSearch(false)) useHotkeys('up', () => { if (active) setActive(act => act - 1) }) useHotkeys('down', () => { setActive(act => act + 1) }) useHotkeys('down', () => { console.log('enter', active) }) const stateProps = { setSearch: props.setSearch, setMenu: props.setMenu, active, setActive } return ( ) } export default Search