mehdi-akbari-calendar 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,30 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import clsx from 'clsx';
4
+ import { useCalendar } from '../../hooks/useCalendar';
5
+ import { CalendarHeader } from '../internal/CalendarHeader';
6
+ import { MonthView } from '../internal/MonthView';
7
+ import { MonthPickerView } from '../internal/MonthPickerView';
8
+ import { YearView } from '../internal/YearView';
9
+ const CheckCircleIcon = () => (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("path", { d: "M22 11.08V12a10 10 0 1 1-5.93-9.14" }), _jsx("polyline", { points: "22 4 12 14.01 9 11.01" })] }));
10
+ export const PersianCalendar = ({ initialDate, onDateSelect, minYear, maxYear, range, className }) => {
11
+ const { viewMode, daysOfMonth, monthsOfYear, yearsOfDecade, headerTitle, calendarType, weekDays, dateFns, toggleCalendarType, goToNext, goToPrev, handleSelectDay, handleSelectMonth, handleSelectYear, handleHeaderClick, isDateSelected, isInRange, isRangeStart, isRangeEnd, isSameMonthAsCurrent, isToday, isCurrentMonth, isCurrentYear, isYearDisabled, } = useCalendar({ initialDate, minYear, maxYear, range });
12
+ const onDayClick = (date) => {
13
+ handleSelectDay(date);
14
+ if (onDateSelect) {
15
+ onDateSelect(date);
16
+ }
17
+ };
18
+ const renderView = () => {
19
+ switch (viewMode) {
20
+ case 'year':
21
+ return _jsx(YearView, { years: yearsOfDecade, onSelectYear: handleSelectYear, isCurrentYear: isCurrentYear, isYearDisabled: isYearDisabled });
22
+ case 'month':
23
+ return _jsx(MonthPickerView, { months: monthsOfYear, onSelectMonth: handleSelectMonth, isCurrentMonth: isCurrentMonth, dateFns: dateFns });
24
+ case 'day':
25
+ default:
26
+ return (_jsx(MonthView, { daysOfMonth: daysOfMonth, weekDays: weekDays, dateFns: dateFns, onSelectDate: onDayClick, isDateSelected: isDateSelected, isInRange: isInRange, isRangeStart: isRangeStart, isRangeEnd: isRangeEnd, isSameMonthAsCurrent: isSameMonthAsCurrent, isToday: isToday }));
27
+ }
28
+ };
29
+ return (_jsxs("div", { className: clsx("prc-container", className), dir: calendarType === 'jalali' ? 'rtl' : 'ltr', children: [_jsx(CalendarHeader, { title: headerTitle, calendarType: calendarType, onToggleCalendarType: toggleCalendarType, onNext: goToNext, onPrev: goToPrev, onTitleClick: handleHeaderClick }), _jsx("div", { className: "prc-view-container", children: renderView() }), _jsxs("footer", { className: "prc-footer", children: [_jsx("span", { children: "\uD835\uDCDF\uD835\uDCF8\uD835\uDD00\uD835\uDCEE\uD835\uDCFB\uD835\uDCEE\uD835\uDCED \uD835\uDCEB\uD835\uDD02 \uD835\uDCDC\uD835\uDCEE\uD835\uDCF1\uD835\uDCED\uD835\uDCF2 \uD835\uDCD0\uD835\uDCF4\uD835\uDCEB\uD835\uDCEA\uD835\uDCFB\uD835\uDCF2" }), _jsx(CheckCircleIcon, {})] })] }));
30
+ };
@@ -0,0 +1,10 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // آیکون خورشید برای تقویم شمسی
3
+ const SunIcon = () => (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("circle", { cx: "12", cy: "12", r: "4" }), _jsx("path", { d: "M12 2v2" }), _jsx("path", { d: "M12 20v2" }), _jsx("path", { d: "m4.93 4.93 1.41 1.41" }), _jsx("path", { d: "m17.66 17.66 1.41 1.41" }), _jsx("path", { d: "M2 12h2" }), _jsx("path", { d: "M20 12h2" }), _jsx("path", { d: "m6.34 17.66-1.41 1.41" }), _jsx("path", { d: "m19.07 4.93-1.41 1.41" })] }));
4
+ // آیکون کره زمین برای تقویم میلادی
5
+ const GlobeIcon = () => (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("circle", { cx: "12", cy: "12", r: "10" }), _jsx("line", { x1: "2", y1: "12", x2: "22", y2: "12" }), _jsx("path", { d: "M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" })] }));
6
+ const ChevronRightIcon = () => (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: _jsx("polyline", { points: "9 18 15 12 9 6" }) }));
7
+ const ChevronLeftIcon = () => (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: _jsx("polyline", { points: "15 18 9 12 15 6" }) }));
8
+ export const CalendarHeader = ({ title, calendarType, onToggleCalendarType, onNext, onPrev, onTitleClick, }) => {
9
+ return (_jsxs("div", { className: "calendar-header", children: [_jsx("button", { type: "button", className: `calendar-header__toggle-btn ${calendarType}`, onClick: onToggleCalendarType, title: calendarType === 'jalali' ? "تغییر به تقویم میلادی" : "Switch to Persian Calendar", children: calendarType === 'jalali' ? _jsx(SunIcon, {}) : _jsx(GlobeIcon, {}) }), _jsxs("div", { className: "calendar-header__controls", children: [_jsx("button", { type: "button", className: "calendar-header__nav-button", onClick: onPrev, "aria-label": "\u0642\u0628\u0644\u06CC", children: _jsx(ChevronRightIcon, {}) }), _jsx("button", { type: "button", className: "calendar-header__title", onClick: onTitleClick, children: title }), _jsx("button", { type: "button", className: "calendar-header__nav-button", onClick: onNext, "aria-label": "\u0628\u0639\u062F\u06CC", children: _jsx(ChevronLeftIcon, {}) })] })] }));
10
+ };
@@ -0,0 +1,16 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import clsx from 'clsx';
3
+ export const DayCell = ({ date, isCurrentMonth, isSelected, isToday, isInRange = false, isRangeStart = false, isRangeEnd = false, isDisabled = false, onClick, dateFns, }) => {
4
+ const dayNumber = dateFns.format(date, 'd');
5
+ const cellClassName = clsx('day-cell', {
6
+ 'day-cell--not-current-month': !isCurrentMonth,
7
+ 'day-cell--is-today': isToday,
8
+ 'day-cell--is-selected': isSelected,
9
+ 'day-cell--is-disabled': isDisabled,
10
+ // ✅ کلاس‌های جدید
11
+ 'day-cell--in-range': isInRange,
12
+ 'day-cell--range-start': isRangeStart,
13
+ 'day-cell--range-end': isRangeEnd,
14
+ });
15
+ return (_jsx("div", { className: cellClassName, children: _jsx("button", { type: "button", className: "day-cell__button", onClick: () => !isDisabled && onClick(date), disabled: isDisabled, children: dayNumber }) }));
16
+ };
@@ -0,0 +1,10 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import clsx from 'clsx';
3
+ export const MonthPickerView = ({ months, onSelectMonth, isCurrentMonth, dateFns }) => {
4
+ return (_jsx("div", { className: "picker-view month-picker-view", children: months.map((monthDate, index) => {
5
+ const monthClassName = clsx('picker-item', {
6
+ 'picker-item--is-current': isCurrentMonth(index),
7
+ });
8
+ return (_jsx("button", { type: "button", className: monthClassName, onClick: () => onSelectMonth(index), children: dateFns.format(monthDate, 'LLLL') }, index));
9
+ }) }));
10
+ };
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { DayCell } from './DayCell';
3
+ export const MonthView = ({ daysOfMonth, weekDays, dateFns, onSelectDate, isDateSelected, isInRange, isRangeStart, isRangeEnd, isSameMonthAsCurrent, isToday, }) => {
4
+ return (_jsxs("div", { className: "month-view", children: [_jsx("div", { className: "month-view__weekdays", children: weekDays.map(dayName => (_jsx("div", { className: "month-view__weekday-name", children: dayName }, dayName))) }), _jsx("div", { className: "month-view__days-grid", children: daysOfMonth.map(day => (_jsx(DayCell, { date: day, onClick: onSelectDate, isSelected: isDateSelected(day),
5
+ // ✅ پاس دادن مقادیر محاسباتی
6
+ isInRange: isInRange(day), isRangeStart: isRangeStart(day), isRangeEnd: isRangeEnd(day), isCurrentMonth: isSameMonthAsCurrent(day), isToday: isToday(day), dateFns: dateFns }, day.toISOString()))) })] }));
7
+ };
@@ -0,0 +1,14 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import clsx from 'clsx';
4
+ // ✅ اطمینان حاصل کنید که کلمه export دقیقاً قبل از const قرار دارد
5
+ export const YearView = ({ years, onSelectYear, isCurrentYear, isYearDisabled }) => {
6
+ return (_jsx("div", { className: "picker-view year-picker-view", children: years.map(year => {
7
+ const isDisabled = isYearDisabled(year);
8
+ const yearClassName = clsx('picker-item', {
9
+ 'picker-item--is-current': isCurrentYear(year),
10
+ 'picker-item--is-disabled': isDisabled,
11
+ });
12
+ return (_jsx("button", { type: "button", className: yearClassName, onClick: () => !isDisabled && onSelectYear(year), disabled: isDisabled, "aria-current": isCurrentYear(year) ? 'true' : undefined, children: year }, year));
13
+ }) }));
14
+ };
@@ -0,0 +1,139 @@
1
+ "use client";
2
+ import { useState, useMemo, useCallback } from 'react';
3
+ // ✅ مرحله ۱: ایمپورت توابع از dateAdapter
4
+ import { getDateFunctions, getWeekDays } from '../utils/dateAdapter';
5
+ export const useCalendar = ({ initialDate = new Date(), minYear = 1300, maxYear = 1405, initialCalendarType = 'jalali', range } = {}) => {
6
+ const [calendarType, setCalendarType] = useState(initialCalendarType);
7
+ const dateFns = useMemo(() => getDateFunctions(calendarType), [calendarType]);
8
+ const effectiveMinYear = calendarType === 'gregorian' && minYear === 1300 ? 1920 : minYear;
9
+ const effectiveMaxYear = calendarType === 'gregorian' && maxYear === 1405 ? 2030 : maxYear;
10
+ const [viewMode, setViewMode] = useState('day');
11
+ const [currentDate, setCurrentDate] = useState(dateFns.startOfMonth(initialDate));
12
+ const [selectedDate, setSelectedDate] = useState(initialDate);
13
+ const daysOfMonth = useMemo(() => {
14
+ if (viewMode !== 'day')
15
+ return [];
16
+ const monthStart = dateFns.startOfMonth(currentDate);
17
+ const monthEnd = dateFns.endOfMonth(currentDate);
18
+ const startDate = dateFns.startOfWeek(monthStart);
19
+ const endDate = dateFns.endOfWeek(monthEnd);
20
+ return dateFns.eachDayOfInterval({ start: startDate, end: endDate });
21
+ }, [currentDate, viewMode, dateFns]);
22
+ const monthsOfYear = useMemo(() => {
23
+ if (viewMode !== 'month')
24
+ return [];
25
+ return dateFns.eachMonthOfInterval({
26
+ start: dateFns.startOfYear(currentDate),
27
+ end: dateFns.endOfYear(currentDate),
28
+ });
29
+ }, [currentDate, viewMode, dateFns]);
30
+ const yearsOfDecade = useMemo(() => {
31
+ if (viewMode !== 'year')
32
+ return [];
33
+ const year = dateFns.getYear(currentDate);
34
+ const decadeStartYear = Math.floor(year / 10) * 10;
35
+ const years = [];
36
+ for (let i = 0; i < 12; i++) {
37
+ years.push(decadeStartYear + i - 1);
38
+ }
39
+ return years;
40
+ }, [currentDate, viewMode, dateFns]);
41
+ const goToNext = useCallback(() => {
42
+ if (viewMode === 'day')
43
+ setCurrentDate(prev => dateFns.addMonths(prev, 1));
44
+ if (viewMode === 'month')
45
+ setCurrentDate(prev => dateFns.addYears(prev, 1));
46
+ if (viewMode === 'year')
47
+ setCurrentDate(prev => dateFns.addYears(prev, 10));
48
+ }, [viewMode, dateFns]);
49
+ const goToPrev = useCallback(() => {
50
+ if (viewMode === 'day')
51
+ setCurrentDate(prev => dateFns.subMonths(prev, 1));
52
+ if (viewMode === 'month')
53
+ setCurrentDate(prev => dateFns.subYears(prev, 1));
54
+ if (viewMode === 'year')
55
+ setCurrentDate(prev => dateFns.subYears(prev, 10));
56
+ }, [viewMode, dateFns]);
57
+ const handleSelectDay = useCallback((date) => {
58
+ setSelectedDate(date);
59
+ if (!dateFns.isSameMonth(currentDate, date)) {
60
+ setCurrentDate(dateFns.startOfMonth(date));
61
+ }
62
+ }, [currentDate, dateFns]);
63
+ const handleSelectMonth = useCallback((monthIndex) => {
64
+ setCurrentDate(prev => dateFns.setMonth(prev, monthIndex));
65
+ setViewMode('day');
66
+ }, [dateFns]);
67
+ const handleSelectYear = useCallback((year) => {
68
+ setCurrentDate(prev => dateFns.setYear(prev, year));
69
+ setViewMode('month');
70
+ }, [dateFns]);
71
+ const handleHeaderClick = useCallback(() => {
72
+ if (viewMode === 'day')
73
+ setViewMode('month');
74
+ if (viewMode === 'month')
75
+ setViewMode('year');
76
+ }, [viewMode]);
77
+ const toggleCalendarType = useCallback(() => {
78
+ setCalendarType(prev => prev === 'jalali' ? 'gregorian' : 'jalali');
79
+ setViewMode('day');
80
+ }, []);
81
+ const isDateSelected = useCallback((date) => {
82
+ if (range) {
83
+ return !!((range.from && dateFns.isSameDay(date, range.from)) ||
84
+ (range.to && dateFns.isSameDay(date, range.to)));
85
+ }
86
+ return selectedDate ? dateFns.isSameDay(date, selectedDate) : false;
87
+ }, [selectedDate, range, dateFns]);
88
+ const isInRange = useCallback((date) => {
89
+ if (!range?.from || !range?.to)
90
+ return false;
91
+ return dateFns.isWithinInterval(date, { start: range.from, end: range.to });
92
+ }, [range, dateFns]);
93
+ const isRangeStart = useCallback((date) => {
94
+ return !!(range?.from && dateFns.isSameDay(date, range.from));
95
+ }, [range, dateFns]);
96
+ const isRangeEnd = useCallback((date) => {
97
+ return !!(range?.to && dateFns.isSameDay(date, range.to));
98
+ }, [range, dateFns]);
99
+ const headerTitle = useMemo(() => {
100
+ if (viewMode === 'day')
101
+ return dateFns.format(currentDate, 'LLLL yyyy');
102
+ if (viewMode === 'month')
103
+ return dateFns.format(currentDate, 'yyyy');
104
+ if (viewMode === 'year') {
105
+ const start = yearsOfDecade[0];
106
+ const end = yearsOfDecade[yearsOfDecade.length - 1];
107
+ return `${end} - ${start}`;
108
+ }
109
+ return '';
110
+ }, [currentDate, viewMode, yearsOfDecade, dateFns]);
111
+ return {
112
+ viewMode,
113
+ currentDate,
114
+ selectedDate,
115
+ daysOfMonth,
116
+ monthsOfYear,
117
+ yearsOfDecade,
118
+ headerTitle,
119
+ calendarType,
120
+ weekDays: getWeekDays(calendarType),
121
+ dateFns,
122
+ toggleCalendarType,
123
+ goToNext,
124
+ goToPrev,
125
+ handleSelectDay,
126
+ handleSelectMonth,
127
+ handleSelectYear,
128
+ handleHeaderClick,
129
+ isSameMonthAsCurrent: (date) => dateFns.isSameMonth(currentDate, date),
130
+ isDateSelected,
131
+ isInRange,
132
+ isRangeStart,
133
+ isRangeEnd,
134
+ isToday: (date) => dateFns.isSameDay(date, new Date()),
135
+ isCurrentMonth: (monthIndex) => dateFns.getMonth(new Date()) === monthIndex && dateFns.getYear(new Date()) === dateFns.getYear(currentDate),
136
+ isCurrentYear: (year) => dateFns.getYear(new Date()) === year,
137
+ isYearDisabled: (year) => year > effectiveMaxYear || year < effectiveMinYear,
138
+ };
139
+ };
package/dist/index.js CHANGED
@@ -1 +1,8 @@
1
- //# sourceMappingURL=index.js.map
1
+ // src/index.ts
2
+ /**
3
+ * This is the main entry point for non-React functionalities and types.
4
+ * It allows users to import types or utility functions without pulling in React.
5
+ */
6
+ export * from "./types";
7
+ // In the future, you could also export utility functions from here:
8
+ // export * from "./utils/dateAdapter";
@@ -0,0 +1,486 @@
1
+ "use strict";
2
+ "use client";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+
31
+ // src/index.react.ts
32
+ var index_react_exports = {};
33
+ __export(index_react_exports, {
34
+ PersianCalendar: () => PersianCalendar
35
+ });
36
+ module.exports = __toCommonJS(index_react_exports);
37
+
38
+ // src/components/Calendar/Calendar.tsx
39
+ var import_clsx4 = __toESM(require("clsx"), 1);
40
+
41
+ // src/hooks/useCalendar.ts
42
+ var import_react = require("react");
43
+
44
+ // src/utils/dateAdapter.ts
45
+ var jdf = __toESM(require("date-fns-jalali"), 1);
46
+ var df = __toESM(require("date-fns"), 1);
47
+ var import_locale = require("date-fns-jalali/locale");
48
+ var getDateFunctions = (type) => {
49
+ const isJalali = type === "jalali";
50
+ const lib = isJalali ? jdf : df;
51
+ return {
52
+ startOfMonth: lib.startOfMonth,
53
+ endOfMonth: lib.endOfMonth,
54
+ startOfWeek: (date) => lib.startOfWeek(date, { locale: isJalali ? import_locale.faIR : void 0, weekStartsOn: isJalali ? 6 : 1 }),
55
+ endOfWeek: (date) => lib.endOfWeek(date, { locale: isJalali ? import_locale.faIR : void 0, weekStartsOn: isJalali ? 6 : 1 }),
56
+ eachDayOfInterval: lib.eachDayOfInterval,
57
+ isSameMonth: lib.isSameMonth,
58
+ isSameDay: lib.isSameDay,
59
+ format: (date, formatStr) => {
60
+ try {
61
+ return lib.format(date, formatStr, { locale: isJalali ? import_locale.faIR : void 0 });
62
+ } catch {
63
+ return "";
64
+ }
65
+ },
66
+ addMonths: lib.addMonths,
67
+ subMonths: lib.subMonths,
68
+ getYear: lib.getYear,
69
+ setYear: lib.setYear,
70
+ getMonth: lib.getMonth,
71
+ setMonth: lib.setMonth,
72
+ startOfYear: lib.startOfYear,
73
+ eachMonthOfInterval: lib.eachMonthOfInterval,
74
+ endOfYear: lib.endOfYear,
75
+ addYears: lib.addYears,
76
+ subYears: lib.subYears,
77
+ isDate: lib.isDate,
78
+ isWithinInterval: lib.isWithinInterval
79
+ };
80
+ };
81
+ var getWeekDays = (type) => {
82
+ if (type === "jalali") {
83
+ return ["\u0634", "\u06CC", "\u062F", "\u0633", "\u0686", "\u067E", "\u062C"];
84
+ } else {
85
+ return ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"];
86
+ }
87
+ };
88
+
89
+ // src/hooks/useCalendar.ts
90
+ var useCalendar = ({
91
+ initialDate = /* @__PURE__ */ new Date(),
92
+ minYear = 1300,
93
+ maxYear = 1405,
94
+ initialCalendarType = "jalali",
95
+ range
96
+ } = {}) => {
97
+ const [calendarType, setCalendarType] = (0, import_react.useState)(initialCalendarType);
98
+ const dateFns = (0, import_react.useMemo)(() => getDateFunctions(calendarType), [calendarType]);
99
+ const effectiveMinYear = calendarType === "gregorian" && minYear === 1300 ? 1920 : minYear;
100
+ const effectiveMaxYear = calendarType === "gregorian" && maxYear === 1405 ? 2030 : maxYear;
101
+ const [viewMode, setViewMode] = (0, import_react.useState)("day");
102
+ const [currentDate, setCurrentDate] = (0, import_react.useState)(dateFns.startOfMonth(initialDate));
103
+ const [selectedDate, setSelectedDate] = (0, import_react.useState)(initialDate);
104
+ const daysOfMonth = (0, import_react.useMemo)(() => {
105
+ if (viewMode !== "day") return [];
106
+ const monthStart = dateFns.startOfMonth(currentDate);
107
+ const monthEnd = dateFns.endOfMonth(currentDate);
108
+ const startDate = dateFns.startOfWeek(monthStart);
109
+ const endDate = dateFns.endOfWeek(monthEnd);
110
+ return dateFns.eachDayOfInterval({ start: startDate, end: endDate });
111
+ }, [currentDate, viewMode, dateFns]);
112
+ const monthsOfYear = (0, import_react.useMemo)(() => {
113
+ if (viewMode !== "month") return [];
114
+ return dateFns.eachMonthOfInterval({
115
+ start: dateFns.startOfYear(currentDate),
116
+ end: dateFns.endOfYear(currentDate)
117
+ });
118
+ }, [currentDate, viewMode, dateFns]);
119
+ const yearsOfDecade = (0, import_react.useMemo)(() => {
120
+ if (viewMode !== "year") return [];
121
+ const year = dateFns.getYear(currentDate);
122
+ const decadeStartYear = Math.floor(year / 10) * 10;
123
+ const years = [];
124
+ for (let i = 0; i < 12; i++) {
125
+ years.push(decadeStartYear + i - 1);
126
+ }
127
+ return years;
128
+ }, [currentDate, viewMode, dateFns]);
129
+ const goToNext = (0, import_react.useCallback)(() => {
130
+ if (viewMode === "day") setCurrentDate((prev) => dateFns.addMonths(prev, 1));
131
+ if (viewMode === "month") setCurrentDate((prev) => dateFns.addYears(prev, 1));
132
+ if (viewMode === "year") setCurrentDate((prev) => dateFns.addYears(prev, 10));
133
+ }, [viewMode, dateFns]);
134
+ const goToPrev = (0, import_react.useCallback)(() => {
135
+ if (viewMode === "day") setCurrentDate((prev) => dateFns.subMonths(prev, 1));
136
+ if (viewMode === "month") setCurrentDate((prev) => dateFns.subYears(prev, 1));
137
+ if (viewMode === "year") setCurrentDate((prev) => dateFns.subYears(prev, 10));
138
+ }, [viewMode, dateFns]);
139
+ const handleSelectDay = (0, import_react.useCallback)((date) => {
140
+ setSelectedDate(date);
141
+ if (!dateFns.isSameMonth(currentDate, date)) {
142
+ setCurrentDate(dateFns.startOfMonth(date));
143
+ }
144
+ }, [currentDate, dateFns]);
145
+ const handleSelectMonth = (0, import_react.useCallback)((monthIndex) => {
146
+ setCurrentDate((prev) => dateFns.setMonth(prev, monthIndex));
147
+ setViewMode("day");
148
+ }, [dateFns]);
149
+ const handleSelectYear = (0, import_react.useCallback)((year) => {
150
+ setCurrentDate((prev) => dateFns.setYear(prev, year));
151
+ setViewMode("month");
152
+ }, [dateFns]);
153
+ const handleHeaderClick = (0, import_react.useCallback)(() => {
154
+ if (viewMode === "day") setViewMode("month");
155
+ if (viewMode === "month") setViewMode("year");
156
+ }, [viewMode]);
157
+ const toggleCalendarType = (0, import_react.useCallback)(() => {
158
+ setCalendarType((prev) => prev === "jalali" ? "gregorian" : "jalali");
159
+ setViewMode("day");
160
+ }, []);
161
+ const isDateSelected = (0, import_react.useCallback)((date) => {
162
+ if (range) {
163
+ return !!(range.from && dateFns.isSameDay(date, range.from) || range.to && dateFns.isSameDay(date, range.to));
164
+ }
165
+ return selectedDate ? dateFns.isSameDay(date, selectedDate) : false;
166
+ }, [selectedDate, range, dateFns]);
167
+ const isInRange = (0, import_react.useCallback)((date) => {
168
+ if (!range?.from || !range?.to) return false;
169
+ return dateFns.isWithinInterval(date, { start: range.from, end: range.to });
170
+ }, [range, dateFns]);
171
+ const isRangeStart = (0, import_react.useCallback)((date) => {
172
+ return !!(range?.from && dateFns.isSameDay(date, range.from));
173
+ }, [range, dateFns]);
174
+ const isRangeEnd = (0, import_react.useCallback)((date) => {
175
+ return !!(range?.to && dateFns.isSameDay(date, range.to));
176
+ }, [range, dateFns]);
177
+ const headerTitle = (0, import_react.useMemo)(() => {
178
+ if (viewMode === "day") return dateFns.format(currentDate, "LLLL yyyy");
179
+ if (viewMode === "month") return dateFns.format(currentDate, "yyyy");
180
+ if (viewMode === "year") {
181
+ const start = yearsOfDecade[0];
182
+ const end = yearsOfDecade[yearsOfDecade.length - 1];
183
+ return `${end} - ${start}`;
184
+ }
185
+ return "";
186
+ }, [currentDate, viewMode, yearsOfDecade, dateFns]);
187
+ return {
188
+ viewMode,
189
+ currentDate,
190
+ selectedDate,
191
+ daysOfMonth,
192
+ monthsOfYear,
193
+ yearsOfDecade,
194
+ headerTitle,
195
+ calendarType,
196
+ weekDays: getWeekDays(calendarType),
197
+ dateFns,
198
+ toggleCalendarType,
199
+ goToNext,
200
+ goToPrev,
201
+ handleSelectDay,
202
+ handleSelectMonth,
203
+ handleSelectYear,
204
+ handleHeaderClick,
205
+ isSameMonthAsCurrent: (date) => dateFns.isSameMonth(currentDate, date),
206
+ isDateSelected,
207
+ isInRange,
208
+ isRangeStart,
209
+ isRangeEnd,
210
+ isToday: (date) => dateFns.isSameDay(date, /* @__PURE__ */ new Date()),
211
+ isCurrentMonth: (monthIndex) => dateFns.getMonth(/* @__PURE__ */ new Date()) === monthIndex && dateFns.getYear(/* @__PURE__ */ new Date()) === dateFns.getYear(currentDate),
212
+ isCurrentYear: (year) => dateFns.getYear(/* @__PURE__ */ new Date()) === year,
213
+ isYearDisabled: (year) => year > effectiveMaxYear || year < effectiveMinYear
214
+ };
215
+ };
216
+
217
+ // src/components/internal/CalendarHeader.tsx
218
+ var import_jsx_runtime = require("react/jsx-runtime");
219
+ var SunIcon = () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
220
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "12", r: "4" }),
221
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 2v2" }),
222
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 20v2" }),
223
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m4.93 4.93 1.41 1.41" }),
224
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m17.66 17.66 1.41 1.41" }),
225
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M2 12h2" }),
226
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M20 12h2" }),
227
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m6.34 17.66-1.41 1.41" }),
228
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m19.07 4.93-1.41 1.41" })
229
+ ] });
230
+ var GlobeIcon = () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
231
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
232
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "2", y1: "12", x2: "22", y2: "12" }),
233
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" })
234
+ ] });
235
+ var ChevronRightIcon = () => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "9 18 15 12 9 6" }) });
236
+ var ChevronLeftIcon = () => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "15 18 9 12 15 6" }) });
237
+ var CalendarHeader = ({
238
+ title,
239
+ calendarType,
240
+ onToggleCalendarType,
241
+ onNext,
242
+ onPrev,
243
+ onTitleClick
244
+ }) => {
245
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "calendar-header", children: [
246
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
247
+ "button",
248
+ {
249
+ type: "button",
250
+ className: `calendar-header__toggle-btn ${calendarType}`,
251
+ onClick: onToggleCalendarType,
252
+ title: calendarType === "jalali" ? "\u062A\u063A\u06CC\u06CC\u0631 \u0628\u0647 \u062A\u0642\u0648\u06CC\u0645 \u0645\u06CC\u0644\u0627\u062F\u06CC" : "Switch to Persian Calendar",
253
+ children: calendarType === "jalali" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SunIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GlobeIcon, {})
254
+ }
255
+ ),
256
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "calendar-header__controls", children: [
257
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: "calendar-header__nav-button", onClick: onPrev, "aria-label": "\u0642\u0628\u0644\u06CC", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronRightIcon, {}) }),
258
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: "calendar-header__title", onClick: onTitleClick, children: title }),
259
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: "calendar-header__nav-button", onClick: onNext, "aria-label": "\u0628\u0639\u062F\u06CC", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronLeftIcon, {}) })
260
+ ] })
261
+ ] });
262
+ };
263
+
264
+ // src/components/internal/DayCell.tsx
265
+ var import_clsx = __toESM(require("clsx"), 1);
266
+ var import_jsx_runtime2 = require("react/jsx-runtime");
267
+ var DayCell = ({
268
+ date,
269
+ isCurrentMonth,
270
+ isSelected,
271
+ isToday,
272
+ isInRange = false,
273
+ isRangeStart = false,
274
+ isRangeEnd = false,
275
+ isDisabled = false,
276
+ onClick,
277
+ dateFns
278
+ }) => {
279
+ const dayNumber = dateFns.format(date, "d");
280
+ const cellClassName = (0, import_clsx.default)("day-cell", {
281
+ "day-cell--not-current-month": !isCurrentMonth,
282
+ "day-cell--is-today": isToday,
283
+ "day-cell--is-selected": isSelected,
284
+ "day-cell--is-disabled": isDisabled,
285
+ // ✅ کلاس‌های جدید
286
+ "day-cell--in-range": isInRange,
287
+ "day-cell--range-start": isRangeStart,
288
+ "day-cell--range-end": isRangeEnd
289
+ });
290
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: cellClassName, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
291
+ "button",
292
+ {
293
+ type: "button",
294
+ className: "day-cell__button",
295
+ onClick: () => !isDisabled && onClick(date),
296
+ disabled: isDisabled,
297
+ children: dayNumber
298
+ }
299
+ ) });
300
+ };
301
+
302
+ // src/components/internal/MonthView.tsx
303
+ var import_jsx_runtime3 = require("react/jsx-runtime");
304
+ var MonthView = ({
305
+ daysOfMonth,
306
+ weekDays,
307
+ dateFns,
308
+ onSelectDate,
309
+ isDateSelected,
310
+ isInRange,
311
+ isRangeStart,
312
+ isRangeEnd,
313
+ isSameMonthAsCurrent,
314
+ isToday
315
+ }) => {
316
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "month-view", children: [
317
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "month-view__weekdays", children: weekDays.map((dayName) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "month-view__weekday-name", children: dayName }, dayName)) }),
318
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "month-view__days-grid", children: daysOfMonth.map((day) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
319
+ DayCell,
320
+ {
321
+ date: day,
322
+ onClick: onSelectDate,
323
+ isSelected: isDateSelected(day),
324
+ isInRange: isInRange(day),
325
+ isRangeStart: isRangeStart(day),
326
+ isRangeEnd: isRangeEnd(day),
327
+ isCurrentMonth: isSameMonthAsCurrent(day),
328
+ isToday: isToday(day),
329
+ dateFns
330
+ },
331
+ day.toISOString()
332
+ )) })
333
+ ] });
334
+ };
335
+
336
+ // src/components/internal/MonthPickerView.tsx
337
+ var import_clsx2 = __toESM(require("clsx"), 1);
338
+ var import_jsx_runtime4 = require("react/jsx-runtime");
339
+ var MonthPickerView = ({
340
+ months,
341
+ onSelectMonth,
342
+ isCurrentMonth,
343
+ dateFns
344
+ }) => {
345
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "picker-view month-picker-view", children: months.map((monthDate, index) => {
346
+ const monthClassName = (0, import_clsx2.default)("picker-item", {
347
+ "picker-item--is-current": isCurrentMonth(index)
348
+ });
349
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
350
+ "button",
351
+ {
352
+ type: "button",
353
+ className: monthClassName,
354
+ onClick: () => onSelectMonth(index),
355
+ children: dateFns.format(monthDate, "LLLL")
356
+ },
357
+ index
358
+ );
359
+ }) });
360
+ };
361
+
362
+ // src/components/internal/YearView.tsx
363
+ var import_clsx3 = __toESM(require("clsx"), 1);
364
+ var import_jsx_runtime5 = require("react/jsx-runtime");
365
+ var YearView = ({
366
+ years,
367
+ onSelectYear,
368
+ isCurrentYear,
369
+ isYearDisabled
370
+ }) => {
371
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "picker-view year-picker-view", children: years.map((year) => {
372
+ const isDisabled = isYearDisabled(year);
373
+ const yearClassName = (0, import_clsx3.default)("picker-item", {
374
+ "picker-item--is-current": isCurrentYear(year),
375
+ "picker-item--is-disabled": isDisabled
376
+ });
377
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
378
+ "button",
379
+ {
380
+ type: "button",
381
+ className: yearClassName,
382
+ onClick: () => !isDisabled && onSelectYear(year),
383
+ disabled: isDisabled,
384
+ "aria-current": isCurrentYear(year) ? "true" : void 0,
385
+ children: year
386
+ },
387
+ year
388
+ );
389
+ }) });
390
+ };
391
+
392
+ // src/components/Calendar/Calendar.tsx
393
+ var import_jsx_runtime6 = require("react/jsx-runtime");
394
+ var CheckCircleIcon = () => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
395
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M22 11.08V12a10 10 0 1 1-5.93-9.14" }),
396
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("polyline", { points: "22 4 12 14.01 9 11.01" })
397
+ ] });
398
+ var PersianCalendar = ({
399
+ initialDate,
400
+ onDateSelect,
401
+ minYear,
402
+ maxYear,
403
+ range,
404
+ className
405
+ }) => {
406
+ const {
407
+ viewMode,
408
+ daysOfMonth,
409
+ monthsOfYear,
410
+ yearsOfDecade,
411
+ headerTitle,
412
+ calendarType,
413
+ weekDays,
414
+ dateFns,
415
+ toggleCalendarType,
416
+ goToNext,
417
+ goToPrev,
418
+ handleSelectDay,
419
+ handleSelectMonth,
420
+ handleSelectYear,
421
+ handleHeaderClick,
422
+ isDateSelected,
423
+ isInRange,
424
+ isRangeStart,
425
+ isRangeEnd,
426
+ isSameMonthAsCurrent,
427
+ isToday,
428
+ isCurrentMonth,
429
+ isCurrentYear,
430
+ isYearDisabled
431
+ } = useCalendar({ initialDate, minYear, maxYear, range });
432
+ const onDayClick = (date) => {
433
+ handleSelectDay(date);
434
+ if (onDateSelect) {
435
+ onDateSelect(date);
436
+ }
437
+ };
438
+ const renderView = () => {
439
+ switch (viewMode) {
440
+ case "year":
441
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(YearView, { years: yearsOfDecade, onSelectYear: handleSelectYear, isCurrentYear, isYearDisabled });
442
+ case "month":
443
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(MonthPickerView, { months: monthsOfYear, onSelectMonth: handleSelectMonth, isCurrentMonth, dateFns });
444
+ case "day":
445
+ default:
446
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
447
+ MonthView,
448
+ {
449
+ daysOfMonth,
450
+ weekDays,
451
+ dateFns,
452
+ onSelectDate: onDayClick,
453
+ isDateSelected,
454
+ isInRange,
455
+ isRangeStart,
456
+ isRangeEnd,
457
+ isSameMonthAsCurrent,
458
+ isToday
459
+ }
460
+ );
461
+ }
462
+ };
463
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: (0, import_clsx4.default)("prc-container", className), dir: calendarType === "jalali" ? "rtl" : "ltr", children: [
464
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
465
+ CalendarHeader,
466
+ {
467
+ title: headerTitle,
468
+ calendarType,
469
+ onToggleCalendarType: toggleCalendarType,
470
+ onNext: goToNext,
471
+ onPrev: goToPrev,
472
+ onTitleClick: handleHeaderClick
473
+ }
474
+ ),
475
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "prc-view-container", children: renderView() }),
476
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("footer", { className: "prc-footer", children: [
477
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "\u{1D4DF}\u{1D4F8}\u{1D500}\u{1D4EE}\u{1D4FB}\u{1D4EE}\u{1D4ED} \u{1D4EB}\u{1D502} \u{1D4DC}\u{1D4EE}\u{1D4F1}\u{1D4ED}\u{1D4F2} \u{1D4D0}\u{1D4F4}\u{1D4EB}\u{1D4EA}\u{1D4FB}\u{1D4F2}" }),
478
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CheckCircleIcon, {})
479
+ ] })
480
+ ] });
481
+ };
482
+ // Annotate the CommonJS export names for ESM import in node:
483
+ 0 && (module.exports = {
484
+ PersianCalendar
485
+ });
486
+ //# sourceMappingURL=index.react.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.react.ts","../src/components/Calendar/Calendar.tsx","../src/hooks/useCalendar.ts","../src/utils/dateAdapter.ts","../src/components/internal/CalendarHeader.tsx","../src/components/internal/DayCell.tsx","../src/components/internal/MonthView.tsx","../src/components/internal/MonthPickerView.tsx","../src/components/internal/YearView.tsx"],"sourcesContent":["// src/index.react.ts\r\n\"use client\";\r\n\r\n// مسیر صحیح بر اساس ساختار شما\r\nexport { PersianCalendar, type PersianCalendarProps } from \"./components/Calendar/Calendar\";\r\nexport * from \"./types\";","\"use client\";\r\nimport React from 'react';\r\nimport clsx from 'clsx';\r\nimport { useCalendar } from '../../hooks/useCalendar';\r\nimport { CalendarHeader } from '../internal/CalendarHeader';\r\nimport { MonthView } from '../internal/MonthView';\r\nimport { MonthPickerView } from '../internal/MonthPickerView';\r\nimport { YearView } from '../internal/YearView';\r\n\r\n// ✅ مرحله ۱: ایمپورت تایپ‌های اصلی از منبع جدید و مرکزی\r\nimport type { DateRange } from '../../types';\r\n\r\n// ✅ مرحله ۲: ایمپورت تایپ‌های مخصوص هوک از خود فایل هوک\r\nimport type { UseCalendarOptions } from '../../hooks/useCalendar';\r\n\r\n// ✅ مرحله ۳: این خط حالا به درستی کار می‌کند چون DateRange از بالا ایمپورت شده است\r\nexport type { DateRange };\r\n\r\nconst CheckCircleIcon = () => (\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"M22 11.08V12a10 10 0 1 1-5.93-9.14\"></path>\r\n <polyline points=\"22 4 12 14.01 9 11.01\"></polyline>\r\n </svg>\r\n);\r\n\r\nexport interface PersianCalendarProps extends Omit<UseCalendarOptions, 'range'> {\r\n onDateSelect?: (date: Date | null) => void;\r\n range?: DateRange;\r\n className?: string;\r\n}\r\n\r\nexport const PersianCalendar: React.FC<PersianCalendarProps> = ({ \r\n initialDate, \r\n onDateSelect,\r\n minYear,\r\n maxYear,\r\n range,\r\n className\r\n}) => {\r\n const {\r\n viewMode,\r\n daysOfMonth,\r\n monthsOfYear,\r\n yearsOfDecade,\r\n headerTitle,\r\n calendarType,\r\n weekDays,\r\n dateFns,\r\n toggleCalendarType,\r\n goToNext,\r\n goToPrev,\r\n handleSelectDay,\r\n handleSelectMonth,\r\n handleSelectYear,\r\n handleHeaderClick,\r\n isDateSelected,\r\n isInRange,\r\n isRangeStart,\r\n isRangeEnd,\r\n isSameMonthAsCurrent,\r\n isToday,\r\n isCurrentMonth,\r\n isCurrentYear,\r\n isYearDisabled,\r\n } = useCalendar({ initialDate, minYear, maxYear, range });\r\n\r\n const onDayClick = (date: Date) => {\r\n handleSelectDay(date);\r\n if (onDateSelect) {\r\n onDateSelect(date);\r\n }\r\n };\r\n\r\n const renderView = () => {\r\n switch (viewMode) {\r\n case 'year':\r\n return <YearView years={yearsOfDecade} onSelectYear={handleSelectYear} isCurrentYear={isCurrentYear} isYearDisabled={isYearDisabled} />;\r\n case 'month':\r\n return <MonthPickerView months={monthsOfYear} onSelectMonth={handleSelectMonth} isCurrentMonth={isCurrentMonth} dateFns={dateFns} />;\r\n case 'day':\r\n default:\r\n return (\r\n <MonthView\r\n daysOfMonth={daysOfMonth}\r\n weekDays={weekDays}\r\n dateFns={dateFns}\r\n onSelectDate={onDayClick}\r\n isDateSelected={isDateSelected}\r\n isInRange={isInRange}\r\n isRangeStart={isRangeStart}\r\n isRangeEnd={isRangeEnd}\r\n isSameMonthAsCurrent={isSameMonthAsCurrent}\r\n isToday={isToday}\r\n />\r\n );\r\n }\r\n };\r\n\r\n return (\r\n <div className={clsx(\"prc-container\", className)} dir={calendarType === 'jalali' ? 'rtl' : 'ltr'}>\r\n <CalendarHeader\r\n title={headerTitle}\r\n calendarType={calendarType}\r\n onToggleCalendarType={toggleCalendarType}\r\n onNext={goToNext}\r\n onPrev={goToPrev}\r\n onTitleClick={handleHeaderClick}\r\n />\r\n <div className=\"prc-view-container\">\r\n {renderView()}\r\n </div>\r\n \r\n <footer className=\"prc-footer\">\r\n <span>𝓟𝓸𝔀𝓮𝓻𝓮𝓭 𝓫𝔂 𝓜𝓮𝓱𝓭𝓲 𝓐𝓴𝓫𝓪𝓻𝓲</span>\r\n <CheckCircleIcon />\r\n </footer>\r\n </div>\r\n );\r\n};","\"use client\";\r\nimport { useState, useMemo, useCallback } from 'react';\r\n\r\n// ✅ مرحله ۱: ایمپورت توابع از dateAdapter\r\nimport { getDateFunctions, getWeekDays } from '../utils/dateAdapter';\r\n\r\n// ✅ مرحله ۲: ایمپورت تمام تایپ‌های مورد نیاز از فایل مرکزی تایپ‌ها\r\nimport type { CalendarViewMode, DateRange, CalendarType } from '../types';\r\n\r\n// ⛔️ تعریف‌های محلی تایپ‌ها حذف شدند تا از یک منبع واحد استفاده شود.\r\n// export type CalendarViewMode = 'day' | 'month' | 'year';\r\n// export interface DateRange {\r\n// from: Date | null;\r\n// to: Date | null;\r\n// }\r\n\r\nexport interface UseCalendarOptions {\r\n initialDate?: Date;\r\n minYear?: number;\r\n maxYear?: number;\r\n initialCalendarType?: CalendarType;\r\n range?: DateRange;\r\n}\r\n\r\nexport const useCalendar = ({ \r\n initialDate = new Date(),\r\n minYear = 1300,\r\n maxYear = 1405,\r\n initialCalendarType = 'jalali',\r\n range\r\n}: UseCalendarOptions = {}) => {\r\n \r\n const [calendarType, setCalendarType] = useState<CalendarType>(initialCalendarType);\r\n const dateFns = useMemo(() => getDateFunctions(calendarType), [calendarType]);\r\n\r\n const effectiveMinYear = calendarType === 'gregorian' && minYear === 1300 ? 1920 : minYear;\r\n const effectiveMaxYear = calendarType === 'gregorian' && maxYear === 1405 ? 2030 : maxYear;\r\n\r\n const [viewMode, setViewMode] = useState<CalendarViewMode>('day');\r\n const [currentDate, setCurrentDate] = useState(dateFns.startOfMonth(initialDate));\r\n const [selectedDate, setSelectedDate] = useState<Date | null>(initialDate);\r\n\r\n const daysOfMonth = useMemo(() => {\r\n if (viewMode !== 'day') return [];\r\n const monthStart = dateFns.startOfMonth(currentDate);\r\n const monthEnd = dateFns.endOfMonth(currentDate);\r\n const startDate = dateFns.startOfWeek(monthStart);\r\n const endDate = dateFns.endOfWeek(monthEnd);\r\n return dateFns.eachDayOfInterval({ start: startDate, end: endDate });\r\n }, [currentDate, viewMode, dateFns]);\r\n\r\n const monthsOfYear = useMemo(() => {\r\n if (viewMode !== 'month') return [];\r\n return dateFns.eachMonthOfInterval({\r\n start: dateFns.startOfYear(currentDate),\r\n end: dateFns.endOfYear(currentDate),\r\n });\r\n }, [currentDate, viewMode, dateFns]);\r\n \r\n const yearsOfDecade = useMemo(() => {\r\n if (viewMode !== 'year') return [];\r\n const year = dateFns.getYear(currentDate);\r\n const decadeStartYear = Math.floor(year / 10) * 10;\r\n const years = [];\r\n for (let i = 0; i < 12; i++) {\r\n years.push(decadeStartYear + i - 1);\r\n }\r\n return years;\r\n }, [currentDate, viewMode, dateFns]);\r\n\r\n const goToNext = useCallback(() => {\r\n if (viewMode === 'day') setCurrentDate(prev => dateFns.addMonths(prev, 1));\r\n if (viewMode === 'month') setCurrentDate(prev => dateFns.addYears(prev, 1));\r\n if (viewMode === 'year') setCurrentDate(prev => dateFns.addYears(prev, 10));\r\n }, [viewMode, dateFns]);\r\n\r\n const goToPrev = useCallback(() => {\r\n if (viewMode === 'day') setCurrentDate(prev => dateFns.subMonths(prev, 1));\r\n if (viewMode === 'month') setCurrentDate(prev => dateFns.subYears(prev, 1));\r\n if (viewMode === 'year') setCurrentDate(prev => dateFns.subYears(prev, 10));\r\n }, [viewMode, dateFns]);\r\n\r\n const handleSelectDay = useCallback((date: Date) => {\r\n setSelectedDate(date);\r\n if (!dateFns.isSameMonth(currentDate, date)) {\r\n setCurrentDate(dateFns.startOfMonth(date));\r\n }\r\n }, [currentDate, dateFns]);\r\n\r\n const handleSelectMonth = useCallback((monthIndex: number) => {\r\n setCurrentDate(prev => dateFns.setMonth(prev, monthIndex));\r\n setViewMode('day');\r\n }, [dateFns]);\r\n\r\n const handleSelectYear = useCallback((year: number) => {\r\n setCurrentDate(prev => dateFns.setYear(prev, year));\r\n setViewMode('month');\r\n }, [dateFns]);\r\n \r\n const handleHeaderClick = useCallback(() => {\r\n if (viewMode === 'day') setViewMode('month');\r\n if (viewMode === 'month') setViewMode('year');\r\n }, [viewMode]);\r\n\r\n const toggleCalendarType = useCallback(() => {\r\n setCalendarType(prev => prev === 'jalali' ? 'gregorian' : 'jalali');\r\n setViewMode('day');\r\n }, []);\r\n\r\n const isDateSelected = useCallback((date: Date): boolean => {\r\n if (range) {\r\n return !!((range.from && dateFns.isSameDay(date, range.from)) || \r\n (range.to && dateFns.isSameDay(date, range.to)));\r\n }\r\n return selectedDate ? dateFns.isSameDay(date, selectedDate) : false;\r\n }, [selectedDate, range, dateFns]);\r\n\r\n const isInRange = useCallback((date: Date): boolean => {\r\n if (!range?.from || !range?.to) return false;\r\n return dateFns.isWithinInterval(date, { start: range.from, end: range.to });\r\n }, [range, dateFns]);\r\n\r\n const isRangeStart = useCallback((date: Date): boolean => {\r\n return !!(range?.from && dateFns.isSameDay(date, range.from));\r\n }, [range, dateFns]);\r\n\r\n const isRangeEnd = useCallback((date: Date): boolean => {\r\n return !!(range?.to && dateFns.isSameDay(date, range.to));\r\n }, [range, dateFns]);\r\n\r\n const headerTitle = useMemo(() => {\r\n if (viewMode === 'day') return dateFns.format(currentDate, 'LLLL yyyy');\r\n if (viewMode === 'month') return dateFns.format(currentDate, 'yyyy');\r\n if (viewMode === 'year') {\r\n const start = yearsOfDecade[0];\r\n const end = yearsOfDecade[yearsOfDecade.length - 1];\r\n return `${end} - ${start}`;\r\n }\r\n return '';\r\n }, [currentDate, viewMode, yearsOfDecade, dateFns]);\r\n \r\n return {\r\n viewMode,\r\n currentDate,\r\n selectedDate,\r\n daysOfMonth,\r\n monthsOfYear,\r\n yearsOfDecade,\r\n headerTitle,\r\n calendarType,\r\n weekDays: getWeekDays(calendarType),\r\n dateFns,\r\n toggleCalendarType,\r\n goToNext,\r\n goToPrev,\r\n handleSelectDay,\r\n handleSelectMonth,\r\n handleSelectYear,\r\n handleHeaderClick,\r\n isSameMonthAsCurrent: (date: Date) => dateFns.isSameMonth(currentDate, date),\r\n isDateSelected,\r\n isInRange,\r\n isRangeStart,\r\n isRangeEnd,\r\n isToday: (date: Date) => dateFns.isSameDay(date, new Date()),\r\n isCurrentMonth: (monthIndex: number) => dateFns.getMonth(new Date()) === monthIndex && dateFns.getYear(new Date()) === dateFns.getYear(currentDate),\r\n isCurrentYear: (year: number) => dateFns.getYear(new Date()) === year,\r\n isYearDisabled: (year: number) => year > effectiveMaxYear || year < effectiveMinYear,\r\n };\r\n};","import * as jdf from 'date-fns-jalali';\r\nimport * as df from 'date-fns';\r\nimport { faIR } from 'date-fns-jalali/locale';\r\n\r\n// ✅ تایپ از فایل مرکزی تایپ‌ها وارد شده است\r\nimport type { CalendarType } from '../types';\r\n\r\n// ⛔️ تعریف محلی تایپ حذف شده است\r\n// export type CalendarType = 'jalali' | 'gregorian';\r\n\r\nexport interface DateFunctions {\r\n startOfMonth: (date: Date) => Date;\r\n endOfMonth: (date: Date) => Date;\r\n startOfWeek: (date: Date) => Date;\r\n endOfWeek: (date: Date) => Date;\r\n eachDayOfInterval: (interval: { start: Date; end: Date }) => Date[];\r\n isSameMonth: (dateLeft: Date, dateRight: Date) => boolean;\r\n isSameDay: (dateLeft: Date, dateRight: Date) => boolean;\r\n format: (date: Date, formatStr: string) => string;\r\n addMonths: (date: Date, amount: number) => Date;\r\n subMonths: (date: Date, amount: number) => Date;\r\n getYear: (date: Date) => number;\r\n setYear: (date: Date, year: number) => Date;\r\n getMonth: (date: Date) => number;\r\n setMonth: (date: Date, month: number) => Date;\r\n startOfYear: (date: Date) => Date;\r\n eachMonthOfInterval: (interval: { start: Date; end: Date }) => Date[];\r\n endOfYear: (date: Date) => Date;\r\n addYears: (date: Date, amount: number) => Date;\r\n subYears: (date: Date, amount: number) => Date;\r\n isDate: (value: any) => boolean;\r\n isWithinInterval: (date: Date, interval: { start: Date; end: Date }) => boolean;\r\n}\r\n\r\nexport const getDateFunctions = (type: CalendarType): DateFunctions => {\r\n const isJalali = type === 'jalali';\r\n const lib: any = isJalali ? jdf : df;\r\n\r\n return {\r\n startOfMonth: lib.startOfMonth,\r\n endOfMonth: lib.endOfMonth,\r\n startOfWeek: (date: Date) => lib.startOfWeek(date, { locale: isJalali ? faIR : undefined, weekStartsOn: isJalali ? 6 : 1 }),\r\n endOfWeek: (date: Date) => lib.endOfWeek(date, { locale: isJalali ? faIR : undefined, weekStartsOn: isJalali ? 6 : 1 }),\r\n eachDayOfInterval: lib.eachDayOfInterval,\r\n isSameMonth: lib.isSameMonth,\r\n isSameDay: lib.isSameDay,\r\n format: (date: Date, formatStr: string) => {\r\n try {\r\n return lib.format(date, formatStr, { locale: isJalali ? faIR : undefined });\r\n } catch {\r\n return '';\r\n }\r\n },\r\n addMonths: lib.addMonths,\r\n subMonths: lib.subMonths,\r\n getYear: lib.getYear,\r\n setYear: lib.setYear,\r\n getMonth: lib.getMonth,\r\n setMonth: lib.setMonth,\r\n startOfYear: lib.startOfYear,\r\n eachMonthOfInterval: lib.eachMonthOfInterval,\r\n endOfYear: lib.endOfYear,\r\n addYears: lib.addYears,\r\n subYears: lib.subYears,\r\n isDate: lib.isDate,\r\n isWithinInterval: lib.isWithinInterval,\r\n };\r\n};\r\n\r\nexport const getWeekDays = (type: CalendarType) => {\r\n if (type === 'jalali') {\r\n return ['ش', 'ی', 'د', 'س', 'چ', 'پ', 'ج'];\r\n } else {\r\n return ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'];\r\n }\r\n};","import React from 'react';\r\n\r\n// آیکون خورشید برای تقویم شمسی\r\nconst SunIcon = () => (\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <circle cx=\"12\" cy=\"12\" r=\"4\"></circle>\r\n <path d=\"M12 2v2\"></path>\r\n <path d=\"M12 20v2\"></path>\r\n <path d=\"m4.93 4.93 1.41 1.41\"></path>\r\n <path d=\"m17.66 17.66 1.41 1.41\"></path>\r\n <path d=\"M2 12h2\"></path>\r\n <path d=\"M20 12h2\"></path>\r\n <path d=\"m6.34 17.66-1.41 1.41\"></path>\r\n <path d=\"m19.07 4.93-1.41 1.41\"></path>\r\n </svg>\r\n);\r\n\r\n// آیکون کره زمین برای تقویم میلادی\r\nconst GlobeIcon = () => (\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\"></circle>\r\n <line x1=\"2\" y1=\"12\" x2=\"22\" y2=\"12\"></line>\r\n <path d=\"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z\"></path>\r\n </svg>\r\n);\r\n\r\nconst ChevronRightIcon = () => (\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><polyline points=\"9 18 15 12 9 6\"></polyline></svg>\r\n);\r\n\r\nconst ChevronLeftIcon = () => (\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><polyline points=\"15 18 9 12 15 6\"></polyline></svg>\r\n);\r\n\r\ninterface CalendarHeaderProps {\r\n title: string;\r\n calendarType: 'jalali' | 'gregorian';\r\n onToggleCalendarType: () => void;\r\n onNext: () => void;\r\n onPrev: () => void;\r\n onTitleClick: () => void;\r\n}\r\n\r\nexport const CalendarHeader: React.FC<CalendarHeaderProps> = ({\r\n title,\r\n calendarType,\r\n onToggleCalendarType,\r\n onNext,\r\n onPrev,\r\n onTitleClick,\r\n}) => {\r\n return (\r\n <div className=\"calendar-header\">\r\n {/* دکمه تغییر تقویم با آیکون */}\r\n <button \r\n type=\"button\" \r\n className={`calendar-header__toggle-btn ${calendarType}`}\r\n onClick={onToggleCalendarType}\r\n title={calendarType === 'jalali' ? \"تغییر به تقویم میلادی\" : \"Switch to Persian Calendar\"}\r\n >\r\n {calendarType === 'jalali' ? <SunIcon /> : <GlobeIcon />}\r\n </button>\r\n\r\n <div className=\"calendar-header__controls\">\r\n <button type=\"button\" className=\"calendar-header__nav-button\" onClick={onPrev} aria-label=\"قبلی\">\r\n <ChevronRightIcon />\r\n </button>\r\n <button type=\"button\" className=\"calendar-header__title\" onClick={onTitleClick}>\r\n {title}\r\n </button>\r\n <button type=\"button\" className=\"calendar-header__nav-button\" onClick={onNext} aria-label=\"بعدی\">\r\n <ChevronLeftIcon />\r\n </button>\r\n </div>\r\n </div>\r\n );\r\n};","import React from 'react';\r\nimport clsx from 'clsx';\r\nimport { DateFunctions } from '../../utils/dateAdapter';\r\n\r\nexport interface DayCellProps {\r\n date: Date;\r\n isCurrentMonth: boolean;\r\n isSelected: boolean;\r\n isToday: boolean;\r\n // ✅ پراپ‌های جدید بازه\r\n isInRange?: boolean;\r\n isRangeStart?: boolean;\r\n isRangeEnd?: boolean;\r\n isDisabled?: boolean;\r\n onClick: (date: Date) => void;\r\n dateFns: DateFunctions;\r\n}\r\n\r\nexport const DayCell: React.FC<DayCellProps> = ({\r\n date,\r\n isCurrentMonth,\r\n isSelected,\r\n isToday,\r\n isInRange = false,\r\n isRangeStart = false,\r\n isRangeEnd = false,\r\n isDisabled = false,\r\n onClick,\r\n dateFns,\r\n}) => {\r\n const dayNumber = dateFns.format(date, 'd');\r\n\r\n const cellClassName = clsx('day-cell', {\r\n 'day-cell--not-current-month': !isCurrentMonth,\r\n 'day-cell--is-today': isToday,\r\n 'day-cell--is-selected': isSelected,\r\n 'day-cell--is-disabled': isDisabled,\r\n // ✅ کلاس‌های جدید\r\n 'day-cell--in-range': isInRange,\r\n 'day-cell--range-start': isRangeStart,\r\n 'day-cell--range-end': isRangeEnd,\r\n });\r\n\r\n return (\r\n <div className={cellClassName}>\r\n <button\r\n type=\"button\"\r\n className=\"day-cell__button\"\r\n onClick={() => !isDisabled && onClick(date)}\r\n disabled={isDisabled}\r\n >\r\n {dayNumber}\r\n </button>\r\n </div>\r\n );\r\n};","import React from 'react';\r\nimport { DayCell } from './DayCell';\r\nimport { DateFunctions } from '../../utils/dateAdapter';\r\n\r\ninterface MonthViewProps {\r\n daysOfMonth: Date[];\r\n weekDays: string[];\r\n dateFns: DateFunctions;\r\n onSelectDate: (date: Date) => void;\r\n isDateSelected: (date: Date) => boolean;\r\n // ✅ پراپ‌های جدید\r\n isInRange: (date: Date) => boolean;\r\n isRangeStart: (date: Date) => boolean;\r\n isRangeEnd: (date: Date) => boolean;\r\n isSameMonthAsCurrent: (date: Date) => boolean;\r\n isToday: (date: Date) => boolean;\r\n}\r\n\r\nexport const MonthView: React.FC<MonthViewProps> = ({\r\n daysOfMonth,\r\n weekDays,\r\n dateFns,\r\n onSelectDate,\r\n isDateSelected,\r\n isInRange,\r\n isRangeStart,\r\n isRangeEnd,\r\n isSameMonthAsCurrent,\r\n isToday,\r\n}) => {\r\n return (\r\n <div className=\"month-view\">\r\n <div className=\"month-view__weekdays\">\r\n {weekDays.map(dayName => (\r\n <div key={dayName} className=\"month-view__weekday-name\">\r\n {dayName}\r\n </div>\r\n ))}\r\n </div>\r\n <div className=\"month-view__days-grid\">\r\n {daysOfMonth.map(day => (\r\n <DayCell\r\n key={day.toISOString()}\r\n date={day}\r\n onClick={onSelectDate}\r\n isSelected={isDateSelected(day)}\r\n // ✅ پاس دادن مقادیر محاسباتی\r\n isInRange={isInRange(day)}\r\n isRangeStart={isRangeStart(day)}\r\n isRangeEnd={isRangeEnd(day)}\r\n isCurrentMonth={isSameMonthAsCurrent(day)}\r\n isToday={isToday(day)}\r\n dateFns={dateFns}\r\n />\r\n ))}\r\n </div>\r\n </div>\r\n );\r\n};","import React from 'react';\r\nimport clsx from 'clsx';\r\nimport { DateFunctions } from '../../utils/dateAdapter';\r\n\r\ninterface MonthPickerViewProps {\r\n months: Date[];\r\n onSelectMonth: (monthIndex: number) => void;\r\n isCurrentMonth: (monthIndex: number) => boolean;\r\n dateFns: DateFunctions; // ✅ دریافت توابع تاریخ\r\n}\r\n\r\nexport const MonthPickerView: React.FC<MonthPickerViewProps> = ({ \r\n months, onSelectMonth, isCurrentMonth, dateFns \r\n}) => {\r\n return (\r\n <div className=\"picker-view month-picker-view\">\r\n {months.map((monthDate, index) => {\r\n const monthClassName = clsx('picker-item', {\r\n 'picker-item--is-current': isCurrentMonth(index),\r\n });\r\n \r\n return (\r\n <button\r\n key={index}\r\n type=\"button\"\r\n className={monthClassName}\r\n onClick={() => onSelectMonth(index)}\r\n >\r\n {dateFns.format(monthDate, 'LLLL')}\r\n </button>\r\n );\r\n })}\r\n </div>\r\n );\r\n};","\"use client\";\r\n\r\nimport React from 'react';\r\nimport clsx from 'clsx';\r\n\r\ninterface YearViewProps {\r\n years: number[];\r\n onSelectYear: (year: number) => void;\r\n isCurrentYear: (year: number) => boolean;\r\n isYearDisabled: (year: number) => boolean;\r\n}\r\n\r\n// ✅ اطمینان حاصل کنید که کلمه export دقیقاً قبل از const قرار دارد\r\nexport const YearView: React.FC<YearViewProps> = ({ \r\n years, \r\n onSelectYear, \r\n isCurrentYear, \r\n isYearDisabled \r\n}) => {\r\n return (\r\n <div className=\"picker-view year-picker-view\">\r\n {years.map(year => {\r\n const isDisabled = isYearDisabled(year);\r\n const yearClassName = clsx('picker-item', {\r\n 'picker-item--is-current': isCurrentYear(year),\r\n 'picker-item--is-disabled': isDisabled,\r\n });\r\n\r\n return (\r\n <button\r\n key={year}\r\n type=\"button\"\r\n className={yearClassName}\r\n onClick={() => !isDisabled && onSelectYear(year)}\r\n disabled={isDisabled}\r\n aria-current={isCurrentYear(year) ? 'true' : undefined}\r\n >\r\n {year}\r\n </button>\r\n );\r\n })}\r\n </div>\r\n );\r\n};"],"mappings":"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","names":["import_clsx","import_jsx_runtime","clsx","import_jsx_runtime","import_clsx","import_jsx_runtime","clsx","import_clsx","import_jsx_runtime","clsx","import_jsx_runtime","clsx"]}
@@ -0,0 +1,3 @@
1
+ export { PersianCalendar, type PersianCalendarProps } from "./components/Calendar/Calendar";
2
+ export * from "./types";
3
+ //# sourceMappingURL=index.react.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.react.d.ts","sourceRoot":"","sources":["../src/index.react.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAC5F,cAAc,SAAS,CAAC"}
@@ -0,0 +1,5 @@
1
+ // src/index.react.ts
2
+ "use client";
3
+ // مسیر صحیح بر اساس ساختار شما
4
+ export { PersianCalendar } from "./components/Calendar/Calendar";
5
+ export * from "./types";
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/Calendar/Calendar.tsx","../src/hooks/useCalendar.ts","../src/utils/dateAdapter.ts","../src/components/internal/CalendarHeader.tsx","../src/components/internal/DayCell.tsx","../src/components/internal/MonthView.tsx","../src/components/internal/MonthPickerView.tsx","../src/components/internal/YearView.tsx"],"sourcesContent":["\"use client\";\r\nimport React from 'react';\r\nimport clsx from 'clsx';\r\nimport { useCalendar } from '../../hooks/useCalendar';\r\nimport { CalendarHeader } from '../internal/CalendarHeader';\r\nimport { MonthView } from '../internal/MonthView';\r\nimport { MonthPickerView } from '../internal/MonthPickerView';\r\nimport { YearView } from '../internal/YearView';\r\n\r\n// ✅ مرحله ۱: ایمپورت تایپ‌های اصلی از منبع جدید و مرکزی\r\nimport type { DateRange } from '../../types';\r\n\r\n// ✅ مرحله ۲: ایمپورت تایپ‌های مخصوص هوک از خود فایل هوک\r\nimport type { UseCalendarOptions } from '../../hooks/useCalendar';\r\n\r\n// ✅ مرحله ۳: این خط حالا به درستی کار می‌کند چون DateRange از بالا ایمپورت شده است\r\nexport type { DateRange };\r\n\r\nconst CheckCircleIcon = () => (\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"M22 11.08V12a10 10 0 1 1-5.93-9.14\"></path>\r\n <polyline points=\"22 4 12 14.01 9 11.01\"></polyline>\r\n </svg>\r\n);\r\n\r\nexport interface PersianCalendarProps extends Omit<UseCalendarOptions, 'range'> {\r\n onDateSelect?: (date: Date | null) => void;\r\n range?: DateRange;\r\n className?: string;\r\n}\r\n\r\nexport const PersianCalendar: React.FC<PersianCalendarProps> = ({ \r\n initialDate, \r\n onDateSelect,\r\n minYear,\r\n maxYear,\r\n range,\r\n className\r\n}) => {\r\n const {\r\n viewMode,\r\n daysOfMonth,\r\n monthsOfYear,\r\n yearsOfDecade,\r\n headerTitle,\r\n calendarType,\r\n weekDays,\r\n dateFns,\r\n toggleCalendarType,\r\n goToNext,\r\n goToPrev,\r\n handleSelectDay,\r\n handleSelectMonth,\r\n handleSelectYear,\r\n handleHeaderClick,\r\n isDateSelected,\r\n isInRange,\r\n isRangeStart,\r\n isRangeEnd,\r\n isSameMonthAsCurrent,\r\n isToday,\r\n isCurrentMonth,\r\n isCurrentYear,\r\n isYearDisabled,\r\n } = useCalendar({ initialDate, minYear, maxYear, range });\r\n\r\n const onDayClick = (date: Date) => {\r\n handleSelectDay(date);\r\n if (onDateSelect) {\r\n onDateSelect(date);\r\n }\r\n };\r\n\r\n const renderView = () => {\r\n switch (viewMode) {\r\n case 'year':\r\n return <YearView years={yearsOfDecade} onSelectYear={handleSelectYear} isCurrentYear={isCurrentYear} isYearDisabled={isYearDisabled} />;\r\n case 'month':\r\n return <MonthPickerView months={monthsOfYear} onSelectMonth={handleSelectMonth} isCurrentMonth={isCurrentMonth} dateFns={dateFns} />;\r\n case 'day':\r\n default:\r\n return (\r\n <MonthView\r\n daysOfMonth={daysOfMonth}\r\n weekDays={weekDays}\r\n dateFns={dateFns}\r\n onSelectDate={onDayClick}\r\n isDateSelected={isDateSelected}\r\n isInRange={isInRange}\r\n isRangeStart={isRangeStart}\r\n isRangeEnd={isRangeEnd}\r\n isSameMonthAsCurrent={isSameMonthAsCurrent}\r\n isToday={isToday}\r\n />\r\n );\r\n }\r\n };\r\n\r\n return (\r\n <div className={clsx(\"prc-container\", className)} dir={calendarType === 'jalali' ? 'rtl' : 'ltr'}>\r\n <CalendarHeader\r\n title={headerTitle}\r\n calendarType={calendarType}\r\n onToggleCalendarType={toggleCalendarType}\r\n onNext={goToNext}\r\n onPrev={goToPrev}\r\n onTitleClick={handleHeaderClick}\r\n />\r\n <div className=\"prc-view-container\">\r\n {renderView()}\r\n </div>\r\n \r\n <footer className=\"prc-footer\">\r\n <span>𝓟𝓸𝔀𝓮𝓻𝓮𝓭 𝓫𝔂 𝓜𝓮𝓱𝓭𝓲 𝓐𝓴𝓫𝓪𝓻𝓲</span>\r\n <CheckCircleIcon />\r\n </footer>\r\n </div>\r\n );\r\n};","\"use client\";\r\nimport { useState, useMemo, useCallback } from 'react';\r\n\r\n// ✅ مرحله ۱: ایمپورت توابع از dateAdapter\r\nimport { getDateFunctions, getWeekDays } from '../utils/dateAdapter';\r\n\r\n// ✅ مرحله ۲: ایمپورت تمام تایپ‌های مورد نیاز از فایل مرکزی تایپ‌ها\r\nimport type { CalendarViewMode, DateRange, CalendarType } from '../types';\r\n\r\n// ⛔️ تعریف‌های محلی تایپ‌ها حذف شدند تا از یک منبع واحد استفاده شود.\r\n// export type CalendarViewMode = 'day' | 'month' | 'year';\r\n// export interface DateRange {\r\n// from: Date | null;\r\n// to: Date | null;\r\n// }\r\n\r\nexport interface UseCalendarOptions {\r\n initialDate?: Date;\r\n minYear?: number;\r\n maxYear?: number;\r\n initialCalendarType?: CalendarType;\r\n range?: DateRange;\r\n}\r\n\r\nexport const useCalendar = ({ \r\n initialDate = new Date(),\r\n minYear = 1300,\r\n maxYear = 1405,\r\n initialCalendarType = 'jalali',\r\n range\r\n}: UseCalendarOptions = {}) => {\r\n \r\n const [calendarType, setCalendarType] = useState<CalendarType>(initialCalendarType);\r\n const dateFns = useMemo(() => getDateFunctions(calendarType), [calendarType]);\r\n\r\n const effectiveMinYear = calendarType === 'gregorian' && minYear === 1300 ? 1920 : minYear;\r\n const effectiveMaxYear = calendarType === 'gregorian' && maxYear === 1405 ? 2030 : maxYear;\r\n\r\n const [viewMode, setViewMode] = useState<CalendarViewMode>('day');\r\n const [currentDate, setCurrentDate] = useState(dateFns.startOfMonth(initialDate));\r\n const [selectedDate, setSelectedDate] = useState<Date | null>(initialDate);\r\n\r\n const daysOfMonth = useMemo(() => {\r\n if (viewMode !== 'day') return [];\r\n const monthStart = dateFns.startOfMonth(currentDate);\r\n const monthEnd = dateFns.endOfMonth(currentDate);\r\n const startDate = dateFns.startOfWeek(monthStart);\r\n const endDate = dateFns.endOfWeek(monthEnd);\r\n return dateFns.eachDayOfInterval({ start: startDate, end: endDate });\r\n }, [currentDate, viewMode, dateFns]);\r\n\r\n const monthsOfYear = useMemo(() => {\r\n if (viewMode !== 'month') return [];\r\n return dateFns.eachMonthOfInterval({\r\n start: dateFns.startOfYear(currentDate),\r\n end: dateFns.endOfYear(currentDate),\r\n });\r\n }, [currentDate, viewMode, dateFns]);\r\n \r\n const yearsOfDecade = useMemo(() => {\r\n if (viewMode !== 'year') return [];\r\n const year = dateFns.getYear(currentDate);\r\n const decadeStartYear = Math.floor(year / 10) * 10;\r\n const years = [];\r\n for (let i = 0; i < 12; i++) {\r\n years.push(decadeStartYear + i - 1);\r\n }\r\n return years;\r\n }, [currentDate, viewMode, dateFns]);\r\n\r\n const goToNext = useCallback(() => {\r\n if (viewMode === 'day') setCurrentDate(prev => dateFns.addMonths(prev, 1));\r\n if (viewMode === 'month') setCurrentDate(prev => dateFns.addYears(prev, 1));\r\n if (viewMode === 'year') setCurrentDate(prev => dateFns.addYears(prev, 10));\r\n }, [viewMode, dateFns]);\r\n\r\n const goToPrev = useCallback(() => {\r\n if (viewMode === 'day') setCurrentDate(prev => dateFns.subMonths(prev, 1));\r\n if (viewMode === 'month') setCurrentDate(prev => dateFns.subYears(prev, 1));\r\n if (viewMode === 'year') setCurrentDate(prev => dateFns.subYears(prev, 10));\r\n }, [viewMode, dateFns]);\r\n\r\n const handleSelectDay = useCallback((date: Date) => {\r\n setSelectedDate(date);\r\n if (!dateFns.isSameMonth(currentDate, date)) {\r\n setCurrentDate(dateFns.startOfMonth(date));\r\n }\r\n }, [currentDate, dateFns]);\r\n\r\n const handleSelectMonth = useCallback((monthIndex: number) => {\r\n setCurrentDate(prev => dateFns.setMonth(prev, monthIndex));\r\n setViewMode('day');\r\n }, [dateFns]);\r\n\r\n const handleSelectYear = useCallback((year: number) => {\r\n setCurrentDate(prev => dateFns.setYear(prev, year));\r\n setViewMode('month');\r\n }, [dateFns]);\r\n \r\n const handleHeaderClick = useCallback(() => {\r\n if (viewMode === 'day') setViewMode('month');\r\n if (viewMode === 'month') setViewMode('year');\r\n }, [viewMode]);\r\n\r\n const toggleCalendarType = useCallback(() => {\r\n setCalendarType(prev => prev === 'jalali' ? 'gregorian' : 'jalali');\r\n setViewMode('day');\r\n }, []);\r\n\r\n const isDateSelected = useCallback((date: Date): boolean => {\r\n if (range) {\r\n return !!((range.from && dateFns.isSameDay(date, range.from)) || \r\n (range.to && dateFns.isSameDay(date, range.to)));\r\n }\r\n return selectedDate ? dateFns.isSameDay(date, selectedDate) : false;\r\n }, [selectedDate, range, dateFns]);\r\n\r\n const isInRange = useCallback((date: Date): boolean => {\r\n if (!range?.from || !range?.to) return false;\r\n return dateFns.isWithinInterval(date, { start: range.from, end: range.to });\r\n }, [range, dateFns]);\r\n\r\n const isRangeStart = useCallback((date: Date): boolean => {\r\n return !!(range?.from && dateFns.isSameDay(date, range.from));\r\n }, [range, dateFns]);\r\n\r\n const isRangeEnd = useCallback((date: Date): boolean => {\r\n return !!(range?.to && dateFns.isSameDay(date, range.to));\r\n }, [range, dateFns]);\r\n\r\n const headerTitle = useMemo(() => {\r\n if (viewMode === 'day') return dateFns.format(currentDate, 'LLLL yyyy');\r\n if (viewMode === 'month') return dateFns.format(currentDate, 'yyyy');\r\n if (viewMode === 'year') {\r\n const start = yearsOfDecade[0];\r\n const end = yearsOfDecade[yearsOfDecade.length - 1];\r\n return `${end} - ${start}`;\r\n }\r\n return '';\r\n }, [currentDate, viewMode, yearsOfDecade, dateFns]);\r\n \r\n return {\r\n viewMode,\r\n currentDate,\r\n selectedDate,\r\n daysOfMonth,\r\n monthsOfYear,\r\n yearsOfDecade,\r\n headerTitle,\r\n calendarType,\r\n weekDays: getWeekDays(calendarType),\r\n dateFns,\r\n toggleCalendarType,\r\n goToNext,\r\n goToPrev,\r\n handleSelectDay,\r\n handleSelectMonth,\r\n handleSelectYear,\r\n handleHeaderClick,\r\n isSameMonthAsCurrent: (date: Date) => dateFns.isSameMonth(currentDate, date),\r\n isDateSelected,\r\n isInRange,\r\n isRangeStart,\r\n isRangeEnd,\r\n isToday: (date: Date) => dateFns.isSameDay(date, new Date()),\r\n isCurrentMonth: (monthIndex: number) => dateFns.getMonth(new Date()) === monthIndex && dateFns.getYear(new Date()) === dateFns.getYear(currentDate),\r\n isCurrentYear: (year: number) => dateFns.getYear(new Date()) === year,\r\n isYearDisabled: (year: number) => year > effectiveMaxYear || year < effectiveMinYear,\r\n };\r\n};","import * as jdf from 'date-fns-jalali';\r\nimport * as df from 'date-fns';\r\nimport { faIR } from 'date-fns-jalali/locale';\r\n\r\n// ✅ تایپ از فایل مرکزی تایپ‌ها وارد شده است\r\nimport type { CalendarType } from '../types';\r\n\r\n// ⛔️ تعریف محلی تایپ حذف شده است\r\n// export type CalendarType = 'jalali' | 'gregorian';\r\n\r\nexport interface DateFunctions {\r\n startOfMonth: (date: Date) => Date;\r\n endOfMonth: (date: Date) => Date;\r\n startOfWeek: (date: Date) => Date;\r\n endOfWeek: (date: Date) => Date;\r\n eachDayOfInterval: (interval: { start: Date; end: Date }) => Date[];\r\n isSameMonth: (dateLeft: Date, dateRight: Date) => boolean;\r\n isSameDay: (dateLeft: Date, dateRight: Date) => boolean;\r\n format: (date: Date, formatStr: string) => string;\r\n addMonths: (date: Date, amount: number) => Date;\r\n subMonths: (date: Date, amount: number) => Date;\r\n getYear: (date: Date) => number;\r\n setYear: (date: Date, year: number) => Date;\r\n getMonth: (date: Date) => number;\r\n setMonth: (date: Date, month: number) => Date;\r\n startOfYear: (date: Date) => Date;\r\n eachMonthOfInterval: (interval: { start: Date; end: Date }) => Date[];\r\n endOfYear: (date: Date) => Date;\r\n addYears: (date: Date, amount: number) => Date;\r\n subYears: (date: Date, amount: number) => Date;\r\n isDate: (value: any) => boolean;\r\n isWithinInterval: (date: Date, interval: { start: Date; end: Date }) => boolean;\r\n}\r\n\r\nexport const getDateFunctions = (type: CalendarType): DateFunctions => {\r\n const isJalali = type === 'jalali';\r\n const lib: any = isJalali ? jdf : df;\r\n\r\n return {\r\n startOfMonth: lib.startOfMonth,\r\n endOfMonth: lib.endOfMonth,\r\n startOfWeek: (date: Date) => lib.startOfWeek(date, { locale: isJalali ? faIR : undefined, weekStartsOn: isJalali ? 6 : 1 }),\r\n endOfWeek: (date: Date) => lib.endOfWeek(date, { locale: isJalali ? faIR : undefined, weekStartsOn: isJalali ? 6 : 1 }),\r\n eachDayOfInterval: lib.eachDayOfInterval,\r\n isSameMonth: lib.isSameMonth,\r\n isSameDay: lib.isSameDay,\r\n format: (date: Date, formatStr: string) => {\r\n try {\r\n return lib.format(date, formatStr, { locale: isJalali ? faIR : undefined });\r\n } catch {\r\n return '';\r\n }\r\n },\r\n addMonths: lib.addMonths,\r\n subMonths: lib.subMonths,\r\n getYear: lib.getYear,\r\n setYear: lib.setYear,\r\n getMonth: lib.getMonth,\r\n setMonth: lib.setMonth,\r\n startOfYear: lib.startOfYear,\r\n eachMonthOfInterval: lib.eachMonthOfInterval,\r\n endOfYear: lib.endOfYear,\r\n addYears: lib.addYears,\r\n subYears: lib.subYears,\r\n isDate: lib.isDate,\r\n isWithinInterval: lib.isWithinInterval,\r\n };\r\n};\r\n\r\nexport const getWeekDays = (type: CalendarType) => {\r\n if (type === 'jalali') {\r\n return ['ش', 'ی', 'د', 'س', 'چ', 'پ', 'ج'];\r\n } else {\r\n return ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'];\r\n }\r\n};","import React from 'react';\r\n\r\n// آیکون خورشید برای تقویم شمسی\r\nconst SunIcon = () => (\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <circle cx=\"12\" cy=\"12\" r=\"4\"></circle>\r\n <path d=\"M12 2v2\"></path>\r\n <path d=\"M12 20v2\"></path>\r\n <path d=\"m4.93 4.93 1.41 1.41\"></path>\r\n <path d=\"m17.66 17.66 1.41 1.41\"></path>\r\n <path d=\"M2 12h2\"></path>\r\n <path d=\"M20 12h2\"></path>\r\n <path d=\"m6.34 17.66-1.41 1.41\"></path>\r\n <path d=\"m19.07 4.93-1.41 1.41\"></path>\r\n </svg>\r\n);\r\n\r\n// آیکون کره زمین برای تقویم میلادی\r\nconst GlobeIcon = () => (\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\"></circle>\r\n <line x1=\"2\" y1=\"12\" x2=\"22\" y2=\"12\"></line>\r\n <path d=\"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z\"></path>\r\n </svg>\r\n);\r\n\r\nconst ChevronRightIcon = () => (\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><polyline points=\"9 18 15 12 9 6\"></polyline></svg>\r\n);\r\n\r\nconst ChevronLeftIcon = () => (\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><polyline points=\"15 18 9 12 15 6\"></polyline></svg>\r\n);\r\n\r\ninterface CalendarHeaderProps {\r\n title: string;\r\n calendarType: 'jalali' | 'gregorian';\r\n onToggleCalendarType: () => void;\r\n onNext: () => void;\r\n onPrev: () => void;\r\n onTitleClick: () => void;\r\n}\r\n\r\nexport const CalendarHeader: React.FC<CalendarHeaderProps> = ({\r\n title,\r\n calendarType,\r\n onToggleCalendarType,\r\n onNext,\r\n onPrev,\r\n onTitleClick,\r\n}) => {\r\n return (\r\n <div className=\"calendar-header\">\r\n {/* دکمه تغییر تقویم با آیکون */}\r\n <button \r\n type=\"button\" \r\n className={`calendar-header__toggle-btn ${calendarType}`}\r\n onClick={onToggleCalendarType}\r\n title={calendarType === 'jalali' ? \"تغییر به تقویم میلادی\" : \"Switch to Persian Calendar\"}\r\n >\r\n {calendarType === 'jalali' ? <SunIcon /> : <GlobeIcon />}\r\n </button>\r\n\r\n <div className=\"calendar-header__controls\">\r\n <button type=\"button\" className=\"calendar-header__nav-button\" onClick={onPrev} aria-label=\"قبلی\">\r\n <ChevronRightIcon />\r\n </button>\r\n <button type=\"button\" className=\"calendar-header__title\" onClick={onTitleClick}>\r\n {title}\r\n </button>\r\n <button type=\"button\" className=\"calendar-header__nav-button\" onClick={onNext} aria-label=\"بعدی\">\r\n <ChevronLeftIcon />\r\n </button>\r\n </div>\r\n </div>\r\n );\r\n};","import React from 'react';\r\nimport clsx from 'clsx';\r\nimport { DateFunctions } from '../../utils/dateAdapter';\r\n\r\nexport interface DayCellProps {\r\n date: Date;\r\n isCurrentMonth: boolean;\r\n isSelected: boolean;\r\n isToday: boolean;\r\n // ✅ پراپ‌های جدید بازه\r\n isInRange?: boolean;\r\n isRangeStart?: boolean;\r\n isRangeEnd?: boolean;\r\n isDisabled?: boolean;\r\n onClick: (date: Date) => void;\r\n dateFns: DateFunctions;\r\n}\r\n\r\nexport const DayCell: React.FC<DayCellProps> = ({\r\n date,\r\n isCurrentMonth,\r\n isSelected,\r\n isToday,\r\n isInRange = false,\r\n isRangeStart = false,\r\n isRangeEnd = false,\r\n isDisabled = false,\r\n onClick,\r\n dateFns,\r\n}) => {\r\n const dayNumber = dateFns.format(date, 'd');\r\n\r\n const cellClassName = clsx('day-cell', {\r\n 'day-cell--not-current-month': !isCurrentMonth,\r\n 'day-cell--is-today': isToday,\r\n 'day-cell--is-selected': isSelected,\r\n 'day-cell--is-disabled': isDisabled,\r\n // ✅ کلاس‌های جدید\r\n 'day-cell--in-range': isInRange,\r\n 'day-cell--range-start': isRangeStart,\r\n 'day-cell--range-end': isRangeEnd,\r\n });\r\n\r\n return (\r\n <div className={cellClassName}>\r\n <button\r\n type=\"button\"\r\n className=\"day-cell__button\"\r\n onClick={() => !isDisabled && onClick(date)}\r\n disabled={isDisabled}\r\n >\r\n {dayNumber}\r\n </button>\r\n </div>\r\n );\r\n};","import React from 'react';\r\nimport { DayCell } from './DayCell';\r\nimport { DateFunctions } from '../../utils/dateAdapter';\r\n\r\ninterface MonthViewProps {\r\n daysOfMonth: Date[];\r\n weekDays: string[];\r\n dateFns: DateFunctions;\r\n onSelectDate: (date: Date) => void;\r\n isDateSelected: (date: Date) => boolean;\r\n // ✅ پراپ‌های جدید\r\n isInRange: (date: Date) => boolean;\r\n isRangeStart: (date: Date) => boolean;\r\n isRangeEnd: (date: Date) => boolean;\r\n isSameMonthAsCurrent: (date: Date) => boolean;\r\n isToday: (date: Date) => boolean;\r\n}\r\n\r\nexport const MonthView: React.FC<MonthViewProps> = ({\r\n daysOfMonth,\r\n weekDays,\r\n dateFns,\r\n onSelectDate,\r\n isDateSelected,\r\n isInRange,\r\n isRangeStart,\r\n isRangeEnd,\r\n isSameMonthAsCurrent,\r\n isToday,\r\n}) => {\r\n return (\r\n <div className=\"month-view\">\r\n <div className=\"month-view__weekdays\">\r\n {weekDays.map(dayName => (\r\n <div key={dayName} className=\"month-view__weekday-name\">\r\n {dayName}\r\n </div>\r\n ))}\r\n </div>\r\n <div className=\"month-view__days-grid\">\r\n {daysOfMonth.map(day => (\r\n <DayCell\r\n key={day.toISOString()}\r\n date={day}\r\n onClick={onSelectDate}\r\n isSelected={isDateSelected(day)}\r\n // ✅ پاس دادن مقادیر محاسباتی\r\n isInRange={isInRange(day)}\r\n isRangeStart={isRangeStart(day)}\r\n isRangeEnd={isRangeEnd(day)}\r\n isCurrentMonth={isSameMonthAsCurrent(day)}\r\n isToday={isToday(day)}\r\n dateFns={dateFns}\r\n />\r\n ))}\r\n </div>\r\n </div>\r\n );\r\n};","import React from 'react';\r\nimport clsx from 'clsx';\r\nimport { DateFunctions } from '../../utils/dateAdapter';\r\n\r\ninterface MonthPickerViewProps {\r\n months: Date[];\r\n onSelectMonth: (monthIndex: number) => void;\r\n isCurrentMonth: (monthIndex: number) => boolean;\r\n dateFns: DateFunctions; // ✅ دریافت توابع تاریخ\r\n}\r\n\r\nexport const MonthPickerView: React.FC<MonthPickerViewProps> = ({ \r\n months, onSelectMonth, isCurrentMonth, dateFns \r\n}) => {\r\n return (\r\n <div className=\"picker-view month-picker-view\">\r\n {months.map((monthDate, index) => {\r\n const monthClassName = clsx('picker-item', {\r\n 'picker-item--is-current': isCurrentMonth(index),\r\n });\r\n \r\n return (\r\n <button\r\n key={index}\r\n type=\"button\"\r\n className={monthClassName}\r\n onClick={() => onSelectMonth(index)}\r\n >\r\n {dateFns.format(monthDate, 'LLLL')}\r\n </button>\r\n );\r\n })}\r\n </div>\r\n );\r\n};","\"use client\";\r\n\r\nimport React from 'react';\r\nimport clsx from 'clsx';\r\n\r\ninterface YearViewProps {\r\n years: number[];\r\n onSelectYear: (year: number) => void;\r\n isCurrentYear: (year: number) => boolean;\r\n isYearDisabled: (year: number) => boolean;\r\n}\r\n\r\n// ✅ اطمینان حاصل کنید که کلمه export دقیقاً قبل از const قرار دارد\r\nexport const YearView: React.FC<YearViewProps> = ({ \r\n years, \r\n onSelectYear, \r\n isCurrentYear, \r\n isYearDisabled \r\n}) => {\r\n return (\r\n <div className=\"picker-view year-picker-view\">\r\n {years.map(year => {\r\n const isDisabled = isYearDisabled(year);\r\n const yearClassName = clsx('picker-item', {\r\n 'picker-item--is-current': isCurrentYear(year),\r\n 'picker-item--is-disabled': isDisabled,\r\n });\r\n\r\n return (\r\n <button\r\n key={year}\r\n type=\"button\"\r\n className={yearClassName}\r\n onClick={() => !isDisabled && onSelectYear(year)}\r\n disabled={isDisabled}\r\n aria-current={isCurrentYear(year) ? 'true' : undefined}\r\n >\r\n {year}\r\n </button>\r\n );\r\n })}\r\n </div>\r\n );\r\n};"],"mappings":"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","names":["clsx","jsx","jsx","jsxs","clsx","jsx","clsx","jsx","jsx","jsxs","clsx"]}
@@ -0,0 +1,2 @@
1
+ // src/types/index.ts
2
+ export {};
@@ -0,0 +1,45 @@
1
+ import * as jdf from 'date-fns-jalali';
2
+ import * as df from 'date-fns';
3
+ import { faIR } from 'date-fns-jalali/locale';
4
+ export const getDateFunctions = (type) => {
5
+ const isJalali = type === 'jalali';
6
+ const lib = isJalali ? jdf : df;
7
+ return {
8
+ startOfMonth: lib.startOfMonth,
9
+ endOfMonth: lib.endOfMonth,
10
+ startOfWeek: (date) => lib.startOfWeek(date, { locale: isJalali ? faIR : undefined, weekStartsOn: isJalali ? 6 : 1 }),
11
+ endOfWeek: (date) => lib.endOfWeek(date, { locale: isJalali ? faIR : undefined, weekStartsOn: isJalali ? 6 : 1 }),
12
+ eachDayOfInterval: lib.eachDayOfInterval,
13
+ isSameMonth: lib.isSameMonth,
14
+ isSameDay: lib.isSameDay,
15
+ format: (date, formatStr) => {
16
+ try {
17
+ return lib.format(date, formatStr, { locale: isJalali ? faIR : undefined });
18
+ }
19
+ catch {
20
+ return '';
21
+ }
22
+ },
23
+ addMonths: lib.addMonths,
24
+ subMonths: lib.subMonths,
25
+ getYear: lib.getYear,
26
+ setYear: lib.setYear,
27
+ getMonth: lib.getMonth,
28
+ setMonth: lib.setMonth,
29
+ startOfYear: lib.startOfYear,
30
+ eachMonthOfInterval: lib.eachMonthOfInterval,
31
+ endOfYear: lib.endOfYear,
32
+ addYears: lib.addYears,
33
+ subYears: lib.subYears,
34
+ isDate: lib.isDate,
35
+ isWithinInterval: lib.isWithinInterval,
36
+ };
37
+ };
38
+ export const getWeekDays = (type) => {
39
+ if (type === 'jalali') {
40
+ return ['ش', 'ی', 'د', 'س', 'چ', 'پ', 'ج'];
41
+ }
42
+ else {
43
+ return ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'];
44
+ }
45
+ };
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "mehdi-akbari-calendar",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "A professional and customizable Persian (Jalali) calendar component for React.",
5
- "type": "module",
5
+ "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.mjs",
8
8
  "types": "./dist/index.d.ts",
@@ -35,7 +35,7 @@
35
35
  "scripts": {
36
36
  "clean": "npx rimraf dist",
37
37
  "build:js": "tsup",
38
- "build:types": "tsc --emitDeclarationOnly --declaration",
38
+ "build:types": "tsc --project tsconfig.json",
39
39
  "build": "npm run clean && npm run build:js && npm run build:types && copyfiles -u 1 src/styles.css dist",
40
40
  "dev": "tsup --watch",
41
41
  "prepublishOnly": "npm run build"
@@ -53,7 +53,6 @@
53
53
  "@types/react": "^18.3.3",
54
54
  "@types/react-dom": "^18.3.0",
55
55
  "copyfiles": "^2.4.1",
56
- "npx": "^10.2.2",
57
56
  "react": "^18.3.1",
58
57
  "react-dom": "^18.3.1",
59
58
  "rimraf": "^5.0.7",
package/dist/react.d.ts DELETED
@@ -1,7 +0,0 @@
1
- /**
2
- * This is the entry point for React components.
3
- * It exports the main PersianCalendar component and its related types.
4
- */
5
- export { PersianCalendar, type PersianCalendarProps } from "./components/Calendar/Calendar";
6
- export * from "./types";
7
- //# sourceMappingURL=react.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAGA;;;GAGG;AAGH,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAG5F,cAAc,SAAS,CAAC"}