React-day-picker: DayPicker doesn't close until you click on a day if keepfocus is set to false

Created on 23 May 2018  路  5Comments  路  Source: gpbl/react-day-picker

I was trying to make a simple implementation of react-day-picker. But I found a problem when trying to close DayPicker container when it is triggered from DayPickerInput and the property keepFocus is set to false.

<DayPickerInput
    keepFocus={false}
    placeholder="DD/MM/YYYY"
    format="DD/MM/YYYY"
/>

Here is the codesandbox: https://codesandbox.io/s/0mn32ryl0n

If you click inside the input the daypicker overlay is displayed correctly and if you click in a empty area of the overlay, then the overlay gets focused and it will be focused until you select one day, otherwise it won't be closed. So if you click in an area outside the overlay it can't be closed automatically.

The question would be, if this is the intended behavior or maybe I'm missing something. How can I close the DayPicker if a day is not selected and the overlay is already focused?

Most helpful comment

I end up doing something like this,

let dayPickerInputRef = null;
function Example() {
  return (
    <div name="main-container">
      <h3>DayPickerInput</h3>
      <DayPickerInput
        ref={ref => (dayPickerInputRef = ref)}
        keepFocus={false}
        placeholder="DD/MM/YYYY"
        format="DD/MM/YYYY" 
        dayPickerProps = {{
          onBlur: () => {
            setTimeout(() => {
              const elClicked = document.activeElement,
                container = document.getElementsByName(`main-container`);
              if (container && !container[0].contains(elClicked)) {
                dayPickerInputRef.hideDayPicker();
              }
            }, 1);
          }
        }}
      />
    </div>
  );
}

This solves the problem, but I don't know if that's the way we should handle that case.

All 5 comments

I end up doing something like this,

let dayPickerInputRef = null;
function Example() {
  return (
    <div name="main-container">
      <h3>DayPickerInput</h3>
      <DayPickerInput
        ref={ref => (dayPickerInputRef = ref)}
        keepFocus={false}
        placeholder="DD/MM/YYYY"
        format="DD/MM/YYYY" 
        dayPickerProps = {{
          onBlur: () => {
            setTimeout(() => {
              const elClicked = document.activeElement,
                container = document.getElementsByName(`main-container`);
              if (container && !container[0].contains(elClicked)) {
                dayPickerInputRef.hideDayPicker();
              }
            }, 1);
          }
        }}
      />
    </div>
  );
}

This solves the problem, but I don't know if that's the way we should handle that case.

I have the same issue. Calendar container closes on blur only first time it's opened. Every other time day must be selected before container is dismissed. This happens whether keepfocus is true or false.

The above "solution" by @matfork-belatrix sort of works except for using name="main-container", which limits the number of instances of react-day-picker to 1.

I think hideAfterDayClick in DayPickerInput.js needs to set this.overlayHasFocus to false.

This solves the problem for me locally, but am unsure if this will have side effects elsewhere?

Thanks everybody for working on this!

The Input components and its interaction with focus and blur has been always problematic, and for this reason it will be replaced by a hook in the upcoming v8.

@thedaruma I can't say either if your solution has side effects, but it seems logic to me.

Here a preview of the useInput hook: https://rdp-v8.netlify.com/docs/input

Was this page helpful?
0 / 5 - 0 ratings

Related issues

NikitaSasin picture NikitaSasin  路  5Comments

magnusohlin picture magnusohlin  路  4Comments

laidinidis picture laidinidis  路  6Comments

dreamyguy picture dreamyguy  路  5Comments

kradical picture kradical  路  3Comments