Reputation: 346
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?
Upvotes: 5
Views: 4349
Reputation: 81370
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:
DesktopDatePicker
or we'll have 2 pickers show up at the same time.DesktopDatePicker
date value. The DesktopDatePicker
requests to change the value when the user edits the TextField
.StaticDatePicker
date value. The StaticDatePicker
requests to change the value when the user picks a date in the modal.PickersModalDialog
open state by overriding the props in the step below.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 in MobileDatePicker
, if you want to display it, set showTodayButton
in PickersModalDialog
.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>
</>
);
Upvotes: 7