Skip to content

Commit b0aa08a

Browse files
[Chat] Fix triple click selection for TextFieldithMention when mention is added in the beginning of the text (#3336)
1 parent c77632d commit b0aa08a

4 files changed

Lines changed: 74 additions & 4 deletions

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "patch",
3+
"comment": "Fix for the text selection for triple click in TextFieldWithMention",
4+
"packageName": "@azure/communication-react",
5+
"email": "98852890+vhuseinova-msft@users.noreply.github.com",
6+
"dependentChangeType": "patch"
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "patch",
3+
"comment": "Fix for the text selection for triple click in TextFieldWithMention",
4+
"packageName": "@azure/communication-react",
5+
"email": "98852890+vhuseinova-msft@users.noreply.github.com",
6+
"dependentChangeType": "patch"
7+
}

packages/react-components/src/components/SendBox.test.tsx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,40 @@ describe('Clicks/Touch should select mention', () => {
272272
expect(input.selectionEnd).toBe((value + suggestions[0].displayText).length);
273273
});
274274

275+
test('Mouse triple click when text starts from mention should select the text in the input field', async () => {
276+
renderSendBox();
277+
// Find the input field
278+
const input = screen.getByRole('textbox') as HTMLInputElement;
279+
act(() => {
280+
// Focus on the input field
281+
input.focus();
282+
});
283+
await waitFor(async () => {
284+
// Type into the input field
285+
await userEvent.keyboard(trigger);
286+
});
287+
// Select the suggestion
288+
await selectFirstMention();
289+
expect(input.value).toBe(trigger + suggestions[0].displayText);
290+
await waitFor(async () => {
291+
// Type into the input field
292+
await userEvent.keyboard(' and');
293+
});
294+
const typedValue = trigger + suggestions[0].displayText + ' and';
295+
// Fix for mousedown issue in userEvent when `document` become null unexpectedly
296+
await act(async () => {
297+
triggerMouseEvent(input, 'mousedown');
298+
});
299+
// Triple click a letter at 14-th index
300+
await userEvent.pointer({
301+
keys: '[MouseLeft][MouseLeft][MouseLeft]',
302+
target: input,
303+
offset: 14
304+
});
305+
expect(input.selectionStart).toBe(0);
306+
expect(input.selectionEnd).toBe(typedValue.length);
307+
});
308+
275309
test('Mouse selection of first word in a mention should select only first word in the mention', async () => {
276310
renderSendBox();
277311
// Find the input field

packages/react-components/src/components/TextFieldWithMention/TextFieldWithMention.tsx

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,13 @@ export const TextFieldWithMention = (props: TextFieldWithMentionProps): JSX.Elem
393393
selectionEndValue?: number;
394394
interactionStartSelection?: { start: number | undefined; end: number | undefined };
395395
}): void => {
396-
if (shouldHandleOnMouseDownDuringSelect) {
396+
if (event.currentTarget.selectionStart === 0 && event.currentTarget.selectionEnd === inputTextValue.length) {
397+
// entire text is selected, no need to change anything
398+
setSelectionStartValue(event.currentTarget.selectionStart);
399+
setSelectionEndValue(event.currentTarget.selectionEnd);
400+
setInteractionStartSelection(undefined);
401+
setShouldHandleOnMouseDownDuringSelect(false);
402+
} else if (shouldHandleOnMouseDownDuringSelect) {
397403
if (
398404
interactionStartSelection !== undefined &&
399405
(interactionStartSelection.start !== event.currentTarget.selectionStart ||
@@ -423,15 +429,32 @@ export const TextFieldWithMention = (props: TextFieldWithMentionProps): JSX.Elem
423429
});
424430
setInteractionStartSelection(undefined);
425431
setShouldHandleOnMouseDownDuringSelect(false);
426-
} else if (event.currentTarget.selectionStart !== null) {
432+
} else if (event.currentTarget.selectionStart !== null && event.currentTarget.selectionEnd !== null) {
427433
// on select was triggered by mouse down/up with no movement
428434
const mentionTag = findMentionTagForSelection(tags, event.currentTarget.selectionStart);
429435
if (mentionTag !== undefined && mentionTag.plainTextBeginIndex !== undefined) {
430436
// handle mention click by selecting the whole mention
431437
// if the selection is not on the bounds of the mention
432-
const mentionEndIndex = mentionTag.plainTextEndIndex ?? mentionTag.plainTextBeginIndex;
433438
// disable selection for clicks on mention bounds
439+
const mentionEndIndex = mentionTag.plainTextEndIndex ?? mentionTag.plainTextBeginIndex;
440+
434441
if (
442+
event.currentTarget.selectionStart !== event.currentTarget.selectionEnd &&
443+
event.currentTarget.selectionEnd > mentionEndIndex
444+
) {
445+
// handle triple click when the text starts from mention
446+
if (event.currentTarget.selectionDirection === null) {
447+
event.currentTarget.setSelectionRange(mentionTag.plainTextBeginIndex, event.currentTarget.selectionEnd);
448+
} else {
449+
event.currentTarget.setSelectionRange(
450+
mentionTag.plainTextBeginIndex,
451+
event.currentTarget.selectionEnd,
452+
event.currentTarget.selectionDirection
453+
);
454+
}
455+
setSelectionStartValue(mentionTag.plainTextBeginIndex);
456+
setSelectionEndValue(event.currentTarget.selectionEnd);
457+
} else if (
435458
event.currentTarget.selectionStart !== event.currentTarget.selectionEnd ||
436459
(event.currentTarget.selectionStart !== mentionTag.plainTextBeginIndex &&
437460
event.currentTarget.selectionStart !== mentionEndIndex)
@@ -458,7 +481,6 @@ export const TextFieldWithMention = (props: TextFieldWithMentionProps): JSX.Elem
458481
setSelectionEndValue(nullToUndefined(event.currentTarget.selectionEnd));
459482
}
460483
setInteractionStartSelection(undefined);
461-
setShouldHandleOnMouseDownDuringSelect(false);
462484
}
463485
} else {
464486
// selection was changed by keyboard

0 commit comments

Comments
 (0)