Skip to content

Instantly share code, notes, and snippets.

@liaujianjie
Created August 6, 2021 14:51
Show Gist options
  • Save liaujianjie/1f2dab15de17783cca14d81a971e0184 to your computer and use it in GitHub Desktop.
Save liaujianjie/1f2dab15de17783cca14d81a971e0184 to your computer and use it in GitHub Desktop.
shiok shiok satay
import { add, getDay, getMonth, getYear, isLastDayOfMonth, sub } from "date-fns";
import { chunk } from "lodash";
import { Dispatch, SetStateAction, useState } from "react";
type CalendarView = "month";
type UseCalendarOptions = {
view: CalendarView;
/**
* Indicates if the week should start on Monday instead of Sunday. Defaults to starting on Sunday.
* @default false
*/
startWeekOnMonday?: boolean;
};
type UseCalendarReturnValue = {
view: "month";
days: number[];
firstDateOfMonth: Date;
dates: Date[];
datesByWeek: Date[][];
date: Date;
setDate: Dispatch<SetStateAction<Date>>;
};
export function useCalendar({
view = "month",
startWeekOnMonday = false,
}: UseCalendarOptions): UseCalendarReturnValue {
const [date, setDate] = useState(new Date());
const firstDateOfMonth = new Date(date);
firstDateOfMonth.setDate(1);
const dates: Date[] = [firstDateOfMonth];
// Create array containing all the dates in the month.
while (!isLastDayOfMonth(dates[dates.length - 1])) {
const lastDateAdded = dates[dates.length - 1];
dates.push(add(lastDateAdded, { days: 1 }));
}
// Then, pad the front to start the dates with sunday/monday depending on startWeekOnMonday.
while (getDay(dates[0]) !== (startWeekOnMonday ? 1 : 0)) {
const firstDateAdded = dates[0];
dates.unshift(sub(firstDateAdded, { days: 1 }));
}
// Then, pad the end to make sure we have a total of 6 weeks in the array.
while (dates.length < 7 * 6) {
const lastDateAdded = dates[dates.length - 1];
dates.push(add(lastDateAdded, { days: 1 }));
}
return {
view: "month",
date,
setDate,
days: startWeekOnMonday ? [1, 2, 3, 4, 5, 6, 0] : [0, 1, 2, 3, 4, 5, 6],
firstDateOfMonth,
dates,
datesByWeek: chunk(dates, 7),
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment