You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

128 lines
3.1 KiB

  1. import PureRenderMixin from 'react-addons-pure-render-mixin';
  2. import ImmutablePropTypes from 'react-immutable-proptypes';
  3. import Autosuggest from 'react-autosuggest';
  4. import AutosuggestAccountContainer from '../containers/autosuggest_account_container';
  5. import { debounce } from 'react-decoration';
  6. const getSuggestionValue = suggestion => suggestion.value;
  7. const renderSuggestion = suggestion => {
  8. if (suggestion.type === 'account') {
  9. return <AutosuggestAccountContainer id={suggestion.id} />;
  10. } else {
  11. return <span>#{suggestion.id}</span>
  12. }
  13. };
  14. const renderSectionTitle = section => (
  15. <strong>{section.title}</strong>
  16. );
  17. const getSectionSuggestions = section => section.items;
  18. const outerStyle = {
  19. padding: '10px',
  20. lineHeight: '20px',
  21. position: 'relative'
  22. };
  23. const inputStyle = {
  24. boxSizing: 'border-box',
  25. display: 'block',
  26. width: '100%',
  27. border: 'none',
  28. padding: '10px',
  29. paddingRight: '30px',
  30. fontFamily: 'Roboto',
  31. background: '#282c37',
  32. color: '#9baec8',
  33. fontSize: '14px',
  34. margin: '0'
  35. };
  36. const iconStyle = {
  37. position: 'absolute',
  38. top: '18px',
  39. right: '20px',
  40. color: '#9baec8',
  41. fontSize: '18px',
  42. pointerEvents: 'none'
  43. };
  44. const Search = React.createClass({
  45. contextTypes: {
  46. router: React.PropTypes.object
  47. },
  48. propTypes: {
  49. suggestions: React.PropTypes.array.isRequired,
  50. value: React.PropTypes.string.isRequired,
  51. onChange: React.PropTypes.func.isRequired,
  52. onClear: React.PropTypes.func.isRequired,
  53. onFetch: React.PropTypes.func.isRequired,
  54. onReset: React.PropTypes.func.isRequired
  55. },
  56. mixins: [PureRenderMixin],
  57. onChange (_, { newValue }) {
  58. if (typeof newValue !== 'string') {
  59. return;
  60. }
  61. this.props.onChange(newValue);
  62. },
  63. onSuggestionsClearRequested () {
  64. this.props.onClear();
  65. },
  66. @debounce(500)
  67. onSuggestionsFetchRequested ({ value }) {
  68. value = value.replace('#', '');
  69. this.props.onFetch(value.trim());
  70. },
  71. onSuggestionSelected (_, { suggestion }) {
  72. if (suggestion.type === 'account') {
  73. this.context.router.push(`/accounts/${suggestion.id}`);
  74. } else {
  75. this.context.router.push(`/statuses/tag/${suggestion.id}`);
  76. }
  77. },
  78. render () {
  79. const inputProps = {
  80. placeholder: 'Search',
  81. value: this.props.value,
  82. onChange: this.onChange,
  83. style: inputStyle
  84. };
  85. return (
  86. <div style={outerStyle}>
  87. <Autosuggest
  88. multiSection={true}
  89. suggestions={this.props.suggestions}
  90. focusFirstSuggestion={true}
  91. focusInputOnSuggestionClick={false}
  92. alwaysRenderSuggestions={false}
  93. onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
  94. onSuggestionsClearRequested={this.onSuggestionsClearRequested}
  95. onSuggestionSelected={this.onSuggestionSelected}
  96. getSuggestionValue={getSuggestionValue}
  97. renderSuggestion={renderSuggestion}
  98. renderSectionTitle={renderSectionTitle}
  99. getSectionSuggestions={getSectionSuggestions}
  100. inputProps={inputProps}
  101. />
  102. <div style={iconStyle}><i className='fa fa-search' /></div>
  103. </div>
  104. );
  105. },
  106. });
  107. export default Search;