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

[pickers] Jumps between being expanded to the top/bottom #5490

Closed
2 tasks done
AlexTalis opened this issue Jul 14, 2022 · 5 comments · Fixed by #9781 or #10541
Closed
2 tasks done

[pickers] Jumps between being expanded to the top/bottom #5490

AlexTalis opened this issue Jul 14, 2022 · 5 comments · Fixed by #9781 or #10541
Assignees
Labels
bug 🐛 Something doesn't work component: DatePicker The React component. component: pickers This is the name of the generic UI component, not the React module! design This is about UI or UX design, please involve a designer

Comments

@AlexTalis
Copy link

AlexTalis commented Jul 14, 2022

Duplicates

  • I have searched the existing issues

Latest version

  • I have tested the latest version

Current behavior 😯

When there is just enough space to show the day view at the bottom of the text field, but not enough space to show the year view, popover jumps between positions at the top and bottom of the text field when switching between the two views.

Screen.Recording.2022-07-13.at.10.08.38.PM.mov

Expected behavior 🤔

The popover should always be positioned based on the size of the largest supported view.

Steps to reproduce 🕹

Link to live example:
https://codesandbox.io/s/mui-picker-popover-312xyl?file=/src/App.tsx

Steps:

  1. Depending on your system, you may need to tweak pb: '340px' prop so that there is just enough space for the day view below the text field, but even more space available above the text field, as shown in the attached video.
  2. Open the popup.
  3. Open Year picker and select any year. Popup should jump to above the text field.
  4. Click anywhere outside the popup. Before closing it will quickly jump to below the text field, then it will close.

Context 🔦

I want to use the various combinations of date picker views without any jarring relocations of the popup. Similar problem also exists when switching between the day and month views.

Your environment 🌎

I used Google Chrome. BTW, I do have Edge installed, but the tool says "Edge: Not Found"

npx @mui/envinfo System: OS: macOS 12.4 Binaries: Node: 16.13.1 - ~/opt/node/current/bin/node Yarn: 1.22.19 - ~/opt/node/current/bin/yarn npm: 8.13.2 - ~/opt/node/current/bin/npm Browsers: Chrome: 103.0.5060.114 Edge: Not Found Firefox: 101.0.1 Safari: 15.5 npmPackages: @emotion/react: ^11.9.3 => 11.9.3 @emotion/styled: ^11.9.3 => 11.9.3 @mui/base: 5.0.0-alpha.89 @mui/icons-material: ^5.8.4 => 5.8.4 @mui/material: ^5.9.0 => 5.9.0 @mui/private-theming: 5.9.0 @mui/styled-engine: 5.8.7 @mui/system: 5.9.0 @mui/types: 7.1.4 @mui/utils: 5.9.0 @mui/x-date-pickers: ^5.0.0-beta.0 => 5.0.0-beta.0 @types/react: ^18.0.15 => 18.0.15 react: ^18.2.0 => 18.2.0 react-dom: ^18.2.0 => 18.2.0 typescript: 4.7.4 => 4.7.4

Order ID 💳 (optional)

No response

@AlexTalis AlexTalis added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Jul 14, 2022
@m4theushw
Copy link
Member

We use a wrapper around Popper.js to position the popover. By default, the popover is placed under the input. But this plugin has a feature that inverts the placement if it detects that there's no enough room. This condition is met when switching to the year view, because it's taller than the day view. Whenever the popper's content changes, popperRef.current.forceUpdate() must be called to recalculate the position. The problem here is that this method is not being called at the right time. .forceUpdate is called when an year is selected, but while still displaying the year view, which is taller and doesn't fit under the input = flip the placement. Popper.js is working correctly but the recalculation is being done before rendering the new content. A quick workaround for now is to simply disable the placement flip with:

<DesktopDatePicker
  value={value}
  onChange={handleChange}
  PopperProps={{
    modifiers: [
      {
        name: 'flip',
        enabled: false,
      },
    ],
  }}
  renderInput={(props) => <TextField {...props} size="small" />}
/>

It will work but note that the calendar will always be at the bottom, potentially displaying scrollbars when there's no room.

A better solution could be to call popperRef.current.forceUpdate() always when the view changes or make the year picker to have the same height of the day picker. cc @flaviendelangle @alexfauquette

@m4theushw m4theushw added bug 🐛 Something doesn't work component: DatePicker The React component. and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Jul 16, 2022
@flaviendelangle flaviendelangle added the component: pickers This is the name of the generic UI component, not the React module! label Oct 17, 2022
@flaviendelangle flaviendelangle changed the title DesktopDatePicker - changing views causes jarring popover position changes [pickers] The popover should not change its position when change view Oct 17, 2022
@iZuminnnn
Copy link

iZuminnnn commented Jul 14, 2023

I try to fix it, it work for me, i make the year picker to have the same height of the day picker:

        <DatePickerStyled
          {...props}
          readOnly={readOnly}
          value={field.value}
          onChange={handleOnChange}
          views={['year', 'month']}
          format="YYYY/MM"
          slotProps={{
            textField: {
              error: hasError,
            },
            popper: {
              popperOptions: {
                modifiers: [
                  {
                    name: 'applyCustom',
                    enabled: true,
                    phase: 'beforeWrite',
                    requires: ['computeStyles'],
                    fn: ({ state }: { state: Partial<any> }) => {
                      state.styles.popper.height = '358px';
                      if (state.placement.includes('top-start')) {
                        state.styles.popper = {
                          ...state.styles.popper,
                          display: 'flex',
                          alignItems: 'flex-end',
                        };
                      }
                      if (state.placement.includes('bottom')) {
                        state.styles.popper = {
                          ...state.styles.popper,
                          display: 'block',
                        };
                      }
                    },
                  },
                ],
              }
            },
          }}
        />

@LukasTy
Copy link
Member

LukasTy commented Jul 14, 2023

That is a very interesting fix that you have provided. 👍
We have discussed similar solutions but with a visual drawback of fixing the YearCalendar height.
In the case of your solution, visually component still looks as it currently does, it's just that technically the popper takes a fixed height. 👌

@oliviertassinari
Copy link
Member

oliviertassinari commented Aug 11, 2023

We now have a workaround since #9781, see https://mui.com/x/react-date-pickers/custom-components/#popper to help.

However, the default behavior of the picker is still broken. We are facing the same problem with the Autocomplete mui/material-ui#21661. I'm reopening. I think we could continue the discussion on the Autocomplete.

@noraleonte In mui/material-ui#21661 (comment) I explored a similar solution which we can likely use on the date pickers as well. The idea would be to only flip when there is no space in the document, rather than the viewport, and to change how the popup height is set, to be more stable.

@oliviertassinari oliviertassinari changed the title [pickers] The popover should not change its position when change view [pickers] Jumps between being expanded to the top/bottom Aug 11, 2023
@oliviertassinari oliviertassinari added design This is about UI or UX design, please involve a designer and removed design: ux labels Aug 18, 2023
@LukasTy
Copy link
Member

LukasTy commented Sep 19, 2023

We decided to set a fixed (min)Height for the calendars to avoid this placement shifting.
Are there any objections?
cc @oliviertassinari

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐛 Something doesn't work component: DatePicker The React component. component: pickers This is the name of the generic UI component, not the React module! design This is about UI or UX design, please involve a designer
Projects
None yet
6 participants