react-day-picker 9.13.2 → 10.0.0-next.0

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 (180) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/DayPicker.js +85 -83
  3. package/dist/cjs/UI.d.ts +0 -230
  4. package/dist/cjs/classes/DateLib.d.ts +0 -21
  5. package/dist/cjs/classes/DateLib.js +3 -13
  6. package/dist/cjs/components/Dropdown.d.ts +0 -11
  7. package/dist/cjs/components/Dropdown.js +3 -1
  8. package/dist/cjs/components/NextMonthButton.js +1 -3
  9. package/dist/cjs/components/PreviousMonthButton.js +1 -3
  10. package/dist/cjs/components/custom-components.d.ts +0 -1
  11. package/dist/cjs/components/custom-components.js +0 -1
  12. package/dist/cjs/formatters/formatCaption.d.ts +0 -6
  13. package/dist/cjs/formatters/formatCaption.js +0 -7
  14. package/dist/cjs/formatters/formatYearDropdown.d.ts +0 -6
  15. package/dist/cjs/formatters/formatYearDropdown.js +0 -7
  16. package/dist/cjs/helpers/getFormatters.d.ts +0 -2
  17. package/dist/cjs/helpers/getFormatters.js +0 -7
  18. package/dist/cjs/helpers/getInitialMonth.d.ts +1 -1
  19. package/dist/cjs/helpers/getNavMonth.d.ts +1 -1
  20. package/dist/cjs/helpers/getNavMonth.js +1 -21
  21. package/dist/cjs/hijri/index.d.ts +28 -0
  22. package/dist/cjs/hijri/index.js +92 -0
  23. package/dist/cjs/hijri/lib/addMonths.d.ts +1 -0
  24. package/dist/cjs/hijri/lib/addMonths.js +9 -0
  25. package/dist/cjs/hijri/lib/addYears.d.ts +1 -0
  26. package/dist/cjs/hijri/lib/addYears.js +9 -0
  27. package/dist/cjs/hijri/lib/differenceInCalendarMonths.d.ts +1 -0
  28. package/dist/cjs/hijri/lib/differenceInCalendarMonths.js +10 -0
  29. package/dist/cjs/hijri/lib/eachMonthOfInterval.d.ts +2 -0
  30. package/dist/cjs/hijri/lib/eachMonthOfInterval.js +29 -0
  31. package/dist/cjs/hijri/lib/eachYearOfInterval.d.ts +2 -0
  32. package/dist/cjs/hijri/lib/eachYearOfInterval.js +19 -0
  33. package/dist/cjs/hijri/lib/endOfMonth.d.ts +1 -0
  34. package/dist/cjs/hijri/lib/endOfMonth.js +14 -0
  35. package/dist/cjs/hijri/lib/endOfYear.d.ts +1 -0
  36. package/dist/cjs/hijri/lib/endOfYear.js +14 -0
  37. package/dist/cjs/hijri/lib/fallbackLocaleData.d.ts +5 -0
  38. package/dist/cjs/hijri/lib/fallbackLocaleData.js +111 -0
  39. package/dist/cjs/hijri/lib/format.d.ts +3 -0
  40. package/dist/cjs/hijri/lib/format.js +149 -0
  41. package/dist/cjs/hijri/lib/getMonth.d.ts +1 -0
  42. package/dist/cjs/hijri/lib/getMonth.js +7 -0
  43. package/dist/cjs/hijri/lib/getYear.d.ts +1 -0
  44. package/dist/cjs/hijri/lib/getYear.js +7 -0
  45. package/dist/cjs/hijri/lib/index.d.ts +17 -0
  46. package/dist/cjs/hijri/lib/index.js +33 -0
  47. package/dist/cjs/hijri/lib/isSameMonth.d.ts +1 -0
  48. package/dist/cjs/hijri/lib/isSameMonth.js +10 -0
  49. package/dist/cjs/hijri/lib/isSameYear.d.ts +1 -0
  50. package/dist/cjs/hijri/lib/isSameYear.js +9 -0
  51. package/dist/cjs/hijri/lib/newDate.d.ts +1 -0
  52. package/dist/cjs/hijri/lib/newDate.js +7 -0
  53. package/dist/cjs/hijri/lib/setMonth.d.ts +1 -0
  54. package/dist/cjs/hijri/lib/setMonth.js +27 -0
  55. package/dist/cjs/hijri/lib/setYear.d.ts +1 -0
  56. package/dist/cjs/hijri/lib/setYear.js +15 -0
  57. package/dist/cjs/hijri/lib/startOfMonth.d.ts +1 -0
  58. package/dist/cjs/hijri/lib/startOfMonth.js +12 -0
  59. package/dist/cjs/hijri/lib/startOfYear.d.ts +1 -0
  60. package/dist/cjs/hijri/lib/startOfYear.js +12 -0
  61. package/dist/cjs/hijri/utils/conversion.d.ts +5 -0
  62. package/dist/cjs/hijri/utils/conversion.js +40 -0
  63. package/dist/cjs/hijri/utils/daysInMonth.d.ts +1 -0
  64. package/dist/cjs/hijri/utils/daysInMonth.js +24 -0
  65. package/dist/cjs/hijri/utils/range.d.ts +21 -0
  66. package/dist/cjs/hijri/utils/range.js +104 -0
  67. package/dist/cjs/hijri/utils/types.d.ts +5 -0
  68. package/dist/cjs/hijri/utils/types.js +2 -0
  69. package/dist/cjs/labels/labelDayButton.d.ts +0 -5
  70. package/dist/cjs/labels/labelDayButton.js +0 -6
  71. package/dist/cjs/labels/labelGrid.d.ts +0 -5
  72. package/dist/cjs/labels/labelGrid.js +0 -6
  73. package/dist/cjs/selection/useRange.js +22 -4
  74. package/dist/cjs/types/index.d.ts +0 -1
  75. package/dist/cjs/types/index.js +0 -1
  76. package/dist/cjs/types/props.d.ts +30 -100
  77. package/dist/cjs/types/shared.d.ts +1 -45
  78. package/dist/cjs/useCalendar.d.ts +1 -1
  79. package/dist/cjs/utils/dateMatchModifiers.d.ts +0 -5
  80. package/dist/cjs/utils/dateMatchModifiers.js +0 -6
  81. package/dist/cjs/utils/rangeIncludesDate.d.ts +0 -5
  82. package/dist/cjs/utils/rangeIncludesDate.js +0 -7
  83. package/dist/esm/DayPicker.js +85 -83
  84. package/dist/esm/UI.d.ts +0 -230
  85. package/dist/esm/classes/DateLib.d.ts +0 -21
  86. package/dist/esm/classes/DateLib.js +2 -12
  87. package/dist/esm/components/Dropdown.d.ts +0 -11
  88. package/dist/esm/components/Dropdown.js +3 -1
  89. package/dist/esm/components/NextMonthButton.js +1 -3
  90. package/dist/esm/components/PreviousMonthButton.js +1 -3
  91. package/dist/esm/components/custom-components.d.ts +0 -1
  92. package/dist/esm/components/custom-components.js +0 -1
  93. package/dist/esm/formatters/formatCaption.d.ts +0 -6
  94. package/dist/esm/formatters/formatCaption.js +0 -6
  95. package/dist/esm/formatters/formatYearDropdown.d.ts +0 -6
  96. package/dist/esm/formatters/formatYearDropdown.js +0 -6
  97. package/dist/esm/helpers/getFormatters.d.ts +0 -2
  98. package/dist/esm/helpers/getFormatters.js +0 -7
  99. package/dist/esm/helpers/getInitialMonth.d.ts +1 -1
  100. package/dist/esm/helpers/getNavMonth.d.ts +1 -1
  101. package/dist/esm/helpers/getNavMonth.js +1 -21
  102. package/dist/esm/hijri/index.d.ts +28 -0
  103. package/dist/esm/hijri/index.js +49 -0
  104. package/dist/esm/hijri/lib/addMonths.d.ts +1 -0
  105. package/dist/esm/hijri/lib/addMonths.js +6 -0
  106. package/dist/esm/hijri/lib/addYears.d.ts +1 -0
  107. package/dist/esm/hijri/lib/addYears.js +6 -0
  108. package/dist/esm/hijri/lib/differenceInCalendarMonths.d.ts +1 -0
  109. package/dist/esm/hijri/lib/differenceInCalendarMonths.js +7 -0
  110. package/dist/esm/hijri/lib/eachMonthOfInterval.d.ts +2 -0
  111. package/dist/esm/hijri/lib/eachMonthOfInterval.js +26 -0
  112. package/dist/esm/hijri/lib/eachYearOfInterval.d.ts +2 -0
  113. package/dist/esm/hijri/lib/eachYearOfInterval.js +16 -0
  114. package/dist/esm/hijri/lib/endOfMonth.d.ts +1 -0
  115. package/dist/esm/hijri/lib/endOfMonth.js +11 -0
  116. package/dist/esm/hijri/lib/endOfYear.d.ts +1 -0
  117. package/dist/esm/hijri/lib/endOfYear.js +11 -0
  118. package/dist/esm/hijri/lib/fallbackLocaleData.d.ts +5 -0
  119. package/dist/esm/hijri/lib/fallbackLocaleData.js +105 -0
  120. package/dist/esm/hijri/lib/format.d.ts +3 -0
  121. package/dist/esm/hijri/lib/format.js +146 -0
  122. package/dist/esm/hijri/lib/getMonth.d.ts +1 -0
  123. package/dist/esm/hijri/lib/getMonth.js +4 -0
  124. package/dist/esm/hijri/lib/getYear.d.ts +1 -0
  125. package/dist/esm/hijri/lib/getYear.js +4 -0
  126. package/dist/esm/hijri/lib/index.d.ts +17 -0
  127. package/dist/esm/hijri/lib/index.js +17 -0
  128. package/dist/esm/hijri/lib/isSameMonth.d.ts +1 -0
  129. package/dist/esm/hijri/lib/isSameMonth.js +7 -0
  130. package/dist/esm/hijri/lib/isSameYear.d.ts +1 -0
  131. package/dist/esm/hijri/lib/isSameYear.js +6 -0
  132. package/dist/esm/hijri/lib/newDate.d.ts +1 -0
  133. package/dist/esm/hijri/lib/newDate.js +4 -0
  134. package/dist/esm/hijri/lib/setMonth.d.ts +1 -0
  135. package/dist/esm/hijri/lib/setMonth.js +24 -0
  136. package/dist/esm/hijri/lib/setYear.d.ts +1 -0
  137. package/dist/esm/hijri/lib/setYear.js +12 -0
  138. package/dist/esm/hijri/lib/startOfMonth.d.ts +1 -0
  139. package/dist/esm/hijri/lib/startOfMonth.js +9 -0
  140. package/dist/esm/hijri/lib/startOfYear.d.ts +1 -0
  141. package/dist/esm/hijri/lib/startOfYear.js +9 -0
  142. package/dist/esm/hijri/utils/conversion.d.ts +5 -0
  143. package/dist/esm/hijri/utils/conversion.js +36 -0
  144. package/dist/esm/hijri/utils/daysInMonth.d.ts +1 -0
  145. package/dist/esm/hijri/utils/daysInMonth.js +21 -0
  146. package/dist/esm/hijri/utils/range.d.ts +21 -0
  147. package/dist/esm/hijri/utils/range.js +96 -0
  148. package/dist/esm/hijri/utils/types.d.ts +5 -0
  149. package/dist/esm/hijri/utils/types.js +1 -0
  150. package/dist/esm/labels/labelDayButton.d.ts +0 -5
  151. package/dist/esm/labels/labelDayButton.js +0 -5
  152. package/dist/esm/labels/labelGrid.d.ts +0 -5
  153. package/dist/esm/labels/labelGrid.js +0 -5
  154. package/dist/esm/selection/useRange.js +22 -4
  155. package/dist/esm/types/index.d.ts +0 -1
  156. package/dist/esm/types/index.js +0 -1
  157. package/dist/esm/types/props.d.ts +30 -100
  158. package/dist/esm/types/shared.d.ts +1 -45
  159. package/dist/esm/useCalendar.d.ts +1 -1
  160. package/dist/esm/utils/dateMatchModifiers.d.ts +0 -5
  161. package/dist/esm/utils/dateMatchModifiers.js +0 -5
  162. package/dist/esm/utils/rangeIncludesDate.d.ts +0 -5
  163. package/dist/esm/utils/rangeIncludesDate.js +0 -5
  164. package/hijri.d.ts +1 -0
  165. package/hijri.js +2 -0
  166. package/package.json +24 -23
  167. package/dist/cjs/components/Button.d.ts +0 -9
  168. package/dist/cjs/components/Button.js +0 -16
  169. package/dist/cjs/jalali.d.ts +0 -2
  170. package/dist/cjs/jalali.js +0 -18
  171. package/dist/cjs/types/deprecated.d.ts +0 -180
  172. package/dist/cjs/types/deprecated.js +0 -26
  173. package/dist/esm/components/Button.d.ts +0 -9
  174. package/dist/esm/components/Button.js +0 -10
  175. package/dist/esm/jalali.d.ts +0 -2
  176. package/dist/esm/jalali.js +0 -2
  177. package/dist/esm/types/deprecated.d.ts +0 -180
  178. package/dist/esm/types/deprecated.js +0 -23
  179. package/jalali.d.ts +0 -1
  180. package/jalali.js +0 -3
