All files / client/components/HeaderSearchBox SearchForm.tsx

0% Statements 0/29
0% Branches 0/12
0% Functions 0/11
0% Lines 0/29

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116                                                                                                                                                                                                                                       
import React from 'react'
import Icon from 'components/Common/Icon'
import Emitter from '../../emitter'
 
interface Props {
  onSearchFormChanged: Function
  isShown: Function
  isSearchPage: boolean
  pollInterval?: number
  keyword: string
  focused: boolean
}
 
interface State {
  keyword: string
  searchedKeyword: string
}
 
// Header.SearchForm
export default class SearchForm extends React.Component<Props, State> {
  static defaultProps = { pollInterval: 1000 }
 
  ticker: number | undefined
 
  constructor(props: Props) {
    super(props)
 
    this.state = {
      keyword: props.keyword,
      searchedKeyword: '',
    }
 
    this.handleSubmit = this.handleSubmit.bind(this)
    this.handleChange = this.handleChange.bind(this)
    this.handleFocus = this.handleFocus.bind(this)
    this.clearForm = this.clearForm.bind(this)
  }
 
  componentDidMount() {
    this.ticker = window.setInterval(this.searchFieldTicker.bind(this), this.props.pollInterval)
  }
 
  componentWillUnmount() {
    window.clearInterval(this.ticker)
  }
 
  search() {
    const { keyword, searchedKeyword } = this.state
    if (keyword !== searchedKeyword) {
      this.props.onSearchFormChanged({ keyword })
      this.setState({ searchedKeyword: keyword })
    }
  }
 
  renderClearForm() {
    return (
      <a className="search-top-clear" onClick={this.clearForm}>
        <Icon name="closeCircle" />
      </a>
    )
  }
 
  clearForm() {
    this.setState({ keyword: '' })
    this.search()
  }
 
  searchFieldTicker() {
    this.search()
  }
 
  handleFocus(event: React.FocusEvent<HTMLInputElement>) {
    this.props.isShown(true)
  }
 
  handleChange(event: React.ChangeEvent<HTMLInputElement>) {
    const keyword = event.target.value
    this.setState({ keyword })
  }
 
  handleSubmit(e: React.FormEvent<HTMLFormElement>) {
    const { keyword } = this.state
    const { isSearchPage } = this.props
    if (isSearchPage) {
      e.preventDefault()
      Emitter.emit('search', { keyword })
    }
  }
 
  render() {
    const showClearForm = this.props.focused && this.state.keyword !== ''
    const focusedStyles = this.props.focused ? { maxWidth: 'none' } : {}
    const formClearStyles = showClearForm ? { paddingRight: 40 } : {}
 
    return (
      <form action="/_search" className="search-form search-top-input-group" onSubmit={this.handleSubmit}>
        <div className="search-top-icon">
          <Icon name="magnify" />
        </div>
        {showClearForm && this.renderClearForm()}
        <input
          autoComplete="off"
          type="text"
          className="search-top-input form-control"
          placeholder="Search ... Page title and content"
          name="q"
          value={this.state.keyword}
          onFocus={this.handleFocus}
          onChange={this.handleChange}
          style={{ ...focusedStyles, ...formClearStyles }}
        />
      </form>
    )
  }
}