summaryrefslogtreecommitdiffstats
path: root/src/components/ui/SearchInput.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/ui/SearchInput.js')
-rw-r--r--src/components/ui/SearchInput.js124
1 files changed, 124 insertions, 0 deletions
diff --git a/src/components/ui/SearchInput.js b/src/components/ui/SearchInput.js
new file mode 100644
index 000000000..bca412cef
--- /dev/null
+++ b/src/components/ui/SearchInput.js
@@ -0,0 +1,124 @@
1import React, { Component } from 'react';
2import PropTypes from 'prop-types';
3import { observer } from 'mobx-react';
4import classnames from 'classnames';
5import uuidv1 from 'uuid/v1';
6import { debounce } from 'lodash';
7
8@observer
9export default class SearchInput extends Component {
10 static propTypes = {
11 value: PropTypes.string,
12 defaultValue: PropTypes.string,
13 className: PropTypes.string,
14 onChange: PropTypes.func,
15 onReset: PropTypes.func,
16 name: PropTypes.string,
17 throttle: PropTypes.bool,
18 throttleDelay: PropTypes.number,
19 };
20
21 static defaultProps = {
22 value: '',
23 defaultValue: '',
24 className: '',
25 name: uuidv1(),
26 throttle: false,
27 throttleDelay: 250,
28 onChange: () => null,
29 onReset: () => null,
30 }
31
32 constructor(props) {
33 super(props);
34
35 this.state = {
36 value: props.value || props.defaultValue,
37 };
38
39 this.throttledOnChange = debounce(this.throttledOnChange, this.props.throttleDelay);
40 }
41
42 onChange(e) {
43 const { throttle, onChange } = this.props;
44 const { value } = e.target;
45 this.setState({ value });
46
47 if (throttle) {
48 e.persist();
49 this.throttledOnChange(value);
50 } else {
51 onChange(value);
52 }
53 }
54
55 onClick() {
56 const { defaultValue } = this.props;
57 const { value } = this.state;
58
59 if (value === defaultValue) {
60 this.setState({ value: '' });
61 }
62
63 this.input.focus();
64 }
65
66 onBlur() {
67 const { defaultValue } = this.props;
68 const { value } = this.state;
69
70 if (value === '') {
71 this.setState({ value: defaultValue });
72 }
73 }
74
75 throttledOnChange(e) {
76 const { onChange } = this.props;
77
78 onChange(e);
79 }
80
81 reset() {
82 const { defaultValue, onReset } = this.props;
83 this.setState({ value: defaultValue });
84
85 onReset();
86 }
87
88 input = null;
89
90 render() {
91 const { className, name, defaultValue } = this.props;
92 const { value } = this.state;
93
94 return (
95 <div
96 className={classnames([
97 className,
98 'search-input',
99 ])}
100 >
101 <label
102 htmlFor={name}
103 className="mdi mdi-magnify"
104 onClick={() => this.onClick()}
105 />
106 <input
107 name={name}
108 type="text"
109 value={value}
110 onChange={e => this.onChange(e)}
111 onClick={() => this.onClick()}
112 onBlur={() => this.onBlur()}
113 ref={(ref) => { this.input = ref; }}
114 />
115 {value !== defaultValue && value.length > 0 && (
116 <span
117 className="mdi mdi-close-circle-outline"
118 onClick={() => this.reset()}
119 />
120 )}
121 </div>
122 );
123 }
124}