1
0
Fork 0
blog/src/components/Search/Search.tsx

88 lines
2.1 KiB
TypeScript
Raw Normal View History

2018-11-18 16:41:37 +01:00
import React, { PureComponent } from 'react'
2018-08-28 23:28:42 +02:00
import PropTypes from 'prop-types'
2018-08-25 11:15:40 +02:00
import Helmet from 'react-helmet'
2018-08-27 19:42:09 +02:00
import { CSSTransition } from 'react-transition-group'
2018-10-11 20:35:10 +02:00
import SearchInput from './SearchInput'
import SearchButton from './SearchButton'
import SearchResults from './SearchResults'
2018-08-28 23:28:42 +02:00
2018-08-25 11:15:40 +02:00
import styles from './Search.module.scss'
2019-10-02 13:35:50 +02:00
export default class Search extends PureComponent<
{},
{ searchOpen: boolean; query: string; results: string[] }
> {
2018-09-06 19:23:34 +02:00
state = {
searchOpen: false,
query: '',
results: []
}
2018-08-25 11:15:40 +02:00
2018-09-06 19:23:34 +02:00
static propTypes = {
lng: PropTypes.string.isRequired
2018-08-25 11:15:40 +02:00
}
toggleSearch = () => {
this.setState(prevState => ({
searchOpen: !prevState.searchOpen
}))
}
2019-10-02 13:35:50 +02:00
getSearchResults(query: string) {
2018-08-28 23:28:42 +02:00
if (!query || !window.__LUNR__) return []
const lunrIndex = window.__LUNR__[this.props.lng]
const results = lunrIndex.index.search(query)
return results.map(({ ref }) => lunrIndex.store[ref])
}
2019-10-02 13:35:50 +02:00
search = (event: any) => {
2018-08-28 23:28:42 +02:00
const query = event.target.value
2018-11-18 19:34:55 +01:00
// wildcard search https://lunrjs.com/guides/searching.html#wildcards
const results = query.length > 1 ? this.getSearchResults(`${query}*`) : []
2018-08-28 23:28:42 +02:00
this.setState({
results,
query
})
}
2018-08-25 11:15:40 +02:00
render() {
2018-08-28 23:28:42 +02:00
const { searchOpen, query, results } = this.state
2018-08-25 11:15:40 +02:00
return (
2018-11-18 16:41:37 +01:00
<>
2018-08-28 23:28:42 +02:00
<SearchButton onClick={this.toggleSearch} />
2018-08-25 11:15:40 +02:00
2018-08-28 23:28:42 +02:00
{searchOpen && (
2018-11-18 16:41:37 +01:00
<>
<Helmet>
<body className="hasSearchOpen" />
</Helmet>
2018-11-18 19:34:55 +01:00
2018-11-18 16:41:37 +01:00
<CSSTransition
appear={searchOpen}
in={searchOpen}
timeout={200}
classNames={styles}
>
<section className={styles.search}>
<SearchInput
value={query}
2019-10-02 13:35:50 +02:00
onChange={() => this.search}
2018-11-18 16:41:37 +01:00
onToggle={this.toggleSearch}
/>
</section>
</CSSTransition>
2018-11-18 19:34:55 +01:00
<SearchResults
searchQuery={query}
results={results}
toggleSearch={this.toggleSearch}
/>
2018-11-18 16:41:37 +01:00
</>
2018-08-28 23:28:42 +02:00
)}
2018-11-18 16:41:37 +01:00
</>
2018-08-25 11:15:40 +02:00
)
}
}