diff --git a/types/webscopeio__react-textarea-autocomplete/index.d.ts b/types/webscopeio__react-textarea-autocomplete/index.d.ts new file mode 100644 index 0000000000..10b582c366 --- /dev/null +++ b/types/webscopeio__react-textarea-autocomplete/index.d.ts @@ -0,0 +1,191 @@ +// Type definitions for webscopeio__react-textarea-autocomplete 2.3 +// Project: https://github.com/webscopeio/react-textarea-autocomplete +// Definitions by: Michal Zochowski +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.9 + +export default ReactTextareaAutocomplete; +export as namespace ReactTextareaAutocomplete; + +import * as React from "react"; + +export type CaretPositionType = 'start' | 'end' | 'next' | number; + +export interface TextToReplaceType { + text: string; + caretPosition: CaretPositionType; + key?: string; +} + +export type DataProviderType = (token: string) => + | Promise + | TItem[]; + +export interface ItemComponentProps { + selected: boolean; + entity: TItem; +} + +/** + * Textarea Types + */ +export interface SettingType { + /** + * The component for rendering the item in suggestion list. It has selected and entity props provided by React Textarea Autocomplete. + */ + component: React.SFC>; + /** + * Called after each keystroke to get data what the suggestion list should display (array or promise resolving array). + */ + dataProvider: DataProviderType; + /** + * Set this to true if you want to provide autocomplete for words (tokens) containing whitespace. + * @default false + */ + allowWhitespace?: boolean; + /** + * Show autocomplete only if it's preceded by whitespace. Cannot be combined with allowWhitespace. + * @default false + */ + afterWhitespace?: boolean; + /** + * (Optional for string based item. If the item is an object this method is required) This function defines text + * which will be placed into textarea after the user makes a selection. + * + * You can also specify the behavior of caret if you return object {text: "item", caretPosition: "start"} the caret + * will be before the word once the user confirms his selection. Other possible value are "next", "end" and number, + * which is absolute number in contex of textarea (0 is equal position before the first char). Defaults to "next" + * which is space after the injected word. + * + * The default behavior for string based item is a string: ). This method should always + * return a unique string, otherwise, you have to use object notation and specify your own key or return object + * from dataProvider with key property. + */ + output?: (item: TItem, trigger?: string) => TextToReplaceType | string; +} + +export interface TriggerType { + [key: string]: SettingType; +} + +type PickedAttributes = "onChange" | "onSelect" | "onBlur" | "value"; + +export interface TextareaProps extends Pick, PickedAttributes> { + /** + * Define triggers and their corresponding behavior. + */ + trigger: TriggerType; + /** + * Gets data props which is already fetched (and displayed) suggestion. + */ + loadingComponent: React.SFC; + /** + * Listener called every time the textarea's caret position is changed. The listener is called with one attribute - caret position denoted by an integer number. + */ + onCaretPositionChange?: (pos: number) => void; + /** + * Allows you to get React ref of the underlying textarea. + */ + innerRef?: (ref: HTMLTextAreaElement) => void; + /** + * With default implementation it will scroll the dropdown every time when the item gets out of the view. + * @default true + */ + scrollToItem?: boolean | ((container: HTMLDivElement, item: HTMLDivElement) => void); + /** + * When it's true autocomplete will close when use click outside. + * @default false + */ + closeOnClickOutside?: boolean; + /** + * When it's true the textarea will move along with a caret as a user continues to type. + * @default false + */ + movePopupAsYouType?: boolean; + /** + * Number of characters that user should type for trigger a suggestion. + * @default 1 + */ + minChar?: number; + /** + * Styles of textarea + */ + style?: React.CSSProperties; + /** + * Styles of list's wrapper. + */ + listStyle?: React.CSSProperties; + /** + * Styles of item's wrapper. + */ + itemStyle?: React.CSSProperties; + /** + * Styles of textarea's container. + */ + containerStyle?: React.CSSProperties; + /** + * Styles of loader's wrapper. + */ + loaderStyle?: React.CSSProperties; + /** + * Styles of dropdown's wrapper. + */ + dropdownStyle?: React.CSSProperties; + /** + * ClassNames of the textarea. + */ + className?: string; + /** + * ClassNames of the textarea's container. + */ + containerClassName?: string; + /** + * ClassNames of list's wrapper. + */ + listClassName?: string; + /** + * ClassNames of item's wrapper. + */ + itemClassName?: string; + /** + * ClassNames of loader's wrapper. + */ + loaderClassName?: string; + /** + * ClassNames of dropdown's wrapper. + */ + dropdownClassName?: string; +} + +export interface TextareaState { + currentTrigger?: string; + top?: number; + left?: number; + actualToken: string; + data?: TItem[]; + value: string; + dataLoading: boolean; + selectionEnd: number; + selectionStart: number; + component?: React.SFC>; +} + +declare class ReactTextareaAutocomplete extends React.Component, TextareaState> { + /** + * Gets the current caret position in the textarea. + */ + getCaretPosition(): number; + /** + * Sets the caret position to the integer value passed as the argument. + * @param position caret position to set. + */ + setCaretPosition(position: number): void; + /** + * Returns selectionStart and selectionEnd of the textarea. + */ + getSelectionPosition(): { selectionStart: number, selectionEnd: number }; + /** + * Returns currently selected word. + */ + getSelectedText(): string | undefined; +} diff --git a/types/webscopeio__react-textarea-autocomplete/tsconfig.json b/types/webscopeio__react-textarea-autocomplete/tsconfig.json new file mode 100644 index 0000000000..e6049c58c6 --- /dev/null +++ b/types/webscopeio__react-textarea-autocomplete/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6", + "dom" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "jsx": "react", + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true, + "paths": { + "@webscopeio/react-textarea-autocomplete": ["webscopeio__react-textarea-autocomplete"] + } + }, + "files": [ + "index.d.ts", + "webscopeio__react-textarea-autocomplete-tests.tsx" + ] +} \ No newline at end of file diff --git a/types/webscopeio__react-textarea-autocomplete/tslint.json b/types/webscopeio__react-textarea-autocomplete/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/webscopeio__react-textarea-autocomplete/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" } diff --git a/types/webscopeio__react-textarea-autocomplete/webscopeio__react-textarea-autocomplete-tests.tsx b/types/webscopeio__react-textarea-autocomplete/webscopeio__react-textarea-autocomplete-tests.tsx new file mode 100644 index 0000000000..ada7fee098 --- /dev/null +++ b/types/webscopeio__react-textarea-autocomplete/webscopeio__react-textarea-autocomplete-tests.tsx @@ -0,0 +1,72 @@ +import ReactTextareaAutocomplete from "webscopeio__react-textarea-autocomplete"; +import * as React from "react"; + +const Loading: React.SFC = () => { + return
Loading
; +}; + +interface ItemProps { + selected: boolean; + entity: string; +} + +const Item: React.SFC = (props: ItemProps) => { + return
props
; +}; + +class Autocomplete extends React.Component { + private rta: ReactTextareaAutocomplete | null; + private textarea: HTMLTextAreaElement; + + private readonly names = [ "abc", "def", "ghi" ]; + + render() { + return + className="my-textarea" + loadingComponent={Loading} + style={{ + fontSize: "18px", + lineHeight: "20px", + padding: 5 + }} + ref={(rta) => { this.rta = rta; }} + innerRef={(textarea) => { this.textarea = textarea; }} + containerStyle={{ + marginTop: 20, + width: 400, + height: 100, + margin: "20px auto" + }} + minChar={0} + trigger={{ + ":": { + dataProvider: token => { + return this.names + .filter((name) => name.startsWith(token)); + }, + component: Item, + output: (item, token) => item, + allowWhitespace: true, + afterWhitespace: false + } + }} + value="aaa" + closeOnClickOutside={false} + movePopupAsYouType={false} + onBlur={(evt: React.FocusEvent) => { console.log(evt); }} + onSelect={(evt: React.SyntheticEvent) => { console.log(evt); }} + onChange={(evt: React.ChangeEvent) => { console.log(evt); }} + scrollToItem={false} + onCaretPositionChange={(pos: number) => { console.log(pos); }} + containerClassName="container" + dropdownClassName="dropdown" + itemClassName="item" + listClassName="list" + loaderClassName="loader" + dropdownStyle={{ width: "100%", margin: "14px"}} + itemStyle={{ width: "100%", margin: "14px"}} + listStyle={{ width: "100%", margin: "14px"}} + loaderStyle={{ width: "100%", margin: "14px"}} + />; + } +}