Introduction
React Calendar component supporting Jalali and Gregorian, with full customization.
Calendar Component
The Calendar component is a flexible React calendar that supports both Gregorian and Jalali calendars.
It allows full customization via props, classNames, and components.
npm i react-evently-calendarexamples
This is a simple example of how to use the calendar with the default style.
SatSunMonTueWedThuFri
29 November301 December23456789101112131415161718192021222324252627282930311 January2
"use client";
import { Calendar as EventlyCalendar } from "react-evently-calendar";
const Calendar = () => {
return (
<EventlyCalendar />
); }; export default Calendar;But this style is quite plain, so the option is provided for users to customize it however they want.
شنبهیکشنبهدوشنبهسهشنبهچهارشنبهپنجشنبهجمعه
1آذر
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
جلسه تیم
30
2دی
3
4
ملاقات مشتری
5
6
"use client";
import dayjs from "dayjs";
import { Calendar } from "react-evently-calendar";
import jalali from "jalali-plugin-dayjs";
import { useEffect, useRef, useState } from "react";
dayjs.extend(jalali);
export const monthsFa = [
"فروردین",
"اردیبهشت",
"خرداد",
"تیر",
"مرداد",
"شهریور",
"مهر",
"آبان",
"آذر",
"دی",
"بهمن",
"اسفند",
];
const events = [
{
id: 1,
title: "جلسه تیم",
date: dayjs().add(1, "day").toDate(),
},
{
id: 2,
title: "ملاقات مشتری",
date: dayjs().add(5, "day").toDate(),
},
];
const CustomRenderDayCalander = () => {
const dayRefs = useRef<Record<string, HTMLDivElement | null>>({});
const [hiddenEvents, setHiddenEvents] = useState<Record<string, boolean>>({});
const checkWidths = () => {
const newHidden: Record<string, boolean> = {};
Object.entries(dayRefs.current).forEach(([key, el]) => {
if (!el) return;
newHidden[key] = el.offsetWidth < 90;
});
setHiddenEvents(newHidden);
};
useEffect(() => {
checkWidths();
window.addEventListener("resize", checkWidths);
return () => window.removeEventListener("resize", checkWidths);
}, []);
return (
<Calendar
CalendarType="jalali"
firstDayOfWeek={6}
dir="rtl"
renderDay={(
day,
date,
isCurrentMonth,
showMonth,
isToday,
CustomOnSelect
) => {
const dayEvents = events.filter((event) =>
dayjs(event.date).isSame(dayjs(date), "day")
);
const dayKey = dayjs(date).format("YYYY-MM-DD");
return (
<div
ref={(el) => {
dayRefs.current[dayKey] = el;
}}
key={dayKey}
className={`
text-start p-0.5 aspect-[3/2] m-0.25 rounded-lg cursor-pointer text-[0.8rem] overflow-hidden
${
isToday
? "bg-[#8f8f8fff] dark:bg-[#3385ff] text-black dark:text-white"
: isCurrentMonth
? "bg-[#c9c9c9ff] dark:bg-[#96bbf8] text-white font-bold"
: "bg-[#ebebebff] dark:bg-[#838383] text-black dark:text-gray-300 font-normal"
}
`}
onClick={() => CustomOnSelect()}
>
<div className="flex flex-row gap-0.5 flex-wrap">
<span>
{day}
{showMonth
? monthsFa[dayjs(date).calendar("jalali").month()]
: null}
</span>
{dayEvents.length > 0 &&
(hiddenEvents[dayKey] ? (
<div className="w-2 h-2 bg-amber-400 rounded-full m-2 mr-auto" />
) : (
dayEvents.map((event) => (
<div
key={event.id}
className="w-full p-[1px] text-[0.7rem] bg-[#ecececff] dark:bg-[#2a2a2a] rounded-[0.4rem] text-black dark:text-gray-200"
>
{event.title}
</div>
))
))}
</div>
</div>
);
}}
/>
);
};
export default CustomRenderDayCalander;
Thanks to the renderDay prop, you have the ability to implement anything you can imagine.