Skip to content

Commit 5b82861

Browse files
authored
Controlled value should trigger autocomplete as well (#110)
Close #109
1 parent 8afb0dc commit 5b82861

File tree

4 files changed

+110
-83
lines changed

4 files changed

+110
-83
lines changed

cypress/integration/textarea.js

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ describe("React Textarea Autocomplete", () => {
121121
* This is probably Cypress bug (1.0.2)
122122
* This test needs to be run in headed mode, otherwise fails
123123
*/
124-
cy.get('[id="caretStart"]').click();
124+
cy.get('[data-test="caretStart"]').click();
125125

126126
cy.get(".rta__textarea").type("This is test :ro{downarrow}{downarrow}");
127127

@@ -135,7 +135,7 @@ describe("React Textarea Autocomplete", () => {
135135
* This is probably Cypress bug (1.0.2)
136136
* This test needs to be run in headed mode, otherwise fails
137137
*/
138-
cy.get('[id="caretEnd"]').click();
138+
cy.get('[data-test="caretEnd"]').click();
139139

140140
cy.get(".rta__textarea").type("This is test :ro{downarrow}{downarrow}");
141141

@@ -149,7 +149,7 @@ describe("React Textarea Autocomplete", () => {
149149
* This is probably Cypress bug (1.0.2)
150150
* This test needs to be run in headed mode, otherwise fails
151151
*/
152-
cy.get('[id="caretNext"]').click();
152+
cy.get('[data-test="caretNext"]').click();
153153

154154
cy.get(".rta__textarea").type("This is test :ro{downarrow}{downarrow}");
155155

@@ -159,14 +159,14 @@ describe("React Textarea Autocomplete", () => {
159159
});
160160

161161
it("set caret position", () => {
162-
cy.get('[id="caretEnd"]').click();
162+
cy.get('[data-test="caretEnd"]').click();
163163
cy.get(".rta__textarea").type("This is test :ro{uparrow}{enter}");
164164
cy.get('[data-test="setCaretPosition"]').click();
165165
cy.get('[data-test="actualCaretPosition"]').contains("1");
166166
});
167167

168168
it("get caret position", () => {
169-
cy.get('[id="caretEnd"]').click();
169+
cy.get('[data-test="caretEnd"]').click();
170170
const stub = cy.stub();
171171

172172
cy.on("window:alert", stub);
@@ -264,5 +264,11 @@ describe("React Textarea Autocomplete", () => {
264264
.click();
265265
cy.get(".rta__textarea").should("have.value", "This is test fred");
266266
});
267+
268+
it("change value from outside should trigger the autocomplete as well", () => {
269+
cy.get(".rta__autocomplete").should("not.be.visible");
270+
cy.get('[data-test="changeValueTo"]').click();
271+
cy.get(".rta__autocomplete").should("be.visible");
272+
});
267273
});
268274
});

example/App.jsx

Lines changed: 73 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
1-
import React from 'react';
2-
import ReactTextareaAutocomplete from '@webscopeio/react-textarea-autocomplete';
3-
import emoji from '@jukben/emoji-search';
1+
import React from "react";
2+
import ReactTextareaAutocomplete from "@webscopeio/react-textarea-autocomplete";
3+
import emoji from "@jukben/emoji-search";
44

55
// import '@webscopeio/react-textarea-autocomplete/style.css'
6-
import '../style.css';
6+
import "../style.css";
77

88
type ItemProps = {
99
entity: {
1010
char: string,
11-
name: string,
12-
},
11+
name: string
12+
}
1313
};
1414

1515
const Item = ({ entity: { name, char } }: ItemProps) => (
1616
<div>{`${name}: ${char}`}</div>
1717
);
1818

1919
type LoadingProps = {
20-
data: Array<{ name: string, char: string }>,
20+
data: Array<{ name: string, char: string }>
2121
};
2222

2323
const Loading = ({ data }: LoadingProps) => <div>Loading</div>;
@@ -28,57 +28,63 @@ class App extends React.Component {
2828
clickoutsideOption: false,
2929
caretPosition: 0,
3030
movePopupAsYouType: false,
31-
text: '',
32-
optionsCaret: 'start',
33-
actualTokenInProvider: '',
34-
showSecondTextarea: false,
31+
text: "",
32+
optionsCaret: "start",
33+
actualTokenInProvider: "",
34+
showSecondTextarea: false
3535
};
3636

3737
_handleOptionsCaretEnd = () => {
3838
this.setState(() => ({
39-
optionsCaret: 'end',
39+
optionsCaret: "end"
4040
}));
4141
};
4242

4343
_handleOptionsCaretNext = () => {
4444
this.setState(() => ({
45-
optionsCaret: 'next',
45+
optionsCaret: "next"
4646
}));
4747
};
4848

4949
_handleOptionsCaretStart = () => {
5050
this.setState(() => ({
51-
optionsCaret: 'start',
51+
optionsCaret: "start"
5252
}));
5353
};
5454

5555
_handleClickoutsideOption = () => {
5656
this.setState(({ clickoutsideOption }) => ({
57-
clickoutsideOption: !clickoutsideOption,
57+
clickoutsideOption: !clickoutsideOption
5858
}));
5959
};
6060

6161
_handleShowSecondTextarea = () => {
6262
this.setState(({ showSecondTextarea }) => ({
63-
showSecondTextarea: !showSecondTextarea,
63+
showSecondTextarea: !showSecondTextarea
6464
}));
6565
};
6666

6767
_handleMovePopupAsYouType = () => {
6868
this.setState(({ movePopupAsYouType }) => ({
69-
movePopupAsYouType: !movePopupAsYouType,
69+
movePopupAsYouType: !movePopupAsYouType
7070
}));
7171
};
7272

7373
_onChangeHandle = ({ target: { value } }) => {
7474
this.setState({
75-
text: value,
75+
text: value
76+
});
77+
};
78+
79+
_changeValueTo = () => {
80+
this.setState({
81+
text: ":troph"
7682
});
7783
};
7884

7985
_onCaretPositionChangeHandle = (position: number) => {
8086
this.setState({
81-
caretPosition: position,
87+
caretPosition: position
8288
});
8389
};
8490

@@ -92,12 +98,12 @@ class App extends React.Component {
9298

9399
_outputCaretEnd = (item, trigger) => ({
94100
text: item.char,
95-
caretPosition: 'end',
101+
caretPosition: "end"
96102
});
97103

98-
_outputCaretStart = item => ({ text: item.char, caretPosition: 'start' });
104+
_outputCaretStart = item => ({ text: item.char, caretPosition: "start" });
99105

100-
_outputCaretNext = item => ({ text: item.char, caretPosition: 'next' });
106+
_outputCaretNext = item => ({ text: item.char, caretPosition: "next" });
101107

102108
_getSelectionPosition = () => {
103109
alert(JSON.stringify(this.rtaRef.getSelectionPosition()));
@@ -124,38 +130,38 @@ class App extends React.Component {
124130
movePopupAsYouType,
125131
actualTokenInProvider,
126132
showSecondTextarea,
127-
text,
133+
text
128134
} = this.state;
129135

130136
return (
131137
<div>
132138
<div>
133139
<input
134-
id="caretStart"
140+
data-test="caretStart"
135141
name="caret"
136142
value="start"
137143
type="radio"
138-
checked={this.state.optionsCaret === 'start'}
144+
checked={this.state.optionsCaret === "start"}
139145
onChange={this._handleOptionsCaretStart}
140146
/>
141147
<label htmlFor="caretStart">Place caret before word</label>
142148

143149
<input
144-
id="caretEnd"
150+
data-test="caretEnd"
145151
name="caret"
146152
value="end"
147153
type="radio"
148-
checked={this.state.optionsCaret === 'end'}
154+
checked={this.state.optionsCaret === "end"}
149155
onChange={this._handleOptionsCaretEnd}
150156
/>
151157
<label htmlFor="caretEnd">Place caret after word</label>
152158

153159
<input
154-
id="caretNext"
160+
data-test="caretNext"
155161
name="caret"
156162
value="next"
157163
type="radio"
158-
checked={this.state.optionsCaret === 'next'}
164+
checked={this.state.optionsCaret === "next"}
159165
onChange={this._handleOptionsCaretNext}
160166
/>
161167
<label htmlFor="caretNext">Place caret after word with a space</label>
@@ -194,7 +200,7 @@ class App extends React.Component {
194200
</label>
195201
</div>
196202
<div>
197-
Actual caret position:{' '}
203+
Actual caret position:{" "}
198204
<span data-test="actualCaretPosition">{caretPosition}</span>
199205
</div>
200206
<button data-test="setCaretPosition" onClick={this._setCaretPosition}>
@@ -215,8 +221,11 @@ class App extends React.Component {
215221
<button data-test="focus" onClick={this._focus}>
216222
Focus the textarea
217223
</button>
224+
<button data-test="changeValueTo" onClick={this._changeValueTo}>
225+
Change value to ":troph"
226+
</button>
218227
<div>
219-
Actual token in "[" provider:{' '}
228+
Actual token in "[" provider:{" "}
220229
<span data-test="actualToken">{actualTokenInProvider}</span>
221230
</div>
222231

@@ -230,13 +239,13 @@ class App extends React.Component {
230239
}}
231240
loadingComponent={Loading}
232241
style={{
233-
padding: 5,
242+
padding: 5
234243
}}
235244
containerStyle={{
236245
marginTop: 20,
237246
width: 400,
238247
height: 100,
239-
margin: '20px auto',
248+
margin: "20px auto"
240249
}}
241250
movePopupAsYouType={movePopupAsYouType}
242251
closeOnClickOutside={clickoutsideOption}
@@ -245,7 +254,7 @@ class App extends React.Component {
245254
value={text}
246255
onChange={this._onChangeHandle}
247256
trigger={{
248-
':': {
257+
":": {
249258
dataProvider: token =>
250259
emoji(token)
251260
.slice(0, 10)
@@ -255,86 +264,86 @@ class App extends React.Component {
255264
output: {
256265
start: this._outputCaretStart,
257266
end: this._outputCaretEnd,
258-
next: this._outputCaretNext,
259-
}[optionsCaret],
267+
next: this._outputCaretNext
268+
}[optionsCaret]
260269
},
261-
'@': {
270+
"@": {
262271
dataProvider: token =>
263272
new Promise(res =>
264273
setTimeout(() => {
265-
res([{ name: 'jakub', char: 'Jakub' }]);
274+
res([{ name: "jakub", char: "Jakub" }]);
266275
}, 1000)
267276
),
268277
component: Item,
269278
output: {
270279
start: this._outputCaretStart,
271280
end: this._outputCaretEnd,
272-
next: this._outputCaretDefault,
273-
}[optionsCaret],
281+
next: this._outputCaretDefault
282+
}[optionsCaret]
274283
},
275284
// test of special character
276-
'[': {
285+
"[": {
277286
dataProvider: token => {
278287
/**
279288
Let's pass token to state to easily test it in Cypress
280289
We going to test that we get also whitespace because this trigger has set "allowWhitespace"
281290
*/
282291
this.setState({ actualTokenInProvider: token });
283292
return [
284-
{ name: 'alt', char: '@' },
285-
{ name: 'another character', char: '/' },
293+
{ name: "alt", char: "@" },
294+
{ name: "another character", char: "/" }
286295
];
287296
},
288297
component: Item,
289298
allowWhitespace: true,
290299
output: {
291300
start: this._outputCaretStart,
292301
end: this._outputCaretEnd,
293-
next: this._outputCaretNext,
294-
}[optionsCaret],
302+
next: this._outputCaretNext
303+
}[optionsCaret]
295304
},
296-
';': {
305+
";": {
297306
dataProvider: token => [
298-
{ name: '1', char: 'one' },
299-
{ name: '2', char: 'two' },
307+
{ name: "1", char: "one" },
308+
{ name: "2", char: "two" }
300309
],
301310
component: Item,
302311
afterWhitespace: true,
303312
output: {
304313
start: this._outputCaretStart,
305314
end: this._outputCaretEnd,
306-
next: this._outputCaretNext,
307-
}[optionsCaret],
315+
next: this._outputCaretNext
316+
}[optionsCaret]
308317
},
309-
'/': {
310-
dataProvider: token => [{ name: '1', char: '/kick' }],
318+
"/": {
319+
dataProvider: token => [{ name: "1", char: "/kick" }],
311320
component: Item,
312-
output: this._outputCaretEnd,
321+
output: this._outputCaretEnd
313322
},
314-
'/kick': {
323+
"/kick": {
315324
dataProvider: token => [
316-
{ name: '1', char: 'fred' },
317-
{ name: '2', char: 'jeremy' },
325+
{ name: "1", char: "fred" },
326+
{ name: "2", char: "jeremy" }
318327
],
319328
component: Item,
320-
output: this._outputCaretEnd,
321-
},
329+
output: this._outputCaretEnd
330+
}
322331
}}
323332
/>
324333
{!showSecondTextarea ? null : (
325334
<ReactTextareaAutocomplete
326335
style={{
327-
padding: 5,
336+
padding: 5
328337
}}
329338
containerStyle={{
330339
marginTop: 20,
331340
width: 400,
332341
height: 100,
333-
margin: '20px auto',
342+
margin: "20px auto"
334343
}}
335344
loadingComponent={Loading}
336345
trigger={{
337-
':': {
346+
":": {
338347
dataProvider: token =>
339348
emoji(token)
340349
.slice(0, 10)
@@ -344,9 +353,9 @@ class App extends React.Component {
344353
output: {
345354
start: this._outputCaretStart,
346355
end: this._outputCaretEnd,
347-
next: this._outputCaretNext,
348-
}[optionsCaret],
349-
},
356+
next: this._outputCaretNext
357+
}[optionsCaret]
358+
}
350359
}}
351360
/>
352361
)}

0 commit comments

Comments
 (0)