aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/ui
diff options
context:
space:
mode:
authorLibravatar muhamedsalih-tw <104364298+muhamedsalih-tw@users.noreply.github.com>2022-11-01 06:42:12 +0530
committerLibravatar GitHub <noreply@github.com>2022-11-01 01:12:12 +0000
commit85d1aac4cd70e79d5ab64684dea09e92b17ed2c2 (patch)
treea006a2eb5c58b9351219d8a85d57a04c5c73787a /src/components/ui
parentrefactor: convert global app to typescript (#723) (diff)
downloadferdium-app-85d1aac4cd70e79d5ab64684dea09e92b17ed2c2.tar.gz
ferdium-app-85d1aac4cd70e79d5ab64684dea09e92b17ed2c2.tar.zst
ferdium-app-85d1aac4cd70e79d5ab64684dea09e92b17ed2c2.zip
Transform ChangeServer components tree to typescript (#725)
Diffstat (limited to 'src/components/ui')
-rw-r--r--src/components/ui/Infobox.tsx (renamed from src/components/ui/Infobox.js)90
-rw-r--r--src/components/ui/Input.tsx21
-rw-r--r--src/components/ui/Select.tsx (renamed from src/components/ui/Select.js)77
-rw-r--r--src/components/ui/infobox/index.tsx88
-rw-r--r--src/components/ui/select/index.tsx151
5 files changed, 221 insertions, 206 deletions
diff --git a/src/components/ui/Infobox.js b/src/components/ui/Infobox.tsx
index 8fb80d87f..1fc24816a 100644
--- a/src/components/ui/Infobox.js
+++ b/src/components/ui/Infobox.tsx
@@ -1,11 +1,11 @@
1import { Component } from 'react'; 1import { Component, MouseEventHandler, ReactElement, ReactNode } from 'react';
2import PropTypes from 'prop-types';
3import { observer } from 'mobx-react';
4import classnames from 'classnames'; 2import classnames from 'classnames';
5import Loader from 'react-loader'; 3import Loader from 'react-loader';
6import { defineMessages, injectIntl } from 'react-intl'; 4import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl';
7import { mdiAlert, mdiCheckboxMarkedCircleOutline, mdiClose } from '@mdi/js'; 5import { mdiAlert, mdiCheckboxMarkedCircleOutline, mdiClose } from '@mdi/js';
8import Icon from '../ui/icon'; 6import { noop } from 'lodash';
7import { observer } from 'mobx-react';
8import Icon from './icon';
9 9
10const icons = { 10const icons = {
11 'checkbox-marked-circle-outline': mdiCheckboxMarkedCircleOutline, 11 'checkbox-marked-circle-outline': mdiCheckboxMarkedCircleOutline,
@@ -19,55 +19,51 @@ const messages = defineMessages({
19 }, 19 },
20}); 20});
21 21
22// Can this file be merged into the './infobox/index.tsx' file? 22interface IProps extends WrappedComponentProps {
23class Infobox extends Component { 23 children: ReactNode;
24 static propTypes = { 24 icon?: string;
25 // eslint-disable-next-line react/forbid-prop-types 25 type?: string;
26 children: PropTypes.any.isRequired, 26 ctaLabel?: string;
27 icon: PropTypes.string, 27 ctaLoading?: boolean;
28 type: PropTypes.string, 28 dismissible?: boolean;
29 ctaOnClick: PropTypes.func, 29 ctaOnClick?: MouseEventHandler<HTMLButtonElement>;
30 ctaLabel: PropTypes.string, 30 onDismiss?: () => void;
31 ctaLoading: PropTypes.bool, 31 onSeen?: () => void;
32 dismissable: PropTypes.bool, 32}
33 onDismiss: PropTypes.func,
34 onSeen: PropTypes.func,
35 };
36 33
37 static defaultProps = { 34interface IState {
38 icon: '', 35 dismissed: boolean;
39 type: 'primary', 36}
40 dismissable: false,
41 ctaOnClick: () => null,
42 ctaLabel: '',
43 ctaLoading: false,
44 onDismiss: () => null,
45 onSeen: () => null,
46 };
47 37
48 state = { 38// Can this file be merged into the './infobox/index.tsx' file?
49 dismissed: false, 39@observer
50 }; 40class Infobox extends Component<IProps, IState> {
41 constructor(props: IProps) {
42 super(props);
43
44 this.state = {
45 dismissed: false,
46 };
47 }
51 48
52 componentDidMount() { 49 componentDidMount(): void {
53 const { onSeen } = this.props; 50 const { onSeen = noop } = this.props;
54 if (onSeen) onSeen(); 51 onSeen();
55 } 52 }
56 53
57 render() { 54 render(): ReactElement | null {
58 const { 55 const {
59 children, 56 children,
60 icon, 57 icon = '',
61 type, 58 type = 'primary',
62 ctaLabel, 59 dismissible = false,
63 ctaLoading, 60 ctaOnClick = noop,
64 ctaOnClick, 61 ctaLabel = '',
65 dismissable, 62 ctaLoading = false,
66 onDismiss, 63 onDismiss = noop,
64 intl,
67 } = this.props; 65 } = this.props;
68 66
69 const { intl } = this.props;
70
71 if (this.state.dismissed) { 67 if (this.state.dismissed) {
72 return null; 68 return null;
73 } 69 }
@@ -94,7 +90,7 @@ class Infobox extends Component {
94 {ctaLabel} 90 {ctaLabel}
95 </button> 91 </button>
96 )} 92 )}
97 {dismissable && ( 93 {dismissible && (
98 <button 94 <button
99 type="button" 95 type="button"
100 onClick={() => { 96 onClick={() => {
@@ -112,4 +108,4 @@ class Infobox extends Component {
112 } 108 }
113} 109}
114 110
115export default injectIntl(observer(Infobox)); 111export default injectIntl(Infobox);
diff --git a/src/components/ui/Input.tsx b/src/components/ui/Input.tsx
index 78b3a9200..c22dc5838 100644
--- a/src/components/ui/Input.tsx
+++ b/src/components/ui/Input.tsx
@@ -1,8 +1,16 @@
1import { ChangeEvent, Component, createRef, RefObject } from 'react'; 1import {
2 ChangeEvent,
3 ChangeEventHandler,
4 Component,
5 createRef,
6 ReactElement,
7 RefObject,
8} from 'react';
2import { observer } from 'mobx-react'; 9import { observer } from 'mobx-react';
3import classnames from 'classnames'; 10import classnames from 'classnames';
4import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl'; 11import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl';
5import { mdiEye, mdiEyeOff } from '@mdi/js'; 12import { mdiEye, mdiEyeOff } from '@mdi/js';
13import { noop } from 'lodash';
6import { scorePassword as scorePasswordFunc } from '../../helpers/password-helpers'; 14import { scorePassword as scorePasswordFunc } from '../../helpers/password-helpers';
7import Icon from './icon'; 15import Icon from './icon';
8import { Field } from '../../@types/mobx-form.types'; 16import { Field } from '../../@types/mobx-form.types';
@@ -23,6 +31,8 @@ interface IProps extends WrappedComponentProps {
23 scorePassword?: boolean; 31 scorePassword?: boolean;
24 prefix?: string; 32 prefix?: string;
25 suffix?: string; 33 suffix?: string;
34 placeholder?: string;
35 onChange?: ChangeEventHandler<HTMLInputElement>;
26} 36}
27 37
28interface IState { 38interface IState {
@@ -53,14 +63,17 @@ class Input extends Component<IProps, IState> {
53 } 63 }
54 64
55 onChange(e: ChangeEvent<HTMLInputElement>): void { 65 onChange(e: ChangeEvent<HTMLInputElement>): void {
56 const { field, scorePassword } = this.props; 66 const { field, scorePassword, onChange = noop } = this.props;
57 67
58 if (field.onChange) { 68 if (field.onChange) {
69 onChange(e);
59 field.onChange(e); 70 field.onChange(e);
60 } 71 }
61 72
62 if (scorePassword) { 73 if (scorePassword) {
63 this.setState({ passwordScore: scorePasswordFunc(field.value) }); 74 this.setState({
75 passwordScore: scorePasswordFunc(field.value as string),
76 });
64 } 77 }
65 } 78 }
66 79
@@ -70,7 +83,7 @@ class Input extends Component<IProps, IState> {
70 } 83 }
71 } 84 }
72 85
73 render() { 86 render(): ReactElement {
74 const { 87 const {
75 field, 88 field,
76 className = null, 89 className = null,
diff --git a/src/components/ui/Select.js b/src/components/ui/Select.tsx
index ca5ec9964..1d69a9acf 100644
--- a/src/components/ui/Select.js
+++ b/src/components/ui/Select.tsx
@@ -1,40 +1,41 @@
1import { createRef, Component } from 'react'; 1import {
2import PropTypes from 'prop-types'; 2 createRef,
3 Component,
4 ReactElement,
5 RefObject,
6 ChangeEvent,
7} from 'react';
3import { observer } from 'mobx-react'; 8import { observer } from 'mobx-react';
4import { Field } from 'mobx-react-form';
5import classnames from 'classnames'; 9import classnames from 'classnames';
10import { Field } from '../../@types/mobx-form.types';
6 11
7// Can this file be merged into the './select/index.tsx' file? 12interface IProps {
8class Select extends Component { 13 field: Field;
9 static propTypes = { 14 className?: string;
10 field: PropTypes.instanceOf(Field).isRequired, 15 showLabel?: boolean;
11 className: PropTypes.string, 16 disabled?: boolean;
12 showLabel: PropTypes.bool, 17 multiple?: boolean;
13 disabled: PropTypes.bool, 18}
14 multiple: PropTypes.bool,
15 };
16 19
17 static defaultProps = { 20// Can this file be merged into the './select/index.tsx' file?
18 className: null, 21@observer
19 showLabel: true, 22class Select extends Component<IProps> {
20 disabled: false, 23 private element: RefObject<HTMLSelectElement> =
21 multiple: false, 24 createRef<HTMLSelectElement>();
22 };
23 25
24 constructor(props) { 26 constructor(props: IProps) {
25 super(props); 27 super(props);
26
27 this.element = createRef();
28 } 28 }
29 29
30 multipleChange() { 30 multipleChange(e: ChangeEvent<HTMLSelectElement>): void {
31 const element = this.element.current; 31 e.preventDefault();
32 32 if (!this.element.current) {
33 const result = []; 33 return;
34 const options = element && element.options; 34 }
35 35 const result: string[] = [];
36 const { options } = this.element.current;
36 for (const option of options) { 37 for (const option of options) {
37 if (option.selected) { 38 if (option.selected && (option.value || option.text)) {
38 result.push(option.value || option.text); 39 result.push(option.value || option.text);
39 } 40 }
40 } 41 }
@@ -43,8 +44,14 @@ class Select extends Component {
43 field.value = result; 44 field.value = result;
44 } 45 }
45 46
46 render() { 47 render(): ReactElement {
47 const { field, className, showLabel, disabled, multiple } = this.props; 48 const {
49 field,
50 className = null,
51 showLabel = true,
52 disabled = false,
53 multiple = false,
54 } = this.props;
48 55
49 let selected = field.value; 56 let selected = field.value;
50 57
@@ -74,7 +81,11 @@ class Select extends Component {
74 </label> 81 </label>
75 )} 82 )}
76 <select 83 <select
77 onChange={multiple ? e => this.multipleChange(e) : field.onChange} 84 onChange={
85 multiple
86 ? (e: ChangeEvent<HTMLSelectElement>) => this.multipleChange(e)
87 : field.onChange
88 }
78 id={field.id} 89 id={field.id}
79 defaultValue={selected} 90 defaultValue={selected}
80 className="franz-form__select" 91 className="franz-form__select"
@@ -82,7 +93,7 @@ class Select extends Component {
82 multiple={multiple} 93 multiple={multiple}
83 ref={this.element} 94 ref={this.element}
84 > 95 >
85 {field.options.map(type => ( 96 {field.options!.map(type => (
86 <option 97 <option
87 key={type.value} 98 key={type.value}
88 value={type.value} 99 value={type.value}
@@ -98,4 +109,4 @@ class Select extends Component {
98 } 109 }
99} 110}
100 111
101export default observer(Select); 112export default Select;
diff --git a/src/components/ui/infobox/index.tsx b/src/components/ui/infobox/index.tsx
index ad59ea81e..3b878a9de 100644
--- a/src/components/ui/infobox/index.tsx
+++ b/src/components/ui/infobox/index.tsx
@@ -1,32 +1,14 @@
1import { mdiClose } from '@mdi/js'; 1import { mdiClose } from '@mdi/js';
2import classnames from 'classnames'; 2import classnames from 'classnames';
3import { Component, ReactNode } from 'react'; 3import { noop } from 'lodash';
4import injectStyle, { WithStylesProps } from 'react-jss'; 4import { Component, ReactElement, ReactNode } from 'react';
5 5import withStyles, { WithStylesProps } from 'react-jss';
6import { Theme } from '../../../themes'; 6import { Theme } from '../../../themes';
7import Icon from '../icon'; 7import Icon from '../icon';
8 8
9interface IProps extends WithStylesProps<typeof styles> {
10 children: ReactNode;
11 icon?: string;
12 type?: string;
13 dismissable?: boolean;
14 ctaLabel?: string;
15
16 className?: string;
17 onDismiss?: () => void;
18 onUnmount?: () => void;
19 ctaOnClick?: () => void;
20}
21
22interface IState {
23 isDismissing: boolean;
24 dismissed: boolean;
25}
26
27const buttonStyles = (theme: Theme) => { 9const buttonStyles = (theme: Theme) => {
28 const styles = {}; 10 const styles = {};
29 Object.keys(theme.styleTypes).map(style => { 11 for (const style of Object.keys(theme.styleTypes)) {
30 Object.assign(styles, { 12 Object.assign(styles, {
31 [style]: { 13 [style]: {
32 background: theme.styleTypes[style].accent, 14 background: theme.styleTypes[style].accent,
@@ -38,7 +20,7 @@ const buttonStyles = (theme: Theme) => {
38 }, 20 },
39 }, 21 },
40 }); 22 });
41 }); 23 }
42 24
43 return styles; 25 return styles;
44}; 26};
@@ -108,23 +90,35 @@ const styles = (theme: Theme) => ({
108 ...buttonStyles(theme), 90 ...buttonStyles(theme),
109}); 91});
110 92
93interface IProps extends WithStylesProps<typeof styles> {
94 children: ReactNode;
95 icon?: string;
96 type?: string;
97 dismissible?: boolean;
98 ctaLabel?: string;
99 className?: string;
100 onDismiss?: () => void;
101 onUnmount?: () => void;
102 ctaOnClick?: () => void;
103}
104
105interface IState {
106 isDismissing: boolean;
107 dismissed: boolean;
108}
109
111class InfoboxComponent extends Component<IProps, IState> { 110class InfoboxComponent extends Component<IProps, IState> {
112 public static defaultProps = { 111 constructor(props: IProps) {
113 type: 'primary', 112 super(props);
114 dismissable: false, 113
115 ctaOnClick: () => {}, 114 this.state = {
116 onDismiss: () => {}, 115 isDismissing: false,
117 ctaLabel: '', 116 dismissed: false,
118 className: '', 117 };
119 }; 118 }
120 119
121 state = { 120 dismiss(): void {
122 isDismissing: false, 121 const { onDismiss = noop } = this.props;
123 dismissed: false,
124 };
125
126 dismiss() {
127 const { onDismiss } = this.props;
128 122
129 this.setState({ 123 this.setState({
130 isDismissing: true, 124 isDismissing: true,
@@ -146,16 +140,16 @@ class InfoboxComponent extends Component<IProps, IState> {
146 if (onUnmount) onUnmount(); 140 if (onUnmount) onUnmount();
147 } 141 }
148 142
149 render() { 143 render(): ReactElement | null {
150 const { 144 const {
151 classes, 145 classes,
152 children, 146 children,
153 icon, 147 icon,
154 type, 148 type = 'primary',
155 ctaLabel, 149 dismissible = false,
156 ctaOnClick, 150 ctaOnClick = noop,
157 dismissable, 151 ctaLabel = '',
158 className, 152 className = '',
159 } = this.props; 153 } = this.props;
160 154
161 const { isDismissing, dismissed } = this.state; 155 const { isDismissing, dismissed } = this.state;
@@ -186,7 +180,7 @@ class InfoboxComponent extends Component<IProps, IState> {
186 {ctaLabel} 180 {ctaLabel}
187 </button> 181 </button>
188 )} 182 )}
189 {dismissable && ( 183 {dismissible && (
190 <button 184 <button
191 type="button" 185 type="button"
192 onClick={this.dismiss.bind(this)} 186 onClick={this.dismiss.bind(this)}
@@ -201,4 +195,4 @@ class InfoboxComponent extends Component<IProps, IState> {
201 } 195 }
202} 196}
203 197
204export default injectStyle(styles, { injectTheme: true })(InfoboxComponent); 198export default withStyles(styles, { injectTheme: true })(InfoboxComponent);
diff --git a/src/components/ui/select/index.tsx b/src/components/ui/select/index.tsx
index 805836130..b22c15320 100644
--- a/src/components/ui/select/index.tsx
+++ b/src/components/ui/select/index.tsx
@@ -5,47 +5,15 @@ import {
5} from '@mdi/js'; 5} from '@mdi/js';
6import Icon from '@mdi/react'; 6import Icon from '@mdi/react';
7import classnames from 'classnames'; 7import classnames from 'classnames';
8import { ChangeEvent, Component, createRef } from 'react'; 8import { ChangeEvent, Component, createRef, ReactElement } from 'react';
9import injectStyle, { WithStylesProps } from 'react-jss'; 9import withStyles, { WithStylesProps } from 'react-jss';
10 10import { noop } from 'lodash';
11import { Theme } from '../../../themes'; 11import { Theme } from '../../../themes';
12import { IFormField } from '../typings/generic'; 12import { IFormField } from '../typings/generic';
13
14import Error from '../error'; 13import Error from '../error';
15import Label from '../label'; 14import Label from '../label';
16import Wrapper from '../wrapper'; 15import Wrapper from '../wrapper';
17 16
18interface IOptions {
19 [index: string]: string;
20}
21
22interface IData {
23 [index: string]: string;
24}
25
26interface IProps extends IFormField, WithStylesProps<typeof styles> {
27 actionText: string;
28 className?: string;
29 inputClassName?: string;
30 defaultValue?: string;
31 disabled?: boolean;
32 id?: string;
33 name: string;
34 options: IOptions;
35 value: string;
36 onChange: (event: ChangeEvent<HTMLInputElement>) => void;
37 showSearch: boolean;
38 data: IData;
39}
40
41interface IState {
42 open: boolean;
43 value: string;
44 needle: string;
45 selected: number;
46 options: IOptions;
47}
48
49let popupTransition: string = 'none'; 17let popupTransition: string = 'none';
50let toggleTransition: string = 'none'; 18let toggleTransition: string = 'none';
51 19
@@ -149,22 +117,38 @@ const styles = (theme: Theme) => ({
149 input: {}, 117 input: {},
150}); 118});
151 119
152class SelectComponent extends Component<IProps> { 120interface IOptions {
153 public static defaultProps = { 121 [index: string]: string;
154 onChange: () => {}, 122}
155 showLabel: true,
156 disabled: false,
157 error: '',
158 };
159
160 state = {
161 open: false,
162 value: '',
163 needle: '',
164 selected: 0,
165 options: null,
166 };
167 123
124interface IData {
125 [index: string]: string;
126}
127
128interface IProps extends IFormField, WithStylesProps<typeof styles> {
129 actionText: string;
130 className?: string;
131 inputClassName?: string;
132 defaultValue?: string;
133 disabled?: boolean;
134 id?: string;
135 name: string;
136 options: IOptions;
137 value: string;
138 onChange: (event: ChangeEvent<HTMLInputElement> | string) => void;
139 showSearch: boolean;
140 data: IData;
141}
142
143interface IState {
144 open: boolean;
145 value: string;
146 needle: string;
147 selected: number;
148 options: IOptions | null;
149}
150
151class SelectComponent extends Component<IProps, IState> {
168 private componentRef = createRef<HTMLDivElement>(); 152 private componentRef = createRef<HTMLDivElement>();
169 153
170 private inputRef = createRef<HTMLInputElement>(); 154 private inputRef = createRef<HTMLInputElement>();
@@ -175,9 +159,12 @@ class SelectComponent extends Component<IProps> {
175 159
176 private activeOptionRef = createRef<HTMLDivElement>(); 160 private activeOptionRef = createRef<HTMLDivElement>();
177 161
178 private keyListener: any; 162 private keyListener: (e: KeyboardEvent) => void;
179 163
180 static getDerivedStateFromProps(nextProps: IProps, prevState: IProps) { 164 static getDerivedStateFromProps(
165 nextProps: IProps,
166 prevState: IProps,
167 ): Partial<IState> {
181 if (nextProps.value && nextProps.value !== prevState.value) { 168 if (nextProps.value && nextProps.value !== prevState.value) {
182 return { 169 return {
183 value: nextProps.value, 170 value: nextProps.value,
@@ -189,7 +176,22 @@ class SelectComponent extends Component<IProps> {
189 }; 176 };
190 } 177 }
191 178
192 componentDidUpdate() { 179 constructor(props: IProps) {
180 super(props);
181
182 this.state = {
183 open: false,
184 value: '',
185 needle: '',
186 selected: 0,
187 options: null,
188 };
189
190 this.keyListener = noop;
191 this.arrowKeysHandler = this.arrowKeysHandler.bind(this);
192 }
193
194 componentDidUpdate(): void {
193 const { open } = this.state; 195 const { open } = this.state;
194 196
195 if (this.searchInputRef && this.searchInputRef.current && open) { 197 if (this.searchInputRef && this.searchInputRef.current && open) {
@@ -197,22 +199,20 @@ class SelectComponent extends Component<IProps> {
197 } 199 }
198 } 200 }
199 201
200 componentDidMount() { 202 componentDidMount(): void {
201 if (this.inputRef && this.inputRef.current) { 203 if (this.inputRef && this.inputRef.current) {
202 const { data } = this.props; 204 const { data } = this.props;
203 205
204 if (data) { 206 if (data) {
205 Object.keys(data).map( 207 for (const key of Object.keys(data))
206 // eslint-disable-next-line no-return-assign 208 this.inputRef.current!.dataset[key] = data[key];
207 key => (this.inputRef.current!.dataset[key] = data[key]),
208 );
209 } 209 }
210 } 210 }
211 211
212 window.addEventListener('keydown', this.arrowKeysHandler.bind(this), false); 212 window.addEventListener('keydown', this.arrowKeysHandler, false);
213 } 213 }
214 214
215 componentWillMount() { 215 UNSAFE_componentWillMount(): void {
216 const { value } = this.props; 216 const { value } = this.props;
217 217
218 if (this.componentRef && this.componentRef.current) { 218 if (this.componentRef && this.componentRef.current) {
@@ -231,17 +231,16 @@ class SelectComponent extends Component<IProps> {
231 this.setFilter(); 231 this.setFilter();
232 } 232 }
233 233
234 componentWillUnmount() { 234 componentWillUnmount(): void {
235 // eslint-disable-next-line unicorn/no-invalid-remove-event-listener 235 window.removeEventListener('keydown', this.arrowKeysHandler);
236 window.removeEventListener('keydown', this.arrowKeysHandler.bind(this));
237 } 236 }
238 237
239 setFilter(needle = '') { 238 setFilter(needle = ''): void {
240 const { options } = this.props; 239 const { options } = this.props;
241 240
242 let filteredOptions = {}; 241 let filteredOptions = {};
243 if (needle) { 242 if (needle) {
244 Object.keys(options).map(key => { 243 for (const key of Object.keys(options)) {
245 if ( 244 if (
246 key.toLocaleLowerCase().startsWith(needle.toLocaleLowerCase()) || 245 key.toLocaleLowerCase().startsWith(needle.toLocaleLowerCase()) ||
247 options[key] 246 options[key]
@@ -252,7 +251,7 @@ class SelectComponent extends Component<IProps> {
252 [`${key}`]: options[key], 251 [`${key}`]: options[key],
253 }); 252 });
254 } 253 }
255 }); 254 }
256 } else { 255 } else {
257 filteredOptions = options; 256 filteredOptions = options;
258 } 257 }
@@ -264,7 +263,7 @@ class SelectComponent extends Component<IProps> {
264 }); 263 });
265 } 264 }
266 265
267 select(key: string) { 266 select(key: string): void {
268 this.setState(() => ({ 267 this.setState(() => ({
269 value: key, 268 value: key,
270 open: false, 269 open: false,
@@ -273,11 +272,11 @@ class SelectComponent extends Component<IProps> {
273 this.setFilter(); 272 this.setFilter();
274 273
275 if (this.props.onChange) { 274 if (this.props.onChange) {
276 this.props.onChange(key as any); 275 this.props.onChange(key);
277 } 276 }
278 } 277 }
279 278
280 arrowKeysHandler(e: KeyboardEvent) { 279 arrowKeysHandler(e: KeyboardEvent): void {
281 const { selected, open, options } = this.state; 280 const { selected, open, options } = this.state;
282 281
283 if (!open) return; 282 if (!open) return;
@@ -329,22 +328,22 @@ class SelectComponent extends Component<IProps> {
329 } 328 }
330 } 329 }
331 330
332 render() { 331 render(): ReactElement {
333 const { 332 const {
334 actionText, 333 actionText,
335 classes, 334 classes,
336 className, 335 className,
337 defaultValue, 336 defaultValue,
338 disabled,
339 error,
340 id, 337 id,
341 inputClassName, 338 inputClassName,
342 name, 339 name,
343 label, 340 label,
344 showLabel,
345 showSearch, 341 showSearch,
346 onChange,
347 required, 342 required,
343 onChange = noop,
344 showLabel = true,
345 disabled = false,
346 error = '',
348 } = this.props; 347 } = this.props;
349 348
350 const { open, needle, value, selected, options } = this.state; 349 const { open, needle, value, selected, options } = this.state;
@@ -440,6 +439,8 @@ class SelectComponent extends Component<IProps> {
440 })} 439 })}
441 onMouseOver={() => this.setState({ selected: i })} 440 onMouseOver={() => this.setState({ selected: i })}
442 ref={selected === i ? this.activeOptionRef : null} 441 ref={selected === i ? this.activeOptionRef : null}
442 onKeyUp={noop}
443 onFocus={noop}
443 > 444 >
444 {options![key]} 445 {options![key]}
445 </div> 446 </div>
@@ -463,4 +464,4 @@ class SelectComponent extends Component<IProps> {
463 } 464 }
464} 465}
465 466
466export default injectStyle(styles, { injectTheme: true })(SelectComponent); 467export default withStyles(styles, { injectTheme: true })(SelectComponent);