@uxf/datepicker 11.111.0-canary.1 → 11.111.2

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 (55) hide show
  1. package/hooks/use-date-picker-navigation.d.ts +3 -4
  2. package/hooks/use-date-picker-navigation.js +34 -30
  3. package/hooks/use-date-picker-navigation.test.js +4 -40
  4. package/hooks/use-date-picker.js +26 -40
  5. package/hooks/use-date-picker.test.js +2 -2
  6. package/hooks/use-date-range-picker.js +76 -103
  7. package/hooks/use-day.js +11 -12
  8. package/hooks/use-decade.js +8 -9
  9. package/package.json +4 -9
  10. package/utils/can-select-range.d.ts +5 -6
  11. package/utils/can-select-range.js +19 -7
  12. package/utils/can-select-range.test.js +27 -30
  13. package/utils/dayjs-utils.d.ts +1 -0
  14. package/utils/dayjs-utils.js +5 -1
  15. package/utils/get-current-year-month-and-date.js +2 -1
  16. package/utils/get-date-invervals.js +5 -2
  17. package/utils/get-date-month-and-year.js +5 -6
  18. package/utils/get-days.js +9 -12
  19. package/utils/get-each.d.ts +1 -2
  20. package/utils/get-each.js +9 -37
  21. package/utils/get-each.test.js +19 -34
  22. package/utils/get-initial-months.js +6 -3
  23. package/utils/get-months.js +7 -7
  24. package/utils/get-next-active-month.js +10 -6
  25. package/utils/get-weekday-labels.js +2 -4
  26. package/utils/get-years.js +4 -5
  27. package/utils/is-date-blocked.d.ts +6 -7
  28. package/utils/is-date-blocked.js +7 -6
  29. package/utils/is-date-blocked.test.js +11 -108
  30. package/utils/is-date-hovered.d.ts +5 -6
  31. package/utils/is-date-hovered.js +24 -17
  32. package/utils/is-date-hovered.test.js +25 -42
  33. package/utils/is-date-inside-range.d.ts +1 -2
  34. package/utils/is-date-inside-range.js +2 -1
  35. package/utils/is-date-selected.test.js +8 -16
  36. package/utils/is-end-date.d.ts +1 -2
  37. package/utils/is-end-date.js +2 -1
  38. package/utils/is-end-date.test.js +6 -11
  39. package/utils/is-first-or-last-selected-date.d.ts +1 -2
  40. package/utils/is-first-or-last-selected-date.js +3 -1
  41. package/utils/is-first-or-last-selected-date.test.js +6 -9
  42. package/utils/is-in-unavailable-dates.d.ts +1 -2
  43. package/utils/is-in-unavailable-dates.js +2 -1
  44. package/utils/is-in-unavailable-dates.test.js +6 -10
  45. package/utils/is-start-date.d.ts +1 -2
  46. package/utils/is-start-date.js +2 -1
  47. package/utils/is-start-date.test.js +6 -12
  48. package/jest.dst.config.js +0 -22
  49. package/jest.dst.global-setup.js +0 -14
  50. package/utils/date-string.d.ts +0 -34
  51. package/utils/date-string.js +0 -64
  52. package/utils/date-string.test.d.ts +0 -1
  53. package/utils/date-string.test.js +0 -63
  54. package/utils/dst-robustness.test.d.ts +0 -11
  55. package/utils/dst-robustness.test.js +0 -328
@@ -1,12 +1,11 @@
1
- import { DateString } from "@uxf/core/date";
2
1
  import { Dispatch, SetStateAction } from "react";
3
2
  import { MonthType } from "../utils/types";
4
3
  export interface UseDatePickerNavigationProps {
5
4
  activeMonths: MonthType[];
6
5
  setActiveMonths: Dispatch<SetStateAction<MonthType[]>>;
7
- setFocusedDate: (date: Date | null) => void;
8
- minBookingDate?: DateString;
9
- maxBookingDate?: DateString;
6
+ setFocusedDate: Dispatch<SetStateAction<Date | null>>;
7
+ minBookingDate?: Date;
8
+ maxBookingDate?: Date;
10
9
  numberOfMonths: number;
11
10
  }
