javascripthtmlcssflatpickr

How to make height transition for flatpick?


I use https://flatpickr.js.org/

My code

const datepicker = flatpickr("#datepicker", {
  inline: true,
  dateFormat: "Y-m-d",
  onMonthChange: function (selectedDates, dateStr, instance) {
    instance.set("disable", [
      function (date) {
        return date.getMonth() !== instance.currentMonth;
      }
    ]);
    updateCalendarDisplay(instance, false);
  },
  onReady: function (selectedDates, dateStr, instance) {
    updateCalendarDisplay(instance, false);
  },
  onChange: function (selectedDates, dateStr, instance) {
    updateCalendarDisplay(instance, true);
  }
});

function updateCalendarDisplay(instance, isDateChanged) {
  setTimeout(() => {
    const calendarContainer = instance.calendarContainer;
    if (!calendarContainer) return;

    const allDays = calendarContainer.querySelectorAll(".flatpickr-day");
    const rowsWithClass = calendarContainer.querySelectorAll(
      ".is-date-one-row"
    );

    let rowStart = 0;
    let rowEnd = 6;
    let isLastRowNextMonth = true;
    let totalRows = 0;

    for (let i = 0; i < allDays.length; i++) {
      const day = allDays[i];

      if (i >= rowStart && i <= rowEnd) {
        if (!day.classList.contains("nextMonthDay")) {
          isLastRowNextMonth = false;
        }
      }

      if (i === rowEnd) {
        totalRows++;

        if (isLastRowNextMonth) {
          for (let j = rowStart; j <= rowEnd; j++) {
            allDays[j].parentElement.classList.add("is-date-one-row");
          }
        } else {
          for (let j = rowStart; j <= rowEnd; j++) {
            allDays[j].parentElement.classList.remove("is-date-one-row");
          }
        }

        rowStart = i + 1;
        rowEnd = i + 7;
        isLastRowNextMonth = true;
      }
    }
  }, 10);
}
body {
  background: #000;
}

.is-date-one-row .prevMonthDay:nth-last-of-type(1),
.is-date-one-row .prevMonthDay:nth-last-of-type(2),
.is-date-one-row .prevMonthDay:nth-last-of-type(3),
.is-date-one-row .prevMonthDay:nth-last-of-type(4),
.is-date-one-row .prevMonthDay:nth-last-of-type(5),
.is-date-one-row .prevMonthDay:nth-last-of-type(6),
.is-date-one-row .prevMonthDay:nth-last-of-type(7),
.is-date-one-row .nextMonthDay:nth-last-of-type(1),
.is-date-one-row .nextMonthDay:nth-last-of-type(2),
.is-date-one-row .nextMonthDay:nth-last-of-type(3),
.is-date-one-row .nextMonthDay:nth-last-of-type(4),
.is-date-one-row .nextMonthDay:nth-last-of-type(5),
.is-date-one-row .nextMonthDay:nth-last-of-type(6),
.is-date-one-row .nextMonthDay:nth-last-of-type(7) {
  opacity: 0;
  display: none;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
<script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>

<input type="text" id="datepicker">

This datepicker always displays dates in 6 rows, because of this sometimes a whole row of dates of another month is displayed.

enter image description here

The result I would like to get

enter image description here

I changed the number of lines with this function updateCalendarDisplay, but now when choosing a date or switching a month, the calendar jumps

This happens when there are less than 6 rows, but when there are 6 rows, the calendar works correctly (For example, if you select August)

Thank you, I will be glad for any help


Solution

  • If you want to achieve this using only CSS, then find the closest .nextMonthDay at the beginning of the week, and hide it and the days after:

    const datepicker = flatpickr("#datepicker", {
      inline: true,
      dateFormat: "Y-m-d",
    });
    body {
      background: #000;
    }
    
    .flatpickr-day:nth-child(7n + 1).nextMonthDay {
      display: none;
      & ~ .nextMonthDay {
        display: none;
      }
    }
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
    <script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>
    
    <input type="text" id="datepicker">