mui / material-ui

Material UI: Comprehensive React component library that implements Google's Material Design. Free forever.
https://mui.com/material-ui/
MIT License
93.69k stars 32.23k forks source link

[Autocomplete] Jumps between being expanded to the top/bottom #21661

Open foxylion opened 4 years ago

foxylion commented 4 years ago

Current Behavior 😯

When having not that much space below the bottom of the input field the Autocomplete opens to the top. By entering text into the input field the Autocomplete field gets shorter and jumps to the bottom.

Expected Behavior 🤔

After opening the Autocomplete ist should stay at the same position as the switch to the bottom is not expected and the user has to re-orientate to find the list of suggestions.

Steps to Reproduce 🕹

CodeSandbox used for reproduction: https://codesandbox.io/s/naughty-hermann-24rmn

Steps:

  1. The input field image
  2. Ensure that there is not much space to the bottom
  3. After clicking into the field, the Autocomplete opens to the top (as expected ✔️) image
  4. After typing an "a", the Autocomplete jumps to the bottom (not expected, should stay ❌) image

Your Environment 🌎

Tech Version
Material-UI v4.11.0
React v16.13.1
Browser Chrome 83
oliviertassinari commented 4 years ago

@foxylion Interesting, do we even need the placement of the popup to maximize visibility? It feels wrong to me when the popup display on-top. I feel like this behavior is best suited for tooltips.

joshwooding commented 4 years ago

I’ve seen someone explicitly ask for the flipping behaviour so the popup is always visible. Seems to me popperjs is too eager when deciding whether to flip back.

foxylion commented 4 years ago

I would say it is expected that the drop-down is opening into the direction of "enough space". But it should not change the position while being open, as this distracts from using the auto complete input.

oliviertassinari commented 4 years ago

Did you look into how we could implement it?

foxylion commented 4 years ago

No, I'm unsure how it can be fixed. But it looks like it is an Popper.js specific behavior and could only be fixed by overriding onUpdate and preventing updates to the position. But it need to be kept in mind, that a repositioning can be required when scrolling with an expanded Autocomplete.

ezgif-1-b55368bee433

pkuczynski commented 3 years ago

I am experiencing the same issue. Did anybody found a solution for it?

StrikEr2909 commented 2 years ago

I am having same issue. someone please update if is there any solution to this issue.

shahab0105 commented 2 years ago

Hello, anyone still trying to solve the position, just add the popperComponent attribute. Popper can be imported from mui


 PopperComponent={({ style, ...props }) => (
    <Popper
      {...props}
      style={{ ...style, height: 0 }} // width is passed in 'style' prop
    />
  )}
oliviertassinari commented 1 year ago

We are facing the same bug with the date pickers https://github.com/mui/mui-x/issues/5490.

There we documented a workaround: https://mui.com/x/react-date-pickers/custom-components/#popper, which can't be applied directly to the Autocomplete but can give ideas.

One thing I suspect is that we should set the document as the flip boundary:

        slotProps={{
          popper: {
            modifiers: [
              {
                name: "flip",
                options: {
                  rootBoundary: "document"
                }
              }
            ]
          }
        }}

https://codesandbox.io/s/twilight-wood-n7n8h7?file=/src/Demo.js

It feels better to scroll to see all the options than to see the displayed above the input. This could solve most of the problems.

However, now, let's assume the document itself is too limiting, I think that we can then set the width of the popper to avoid variations:

        slotProps={{
          popper: {
            sx: {
              height: "40vh",
              display: "flex",
              alignItems: "flex-start",
              '&[data-popper-placement="top"]': {
                alignItems: "flex-end"
              },
              "& .MuiAutocomplete-paper": {
                flexGrow: 1
              },
              "& .MuiAutocomplete-listbox": {
                maxHeight: "auto"
              }
            },

https://codesandbox.io/s/jolly-leftpad-swkw9n?file=/src/Demo.js

Problem solved?

There is one more problem to solve, this approach blocks interaction with the rest of the page when the full height isn't used, so we need to add a pointerEvents: none & auto style.

oliviertassinari commented 1 year ago

A more extreme workaround, but likely not for the best https://github.com/mui/material-ui/issues/24962#issuecomment-1663488488

niranjan404 commented 7 months ago

We are facing the same bug with the date pickers mui/mui-x#5490.

There we documented a workaround: https://mui.com/x/react-date-pickers/custom-components/#popper, which can't be applied directly to the Autocomplete but can give ideas.

One thing I suspect is that we should set the document as the flip boundary:

        slotProps={{
          popper: {
            modifiers: [
              {
                name: "flip",
                options: {
                  rootBoundary: "document"
                }
              }
            ]
          }
        }}

https://codesandbox.io/s/twilight-wood-n7n8h7?file=/src/Demo.js

It feels better to scroll to see all the options than to see the displayed above the input. This could solve most of the problems.

However, now, let's assume the document itself is too limiting, I think that we can then set the width of the popper to avoid variations:

        slotProps={{
          popper: {
            sx: {
              height: "40vh",
              display: "flex",
              alignItems: "flex-start",
              '&[data-popper-placement="top"]': {
                alignItems: "flex-end"
              },
              "& .MuiAutocomplete-paper": {
                flexGrow: 1
              },
              "& .MuiAutocomplete-listbox": {
                maxHeight: "auto"
              }
            },

https://codesandbox.io/s/jolly-leftpad-swkw9n?file=/src/Demo.js

Problem solved?

There is one more problem to solve, this approach blocks interaction with the rest of the page when the full height isn't used, so we need to add a pointerEvents: none & auto style.

slotProps doesn't work for me, I use mui v4

image

Any alternatives?