'Open Dialog instead of Popper in desktop MUI 5 DatePicker
I want the MUI v5 DatePicker
(@mui/lab 5.0.0-alpha-51) to behave like the DesktopDatePicker
(allowing to directly edit the date in the textbox). But when clicking on the calendar icon, I want to open the picker dialog, just like when clicking the MobileDatePicker
.
I tried using the MobileDatePicker
and added endAdornment
to the InputProps
to just get the calendar icon to draw. But this wasn't working.
Perhaps to put it more clearly: I want the DesktopDatePicker
to open the Dialog of the MobileDatePicker
when the user clicks on the calendar icon.
Is there a way to achieve this hybrid behavior?
Solution 1:[1]
If you have a look at MobileWrapper
and DesktopWrapper
definitions, you'll see that they use different components to display the picker (the former uses modal, the latter uses popover) and there is no way to swap it using the props provided by the picker component, but you also know where the internal modal comes from, so you can grab it:
import PickersModalDialog from "@mui/lab/internal/pickers/PickersModalDialog";
In this section, you can see that MUI exposes the StaticDatePicker
which uses the internal Picker
component that both the desktop and mobile pickers utilize, in case you want to build your own custom popup/modal, this is exactly what you want here, so grab this one too:
import StaticDatePicker from '@mui/lab/StaticDatePicker';
The next step is to integrate and make them work together, we have the DesktopDatePicker
because you want to edit the TextField
, the PickersModalDialog
to display the StaticDatePicker
in a modal. To do that you need to do the following things:
- (1) Disable the popover picker from the
DesktopDatePicker
or we'll have 2 pickers show up at the same time. - (2) Control the
DesktopDatePicker
date value. TheDesktopDatePicker
requests to change the value when the user edits theTextField
. - (3) Control the
StaticDatePicker
date value. TheStaticDatePicker
requests to change the value when the user picks a date in the modal. - (4) Control the
PickersModalDialog
open state by overriding the props in the step below. - (5) Add the required props in
PickersModalDialog
:onAccept
: When the user clicks the OK button.onClear
: When the user clicks the CANCEL button.onSetToday
: When the user clicks the TODAY button. Only available inMobileDatePicker
, if you want to display it, setshowTodayButton
inPickersModalDialog
.onDismiss
: When the dialog wants to close itself (for example when the user clicks outside the modal)
Putting it together, we'll have something like below:
const [value, setValue] = React.useState<Date | null>(() => new Date()); // (2)
const [tempValue, setTempValue] = React.useState<Date | null>(null); // (3)
const [open, setOpen] = React.useState(false); // (4)
return (
<>
<DesktopDatePicker
label="For desktop"
value={value}
open={false} // (1)
onChange={(newValue) => setValue(newValue)}
onOpen={() => {
setTempValue(value);
setOpen(true);
}}
renderInput={(params) => <TextField {...params} />}
/>
<PickersModalDialog
showTodayButton
open={open}
// (5)
onAccept={() => {
setValue(tempValue);
setOpen(false);
}}
onSetToday={() => {
setValue(new Date());
setOpen(false);
}}
onDismiss={() => setOpen(false)}
onClear={() => setOpen(false)}
>
<StaticDatePicker
displayStaticWrapperAs="mobile"
value={tempValue}
onChange={(newValue) => setTempValue(newValue)}
renderInput={(params) => <TextField {...params} />}
/>
</PickersModalDialog>
</>
);
Live Demo
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |