import React from "react"; import ReactTextareaAutocomplete from "@webscopeio/react-textarea-autocomplete"; import emoji from "@jukben/emoji-search"; // import '@webscopeio/react-textarea-autocomplete/style.css' import "../style.css"; type ItemProps = { entity: { char: string, name: string } }; const Item = ({ entity: { name, char } }: ItemProps) => (
{`${name}: ${char}`}
); type LoadingProps = { data: Array<{ name: string, char: string }> }; const Loading = ({ data }: LoadingProps) =>
Loading
; class App extends React.Component { state = { optionsCaretStart: false, caretPosition: 0, movePopupAsYouType: false, text: "", minChar: 0, optionsCaret: "start", actualTokenInProvider: "", showSecondTextarea: false, renderToBody: false }; _handleOptionsCaretEnd = () => { this.setState(() => ({ optionsCaret: "end" })); }; _handleOptionsCaretNext = () => { this.setState(() => ({ optionsCaret: "next" })); }; _handleOptionsCaretStart = () => { this.setState(() => ({ optionsCaret: "start" })); }; _handleShowSecondTextarea = () => { this.setState(({ showSecondTextarea }) => ({ showSecondTextarea: !showSecondTextarea })); }; _handleMovePopupAsYouType = () => { this.setState(({ movePopupAsYouType }) => ({ movePopupAsYouType: !movePopupAsYouType })); }; _handleRenderToBody = () => { this.setState(({ renderToBody }) => ({ renderToBody: !renderToBody })); }; _onChangeHandle = ({ target: { value } }) => { this.setState({ text: value }); }; _changeValueTo = () => { this.setState({ text: ":troph" }); }; _onCaretPositionChangeHandle = (position: number) => { this.setState({ caretPosition: position }); }; _handleMinChar = ({ target: { value } }) => { this.setState({ minChar: +value }); }; _setCaretPosition = () => { this.rtaRef.setCaretPosition(1); }; _getCaretPosition = () => { alert(this.rtaRef.getCaretPosition()); }; _outputCaretEnd = (item, trigger) => ({ text: item.char, caretPosition: "end" }); _outputCaretStart = item => ({ text: item.char, caretPosition: "start" }); _outputCaretNext = item => ({ text: item.char, caretPosition: "next" }); _getSelectionPosition = () => { alert(JSON.stringify(this.rtaRef.getSelectionPosition())); }; _getSelectedText = () => { alert(this.rtaRef.getSelectedText()); }; /** * it's the same as _outputCaretNext */ _outputCaretDefault = item => item.char; _focus = () => { this.textareaRef.focus(); }; render() { const { optionsCaret, caretPosition, movePopupAsYouType, actualTokenInProvider, showSecondTextarea, text, minChar, renderToBody } = this.state; return (
Actual caret position:{" "} {caretPosition}
Actual token in "[" provider:{" "} {actualTokenInProvider}
{ console.log(`pressed "${e.key}"`); }} ref={ref => { this.rtaRef = ref; }} innerRef={ref => { this.textareaRef = ref; }} loadingComponent={Loading} style={{ padding: 5 }} containerStyle={{ marginTop: 20, width: 500, height: 100, margin: "20px auto" }} movePopupAsYouType={movePopupAsYouType} onCaretPositionChange={this._onCaretPositionChangeHandle} onItemHighlighted={info => { // save highlighted item to window; use it later in E2E tests window.__lastHighlightedItem = info; }} onItemSelected={info => { // save selected item to window; use it later in E2E tests window.__lastSelectedItem = info; }} minChar={minChar} value={text} onChange={this._onChangeHandle} renderToBody={renderToBody} trigger={{ ":": { dataProvider: token => emoji(token) .slice(0, 10) .filter(({ char }) => char) .map(({ name, char }) => ({ name, char })), component: Item, output: { start: this._outputCaretStart, end: this._outputCaretEnd, next: this._outputCaretNext }[optionsCaret] }, "::": { dataProvider: token => [{ name: "test", char: "test2" }], component: Item, output: { start: this._outputCaretStart, end: this._outputCaretEnd, next: this._outputCaretNext }[optionsCaret] }, "@": { dataProvider: token => new Promise(res => setTimeout(() => { res([{ name: "jakub", char: "Jakub" }]); }, 1000) ), component: Item, output: { start: this._outputCaretStart, end: this._outputCaretEnd, next: this._outputCaretDefault }[optionsCaret] }, // test of special character "[": { dataProvider: token => { /** Let's pass token to state to easily test it in Cypress We going to test that we get also whitespace because this trigger has set "allowWhitespace" */ this.setState({ actualTokenInProvider: token }); return [ { name: "alt", char: "@" }, { name: "another character", char: "/" } ]; }, component: Item, allowWhitespace: true, output: { start: this._outputCaretStart, end: this._outputCaretEnd, next: this._outputCaretNext }[optionsCaret] }, ";": { dataProvider: token => [ { name: "1", char: "one" }, { name: "2", char: "two" } ], component: Item, afterWhitespace: true, output: { start: this._outputCaretStart, end: this._outputCaretEnd, next: this._outputCaretNext }[optionsCaret] }, "/": { dataProvider: token => [{ name: "1", char: "/kick" }], component: Item, output: this._outputCaretEnd }, "/kick": { dataProvider: token => [ { name: "1", char: "fred" }, { name: "2", char: "jeremy" } ], component: Item, output: this._outputCaretEnd }, "/filter": { dataProvider: token => [ { name: "a", char: "amy" }, { name: "b", char: "ben" }, { name: "c", char: "cheryl" }, { name: "d", char: "daniel" }, { name: "e", char: "emily" } ].filter(x => x.name == token.slice(6) || token.length === 6), component: Item, output: this._outputCaretEnd }, "(": { dataProvider: token => [ { name: "country", char: "country" }, { name: "person", char: "person" }, { name: "trigger", char: "trigger", // has to be defined because we are not gonna return nothing key: "trigger", // custom type: "trigger" } ], component: Item, output: (item, trigger) => { if (item.type === "trigger") return null; return { text: `${trigger}${item.name}`, caretPosition: "end" }; } }, ".": { dataProvider: token => [ { name: "ID", char: "ID" }, { name: "name", char: "name" }, { name: "someProperty", char: "someProperty" } ], component: Item, output: (item, trigger) => ({ text: `${trigger}${item.name}`, caretPosition: "end" }) }, "-": { dataProvider: token => { return [ { name: "f", char: "-first" }, { name: "s", char: "-second" } ]; }, component: Item, output: this._outputCaretEnd }, }} /> {!showSecondTextarea ? null : ( emoji(token) .slice(0, 10) .filter(({ char }) => char) .map(({ name, char }) => ({ name, char })), component: Item, output: { start: this._outputCaretStart, end: this._outputCaretEnd, next: this._outputCaretNext }[optionsCaret] } }} /> )}
); } } export default App;