diff --git a/cypress/integration/textarea.js b/cypress/integration/textarea.js index b3a1745..521d8c9 100644 --- a/cypress/integration/textarea.js +++ b/cypress/integration/textarea.js @@ -339,6 +339,16 @@ describe("React Textarea Autocomplete", () => { cy.get(".rta__textarea").should("have.value", "This is test test2"); }); + // https://github.com/webscopeio/react-textarea-autocomplete/issues/219 + it("test multi-character trigger doesn't replace entire text", () => { + cy.get(".rta__textarea").type("This is test /filtere"); + cy.get(".rta__autocomplete").should("be.visible"); + cy.get(".rta__list") + .get("li:nth-child(1)") + .click(); + cy.get(".rta__textarea").should("have.value", "This is test emily"); + }); + it("change value from outside should trigger the autocomplete as well", () => { cy.get(".rta__autocomplete").should("not.be.visible"); cy.get('[data-test="changeValueTo"]').click(); diff --git a/example/App.jsx b/example/App.jsx index 3bdd382..1600230 100644 --- a/example/App.jsx +++ b/example/App.jsx @@ -367,6 +367,17 @@ class App extends React.Component { 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" }, diff --git a/src/Textarea.jsx b/src/Textarea.jsx index 7826508..1e3a1b8 100644 --- a/src/Textarea.jsx +++ b/src/Textarea.jsx @@ -435,14 +435,14 @@ class ReactTextareaAutocomplete extends React.Component< const textToModify = textareaValue.slice(0, selectionEnd); + /** + * It's important to escape the currentTrigger char for chars like [, (,... + */ + const escapedCurrentTrigger = escapeRegex(currentTrigger); + const escapedCurrentTriggerWithWhitespace = escapedCurrentTrigger + (trigger[currentTrigger].allowWhitespace ? "" : "\\s"); const startOfTokenPosition = textToModify.search( - /** - * It's important to escape the currentTrigger char for chars like [, (,... - */ new RegExp( - `${escapeRegex(currentTrigger)}${`[^${escapeRegex(currentTrigger)}${ - trigger[currentTrigger].allowWhitespace ? "" : "\\s" - }]`}*$` + `${escapedCurrentTrigger}((?!${escapedCurrentTriggerWithWhitespace}).)*$` ) );