Skip to content
This repository was archived by the owner on Jan 16, 2022. It is now read-only.

Commit 4a61fd3

Browse files
authored
fix: strict Typing for AutoComplete Component (#503)
* feat: added autocomplete typings * formatting cleanup
1 parent 3d85e2f commit 4a61fd3

File tree

2 files changed

+41
-22
lines changed

2 files changed

+41
-22
lines changed

src/components/AutoComplete/AutoComplete.tsx

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,16 @@ import styled from '@emotion/styled';
22
import match from 'autosuggest-highlight/match';
33
import parse from 'autosuggest-highlight/parse';
44
import React, { KeyboardEvent, memo } from 'react';
5-
import Autosuggest, { SuggestionSelectedEventData, InputProps, ChangeEvent } from 'react-autosuggest';
5+
import Autosuggest, {
6+
SuggestionSelectedEventData,
7+
InputProps,
8+
ChangeEvent,
9+
SuggestionsFetchRequested,
10+
GetSuggestionValue,
11+
RenderSuggestion,
12+
RenderSuggestionsContainer,
13+
RenderInputComponent,
14+
} from 'react-autosuggest';
615
import { useTranslation } from 'react-i18next';
716

817
import { Theme } from 'verdaccio-ui/design-tokens/theme';
@@ -20,7 +29,7 @@ const StyledMenuItem = styled(MenuItem)({
2029
});
2130

2231
interface Props {
23-
suggestions: unknown[];
32+
suggestions: Suggestion[];
2433
suggestionsLoading?: boolean;
2534
suggestionsLoaded?: boolean;
2635
suggestionsError?: boolean;
@@ -30,22 +39,29 @@ interface Props {
3039
startAdornment?: JSX.Element;
3140
disableUnderline?: boolean;
3241
onChange: (event: React.FormEvent<HTMLInputElement>, params: ChangeEvent) => void;
33-
onSuggestionsFetch: ({ value: string }) => Promise<void>;
42+
onSuggestionsFetch: SuggestionsFetchRequested;
3443
onCleanSuggestions?: () => void;
3544
onClick?: (event: React.FormEvent<HTMLInputElement>, data: SuggestionSelectedEventData<unknown>) => void;
3645
onKeyDown?: (event: KeyboardEvent<HTMLInputElement>) => void;
3746
onBlur?: (event: React.FormEvent<HTMLInputElement>) => void;
3847
}
3948

49+
interface Suggestion {
50+
name: string;
51+
}
52+
53+
type CustomInputProps = Pick<Props, 'disableUnderline' | 'startAdornment'>;
54+
4055
/* eslint-disable react/jsx-sort-props */
4156
/* eslint-disable verdaccio/jsx-spread */
42-
const renderInputComponent = (inputProps): JSX.Element => {
57+
const renderInputComponent: RenderInputComponent<Suggestion> = inputProps => {
58+
// @ts-ignore
4359
const { ref, startAdornment, disableUnderline, onKeyDown, ...others } = inputProps;
4460
return (
4561
<InputField
4662
fullWidth={true}
4763
InputProps={{
48-
inputRef: node => {
64+
inputRef: (node: any) => {
4965
ref(node);
5066
},
5167
startAdornment,
@@ -57,9 +73,9 @@ const renderInputComponent = (inputProps): JSX.Element => {
5773
);
5874
};
5975

60-
const getSuggestionValue = (suggestion): string => suggestion.name;
76+
const getSuggestionValue: GetSuggestionValue<Suggestion> = (suggestion): string => suggestion.name;
6177

62-
const renderSuggestion = (suggestion, { query, isHighlighted }): JSX.Element => {
78+
const renderSuggestion: RenderSuggestion<Suggestion> = (suggestion, { query, isHighlighted }): JSX.Element => {
6379
const matches = match(suggestion.name, query);
6480
const parts = parse(suggestion.name, matches);
6581
return (
@@ -77,7 +93,7 @@ const renderSuggestion = (suggestion, { query, isHighlighted }): JSX.Element =>
7793
);
7894
};
7995

80-
const renderMessage = (message): JSX.Element => {
96+
const renderMessage = (message: string): JSX.Element => {
8197
return (
8298
<MenuItem component="div" selected={false}>
8399
<div>{message}</div>
@@ -104,15 +120,7 @@ const AutoComplete = memo(
104120
}: Props) => {
105121
const { t } = useTranslation();
106122

107-
const autosuggestProps = {
108-
renderInputComponent,
109-
suggestions,
110-
getSuggestionValue,
111-
renderSuggestion,
112-
onSuggestionsFetchRequested: onSuggestionsFetch,
113-
onSuggestionsClearRequested: onCleanSuggestions,
114-
};
115-
const inputProps: InputProps<unknown> = {
123+
const inputProps: InputProps<Suggestion> = {
116124
value,
117125
onChange,
118126
placeholder,
@@ -125,7 +133,11 @@ const AutoComplete = memo(
125133
};
126134

127135
// this format avoid arrow function eslint rule
128-
function renderSuggestionsContainer({ containerProps, children, query }): JSX.Element {
136+
const renderSuggestionsContainer: RenderSuggestionsContainer = function({
137+
containerProps,
138+
children,
139+
query,
140+
}): JSX.Element {
129141
return (
130142
<SuggestionContainer {...containerProps} square={true}>
131143
{suggestionsLoaded && children === null && query && renderMessage(t('autoComplete.no-results-found'))}
@@ -134,12 +146,17 @@ const AutoComplete = memo(
134146
{children}
135147
</SuggestionContainer>
136148
);
137-
}
149+
};
138150

139151
return (
140152
<Wrapper>
141-
<Autosuggest
142-
{...autosuggestProps}
153+
<Autosuggest<Suggestion>
154+
renderInputComponent={renderInputComponent}
155+
suggestions={suggestions}
156+
getSuggestionValue={getSuggestionValue}
157+
renderSuggestion={renderSuggestion}
158+
onSuggestionsFetchRequested={onSuggestionsFetch}
159+
onSuggestionsClearRequested={onCleanSuggestions}
143160
inputProps={inputProps}
144161
onSuggestionSelected={onClick}
145162
renderSuggestionsContainer={renderSuggestionsContainer}

src/components/AutoComplete/styles.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ export const StyledTextField = styled(TextField)<{ theme?: Theme }>(props => ({
3737

3838
/* eslint-disable verdaccio/jsx-spread */
3939
// @ts-ignore types of color are incompatible
40-
export const InputField: React.FC<InputFieldProps> = ({ ...others }) => <StyledTextField {...others} />;
40+
export const InputField: React.FC<InputFieldProps & TextFieldProps> = ({ ...others }) => (
41+
<StyledTextField {...others} />
42+
);
4143

4244
export const SuggestionContainer = styled(Paper)({
4345
maxHeight: '500px',

0 commit comments

Comments
 (0)