Switch from combobox to plaintextArea on click outside (#13333)
* switch back to plaintextArea on click outside * add a test for click outside * restore plainTextArea on blur, add cypress test
This commit is contained in:
parent
25bf0e3950
commit
94bca23f07
2 changed files with 80 additions and 1 deletions
|
|
@ -124,7 +124,12 @@ export const MentionAutocompleteTextArea = forwardRef(
|
|||
|
||||
const { setTextArea, setAdditionalElements } = useTextAreaAutoResize();
|
||||
|
||||
const { onChange, id: inputId, ...autocompleteInputProps } = inputProps;
|
||||
const {
|
||||
onChange,
|
||||
onBlur,
|
||||
id: inputId,
|
||||
...autocompleteInputProps
|
||||
} = inputProps;
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (autoResize && comboboxRef.current && plainTextAreaRef.current) {
|
||||
|
|
@ -180,6 +185,13 @@ export const MentionAutocompleteTextArea = forwardRef(
|
|||
setSearchTerm('');
|
||||
setAriaHelperText('');
|
||||
setUsers([]);
|
||||
|
||||
const { selectionStart } = comboboxRef.current;
|
||||
|
||||
// Switch back to the plain text area
|
||||
comboboxRef.current.classList.add('hidden');
|
||||
plainTextAreaRef.current.classList.remove('hidden');
|
||||
setCursorPosition(selectionStart + 1);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -270,6 +282,12 @@ export const MentionAutocompleteTextArea = forwardRef(
|
|||
}
|
||||
};
|
||||
|
||||
const handleComboboxBlur = () => {
|
||||
// User has left the textarea, exit combobox functionality without refocusing plainTextArea
|
||||
comboboxRef.current.classList.add('hidden');
|
||||
plainTextAreaRef.current.classList.remove('hidden');
|
||||
};
|
||||
|
||||
const handleSelect = (username) => {
|
||||
// Construct the new textArea content with selected username inserted
|
||||
const textWithSelection = `${textContent.substring(
|
||||
|
|
@ -340,6 +358,10 @@ export const MentionAutocompleteTextArea = forwardRef(
|
|||
onChange?.(e);
|
||||
handleTextInputChange(e);
|
||||
}}
|
||||
onBlur={(e) => {
|
||||
onBlur?.(e);
|
||||
handleComboboxBlur();
|
||||
}}
|
||||
/>
|
||||
|
||||
<textarea
|
||||
|
|
|
|||
|
|
@ -202,6 +202,63 @@ describe('Comment on articles', () => {
|
|||
cy.findByText('@search_user_1').should('not.be.visible');
|
||||
});
|
||||
|
||||
it('should close the autocomplete suggestions and exit combobox on click outside', () => {
|
||||
cy.intercept(
|
||||
{ method: 'GET', url: '/search/usernames' },
|
||||
{ fixture: 'search/usernames.json' },
|
||||
);
|
||||
|
||||
cy.findByLabelText(/^Add a comment to the discussion$/i).click();
|
||||
|
||||
// Get a handle to the newly substituted textbox
|
||||
cy.findByRole('textbox', {
|
||||
name: /^Add a comment to the discussion$/i,
|
||||
}).as('plainTextArea');
|
||||
|
||||
cy.get('@plainTextArea').type('Some text @s');
|
||||
|
||||
// Verify the combobox has appeared
|
||||
cy.findByRole('combobox', { name: /Add a comment to the discussion/ }).as(
|
||||
'autocompleteCommentBox',
|
||||
);
|
||||
|
||||
cy.get('@autocompleteCommentBox').type('earch');
|
||||
cy.findByText('@search_user_1').should('be.visible');
|
||||
|
||||
// Click away from the dropdown
|
||||
cy.get('@autocompleteCommentBox').click({ position: 'right' });
|
||||
cy.findByText('@search_user_1').should('not.exist');
|
||||
|
||||
// Check the combobox has exited and we are returned to the plainTextArea
|
||||
cy.get('@plainTextArea').should('have.focus');
|
||||
});
|
||||
|
||||
it('should exit combobox when blurred and refocused', () => {
|
||||
cy.intercept(
|
||||
{ method: 'GET', url: '/search/usernames' },
|
||||
{ fixture: 'search/usernames.json' },
|
||||
);
|
||||
|
||||
cy.findByLabelText(/^Add a comment to the discussion$/i).click();
|
||||
|
||||
// Get a handle to the newly substituted textbox
|
||||
cy.findByRole('textbox', {
|
||||
name: /^Add a comment to the discussion$/i,
|
||||
}).as('plainTextArea');
|
||||
|
||||
cy.get('@plainTextArea').type('Some text @s');
|
||||
|
||||
// Verify the combobox has appeared
|
||||
cy.findByRole('combobox', {
|
||||
name: /Add a comment to the discussion/,
|
||||
}).as('combobox');
|
||||
|
||||
// Blur the currently active textarea, and check that the blur results in the plainTextArea being restored
|
||||
cy.get('@combobox').blur();
|
||||
cy.get('@combobox').should('not.be.visible');
|
||||
cy.get('@plainTextArea').should('be.visible');
|
||||
});
|
||||
|
||||
// TODO: Flaky spec
|
||||
xit('should reply to a comment with user mention autocomplete', () => {
|
||||
cy.intercept(
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue