Skip to content

Commit e73257a

Browse files
Yannick CroissantHaroenv
Yannick Croissant
andauthoredApr 6, 2021
feat(ts): convert search-box to TypeScript (#4710)
* feat(ts): convert search-box to TypeScript * Apply suggestions from code review Co-authored-by: Haroen Viaene <hello@haroen.me> * fixup! feat(ts): convert search-box to TypeScript * fixup! feat(ts): convert search-box to TypeScript * fixup! feat(ts): convert search-box to TypeScript Co-authored-by: Haroen Viaene <hello@haroen.me>
1 parent 8f2aad2 commit e73257a

File tree

13 files changed

+626
-484
lines changed

13 files changed

+626
-484
lines changed
 

‎src/components/SearchBox/SearchBox.js ‎src/components/SearchBox/SearchBox.tsx

+74-62
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,81 @@
11
/** @jsx h */
22

3-
import { h, Component } from 'preact';
4-
import PropTypes from 'prop-types';
3+
import { h, createRef, Component } from 'preact';
54
import { noop } from '../../lib/utils';
65
import Template from '../Template/Template';
7-
8-
const SearchBoxCSSClasses = PropTypes.shape({
9-
root: PropTypes.string.isRequired,
10-
form: PropTypes.string.isRequired,
11-
input: PropTypes.string.isRequired,
12-
submit: PropTypes.string.isRequired,
13-
submitIcon: PropTypes.string.isRequired,
14-
reset: PropTypes.string.isRequired,
15-
resetIcon: PropTypes.string.isRequired,
16-
loadingIndicator: PropTypes.string.isRequired,
17-
loadingIcon: PropTypes.string.isRequired,
18-
});
19-
20-
class SearchBox extends Component {
21-
static propTypes = {
22-
placeholder: PropTypes.string.isRequired,
23-
cssClasses: SearchBoxCSSClasses.isRequired,
24-
templates: PropTypes.object.isRequired,
25-
query: PropTypes.string,
26-
showSubmit: PropTypes.bool,
27-
showReset: PropTypes.bool,
28-
showLoadingIndicator: PropTypes.bool,
29-
refine: PropTypes.func,
30-
autofocus: PropTypes.bool,
31-
searchAsYouType: PropTypes.bool,
32-
isSearchStalled: PropTypes.bool,
33-
disabled: PropTypes.bool,
34-
onChange: PropTypes.func,
35-
onSubmit: PropTypes.func,
36-
onReset: PropTypes.func,
37-
};
38-
39-
static defaultProps = {
40-
query: '',
41-
showSubmit: true,
42-
showReset: true,
43-
showLoadingIndicator: true,
44-
autofocus: false,
45-
searchAsYouType: true,
46-
isSearchStalled: false,
47-
disabled: false,
48-
onChange: noop,
49-
onSubmit: noop,
50-
onReset: noop,
51-
refine: noop,
52-
};
53-
54-
state = {
6+
import {
7+
SearchBoxRendererCSSClasses,
8+
SearchBoxTemplates,
9+
} from '../../widgets/search-box/search-box';
10+
11+
type SearchBoxProps = {
12+
placeholder?: string;
13+
cssClasses: SearchBoxRendererCSSClasses;
14+
templates?: SearchBoxTemplates;
15+
query?: string;
16+
showSubmit?: boolean;
17+
showReset?: boolean;
18+
showLoadingIndicator?: boolean;
19+
refine?: (value: string) => void;
20+
autofocus?: boolean;
21+
searchAsYouType?: boolean;
22+
isSearchStalled?: boolean;
23+
disabled?: boolean;
24+
onChange?: (event: Event) => void;
25+
onSubmit?: (event: Event) => void;
26+
onReset?: (event: Event) => void;
27+
};
28+
29+
const defaultProps = {
30+
query: '',
31+
showSubmit: true,
32+
showReset: true,
33+
showLoadingIndicator: true,
34+
autofocus: false,
35+
searchAsYouType: true,
36+
isSearchStalled: false,
37+
disabled: false,
38+
onChange: noop,
39+
onSubmit: noop,
40+
onReset: noop,
41+
refine: noop,
42+
};
43+
44+
type SearchBoxPropsWithDefaultProps = SearchBoxProps &
45+
Readonly<typeof defaultProps>;
46+
47+
type SearchBoxState = {
48+
query: string;
49+
focused: boolean;
50+
};
51+
52+
class SearchBox extends Component<
53+
SearchBoxPropsWithDefaultProps,
54+
SearchBoxState
55+
> {
56+
public static defaultProps = defaultProps;
57+
58+
public state = {
5559
query: this.props.query,
5660
focused: false,
5761
};
5862

63+
private input = createRef<HTMLInputElement>();
64+
5965
/**
6066
* This public method is used in the RefinementList SFFV search box
6167
* to reset the input state when an item is selected.
6268
*
6369
* @see RefinementList#componentWillReceiveProps
6470
* @return {undefined}
6571
*/
66-
resetInput() {
72+
public resetInput() {
6773
this.setState({ query: '' });
6874
}
6975

70-
onInput = event => {
76+
private onInput = (event: Event) => {
7177
const { searchAsYouType, refine, onChange } = this.props;
72-
const query = event.target.value;
78+
const query = (event.target as HTMLInputElement).value;
7379

7480
if (searchAsYouType) {
7581
refine(query);
@@ -79,7 +85,7 @@ class SearchBox extends Component {
7985
onChange(event);
8086
};
8187

82-
componentWillReceiveProps(nextProps) {
88+
public componentWillReceiveProps(nextProps: SearchBoxPropsWithDefaultProps) {
8389
/**
8490
* when the user is typing, we don't want to replace the query typed
8591
* by the user (state.query) with the query exposed by the connector (props.query)
@@ -90,12 +96,14 @@ class SearchBox extends Component {
9096
}
9197
}
9298

93-
onSubmit = event => {
99+
private onSubmit = (event: Event) => {
94100
const { searchAsYouType, refine, onSubmit } = this.props;
95101

96102
event.preventDefault();
97103
event.stopPropagation();
98-
this.input.blur();
104+
if (this.input.current) {
105+
this.input.current.blur();
106+
}
99107

100108
if (!searchAsYouType) {
101109
refine(this.state.query);
@@ -106,27 +114,29 @@ class SearchBox extends Component {
106114
return false;
107115
};
108116

109-
onReset = event => {
117+
private onReset = (event: Event) => {
110118
const { refine, onReset } = this.props;
111119
const query = '';
112120

113-
this.input.focus();
121+
if (this.input.current) {
122+
this.input.current.focus();
123+
}
114124

115125
refine(query);
116126
this.setState({ query });
117127

118128
onReset(event);
119129
};
120130

121-
onBlur = () => {
131+
private onBlur = () => {
122132
this.setState({ focused: false });
123133
};
124134

125-
onFocus = () => {
135+
private onFocus = () => {
126136
this.setState({ focused: true });
127137
};
128138

129-
render() {
139+
public render() {
130140
const {
131141
cssClasses,
132142
placeholder,
@@ -146,10 +156,11 @@ class SearchBox extends Component {
146156
className={cssClasses.form}
147157
noValidate
148158
onSubmit={this.onSubmit}
159+
// @ts-expect-error `onReset` attibute is missing in preact 10.0.0 JSX types
149160
onReset={this.onReset}
150161
>
151162
<input
152-
ref={inputRef => (this.input = inputRef)}
163+
ref={this.input}
153164
value={this.state.query}
154165
disabled={this.props.disabled}
155166
className={cssClasses.input}
@@ -158,6 +169,7 @@ class SearchBox extends Component {
158169
autoFocus={autofocus}
159170
autoComplete="off"
160171
autoCorrect="off"
172+
// @ts-expect-error `autoCapitalize` attibute is missing in preact 10.0.0 JSX types
161173
autoCapitalize="off"
162174
spellCheck="false"
163175
maxLength={512}

0 commit comments

Comments
 (0)
Please sign in to comment.