Skip to content

Options in Autocomplete lose the last focus after component is rerendered #48093

@VadimZvf

Description

@VadimZvf

Steps to reproduce

Steps:

  1. Open this link to live example: https://codesandbox.io/p/sandbox/5gc5pj
  2. Set focus to the text input
  3. Press "ArrowDown" key so the first option is highlighted
  4. Press "Enter" key
  5. Press "ArrowDown" three times, so the "Focus on me now, and try to select too" option is highlighted
  6. Press "Enter" key
  7. Press "ArrowDown"

Current behavior

The focus goes to the first option

Expected behavior

The next "Then try to focus on me" option is highlighted

Context

The example code looks strange, because we manually trigger rerenders.
However, this rerender could be triggered by an async action at the parent component.

I think the problem is easier to understand if we look at its test case 👇

    it('should keep focus when component is re-rendered', () => {
      const onChange = spy();

      function TestComponent(props) {
        return (
          <Autocomplete
            open
            multiple
            value={[]}
            options={props.options}
            renderInput={(params) => <TextField {...params} autoFocus />}
            onChange={onChange}
          />
        );
      }

      const view = render(<TestComponent options={['one', 'two']} />);

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

      // highlight 'two'
      fireEvent.keyDown(textbox, { key: 'ArrowDown' });
      fireEvent.keyDown(textbox, { key: 'ArrowDown' });
      checkHighlightIs(listbox, 'two');

      // the highlighted option should be the same even if the options are updated
      view.rerender(<TestComponent options={['one', 'two', 'three', 'four', 'five']} />);
      checkHighlightIs(listbox, 'two');

      // highlight 'four'
      fireEvent.keyDown(textbox, { key: 'ArrowDown' });
      fireEvent.keyDown(textbox, { key: 'ArrowDown' });
      checkHighlightIs(listbox, 'four');

      // re-rendering the component should not change the highlighted option
      view.rerender(<TestComponent options={['one', 'two', 'three', 'four', 'five']} />);

      // highlight 'five'
      fireEvent.keyDown(textbox, { key: 'ArrowDown' });
      checkHighlightIs(listbox, 'five'); // Test fails here, the focus goes to the first option
    });

Your environment

We only need the latest @mui/material package

Search keywords: focus, Autocomplete, highlight

Metadata

Metadata

Assignees

No one assigned

    Labels

    scope: autocompleteChanges related to the autocomplete. This includes ComboBox.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions