Skip to content

Commit 2cd2a96

Browse files
authored
Allows output null (#134)
Close #132 This PR allows returning `null` from output functor in order to skip replace phase of the autocomplete. I think this solution is good enough for the use case. Could you please take a look on this @saumitra171?
1 parent cf8f984 commit 2cd2a96

File tree

6 files changed

+61
-19
lines changed

6 files changed

+61
-19
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ export default App;
135135
text: string,
136136
caretPosition: "start" | "end" | "next" | number
137137
|}
138-
| string,
138+
| string | null,
139139
dataProvider: (
140140
token: string
141141
) => Promise<Array<Object | string>> | Array<Object | string>,
@@ -156,6 +156,8 @@ export default App;
156156

157157
The default behavior for string based item is a string: `<TRIGGER><ITEM><TRIGGER>`). 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.
158158

159+
In order to skip the text replace phase let's return `null`.
160+
159161
## [Example of usage](http://react-textarea-autocomplete.surge.sh/)
160162

161163
`create-react-app example && cd example && yarn add @jukben/emoji-search @webscopeio/react-textarea-autocomplete`
@@ -268,6 +270,7 @@ Also, I'd love to thank these wonderful people for their contribution ([emoji ke
268270
| :---: | :---: | :---: | :---: | :---: | :---: | :---: |
269271
| [<img src="https://avatars0.githubusercontent.com/u/35139777?v=4" width="100px;"/><br /><sub><b>Deepak Pai</b></sub>](https://github.com/debugpai2)<br />[🐛](https://github.com/webscopeio/react-textarea-autocomplete/issues?q=author%3Adebugpai2 "Bug reports") [💻](https://github.com/webscopeio/react-textarea-autocomplete/commits?author=debugpai2 "Code") | [<img src="https://avatars0.githubusercontent.com/u/2336595?v=4" width="100px;"/><br /><sub><b>Aleck Landgraf</b></sub>](http://aleck.me)<br />[💻](https://github.com/webscopeio/react-textarea-autocomplete/commits?author=alecklandgraf "Code") | [<img src="https://avatars3.githubusercontent.com/u/8123356?v=4" width="100px;"/><br /><sub><b>Serguei Okladnikov</b></sub>](https://github.com/oklas)<br />[🐛](https://github.com/webscopeio/react-textarea-autocomplete/issues?q=author%3Aoklas "Bug reports") [💻](https://github.com/webscopeio/react-textarea-autocomplete/commits?author=oklas "Code") | [<img src="https://avatars1.githubusercontent.com/u/2987177?v=4" width="100px;"/><br /><sub><b>Michal Zochowski</b></sub>](https://github.com/michauzo)<br />[🐛](https://github.com/webscopeio/react-textarea-autocomplete/issues?q=author%3Amichauzo "Bug reports") [💻](https://github.com/webscopeio/react-textarea-autocomplete/commits?author=michauzo "Code") | [<img src="https://avatars2.githubusercontent.com/u/1263650?v=4" width="100px;"/><br /><sub><b>Igor Sachivka</b></sub>](https://github.com/isachivka)<br />[🐛](https://github.com/webscopeio/react-textarea-autocomplete/issues?q=author%3Aisachivka "Bug reports") [💻](https://github.com/webscopeio/react-textarea-autocomplete/commits?author=isachivka "Code") | [<img src="https://avatars3.githubusercontent.com/u/13059204?v=4" width="100px;"/><br /><sub><b>Andrew Shini</b></sub>](https://github.com/superandrew213)<br />[🐛](https://github.com/webscopeio/react-textarea-autocomplete/issues?q=author%3Asuperandrew213 "Bug reports") [💻](https://github.com/webscopeio/react-textarea-autocomplete/commits?author=superandrew213 "Code") | [<img src="https://avatars3.githubusercontent.com/u/3250906?v=4" width="100px;"/><br /><sub><b>Rikesh Ramlochund</b></sub>](https://paperboat.io)<br />[🐛](https://github.com/webscopeio/react-textarea-autocomplete/issues?q=author%3Arrikesh "Bug reports") [💻](https://github.com/webscopeio/react-textarea-autocomplete/commits?author=rrikesh "Code") |
270272
| [<img src="https://avatars1.githubusercontent.com/u/983876?v=4" width="100px;"/><br /><sub><b>Matthew Hamilton</b></sub>](https://github.com/diogeneshamilton)<br />[🐛](https://github.com/webscopeio/react-textarea-autocomplete/issues?q=author%3Adiogeneshamilton "Bug reports") | [<img src="https://avatars3.githubusercontent.com/u/12836237?v=4" width="100px;"/><br /><sub><b>Danila</b></sub>](https://github.com/O4epegb)<br />[🐛](https://github.com/webscopeio/react-textarea-autocomplete/issues?q=author%3AO4epegb "Bug reports") [💻](https://github.com/webscopeio/react-textarea-autocomplete/commits?author=O4epegb "Code") | [<img src="https://avatars3.githubusercontent.com/u/600021?v=4" width="100px;"/><br /><sub><b>Silvio Di Stefano</b></sub>](http://sites.google.com/site/sdistefano/)<br />[💻](https://github.com/webscopeio/react-textarea-autocomplete/commits?author=sdistefano "Code") | [<img src="https://avatars2.githubusercontent.com/u/1162278?v=4" width="100px;"/><br /><sub><b>Jelte Fennema</b></sub>](https://github.com/JelteF)<br />[🐛](https://github.com/webscopeio/react-textarea-autocomplete/issues?q=author%3AJelteF "Bug reports") [💻](https://github.com/webscopeio/react-textarea-autocomplete/commits?author=JelteF "Code") | [<img src="https://avatars0.githubusercontent.com/u/857?v=4" width="100px;"/><br /><sub><b>Andy Pearson</b></sub>](http://andypearson.co)<br />[🐛](https://github.com/webscopeio/react-textarea-autocomplete/issues?q=author%3Aandypearson "Bug reports") [💻](https://github.com/webscopeio/react-textarea-autocomplete/commits?author=andypearson "Code") | [<img src="https://avatars0.githubusercontent.com/u/1889215?v=4" width="100px;"/><br /><sub><b>Martin Kinkelin</b></sub>](https://github.com/kinke)<br />[🐛](https://github.com/webscopeio/react-textarea-autocomplete/issues?q=author%3Akinke "Bug reports") [💻](https://github.com/webscopeio/react-textarea-autocomplete/commits?author=kinke "Code") |
273+
271274
<!-- ALL-CONTRIBUTORS-LIST:END -->
272275

273276
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!

cypress/integration/textarea.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,5 +308,14 @@ describe("React Textarea Autocomplete", () => {
308308
});
309309
});
310310
});
311+
312+
it("should be possible return null and do nothing", () => {
313+
cy.get(".rta__textarea").type("This is test (");
314+
cy.get(".rta__autocomplete").should("be.visible");
315+
cy.get(".rta__list")
316+
.get("li:nth-child(3)")
317+
.click();
318+
cy.get(".rta__textarea").should("have.value", "This is test (");
319+
});
311320
});
312321
});