12
11
  export interface UseDatePickerNavigationReturnType {
@@ -2,12 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useDatePickerNavigation = useDatePickerNavigation;
4
4
  const react_1 = require("react");
5
- const create_date_string_1 = require("../utils/create-date-string");
6
- const date_string_1 = require("../utils/date-string");
5
+ const dayjs_utils_1 = require("../utils/dayjs-utils");
7
6
  const get_initial_months_1 = require("../utils/get-initial-months");
8
7
  const get_next_active_month_1 = require("../utils/get-next-active-month");
9
8
  function useDatePickerNavigation({ activeMonths, setActiveMonths, setFocusedDate, minBookingDate, maxBookingDate, numberOfMonths, }) {
10
- var _a, _b;
9
+ var _a, _b, _c, _d;
11
10
  const goToPrevMonths = (0, react_1.useCallback)(() => {
12
11
  const newActiveMonths = (0, get_next_active_month_1.getNextActiveMonth)(activeMonths, numberOfMonths, -1);
13
12
  setActiveMonths(newActiveMonths);
@@ -50,35 +49,40 @@ function useDatePickerNavigation({ activeMonths, setActiveMonths, setFocusedDate
50
49
  setFocusedDate(null);
51
50
  return newActiveMonths;
52
51
  }, [activeMonths, numberOfMonths, setActiveMonths, setFocusedDate]);
53
- const firstMonthStr = (0, date_string_1.toDateString)((_b = (_a = activeMonths.at(0)) === null || _a === void 0 ? void 0 : _a.date) !== null && _b !== void 0 ? _b : new Date());
54
- const lastMonthStr = (0, date_string_1.toDateString)(activeMonths[activeMonths.length - 1].date);
55
- const firstYear = parseInt(firstMonthStr.slice(0, 4), 10);
56
- const lastYear = parseInt(lastMonthStr.slice(0, 4), 10);
57
- // Can navigate back if the first active month is not before minBookingDate.
58
- const canGoToPrevMonth = !minBookingDate || minBookingDate <= firstMonthStr;
59
- // Can navigate forward if the month after the last active month is still within maxBookingDate.
60
- const canGoToNextMonth = !maxBookingDate || (0, date_string_1.addMonths)(lastMonthStr, 1) <= maxBookingDate;
61
- // Can navigate back a year if Dec 31 of (firstYear - 1) is still on or after minBookingDate.
62
- const canGoToPrevYear = !minBookingDate || (0, create_date_string_1.createDateString)(firstYear - 1, 11, 31) >= minBookingDate;
63
- // Can navigate forward a year if Jan 1 of (lastYear + 1) is still within maxBookingDate.
64
- const canGoToNextYear = !maxBookingDate || (0, create_date_string_1.createDateString)(lastYear + 1, 0) <= maxBookingDate;
52
+ const canGoToPrevMonth = minBookingDate
53
+ ? !(0, dayjs_utils_1.dayjsEnRaw)((_b = (_a = activeMonths.at(0)) === null || _a === void 0 ? void 0 : _a.date) !== null && _b !== void 0 ? _b : new Date()).isBefore((0, dayjs_utils_1.dayjsEnRaw)(minBookingDate))
54
+ : true;
55
+ const canGoToNextMonth = maxBookingDate
56
+ ? !(0, dayjs_utils_1.dayjsEnWithTz)(activeMonths[activeMonths.length - 1].date)
57
+ .endOf("month")
58
+ .isAfter((0, dayjs_utils_1.dayjsEnWithTz)(maxBookingDate))
59
+ : true;
60
+ const canGoToPrevYear = minBookingDate
61
+ ? !(0, dayjs_utils_1.dayjsEnWithTz)((_d = (_c = activeMonths.at(0)) === null || _c === void 0 ? void 0 : _c.date) !== null && _d !== void 0 ? _d : new Date())
62
+ .subtract(1, "year")
63
+ .endOf("year")
64
+ .isBefore((0, dayjs_utils_1.dayjsEnRaw)(minBookingDate))
65
+ : true;
66
+ const canGoToNextYear = maxBookingDate
67
+ ? !(0, dayjs_utils_1.dayjsEnWithTz)(activeMonths[activeMonths.length - 1].date)
68
+ .add(1, "year")
69
+ .startOf("year")
70
+ .isAfter((0, dayjs_utils_1.dayjsEnWithTz)(maxBookingDate))
71
+ : true;
65
72
  const canGoTo = (0, react_1.useCallback)((month, type) => {
66
- if (!minBookingDate && !maxBookingDate) {
67
- return true;
73
+ if (minBookingDate || maxBookingDate) {
74
+ if (minBookingDate && maxBookingDate) {
75
+ return ((0, dayjs_utils_1.dayjsEnWithTz)(month).endOf(type).add(1, "day").isAfter(minBookingDate, "day") &&
76
+ (0, dayjs_utils_1.dayjsEnWithTz)(month).startOf(type).subtract(1, "day").isBefore(maxBookingDate, "day"));
77
+ }
78
+ if (minBookingDate) {
79
+ return (0, dayjs_utils_1.dayjsEnWithTz)(month).endOf(type).add(1, "day").isAfter(minBookingDate, "day");
80
+ }
81
+ if (maxBookingDate) {
82
+ return (0, dayjs_utils_1.dayjsEnWithTz)(month).startOf(type).subtract(1, "day").isBefore(maxBookingDate, "day");
83
+ }
68
84
  }
69
- const ds = (0, date_string_1.toDateString)(month);
70
- const year = parseInt(ds.slice(0, 4), 10);
71
- if (type === "month") {
72
- // Month is reachable if its range overlaps [minBookingDate, maxBookingDate].
73
- // "end of this month + 1 day > min" AND "start of this month - 1 day < max"
74
- const afterMin = !minBookingDate || (0, date_string_1.addMonths)(ds, 1) > minBookingDate;
75
- const beforeMax = !maxBookingDate || (0, date_string_1.addDays)(ds, -1) < maxBookingDate;
76
- return afterMin && beforeMax;
77
- }
78
- // type === "year"
79
- const afterMin = !minBookingDate || (0, create_date_string_1.createDateString)(year + 1, 0) > minBookingDate;
80
- const beforeMax = !maxBookingDate || (0, create_date_string_1.createDateString)(year - 1, 11, 31) < maxBookingDate;
81
- return afterMin && beforeMax;
85
+ return true;
82
86
  }, [maxBookingDate, minBookingDate]);
83
87
  const canGoToMonth = (0, react_1.useCallback)((date) => canGoTo(date, "month"), [canGoTo]);
84
88
  const canGoToYear = (0, react_1.useCallback)((date) => canGoTo(date, "year"), [canGoTo]);
@@ -24,8 +24,8 @@ test("base data with min and max date", () => {
24
24
  setActiveMonths: () => undefined,
25
25
  numberOfMonths: 1,
26
26
  setFocusedDate: () => undefined,
27
- minBookingDate: "2015-05-05",
28
- maxBookingDate: "2025-10-11",
27
+ minBookingDate: new Date("2015-05-05"),
28
+ maxBookingDate: new Date("2025-10-11"),
29
29
  }));
30
30
  expect(result.current.canGoToMonth(new Date("2021-08-01"))).toBe(true);
31
31
  expect(result.current.canGoToMonth(new Date("2015-04-01"))).toBe(false);
@@ -34,42 +34,6 @@ test("base data with min and max date", () => {
34
34
  expect(result.current.canGoToYear(new Date("2014-01-01"))).toBe(false);
35
35
  expect(result.current.canGoToYear(new Date("2026-01-01"))).toBe(false);
36
36
  });
37
- test("canGoToNextMonth edge cases with maxBookingDate", () => {
38
- // Active month: September 2021 (lastMonthStr = "2021-09-01")
39
- // addMonths("2021-09-01", 1) = "2021-10-01"
40
- // maxBookingDate = 1st of next month ("2021-10-01"):
41
- // "2021-10-01" <= "2021-10-01" → true → can navigate forward
42
- // (October has at least one bookable day)
43
- const { result: result1 } = (0, react_1.renderHook)(() => (0, use_date_picker_navigation_1.useDatePickerNavigation)({
44
- activeMonths: ACTIVE_MONTHS,
45
- setActiveMonths: () => undefined,
46
- numberOfMonths: 1,
47
- setFocusedDate: () => undefined,
48
- maxBookingDate: "2021-10-01",
49
- }));
50
- expect(result1.current.canGoToNextMonth).toBe(true);
51
- // maxBookingDate = last day of current month ("2021-09-30"):
52
- // "2021-10-01" <= "2021-09-30" → false → cannot navigate forward
53
- // (October is entirely past maxBookingDate)
54
- const { result: result2 } = (0, react_1.renderHook)(() => (0, use_date_picker_navigation_1.useDatePickerNavigation)({
55
- activeMonths: ACTIVE_MONTHS,
56
- setActiveMonths: () => undefined,
57
- numberOfMonths: 1,
58
- setFocusedDate: () => undefined,
59
- maxBookingDate: "2021-09-30",
60
- }));
61
- expect(result2.current.canGoToNextMonth).toBe(false);
62
- // maxBookingDate = mid-next-month ("2021-10-15"):
63
- // "2021-10-01" <= "2021-10-15" → true → can navigate forward
64
- const { result: result3 } = (0, react_1.renderHook)(() => (0, use_date_picker_navigation_1.useDatePickerNavigation)({
65
- activeMonths: ACTIVE_MONTHS,
66
- setActiveMonths: () => undefined,
67
- numberOfMonths: 1,
68
- setFocusedDate: () => undefined,
69
- maxBookingDate: "2021-10-15",
70
- }));
71
- expect(result3.current.canGoToNextMonth).toBe(true);
72
- });
73
37
  test("actions", () => {
74
38
  const { result: state } = (0, react_1.renderHook)(() => (0, react_2.useState)([{ month: 8, year: 2021, date: new Date("2021-09-01") }]));
75
39
  const { result, rerender } = (0, react_1.renderHook)(() => {
@@ -79,8 +43,8 @@ test("actions", () => {
79
43
  setActiveMonths,
80
44
  numberOfMonths: 1,
81
45
  setFocusedDate: () => undefined,
82
- minBookingDate: "2020-12-25",
83
- maxBookingDate: "2022-03-11",
46
+ minBookingDate: new Date("2020-12-25"),
47
+ maxBookingDate: new Date("2022-03-11"),
84
48
  });
85
49
  });
86
50
  // go to year 2020
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useDatePicker = useDatePicker;
4
4
  const react_1 = require("react");
5
- const date_string_1 = require("../utils/date-string");
5
+ const dayjs_utils_1 = require("../utils/dayjs-utils");
6
6
  const get_initial_months_1 = require("../utils/get-initial-months");
7
7
  const is_date_blocked_1 = require("../utils/is-date-blocked");
8
8
  const is_date_hovered_1 = require("../utils/is-date-hovered");
@@ -10,50 +10,38 @@ const is_in_unavailable_dates_1 = require("../utils/is-in-unavailable-dates");
10
10
  const is_start_date_1 = require("../utils/is-start-date");
11
11
  const use_date_picker_navigation_1 = require("./use-date-picker-navigation");
12
12
  function useDatePicker({ datesConfig = [], firstDayOfWeek = 0, initialVisibleMonth, isDateBlocked: isDateBlockedProps = () => false, maxBookingDate, minBookingDate, numberOfMonths = 1, onDateChange, preventScroll, selectedDate, unavailableDates = [], }) {
13
- // --- Normalize all Date inputs to DateString at boundary ---
14
- const normalizedSelectedDate = selectedDate ? (0, date_string_1.toDateString)(selectedDate) : null;
15
- const normalizedMinBookingDate = minBookingDate ? (0, date_string_1.toDateString)(minBookingDate) : undefined;
16
- const normalizedMaxBookingDate = maxBookingDate ? (0, date_string_1.toDateString)(maxBookingDate) : undefined;
17
13
  const disabledDatesFromConfig = datesConfig.filter((config) => config.isDisabled).flatMap((config) => config.dates);
18
- const allDisabledDates = [
19
- ...unavailableDates.map(date_string_1.toDateString),
20
- ...disabledDatesFromConfig.map(date_string_1.toDateString),
21
- ];
14
+ const disabledDates = [...unavailableDates, ...disabledDatesFromConfig];
22
15
  const [activeMonths, setActiveMonths] = (0, react_1.useState)(() => selectedDate
23
16
  ? (0, get_initial_months_1.getInitialMonths)(numberOfMonths, selectedDate)
24
17
  : (0, get_initial_months_1.getInitialMonths)(numberOfMonths, initialVisibleMonth || null));
25
18
  const [hoveredDate, setHoveredDate] = (0, react_1.useState)(null);
26
- const [focusedDate, setFocusedDate] = (0, react_1.useState)(normalizedSelectedDate);
27
- // Consumer's isDateBlocked callback still receives Date via fromDateString
19
+ const [focusedDate, setFocusedDate] = (0, react_1.useState)(selectedDate);
28
20
  const disabledDatesByUser = (date) => {
29
- return (0, is_in_unavailable_dates_1.isInUnavailableDates)(allDisabledDates, date) || isDateBlockedProps((0, date_string_1.fromDateString)(date));
21
+ return (0, is_in_unavailable_dates_1.isInUnavailableDates)(disabledDates, date) || isDateBlockedProps(date);
30
22
  };
31
23
  const onDateFocus = (0, react_1.useCallback)((date) => {
32
- const dateStr = (0, date_string_1.toDateString)(date);
33
- setFocusedDate(dateStr);
34
- const focusedYYYYMM = (0, date_string_1.toDateString)(date).slice(0, 7);
35
- if (!focusedDate ||
36
- !activeMonths.some((m) => `${m.year}-${String(m.month + 1).padStart(2, "0")}` === focusedYYYYMM)) {
24
+ setFocusedDate(date);
25
+ if (!focusedDate || !activeMonths.map((m) => m.month).includes((0, dayjs_utils_1.dayjsEnRaw)(date).month())) {
37
26
  setActiveMonths((0, get_initial_months_1.getInitialMonths)(numberOfMonths, date));
38
27
  }
39
28
  }, [activeMonths, focusedDate, numberOfMonths]);
40
- const _isDateSelected = (date) => (0, is_start_date_1.isStartDate)((0, date_string_1.toDateString)(date), normalizedSelectedDate);
29
+ const _isDateSelected = (date) => (0, is_start_date_1.isStartDate)(date, selectedDate);
41
30
  const _isDateBlocked = (date) => (0, is_date_blocked_1.isDateBlocked)({
42
- date: (0, date_string_1.toDateString)(date),
43
- minBookingDate: normalizedMinBookingDate,
44
- maxBookingDate: normalizedMaxBookingDate,
45
- startDate: normalizedSelectedDate,
46
- endDate: normalizedSelectedDate,
31
+ date,
32
+ minBookingDate,
33
+ maxBookingDate,
34
+ startDate: selectedDate,
35
+ endDate: selectedDate,
47
36
  minBookingDays: 1,
48
- isDateBlockedFn: isDateBlockedProps,
49
- unavailableDates: allDisabledDates,
37
+ isDateBlockedFn: disabledDatesByUser,
50
38
  });
51
- const isDateFocused = (date) => focusedDate !== null && (0, date_string_1.toDateString)(date) === focusedDate;
39
+ const isDateFocused = (date) => (focusedDate ? (0, dayjs_utils_1.dayjsEnRaw)(date).isSame(focusedDate, "day") : false);
52
40
  const _isDateHovered = (date) => (0, is_date_hovered_1.isDateHovered)({
53
- date: (0, date_string_1.toDateString)(date),
41
+ date,
54
42
  hoveredDate,
55
- startDate: normalizedSelectedDate,
56
- endDate: normalizedSelectedDate,
43
+ startDate: selectedDate,
44
+ endDate: selectedDate,
57
45
  minBookingDays: 1,
58
46
  exactMinBookingDays: false,
59
47
  isDateBlocked: disabledDatesByUser,
@@ -77,8 +65,7 @@ function useDatePicker({ datesConfig = [], firstDayOfWeek = 0, initialVisibleMon
77
65
  onDateChange(null);
78
66
  }, [onDateChange]);
79
67
  function onDateSelect(date) {
80
- const dateStr = (0, date_string_1.toDateString)(date);
81
- if (dateStr !== normalizedSelectedDate) {
68
+ if (!(0, dayjs_utils_1.dayjsEnRaw)(date).isSame(selectedDate)) {
82
69
  onDateChange(date);
83
70
  }
84
71
  else {
@@ -90,10 +77,9 @@ function useDatePicker({ datesConfig = [], firstDayOfWeek = 0, initialVisibleMon
90
77
  setHoveredDate(null);
91
78
  }
92
79
  else {
93
- const dateStr = (0, date_string_1.toDateString)(date);
94
- const isNotBlocked = !_isDateBlocked(date) || (normalizedSelectedDate && dateStr === normalizedSelectedDate);
80
+ const isNotBlocked = !_isDateBlocked(date) || (selectedDate && (0, dayjs_utils_1.dayjsEnRaw)(date).isSame(selectedDate, "day"));
95
81
  if (isNotBlocked) {
96
- setHoveredDate(dateStr);
82
+ setHoveredDate(date);
97
83
  }
98
84
  else if (hoveredDate !== null) {
99
85
  setHoveredDate(null);
@@ -103,17 +89,17 @@ function useDatePicker({ datesConfig = [], firstDayOfWeek = 0, initialVisibleMon
103
89
  return {
104
90
  ...(0, use_date_picker_navigation_1.useDatePickerNavigation)({
105
91
  activeMonths,
106
- maxBookingDate: normalizedMaxBookingDate,
107
- minBookingDate: normalizedMinBookingDate,
92
+ maxBookingDate,
93
+ minBookingDate,
108
94
  numberOfMonths,
109
95
  setActiveMonths,
110
- setFocusedDate: (date) => setFocusedDate(date ? (0, date_string_1.toDateString)(date) : null),
96
+ setFocusedDate,
111
97
  }),
112
98
  activeMonths,
113
99
  datesConfig,
114
100
  firstDayOfWeek,
115
- focusedDate: focusedDate ? (0, date_string_1.fromDateString)(focusedDate) : null,
116
- hoveredDate: hoveredDate ? (0, date_string_1.fromDateString)(hoveredDate) : null,
101
+ focusedDate,
102
+ hoveredDate,
117
103
  isDateBlocked: _isDateBlocked,
118
104
  isDateFocused,
119
105
  isDateHovered: _isDateHovered,
@@ -125,6 +111,6 @@ function useDatePicker({ datesConfig = [], firstDayOfWeek = 0, initialVisibleMon
125
111
  onResetDates: onReset,
126
112
  preventScroll,
127
113
  selectedDate,
128
- unavailableDates: allDisabledDates.map(date_string_1.fromDateString),
114
+ unavailableDates: disabledDates,
129
115
  };
130
116
  }
@@ -4,11 +4,11 @@ const react_1 = require("@testing-library/react");
4
4
  const react_2 = require("react");
5
5
  const use_date_picker_1 = require("./use-date-picker");
6
6
  test("base data", () => {
7
- const BASE_DATE = new Date("2021-09-15T00:00:00Z");
7
+ const BASE_DATE = new Date("2021-09-15T00:00:00+02:00");
8
8
  const { result } = (0, react_1.renderHook)(() => (0, use_date_picker_1.useDatePicker)({
9
9
  selectedDate: BASE_DATE,
10
10
  onDateChange: () => undefined,
11
- minBookingDate: new Date("2020-01-01T00:00:00Z"),
11
+ minBookingDate: new Date("2020-01-01"),
12
12
  }));
13
13
  expect(result.current.firstDayOfWeek).toBe(0);
14
14
  expect(result.current.focusedDate).toStrictEqual(BASE_DATE);
@@ -4,7 +4,7 @@ exports.END_DATE = exports.START_DATE = void 0;
4
4
  exports.useDateRangePicker = useDateRangePicker;
5
5
  const react_1 = require("react");
6
6
  const can_select_range_1 = require("../utils/can-select-range");
7
- const date_string_1 = require("../utils/date-string");
7
+ const dayjs_utils_1 = require("../utils/dayjs-utils");
8
8
  const get_initial_months_1 = require("../utils/get-initial-months");
9
9
  const is_date_blocked_1 = require("../utils/is-date-blocked");
10
10
  const is_date_hovered_1 = require("../utils/is-date-hovered");
@@ -17,62 +17,44 @@ const use_date_picker_navigation_1 = require("./use-date-picker-navigation");
17
17
  exports.START_DATE = "startDate";
18
18
  exports.END_DATE = "endDate";
19
19
  function useDateRangePicker({ changeActiveMonthOnSelect = false, datesConfig = [], endDate, exactMinBookingDays = false, firstDayOfWeek = 0, focusedInput, initialVisibleMonth, isDateBlocked: isDateBlockedProps, maxBookingDate, minBookingDate, minBookingDays = 1, numberOfMonths = 2, onDatesChange, startDate, unavailableDates = [], }) {
20
- // --- Normalize all Date inputs to DateString at boundary ---
21
- const normalizedStartDate = startDate ? (0, date_string_1.toDateString)(startDate) : null;
22
- const normalizedEndDate = endDate ? (0, date_string_1.toDateString)(endDate) : null;
23
- const normalizedMinBookingDate = minBookingDate ? (0, date_string_1.toDateString)(minBookingDate) : undefined;
24
- const normalizedMaxBookingDate = maxBookingDate ? (0, date_string_1.toDateString)(maxBookingDate) : undefined;
25
20
  const disabledDatesFromConfig = datesConfig.filter((config) => config.isDisabled).flatMap((config) => config.dates);
26
- const allDisabledDates = [
27
- ...unavailableDates.map(date_string_1.toDateString),
28
- ...disabledDatesFromConfig.map(date_string_1.toDateString),
29
- ];
21
+ const disabledDates = [...unavailableDates, ...disabledDatesFromConfig];
30
22
  const [activeMonths, setActiveMonths] = (0, react_1.useState)(() => startDate
31
23
  ? (0, get_initial_months_1.getInitialMonths)(numberOfMonths, startDate)
32
24
  : (0, get_initial_months_1.getInitialMonths)(numberOfMonths, initialVisibleMonth || null));
33
25
  const [hoveredDate, setHoveredDate] = (0, react_1.useState)(null);
34
- const [focusedDate, setFocusedDate] = (0, react_1.useState)(normalizedStartDate);
35
- // Consumer's isDateBlockedProps (Date boolean) wrapped as DateString → boolean
36
- const disabledDatesByUser = isDateBlockedProps || allDisabledDates.length > 0
26
+ const [focusedDate, setFocusedDate] = (0, react_1.useState)(startDate);
27
+ const disabledDatesByUser = isDateBlockedProps || disabledDates.length > 0
37
28
  ? (date) => {
38
29
  var _a;
39
- return ((0, is_in_unavailable_dates_1.isInUnavailableDates)(allDisabledDates, date) ||
40
- ((_a = isDateBlockedProps === null || isDateBlockedProps === void 0 ? void 0 : isDateBlockedProps((0, date_string_1.fromDateString)(date))) !== null && _a !== void 0 ? _a : false));
30
+ return (0, is_in_unavailable_dates_1.isInUnavailableDates)(disabledDates, date) || ((_a = isDateBlockedProps === null || isDateBlockedProps === void 0 ? void 0 : isDateBlockedProps(date)) !== null && _a !== void 0 ? _a : false);
41
31
  }
42
32
  : null;
43
33
  const onDateFocus = (0, react_1.useCallback)((date) => {
44
- const dateStr = (0, date_string_1.toDateString)(date);
45
- setFocusedDate(dateStr);
46
- const focusedYYYYMM = (0, date_string_1.toDateString)(date).slice(0, 7);
47
- if (!focusedDate ||
48
- !activeMonths.some((m) => `${m.year}-${String(m.month + 1).padStart(2, "0")}` === focusedYYYYMM)) {
34
+ setFocusedDate(date);
35
+ if (!focusedDate || !activeMonths.map((m) => m.month).includes((0, dayjs_utils_1.dayjsEnRaw)(date).month())) {
49
36
  setActiveMonths((0, get_initial_months_1.getInitialMonths)(numberOfMonths, date));
50
37
  }
51
38
  }, [activeMonths, focusedDate, numberOfMonths]);
52
- const _isDateSelected = (date) => {
53
- const dateStr = (0, date_string_1.toDateString)(date);
54
- return ((0, is_date_inside_range_1.isDateInsideRange)(dateStr, normalizedStartDate, normalizedEndDate) ||
55
- (0, is_first_or_last_selected_date_1.isFirstOrLastSelectedDate)(dateStr, normalizedStartDate, normalizedEndDate));
56
- };
57
- const _isStartDate = (date) => (0, is_start_date_1.isStartDate)((0, date_string_1.toDateString)(date), normalizedStartDate);
58
- const _isEndDate = (date) => (0, is_end_date_1.isEndDate)((0, date_string_1.toDateString)(date), normalizedEndDate);
59
- const _isDateInsideRange = (date) => (0, is_date_inside_range_1.isDateInsideRange)((0, date_string_1.toDateString)(date), normalizedStartDate, normalizedEndDate);
39
+ const _isDateSelected = (date) => (0, is_date_inside_range_1.isDateInsideRange)(date, startDate, endDate) || (0, is_first_or_last_selected_date_1.isFirstOrLastSelectedDate)(date, startDate, endDate);
40
+ const _isStartDate = (date) => (0, is_start_date_1.isStartDate)(date, startDate);
41
+ const _isEndDate = (date) => (0, is_end_date_1.isEndDate)(date, endDate);
42
+ const _isDateInsideRange = (date) => (0, is_date_inside_range_1.isDateInsideRange)(date, startDate, endDate);
60
43
  const _isDateBlocked = (date) => (0, is_date_blocked_1.isDateBlocked)({
61
- date: (0, date_string_1.toDateString)(date),
62
- minBookingDate: normalizedMinBookingDate,
63
- maxBookingDate: normalizedMaxBookingDate,
64
- startDate: normalizedStartDate,
65
- endDate: normalizedEndDate,
44
+ date,
45
+ minBookingDate,
46
+ maxBookingDate,
47
+ startDate,
48
+ endDate,
66
49
  minBookingDays,
67
- isDateBlockedFn: isDateBlockedProps,
68
- unavailableDates: allDisabledDates,
50
+ isDateBlockedFn: disabledDatesByUser,
69
51
  });
70
- const isDateFocused = (date) => focusedDate !== null && (0, date_string_1.toDateString)(date) === focusedDate;
52
+ const isDateFocused = (date) => (focusedDate ? (0, dayjs_utils_1.dayjsEnRaw)(date).isSame(focusedDate, "day") : false);
71
53
  const _isDateHovered = (date) => (0, is_date_hovered_1.isDateHovered)({
72
- date: (0, date_string_1.toDateString)(date),
54
+ date,
73
55
  hoveredDate,
74
- startDate: normalizedStartDate,
75
- endDate: normalizedEndDate,
56
+ startDate,
57
+ endDate,
76
58
  minBookingDays,
77
59
  exactMinBookingDays,
78
60
  isDateBlocked: disabledDatesByUser,
@@ -101,45 +83,41 @@ function useDateRangePicker({ changeActiveMonthOnSelect = false, datesConfig = [
101
83
  }, [onDatesChange]);
102
84
  // eslint-disable-next-line complexity
103
85
  function onDateSelect(date) {
104
- const dateStr = (0, date_string_1.toDateString)(date);
105
86
  if ((focusedInput === exports.END_DATE || focusedInput === exports.START_DATE) &&
106
87
  minBookingDays > 0 &&
107
88
  exactMinBookingDays &&
108
89
  (0, can_select_range_1.canSelectRange)({
109
90
  minBookingDays,
110
91
  exactMinBookingDays,
111
- minBookingDate: normalizedMinBookingDate,
112
- maxBookingDate: normalizedMaxBookingDate,
92
+ minBookingDate,
93
+ maxBookingDate,
113
94
  isDateBlocked: disabledDatesByUser,
114
- startDate: dateStr,
95
+ startDate: date,
115
96
  endDate: null,
116
97
  })) {
117
98
  onDatesChange({
118
- startDate: (0, date_string_1.fromDateString)(dateStr),
119
- endDate: (0, date_string_1.fromDateString)((0, date_string_1.addDays)(dateStr, minBookingDays - 1)),
99
+ startDate: date,
100
+ endDate: (0, dayjs_utils_1.dayjsEnRaw)(date)
101
+ .add(minBookingDays - 1, "day")
102
+ .toDate(),
120
103
  focusedInput: null,
121
104
  });
122
105
  }
123
- else if ((((focusedInput === exports.END_DATE && normalizedStartDate && dateStr < normalizedStartDate) ||
124
- (focusedInput === exports.START_DATE && normalizedEndDate && dateStr > normalizedEndDate)) &&
106
+ else if ((((focusedInput === exports.END_DATE && startDate && (0, dayjs_utils_1.dayjsEnRaw)(date).isBefore(startDate)) ||
107
+ (focusedInput === exports.START_DATE && endDate && (0, dayjs_utils_1.dayjsEnRaw)(date).isAfter(endDate))) &&
125
108
  !exactMinBookingDays &&
126
109
  (0, can_select_range_1.canSelectRange)({
127
110
  minBookingDays,
128
111
  isDateBlocked: disabledDatesByUser,
129
- startDate: dateStr,
112
+ startDate: date,
130
113
  endDate: null,
131
114
  })) ||
132
115
  (focusedInput === exports.START_DATE &&
133
116
  !exactMinBookingDays &&
134
- (0, can_select_range_1.canSelectRange)({
135
- minBookingDays,
136
- isDateBlocked: disabledDatesByUser,
137
- endDate: normalizedEndDate,
138
- startDate: dateStr,
139
- }))) {
117
+ (0, can_select_range_1.canSelectRange)({ minBookingDays, isDateBlocked: disabledDatesByUser, endDate, startDate: date }))) {
140
118
  onDatesChange({
141
119
  endDate: null,
142
- startDate: (0, date_string_1.fromDateString)(dateStr),
120
+ startDate: date,
143
121
  focusedInput: exports.END_DATE,
144
122
  });
145
123
  }
@@ -149,58 +127,51 @@ function useDateRangePicker({ changeActiveMonthOnSelect = false, datesConfig = [
149
127
  minBookingDays,
150
128
  isDateBlocked: disabledDatesByUser,
151
129
  endDate: null,
152
- startDate: dateStr,
130
+ startDate: date,
153
131
  })) {
154
132
  onDatesChange({
155
133
  endDate: null,
156
- startDate: (0, date_string_1.fromDateString)(dateStr),
134
+ startDate: date,
157
135
  focusedInput: exports.END_DATE,
158
136
  });
159
137
  }
160
138
  else if (focusedInput === exports.END_DATE &&
161
- normalizedStartDate &&
162
- dateStr >= normalizedStartDate &&
139
+ startDate &&
140
+ !(0, dayjs_utils_1.dayjsEnRaw)(date).isBefore(startDate) &&
163
141
  !exactMinBookingDays &&
164
- (0, can_select_range_1.canSelectRange)({
165
- minBookingDays,
166
- isDateBlocked: disabledDatesByUser,
167
- startDate: normalizedStartDate,
168
- endDate: dateStr,
169
- })) {
142
+ (0, can_select_range_1.canSelectRange)({ minBookingDays, isDateBlocked: disabledDatesByUser, startDate, endDate: date })) {
170
143
  onDatesChange({
171
- startDate: (0, date_string_1.fromDateString)(normalizedStartDate),
172
- endDate: (0, date_string_1.fromDateString)(dateStr),
144
+ startDate,
145
+ endDate: date,
173
146
  focusedInput: null,
174
147
  });
175
148
  }
176
149
  if (focusedInput !== exports.END_DATE &&
177
- (!focusedDate || dateStr.slice(0, 7) !== focusedDate.slice(0, 7)) &&
150
+ (!focusedDate || !(0, dayjs_utils_1.dayjsEnRaw)(date).isSame(focusedDate, "month")) &&
178
151
  changeActiveMonthOnSelect) {
179
- setActiveMonths((0, get_initial_months_1.getInitialMonths)(numberOfMonths, (0, date_string_1.fromDateString)(dateStr)));
152
+ setActiveMonths((0, get_initial_months_1.getInitialMonths)(numberOfMonths, date));
180
153
  }
181
154
  }
182
155
  function onDatesSelect(start, end) {
183
- const startStr = (0, date_string_1.toDateString)(start);
184
- const endStr = end ? (0, date_string_1.toDateString)(end) : null;
185
156
  if ((0, can_select_range_1.canSelectRange)({
186
157
  minBookingDays,
187
158
  exactMinBookingDays,
188
- minBookingDate: normalizedMinBookingDate,
189
- maxBookingDate: normalizedMaxBookingDate,
159
+ minBookingDate,
160
+ maxBookingDate,
190
161
  isDateBlocked: disabledDatesByUser,
191
- startDate: startStr,
192
- endDate: endStr,
162
+ startDate: start,
163
+ endDate: end,
193
164
  })) {
194
165
  onDatesChange({
195
- endDate: endStr ? (0, date_string_1.fromDateString)(endStr) : null,
196
- startDate: (0, date_string_1.fromDateString)(startStr),
166
+ endDate: end,
167
+ startDate: start,
197
168
  focusedInput: exports.START_DATE,
198
169
  });
199
170
  }
200
171
  if (focusedInput !== exports.END_DATE &&
201
- (!focusedDate || startStr.slice(0, 7) !== focusedDate.slice(0, 7)) &&
172
+ (!focusedDate || !(0, dayjs_utils_1.dayjsEnRaw)(start).isSame(focusedDate, "month")) &&
202
173
  changeActiveMonthOnSelect) {
203
- setActiveMonths((0, get_initial_months_1.getInitialMonths)(numberOfMonths, (0, date_string_1.fromDateString)(startStr)));
174
+ setActiveMonths((0, get_initial_months_1.getInitialMonths)(numberOfMonths, start));
204
175
  }
205
176
  }
206
177
  // eslint-disable-next-line complexity
@@ -209,20 +180,20 @@ function useDateRangePicker({ changeActiveMonthOnSelect = false, datesConfig = [
209
180
  setHoveredDate(null);
210
181
  }
211
182
  else {
212
- const dateStr = (0, date_string_1.toDateString)(date);
213
- const isNotBlocked = !_isDateBlocked(date) || (normalizedStartDate && dateStr === normalizedStartDate);
214
- const isHoveredDateAfterOrEqualMinDate = normalizedMinBookingDate
215
- ? dateStr >= (0, date_string_1.addDays)(normalizedMinBookingDate, -1)
183
+ const isNotBlocked = !_isDateBlocked(date) || (startDate && (0, dayjs_utils_1.dayjsEnRaw)(date).isSame(startDate, "day"));
184
+ const isHoveredDateAfterOrEqualMinDate = minBookingDate
185
+ ? !(0, dayjs_utils_1.dayjsEnRaw)(date).isBefore((0, dayjs_utils_1.dayjsEnRaw)(minBookingDate).subtract(1, "day"))
216
186
  : true;
217
- const isHoveredDateBeforeOrEqualMaxDate = normalizedMaxBookingDate
218
- ? dateStr <= normalizedMaxBookingDate
187
+ const isHoveredDateBeforeOrEqualMaxDate = maxBookingDate ? !(0, dayjs_utils_1.dayjsEnRaw)(date).isAfter(maxBookingDate) : true;
188
+ // Exact minimal booking days
189
+ const potentialEndDate = (0, dayjs_utils_1.dayjsEnRaw)(date)
190
+ .add(minBookingDays - 1, "day")
191
+ .toDate();
192
+ const isPotentialEndDateAfterOrEqualMinDate = minBookingDate
193
+ ? !(0, dayjs_utils_1.dayjsEnRaw)(potentialEndDate).isBefore(minBookingDate)
219
194
  : true;
220
- const potentialEndDateStr = (0, date_string_1.addDays)(dateStr, minBookingDays - 1);
221
- const isPotentialEndDateAfterOrEqualMinDate = normalizedMinBookingDate
222
- ? potentialEndDateStr >= normalizedMinBookingDate
223
- : true;
224
- const isPotentialEndDateBeforeOrEqualMaxDate = normalizedMaxBookingDate
225
- ? potentialEndDateStr <= normalizedMaxBookingDate
195
+ const isPotentialEndDateBeforeOrEqualMaxDate = maxBookingDate
196
+ ? !(0, dayjs_utils_1.dayjsEnRaw)(potentialEndDate).isAfter(maxBookingDate)
226
197
  : true;
227
198
  const isExactAndInRange = exactMinBookingDays &&
228
199
  minBookingDays > 1 &&
@@ -230,17 +201,19 @@ function useDateRangePicker({ changeActiveMonthOnSelect = false, datesConfig = [
230
201
  isHoveredDateBeforeOrEqualMaxDate &&
231
202
  isPotentialEndDateAfterOrEqualMinDate &&
232
203
  isPotentialEndDateBeforeOrEqualMaxDate;
233
- const isInRange = normalizedStartDate &&
234
- !normalizedEndDate &&
204
+ // Is date in range
205
+ const isInRange = startDate &&
206
+ !endDate &&
235
207
  !exactMinBookingDays &&
236
208
  isHoveredDateAfterOrEqualMinDate &&
237
209
  isHoveredDateBeforeOrEqualMaxDate;
238
- const isMinBookingDaysInRange = minBookingDays > 1 && normalizedStartDate
239
- ? dateStr > normalizedStartDate && dateStr < (0, date_string_1.addDays)(normalizedStartDate, minBookingDays - 2)
210
+ // Is start date hovered and in range
211
+ const isMinBookingDaysInRange = minBookingDays > 1 && startDate
212
+ ? (0, dayjs_utils_1.dayjsEnRaw)(date).isBetween(startDate, (0, dayjs_utils_1.dayjsEnRaw)(startDate).add(minBookingDays - 2, "day"))
240
213
  : true;
241
- const isStartDateHoveredAndInRange = normalizedStartDate && dateStr === normalizedStartDate && isMinBookingDaysInRange;
214
+ const isStartDateHoveredAndInRange = startDate && (0, dayjs_utils_1.dayjsEnRaw)(date).isSame(startDate, "day") && isMinBookingDaysInRange;
242
215
  if (isNotBlocked && (isExactAndInRange || isInRange || isStartDateHoveredAndInRange)) {
243
- setHoveredDate(dateStr);
216
+ setHoveredDate(date);
244
217
  }
245
218
  else if (hoveredDate !== null) {
246
219
  setHoveredDate(null);
@@ -250,17 +223,17 @@ function useDateRangePicker({ changeActiveMonthOnSelect = false, datesConfig = [
250
223
  return {
251
224
  ...(0, use_date_picker_navigation_1.useDatePickerNavigation)({
252
225
  activeMonths,
253
- maxBookingDate: normalizedMaxBookingDate,
254
- minBookingDate: normalizedMinBookingDate,
226
+ maxBookingDate,
227
+ minBookingDate,
255
228
  numberOfMonths,
256
229
  setActiveMonths,
257
- setFocusedDate: (d) => setFocusedDate(d ? (0, date_string_1.toDateString)(d) : null),
230
+ setFocusedDate,
258
231
  }),
259
232
  activeMonths,
260
233
  datesConfig,
261
234
  firstDayOfWeek,
262
- focusedDate: focusedDate ? (0, date_string_1.fromDateString)(focusedDate) : null,
263
- hoveredDate: hoveredDate ? (0, date_string_1.fromDateString)(hoveredDate) : null,
235
+ focusedDate,
236
+ hoveredDate,
264
237
  isDateBlocked: _isDateBlocked,
265
238
  isDateFocused,
266
239
  isDateHovered: _isDateHovered,
@@ -274,6 +247,6 @@ function useDateRangePicker({ changeActiveMonthOnSelect = false, datesConfig = [
274
247
  onDateSelect,
275
248
  onDatesSelect,
276
249
  onResetDates,
277
- unavailableDates: allDisabledDates.map(date_string_1.fromDateString),
250
+ unavailableDates: disabledDates,
278
251
  };
279
252
  }