search.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import fuse from 'fuse.js'
  2. const dummyResults = [{
  3. title: 'good :-)',
  4. text: 'a good text.',
  5. link: 'good'
  6. }, {
  7. title: 'bad :-(',
  8. text: 'a bad text.',
  9. link: 'bad'
  10. }]
  11. class Search extends React.Component {
  12. state = {
  13. active: false,
  14. query: '',
  15. results: []
  16. }
  17. focus = ev => {
  18. this.setState({ active: true })
  19. }
  20. blur = ev => {
  21. this.setState({ active: false })
  22. }
  23. change = ev => {
  24. const { value } = ev.target
  25. this.setState({ query: ev.target.value })
  26. const fuseOptions = {
  27. shouldSort: true,
  28. includeMatches: true,
  29. threshold: 0.3,
  30. location: true,
  31. keys: ['title', 'text', 'link']
  32. }
  33. const fuseInst = new fuse(dummyResults, fuseOptions)
  34. const searchResults = fuseInst.search(value)
  35. console.log(dummyResults, searchResults)
  36. if (value) {
  37. this.setState({
  38. results: searchResults
  39. })
  40. } else {
  41. this.setState({ results: [] })
  42. }
  43. }
  44. render() {
  45. return (
  46. <>
  47. <div id='searchbar'>
  48. <input
  49. type="text"
  50. placeholder="Search.."
  51. onFocus={this.focus}
  52. onBlur={this.blur}
  53. onChange={this.change}
  54. />
  55. <button type="submit">Search</button>
  56. {(this.state.active && this.state.query) && (this.state.results ?
  57. (
  58. <ul id='searchresults'>
  59. {this.state.results.map(result => <Result key={result.title} {...result} />)}
  60. </ul>
  61. ) : (
  62. <p>Nothing found.</p>
  63. )
  64. )}
  65. </div>
  66. <style jsx>
  67. {`
  68. input[type=text] {
  69. float: right;
  70. padding: 6px;
  71. border: none;
  72. margin-top: 8px;
  73. margin-right: 16px;
  74. font-size: 17px;
  75. }
  76. `}
  77. </style>
  78. </>
  79. )
  80. }
  81. }
  82. const Result = props => {
  83. const { item, matches } = props
  84. return (
  85. <li>
  86. <a href={item.link}>
  87. <h3>{item.title}</h3>
  88. <p>{item.text}</p>
  89. </a>
  90. </li>
  91. )
  92. }
  93. export default Search