example/App.jsx

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -314,13 +314,24 @@ class App extends React.Component {
314314
"(": {
315315
dataProvider: token => [
316316
{ name: "country", char: "country" },
317-
{ name: "person", char: "person" }
317+
{ name: "person", char: "person" },
318+
{
319+
name: "trigger",
320+
char: "trigger",
321+
// has to be defined because we are not gonna return nothing
322+
key: "trigger",
323+
// custom
324+
type: "trigger"
325+
}
318326
],
319327
component: Item,
320-
output: (item, trigger) => ({
321-
text: `${trigger}${item.name}`,
322-
caretPosition: "end"
323-
})
328+
output: (item, trigger) => {
329+
if (item.type === "trigger") return null;
330+
return {
331+
text: `${trigger}${item.name}`,
332+
caretPosition: "end"
333+
};
334+
}
324335
},
325336
".": {
326337
dataProvider: token => [

src/List.jsx

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import React from "react";
44

55
import Listeners, { KEY_CODES } from "./listener";
66
import Item from "./Item";
7-
import type { ListProps, ListState, textToReplaceType } from "./types";
7+
import type { ListProps, ListState } from "./types";
88

99
export default class List extends React.Component<ListProps, ListState> {
1010
state: ListState = {
@@ -59,16 +59,26 @@ export default class List extends React.Component<ListProps, ListState> {
5959
return values.findIndex(a => this.getId(a) === this.getId(selectedItem));
6060
};
6161

62-
getId = (item: textToReplaceType | string): string => {
62+
getId = (item: Object | string): string => {
6363
const textToReplace = this.props.getTextToReplace(item);
64-
if (textToReplace.key) {
65-
return textToReplace.key;
64+
65+
if (textToReplace) {
66+
if (textToReplace.key) {
67+
return textToReplace.key;
68+
}
69+
70+
if (typeof item === "string" || !item.key) {
71+
return textToReplace.text;
72+
}
6673
}
6774

68-
if (typeof item === "string" || !item.key) {
69-
return textToReplace.text;
75+
if (!item.key) {
76+
throw new Error(
77+
`Item ${JSON.stringify(item)} has to have defined "key" property`
78+
);
7079
}
7180

81+
// $FlowFixMe
7282
return item.key;
7383
};
7484

src/Textarea.jsx

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,11 @@ class ReactTextareaAutocomplete extends React.Component<
340340
const { selectionEnd, currentTrigger, value: textareaValue } = this.state;
341341
const { trigger } = this.props;
342342

343+
if (!newToken) {
344+
this._closeAutocomplete();
345+
return;
346+
}
347+
343348
if (!currentTrigger) return;
344349

345350
const computeCaretPosition = (
@@ -448,14 +453,16 @@ class ReactTextareaAutocomplete extends React.Component<
448453
if (output) {
449454
const textToReplace = output(item, currentTrigger);
450455

451-
if (!textToReplace || typeof textToReplace === "number") {
456+
if (textToReplace === undefined || typeof textToReplace === "number") {
452457
throw new Error(
453458
`Output functor should return string or object in shape {text: string, caretPosition: string | number}.\nGot "${String(
454459
textToReplace
455460
)}". Check the implementation for trigger "${currentTrigger}" and its token "${actualToken}"\n\nSee https://github.com/webscopeio/react-textarea-autocomplete#trigger-type for more informations.\n`
456461
);
457462
}
458463

464+
if (textToReplace === null) return null;
465+
459466
if (typeof textToReplace === "string") {
460467
return {
461468
text: textToReplace,
@@ -791,14 +798,16 @@ class ReactTextareaAutocomplete extends React.Component<
791798

792799
this.escListenerInit();
793800

801+
const textToReplace = this._getTextToReplace({
802+
actualToken,
803+
currentTrigger
804+
});
805+
794806
this.setState(
795807
{
796808
selectionEnd,
797809
currentTrigger,
798-
textToReplace: this._getTextToReplace({
799-
actualToken,
800-
currentTrigger
801-
}),
810+
textToReplace,
802811
actualToken
803812
},
804813
() => {

src/types.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
export type caretPositionType = "start" | "end" | "next" | number;
44

5-
export type textToReplaceType = {|
5+
export type textToReplaceType = ?{|
66
text: string,
77
caretPosition: caretPositionType,
88
key?: ?string
99
|};
1010

11-
export type outputType = (Object | string, ?string) => textToReplaceType;
11+
export type outputType = (Object | string, ?string) => ?textToReplaceType;
1212

1313
export type dataProviderType = string =>
1414
| Promise<Array<Object | string>>

0 commit comments

Comments
 (0)