Skip to content
This repository was archived by the owner on Jan 16, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 38 additions & 21 deletions src/components/AutoComplete/AutoComplete.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,16 @@ import styled from '@emotion/styled';
import match from 'autosuggest-highlight/match';
import parse from 'autosuggest-highlight/parse';
import React, { KeyboardEvent, memo } from 'react';
import Autosuggest, { SuggestionSelectedEventData, InputProps, ChangeEvent } from 'react-autosuggest';
import Autosuggest, {
SuggestionSelectedEventData,
InputProps,
ChangeEvent,
SuggestionsFetchRequested,
GetSuggestionValue,
RenderSuggestion,
RenderSuggestionsContainer,
RenderInputComponent,
} from 'react-autosuggest';
import { useTranslation } from 'react-i18next';

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

interface Props {
suggestions: unknown[];
suggestions: Suggestion[];
suggestionsLoading?: boolean;
suggestionsLoaded?: boolean;
suggestionsError?: boolean;
Expand All @@ -30,22 +39,29 @@ interface Props {
startAdornment?: JSX.Element;
disableUnderline?: boolean;
onChange: (event: React.FormEvent<HTMLInputElement>, params: ChangeEvent) => void;
onSuggestionsFetch: ({ value: string }) => Promise<void>;
onSuggestionsFetch: SuggestionsFetchRequested;
onCleanSuggestions?: () => void;
onClick?: (event: React.FormEvent<HTMLInputElement>, data: SuggestionSelectedEventData<unknown>) => void;
onKeyDown?: (event: KeyboardEvent<HTMLInputElement>) => void;
onBlur?: (event: React.FormEvent<HTMLInputElement>) => void;
}

interface Suggestion {
name: string;
}

type CustomInputProps = Pick<Props, 'disableUnderline' | 'startAdornment'>;

/* eslint-disable react/jsx-sort-props */
/* eslint-disable verdaccio/jsx-spread */
const renderInputComponent = (inputProps): JSX.Element => {
const renderInputComponent: RenderInputComponent<Suggestion> = inputProps => {
// @ts-ignore
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the new ts-ignore, since there is currently no way to type startAdornment & disableUnderline

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, we can find a solution later for this

const { ref, startAdornment, disableUnderline, onKeyDown, ...others } = inputProps;
return (
<InputField
fullWidth={true}
InputProps={{
inputRef: node => {
inputRef: (node: any) => {
ref(node);
},
startAdornment,
Expand All @@ -57,9 +73,9 @@ const renderInputComponent = (inputProps): JSX.Element => {
);
};

const getSuggestionValue = (suggestion): string => suggestion.name;
const getSuggestionValue: GetSuggestionValue<Suggestion> = (suggestion): string => suggestion.name;

const renderSuggestion = (suggestion, { query, isHighlighted }): JSX.Element => {
const renderSuggestion: RenderSuggestion<Suggestion> = (suggestion, { query, isHighlighted }): JSX.Element => {
const matches = match(suggestion.name, query);
const parts = parse(suggestion.name, matches);
return (
Expand All @@ -77,7 +93,7 @@ const renderSuggestion = (suggestion, { query, isHighlighted }): JSX.Element =>
);
};

const renderMessage = (message): JSX.Element => {
const renderMessage = (message: string): JSX.Element => {
return (
<MenuItem component="div" selected={false}>
<div>{message}</div>
Expand All @@ -104,15 +120,7 @@ const AutoComplete = memo(
}: Props) => {
const { t } = useTranslation();

const autosuggestProps = {
renderInputComponent,
suggestions,
getSuggestionValue,
renderSuggestion,
onSuggestionsFetchRequested: onSuggestionsFetch,
onSuggestionsClearRequested: onCleanSuggestions,
};
const inputProps: InputProps<unknown> = {
const inputProps: InputProps<Suggestion> = {
value,
onChange,
placeholder,
Expand All @@ -125,7 +133,11 @@ const AutoComplete = memo(
};

// this format avoid arrow function eslint rule
function renderSuggestionsContainer({ containerProps, children, query }): JSX.Element {
const renderSuggestionsContainer: RenderSuggestionsContainer = function({
containerProps,
children,
query,
}): JSX.Element {
return (
<SuggestionContainer {...containerProps} square={true}>
{suggestionsLoaded && children === null && query && renderMessage(t('autoComplete.no-results-found'))}
Expand All @@ -134,12 +146,17 @@ const AutoComplete = memo(
{children}
</SuggestionContainer>
);
}
};

return (
<Wrapper>
<Autosuggest
{...autosuggestProps}
<Autosuggest<Suggestion>
renderInputComponent={renderInputComponent}
suggestions={suggestions}
getSuggestionValue={getSuggestionValue}
renderSuggestion={renderSuggestion}
onSuggestionsFetchRequested={onSuggestionsFetch}
onSuggestionsClearRequested={onCleanSuggestions}
inputProps={inputProps}
onSuggestionSelected={onClick}
renderSuggestionsContainer={renderSuggestionsContainer}
Expand Down
4 changes: 3 additions & 1 deletion src/components/AutoComplete/styles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ export const StyledTextField = styled(TextField)<{ theme?: Theme }>(props => ({

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

export const SuggestionContainer = styled(Paper)({
maxHeight: '500px',
Expand Down