Skip to content Skip to sidebar Skip to footer

Solved: React-day-picker Daypicker Input Loses Focus When Using Custom Input Component

The working sandbox is https://codesandbox.io/s/react-day-picker-base-h9fv6 I have been trying to implement a simple day picker input, where you can both enter the date in the inpu

Solution 1:

If you need a custom component with a focus method, I think you need to use a class component, and refs:

classInputextendsReact.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:

constrenderMaskedInput = (_props, _ref) => {
        return (
           <MaskedInputmask={getLocaleMask}showMaskref={_ref}type="text"render={(ref,inputProps) =><inputref={ref} {...inputProps} />}
             {..._props}
      />
    );};


<DayPickerInputcomponent={_props => renderMaskedInput(_props, startInputRef)}
   overlayComponent={_props => (
      <Popperopen={Boolean(startAnchorEl)}anchorEl={startAnchorEl}style={{zIndex:10000 }}
      ><div {..._props} className={customOverlayWrapper}><divclassName={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:

constfocusStartInput = () => {
      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 inputif (startAnchorEl) {
      // if the start picker overlay is openfocusStartInput(); // input loses focus after overlay opening,// so just reset focus
    }

    if (endAnchorEl) {
      // if the end picker overlay is openfocusEndInput(); // input loses focus after overlay opening, so just reset focus
    }
  }, [startAnchorEl, endAnchorEl]);

<DayPickerInputdayPickerProps={{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"