From ed9e0f6d14d9fb43ae5ff61dfeb213a37b510e91 Mon Sep 17 00:00:00 2001 From: Kevin Ross Date: Wed, 29 Nov 2017 09:28:28 -0600 Subject: [PATCH 1/4] Update react-autosuggest signatures, documentation, use generic type - Convert Autosuggest component to a generic - Update the renderSuggestionsContainer signature - Add readme with usage example - Document component props - Export function types for easier reuse/passing in as props --- types/react-autosuggest/README.md | 28 ++ types/react-autosuggest/index.d.ts | 245 +++++++++++++----- .../react-autosuggest-tests.tsx | 14 +- 3 files changed, 218 insertions(+), 69 deletions(-) create mode 100644 types/react-autosuggest/README.md diff --git a/types/react-autosuggest/README.md b/types/react-autosuggest/README.md new file mode 100644 index 0000000000..44ff83ecc5 --- /dev/null +++ b/types/react-autosuggest/README.md @@ -0,0 +1,28 @@ +# react-autosuggest usage notes + +The definition uses generics for stronger typing. Read the [TypeScript deep dive on JSX Generic components](https://basarat.gitbooks.io/typescript/docs/jsx/tsx.html#react-jsx-tip-generic-components) for details on consuming these type definitions. + +## Example + +```jsx +import * as Autosuggest from 'react-autosuggest' +interface Language { + name: string + year: number +} + +const LanguageAutosuggest = Autosuggest as { new (): Autosuggest } + + +``` + +Find multiple full examples in `react-autosuggest-tests.tsx` diff --git a/types/react-autosuggest/index.d.ts b/types/react-autosuggest/index.d.ts index b1f080efe5..4c4d6caaed 100644 --- a/types/react-autosuggest/index.d.ts +++ b/types/react-autosuggest/index.d.ts @@ -1,88 +1,205 @@ -// Type definitions for react-autosuggest 9.3 +// Type definitions for react-autosuggest 9.3.2 // Project: http://react-autosuggest.js.org/ // Definitions by: Nicolas Schmitt // Philip Ottesen // Robert Essig // Terry Bayne // Christopher Deutsch +// Kevin Ross // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.3 -import * as React from 'react'; +import * as React from 'react' -declare class Autosuggest extends React.Component {} +declare class Autosuggest extends React.Component> {} -export = Autosuggest; +export = Autosuggest declare namespace Autosuggest { - interface SuggestionsFetchRequest { - value: string; - reason: 'input-changed' | 'input-focused' | 'escape-pressed' | 'suggestions-revealed' | 'suggestion-selected'; - } + /** + * Utilies types based on: + * https://github.com/Microsoft/TypeScript/issues/12215#issuecomment-307871458 + */ - interface InputValues { - value: string; - valueBeforeUpDown?: string; - } + /** @internal */ + type Diff = ({ [P in T]: P } & + { [P in U]: never } & { [x: string]: never })[T] - interface RenderSuggestionParams { - query: string; - isHighlighted: boolean; - } + /** @internal */ + type Omit = Pick> - interface SuggestionHighlightedParams { - suggestion: any; - } + export interface SuggestionsFetchRequestedParams { + value: string + reason: + | 'input-changed' + | 'input-focused' + | 'escape-pressed' + | 'suggestions-revealed' + | 'suggestion-selected' + } - interface ChangeEvent { - newValue: string; - method: 'down' | 'up' | 'escape' | 'enter' | 'click' | 'type'; - } + export interface RenderSuggestionParams { + query: string + isHighlighted: boolean + } - interface BlurEvent { - highlightedSuggestion: any; - } + export interface SuggestionHighlightedParams { + suggestion: any + } - interface InputProps extends React.InputHTMLAttributes { - value: string; - onChange(event: React.FormEvent, params?: ChangeEvent): void; - onBlur?(event: React.FormEvent, params?: BlurEvent): void; - [key: string]: any; - } + export interface ChangeEvent { + newValue: string + method: 'down' | 'up' | 'escape' | 'enter' | 'click' | 'type' + } - interface SuggestionSelectedEventData { - suggestion: TSuggestion; - suggestionValue: string; - suggestionIndex: number; - sectionIndex: number | null; - method: 'click' | 'enter'; - } + export interface BlurEvent { + highlightedSuggestion: TSuggestion + } - type ThemeKey = 'container' | 'containerOpen' | 'input' | 'inputOpen' | 'inputFocused' | 'suggestionsContainer' | - 'suggestionsContainerOpen' | 'suggestionsList' | 'suggestion' | 'suggestionFirst' | 'suggestionHighlighted' | - 'sectionContainer' | 'sectionContainerFirst' | 'sectionTitle'; + export interface InputProps + extends Omit, 'onChange' | 'onBlur'> { + onChange(event: React.FormEvent, params?: ChangeEvent): void + onBlur?(event: React.FormEvent, params?: BlurEvent): void + value: string + [key: string]: any + } - type Theme = Record | Partial>; + export interface SuggestionSelectedEventData { + suggestion: TSuggestion + suggestionValue: string + suggestionIndex: number + sectionIndex: number | null + method: 'click' | 'enter' + } - interface AutosuggestProps extends React.Props { - suggestions: any[]; - onSuggestionsFetchRequested(request: SuggestionsFetchRequest): void; - onSuggestionsClearRequested?(): void; - getSuggestionValue(suggestion: any): any; - renderSuggestion(suggestion: any, params: RenderSuggestionParams): JSX.Element; - inputProps: InputProps; - onSuggestionSelected?(event: React.FormEvent, data: SuggestionSelectedEventData): void; - onSuggestionHighlighted?(params: SuggestionHighlightedParams): void; - shouldRenderSuggestions?(value: string): boolean; - alwaysRenderSuggestions?: boolean; - highlightFirstSuggestion?: boolean; - focusInputOnSuggestionClick?: boolean; - multiSection?: boolean; - renderSectionTitle?(section: any): JSX.Element; - getSectionSuggestions?(section: any): any[]; - renderInputComponent?(inputProps: InputProps): JSX.Element; - renderSuggestionsContainer?(containerProps: any, children: any, query: string): JSX.Element; - theme?: Theme; - id?: string; - } + export type ThemeKey = + | 'container' + | 'containerOpen' + | 'input' + | 'inputOpen' + | 'inputFocused' + | 'suggestionsContainer' + | 'suggestionsContainerOpen' + | 'suggestionsList' + | 'suggestion' + | 'suggestionFirst' + | 'suggestionHighlighted' + | 'sectionContainer' + | 'sectionContainerFirst' + | 'sectionTitle' + + export type Theme = + | Record + | Partial> + + export type RenderSuggestionsContainerParams = { + containerProps: { + id: string + key: string + ref: any + style: Object + } + children: React.ReactNode + query: string + } + + // export types for functions - allowing reuse externally - e.g. as props and bound in the constructor + export type GetSectionSuggestions = (section: any) => TSuggestion[] + export type GetSuggestionValue = (suggestion: TSuggestion) => string + export type OnSuggestionHighlighted = (params: SuggestionHighlightedParams) => void + export type SuggestionsFetchRequested = (request: SuggestionsFetchRequestedParams) => void + export type OnSuggestionsClearRequested = () => void + export type OnSuggestionSelected = ( + event: React.FormEvent, + data: SuggestionSelectedEventData, + ) => void + export type RenderInputComponent = ( + inputProps: InputProps, + ) => JSX.Element + export type RenderSuggestionsContainer = (params: RenderSuggestionsContainerParams) => JSX.Element + export type RenderSectionTitle = (section: any) => JSX.Element + export type RenderSuggestion = ( + suggestion: TSuggestion, + params: RenderSuggestionParams, + ) => JSX.Element + export type ShouldRenderSuggestions = (value: string) => boolean + + export interface AutosuggestProps { + /** + * Set it to true if you'd like to render suggestions even when the input is not focused. + */ + alwaysRenderSuggestions?: boolean + /** + * Set it to false if you don't want Autosuggest to keep the input focused when suggestions are clicked/tapped. + */ + focusInputOnSuggestionClick?: boolean + /** + * Implement it to teach Autosuggest where to find the suggestions for every section. + */ + getSectionSuggestions?: GetSectionSuggestions + /** + * Implement it to teach Autosuggest what should be the input value when suggestion is clicked. + */ + getSuggestionValue: GetSuggestionValue + /** + * Set it to true if you'd like Autosuggest to automatically highlight the first suggestion. + */ + highlightFirstSuggestion?: boolean + /** + * Use it only if you have multiple Autosuggest components on a page. + */ + id?: string + /** + * Pass through arbitrary props to the input. It must contain at least value and onChange. + */ + inputProps: InputProps + /** + * Set it to true if you'd like to display suggestions in multiple sections (with optional titles). + */ + multiSection?: boolean + /** + * Will be called every time the highlighted suggestion changes. + */ + onSuggestionHighlighted?: OnSuggestionHighlighted + /** + * Will be called every time you need to recalculate suggestions. + */ + onSuggestionsFetchRequested: SuggestionsFetchRequested + /** + * Will be called every time you need to set suggestions to []. + */ + onSuggestionsClearRequested?: OnSuggestionsClearRequested + /** + * Will be called every time suggestion is selected via mouse or keyboard. + */ + onSuggestionSelected?: OnSuggestionSelected + /** + * Use it only if you need to customize the rendering of the input. + */ + renderInputComponent?: RenderInputComponent + /** + * Use it if you want to customize things inside the suggestions container beyond rendering the suggestions themselves. + */ + renderSuggestionsContainer?: RenderSuggestionsContainer + /** + * Use your imagination to define how section titles are rendered. + */ + renderSectionTitle?: RenderSectionTitle + /** + * Use your imagination to define how suggestions are rendered. + */ + renderSuggestion: RenderSuggestion + /** + * When the input is focused, Autosuggest will consult this function when to render suggestions. Use it, for example, if you want to display suggestions when input value is at least 2 characters long. + */ + shouldRenderSuggestions?: ShouldRenderSuggestions + /** + * These are the suggestions that will be displayed. Items can take an arbitrary shape. + */ + suggestions: TSuggestion[] + /** + * Use your imagination to style the Autosuggest. + */ + theme?: Theme + } } diff --git a/types/react-autosuggest/react-autosuggest-tests.tsx b/types/react-autosuggest/react-autosuggest-tests.tsx index 23841519e4..a8a6268445 100644 --- a/types/react-autosuggest/react-autosuggest-tests.tsx +++ b/types/react-autosuggest/react-autosuggest-tests.tsx @@ -15,6 +15,8 @@ function escapeRegexCharacters(str: string): string { return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } +const LanguageAutosuggest = Autosuggest as { new (): Autosuggest } + export class ReactAutosuggestBasicTest extends React.Component { // region Fields static languages: Language[] = [ @@ -89,7 +91,7 @@ export class ReactAutosuggestBasicTest extends React.Component { sectionTitle: { color: 'blue' } }; - return { .bind(this) }; - return { return {section.title}; } - protected renderInputComponent(inputProps: Autosuggest.InputProps): JSX.Element { + protected renderInputComponent(inputProps: Autosuggest.InputProps): JSX.Element { return (
@@ -280,7 +282,7 @@ export class ReactAutosuggestMultipleTest extends React.Component { ); } - protected renderSuggestionsContainer(containerProps: any, children: any, query: string): JSX.Element { + protected renderSuggestionsContainer({containerProps, children, query}: Autosuggest.RenderSuggestionsContainerParams): JSX.Element { return (
{children} @@ -345,6 +347,8 @@ interface Person { twitter: string; } +const PersonAutosuggest = Autosuggest as { new (): Autosuggest } + export class ReactAutosuggestCustomTest extends React.Component { // region Fields static people: Person[] = [ @@ -386,7 +390,7 @@ export class ReactAutosuggestCustomTest extends React.Component { .bind(this) }; - return Date: Wed, 29 Nov 2017 09:38:47 -0600 Subject: [PATCH 2/4] lint --- types/react-autosuggest/index.d.ts | 155 +++++++++--------- .../react-autosuggest-tests.tsx | 4 +- 2 files changed, 79 insertions(+), 80 deletions(-) diff --git a/types/react-autosuggest/index.d.ts b/types/react-autosuggest/index.d.ts index 4c4d6caaed..78c11d6878 100644 --- a/types/react-autosuggest/index.d.ts +++ b/types/react-autosuggest/index.d.ts @@ -1,4 +1,4 @@ -// Type definitions for react-autosuggest 9.3.2 +// Type definitions for react-autosuggest 9.3 // Project: http://react-autosuggest.js.org/ // Definitions by: Nicolas Schmitt // Philip Ottesen @@ -9,11 +9,11 @@ // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.3 -import * as React from 'react' +import * as React from 'react'; declare class Autosuggest extends React.Component> {} -export = Autosuggest +export = Autosuggest; declare namespace Autosuggest { /** @@ -23,56 +23,56 @@ declare namespace Autosuggest { /** @internal */ type Diff = ({ [P in T]: P } & - { [P in U]: never } & { [x: string]: never })[T] + { [P in U]: never } & { [x: string]: never })[T]; /** @internal */ - type Omit = Pick> + type Omit = Pick>; - export interface SuggestionsFetchRequestedParams { - value: string + interface SuggestionsFetchRequestedParams { + value: string; reason: | 'input-changed' | 'input-focused' | 'escape-pressed' | 'suggestions-revealed' - | 'suggestion-selected' + | 'suggestion-selected'; } - export interface RenderSuggestionParams { - query: string - isHighlighted: boolean + interface RenderSuggestionParams { + query: string; + isHighlighted: boolean; } - export interface SuggestionHighlightedParams { - suggestion: any + interface SuggestionHighlightedParams { + suggestion: any; } - export interface ChangeEvent { - newValue: string - method: 'down' | 'up' | 'escape' | 'enter' | 'click' | 'type' + interface ChangeEvent { + newValue: string; + method: 'down' | 'up' | 'escape' | 'enter' | 'click' | 'type'; } - export interface BlurEvent { - highlightedSuggestion: TSuggestion + interface BlurEvent { + highlightedSuggestion: TSuggestion; } - export interface InputProps + interface InputProps extends Omit, 'onChange' | 'onBlur'> { - onChange(event: React.FormEvent, params?: ChangeEvent): void - onBlur?(event: React.FormEvent, params?: BlurEvent): void - value: string - [key: string]: any + onChange(event: React.FormEvent, params?: ChangeEvent): void; + onBlur?(event: React.FormEvent, params?: BlurEvent): void; + value: string; + [key: string]: any; } - export interface SuggestionSelectedEventData { - suggestion: TSuggestion - suggestionValue: string - suggestionIndex: number - sectionIndex: number | null - method: 'click' | 'enter' + interface SuggestionSelectedEventData { + suggestion: TSuggestion; + suggestionValue: string; + suggestionIndex: number; + sectionIndex: number | null; + method: 'click' | 'enter'; } - export type ThemeKey = + type ThemeKey = | 'container' | 'containerOpen' | 'input' @@ -86,120 +86,119 @@ declare namespace Autosuggest { | 'suggestionHighlighted' | 'sectionContainer' | 'sectionContainerFirst' - | 'sectionTitle' + | 'sectionTitle'; - export type Theme = + type Theme = | Record - | Partial> + | Partial>; - export type RenderSuggestionsContainerParams = { + interface RenderSuggestionsContainerParams { containerProps: { - id: string - key: string - ref: any - style: Object - } - children: React.ReactNode - query: string + id: string; + key: string; + ref: any; + style: any; + }; + children: React.ReactNode; + query: string; } - // export types for functions - allowing reuse externally - e.g. as props and bound in the constructor - export type GetSectionSuggestions = (section: any) => TSuggestion[] - export type GetSuggestionValue = (suggestion: TSuggestion) => string - export type OnSuggestionHighlighted = (params: SuggestionHighlightedParams) => void - export type SuggestionsFetchRequested = (request: SuggestionsFetchRequestedParams) => void - export type OnSuggestionsClearRequested = () => void - export type OnSuggestionSelected = ( + // types for functions - allowing reuse externally - e.g. as props and bound in the constructor + type GetSectionSuggestions = (section: any) => TSuggestion[]; + type GetSuggestionValue = (suggestion: TSuggestion) => string; + type OnSuggestionHighlighted = (params: SuggestionHighlightedParams) => void; + type SuggestionsFetchRequested = (request: SuggestionsFetchRequestedParams) => void; + type OnSuggestionsClearRequested = () => void; + type OnSuggestionSelected = ( event: React.FormEvent, data: SuggestionSelectedEventData, - ) => void - export type RenderInputComponent = ( - inputProps: InputProps, - ) => JSX.Element - export type RenderSuggestionsContainer = (params: RenderSuggestionsContainerParams) => JSX.Element - export type RenderSectionTitle = (section: any) => JSX.Element - export type RenderSuggestion = ( + ) => void; + type RenderInputComponent = (inputProps: InputProps) => JSX.Element; + type RenderSuggestionsContainer = (params: RenderSuggestionsContainerParams) => JSX.Element; + type RenderSectionTitle = (section: any) => JSX.Element; + type RenderSuggestion = ( suggestion: TSuggestion, params: RenderSuggestionParams, - ) => JSX.Element - export type ShouldRenderSuggestions = (value: string) => boolean + ) => JSX.Element; + type ShouldRenderSuggestions = (value: string) => boolean; - export interface AutosuggestProps { + interface AutosuggestProps { /** * Set it to true if you'd like to render suggestions even when the input is not focused. */ - alwaysRenderSuggestions?: boolean + alwaysRenderSuggestions?: boolean; /** * Set it to false if you don't want Autosuggest to keep the input focused when suggestions are clicked/tapped. */ - focusInputOnSuggestionClick?: boolean + focusInputOnSuggestionClick?: boolean; /** * Implement it to teach Autosuggest where to find the suggestions for every section. */ - getSectionSuggestions?: GetSectionSuggestions + getSectionSuggestions?: GetSectionSuggestions; /** * Implement it to teach Autosuggest what should be the input value when suggestion is clicked. */ - getSuggestionValue: GetSuggestionValue + getSuggestionValue: GetSuggestionValue; /** * Set it to true if you'd like Autosuggest to automatically highlight the first suggestion. */ - highlightFirstSuggestion?: boolean + highlightFirstSuggestion?: boolean; /** * Use it only if you have multiple Autosuggest components on a page. */ - id?: string + id?: string; /** * Pass through arbitrary props to the input. It must contain at least value and onChange. */ - inputProps: InputProps + inputProps: InputProps; /** * Set it to true if you'd like to display suggestions in multiple sections (with optional titles). */ - multiSection?: boolean + multiSection?: boolean; /** * Will be called every time the highlighted suggestion changes. */ - onSuggestionHighlighted?: OnSuggestionHighlighted + onSuggestionHighlighted?: OnSuggestionHighlighted; /** * Will be called every time you need to recalculate suggestions. */ - onSuggestionsFetchRequested: SuggestionsFetchRequested + onSuggestionsFetchRequested: SuggestionsFetchRequested; /** * Will be called every time you need to set suggestions to []. */ - onSuggestionsClearRequested?: OnSuggestionsClearRequested + onSuggestionsClearRequested?: OnSuggestionsClearRequested; /** * Will be called every time suggestion is selected via mouse or keyboard. */ - onSuggestionSelected?: OnSuggestionSelected + onSuggestionSelected?: OnSuggestionSelected; /** * Use it only if you need to customize the rendering of the input. */ - renderInputComponent?: RenderInputComponent + renderInputComponent?: RenderInputComponent; /** * Use it if you want to customize things inside the suggestions container beyond rendering the suggestions themselves. */ - renderSuggestionsContainer?: RenderSuggestionsContainer + renderSuggestionsContainer?: RenderSuggestionsContainer; /** * Use your imagination to define how section titles are rendered. */ - renderSectionTitle?: RenderSectionTitle + renderSectionTitle?: RenderSectionTitle; /** * Use your imagination to define how suggestions are rendered. */ - renderSuggestion: RenderSuggestion + renderSuggestion: RenderSuggestion; /** - * When the input is focused, Autosuggest will consult this function when to render suggestions. Use it, for example, if you want to display suggestions when input value is at least 2 characters long. + * When the input is focused, Autosuggest will consult this function when to render suggestions. + * Use it, for example, if you want to display suggestions when input value is at least 2 characters long. */ - shouldRenderSuggestions?: ShouldRenderSuggestions + shouldRenderSuggestions?: ShouldRenderSuggestions; /** * These are the suggestions that will be displayed. Items can take an arbitrary shape. */ - suggestions: TSuggestion[] + suggestions: TSuggestion[]; /** * Use your imagination to style the Autosuggest. */ - theme?: Theme + theme?: Theme; } } diff --git a/types/react-autosuggest/react-autosuggest-tests.tsx b/types/react-autosuggest/react-autosuggest-tests.tsx index a8a6268445..753af3a552 100644 --- a/types/react-autosuggest/react-autosuggest-tests.tsx +++ b/types/react-autosuggest/react-autosuggest-tests.tsx @@ -15,7 +15,7 @@ function escapeRegexCharacters(str: string): string { return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } -const LanguageAutosuggest = Autosuggest as { new (): Autosuggest } +const LanguageAutosuggest = Autosuggest as { new (): Autosuggest }; export class ReactAutosuggestBasicTest extends React.Component { // region Fields @@ -347,7 +347,7 @@ interface Person { twitter: string; } -const PersonAutosuggest = Autosuggest as { new (): Autosuggest } +const PersonAutosuggest = Autosuggest as { new (): Autosuggest }; export class ReactAutosuggestCustomTest extends React.Component { // region Fields From 2c3a4232beece64ed9947db3ab34d127fdcc7865 Mon Sep 17 00:00:00 2001 From: Kevin Ross Date: Fri, 1 Dec 2017 12:31:15 -0600 Subject: [PATCH 3/4] Add and additional basic test for backward compatibility --- types/react-autosuggest/index.d.ts | 2 +- .../react-autosuggest-tests.tsx | 126 +++++++++++++++++- 2 files changed, 126 insertions(+), 2 deletions(-) diff --git a/types/react-autosuggest/index.d.ts b/types/react-autosuggest/index.d.ts index 78c11d6878..c7f46200d1 100644 --- a/types/react-autosuggest/index.d.ts +++ b/types/react-autosuggest/index.d.ts @@ -11,7 +11,7 @@ import * as React from 'react'; -declare class Autosuggest extends React.Component> {} +declare class Autosuggest extends React.Component> {} export = Autosuggest; diff --git a/types/react-autosuggest/react-autosuggest-tests.tsx b/types/react-autosuggest/react-autosuggest-tests.tsx index 753af3a552..3747e8457b 100644 --- a/types/react-autosuggest/react-autosuggest-tests.tsx +++ b/types/react-autosuggest/react-autosuggest-tests.tsx @@ -15,9 +15,133 @@ function escapeRegexCharacters(str: string): string { return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } +export class ReactAutosuggestBasicTest extends React.Component { + // region Fields + static languages: Language[] = [ + { + name: 'C', + year: 1972 + }, { + name: 'C#', + year: 2000 + }, { + name: 'C++', + year: 1983 + }, { + name: 'Clojure', + year: 2007 + }, { + name: 'Elm', + year: 2012 + }, { + name: 'Go', + year: 2009 + }, { + name: 'Haskell', + year: 1990 + }, { + name: 'Java', + year: 1995 + }, { + name: 'Javascript', + year: 1995 + }, { + name: 'Perl', + year: 1987 + }, { + name: 'PHP', + year: 1995 + }, { + name: 'Python', + year: 1991 + }, { + name: 'Ruby', + year: 1995 + }, { + name: 'Scala', + year: 2003 + } + ]; + // endregion region Constructor + constructor(props: any) { + super(props); + + this.state = { + value: '', + suggestions: this.getSuggestions('') + }; + } + // endregion region Rendering methods + render(): JSX.Element { + const {value, suggestions} = this.state; + const inputProps = { + placeholder: `Type 'c'`, + value, + onChange: this + .onChange + .bind(this) + }; + + const theme = { + input: 'themed-input-class', + container: 'themed-container-class', + suggestionFocused: 'active', + sectionTitle: { color: 'blue' } + }; + + return ; + } + + protected onSuggestionsSelected(event: React.FormEvent, data: Autosuggest.SuggestionSelectedEventData): void { + alert(`Selected language is ${data.suggestion.name} (${data.suggestion.year}).`); + } + + protected renderSuggestion(suggestion: Language, params: Autosuggest.RenderSuggestionParams): JSX.Element { + const className = params.isHighlighted ? "highlighted" : undefined; + return {suggestion.name}; + } + // endregion region Event handlers + protected onChange(event: React.FormEvent, {newValue, method}: any): void { + this.setState({value: newValue}); + } + + protected onSuggestionsFetchRequested({value}: any): void { + this.setState({ + suggestions: this.getSuggestions(value) + }); + } + // endregion region Helper methods + protected getSuggestions(value: string): Language[] { + const escapedValue = escapeRegexCharacters(value.trim()); + + if (escapedValue === '') { + return []; + } + + const regex = new RegExp('^' + escapedValue, 'i'); + + return ReactAutosuggestBasicTest + .languages + .filter(language => regex.test(language.name)); + } + + protected getSuggestionValue(suggestion: Language): string { return suggestion.name; } + // endregion +} + const LanguageAutosuggest = Autosuggest as { new (): Autosuggest }; -export class ReactAutosuggestBasicTest extends React.Component { +export class ReactAutosuggestTypedTest extends React.Component { // region Fields static languages: Language[] = [ { From ec54184e1bf53c8d3344fe1e3c2ccbe1033b1bd5 Mon Sep 17 00:00:00 2001 From: Kevin Ross Date: Mon, 4 Dec 2017 10:39:31 -0600 Subject: [PATCH 4/4] JSX.Element -> React.ReactNode --- types/react-autosuggest/index.d.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/types/react-autosuggest/index.d.ts b/types/react-autosuggest/index.d.ts index c7f46200d1..444753bd54 100644 --- a/types/react-autosuggest/index.d.ts +++ b/types/react-autosuggest/index.d.ts @@ -113,13 +113,13 @@ declare namespace Autosuggest { event: React.FormEvent, data: SuggestionSelectedEventData, ) => void; - type RenderInputComponent = (inputProps: InputProps) => JSX.Element; - type RenderSuggestionsContainer = (params: RenderSuggestionsContainerParams) => JSX.Element; - type RenderSectionTitle = (section: any) => JSX.Element; + type RenderInputComponent = (inputProps: InputProps) => React.ReactNode; + type RenderSuggestionsContainer = (params: RenderSuggestionsContainerParams) => React.ReactNode; + type RenderSectionTitle = (section: any) => React.ReactNode; type RenderSuggestion = ( suggestion: TSuggestion, params: RenderSuggestionParams, - ) => JSX.Element; + ) => React.ReactNode; type ShouldRenderSuggestions = (value: string) => boolean; interface AutosuggestProps {