Functional Tailwind calendar component with the help from ChatGPT
I was super excited when TailwindUI released their calendar components. Calendars can be a tricky UI element to implement so having the blessings from Lord Adam and team really helped. The only problem was... it didn't navigate back and forth as a normal calendar would.
As I have grown itnerest in seeing how these LM's like ChatGPT and GitHub CoPilot fit within our developer ecosystem, I figured I would give ChatGPT a shot at construncting the "functional" piece of this component.
This is what we will be building:
If you look at the component prior to scrolling, this is roughly what you get from the TailwindUI library. While it's beautiful, it doesn't necessarily function! In order to do this, I figured, why not ask ChatGPT.
With it's first shot, it got pretty dang close. I noticed it had some trouble with the calculations I wanted for previous and next month dates that surround the current month (since no months have 42 dates, duh). Within 10 minutes of fidgetting with the code, you ended up with a pretty clean function:
// This entire function was written by ChatGPT
const generateDays = (givenDate: Date): CalendarDate[] => {
// Get the month and year of the given date
let month = givenDate.getMonth()
let year = givenDate.getFullYear()
// Get the number of days in the month of the given date
let numDaysInMonth = new Date(year, month + 1, 0).getDate()
// Initialize the array of objects
let dates: CalendarDate[] = []
// Calculate the number of dates to include from the previous month
let numDatesFromPrevMonth = new Date(year, month, 1).getDay()
if (numDatesFromPrevMonth === 0) numDatesFromPrevMonth = 7 // If the given date is a Sunday, include 0 dates from the previous month
// Get the month and year of the previous month
let prevMonth = month - 1
let prevYear = year
if (prevMonth < 0) {
prevMonth = 11
prevYear--
}
let numDaysInPrevMonth = new Date(year, month, 0).getDate()
// Add the dates from the previous month to the array
for (let i = numDatesFromPrevMonth - 1; i >= 0; i--) {
let date = new Date(prevYear, prevMonth, numDaysInPrevMonth - i)
let dateObject: CalendarDate = {
date: date,
isCurrentMonth: false,
isToday: false,
isSelected: areDatesEqual(date, givenDate),
}
dates.push(dateObject)
}
// Add the dates from the current month to the array
let today = new Date()
for (let i = 1; i <= numDaysInMonth; i++) {
let date = new Date(year, month, i)
let dateObject = {
date: date,
isCurrentMonth: true,
isToday: areDatesEqual(date, today),
isSelected: areDatesEqual(date, givenDate),
}
dates.push(dateObject)
}
// Calculate the number of dates to include from the next month
let numDatesFromNextMonth = 42 - dates.length
// Get the month and year of the next month
let nextMonth = month + 1
let nextYear = year
if (nextMonth > 11) {
nextMonth = 0
nextYear++
}
// Add the dates from the next month to the array
for (let i = 1; i <= numDatesFromNextMonth; i++) {
let date = new Date(nextYear, nextMonth, i)
let dateObject = {
date: date,
isCurrentMonth: false,
isToday: false,
isSelected: areDatesEqual(date, givenDate),
}
dates.push(dateObject)
}
return dates
}
While I am sure there are some enhancements you could make to the function, it was pretty amazing to go from UI design to a functioning component in < 20 minutes!