Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Autocomplete] Remove tags with the Delete key #33822

Merged
merged 22 commits into from Nov 14, 2022

Conversation

sfavello
Copy link
Contributor

@sfavello sfavello commented Aug 6, 2022

This was to solve the issue that Autocomplete does not handle the functionality of the delete key, more specifically the forward delete key. When creating a Chip and the chip is on hover, it passes on the impression that you can use either the backspace key or the delete key to eliminate the chip. It's best to stay consistent and include the functionality of a delete key.

React.Autocomplete.component.-.Material.UI.-.Google.Chrome.2022-08-06.13-09-14_Trim.mp4

@mui-bot
Copy link

mui-bot commented Aug 6, 2022

Messages
📖 Netlify deploy preview: https://deploy-preview-33822--material-ui.netlify.app/

Details of bundle changes

Generated by 🚫 dangerJS against 8d3da58

@michaldudak michaldudak added component: autocomplete This is the name of the generic UI component, not the React module! enhancement This is not a bug, nor a new feature labels Oct 12, 2022
Copy link
Member

@michaldudak michaldudak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea, thanks!
It would be great to include this new functionality in tests.

Comment on lines 849 to 858
case 'Delete':
if (multiple && !readOnly && inputValue === '' && value.length > 0) {
const index = focusedTag === -1 ? value.length - 1 : focusedTag;
const newValue = value.slice();
newValue.splice(index, 1);
handleValue(event, newValue, 'removeOption', {
option: value[index],
});
}
break;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the code is duplicated. Could you add the case 'Delete' to the previous case block?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, thank you! I will do that asap.

@michaldudak
Copy link
Member

Thanks!

During testing, I found one behavior I'm not sure about. When no tags are selected (the cursor is visible), pressing Delete removes the last tag (just like the Backspace key does). This may be a bit confusing, as Delete usually removes a character to the right of the visible cursor, not to the left as in this case. So, after all, we may need a separate case for 'Delete' and run the code only if focusedTag !== -1.

The behavior for deleting selected tags looks fine.


Could you please merge/rebase on the latest master? We've had some issues with uploading regression tests' screenshots in the past, but they have been fixed, and the current master should work fine.

@sfavello
Copy link
Contributor Author

sfavello commented Oct 16, 2022

Thanks!

During testing, I found one behavior I'm not sure about. When no tags are selected (the cursor is visible), pressing Delete removes the last tag (just like the Backspace key does). This may be a bit confusing, as Delete usually removes a character to the right of the visible cursor, not to the left as in this case. So, after all, we may need a separate case for 'Delete' and run the code only if focusedTag !== -1.

The behavior for deleting selected tags looks fine.

Could you please merge/rebase on the latest master? We've had some issues with uploading regression tests' screenshots in the past, but they have been fixed, and the current master should work fine.

I updated it whereDelete key will not delete the value at the end but will delete the value to the right when it's on a focusedTag. 😄

Video update (you can't see but in beginning I was hitting the delete key to show it won't work) 😅
_From around 0 to 5 seconds is the test to make sure the delete will only run when focusedTag !== -1

autocomplete.mov

@sfavello sfavello requested review from michaldudak and removed request for mnajdova October 16, 2022 20:19
@michaldudak
Copy link
Member

👍 It does work well now when the cursor is behind tags. But when a tag is focused, Delete should delete the focused tag itself, not the next one.

@sfavello
Copy link
Contributor Author

I completely misunderstood. 😅 My apologies. I fixed it where it will not delete a chip when the cursor is behind the tags and when on focusedTag it will delete the tag that's on focus. I also updated the test to reflect the changes. 😄

DEMO

autocompleteDemo.mov

Copy link
Member

@michaldudak michaldudak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now the behavior is correct, thanks!
I found one possible improvement to do in the code.

@@ -850,6 +850,16 @@ export default function useAutocomplete(props) {
});
}
break;
case 'Delete':
if (multiple && !readOnly && inputValue === '' && value.length > 0 && focusedTag !== -1) {
const index = focusedTag === -1 ? value.length - 1 : focusedTag;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to check if focusedTag === -1, as the outer if handles this already.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, thank you! I appreciate it. I went in and made the change. 😄

michaldudak
michaldudak previously approved these changes Nov 1, 2022
Copy link
Member

@michaldudak michaldudak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your work!

Copy link
Member

@michaldudak michaldudak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's some issue with tests - would you mind checking it?

@michaldudak michaldudak dismissed their stale review November 1, 2022 07:31

Failing tests

@sfavello
Copy link
Contributor Author

sfavello commented Nov 1, 2022

So I checked the 3. failing tests

  1. argos states that there is 8 differences detected in the screenshots
  2. the e2e test is failing in a material-docs.spec.ts where the icon AcUnit is not visible.
    I'm still researching around why my changes could have possibly effected these two things, but I'll keep investigating.
  3. The other failing test was fixed. 😄

@michaldudak
Copy link
Member

Try merging in the latest master. It should help to solve the problems with Argos and E2E tests.
Could you also add another unit test that would verify if no tags are deleted if they are not highlighted? Something along these lines:

it('does not delete any tags with the delete key when no tag is highlighted', () => {
  const handleChange = spy();
  const options = ['one', 'two'];
  render(
    <Autocomplete
      defaultValue={options}
      options={options}
      onChange={handleChange}
      renderInput={(params) => <TextField {...params} autoFocus />}
      multiple
    />,
  );

  const textbox = screen.getByRole('combobox');

  fireEvent.keyDown(textbox, { key: 'Delete' });

  expect(handleChange.callCount).to.equal(0);
  expect(textbox).toHaveFocus();
});

@sfavello
Copy link
Contributor Author

sfavello commented Nov 4, 2022

Try merging in the latest master. It should help to solve the problems with Argos and E2E tests. Could you also add another unit test that would verify if no tags are deleted if they are not highlighted? Something along these lines:

it('does not delete any tags with the delete key when no tag is highlighted', () => {
  const handleChange = spy();
  const options = ['one', 'two'];
  render(
    <Autocomplete
      defaultValue={options}
      options={options}
      onChange={handleChange}
      renderInput={(params) => <TextField {...params} autoFocus />}
      multiple
    />,
  );

  const textbox = screen.getByRole('combobox');

  fireEvent.keyDown(textbox, { key: 'Delete' });

  expect(handleChange.callCount).to.equal(0);
  expect(textbox).toHaveFocus();
});

Added test and updated the branch. That fixed the problem. 🥳 . Thank you for your patience. I appreciate it.

Copy link
Member

@michaldudak michaldudak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. Thanks again for your contribution!

@michaldudak michaldudak changed the title [Autocomplete] Bring Accessibility to Autocomplete with Delete key [Autocomplete] Remove tags with the Delete key Nov 14, 2022
@michaldudak michaldudak merged commit 6a25f36 into mui:master Nov 14, 2022
@oliviertassinari
Copy link
Member

oliviertassinari commented Nov 15, 2022

Oh nice, I didn't think about the Del key. When I was on Windows, I always struggled to reach this key on my keyboard.

the-mgi pushed a commit to the-mgi/material-ui that referenced this pull request Nov 17, 2022
Co-authored-by: Sylvialynn Favello <sylvia-favello@docker.com>
daniel-rabe pushed a commit to daniel-rabe/material-ui that referenced this pull request Nov 29, 2022
Co-authored-by: Sylvialynn Favello <sylvia-favello@docker.com>
feliperli pushed a commit to jesrodri/material-ui that referenced this pull request Dec 6, 2022
Co-authored-by: Sylvialynn Favello <sylvia-favello@docker.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: autocomplete This is the name of the generic UI component, not the React module! enhancement This is not a bug, nor a new feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants