mehdi-akbari-calendar 0.1.1 → 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.
Files changed (43) hide show
  1. package/dist/components/Calendar/Calendar.d.ts +1 -0
  2. package/dist/components/Calendar/Calendar.d.ts.map +1 -0
  3. package/dist/components/Calendar/Calendar.js +30 -0
  4. package/dist/components/internal/CalendarHeader.d.ts +1 -0
  5. package/dist/components/internal/CalendarHeader.d.ts.map +1 -0
  6. package/dist/components/internal/CalendarHeader.js +10 -0
  7. package/dist/components/internal/DayCell.d.ts +1 -0
  8. package/dist/components/internal/DayCell.d.ts.map +1 -0
  9. package/dist/components/internal/DayCell.js +16 -0
  10. package/dist/components/internal/MonthPickerView.d.ts +1 -0
  11. package/dist/components/internal/MonthPickerView.d.ts.map +1 -0
  12. package/dist/components/internal/MonthPickerView.js +10 -0
  13. package/dist/components/internal/MonthView.d.ts +1 -0
  14. package/dist/components/internal/MonthView.d.ts.map +1 -0
  15. package/dist/components/internal/MonthView.js +7 -0
  16. package/dist/components/internal/YearView.d.ts +1 -0
  17. package/dist/components/internal/YearView.d.ts.map +1 -0
  18. package/dist/components/internal/YearView.js +14 -0
  19. package/dist/hooks/useCalendar.d.ts +1 -0
  20. package/dist/hooks/useCalendar.d.ts.map +1 -0
  21. package/dist/hooks/useCalendar.js +139 -0
  22. package/dist/index.cjs +19 -0
  23. package/dist/index.cjs.map +1 -0
  24. package/dist/index.d.ts +1 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +7 -18
  27. package/dist/index.js.map +1 -1
  28. package/dist/index.react.cjs +486 -0
  29. package/dist/index.react.cjs.map +1 -0
  30. package/dist/index.react.d.ts +3 -0
  31. package/dist/index.react.d.ts.map +1 -0
  32. package/dist/index.react.js +5 -0
  33. package/dist/index.react.js.map +1 -0
  34. package/dist/types/index.d.ts +1 -0
  35. package/dist/types/index.d.ts.map +1 -0
  36. package/dist/types/index.js +2 -0
  37. package/dist/utils/dateAdapter.d.ts +1 -0
  38. package/dist/utils/dateAdapter.d.ts.map +1 -0
  39. package/dist/utils/dateAdapter.js +45 -0
  40. package/package.json +29 -28
  41. package/dist/index.mjs +0 -1
  42. package/dist/index.mjs.map +0 -1
  43. package/dist/react.d.ts +0 -6
@@ -8,3 +8,4 @@ export interface PersianCalendarProps extends Omit<UseCalendarOptions, 'range'>
8
8
  className?: string;
9
9
  }
10
10
  export declare const PersianCalendar: React.FC<PersianCalendarProps>;
11
+ //# sourceMappingURL=Calendar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Calendar.d.ts","sourceRoot":"","sources":["../../../src/components/Calendar/Calendar.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAS1B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAG7C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAGlE,YAAY,EAAE,SAAS,EAAE,CAAC;AAS1B,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAAC,kBAAkB,EAAE,OAAO,CAAC;IAC7E,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,IAAI,CAAC;IAC3C,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAuF1D,CAAC"}
@@ -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
+ };
@@ -9,3 +9,4 @@ interface CalendarHeaderProps {
9
9
  }
10
10
  export declare const CalendarHeader: React.FC<CalendarHeaderProps>;
11
11
  export {};
12
+ //# sourceMappingURL=CalendarHeader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CalendarHeader.d.ts","sourceRoot":"","sources":["../../../src/components/internal/CalendarHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAkC1B,UAAU,mBAAmB;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,QAAQ,GAAG,WAAW,CAAC;IACrC,oBAAoB,EAAE,MAAM,IAAI,CAAC;IACjC,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,YAAY,EAAE,MAAM,IAAI,CAAC;CAC1B;AAED,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAiCxD,CAAC"}
@@ -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
+ };
@@ -13,3 +13,4 @@ export interface DayCellProps {
13
13
  dateFns: DateFunctions;
14
14
  }
15
15
  export declare const DayCell: React.FC<DayCellProps>;
16
+ //# sourceMappingURL=DayCell.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DayCell.d.ts","sourceRoot":"","sources":["../../../src/components/internal/DayCell.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,IAAI,CAAC;IACX,cAAc,EAAE,OAAO,CAAC;IACxB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IAEjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAC9B,OAAO,EAAE,aAAa,CAAC;CACxB;AAED,eAAO,MAAM,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,YAAY,CAqC1C,CAAC"}
@@ -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
+ };
@@ -8,3 +8,4 @@ interface MonthPickerViewProps {
8
8
  }
9
9
  export declare const MonthPickerView: React.FC<MonthPickerViewProps>;
10
10
  export {};
11
+ //# sourceMappingURL=MonthPickerView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MonthPickerView.d.ts","sourceRoot":"","sources":["../../../src/components/internal/MonthPickerView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD,UAAU,oBAAoB;IAC5B,MAAM,EAAE,IAAI,EAAE,CAAC;IACf,aAAa,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,cAAc,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC;IAChD,OAAO,EAAE,aAAa,CAAC;CACxB;AAED,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAuB1D,CAAC"}
@@ -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
+ };
@@ -14,3 +14,4 @@ interface MonthViewProps {
14
14
  }
15
15
  export declare const MonthView: React.FC<MonthViewProps>;
16
16
  export {};
17
+ //# sourceMappingURL=MonthView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MonthView.d.ts","sourceRoot":"","sources":["../../../src/components/internal/MonthView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD,UAAU,cAAc;IACtB,WAAW,EAAE,IAAI,EAAE,CAAC;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,aAAa,CAAC;IACvB,YAAY,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACnC,cAAc,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC;IAExC,SAAS,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC;IACnC,YAAY,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC;IACtC,UAAU,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC;IACpC,oBAAoB,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC;IAC9C,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC;CAClC;AAED,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAwC9C,CAAC"}
@@ -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
+ };
@@ -7,3 +7,4 @@ interface YearViewProps {
7
7
  }
8
8
  export declare const YearView: React.FC<YearViewProps>;
9
9
  export {};
10
+ //# sourceMappingURL=YearView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"YearView.d.ts","sourceRoot":"","sources":["../../../src/components/internal/YearView.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,UAAU,aAAa;IACrB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IACzC,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;CAC3C;AAGD,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CA8B5C,CAAC"}
@@ -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
+ };
@@ -34,3 +34,4 @@ export declare const useCalendar: ({ initialDate, minYear, maxYear, initialCalen
34
34
  isCurrentYear: (year: number) => boolean;
35
35
  isYearDisabled: (year: number) => boolean;
36
36
  };
37
+ //# sourceMappingURL=useCalendar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCalendar.d.ts","sourceRoot":"","sources":["../../src/hooks/useCalendar.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAS1E,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,EAAE,IAAI,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mBAAmB,CAAC,EAAE,YAAY,CAAC;IACnC,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAED,eAAO,MAAM,WAAW,GAAI,gEAMzB,kBAAuB;;;;;;;;;;;;;;4BAoDmB,IAAI;oCAOI,MAAM;6BAKb,MAAM;;iCAiEnB,IAAI;2BAlDO,IAAI,KAAG,OAAO;sBAQnB,IAAI,KAAG,OAAO;yBAKX,IAAI,KAAG,OAAO;uBAIhB,IAAI,KAAG,OAAO;oBAsClC,IAAI;iCACS,MAAM;0BACb,MAAM;2BACL,MAAM;CAEhC,CAAC"}
@@ -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.cjs ADDED
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+
16
+ // src/index.ts
17
+ var index_exports = {};
18
+ module.exports = __toCommonJS(index_exports);
19
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["// src/index.ts\r\n\r\n/**\r\n * This is the main entry point for non-React functionalities and types.\r\n * It allows users to import types or utility functions without pulling in React.\r\n */\r\n\r\nexport * from \"./types\";\r\n\r\n// In the future, you could also export utility functions from here:\r\n// export * from \"./utils/dateAdapter\";"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
package/dist/index.d.ts CHANGED
@@ -3,3 +3,4 @@
3
3
  * It allows users to import types or utility functions without pulling in React.
4
4
  */
5
5
  export * from "./types";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA;;;GAGG;AAEH,cAAc,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -1,19 +1,8 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __copyProps = (to, from, except, desc) => {
7
- if (from && typeof from === "object" || typeof from === "function") {
8
- for (let key of __getOwnPropNames(from))
9
- if (!__hasOwnProp.call(to, key) && key !== except)
10
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
- }
12
- return to;
13
- };
14
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
-
16
1
  // src/index.ts
17
- var index_exports = {};
18
- module.exports = __toCommonJS(index_exports);
19
- //# sourceMappingURL=index.js.map
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";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["// src/index.ts\r\n\r\n/**\r\n * This is the main entry point for non-React functionalities and types.\r\n * It allows users to import types or utility functions without pulling in React.\r\n */\r\n\r\nexport * from \"./types\";\r\n\r\n// In the future, you could also export utility functions from here:\r\n// export * from \"./utils/dateAdapter\";"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}