UNPKG

3.31 kBTypeScriptView Raw
1import * as React from 'react';
2import { PropTypes } from 'react';
3
4import { Search, SearchResultData, SearchProps } from 'semantic-ui-react';
5import { take } from 'lodash';
6import { SearchParams } from '../context/DataStore';
7
8interface SearchBoxProps {
9 placeholder: string;
10 loading: boolean;
11 sampleSearches?: string[];
12 transition?: (params: SearchParams) => void;
13}
14
15interface SearchBoxState {
16 query: string;
17 shouldBeOpen: boolean;
18 searchEditedByUser: boolean;
19}
20
21class SearchBox extends React.Component<SearchBoxProps, SearchBoxState> {
22 static contextTypes = {
23 searchState: PropTypes.object,
24 transition: PropTypes.func
25 };
26
27 state = {
28 query: '',
29 shouldBeOpen: false,
30 searchEditedByUser: false
31 };
32
33 constructor() {
34 super();
35
36 this.onKeyUp = this.onKeyUp.bind(this);
37 this.onBlur = this.onBlur.bind(this);
38 this.onChangeQuery = this.onChangeQuery.bind(this);
39 this.onSelectTypeahead = this.onSelectTypeahead.bind(this);
40 }
41
42 onKeyUp(event: React.KeyboardEvent<object>) {
43 event.preventDefault();
44
45 if (event.keyCode === 13) {
46 this.onDoSearch(this.state.query);
47 this.setState({shouldBeOpen: false});
48 } else if (event.keyCode === 27) {
49 this.setState({shouldBeOpen: false});
50 }
51 }
52
53 onChangeQuery(e: React.MouseEvent<HTMLElement>, data: SearchProps) {
54 this.setState(
55 {
56 query: data.value + '',
57 shouldBeOpen: (data.value || '').length > 0,
58 searchEditedByUser: true
59 }
60 );
61 }
62
63 onSelectTypeahead(e: React.MouseEvent<HTMLDivElement>, data: SearchResultData) {
64 this.setState(
65 {
66 query: data.result.title,
67 shouldBeOpen: false,
68 searchEditedByUser: true
69 }
70 );
71
72 this.onDoSearch(data.value + '');
73 }
74
75 onDoSearch(value: string) {
76 const query: SearchParams = {
77 query: value,
78 start: 0
79 };
80
81 if (this.props.transition) {
82 this.props.transition(query);
83 } else {
84 this.context.transition(query);
85 }
86 }
87
88 onBlur() {
89 this.setState({shouldBeOpen: false});
90 }
91
92 render() {
93 const self = this;
94
95 const query =
96 (self.state.searchEditedByUser ?
97 self.state.query :
98 self.context.searchState ?
99 (
100 self.context.searchState.query
101 ) : ''
102 ) || '';
103
104 const lc = query.toLowerCase();
105 const filteredSearches = take(
106 (self.props.sampleSearches || []).filter(
107 (search) => search.indexOf(lc) === 0
108 ),
109 5
110 ).map(
111 (title) => { return {title}; }
112 );
113
114 return (
115 <Search
116 className="full"
117 id="searchBox"
118 open={this.state.shouldBeOpen}
119 loading={this.props.loading}
120 onResultSelect={self.onSelectTypeahead}
121 onSearchChange={self.onChangeQuery}
122 results={filteredSearches}
123 input={{fluid: true}}
124 value={query}
125 showNoResults={false}
126 fluid={true}
127 onKeyUp={self.onKeyUp}
128 onBlur={self.onBlur}
129 placeholder={this.props.placeholder}
130 size="large"
131 />
132 );
133 }
134}
135
136export {
137 SearchBoxProps,
138 SearchBoxState,
139 SearchBox
140};
\No newline at end of file