@@ -0,0 +1,16 @@
1
+ import { toDate } from "date-fns";
2
+ import { toGregorianDate, toHijriDate } from "../utils/conversion.js";
3
+ export function eachYearOfInterval(interval) {
4
+ const start = toDate(interval.start);
5
+ const end = toDate(interval.end);
6
+ if (end.getTime() < start.getTime()) {
7
+ return [];
8
+ }
9
+ const startYear = toHijriDate(start).year;
10
+ const endYear = toHijriDate(end).year;
11
+ const years = [];
12
+ for (let year = startYear; year <= endYear; year += 1) {
13
+ years.push(toGregorianDate({ year, monthIndex: 0, day: 1 }));
14
+ }
15
+ return years;
16
+ }
@@ -0,0 +1 @@
1
+ export declare function endOfMonth(date: Date): Date;
@@ -0,0 +1,11 @@
1
+ import { toGregorianDate, toHijriDate } from "../utils/conversion.js";
2
+ import { getDaysInMonth } from "../utils/daysInMonth.js";
3
+ export function endOfMonth(date) {
4
+ const hijri = toHijriDate(date);
5
+ const day = getDaysInMonth(hijri.year, hijri.monthIndex);
6
+ return toGregorianDate({
7
+ year: hijri.year,
8
+ monthIndex: hijri.monthIndex,
9
+ day,
10
+ });
11
+ }
@@ -0,0 +1 @@
1
+ export declare function endOfYear(date: Date): Date;
@@ -0,0 +1,11 @@
1
+ import { toGregorianDate, toHijriDate } from "../utils/conversion.js";
2
+ import { getDaysInMonth } from "../utils/daysInMonth.js";
3
+ export function endOfYear(date) {
4
+ const hijri = toHijriDate(date);
5
+ const day = getDaysInMonth(hijri.year, 11);
6
+ return toGregorianDate({
7
+ year: hijri.year,
8
+ monthIndex: 11,
9
+ day,
10
+ });
11
+ }
@@ -0,0 +1,5 @@
1
+ export type FallbackLocaleCode = "ar" | "en";
2
+ export type IntlNameWidth = "long" | "short" | "narrow";
3
+ export declare const getFallbackLocaleCode: (localeCode: string) => FallbackLocaleCode;
4
+ export declare const getFallbackMonthName: (date: Date, localeCode: string, width: IntlNameWidth) => string;
5
+ export declare const getFallbackWeekdayName: (date: Date, localeCode: string, width: IntlNameWidth) => string;
@@ -0,0 +1,105 @@
1
+ import { toHijriDate } from "../utils/conversion.js";
2
+ const fallbackMonthNames = {
3
+ en: {
4
+ long: [
5
+ "Muharram",
6
+ "Safar",
7
+ "Rabi I",
8
+ "Rabi II",
9
+ "Jumada I",
10
+ "Jumada II",
11
+ "Rajab",
12
+ "Shaban",
13
+ "Ramadan",
14
+ "Shawwal",
15
+ "Dhu al-Qadah",
16
+ "Dhu al-Hijjah",
17
+ ],
18
+ short: [
19
+ "Muh",
20
+ "Saf",
21
+ "Rab-I",
22
+ "Rab-II",
23
+ "Jum-I",
24
+ "Jum-II",
25
+ "Raj",
26
+ "Sha",
27
+ "Ram",
28
+ "Shw",
29
+ "Dhu-Q",
30
+ "Dhu-H",
31
+ ],
32
+ narrow: ["M", "S", "R", "R", "J", "J", "R", "S", "R", "S", "D", "D"],
33
+ },
34
+ ar: {
35
+ long: [
36
+ "محرم",
37
+ "صفر",
38
+ "ربيع الأول",
39
+ "ربيع الآخر",
40
+ "جمادى الأولى",
41
+ "جمادى الآخرة",
42
+ "رجب",
43
+ "شعبان",
44
+ "رمضان",
45
+ "شوال",
46
+ "ذو القعدة",
47
+ "ذو الحجة",
48
+ ],
49
+ short: [
50
+ "محرم",
51
+ "صفر",
52
+ "ربيع ١",
53
+ "ربيع ٢",
54
+ "جمادى ١",
55
+ "جمادى ٢",
56
+ "رجب",
57
+ "شعبان",
58
+ "رمضان",
59
+ "شوال",
60
+ "ذو القعدة",
61
+ "ذو الحجة",
62
+ ],
63
+ narrow: ["م", "ص", "ر", "ر", "ج", "ج", "ر", "ش", "ر", "ش", "ذ", "ذ"],
64
+ },
65
+ };
66
+ const fallbackWeekdayNames = {
67
+ en: {
68
+ long: [
69
+ "Sunday",
70
+ "Monday",
71
+ "Tuesday",
72
+ "Wednesday",
73
+ "Thursday",
74
+ "Friday",
75
+ "Saturday",
76
+ ],
77
+ short: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
78
+ narrow: ["S", "M", "T", "W", "T", "F", "S"],
79
+ },
80
+ ar: {
81
+ long: [
82
+ "الأحد",
83
+ "الاثنين",
84
+ "الثلاثاء",
85
+ "الأربعاء",
86
+ "الخميس",
87
+ "الجمعة",
88
+ "السبت",
89
+ ],
90
+ short: ["أحد", "اثن", "ثلا", "أرب", "خمي", "جمع", "سبت"],
91
+ narrow: ["ح", "ن", "ث", "ر", "خ", "ج", "س"],
92
+ },
93
+ };
94
+ export const getFallbackLocaleCode = (localeCode) => {
95
+ return localeCode.toLowerCase().startsWith("ar") ? "ar" : "en";
96
+ };
97
+ export const getFallbackMonthName = (date, localeCode, width) => {
98
+ const hijri = toHijriDate(date);
99
+ const locale = getFallbackLocaleCode(localeCode);
100
+ return fallbackMonthNames[locale][width][hijri.monthIndex];
101
+ };
102
+ export const getFallbackWeekdayName = (date, localeCode, width) => {
103
+ const locale = getFallbackLocaleCode(localeCode);
104
+ return fallbackWeekdayNames[locale][width][date.getDay()];
105
+ };
@@ -0,0 +1,3 @@
1
+ import type { FormatOptions as DateFnsFormatOptions } from "date-fns";
2
+ /** Hijri calendar formatting override. */
3
+ export declare function format(date: Date, formatStr: string, options?: DateFnsFormatOptions): string;
@@ -0,0 +1,146 @@
1
+ import { toHijriDate } from "../utils/conversion.js";
2
+ import { clampGregorianDate, getGregorianDateParts } from "../utils/range.js";
3
+ import { getFallbackMonthName, getFallbackWeekdayName, } from "./fallbackLocaleData.js";
4
+ const DEFAULT_LOCALE_CODE = "ar-SA";
5
+ const BASE_NUMBERING_SYSTEM = "latn";
6
+ const UMM_AL_QURA_CALENDAR = "islamic-umalqura";
7
+ const getLocaleCode = (options) => {
8
+ return options?.locale?.code ?? DEFAULT_LOCALE_CODE;
9
+ };
10
+ const formatWithUmmAlQura = (date, localeCode, options) => {
11
+ try {
12
+ return new Intl.DateTimeFormat(localeCode, {
13
+ ...options,
14
+ calendar: UMM_AL_QURA_CALENDAR,
15
+ numberingSystem: BASE_NUMBERING_SYSTEM,
16
+ }).format(date);
17
+ }
18
+ catch {
19
+ return undefined;
20
+ }
21
+ };
22
+ const formatNumber = (value) => {
23
+ return value.toString();
24
+ };
25
+ const formatPaddedNumber = (value) => {
26
+ return formatNumber(value).padStart(2, "0");
27
+ };
28
+ const formatMonthName = (date, localeCode, width) => {
29
+ const formatted = formatWithUmmAlQura(date, localeCode, {
30
+ month: width,
31
+ });
32
+ return formatted ?? getFallbackMonthName(date, localeCode, width);
33
+ };
34
+ const formatWeekdayName = (date, localeCode, width) => {
35
+ const formatted = formatWithUmmAlQura(date, localeCode, {
36
+ weekday: width,
37
+ });
38
+ return formatted ?? getFallbackWeekdayName(date, localeCode, width);
39
+ };
40
+ const formatDateStyle = (date, localeCode, style) => {
41
+ const formatted = formatWithUmmAlQura(date, localeCode, {
42
+ dateStyle: style,
43
+ });
44
+ if (formatted) {
45
+ return formatted;
46
+ }
47
+ const hijri = toHijriDate(date);
48
+ const monthName = getFallbackMonthName(date, localeCode, "long");
49
+ switch (style) {
50
+ case "full":
51
+ return `${getFallbackWeekdayName(date, localeCode, "long")}, ${monthName} ${hijri.day}, ${hijri.year}`;
52
+ case "long":
53
+ return `${monthName} ${hijri.day}, ${hijri.year}`;
54
+ case "medium":
55
+ return `${formatPaddedNumber(hijri.day)} ${monthName} ${hijri.year}`;
56
+ case "short":
57
+ return `${hijri.monthIndex + 1}/${hijri.day}/${hijri.year}`;
58
+ }
59
+ };
60
+ const buildTimeFormat = (date, localeCode, formatStr) => {
61
+ const hour12 = formatStr.includes("a");
62
+ const formatted = formatWithUmmAlQura(date, localeCode, {
63
+ hour: "numeric",
64
+ minute: "numeric",
65
+ hour12,
66
+ });
67
+ if (formatted) {
68
+ return formatted;
69
+ }
70
+ try {
71
+ return new Intl.DateTimeFormat(localeCode, {
72
+ hour: "numeric",
73
+ minute: "numeric",
74
+ hour12,
75
+ numberingSystem: BASE_NUMBERING_SYSTEM,
76
+ }).format(date);
77
+ }
78
+ catch {
79
+ const minutes = formatPaddedNumber(date.getMinutes());
80
+ if (hour12) {
81
+ const hour = date.getHours() % 12 || 12;
82
+ const period = date.getHours() >= 12 ? "PM" : "AM";
83
+ return `${hour}:${minutes} ${period}`;
84
+ }
85
+ return `${formatNumber(date.getHours())}:${minutes}`;
86
+ }
87
+ };
88
+ /** Hijri calendar formatting override. */
89
+ export function format(date, formatStr, options) {
90
+ const extendedOptions = options;
91
+ const localeCode = getLocaleCode(extendedOptions);
92
+ const hijri = toHijriDate(date);
93
+ const gregorian = getGregorianDateParts(date);
94
+ const isOutOfRange = clampGregorianDate(date) !== date;
95
+ const numericDate = isOutOfRange
96
+ ? {
97
+ year: gregorian.year,
98
+ monthIndex: gregorian.month - 1,
99
+ day: gregorian.day,
100
+ }
101
+ : hijri;
102
+ switch (formatStr) {
103
+ case "LLLL y":
104
+ case "LLLL yyyy":
105
+ return `${formatMonthName(date, localeCode, "long")} ${formatNumber(numericDate.year)}`;
106
+ case "LLLL":
107
+ return formatMonthName(date, localeCode, "long");
108
+ case "LLL":
109
+ return formatMonthName(date, localeCode, "short");
110
+ case "PPP":
111
+ return formatDateStyle(date, localeCode, "long");
112
+ case "PPPP":
113
+ return formatDateStyle(date, localeCode, "full");
114
+ case "PP":
115
+ return formatDateStyle(date, localeCode, "medium");
116
+ case "P":
117
+ return formatDateStyle(date, localeCode, "short");
118
+ case "cccc":
119
+ return formatWeekdayName(date, localeCode, "long");
120
+ case "ccc":
121
+ return formatWeekdayName(date, localeCode, "short");
122
+ case "ccccc":
123
+ case "cccccc":
124
+ return formatWeekdayName(date, localeCode, "narrow");
125
+ case "yyyy":
126
+ case "y":
127
+ return formatNumber(numericDate.year);
128
+ case "yyyy-MM":
129
+ return `${formatNumber(numericDate.year)}-${formatPaddedNumber(numericDate.monthIndex + 1)}`;
130
+ case "yyyy-MM-dd":
131
+ return `${formatNumber(numericDate.year)}-${formatPaddedNumber(numericDate.monthIndex + 1)}-${formatPaddedNumber(numericDate.day)}`;
132
+ case "MM":
133
+ return formatPaddedNumber(numericDate.monthIndex + 1);
134
+ case "M":
135
+ return formatNumber(numericDate.monthIndex + 1);
136
+ case "dd":
137
+ return formatPaddedNumber(numericDate.day);
138
+ case "d":
139
+ return formatNumber(numericDate.day);
140
+ default:
141
+ if (/[Hh]/.test(formatStr) && /m/.test(formatStr)) {
142
+ return buildTimeFormat(date, localeCode, formatStr);
143
+ }
144
+ return formatDateStyle(date, localeCode, "medium");
145
+ }
146
+ }
@@ -0,0 +1 @@
1
+ export declare function getMonth(date: Date): number;
@@ -0,0 +1,4 @@
1
+ import { toHijriDate } from "../utils/conversion.js";
2
+ export function getMonth(date) {
3
+ return toHijriDate(date).monthIndex;
4
+ }
@@ -0,0 +1 @@
1
+ export declare function getYear(date: Date): number;
@@ -0,0 +1,4 @@
1
+ import { toHijriDate } from "../utils/conversion.js";
2
+ export function getYear(date) {
3
+ return toHijriDate(date).year;
4
+ }
@@ -0,0 +1,17 @@
1
+ export * from "./addMonths.js";
2
+ export * from "./addYears.js";
3
+ export * from "./differenceInCalendarMonths.js";
4
+ export * from "./eachMonthOfInterval.js";
5
+ export * from "./eachYearOfInterval.js";
6
+ export * from "./endOfMonth.js";
7
+ export * from "./endOfYear.js";
8
+ export * from "./format.js";
9
+ export * from "./getMonth.js";
10
+ export * from "./getYear.js";
11
+ export * from "./isSameMonth.js";
12
+ export * from "./isSameYear.js";
13
+ export * from "./newDate.js";
14
+ export * from "./setMonth.js";
15
+ export * from "./setYear.js";
16
+ export * from "./startOfMonth.js";
17
+ export * from "./startOfYear.js";
@@ -0,0 +1,17 @@
1
+ export * from "./addMonths.js";
2
+ export * from "./addYears.js";
3
+ export * from "./differenceInCalendarMonths.js";
4
+ export * from "./eachMonthOfInterval.js";
5
+ export * from "./eachYearOfInterval.js";
6
+ export * from "./endOfMonth.js";
7
+ export * from "./endOfYear.js";
8
+ export * from "./format.js";
9
+ export * from "./getMonth.js";
10
+ export * from "./getYear.js";
11
+ export * from "./isSameMonth.js";
12
+ export * from "./isSameYear.js";
13
+ export * from "./newDate.js";
14
+ export * from "./setMonth.js";
15
+ export * from "./setYear.js";
16
+ export * from "./startOfMonth.js";
17
+ export * from "./startOfYear.js";
@@ -0,0 +1 @@
1
+ export declare function isSameMonth(dateLeft: Date, dateRight: Date): boolean;
@@ -0,0 +1,7 @@
1
+ import { toHijriDate } from "../utils/conversion.js";
2
+ export function isSameMonth(dateLeft, dateRight) {
3
+ const hijriLeft = toHijriDate(dateLeft);
4
+ const hijriRight = toHijriDate(dateRight);
5
+ return (hijriLeft.year === hijriRight.year &&
6
+ hijriLeft.monthIndex === hijriRight.monthIndex);
7
+ }
@@ -0,0 +1 @@
1
+ export declare function isSameYear(dateLeft: Date, dateRight: Date): boolean;
@@ -0,0 +1,6 @@
1
+ import { toHijriDate } from "../utils/conversion.js";
2
+ export function isSameYear(dateLeft, dateRight) {
3
+ const hijriLeft = toHijriDate(dateLeft);
4
+ const hijriRight = toHijriDate(dateRight);
5
+ return hijriLeft.year === hijriRight.year;
6
+ }
@@ -0,0 +1 @@
1
+ export declare function newDate(year: number, monthIndex: number, day: number): Date;
@@ -0,0 +1,4 @@
1
+ import { toGregorianDate } from "../utils/conversion.js";
2
+ export function newDate(year, monthIndex, day) {
3
+ return toGregorianDate({ year, monthIndex, day });
4
+ }
@@ -0,0 +1 @@
1
+ export declare function setMonth(date: Date, monthIndex: number): Date;
@@ -0,0 +1,24 @@
1
+ import { toGregorianDate, toHijriDate } from "../utils/conversion.js";
2
+ import { getDaysInMonth } from "../utils/daysInMonth.js";
3
+ export function setMonth(date, monthIndex) {
4
+ const hijri = toHijriDate(date);
5
+ // Handle overflow/underflow of monthIndex
6
+ // Note: monthIndex argument is absolute month index for the year.
7
+ // E.g. setMonth(..., 13) sets to Safar next year.
8
+ let targetYear = hijri.year;
9
+ let targetMonth = monthIndex;
10
+ if (targetMonth > 11 || targetMonth < 0) {
11
+ targetYear += Math.floor(targetMonth / 12);
12
+ targetMonth = targetMonth % 12;
13
+ if (targetMonth < 0) {
14
+ targetMonth += 12;
15
+ }
16
+ }
17
+ const daysInTargetMonth = getDaysInMonth(targetYear, targetMonth);
18
+ const day = Math.min(hijri.day, daysInTargetMonth);
19
+ return toGregorianDate({
20
+ year: targetYear,
21
+ monthIndex: targetMonth,
22
+ day,
23
+ });
24
+ }
@@ -0,0 +1 @@
1
+ export declare function setYear(date: Date, year: number): Date;
@@ -0,0 +1,12 @@
1
+ import { toGregorianDate, toHijriDate } from "../utils/conversion.js";
2
+ import { getDaysInMonth } from "../utils/daysInMonth.js";
3
+ export function setYear(date, year) {
4
+ const hijri = toHijriDate(date);
5
+ const daysInTargetMonth = getDaysInMonth(year, hijri.monthIndex);
6
+ const day = Math.min(hijri.day, daysInTargetMonth);
7
+ return toGregorianDate({
8
+ year,
9
+ monthIndex: hijri.monthIndex,
10
+ day,
11
+ });
12
+ }
@@ -0,0 +1 @@
1
+ export declare function startOfMonth(date: Date): Date;
@@ -0,0 +1,9 @@
1
+ import { toGregorianDate, toHijriDate } from "../utils/conversion.js";
2
+ export function startOfMonth(date) {
3
+ const hijri = toHijriDate(date);
4
+ return toGregorianDate({
5
+ year: hijri.year,
6
+ monthIndex: hijri.monthIndex,
7
+ day: 1,
8
+ });
9
+ }
@@ -0,0 +1 @@
1
+ export declare function startOfYear(date: Date): Date;
@@ -0,0 +1,9 @@
1
+ import { toGregorianDate, toHijriDate } from "../utils/conversion.js";
2
+ export function startOfYear(date) {
3
+ const hijri = toHijriDate(date);
4
+ return toGregorianDate({
5
+ year: hijri.year,
6
+ monthIndex: 0,
7
+ day: 1,
8
+ });
9
+ }
@@ -0,0 +1,5 @@
1
+ import type { HijriDate } from "./types.js";
2
+ /** Convert a Gregorian date to a Hijri date. */
3
+ export declare function toHijriDate(date: Date): HijriDate;
4
+ /** Convert a Hijri date back to the Gregorian calendar. */
5
+ export declare function toGregorianDate(hijri: HijriDate): Date;
@@ -0,0 +1,36 @@
1
+ import { gregorianToHijri, hijriToGregorian } from "@tabby_ai/hijri-converter";
2
+ import { clampGregorianDate, clampHijriDate, GREGORIAN_MIN_DATE, getGregorianDateParts, } from "./range.js";
3
+ /** Convert a Gregorian date to a Hijri date. */
4
+ export function toHijriDate(date) {
5
+ const clamped = clampGregorianDate(date);
6
+ const { year, month, day } = getGregorianDateParts(clamped);
7
+ // gregorianToHijri uses 1-indexed months
8
+ const hijri = gregorianToHijri({ year, month, day });
9
+ return {
10
+ year: hijri.year,
11
+ monthIndex: hijri.month - 1, // Convert to 0-indexed
12
+ day: hijri.day,
13
+ };
14
+ }
15
+ /** Convert a Hijri date back to the Gregorian calendar. */
16
+ export function toGregorianDate(hijri) {
17
+ const clamped = clampHijriDate(hijri);
18
+ // hijriToGregorian expects 1-indexed months. Probe down from the candidate
19
+ // day to handle invalid month/day combinations without throwing.
20
+ for (let day = clamped.day; day >= 1; day -= 1) {
21
+ try {
22
+ const gregorian = hijriToGregorian({
23
+ year: clamped.year,
24
+ month: clamped.monthIndex + 1,
25
+ day,
26
+ });
27
+ return clampGregorianDate(new Date(gregorian.year, gregorian.month - 1, gregorian.day));
28
+ }
29
+ catch {
30
+ // Try a lower day for months that only have 29 days.
31
+ }
32
+ }
33
+ // Fallback to the minimum supported Gregorian date if conversion probing
34
+ // somehow fails for all days.
35
+ return new Date(GREGORIAN_MIN_DATE);
36
+ }
@@ -0,0 +1 @@
1
+ export declare function getDaysInMonth(year: number, monthIndex: number): number;
@@ -0,0 +1,21 @@
1
+ import { toGregorianDate, toHijriDate } from "./conversion.js";
2
+ import { clampHijriDate } from "./range.js";
3
+ const MAX_DAY_IN_HIJRI_MONTH = 30;
4
+ const MIN_DAY_IN_HIJRI_MONTH = 29;
5
+ export function getDaysInMonth(year, monthIndex) {
6
+ const clamped = clampHijriDate({ year, monthIndex, day: 1 });
7
+ for (let day = MAX_DAY_IN_HIJRI_MONTH; day >= MIN_DAY_IN_HIJRI_MONTH; day -= 1) {
8
+ const candidateDate = toGregorianDate({
9
+ year: clamped.year,
10
+ monthIndex: clamped.monthIndex,
11
+ day,
12
+ });
13
+ const roundTrip = toHijriDate(candidateDate);
14
+ if (roundTrip.year === clamped.year &&
15
+ roundTrip.monthIndex === clamped.monthIndex &&
16
+ roundTrip.day === day) {
17
+ return day;
18
+ }
19
+ }
20
+ return MIN_DAY_IN_HIJRI_MONTH;
21
+ }
@@ -0,0 +1,21 @@
1
+ import type { HijriDate } from "./types.js";
2
+ type GregorianDateParts = {
3
+ year: number;
4
+ month: number;
5
+ day: number;
6
+ };
7
+ /** Returns Gregorian date parts while preserving years < 100. */
8
+ export declare function getGregorianDateParts(date: Date): GregorianDateParts;
9
+ /** Internal Gregorian lower bound supported by the Hijri converter. */
10
+ export declare const GREGORIAN_MIN_DATE: Date;
11
+ /** Internal Gregorian upper bound supported by the Hijri converter. */
12
+ export declare const GREGORIAN_MAX_DATE: Date;
13
+ /** Clamp a Gregorian date to the supported Hijri conversion range. */
14
+ export declare function clampGregorianDate(date: Date): Date;
15
+ /** Returns whether the provided Gregorian date was clamped. */
16
+ export declare function wasGregorianDateClamped(date: Date): boolean;
17
+ /** Clamp a Hijri date to the supported range and normalize month overflow. */
18
+ export declare function clampHijriDate(date: HijriDate): HijriDate;
19
+ /** Returns whether the provided Hijri date was clamped. */
20
+ export declare function wasHijriDateClamped(date: HijriDate): boolean;
21
+ export {};
@@ -0,0 +1,96 @@
1
+ const MAX_HIJRI_DAY = 30;
2
+ const MONTHS_PER_YEAR = 12;
3
+ const HIJRI_MIN = { year: 1343, monthIndex: 0, day: 1 };
4
+ const HIJRI_MAX = { year: 1500, monthIndex: 11, day: 30 };
5
+ const GREGORIAN_MIN = { year: 1924, month: 8, day: 1 };
6
+ const GREGORIAN_MAX = { year: 2077, month: 11, day: 16 };
7
+ function compareGregorianDates(left, right) {
8
+ if (left.year !== right.year) {
9
+ return left.year - right.year;
10
+ }
11
+ if (left.month !== right.month) {
12
+ return left.month - right.month;
13
+ }
14
+ return left.day - right.day;
15
+ }
16
+ function createDate(parts) {
17
+ return new Date(parts.year, parts.month - 1, parts.day);
18
+ }
19
+ function normalizeHijriMonth(year, monthIndex) {
20
+ let normalizedYear = year + Math.trunc(monthIndex / MONTHS_PER_YEAR);
21
+ let normalizedMonth = monthIndex % MONTHS_PER_YEAR;
22
+ if (normalizedMonth < 0) {
23
+ normalizedMonth += MONTHS_PER_YEAR;
24
+ normalizedYear -= 1;
25
+ }
26
+ return { year: normalizedYear, monthIndex: normalizedMonth };
27
+ }
28
+ /** Returns Gregorian date parts while preserving years < 100. */
29
+ export function getGregorianDateParts(date) {
30
+ const useUTC = date.getFullYear() < 100;
31
+ return {
32
+ year: useUTC ? date.getUTCFullYear() : date.getFullYear(),
33
+ month: (useUTC ? date.getUTCMonth() : date.getMonth()) + 1,
34
+ day: useUTC ? date.getUTCDate() : date.getDate(),
35
+ };
36
+ }
37
+ /** Internal Gregorian lower bound supported by the Hijri converter. */
38
+ export const GREGORIAN_MIN_DATE = createDate(GREGORIAN_MIN);
39
+ /** Internal Gregorian upper bound supported by the Hijri converter. */
40
+ export const GREGORIAN_MAX_DATE = createDate(GREGORIAN_MAX);
41
+ /** Clamp a Gregorian date to the supported Hijri conversion range. */
42
+ export function clampGregorianDate(date) {
43
+ const parts = getGregorianDateParts(date);
44
+ if (compareGregorianDates(parts, GREGORIAN_MIN) < 0) {
45
+ return createDate(GREGORIAN_MIN);
46
+ }
47
+ if (compareGregorianDates(parts, GREGORIAN_MAX) > 0) {
48
+ return createDate(GREGORIAN_MAX);
49
+ }
50
+ return date;
51
+ }
52
+ /** Returns whether the provided Gregorian date was clamped. */
53
+ export function wasGregorianDateClamped(date) {
54
+ return clampGregorianDate(date) !== date;
55
+ }
56
+ /** Clamp a Hijri date to the supported range and normalize month overflow. */
57
+ export function clampHijriDate(date) {
58
+ const normalized = normalizeHijriMonth(date.year, date.monthIndex);
59
+ const candidate = {
60
+ year: normalized.year,
61
+ monthIndex: normalized.monthIndex,
62
+ day: Math.min(Math.max(date.day, 1), MAX_HIJRI_DAY),
63
+ };
64
+ if (candidate.year < HIJRI_MIN.year) {
65
+ return { ...HIJRI_MIN };
66
+ }
67
+ if (candidate.year > HIJRI_MAX.year) {
68
+ return { ...HIJRI_MAX };
69
+ }
70
+ if (candidate.year === HIJRI_MIN.year &&
71
+ candidate.monthIndex < HIJRI_MIN.monthIndex) {
72
+ return { ...HIJRI_MIN };
73
+ }
74
+ if (candidate.year === HIJRI_MAX.year &&
75
+ candidate.monthIndex > HIJRI_MAX.monthIndex) {
76
+ return { ...HIJRI_MAX };
77
+ }
78
+ if (candidate.year === HIJRI_MIN.year &&
79
+ candidate.monthIndex === HIJRI_MIN.monthIndex &&
80
+ candidate.day < HIJRI_MIN.day) {
81
+ return { ...HIJRI_MIN };
82
+ }
83
+ if (candidate.year === HIJRI_MAX.year &&
84
+ candidate.monthIndex === HIJRI_MAX.monthIndex &&
85
+ candidate.day > HIJRI_MAX.day) {
86
+ return { ...HIJRI_MAX };
87
+ }
88
+ return candidate;
89
+ }
90
+ /** Returns whether the provided Hijri date was clamped. */
91
+ export function wasHijriDateClamped(date) {
92
+ const clamped = clampHijriDate(date);
93
+ return (clamped.year !== date.year ||
94
+ clamped.monthIndex !== date.monthIndex ||
95
+ clamped.day !== date.day);
96
+ }