Source

components/search-box.js

  1. import { any, element, func, string } from 'prop-types';
  2. import React from 'react';
  3. import { connect } from "react-redux";
  4. class SearchBoxBase extends React.Component {
  5. constructor(props) {
  6. super(props);
  7. this.state = {
  8. query: this.props.initValue || ""
  9. };
  10. }
  11. componentDidMount() {
  12. this.focus();
  13. }
  14. onSubmit(e) {
  15. e.preventDefault();
  16. this.state.query && this.props.navigateTo(`/search?q=${encodeURIComponent(this.state.query)}`);
  17. this.props.onSubmitHandler && this.props.onSubmitHandler(this.state.query);
  18. }
  19. keyPress(e) {
  20. if (e.keyCode === 27)
  21. this.props.onEscape && this.props.onEscape();
  22. }
  23. focus() {
  24. this.textInput && this.textInput.focus();
  25. }
  26. static defaultTemplate({ children }) {
  27. return children;
  28. }
  29. render() {
  30. const Render = this.props.template || this.defaultTemplate;
  31. return <form role="search" action="/search" onSubmit={(e) => this.onSubmit(e)} className={this.props.className} ref={this.props.formRef}>
  32. <Render>
  33. <input type="search"
  34. name="q"
  35. placeholder={this.props.placeholder}
  36. value={this.state.query}
  37. onChange={(e) => this.setState({ query: e.target.value })}
  38. className={this.props.inputClassName}
  39. id={this.props.inputId}
  40. ref={(input) => this.textInput = input}
  41. onKeyDown={(e) => this.keyPress(e)} />
  42. </Render>
  43. </form>
  44. }
  45. }
  46. SearchBoxBase.propTypes = {
  47. initValue: string,
  48. placeholder: string,
  49. className: string,
  50. formRef: any,
  51. inputClassName: string,
  52. inputId: string,
  53. template: element,
  54. onSubmitHandler: func,
  55. onEscape: func,
  56. navigateTo: func
  57. };
  58. const mapStateToProps = state => ({});
  59. const mapDispatchToProps = dispatch => ({
  60. navigateTo: function (url) {
  61. global.app.navigateToPage(dispatch, url);
  62. }
  63. });
  64. /**
  65. * This component provides a form with a search text box. On submit, the user is redirected to the search page via AJAX.
  66. *
  67. * A template function can also be passed in, to do custom rendering. The template prop will be called with childen having the child text box.
  68. *
  69. * Example
  70. * ```javascript
  71. * import { SearchBox } from '@quintype/components';
  72. *
  73. * <SearchBox className="foobar" placeholder="search" inputClassName="foobar-box" inputId="stg" inputRef={(x) => this.foo = x} onEscape={() => this.closeDialog()}/>
  74. * ```
  75. * @component
  76. * @category Header
  77. */
  78. export const SearchBox = connect(mapStateToProps, mapDispatchToProps)(SearchBoxBase);