@uxf/datepicker 10.0.0 → 10.8.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.
- package/contexts/date-picker-context.js +1 -0
- package/contexts/date-range-picker-context.js +1 -0
- package/hooks/use-date-picker.d.ts +1 -0
- package/hooks/use-date-picker.js +1 -0
- package/hooks/use-date-range-picker.d.ts +1 -0
- package/hooks/use-date-range-picker.js +1 -0
- package/hooks/use-day.d.ts +4 -1
- package/hooks/use-day.js +16 -1
- package/hooks/use-day.test.js +28 -0
- package/package.json +1 -1
- package/utils/get-date-intervals.test.d.ts +1 -0
- package/utils/get-date-intervals.test.js +39 -0
- package/utils/get-date-invervals.d.ts +3 -0
- package/utils/get-date-invervals.js +31 -0
|
@@ -28,5 +28,6 @@ export interface UseDatePickerReturnType extends UseDatePickerNavigationReturnTy
|
|
|
28
28
|
onDateSelect: (date: Date) => void;
|
|
29
29
|
onResetDates: () => void;
|
|
30
30
|
preventScroll?: boolean;
|
|
31
|
+
unavailableDates: Date[];
|
|
31
32
|
}
|
|
32
33
|
export declare function useDatePicker({ firstDayOfWeek, initialVisibleMonth, isDateBlocked: isDateBlockedProps, maxBookingDate, minBookingDate, numberOfMonths, onDateChange, preventScroll, selectedDate, unavailableDates, }: UseDatePickerProps): UseDatePickerReturnType;
|
package/hooks/use-date-picker.js
CHANGED
|
@@ -43,5 +43,6 @@ export interface UseDateRangePickerReturnType extends UseDatePickerNavigationRet
|
|
|
43
43
|
onDateSelect: (date: Date) => void;
|
|
44
44
|
onResetDates: () => void;
|
|
45
45
|
preventScroll?: boolean;
|
|
46
|
+
unavailableDates: Date[];
|
|
46
47
|
}
|
|
47
48
|
export declare function useDateRangePicker({ changeActiveMonthOnSelect, endDate, exactMinBookingDays, firstDayOfWeek, focusedInput, initialVisibleMonth, isDateBlocked: isDateBlockedProps, maxBookingDate, minBookingDate, minBookingDays, numberOfMonths, onDatesChange, startDate, unavailableDates, }: UseDateRangePickerProps): UseDateRangePickerReturnType;
|
package/hooks/use-day.d.ts
CHANGED
|
@@ -12,8 +12,11 @@ export interface UseDayProps {
|
|
|
12
12
|
onDateHover: (date: Date) => void;
|
|
13
13
|
onDateSelect: (date: Date) => void;
|
|
14
14
|
preventScroll?: boolean;
|
|
15
|
+
unavailableDates: Date[];
|
|
15
16
|
}
|
|
16
17
|
export interface UseDayReturnType {
|
|
18
|
+
isFirstDisabled: boolean;
|
|
19
|
+
isLastDisabled: boolean;
|
|
17
20
|
disabledDate: boolean;
|
|
18
21
|
isHovered: boolean;
|
|
19
22
|
isSelected: boolean;
|
|
@@ -25,4 +28,4 @@ export interface UseDayReturnType {
|
|
|
25
28
|
onMouseEnter: () => void;
|
|
26
29
|
tabIndex: number;
|
|
27
30
|
}
|
|
28
|
-
export declare function useDay({ date, dayRef, focusedDate, isDateBlocked, isDateFocused, isDateHovered, isDateInsideRange, isDateSelected, onDateFocus, onDateHover, onDateSelect, preventScroll, }: UseDayProps): UseDayReturnType;
|
|
31
|
+
export declare function useDay({ date, dayRef, focusedDate, isDateBlocked, isDateFocused, isDateHovered, isDateInsideRange, isDateSelected, onDateFocus, onDateHover, onDateSelect, preventScroll, unavailableDates, }: UseDayProps): UseDayReturnType;
|
package/hooks/use-day.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.useDay = void 0;
|
|
7
|
+
const dayjs_1 = __importDefault(require("dayjs"));
|
|
4
8
|
const react_1 = require("react");
|
|
5
9
|
const dayjs_en_1 = require("../utils/dayjs-en");
|
|
6
|
-
|
|
10
|
+
const get_date_invervals_1 = require("../utils/get-date-invervals");
|
|
11
|
+
function useDay({ date, dayRef, focusedDate, isDateBlocked, isDateFocused, isDateHovered, isDateInsideRange, isDateSelected, onDateFocus, onDateHover, onDateSelect, preventScroll, unavailableDates, }) {
|
|
7
12
|
const onClick = (0, react_1.useCallback)(() => onDateSelect(date), [date, onDateSelect]);
|
|
8
13
|
const onMouseEnter = (0, react_1.useCallback)(() => onDateHover(date), [date, onDateHover]);
|
|
9
14
|
const disabled = isDateBlocked(date) && !isDateHovered(date);
|
|
@@ -34,8 +39,18 @@ function useDay({ date, dayRef, focusedDate, isDateBlocked, isDateFocused, isDat
|
|
|
34
39
|
}
|
|
35
40
|
}
|
|
36
41
|
}, [date, onDateFocus]);
|
|
42
|
+
const sortedUnavailableDates = unavailableDates.slice().sort((a, b) => a.getTime() - b.getTime());
|
|
43
|
+
const dateIntervals = (0, get_date_invervals_1.getDateIntervals)(sortedUnavailableDates);
|
|
44
|
+
const _isFirstUnavailableDate = () => {
|
|
45
|
+
return dateIntervals.some((interval) => (0, dayjs_1.default)(interval.start).isSame(date, "day"));
|
|
46
|
+
};
|
|
47
|
+
const _isLastUnavailableDate = () => {
|
|
48
|
+
return dateIntervals.some((interval) => (0, dayjs_1.default)(interval.end).isSame(date, "day"));
|
|
49
|
+
};
|
|
37
50
|
return {
|
|
38
51
|
disabledDate: disabled,
|
|
52
|
+
isFirstDisabled: _isFirstUnavailableDate(),
|
|
53
|
+
isLastDisabled: _isLastUnavailableDate(),
|
|
39
54
|
isHovered: isDateHovered(date),
|
|
40
55
|
isSelected: isDateSelected(date),
|
|
41
56
|
isInsideRange: isDateInsideRange ? isDateInsideRange(date) : false,
|
package/hooks/use-day.test.js
CHANGED
|
@@ -24,9 +24,36 @@ test("useDay", () => {
|
|
|
24
24
|
isDateInsideRange: () => false,
|
|
25
25
|
onDateHover: () => undefined,
|
|
26
26
|
onDateSelect: () => undefined,
|
|
27
|
+
unavailableDates: [],
|
|
27
28
|
}));
|
|
28
29
|
expect(result.current.tabIndex).toBe(0);
|
|
29
30
|
expect(result.current.disabledDate).toBe(false);
|
|
31
|
+
expect(result.current.isFirstDisabled).toBe(false);
|
|
32
|
+
expect(result.current.isLastDisabled).toBe(false);
|
|
33
|
+
expect(result.current.isHovered).toBe(false);
|
|
34
|
+
expect(result.current.isToday).toBe(false);
|
|
35
|
+
expect(result.current.isSelected).toBe(false);
|
|
36
|
+
expect(result.current.isInsideRange).toBe(false);
|
|
37
|
+
expect(result.current.isWithinHoverRange).toBe(false);
|
|
38
|
+
});
|
|
39
|
+
test("useDay with unavailableDates", () => {
|
|
40
|
+
const { result } = (0, react_hooks_1.renderHook)(() => (0, use_day_1.useDay)({
|
|
41
|
+
date: new Date("2021-09-05"),
|
|
42
|
+
isDateBlocked: () => true,
|
|
43
|
+
focusedDate: null,
|
|
44
|
+
onDateFocus: () => undefined,
|
|
45
|
+
isDateFocused: () => false,
|
|
46
|
+
isDateHovered: () => false,
|
|
47
|
+
isDateSelected: () => false,
|
|
48
|
+
isDateInsideRange: () => false,
|
|
49
|
+
onDateHover: () => undefined,
|
|
50
|
+
onDateSelect: () => undefined,
|
|
51
|
+
unavailableDates: [new Date("2021-09-05")],
|
|
52
|
+
}));
|
|
53
|
+
expect(result.current.tabIndex).toBe(0);
|
|
54
|
+
expect(result.current.disabledDate).toBe(true);
|
|
55
|
+
expect(result.current.isFirstDisabled).toBe(true);
|
|
56
|
+
expect(result.current.isLastDisabled).toBe(true);
|
|
30
57
|
expect(result.current.isHovered).toBe(false);
|
|
31
58
|
expect(result.current.isToday).toBe(false);
|
|
32
59
|
expect(result.current.isSelected).toBe(false);
|
|
@@ -51,6 +78,7 @@ test("actions", () => {
|
|
|
51
78
|
onDateHover: (date) => (hoveredDate = date),
|
|
52
79
|
onDateSelect: (date) => (selectedDate = date),
|
|
53
80
|
dayRef: ref.current,
|
|
81
|
+
unavailableDates: [new Date("2021-09-05")],
|
|
54
82
|
}));
|
|
55
83
|
// hover
|
|
56
84
|
expect(result.current.isHovered).toBe(false);
|
package/package.json
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const dayjs_1 = __importDefault(require("dayjs"));
|
|
7
|
+
const get_date_invervals_1 = require("./get-date-invervals");
|
|
8
|
+
describe("getDateIntervals", () => {
|
|
9
|
+
it("should return empty array for empty input", () => {
|
|
10
|
+
expect((0, get_date_invervals_1.getDateIntervals)([])).toStrictEqual([]);
|
|
11
|
+
});
|
|
12
|
+
it("should return single date as an interval", () => {
|
|
13
|
+
const date = (0, dayjs_1.default)("2023-10-12").toDate();
|
|
14
|
+
expect((0, get_date_invervals_1.getDateIntervals)([date])).toStrictEqual([{ start: date, end: date }]);
|
|
15
|
+
});
|
|
16
|
+
it("should group contiguous dates into intervals", () => {
|
|
17
|
+
const dates = [
|
|
18
|
+
(0, dayjs_1.default)("2023-10-12").toDate(),
|
|
19
|
+
(0, dayjs_1.default)("2023-10-13").toDate(),
|
|
20
|
+
(0, dayjs_1.default)("2023-10-14").toDate(),
|
|
21
|
+
(0, dayjs_1.default)("2023-10-16").toDate(),
|
|
22
|
+
(0, dayjs_1.default)("2023-10-17").toDate(),
|
|
23
|
+
];
|
|
24
|
+
const expected = [
|
|
25
|
+
{ start: dates[0], end: dates[2] },
|
|
26
|
+
{ start: dates[3], end: dates[4] },
|
|
27
|
+
];
|
|
28
|
+
expect((0, get_date_invervals_1.getDateIntervals)(dates)).toStrictEqual(expected);
|
|
29
|
+
});
|
|
30
|
+
it("should handle non-contiguous dates", () => {
|
|
31
|
+
const dates = [(0, dayjs_1.default)("2023-10-12").toDate(), (0, dayjs_1.default)("2023-10-14").toDate(), (0, dayjs_1.default)("2023-10-16").toDate()];
|
|
32
|
+
const expected = [
|
|
33
|
+
{ start: dates[0], end: dates[0] },
|
|
34
|
+
{ start: dates[1], end: dates[1] },
|
|
35
|
+
{ start: dates[2], end: dates[2] },
|
|
36
|
+
];
|
|
37
|
+
expect((0, get_date_invervals_1.getDateIntervals)(dates)).toStrictEqual(expected);
|
|
38
|
+
});
|
|
39
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getDateIntervals = void 0;
|
|
7
|
+
const dayjs_1 = __importDefault(require("dayjs"));
|
|
8
|
+
function getDateIntervals(dates) {
|
|
9
|
+
const intervals = [];
|
|
10
|
+
let currentStart = dates[0];
|
|
11
|
+
let currentEnd = dates[0];
|
|
12
|
+
for (let i = 1; i < dates.length; i++) {
|
|
13
|
+
const currentDate = dates[i];
|
|
14
|
+
const nextDate = (0, dayjs_1.default)(currentEnd).add(1, "day").toDate();
|
|
15
|
+
// If the current date matches the expected next date, it's contiguous
|
|
16
|
+
if ((0, dayjs_1.default)(currentDate).isSame(nextDate, "day")) {
|
|
17
|
+
currentEnd = currentDate;
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
intervals.push({ start: currentStart, end: currentEnd });
|
|
21
|
+
currentStart = currentDate;
|
|
22
|
+
currentEnd = currentDate;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (dates[0]) {
|
|
26
|
+
// Push the last interval
|
|
27
|
+
intervals.push({ start: currentStart, end: currentEnd });
|
|
28
|
+
}
|
|
29
|
+
return intervals;
|
|
30
|
+
}
|
|
31
|
+
exports.getDateIntervals = getDateIntervals;
|