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;