/ build a calendar from scratch
Build a calendar from scratch

Build a calendar from scratch

Calendar components are quite popular in every ui library. So the case with react but sometimes we cannot find exact the one we need that fit to our setup due to choices of css lib for example. So today I will go through how we can build a calendar from scratch with tailwind css.

September 20, 2024


Build a calendar from scratch with react and tailwind css.

Calendar components are very popular and we can easily get a lib from npm. However calendar components can be also a hard one to style due to it comes with a set of builtin css. So we can build a calendar on our own to fit what we need and what we have set up.

Getting started.

The calendar I built in this post can be found here https://maxaledigheten.info/.

Install dependencies

It is actually not so difficult to build a calendar. First we need to install libraries for building this.

  • tailwindcss for ui css.
  • dayjs for working with datime.

Build a month calendar

In the application we render 12 months calendar. The core component here is a month calendar. The month calendar takes only two props month and year which is quite straightforward. The component will look like this

<MonthCalendar year={2022} month={4} key={4} />

We will start with week days to render

const today = dayjs().set('year', year);
const startWeek = today.startOf("isoWeek");
const weekDays = Array.from(new Array(7).keys()).map((index) => {
    return startWeek.add(index, "day");
  });


We get number of days in the month to render

const startOfMonth = today.set("month", month).startOf("month");
  const startOfFirstWeek = startOfMonth.startOf("isoWeek");
  const daysToFirstDay = startOfMonth.diff(startOfFirstWeek, "day");
  const daysToPrepend = Array.from(new Array(daysToFirstDay).keys());
  const daysInMonth = Array.from(new Array(startOfMonth.daysInMonth()).keys());


  • daysToPrepend is the number of days in the first week of the month but from the previous month.

Last step is to gather data and then render

<div className="grid grid-cols-7 mt-2 rounded-md border overflow-hidden flex-1"> 
 {weekDays.map((weekDay, index) => (
          <div className="text-center" key={`weekday_${index}`}>
            {weekDay.format("ddd")}
          </div>
        ))}
{daysToPrepend.map((day) => (
          <div key={`prepend_${day}`}></div>
        ))}
{daysInMonth.map((day) => {
          const key = getDate(startOfMonth, day);
          return (
            <div
              className={`text-center `}
              key={key}
            >
              {day + 1}
            </div>
          )
        })}
</div>

  • so we use a grid of 7 columns which corresponds to 7 days in a week.
  • to render days in the right order we need to compensate with daysToPrepend.

TLDR

with the help of tailwind css and dayjs so to build a calendar component is quite simple and straightforward. Life is getting easier when we have the help from grid also.

Back to blog