Skip to content

changeMonth in custom header is inconsistent based on last selected date #3829

@TravisJRyan

Description

@TravisJRyan

Describe the bug
When you use the "changeMonth" function in a custom header, the actual month that gets selected is different dependent on the last date you clicked on. This seems to be happening when you use react-datepicker with monthsShown >= 2.

To Reproduce
I copied the below from the example docs ("Custom header with two months displayed" section) with small changes (adding a "Jump to June" button which calls changeMonth(5)). Try the following:

  1. Click on the "Jump to June" button. It changes the display to show June on the left and July on the right. This seems correct.
  2. Then click some day in July and reopen the calendar.
  3. Then click the button again. The display is May on the left and June on the right. It seems react-datepicker is doing some implicit offset that makes it impossible to control which month gets displayed by passing in a target value. Now I'm trying to get June to be on the left by calling changeMonth(5) again but it won't happen. The offset seems to get worse the more calendars I put on the screen.

The only workaround seems to be some hack where I keep track of the last month I clicked and write some offset logic to fix the bug myself.

() => {
  const [startDate, setStartDate] = useState(new Date());
  return (
    <DatePicker
      renderCustomHeader={({
        monthDate,
        customHeaderCount,
        decreaseMonth,
        increaseMonth,
        changeMonth
      }) => (
        <div>
          <button
            aria-label="Previous Month"
            className={
              "react-datepicker__navigation react-datepicker__navigation--previous"
            }
            style={customHeaderCount === 1 ? { visibility: "hidden" } : null}
            onClick={decreaseMonth}
          >
            <span
              className={
                "react-datepicker__navigation-icon react-datepicker__navigation-icon--previous"
              }
            >
              {"<"}
            </span>
          </button>
          <button onClick={() => {changeMonth(5)}}>Jump to June</button>
          <span
          className="react-datepicker__current-month">
            {monthDate.toLocaleString("en-US", {
              month: "long",
              year: "numeric",
            })}
          </span>
          <button
            aria-label="Next Month"
            className={
              "react-datepicker__navigation react-datepicker__navigation--next"
            }
            style={customHeaderCount === 0 ? { visibility: "hidden" } : null}
            onClick={increaseMonth}
          >
            <span
              className={
                "react-datepicker__navigation-icon react-datepicker__navigation-icon--next"
              }
            >
              {">"}
            </span>
          </button>
        </div>
      )}
      selected={startDate}
      onChange={(date) => setStartDate(date)}
      monthsShown={2}
    />
  );
};

Expected behavior
Calling changeMonth(5) should always put June on the left. Jumping to a month, when in a sequence of calendars, should have a consistent defintion of what changing a month means.

Screenshots

  1. Open the calendar.
    datepicker-bug-1
  2. Click the "jump to June" button
    datepicker-bug-2
  3. Click a day in July
    datepicker-bug-3
  4. Click the "jump to June" button again. Observe how June is now on the right and not the left, and July is no longer visible.
    datepicker-bug-4

Desktop (please complete the following information):

  • OS: Windows
  • Browser: all browsers
  • Version: latest

Smartphone (please complete the following information):

  • Device: N/A
  • OS: N/A
  • Browser N/A
  • Version N/A

Additional context
N/A

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions