@uxf/datepicker 11.86.0 → 11.88.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-range-picker-context.js +1 -0
- package/hooks/use-date-picker.js +0 -4
- package/hooks/use-date-range-picker.d.ts +1 -0
- package/hooks/use-date-range-picker.js +23 -4
- package/hooks/use-date-range-picker.test.js +170 -0
- package/package.json +1 -1
- package/utils/is-browser.d.ts +0 -1
- package/utils/is-browser.js +0 -5
|
@@ -32,6 +32,7 @@ exports.DateRangePickerContext = (0, react_1.createContext)({
|
|
|
32
32
|
onDateFocus: () => undefined,
|
|
33
33
|
onDateHover: () => undefined,
|
|
34
34
|
onDateSelect: () => undefined,
|
|
35
|
+
onDatesSelect: () => undefined,
|
|
35
36
|
onResetDates: () => undefined,
|
|
36
37
|
unavailableDates: [],
|
|
37
38
|
});
|
package/hooks/use-date-picker.js
CHANGED
|
@@ -4,7 +4,6 @@ exports.useDatePicker = useDatePicker;
|
|
|
4
4
|
const react_1 = require("react");
|
|
5
5
|
const dayjs_en_1 = require("../utils/dayjs-en");
|
|
6
6
|
const get_initial_months_1 = require("../utils/get-initial-months");
|
|
7
|
-
const is_browser_1 = require("../utils/is-browser");
|
|
8
7
|
const is_date_blocked_1 = require("../utils/is-date-blocked");
|
|
9
8
|
const is_date_hovered_1 = require("../utils/is-date-hovered");
|
|
10
9
|
const is_in_unavailable_dates_1 = require("../utils/is-in-unavailable-dates");
|
|
@@ -48,9 +47,6 @@ function useDatePicker({ datesConfig = [], firstDayOfWeek = 0, initialVisibleMon
|
|
|
48
47
|
isDateBlocked: disabledDatesByUser,
|
|
49
48
|
});
|
|
50
49
|
(0, react_1.useEffect)(() => {
|
|
51
|
-
if (!is_browser_1.isBrowser) {
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
50
|
function handleKeyDown(e) {
|
|
55
51
|
var _a, _b;
|
|
56
52
|
if ((e.key === "ArrowRight" || e.key === "ArrowLeft" || e.key === "ArrowDown" || e.key === "ArrowUp") &&
|
|
@@ -44,6 +44,7 @@ export interface UseDateRangePickerReturnType extends UseDatePickerNavigationRet
|
|
|
44
44
|
onDateFocus: (date: Date) => void;
|
|
45
45
|
onDateHover: (date: Date | null) => void;
|
|
46
46
|
onDateSelect: (date: Date) => void;
|
|
47
|
+
onDatesSelect: (startDate: Date, endDate: Date | null) => void;
|
|
47
48
|
onResetDates: () => void;
|
|
48
49
|
preventScroll?: boolean;
|
|
49
50
|
unavailableDates: Date[];
|
|
@@ -6,7 +6,6 @@ const react_1 = require("react");
|
|
|
6
6
|
const can_select_range_1 = require("../utils/can-select-range");
|
|
7
7
|
const dayjs_en_1 = require("../utils/dayjs-en");
|
|
8
8
|
const get_initial_months_1 = require("../utils/get-initial-months");
|
|
9
|
-
const is_browser_1 = require("../utils/is-browser");
|
|
10
9
|
const is_date_blocked_1 = require("../utils/is-date-blocked");
|
|
11
10
|
const is_date_hovered_1 = require("../utils/is-date-hovered");
|
|
12
11
|
const is_date_inside_range_1 = require("../utils/is-date-inside-range");
|
|
@@ -58,9 +57,6 @@ function useDateRangePicker({ changeActiveMonthOnSelect = false, datesConfig = [
|
|
|
58
57
|
isDateBlocked: disabledDatesByUser,
|
|
59
58
|
});
|
|
60
59
|
(0, react_1.useEffect)(() => {
|
|
61
|
-
if (!is_browser_1.isBrowser) {
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
60
|
function handleKeyDown(e) {
|
|
65
61
|
var _a, _b;
|
|
66
62
|
if ((e.key === "ArrowRight" || e.key === "ArrowLeft" || e.key === "ArrowDown" || e.key === "ArrowUp") &&
|
|
@@ -153,6 +149,28 @@ function useDateRangePicker({ changeActiveMonthOnSelect = false, datesConfig = [
|
|
|
153
149
|
setActiveMonths((0, get_initial_months_1.getInitialMonths)(numberOfMonths, date));
|
|
154
150
|
}
|
|
155
151
|
}
|
|
152
|
+
function onDatesSelect(start, end) {
|
|
153
|
+
if ((0, can_select_range_1.canSelectRange)({
|
|
154
|
+
minBookingDays,
|
|
155
|
+
exactMinBookingDays,
|
|
156
|
+
minBookingDate,
|
|
157
|
+
maxBookingDate,
|
|
158
|
+
isDateBlocked: disabledDatesByUser,
|
|
159
|
+
startDate: start,
|
|
160
|
+
endDate: end,
|
|
161
|
+
})) {
|
|
162
|
+
onDatesChange({
|
|
163
|
+
endDate: end,
|
|
164
|
+
startDate: start,
|
|
165
|
+
focusedInput: exports.START_DATE,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
if (focusedInput !== exports.END_DATE &&
|
|
169
|
+
(!focusedDate || !(0, dayjs_en_1.dayjsEn)(start).isSame(focusedDate, "month")) &&
|
|
170
|
+
changeActiveMonthOnSelect) {
|
|
171
|
+
setActiveMonths((0, get_initial_months_1.getInitialMonths)(numberOfMonths, start));
|
|
172
|
+
}
|
|
173
|
+
}
|
|
156
174
|
// eslint-disable-next-line complexity
|
|
157
175
|
function onDateHover(date) {
|
|
158
176
|
if (!date) {
|
|
@@ -224,6 +242,7 @@ function useDateRangePicker({ changeActiveMonthOnSelect = false, datesConfig = [
|
|
|
224
242
|
onDateFocus,
|
|
225
243
|
onDateHover,
|
|
226
244
|
onDateSelect,
|
|
245
|
+
onDatesSelect,
|
|
227
246
|
onResetDates,
|
|
228
247
|
unavailableDates: disabledDates,
|
|
229
248
|
};
|
|
@@ -85,3 +85,173 @@ test("date select", () => {
|
|
|
85
85
|
});
|
|
86
86
|
expect(result.current.isDateSelected(BASE_DATE)).toBe(false);
|
|
87
87
|
});
|
|
88
|
+
test("date range select - valid range", () => {
|
|
89
|
+
const { result: state } = (0, react_1.renderHook)(() => (0, react_2.useState)({ startDate: null, endDate: null, focusedInput: "startDate" }));
|
|
90
|
+
const { result, rerender } = (0, react_1.renderHook)(() => (0, use_date_range_picker_1.useDateRangePicker)({
|
|
91
|
+
startDate: state.current[0].startDate,
|
|
92
|
+
endDate: state.current[0].endDate,
|
|
93
|
+
onDatesChange: (data) => state.current[1](data),
|
|
94
|
+
focusedInput: state.current[0].focusedInput,
|
|
95
|
+
minBookingDate: new Date("2020-01-01"),
|
|
96
|
+
}));
|
|
97
|
+
const START_DATE = new Date("2021-09-15");
|
|
98
|
+
const END_DATE = new Date("2021-09-20");
|
|
99
|
+
(0, react_1.act)(() => {
|
|
100
|
+
result.current.onDatesSelect(START_DATE, END_DATE);
|
|
101
|
+
rerender();
|
|
102
|
+
});
|
|
103
|
+
expect(result.current.isStartDate(START_DATE)).toBe(true);
|
|
104
|
+
expect(result.current.isEndDate(END_DATE)).toBe(true);
|
|
105
|
+
expect(result.current.isDateInsideRange(new Date("2021-09-17"))).toBe(true);
|
|
106
|
+
});
|
|
107
|
+
test("date range select - with null end date", () => {
|
|
108
|
+
const { result: state } = (0, react_1.renderHook)(() => (0, react_2.useState)({ startDate: null, endDate: null, focusedInput: "startDate" }));
|
|
109
|
+
const { result, rerender } = (0, react_1.renderHook)(() => (0, use_date_range_picker_1.useDateRangePicker)({
|
|
110
|
+
startDate: state.current[0].startDate,
|
|
111
|
+
endDate: state.current[0].endDate,
|
|
112
|
+
onDatesChange: (data) => state.current[1](data),
|
|
113
|
+
focusedInput: state.current[0].focusedInput,
|
|
114
|
+
minBookingDate: new Date("2020-01-01"),
|
|
115
|
+
}));
|
|
116
|
+
const START_DATE = new Date("2021-09-15");
|
|
117
|
+
(0, react_1.act)(() => {
|
|
118
|
+
result.current.onDatesSelect(START_DATE, null);
|
|
119
|
+
rerender();
|
|
120
|
+
});
|
|
121
|
+
expect(result.current.isStartDate(START_DATE)).toBe(true);
|
|
122
|
+
expect(state.current[0].endDate).toBe(null);
|
|
123
|
+
});
|
|
124
|
+
test("date range select - with minBookingDays", () => {
|
|
125
|
+
const { result: state } = (0, react_1.renderHook)(() => (0, react_2.useState)({ startDate: null, endDate: null, focusedInput: "startDate" }));
|
|
126
|
+
const { result, rerender } = (0, react_1.renderHook)(() => (0, use_date_range_picker_1.useDateRangePicker)({
|
|
127
|
+
startDate: state.current[0].startDate,
|
|
128
|
+
endDate: state.current[0].endDate,
|
|
129
|
+
onDatesChange: (data) => state.current[1](data),
|
|
130
|
+
focusedInput: state.current[0].focusedInput,
|
|
131
|
+
minBookingDate: new Date("2020-01-01"),
|
|
132
|
+
minBookingDays: 3,
|
|
133
|
+
}));
|
|
134
|
+
const START_DATE = new Date("2021-09-15");
|
|
135
|
+
const END_DATE = new Date("2021-09-17");
|
|
136
|
+
(0, react_1.act)(() => {
|
|
137
|
+
result.current.onDatesSelect(START_DATE, END_DATE);
|
|
138
|
+
rerender();
|
|
139
|
+
});
|
|
140
|
+
expect(result.current.isStartDate(START_DATE)).toBe(true);
|
|
141
|
+
expect(result.current.isEndDate(END_DATE)).toBe(true);
|
|
142
|
+
});
|
|
143
|
+
test("date range select - invalid range with minBookingDays", () => {
|
|
144
|
+
const onDatesChange = jest.fn();
|
|
145
|
+
const { result } = (0, react_1.renderHook)(() => (0, use_date_range_picker_1.useDateRangePicker)({
|
|
146
|
+
startDate: null,
|
|
147
|
+
endDate: null,
|
|
148
|
+
onDatesChange,
|
|
149
|
+
focusedInput: "startDate",
|
|
150
|
+
minBookingDate: new Date("2020-01-01"),
|
|
151
|
+
minBookingDays: 5,
|
|
152
|
+
}));
|
|
153
|
+
const START_DATE = new Date("2021-09-15");
|
|
154
|
+
const END_DATE = new Date("2021-09-17"); // Only 3 days, but minBookingDays is 5
|
|
155
|
+
(0, react_1.act)(() => {
|
|
156
|
+
result.current.onDatesSelect(START_DATE, END_DATE);
|
|
157
|
+
});
|
|
158
|
+
// onDatesChange should not be called with invalid range
|
|
159
|
+
expect(onDatesChange).not.toHaveBeenCalled();
|
|
160
|
+
});
|
|
161
|
+
test("date range select - with exactMinBookingDays", () => {
|
|
162
|
+
const { result: state } = (0, react_1.renderHook)(() => (0, react_2.useState)({ startDate: null, endDate: null, focusedInput: "startDate" }));
|
|
163
|
+
const { result, rerender } = (0, react_1.renderHook)(() => (0, use_date_range_picker_1.useDateRangePicker)({
|
|
164
|
+
startDate: state.current[0].startDate,
|
|
165
|
+
endDate: state.current[0].endDate,
|
|
166
|
+
onDatesChange: (data) => state.current[1](data),
|
|
167
|
+
focusedInput: state.current[0].focusedInput,
|
|
168
|
+
minBookingDate: new Date("2020-01-01"),
|
|
169
|
+
minBookingDays: 3,
|
|
170
|
+
exactMinBookingDays: true,
|
|
171
|
+
}));
|
|
172
|
+
const START_DATE = new Date("2021-09-15");
|
|
173
|
+
const END_DATE = new Date("2021-09-17");
|
|
174
|
+
(0, react_1.act)(() => {
|
|
175
|
+
result.current.onDatesSelect(START_DATE, END_DATE);
|
|
176
|
+
rerender();
|
|
177
|
+
});
|
|
178
|
+
expect(result.current.isStartDate(START_DATE)).toBe(true);
|
|
179
|
+
expect(result.current.isEndDate(END_DATE)).toBe(true);
|
|
180
|
+
});
|
|
181
|
+
test("date range select - blocked dates in range", () => {
|
|
182
|
+
const onDatesChange = jest.fn();
|
|
183
|
+
const { result } = (0, react_1.renderHook)(() => (0, use_date_range_picker_1.useDateRangePicker)({
|
|
184
|
+
startDate: null,
|
|
185
|
+
endDate: null,
|
|
186
|
+
onDatesChange,
|
|
187
|
+
focusedInput: "startDate",
|
|
188
|
+
minBookingDate: new Date("2020-01-01"),
|
|
189
|
+
unavailableDates: [new Date("2021-09-17")],
|
|
190
|
+
}));
|
|
191
|
+
const START_DATE = new Date("2021-09-15");
|
|
192
|
+
const END_DATE = new Date("2021-09-20");
|
|
193
|
+
(0, react_1.act)(() => {
|
|
194
|
+
result.current.onDatesSelect(START_DATE, END_DATE);
|
|
195
|
+
});
|
|
196
|
+
// onDatesChange should not be called when blocked date is in range
|
|
197
|
+
expect(onDatesChange).not.toHaveBeenCalled();
|
|
198
|
+
});
|
|
199
|
+
test("date range select - with changeActiveMonthOnSelect", () => {
|
|
200
|
+
const { result: state } = (0, react_1.renderHook)(() => (0, react_2.useState)({ startDate: null, endDate: null, focusedInput: "startDate" }));
|
|
201
|
+
const { result, rerender } = (0, react_1.renderHook)(() => (0, use_date_range_picker_1.useDateRangePicker)({
|
|
202
|
+
startDate: state.current[0].startDate,
|
|
203
|
+
endDate: state.current[0].endDate,
|
|
204
|
+
onDatesChange: (data) => state.current[1](data),
|
|
205
|
+
focusedInput: state.current[0].focusedInput,
|
|
206
|
+
minBookingDate: new Date("2020-01-01"),
|
|
207
|
+
changeActiveMonthOnSelect: true,
|
|
208
|
+
}));
|
|
209
|
+
const START_DATE = new Date("2022-12-15");
|
|
210
|
+
const END_DATE = new Date("2022-12-20");
|
|
211
|
+
const initialActiveMonths = result.current.activeMonths;
|
|
212
|
+
(0, react_1.act)(() => {
|
|
213
|
+
result.current.onDatesSelect(START_DATE, END_DATE);
|
|
214
|
+
rerender();
|
|
215
|
+
});
|
|
216
|
+
// Active months should change to the selected date's month
|
|
217
|
+
expect(result.current.activeMonths[0].year).toBe(2022);
|
|
218
|
+
expect(result.current.activeMonths[0].month).toBe(11); // December is month 11
|
|
219
|
+
expect(result.current.activeMonths).not.toEqual(initialActiveMonths);
|
|
220
|
+
});
|
|
221
|
+
test("date range select - respects maxBookingDate", () => {
|
|
222
|
+
const onDatesChange = jest.fn();
|
|
223
|
+
const { result } = (0, react_1.renderHook)(() => (0, use_date_range_picker_1.useDateRangePicker)({
|
|
224
|
+
startDate: null,
|
|
225
|
+
endDate: null,
|
|
226
|
+
onDatesChange,
|
|
227
|
+
focusedInput: "startDate",
|
|
228
|
+
minBookingDate: new Date("2020-01-01"),
|
|
229
|
+
maxBookingDate: new Date("2021-09-18"),
|
|
230
|
+
}));
|
|
231
|
+
const START_DATE = new Date("2021-09-15");
|
|
232
|
+
const END_DATE = new Date("2021-09-20"); // After maxBookingDate
|
|
233
|
+
(0, react_1.act)(() => {
|
|
234
|
+
result.current.onDatesSelect(START_DATE, END_DATE);
|
|
235
|
+
});
|
|
236
|
+
// onDatesChange should not be called when end date is after maxBookingDate
|
|
237
|
+
expect(onDatesChange).not.toHaveBeenCalled();
|
|
238
|
+
});
|
|
239
|
+
test("date range select - with isDateBlocked callback", () => {
|
|
240
|
+
const onDatesChange = jest.fn();
|
|
241
|
+
const isDateBlocked = (date) => date.getDate() === 17;
|
|
242
|
+
const { result } = (0, react_1.renderHook)(() => (0, use_date_range_picker_1.useDateRangePicker)({
|
|
243
|
+
startDate: null,
|
|
244
|
+
endDate: null,
|
|
245
|
+
onDatesChange,
|
|
246
|
+
focusedInput: "startDate",
|
|
247
|
+
minBookingDate: new Date("2020-01-01"),
|
|
248
|
+
isDateBlocked,
|
|
249
|
+
}));
|
|
250
|
+
const START_DATE = new Date("2021-09-15");
|
|
251
|
+
const END_DATE = new Date("2021-09-20");
|
|
252
|
+
(0, react_1.act)(() => {
|
|
253
|
+
result.current.onDatesSelect(START_DATE, END_DATE);
|
|
254
|
+
});
|
|
255
|
+
// onDatesChange should not be called when a blocked date (17th) is in the range
|
|
256
|
+
expect(onDatesChange).not.toHaveBeenCalled();
|
|
257
|
+
});
|
package/package.json
CHANGED
package/utils/is-browser.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const isBrowser: boolean;
|
package/utils/is-browser.js
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isBrowser = void 0;
|
|
4
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
5
|
-
exports.isBrowser = Boolean(typeof window !== "undefined" && window.document && window.document.createElement);
|