The Making of Dooboo-UI’s Calendar Carousel

Jessie Lee
dooboolab
Published in
8 min readAug 19, 2020

My experience creating a Calendar with react-native @dooboolab

Starting from July 2020, I had the incredible opportunity to intern @dooboolab , a IT tech startup that also maintains a widely used React-Native open-source library, dooboo-ui .

For my first task, I was asked to create a new Calendar Component for dooboo-ui . This is what the final version of the Calendar Carousel looks like.

The CalendarCarousel is a React- Native UI that allows users to swipe through the dates infinitely, mark days with events, and note what today’s date is.

This post will summarize the process I went through in making the CalendarCarousel for dooboo-ui. The code is available down here.

path info

../dooboo-ui/packages/CalendarCarousel/index.tsx../dooboo-ui/stories/packages/CalendarCarousel.stories.tsx

How I created the Calendar Carousel

I will now go through each of the parts in the CalendarCarousel to explain how the components are created. If you want to gain an even more thorough understanding of the CalendarCarousel, go to dooboo-ui and download the source code! You can look through the source code and this article side-by-side.

What the CalendarCarousel index.tsx returns

At the end, the main CalendarCarousel function returns three functions called renderCalendar() wrapped in a ScrollView.

To put it simply, it looks like this.

renderCalendar()

So basically, the Calendars are rendered through the function renderCalendar(). It does these things.

  • print Month Name
  • print year
  • print dates of the Calendar

Now I will explain how each of these things are done. First let’s start with the monthName.

How is the MonthName printed?

The monthName here is printed using Intl also known as ECMAScript Internationalization API, which provides language sensitive string comparison, number formatting, and date and time formatting. Here, the displayDate is taken in as a parameter and and returns the name of the month in a long format.

How are the Year and Dates Printed?

The year and the date are printed using the javascript Date Object. Check the link to understand how the javascript Date Object works.

Why new Date() and not Moment?

Many people ask about the reason behind choosing javascript Date object to print out the dates instead of using the moment library. To put it short, I used date because it is in javascript by default and therefore much lighter. To use moment, I have to import its library.

Year

This is the code for the year printed underneath the month name. getFullYear() returns the year of the displayDate as a number.

const year = displayDate.getFullYear();

Dates

The dates are a little bit more complicated. I divided the dates into three parts.

  • prevDates
  • currentDates
  • nextDates

prevDates

The weekdays in javascript Date have index numbers 0~6. To print the prevDates, I get the weekday index of the currentDate and save that in firstWeekday like below.

const firstWeekday = new Date(year, month, 1).getDay();

Then, create an empty array and push the prevDates backwards using the unshift method.

const prevDates = [];for (let idx = 0; idx < firstWeekday; idx++) {       const date = new Date(year, month, 0);       date.setDate(date.getDate() - idx);       prevDates.unshift(date);}

(currentMonth)Dates

To get the dates of the current month, I save the last day of that month in lastDate.

const lastDate = new Date(year, month + 1, 0).getDate();

Then the dates are pushed into the empty dates array.

const dates = [];for (let idx = 1; idx <= lastDate; idx++) {       dates.push(new Date(year, month, idx));}

nextDates

To get the dates of the next month, I save the last weekday in lastWeekday.

const lastWeekday = new Date(year, month, lastDate).getDay();

Then the dates are pushed into empty nextDates array.

const nextDates = [];if (6 - lastWeekday >= 1) {for (let idx = 1; idx <= 6 - lastWeekday; idx++) {      nextDates.push(new Date(year, month + 1, idx));}}

Note that for all of these three parts, Date objects (not numbers) are pushed into the array. After each array is created, these arrays are all pushed in the calendarDates.

How are Weekdays Printed?

Here the weekdays are printed using toLocaleString(), a function that exists in javascript Date object. I used the matchMonth as June of 2020 because its weekdays fit the default weekdays I wanted to set.

In toLocaleString(), the ‘narrow’ will print the weekdays in one letter. The ‘default’ section sets the language. By setting it to default, it will render the weekdays as any default language set in the user’s computer.

How renderCalendar() prints the Calendar

The monthName, year, and Dates are rendered inside the function renderCalendar() and returned at the end like below.

Calendar Carousel Features

From the image, below, you can see that when the renderCalendar() is called, other functions like changeMonth() renderDates() and renderDayEvents() are called too.

To explain it simply,

  • changeMonth() — changes month when arrow button is pressed
  • renderDates() — render effects that will be placed on dates such as days with events, selected dates, and today’s date.
  • renderEvent() — renders the event text saved on that day.

Display Features in renderDates()

The display features that this Calendar has can be summarized into three parts.

  • isSelected() — light blue display change with date is clicked on
isSelected() : when a user clicks on a date
  • isToday() — blue display on current date
isToday(): displays currentDate wit ha blue circle
  • hasEvent() — small circle mark on dates with events.
hasEvent(): marks a date with an event with a small blue circle

I will explain each of these parts . But first, note that renderDates() is called within the FlatList and takes each of the Date objects inside of the data calendarDates and checks if they are values that should have a different display.

A closer look into the code looks like this.

isSelected()

isSelected()

This feature is the click feature that displays a light blue circle when the user clicks on a random date in the Calendar.

This is what the code looks like.

You may be wondering what the parameter itemDay() is.

const itemDay = dateItem.getDate();

isToday()

isToday()

This feature displays the current Date with a blue circle. The dateItem here is each of the Date objects in calendarDates.

hasEvent()

hasEvent()

The markedDates, Months, and Years are defined like this. They take the date, month, and year of a selectedEventDate in markedDayEvents.

markedDayEvents here is an Object data array that looks like this. It is called as a Props. Currently this is set as default values as below.

ScrollingFeatures

There are two ways to swipe through this Calendar.

  • With the arrow buttons — changeMonth()
  • By swiping — ScrollView

changeMonth()

If the previous arrow button is pressed, then toPrevMonth is set as true and the currentDate is updated to the previousMonth.

ScrollView

ScrollView is wrapped around three renderCalendar() functions. We call three renderCalendar() functions because ScrollView requires that it wraps the data that it will scroll through.

For one of the props, onMomentumScrollEnd, ScrollView receives the function scrollEffect is called.

contentOffset — Used to manually set the starting scroll offset. The default value is {x: 0, y: 0}.

layoutWidth — I have set this as default to 330 which is the middle calendar, the calendar with the currentDate.

scrollEffect()

scrollEffect() takes in a native event as a parameter. By ‘event’ I am referring to event where the user scrolls left or right. It looks into the event and sees what properties it currently holds and updates the calendar on scroll based on that.

If the xValue ( contentOffset of x ) is equal to 0 it means that the user had scrolled to the previousMonth section. Then we scroll to the middle of the calendar and set the currentDate the the previous Month.

If the xValue is equal to twice the length of the layoutWidth, it means that the user is in the nextMonth section. Then we scroll to the middle of the calendar and set the currentDate the the next Month.

renderEvent()

One final function we should look over is the renderEvent() function that will be called when the user clicks on a day with a marked event.

With this I have covered how the CalendarCarousel is created. If you have any more questions, please feel free to contact me! :)

Contribute to the CalendarCarousel!

Dooboo-UI is an open source project which means that anyone can download the code and make PR requests to improve the current code, or add new features to this code.

  • web ScrollView feature
  • select Day range
  • add events
  • customize events

Well that’s it for now feel free to ask any questions! Stay Safe!

--

--