Solved: React-day-picker Daypicker Input Loses Focus When Using Custom Input Component
Solution 1:
If you need a custom component with a focus method, I think you need to use a class component, and refs:
class Input extends React.Component {
constructor(props) {
super(props);
this.inputRef = React.createRef();
}
focus() {
this.inputRef.current.focus();
}
render() {
return <input {...this.props} ref={this.inputRef}/>
}
}
Solution 2:
I use the MaskedInput component from "react-text-mask" library, and custom overlay component for 'Date Range picker with two inputs' from 'react-day-picker'.
Custom overlay and input:
const renderMaskedInput = (_props, _ref) => {
return (
<MaskedInput
mask={getLocaleMask}
showMask
ref={_ref}
type="text"
render={(ref, inputProps) => <input ref={ref} {...inputProps} />}
{..._props}
/>
);};
<DayPickerInput
component={_props => renderMaskedInput(_props, startInputRef)}
overlayComponent={_props => (
<Popper
open={Boolean(startAnchorEl)}
anchorEl={startAnchorEl}
style={{ zIndex: 10000 }}
>
<div {..._props} className={customOverlayWrapper}>
<div className={customOverlay}>{_props.children}</div>
</div>
</Popper>
)}
My problem was in losing focus from the picker input when opening or clicking on the custom overlay, and the 'keepFocus' prop is did not work with custom input. So it causes problems with closing overlay after clicking on backdrop, because the overlay is closing only by 'onBlur' of input.
Just hard-setting focus on the input by onClick or something else did not work. My solution is setting focus in useEffect after changing input ref when the custom overlay is opening, but it did not enough because the focus is losing after clicking on the overlay, so we just setting focus to input after 3 handlers of DayPicker: onFocus, onMonthChange, onCaptionChange (see codesandbox example).
And using Popper as a custom overlay for DayPickerInput solves a problem with rendering overlay in a free area at the screen (auto-positioning of overlay). Also, Popper works with Portal and it solves many problems with rendering overlay.
Full code: https://codesandbox.io/s/optimistic-glitter-c77gb
Short version:
const focusStartInput = () => {
startInputRef.current.inputElement.focus();
}
useEffect(() => {
// used because 'keepFocus' prop from the library does not work with the custom
// overlay or with the react-text-mask input
if (startAnchorEl) {
// if the start picker overlay is open
focusStartInput(); // input loses focus after overlay opening,
// so just reset focus
}
if (endAnchorEl) {
// if the end picker overlay is open
focusEndInput(); // input loses focus after overlay opening, so just reset focus
}
}, [startAnchorEl, endAnchorEl]);
<DayPickerInput
dayPickerProps={{
onMonthChange: focusStartInput,
onFocus: focusStartInput,
onCaptionClick: focusStartInput,
}}
There is a problem with a solution from the main question. His input loses focus if we clicking not on the day in date picker (on the caption, month navigation, or somewhere else). My code helps to solve it.
Post a Comment for "Solved: React-day-picker Daypicker Input Loses Focus When Using Custom Input Component"