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

89 lines
2.0 KiB
React
Raw Normal View History

2018-08-25 11:15:40 +02:00
import React, { PureComponent, Fragment } 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'
2018-09-06 19:23:34 +02:00
export default class Search extends PureComponent {
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
}))
}
2018-08-28 23:28:42 +02:00
closeSearch = () => {
this.setState({
searchOpen: false,
query: '',
results: []
})
}
2018-08-25 11:15:40 +02:00
isSearchOpen = () => this.state.searchOpen === true
2018-08-28 23:28:42 +02:00
getSearchResults(query) {
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])
}
search = event => {
const query = event.target.value
const results = this.getSearchResults(query)
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 (
<Fragment>
<Helmet>
<body className={this.isSearchOpen() ? 'has-search-open' : null} />
</Helmet>
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-08-27 19:42:09 +02:00
<CSSTransition
2018-08-28 23:28:42 +02:00
appear={searchOpen}
in={searchOpen}
2018-08-27 19:42:09 +02:00
timeout={200}
classNames={styles}
>
<section className={styles.search}>
2018-08-28 23:28:42 +02:00
<SearchInput
value={query}
onChange={this.search}
onToggle={this.closeSearch}
2018-08-27 19:42:09 +02:00
/>
</section>
</CSSTransition>
2018-08-25 11:15:40 +02:00
)}
2018-08-28 23:28:42 +02:00
{query && (
<SearchResults results={results} onClose={this.closeSearch} />
)}
2018-08-25 11:15:40 +02:00
</Fragment>
)
}
}