Material UI DateTimePicker Rendering In Wrong Spot

Viewed 3112

I am rendering a new material ui date time picker immediately on page render by enabling the open prop.

<Grid item xs={6} className={styles.CampaignDates_calendar_right}>
  <MuiPickersUtilsProvider utils={DateFnsUtils} className={styles.CampaignDates_calendar_right}>
   <KeyboardDatePicker
      open
      disableToolbar
      variant="inline"
      format="MM/dd/yyyy"
      margin="normal"
      id="date-picker-inline"
      value={date}
      onChange={handleDateChange}
   />
   </MuiPickersUtilsProvider>
</Grid>

For some reason though it renders in a random part in the screen and I dont get why. What's weirder is as soon as i change a prop in my code and hot reload it immediately snaps into place where its supposed to be.

I see that the calendar is loading with this css

    top: 361px;
    left: 126px;

when i play with these values i can move around the calendar but I am not sure what is triggering these values in the first place.

Here is how I want it looking

enter image description here

Here is how it is looking for some reasonenter image description here

Note: It works fine when I am not using the open prop but I would like to have the calendar open render which is why I am using the open prop.

Thank you

2 Answers

It's actually pretty straightforward to have the Picker be open on page load, but the thing you need to be cognizant of when using the open prop is that you now have to handle the show state of the picker yourself as MUI no longer will do it for you.

So let's start by rendering the picker in its proper place on page load. For that we shall use a state variable open and set it to false to give MUI time to render everything properly before we pop the Picker open. Then use useEffect to set open to true on second render, which will happen so quickly, nobody will even notice.

So here is what you need:

export default function MaterialUIPickers() {
  // The first commit of Material-UI
  const [date, setSelectedDate] = React.useState(
    new Date("2021-03-01T21:11:54")
  );

  const [open, setOpen] = React.useState(false);

  React.useEffect(() => {
    setOpen(true);
  }, []);

  const handleDateChange = (date) => {
    setSelectedDate(date);
  };

  return (
    <MuiPickersUtilsProvider utils={DateFnsUtils}>
      <Grid container justify="space-around">
        <KeyboardDatePicker
          open={open}
          disableToolbar
          variant="inline"
          format="MM/dd/yyyy"
          margin="normal"
          id="date-picker-inline"
          label="Date picker inline"
          value={date}
          onChange={handleDateChange}
          onClose={() => setOpen(false)}
          onOpen={() => setOpen(true)}
        />
      </Grid>
    </MuiPickersUtilsProvider>
  );
}

Notice these guys now:

...
   onClose={() => setOpen(false)}
   onOpen={() => setOpen(true)}
...

Those are needed to handle the open state manually. Here is a sandbox: https://codesandbox.io/s/material-demo-forked-jbw9o?file=/demo.js

It looks like you are forced to rerender (for example by updating a state) at least once to have the correct position.

Unfortunately Material UI team do not support v3 anymore. And in v4 KeyboardDatePicker is becoming DesktopDatePicker.

Here is an example with DesktopDatePicker, it starts with the correct position without having to rerender by yourself.

Related