Last active
February 14, 2022 13:44
-
-
Save willmanduffy/a62a88cb2b3902e09d8f333906a65032 to your computer and use it in GitHub Desktop.
Calendar Generation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { | |
| endOfMonth, | |
| getDay, | |
| getDaysInMonth, | |
| getWeeksInMonth, | |
| startOfMonth, | |
| } from 'date-fns'; | |
| import takeRight from 'lodash/takeRight'; | |
| const NUMBER_OF_CALENDAR_ROWS = 6; | |
| export const daysOfCurrentMonth = (calendarDate: Date): number[] => { | |
| const numberOfDaysInMonth = getDaysInMonth(calendarDate); | |
| // Generate an array of the all of days in the month: | |
| // ex. [1, 2, 3, 4, ..., 31] | |
| return Array.from(Array(numberOfDaysInMonth).keys()).map((day) => day + 1); | |
| }; | |
| export const daysOfPreviousMonth = ( | |
| calendarDate: Date, | |
| previousMonth: Date | |
| ): number[] => { | |
| const numberOfDaysInPreviousMonth = getDaysInMonth(previousMonth); | |
| // Find the number of days in the week before the first day of the current calendar month. For | |
| // example, if the first of the month is on a Tuesday then we will return 2 (referring to Sunday | |
| // and Monday). | |
| const daysBeforeFirstDayOfMonth = getDay(startOfMonth(calendarDate)); | |
| // Generate an array of the last days of the previous month using the daysBeforeFirstDayOfMonth | |
| // If the previous month has 31 days and daysBeforeFirstDayOfMonth is 2 we will return [30, 31] | |
| const allDaysOfPreviousMonth = Array.from( | |
| Array(numberOfDaysInPreviousMonth).keys() | |
| ).map((day) => day + 1); | |
| return takeRight(allDaysOfPreviousMonth, daysBeforeFirstDayOfMonth); | |
| }; | |
| export const daysOfNextMonth = (calendarDate: Date): number[] => { | |
| let daysAfterLastDayOfMonth: number; | |
| const numberOfWeeksInCurrentMonth = getWeeksInMonth(calendarDate); | |
| const lastDayOfTheMonth = endOfMonth(calendarDate); | |
| // Get the number of days in the week after the last day of the month | |
| // The 6 is confusing, but it's just working off of week indicies that start at 0, so it's the | |
| // representation of 7 days in the week: 0, 1, 2, 3, 4, 5, 6 | |
| daysAfterLastDayOfMonth = 6 - getDay(lastDayOfTheMonth); | |
| // We always want to display 6 rows in our calendar. Add the number of days that's needed to fill | |
| // out 6 rows if we have not done so yet. | |
| if (numberOfWeeksInCurrentMonth !== NUMBER_OF_CALENDAR_ROWS) { | |
| const weeksToAdd = NUMBER_OF_CALENDAR_ROWS - numberOfWeeksInCurrentMonth; | |
| daysAfterLastDayOfMonth = daysAfterLastDayOfMonth + weeksToAdd * 7; | |
| } | |
| // Generate an array of the first days of the next month. If we want to display the first 8 days | |
| // of the next month we would return [1, 2, 3, 4, 5, 6, 7, 8] | |
| return Array.from(Array(daysAfterLastDayOfMonth).keys()).map( | |
| (day) => day + 1 | |
| ); | |
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const Calendar = () => ( | |
| <div className="grid grid-cols-7 justify-items-center gap-0.5"> | |
| {daysOfPreviousMonth(calendarDate, previousMonth).map((day) => ( | |
| <Day calendarDate={calendarDate} day={day} classes="text-gray-400" /> | |
| ))} | |
| {daysOfCurrentMonth(calendarDate).map((day) => ( | |
| <Day | |
| calendarDate={calendarDate} | |
| selectedDate={selectedDate} | |
| day={day} | |
| /> | |
| ))} | |
| {daysOfNextMonth(calendarDate).map((day) => ( | |
| <Day calendarDate={calendarDate} day={day} classes="text-gray-400" /> | |
| ))} | |
| </div> | |
| ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment