nepali-date-utility
Version:
A beautiful React date picker component with other date utilities for Nepali Bikram Sambat calendar
809 lines (803 loc) • 28.4 kB
JavaScript
import { useState, useRef, useEffect } from 'react';
import { jsxs, jsx } from 'react/jsx-runtime';
import { twMerge, twJoin } from 'tailwind-merge';
// Nepali Date Utility- Beautiful React component for Nepali Bikram Sambat calendar
// src/data/bs-calendar.ts
var bsCalendarData = {
2e3: [30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
2001: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2002: [31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
2003: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
2004: [30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
2005: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2006: [31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
2007: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
2008: [31, 31, 31, 32, 31, 31, 29, 30, 30, 29, 29, 31],
2009: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2010: [31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
2011: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
2012: [31, 31, 31, 32, 31, 31, 29, 30, 30, 29, 30, 30],
2013: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2014: [31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
2015: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
2016: [31, 31, 31, 32, 31, 31, 29, 30, 30, 29, 30, 30],
2017: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2018: [31, 32, 31, 32, 31, 30, 30, 29, 30, 29, 30, 30],
2019: [31, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
2020: [31, 31, 31, 32, 31, 31, 30, 29, 30, 29, 30, 30],
2021: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2022: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 30],
2023: [31, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
2024: [31, 31, 31, 32, 31, 31, 30, 29, 30, 29, 30, 30],
2025: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2026: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
2027: [30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
2028: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2029: [31, 31, 32, 31, 32, 30, 30, 29, 30, 29, 30, 30],
2030: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
2031: [30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
2032: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2033: [31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
2034: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
2035: [30, 32, 31, 32, 31, 31, 29, 30, 30, 29, 29, 31],
2036: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2037: [31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
2038: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
2039: [31, 31, 31, 32, 31, 31, 29, 30, 30, 29, 30, 30],
2040: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2041: [31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
2042: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
2043: [31, 31, 31, 32, 31, 31, 29, 30, 30, 29, 30, 30],
2044: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2045: [31, 32, 31, 32, 31, 30, 30, 29, 30, 29, 30, 30],
2046: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
2047: [31, 31, 31, 32, 31, 31, 30, 29, 30, 29, 30, 30],
2048: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2049: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 30],
2050: [31, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
2051: [31, 31, 31, 32, 31, 31, 30, 29, 30, 29, 30, 30],
2052: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2053: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 30],
2054: [31, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
2055: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2056: [31, 31, 32, 31, 32, 30, 30, 29, 30, 29, 30, 30],
2057: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
2058: [30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
2059: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2060: [31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
2061: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
2062: [30, 32, 31, 32, 31, 31, 29, 30, 29, 30, 29, 31],
2063: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2064: [31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
2065: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
2066: [31, 31, 31, 32, 31, 31, 29, 30, 30, 29, 29, 31],
2067: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2068: [31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30],
2069: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
2070: [31, 31, 31, 32, 31, 31, 29, 30, 30, 29, 30, 30],
2071: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2072: [31, 32, 31, 32, 31, 30, 30, 29, 30, 29, 30, 30],
2073: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
2074: [31, 31, 31, 32, 31, 31, 30, 29, 30, 29, 30, 30],
2075: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2076: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 30],
2077: [31, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
2078: [31, 31, 31, 32, 31, 31, 30, 29, 30, 29, 30, 30],
2079: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2080: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 30],
2081: [31, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
2082: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2083: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2084: [31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31],
2085: [30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31],
2086: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
2087: [31, 31, 32, 31, 31, 31, 30, 30, 29, 30, 30, 30],
2088: [30, 31, 32, 32, 30, 31, 30, 30, 29, 30, 30, 30],
2089: [30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 30, 30],
2090: [30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 30, 30]
};
var bsMonthsEn = [
"Baishakh",
"Jestha",
"Ashadh",
"Shrawan",
"Bhadra",
"Ashwin",
"Kartik",
"Mangsir",
"Poush",
"Magh",
"Falgun",
"Chaitra"
];
var bsMonthsNe = [
"\u092C\u0948\u0936\u093E\u0916",
"\u091C\u0947\u0937\u094D\u0920",
"\u0906\u0937\u093E\u0922",
"\u0936\u094D\u0930\u093E\u0935\u0923",
"\u092D\u093E\u0926\u094D\u0930",
"\u0906\u0936\u094D\u0935\u093F\u0928",
"\u0915\u093E\u0930\u094D\u0924\u093F\u0915",
"\u092E\u0902\u0938\u093F\u0930",
"\u092A\u094C\u0937",
"\u092E\u093E\u0918",
"\u092B\u093E\u0932\u094D\u0917\u0941\u0928",
"\u091A\u0948\u0924\u094D\u0930"
];
var bsDaysEn = [
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday"
];
var bsDaysNe = [
"\u0906\u0907\u0924\u092C\u093E\u0930",
"\u0938\u094B\u092E\u092C\u093E\u0930",
"\u092E\u0902\u0917\u0932\u092C\u093E\u0930",
"\u092C\u0941\u0927\u092C\u093E\u0930",
"\u092C\u093F\u0939\u093F\u092C\u093E\u0930",
"\u0936\u0941\u0915\u094D\u0930\u092C\u093E\u0930",
"\u0936\u0928\u093F\u092C\u093E\u0930"
];
var bsDaysShortEn = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
var bsDaysShortNe = [
"\u0906\u0907\u0924",
"\u0938\u094B\u092E",
"\u092E\u0902\u0917\u0932",
"\u092C\u0941\u0927",
"\u092C\u093F\u0939\u093F",
"\u0936\u0941\u0915\u094D\u0930",
"\u0936\u0928\u093F"
];
var nepaliDigits = ["\u0966", "\u0967", "\u0968", "\u0969", "\u096A", "\u096B", "\u096C", "\u096D", "\u096E", "\u096F"];
function toNepaliDigits(num) {
return num.toString().split("").map((c) => {
if (c >= "0" && c <= "9") {
return nepaliDigits[parseInt(c)];
}
return c;
}).join("");
}
// src/utils/converter.ts
var bsEpoch = { year: 2e3, month: 1, day: 1 };
var adEpoch = new Date(1943, 3, 14);
function daysBetweenDates(d1, d2) {
const date1 = new Date(d1.getFullYear(), d1.getMonth(), d1.getDate());
const date2 = new Date(d2.getFullYear(), d2.getMonth(), d2.getDate());
const msPerDay = 1e3 * 60 * 60 * 24;
return Math.round((date2.getTime() - date1.getTime()) / msPerDay);
}
function convertADToBS(adDate) {
const diffDays = daysBetweenDates(adEpoch, adDate);
let bsYear = bsEpoch.year;
let bsMonth = bsEpoch.month;
let bsDay = bsEpoch.day;
let remainingDays = diffDays;
while (remainingDays > 0) {
if (!bsCalendarData[bsYear]) {
throw new Error(
`Year ${bsYear} is outside the supported range (2000-2090)`
);
}
const daysInMonth = bsCalendarData[bsYear][bsMonth - 1];
if (typeof daysInMonth !== "number") {
throw new Error(
`Invalid calendar data for year ${bsYear}, month ${bsMonth}`
);
}
bsDay++;
if (bsDay > daysInMonth) {
bsDay = 1;
bsMonth++;
if (bsMonth > 12) {
bsMonth = 1;
bsYear++;
}
}
remainingDays--;
}
return { year: bsYear, month: bsMonth, day: bsDay };
}
function convertBSToAD(bsDate) {
let bsYear = bsEpoch.year;
let bsMonth = bsEpoch.month;
let bsDay = bsEpoch.day;
let adDate = new Date(adEpoch);
while (bsYear !== bsDate.year || bsMonth !== bsDate.month || bsDay !== bsDate.day) {
if (!bsCalendarData[bsYear]) {
throw new Error(
`Year ${bsYear} is outside the supported range (2000-2090)`
);
}
const daysInMonth = bsCalendarData[bsYear][bsMonth - 1];
if (typeof daysInMonth !== "number") {
throw new Error(
`Invalid calendar data for year ${bsYear}, month ${bsMonth}`
);
}
bsDay++;
adDate.setDate(adDate.getDate() + 1);
if (bsDay > daysInMonth) {
bsDay = 1;
bsMonth++;
if (bsMonth > 12) {
bsMonth = 1;
bsYear++;
}
}
}
return {
year: adDate.getFullYear(),
month: adDate.getMonth() + 1,
// JS months are 0-based, so add 1
day: adDate.getDate()
};
}
function getTodayBS() {
return convertADToBS(/* @__PURE__ */ new Date());
}
function getDaysInMonth(year, month) {
if (!bsCalendarData[year]) {
throw new Error(`Year ${year} is outside the supported range (2000-2090)`);
}
const daysInMonth = bsCalendarData[year][month - 1];
if (typeof daysInMonth !== "number") {
throw new Error(`Invalid calendar data for year ${year}, month ${month}`);
}
return daysInMonth;
}
function isValidBsDate(date) {
try {
const { year, month, day } = date;
if (!bsCalendarData[year]) return false;
if (month < 1 || month > 12) return false;
const daysInMonth = bsCalendarData[year][month - 1];
if (typeof daysInMonth !== "number") return false;
if (day < 1 || day > daysInMonth) return false;
return true;
} catch (error) {
return false;
}
}
function isDateInRange(date, minDate, maxDate) {
if (!isValidBsDate(date)) return false;
if (minDate && compareDates(date, minDate) < 0) return false;
if (maxDate && compareDates(date, maxDate) > 0) return false;
return true;
}
function compareDates(a, b) {
if (a.year !== b.year) return a.year - b.year;
if (a.month !== b.month) return a.month - b.month;
return a.day - b.day;
}
function getFirstDayOfMonth(bsYear, bsMonth) {
const bsDate = { year: bsYear, month: bsMonth, day: 1 };
const adDate = convertBSToAD(bsDate);
const jsDate = new Date(adDate.year, adDate.month - 1, adDate.day);
return jsDate.getDay();
}
function addMonths(date, months) {
let { year, month, day } = date;
month += months;
while (month > 12) {
month -= 12;
year++;
}
while (month < 1) {
month += 12;
year--;
}
const maxDays = getDaysInMonth(year, month);
if (day > maxDays) {
day = maxDays;
}
return { year, month, day };
}
// src/utils/formatter.ts
function formatDate(date, options = {}) {
const { format = "YYYY-MM-DD", locale = "en", separator = "-" } = options;
if (!date) return "";
const { year, month, day } = date;
const yearStr = year.toString();
const monthStr = month < 10 ? `0${month}` : month.toString();
const dayStr = day < 10 ? `0${day}` : day.toString();
let formatted = format.replace("YYYY", yearStr).replace("MM", monthStr).replace("DD", dayStr).replace("M", month.toString()).replace("D", day.toString());
if (format.includes("MMMM")) {
const monthNames = locale === "ne" ? bsMonthsNe : bsMonthsEn;
formatted = formatted.replace("MMMM", monthNames[month - 1]);
}
if (locale === "ne") {
formatted = formatted.split("").map((char) => {
if (char >= "0" && char <= "9") {
return nepaliDigits[parseInt(char)];
}
return char;
}).join("");
}
if (separator !== "-" && (format === "YYYY-MM-DD" || format === "DD-MM-YYYY")) {
formatted = formatted.replace(/-/g, separator);
}
return formatted;
}
function parseDate(dateStr, format = "YYYY-MM-DD") {
try {
if (format === "YYYY-MM-DD") {
const [yearStr, monthStr, dayStr] = dateStr.split("-");
return {
year: parseInt(yearStr, 10),
month: parseInt(monthStr, 10),
day: parseInt(dayStr, 10)
};
}
if (format === "DD-MM-YYYY") {
const [dayStr, monthStr, yearStr] = dateStr.split("-");
return {
year: parseInt(yearStr, 10),
month: parseInt(monthStr, 10),
day: parseInt(dayStr, 10)
};
}
if (format === "MM/DD/YYYY") {
const [monthStr, dayStr, yearStr] = dateStr.split("/");
return {
year: parseInt(yearStr, 10),
month: parseInt(monthStr, 10),
day: parseInt(dayStr, 10)
};
}
if (format === "YYYY/MM/DD") {
const [yearStr, monthStr, dayStr] = dateStr.split("/");
return {
year: parseInt(yearStr, 10),
month: parseInt(monthStr, 10),
day: parseInt(dayStr, 10)
};
}
return null;
} catch (error) {
return null;
}
}
var MonthNavigation = ({
viewDate,
onViewDateChange,
locale = "en"
}) => {
const [showYearDropdown, setShowYearDropdown] = useState(false);
const [showMonthDropdown, setShowMonthDropdown] = useState(false);
const monthNames = locale === "ne" ? bsMonthsNe : bsMonthsEn;
const handlePrevMonth = () => {
onViewDateChange(addMonths(viewDate, -1));
};
const handleNextMonth = () => {
onViewDateChange(addMonths(viewDate, 1));
};
const handleYearSelect = (year) => {
onViewDateChange({ ...viewDate, year });
setShowYearDropdown(false);
};
const handleMonthSelect = (month) => {
onViewDateChange({ ...viewDate, month });
setShowMonthDropdown(false);
};
const yearOptions = Array.from({ length: 91 }, (_, i) => 2e3 + i);
return /* @__PURE__ */ jsxs(
"div",
{
className: `flex items-center justify-between p-2 border-b border-gray-300`,
children: [
/* @__PURE__ */ jsx(
"button",
{
type: "button",
onClick: handlePrevMonth,
className: "p-1 rounded-md hover:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500",
"aria-label": "Previous month",
children: /* @__PURE__ */ jsx(
"svg",
{
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 20 20",
fill: "currentColor",
className: "w-5 h-5",
children: /* @__PURE__ */ jsx(
"path",
{
fillRule: "evenodd",
d: "M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z",
clipRule: "evenodd"
}
)
}
)
}
),
/* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-1", children: [
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
/* @__PURE__ */ jsx(
"button",
{
type: "button",
onClick: () => setShowMonthDropdown(!showMonthDropdown),
className: "px-2 py-1 rounded-md hover:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500 font-medium",
children: monthNames[viewDate.month - 1]
}
),
showMonthDropdown && /* @__PURE__ */ jsx("div", { className: "absolute z-10 mt-1 w-max bg-white shadow-lg max-h-60 rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm", children: monthNames.map((month, index) => /* @__PURE__ */ jsx(
"div",
{
onClick: () => handleMonthSelect(index + 1),
className: `cursor-pointer select-none relative py-2 pl-3 pr-9 hover:bg-indigo-200 font-medium ${viewDate.month === index + 1 ? "bg-indigo-500 text-white hover:bg-indigo-500" : ""}`,
children: month
},
month
)) })
] }),
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
/* @__PURE__ */ jsx(
"button",
{
type: "button",
onClick: () => setShowYearDropdown(!showYearDropdown),
className: "px-2 py-1 rounded-md hover:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500 font-medium",
children: locale === "ne" ? toNepaliDigits(viewDate.year) : viewDate.year
}
),
showYearDropdown && /* @__PURE__ */ jsx("div", { className: "absolute z-10 mt-1 w-max bg-white shadow-lg max-h-60 rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm", children: yearOptions.map((year) => /* @__PURE__ */ jsx(
"div",
{
onClick: () => handleYearSelect(year),
className: `cursor-pointer select-none relative py-2 pl-3 pr-9 hover:bg-indigo-200 ${viewDate.year === year ? "bg-indigo-500 text-white hover:bg-indigo-500" : ""}`,
children: locale === "ne" ? toNepaliDigits(year) : year
},
year
)) })
] })
] }),
/* @__PURE__ */ jsx(
"button",
{
type: "button",
onClick: handleNextMonth,
className: "p-1 rounded-md hover:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500",
"aria-label": "Next month",
children: /* @__PURE__ */ jsx(
"svg",
{
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 20 20",
fill: "currentColor",
className: "w-5 h-5",
children: /* @__PURE__ */ jsx(
"path",
{
fillRule: "evenodd",
d: "M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z",
clipRule: "evenodd"
}
)
}
)
}
)
]
}
);
};
var MonthNavigation_default = MonthNavigation;
var Calendar = ({
locale = "en",
selectedDate,
viewDate,
onDateSelect,
onViewDateChange,
minDate,
maxDate,
calendarClassName,
dayClassName,
selectedDayClassName,
todayClassName,
disabledDayClassName
}) => {
const firstDayOfMonth = getFirstDayOfMonth(viewDate.year, viewDate.month);
const daysInMonth = getDaysInMonth(viewDate.year, viewDate.month);
const generateCalendarDays = () => {
const days = [];
const dayNames = locale === "ne" ? bsDaysShortNe : bsDaysShortEn;
days.push(
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-7 mb-1", children: dayNames.map((day, index) => /* @__PURE__ */ jsx(
"div",
{
className: twMerge(
"relative h-8 w-8 flex items-center justify-center text-sm text-gray-800 font-medium hover:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500",
dayClassName
),
children: day
},
`day-name-${index}`
)) }, "day-names")
);
const totalCells = Math.ceil((daysInMonth + firstDayOfMonth) / 7) * 7;
let cells = [];
for (let i = 0; i < totalCells; i++) {
const dayOfMonth = i - firstDayOfMonth + 1;
const isCurrentMonth = dayOfMonth > 0 && dayOfMonth <= daysInMonth;
if (isCurrentMonth) {
const date = {
year: viewDate.year,
month: viewDate.month,
day: dayOfMonth
};
const isSelected = selectedDate && compareDates(selectedDate, date) === 0;
const isToday = compareDates(date, getTodayBS()) === 0;
const isInRange = isDateInRange(date, minDate, maxDate);
cells.push(
/* @__PURE__ */ jsx(
"button",
{
type: "button",
disabled: !isInRange,
onClick: () => isInRange && onDateSelect(date),
className: twJoin(
isSelected ? twMerge(
"text-white cursor-not-allowed bg-indigo-500",
selectedDayClassName
) : twMerge(
"relative h-8 w-8 flex items-center justify-center text-sm text-gray-800 font-medium hover:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500",
dayClassName
),
isToday && !isSelected ? twMerge(
"text-indigo-600 border-2 border-indigo-600 font-bold",
todayClassName
) : "",
isInRange && !isSelected ? "hover:bg-gray-300" : "",
!isInRange ? twMerge(
"opacity-50 cursor-not-allowed hover:bg-transparent ",
disabledDayClassName
) : ""
),
"aria-selected": isSelected ? "true" : "false",
children: locale === "ne" ? toNepaliDigits(dayOfMonth) : dayOfMonth
},
`day-${i}`
)
);
} else {
cells.push(/* @__PURE__ */ jsx("div", { className: "h-8 w-8" }, `empty-${i}`));
}
}
const weeks = [];
for (let i = 0; i < cells.length; i += 7) {
weeks.push(
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-7 gap-1", children: cells.slice(i, i + 7) }, `week-${i}`)
);
}
days.push(
/* @__PURE__ */ jsx("div", { className: "mt-2 space-y-1", children: weeks }, "calendar-grid")
);
return days;
};
return /* @__PURE__ */ jsxs(
"div",
{
className: twMerge(
"border border-gray-300 shadow-lg rounded-md bg-white",
calendarClassName
),
children: [
/* @__PURE__ */ jsx(
MonthNavigation_default,
{
viewDate,
onViewDateChange,
locale
}
),
/* @__PURE__ */ jsx("div", { className: "p-2", children: generateCalendarDays() })
]
}
);
};
var Calendar_default = Calendar;
var DateInput = ({
value,
onChange,
placeholder = "YYYY-MM-DD",
disabled = false,
formatOptions = { format: "YYYY-MM-DD" },
className,
onFocus,
onBlur
}) => {
const [inputValue, setInputValue] = useState(
value ? formatDate(value, formatOptions) : ""
);
const inputRef = useRef(null);
useEffect(() => {
if (value && isValidBsDate(value)) {
setInputValue(formatDate(value, formatOptions));
} else if (value === null) {
setInputValue("");
}
}, [value, formatOptions]);
const handleChange = (e) => {
const newValue = e.target.value;
setInputValue(newValue);
if (onChange) {
onChange(newValue);
}
};
const handleFocus = () => {
if (onFocus) {
onFocus();
}
};
const handleBlur = () => {
if (onBlur) {
onBlur();
}
};
return /* @__PURE__ */ jsx(
"input",
{
ref: inputRef,
type: "text",
value: inputValue,
onChange: handleChange,
onFocus: handleFocus,
onBlur: handleBlur,
placeholder,
disabled,
className: `${className}`
}
);
};
var DateInput_default = DateInput;
var DatePicker = ({
value,
onChange,
placeholder = "YYYY-MM-DD",
disabled = false,
minDate,
maxDate,
formatOptions = { format: "YYYY-MM-DD" },
className = "",
inputClassName = "",
calendarClassName = "",
dayClassName = "",
selectedDayClassName = "",
todayClassName = "",
disabledDayClassName = "",
position = "bottom"
}) => {
const [isOpen, setIsOpen] = useState(false);
const [viewDate, setViewDate] = useState(value || getTodayBS());
const [selectedDate, setSelectedDate] = useState(
value || null
);
const containerRef = useRef(null);
useEffect(() => {
if (value) {
setSelectedDate(value);
setViewDate(value);
}
}, [value]);
useEffect(() => {
const handleClickOutside = (event) => {
if (containerRef.current && !containerRef.current.contains(event.target)) {
setIsOpen(false);
}
};
document.addEventListener("mousedown", handleClickOutside);
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, []);
const handleDateSelect = (date) => {
setSelectedDate(date);
setIsOpen(false);
if (onChange) {
onChange(date);
}
};
const handleInputFocus = () => {
if (!disabled) {
setIsOpen(true);
}
};
const handleInputChange = (value2) => {
const date = parseDate(value2, formatOptions.format);
if (date && isValidBsDate(date)) {
setSelectedDate(date);
setViewDate(date);
if (onChange) {
onChange(date);
}
}
};
const getCalendarPosition = () => {
switch (position) {
case "top":
return "bottom-full mb-1";
case "bottom":
default:
return "top-full mt-1";
}
};
return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: `relative inline-block ${className}`, children: [
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
/* @__PURE__ */ jsx(
DateInput_default,
{
value: selectedDate,
onChange: handleInputChange,
onFocus: handleInputFocus,
placeholder,
disabled,
formatOptions,
className: twMerge(
"px-3 py-2 rounded-md shadow-sm block w-full border border-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500 pr-10",
inputClassName
)
}
),
/* @__PURE__ */ jsx(
"button",
{
type: "button",
onClick: () => !disabled && setIsOpen(!isOpen),
className: "absolute inset-y-0 right-0 pr-3 flex items-center text-gray-600 cursor-pointer hover:text-gray-800 disabled:opacity-50 disabled:cursor-not-allowed",
disabled,
"aria-label": "Toggle calendar",
children: /* @__PURE__ */ jsx(
"svg",
{
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 20 20",
fill: "currentColor",
className: "w-5 h-5",
children: /* @__PURE__ */ jsx(
"path",
{
fillRule: "evenodd",
d: "M5.75 2a.75.75 0 01.75.75V4h7V2.75a.75.75 0 011.5 0V4h.25A2.75 2.75 0 0118 6.75v8.5A2.75 2.75 0 0115.25 18H4.75A2.75 2.75 0 012 15.25v-8.5A2.75 2.75 0 014.75 4H5V2.75A.75.75 0 015.75 2zm-1 5.5c-.69 0-1.25.56-1.25 1.25v6.5c0 .69.56 1.25 1.25 1.25h10.5c.69 0 1.25-.56 1.25-1.25v-6.5c0-.69-.56-1.25-1.25-1.25H4.75z",
clipRule: "evenodd"
}
)
}
)
}
)
] }),
isOpen && /* @__PURE__ */ jsx(
"div",
{
className: `absolute z-10 w-72 bg-white rounded-md shadow-lg ${getCalendarPosition()}`,
children: /* @__PURE__ */ jsx(
Calendar_default,
{
selectedDate,
viewDate,
onDateSelect: handleDateSelect,
onViewDateChange: setViewDate,
minDate,
maxDate,
locale: formatOptions.locale,
calendarClassName,
dayClassName,
selectedDayClassName,
todayClassName,
disabledDayClassName
}
)
}
)
] });
};
var DatePicker_default = DatePicker;
export { Calendar_default as Calendar, DateInput_default as DateInput, DatePicker_default as NepaliDatePicker, bsDaysEn, bsDaysNe, bsMonthsEn, bsMonthsNe, convertADToBS, convertBSToAD, formatDate, getDaysInMonth, getTodayBS, isDateInRange, isValidBsDate, parseDate };
//# sourceMappingURL=index.js.map
//# sourceMappingURL=index.js.map