diff --git a/types/react-mentions/index.d.ts b/types/react-mentions/index.d.ts new file mode 100644 index 0000000000..ff10bbc013 --- /dev/null +++ b/types/react-mentions/index.d.ts @@ -0,0 +1,112 @@ +// Type definitions for react-mentions 2.3 +// Project: https://github.com/signavio/react-mentions +// Definitions by: Scott Willeke +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.8 +import * as React from "react"; + +/** + * MentionsInput is the main component rendering the textarea control. It takes one or multiple Mention components as its children. + */ +export const MentionsInput: MentionsInputClass; + +/** + * Each Mention component represents a data source for a specific class of mentionable objects, such as users, template variables, issues, etc. + */ +export const Mention: React.SFC; + +/** + * The properties for the @see MentionsInput component. + */ +export interface MentionsInputProps { + /** + * If set to `true` a regular text input element will be rendered + * instead of a textarea + */ + singleLine?: boolean; + /** + * If set to `true` spaces will not interrupt matching suggestions + */ + allowSpaceInQuery?: boolean; + markup?: string; + value?: string; + displayTransform?: DisplayTransformFunc; + onChange?: OnChangeHandlerFunc; + placeholder?: string; + onBlur?: (event: React.FocusEvent | React.FocusEvent, clickedSuggestion: boolean) => void; + onSelect?: (event: React.UIEvent) => void; + onKeyDown?: (event: React.KeyboardEvent | React.KeyboardEvent) => void; + children: React.ReactElement | Array>; + className?: string; + style?: any; + regex?: RegExp; + suggestionsPortalHost?: Element; +} + +/** + * Exposes the type for use with the @see MentionsInputComponent.wrappedInstance which is added by react-mentions' use of substyle (https://github.com/jfschwarz/substyle). + */ +export interface MentionsInputComponentUnrwapped extends React.Component { + inputRef?: HTMLInputElement | HTMLTextAreaElement; +} + +/** + * Used with @see React.RefObject. + */ +export interface MentionsInputComponent extends React.Component { + // MentionsInput uses substyle (https://github.com/jfschwarz/substyle) which adds this wrappedInstance + wrappedInstance?: MentionsInputComponentUnrwapped; +} + +/** + * Used to reference MentionsInput element in a TSX file. + */ +export interface MentionsInputClass extends React.ComponentClass { +} + +/** + * Props definition for a mention subelement. + */ +export interface MentionProps { + type?: string; + onAdd?: (id: string | number, display: string) => void; + renderSuggestion?: (suggestion: SuggestionDataItem, search: string, highlightedDisplay: React.ReactNode, index: number, focused: boolean) => React.ReactNode; + className?: string; + trigger: string | RegExp; + isLoading?: boolean; + data: SuggestionDataItem[] | DataFunc; + style?: any; + appendSpaceOnAdd?: boolean; +} + +/** + * The shape of a mention. + */ +export interface MentionItem { + display: string; + id: string; + type: null; +} + +/** + * The shape of suggestion items. + */ +export interface SuggestionDataItem { + id: string | number; + display: string; +} + +/** + * Defines the function signature for implementing @see MentionsInputProps.displayTransform + */ +export type DisplayTransformFunc = (id: string, display: string, type: string) => string; + +/** + * Defines the function signature for implementing @see MentionsInputProps.onChange + */ +export type OnChangeHandlerFunc = (event: { target: { value: string } }, newValue: string, newPlainTextValue: string, mentions: MentionItem[]) => void; + +/** + * The function to implement asynchronous loading of suggestions in @see MentionProps.data . + */ +export type DataFunc = (query: string, callback: (data: SuggestionDataItem[]) => void) => void | SuggestionDataItem[]; diff --git a/types/react-mentions/lib/utils.d.ts b/types/react-mentions/lib/utils.d.ts new file mode 100644 index 0000000000..ab0d1e7aed --- /dev/null +++ b/types/react-mentions/lib/utils.d.ts @@ -0,0 +1,17 @@ +import { DisplayTransformFunc } from "../"; + +/** + * For the passed character index in the plain text string, returns the corresponding index in the marked up value string. + * If the passed character index lies inside a mention, the value of `inMarkupCorrection` defines the correction to apply: + * - 'START' to return the index of the mention markup's first char (default) + * - 'END' to return the index after its last char + * - 'NULL' to return null + */ +export function mapPlainTextIndex( + value: string, + markup: string, + indexInPlainText: number, + inMarkupCorrection: string, + displayTransform: DisplayTransformFunc, + regex: RegExp +): number; diff --git a/types/react-mentions/react-mentions-tests.tsx b/types/react-mentions/react-mentions-tests.tsx new file mode 100644 index 0000000000..49f5180720 --- /dev/null +++ b/types/react-mentions/react-mentions-tests.tsx @@ -0,0 +1,60 @@ +import * as React from "react"; +import { MentionsInput, Mention, SuggestionDataItem } from "react-mentions"; +import { mapPlainTextIndex } from "react-mentions/lib/utils"; + +interface TestProps { + data: SuggestionDataItem[]; + value?: string; + onChange?: () => void; + onAdd?: () => void; + regex: RegExp; +} + +export const TestSimple: React.SFC = (props) => { + return ( + `@${login}`} + > + + + ); +}; + +export const TestMultipleTrigger: React.SFC = (props) => { + return ( + + ( +
+ {highlightedDisplay} +
+ )} + onAdd={props.onAdd} + /> + + [{ id: search, display: search }]} + onAdd={props.onAdd} + /> +
+ ); +}; + +mapPlainTextIndex("foo", "bar", 1, "NULL", login => `@${login}`, /.*/); // $ExpectType number diff --git a/types/react-mentions/tsconfig.json b/types/react-mentions/tsconfig.json new file mode 100644 index 0000000000..260c003e2d --- /dev/null +++ b/types/react-mentions/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true, + "jsx": "react" + }, + "files": [ + "index.d.ts", + "lib/utils.d.ts", + "react-mentions-tests.tsx" + ] +} diff --git a/types/react-mentions/tslint.json b/types/react-mentions/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/react-mentions/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" }