How do I spawn my date picker UI upon first clicking on the date text field?
Multiple issues to handle while solving this:
- Since you want to the focus on the
Input
to control the opening of the DatePicker Popover - has to be a controlled component (which you control the opening of it using a state.
This state is actually theopen
prop of theKeyboardDatePicker
- Next issue is that once the Popover is closed - the focus is getting back to the
Input
, and once we have a focus the the Popover will open (not good). We can solve this using thedisableRestoreFocus
prop of the Popover. - We need to use the
onFocus
of theInput
to open the Popover, but theonClose
of the Popover to actually close it (because we control the open-state of the Popover). - Lastly - the icon is no longer controlling the opening of the Popover. We need to do this, using the
onFocus
of theKeyboardButtonProps
.
This is the complete code:
const KeyDatePickerContainer = () => { const [selectedDate, handleDateChange] = useState(null); const [isOpen, setIsOpen] = useState(false); return ( <KeyboardDatePicker variant="inline" value={selectedDate} inputVariant="outlined" label="With keyboard" format="MM/dd/yyyy" onChange={newDate => { handleDateChange(newDate); }} KeyboardButtonProps={{ onFocus: e => { setIsOpen(true); } }} PopoverProps={{ disableRestoreFocus: true, onClose: () => { setIsOpen(false); } }} InputProps={{ onFocus: () => { setIsOpen(true); } }} open={isOpen} /> );};
Here is a link to a working example: https://codesandbox.io/s/material-pickers-open-modal-click-on-text-kjgjk
Update: if you want to also close the DatePicker once the date was selected you can use the onChange
function to not only set the new date, but also close the Popover:
onChange={newDate => { handleDateChange(newDate); setIsOpen(false); // Add this}}
For anyone else interested I came up with the following solution:
- You change the
KeyboardDatePicker
toDatePicker
- You take advantage of
InputProps
and add the calendar icon
InputProps={{ endAdornment: ( <InputAdornment> <Event /> </InputAdornment> ) }}
Working sandbox:https://codesandbox.io/s/customicon-forked-zitm9?file=/src/DatePicker.js
For anyone who uses updated material-ui library (v5), you can use open={bool} attribute to make use of when to open DatePicker.
const [dateOpen,setDateOpen] = useState(false); const [dueDate,setDueDate] = useState(new Date()); <DatePicker clearable={true} open={dateOpen} onClose={() => setDateOpen(false)} label="Due Date" value={dueDate} minDate={new Date()} onChange={(newValue) => { setDueDate(newValue); }} renderInput={(params) => ( <TextField {...params} onClick={() => setDateOpen(true)} /> )} />