@uxf/datepicker 10.8.0 → 11.1.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/README.md +25 -17
- package/contexts/date-picker-context.js +1 -0
- package/contexts/date-range-picker-context.js +1 -0
- package/hooks/use-date-picker.d.ts +6 -2
- package/hooks/use-date-picker.js +6 -3
- package/hooks/use-date-range-picker.d.ts +5 -2
- package/hooks/use-date-range-picker.js +6 -3
- package/hooks/use-day.d.ts +8 -4
- package/hooks/use-day.js +23 -6
- package/hooks/use-day.test.js +39 -10
- package/package.json +1 -1
- package/utils/get-date-invervals.js +6 -5
- package/utils/types.d.ts +10 -0
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ A set of React hooks to create an awesome datepicker.
|
|
|
10
10
|
|
|
11
11
|
### Main logic component
|
|
12
12
|
|
|
13
|
-
```
|
|
13
|
+
```tsx
|
|
14
14
|
export const DatePicker: FC = () => {
|
|
15
15
|
// prepare state to handle selected date
|
|
16
16
|
const [selectedDate, setSelectedDate] = useState<OnDateChangeType>(null);
|
|
@@ -42,7 +42,7 @@ export const DatePicker: FC = () => {
|
|
|
42
42
|
|
|
43
43
|
### Month component
|
|
44
44
|
|
|
45
|
-
```
|
|
45
|
+
```tsx
|
|
46
46
|
export const DateRangePickerMonth: FC<UseMonthProps> = ({
|
|
47
47
|
firstDayOfWeek,
|
|
48
48
|
month,
|
|
@@ -69,7 +69,7 @@ export const DateRangePickerMonth: FC<UseMonthProps> = ({
|
|
|
69
69
|
|
|
70
70
|
### Day component
|
|
71
71
|
|
|
72
|
-
```
|
|
72
|
+
```tsx
|
|
73
73
|
export const DateRangePickerDay: FC<{ day: string; date: Date }> = ({ day, date }) => {
|
|
74
74
|
const dayRef = useRef(null);
|
|
75
75
|
const {
|
|
@@ -134,7 +134,8 @@ export const DateRangePickerDay: FC<{ day: string; date: Date }> = ({ day, date
|
|
|
134
134
|
| numberOfMonths | `number` | | `1` | |
|
|
135
135
|
| onDateChange | `(data: OnDateChangeType): void` | yes | | |
|
|
136
136
|
| selectedDate | `Date \| null` | yes | | |
|
|
137
|
-
| unavailableDates | `Date[]` | | `[]` |
|
|
137
|
+
| unavailableDates | `Date[]` | | `[]` | @deprecated |
|
|
138
|
+
| datesConfig | `DatesConfig[]` | | `[]` | |
|
|
138
139
|
|
|
139
140
|
**UseDatePickerReturnType**
|
|
140
141
|
|
|
@@ -186,7 +187,8 @@ export const DateRangePickerDay: FC<{ day: string; date: Date }> = ({ day, date
|
|
|
186
187
|
| numberOfMonths | `number` | | `2` | |
|
|
187
188
|
| onDatesChange | `(data: OnDatesChangeType): void` | yes | | |
|
|
188
189
|
| startDate | `Date \| null` | yes | | |
|
|
189
|
-
| unavailableDates | `Date[]` | | `[]` |
|
|
190
|
+
| unavailableDates | `Date[]` | | `[]` | @deprecated |
|
|
191
|
+
| datesConfig | `DatesConfig[]` | | `[]` | |
|
|
190
192
|
|
|
191
193
|
**UseDateRangePickerReturnType**
|
|
192
194
|
|
|
@@ -280,24 +282,29 @@ export const DateRangePickerDay: FC<{ day: string; date: Date }> = ({ day, date
|
|
|
280
282
|
|
|
281
283
|
**UseDayProps**
|
|
282
284
|
|
|
283
|
-
| name
|
|
284
|
-
|
|
285
|
-
| date
|
|
286
|
-
| dayRef
|
|
287
|
-
| focusedDate
|
|
288
|
-
| isDateBlocked
|
|
289
|
-
| isDateFocused
|
|
290
|
-
| isDateHovered
|
|
291
|
-
| isDateSelected
|
|
292
|
-
| onDateFocus
|
|
293
|
-
| onDateHover
|
|
294
|
-
| onDateSelect
|
|
285
|
+
| name | type | required | default | description |
|
|
286
|
+
|------------------|---------------------------|----------|---------|-------------|
|
|
287
|
+
| date | `Date` | yes | | |
|
|
288
|
+
| dayRef | `RefObject` | | | |
|
|
289
|
+
| focusedDate | `Date \| null` | yes | | |
|
|
290
|
+
| isDateBlocked | `(date: Date) => boolean` | yes | | |
|
|
291
|
+
| isDateFocused | `(date: Date) => boolean` | yes | | |
|
|
292
|
+
| isDateHovered | `(date: Date) => boolean` | yes | | |
|
|
293
|
+
| isDateSelected | `(date: Date) => boolean` | yes | | |
|
|
294
|
+
| onDateFocus | `(date: Date) => void` | yes | | |
|
|
295
|
+
| onDateHover | `(date: Date) => void` | yes | | |
|
|
296
|
+
| onDateSelect | `(date: Date) => void` | yes | | |
|
|
297
|
+
| unavailableDates | `Date[]` | | | @deprecated |
|
|
298
|
+
| datesConfig | `DatesConfig[]` | | | |
|
|
295
299
|
|
|
296
300
|
**UseDayReturnType**
|
|
297
301
|
|
|
298
302
|
| name | type | description |
|
|
299
303
|
|--------------------|------------------------------|-------------|
|
|
300
304
|
| disabledDate | `boolean` | |
|
|
305
|
+
| isFirstDisabled | `boolean` | |
|
|
306
|
+
| isLastDisabled | `boolean` | |
|
|
307
|
+
| disabledDate | `boolean` | |
|
|
301
308
|
| isHovered | `boolean` | |
|
|
302
309
|
| isSelected | `boolean` | |
|
|
303
310
|
| isToday | `boolean` | |
|
|
@@ -306,6 +313,7 @@ export const DateRangePickerDay: FC<{ day: string; date: Date }> = ({ day, date
|
|
|
306
313
|
| onKeyDown | `(e: KeyboardEvent) => void` | |
|
|
307
314
|
| onMouseEnter | `() => void` | |
|
|
308
315
|
| tabIndex | `number` | |
|
|
316
|
+
| flags | `Flag[]` | |
|
|
309
317
|
|
|
310
318
|
## Known issues
|
|
311
319
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { FirstDayOfWeek, MonthType } from "../utils/types";
|
|
1
|
+
import { DatesConfig, FirstDayOfWeek, MonthType } from "../utils/types";
|
|
2
2
|
import { UseDatePickerNavigationReturnType } from "./use-date-picker-navigation";
|
|
3
3
|
export type OnDateChangeType = Date | null;
|
|
4
4
|
export interface UseDatePickerProps {
|
|
5
|
+
datesConfig?: DatesConfig[];
|
|
5
6
|
firstDayOfWeek?: FirstDayOfWeek;
|
|
6
7
|
initialVisibleMonth?: Date;
|
|
7
8
|
isDateBlocked?: (date: Date) => boolean;
|
|
@@ -11,10 +12,12 @@ export interface UseDatePickerProps {
|
|
|
11
12
|
onDateChange: (data: OnDateChangeType) => void;
|
|
12
13
|
preventScroll?: boolean;
|
|
13
14
|
selectedDate: Date | null;
|
|
15
|
+
/** @deprecated */
|
|
14
16
|
unavailableDates?: Date[];
|
|
15
17
|
}
|
|
16
18
|
export interface UseDatePickerReturnType extends UseDatePickerNavigationReturnType {
|
|
17
19
|
activeMonths: MonthType[];
|
|
20
|
+
datesConfig?: DatesConfig[];
|
|
18
21
|
firstDayOfWeek: FirstDayOfWeek;
|
|
19
22
|
focusedDate: Date | null;
|
|
20
23
|
hoveredDate: Date | null;
|
|
@@ -28,6 +31,7 @@ export interface UseDatePickerReturnType extends UseDatePickerNavigationReturnTy
|
|
|
28
31
|
onDateSelect: (date: Date) => void;
|
|
29
32
|
onResetDates: () => void;
|
|
30
33
|
preventScroll?: boolean;
|
|
34
|
+
/** deprecated */
|
|
31
35
|
unavailableDates: Date[];
|
|
32
36
|
}
|
|
33
|
-
export declare function useDatePicker({ firstDayOfWeek, initialVisibleMonth, isDateBlocked: isDateBlockedProps, maxBookingDate, minBookingDate, numberOfMonths, onDateChange, preventScroll, selectedDate, unavailableDates, }: UseDatePickerProps): UseDatePickerReturnType;
|
|
37
|
+
export declare function useDatePicker({ datesConfig, firstDayOfWeek, initialVisibleMonth, isDateBlocked: isDateBlockedProps, maxBookingDate, minBookingDate, numberOfMonths, onDateChange, preventScroll, selectedDate, unavailableDates, }: UseDatePickerProps): UseDatePickerReturnType;
|
package/hooks/use-date-picker.js
CHANGED
|
@@ -10,14 +10,16 @@ const is_date_hovered_1 = require("../utils/is-date-hovered");
|
|
|
10
10
|
const is_in_unavailable_dates_1 = require("../utils/is-in-unavailable-dates");
|
|
11
11
|
const is_start_date_1 = require("../utils/is-start-date");
|
|
12
12
|
const use_date_picker_navigation_1 = require("./use-date-picker-navigation");
|
|
13
|
-
function useDatePicker({ firstDayOfWeek = 0, initialVisibleMonth, isDateBlocked: isDateBlockedProps = () => false, maxBookingDate, minBookingDate, numberOfMonths = 1, onDateChange, preventScroll, selectedDate, unavailableDates = [], }) {
|
|
13
|
+
function useDatePicker({ datesConfig = [], firstDayOfWeek = 0, initialVisibleMonth, isDateBlocked: isDateBlockedProps = () => false, maxBookingDate, minBookingDate, numberOfMonths = 1, onDateChange, preventScroll, selectedDate, unavailableDates = [], }) {
|
|
14
|
+
const disabledDatesFromConfig = datesConfig.filter((config) => config.isDisabled).flatMap((config) => config.dates);
|
|
15
|
+
const disabledDates = [...unavailableDates, ...disabledDatesFromConfig];
|
|
14
16
|
const [activeMonths, setActiveMonths] = (0, react_1.useState)(() => selectedDate
|
|
15
17
|
? (0, get_initial_months_1.getInitialMonths)(numberOfMonths, selectedDate)
|
|
16
18
|
: (0, get_initial_months_1.getInitialMonths)(numberOfMonths, initialVisibleMonth || null));
|
|
17
19
|
const [hoveredDate, setHoveredDate] = (0, react_1.useState)(null);
|
|
18
20
|
const [focusedDate, setFocusedDate] = (0, react_1.useState)(selectedDate);
|
|
19
21
|
const disabledDatesByUser = (date) => {
|
|
20
|
-
return (0, is_in_unavailable_dates_1.isInUnavailableDates)(
|
|
22
|
+
return (0, is_in_unavailable_dates_1.isInUnavailableDates)(disabledDates, date) || isDateBlockedProps(date);
|
|
21
23
|
};
|
|
22
24
|
const onDateFocus = (0, react_1.useCallback)((date) => {
|
|
23
25
|
setFocusedDate(date);
|
|
@@ -97,6 +99,7 @@ function useDatePicker({ firstDayOfWeek = 0, initialVisibleMonth, isDateBlocked:
|
|
|
97
99
|
setFocusedDate,
|
|
98
100
|
}),
|
|
99
101
|
activeMonths,
|
|
102
|
+
datesConfig,
|
|
100
103
|
firstDayOfWeek,
|
|
101
104
|
focusedDate,
|
|
102
105
|
hoveredDate,
|
|
@@ -110,7 +113,7 @@ function useDatePicker({ firstDayOfWeek = 0, initialVisibleMonth, isDateBlocked:
|
|
|
110
113
|
onDateSelect,
|
|
111
114
|
onResetDates: onReset,
|
|
112
115
|
preventScroll,
|
|
113
|
-
unavailableDates,
|
|
116
|
+
unavailableDates: disabledDates,
|
|
114
117
|
};
|
|
115
118
|
}
|
|
116
119
|
exports.useDatePicker = useDatePicker;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FirstDayOfWeek, MonthType } from "../utils/types";
|
|
1
|
+
import { DatesConfig, FirstDayOfWeek, MonthType } from "../utils/types";
|
|
2
2
|
import { UseDatePickerNavigationReturnType } from "./use-date-picker-navigation";
|
|
3
3
|
export declare const START_DATE = "startDate";
|
|
4
4
|
export declare const END_DATE = "endDate";
|
|
@@ -10,6 +10,7 @@ export interface OnDatesChangeProps {
|
|
|
10
10
|
}
|
|
11
11
|
export interface UseDateRangePickerProps {
|
|
12
12
|
changeActiveMonthOnSelect?: boolean;
|
|
13
|
+
datesConfig?: DatesConfig[];
|
|
13
14
|
endDate: Date | null;
|
|
14
15
|
exactMinBookingDays?: boolean;
|
|
15
16
|
firstDayOfWeek?: FirstDayOfWeek;
|
|
@@ -23,10 +24,12 @@ export interface UseDateRangePickerProps {
|
|
|
23
24
|
onDatesChange: (data: OnDatesChangeProps) => void;
|
|
24
25
|
preventScroll?: boolean;
|
|
25
26
|
startDate: Date | null;
|
|
27
|
+
/** @deprecated */
|
|
26
28
|
unavailableDates?: Date[];
|
|
27
29
|
}
|
|
28
30
|
export interface UseDateRangePickerReturnType extends UseDatePickerNavigationReturnType {
|
|
29
31
|
activeMonths: MonthType[];
|
|
32
|
+
datesConfig?: DatesConfig[];
|
|
30
33
|
firstDayOfWeek: FirstDayOfWeek;
|
|
31
34
|
focusedDate: Date | null;
|
|
32
35
|
hoveredDate: Date | null;
|
|
@@ -45,4 +48,4 @@ export interface UseDateRangePickerReturnType extends UseDatePickerNavigationRet
|
|
|
45
48
|
preventScroll?: boolean;
|
|
46
49
|
unavailableDates: Date[];
|
|
47
50
|
}
|
|
48
|
-
export declare function useDateRangePicker({ changeActiveMonthOnSelect, endDate, exactMinBookingDays, firstDayOfWeek, focusedInput, initialVisibleMonth, isDateBlocked: isDateBlockedProps, maxBookingDate, minBookingDate, minBookingDays, numberOfMonths, onDatesChange, startDate, unavailableDates, }: UseDateRangePickerProps): UseDateRangePickerReturnType;
|
|
51
|
+
export declare function useDateRangePicker({ changeActiveMonthOnSelect, datesConfig, endDate, exactMinBookingDays, firstDayOfWeek, focusedInput, initialVisibleMonth, isDateBlocked: isDateBlockedProps, maxBookingDate, minBookingDate, minBookingDays, numberOfMonths, onDatesChange, startDate, unavailableDates, }: UseDateRangePickerProps): UseDateRangePickerReturnType;
|
|
@@ -16,14 +16,16 @@ const is_start_date_1 = require("../utils/is-start-date");
|
|
|
16
16
|
const use_date_picker_navigation_1 = require("./use-date-picker-navigation");
|
|
17
17
|
exports.START_DATE = "startDate";
|
|
18
18
|
exports.END_DATE = "endDate";
|
|
19
|
-
function useDateRangePicker({ changeActiveMonthOnSelect = false, endDate, exactMinBookingDays = false, firstDayOfWeek = 0, focusedInput, initialVisibleMonth, isDateBlocked: isDateBlockedProps = () => false, maxBookingDate, minBookingDate, minBookingDays = 1, numberOfMonths = 2, onDatesChange, startDate, unavailableDates = [], }) {
|
|
19
|
+
function useDateRangePicker({ changeActiveMonthOnSelect = false, datesConfig = [], endDate, exactMinBookingDays = false, firstDayOfWeek = 0, focusedInput, initialVisibleMonth, isDateBlocked: isDateBlockedProps = () => false, maxBookingDate, minBookingDate, minBookingDays = 1, numberOfMonths = 2, onDatesChange, startDate, unavailableDates = [], }) {
|
|
20
|
+
const disabledDatesFromConfig = datesConfig.filter((config) => config.isDisabled).flatMap((config) => config.dates);
|
|
21
|
+
const disabledDates = [...unavailableDates, ...disabledDatesFromConfig];
|
|
20
22
|
const [activeMonths, setActiveMonths] = (0, react_1.useState)(() => startDate
|
|
21
23
|
? (0, get_initial_months_1.getInitialMonths)(numberOfMonths, startDate)
|
|
22
24
|
: (0, get_initial_months_1.getInitialMonths)(numberOfMonths, initialVisibleMonth || null));
|
|
23
25
|
const [hoveredDate, setHoveredDate] = (0, react_1.useState)(null);
|
|
24
26
|
const [focusedDate, setFocusedDate] = (0, react_1.useState)(startDate);
|
|
25
27
|
const disabledDatesByUser = (date) => {
|
|
26
|
-
return (0, is_in_unavailable_dates_1.isInUnavailableDates)(
|
|
28
|
+
return (0, is_in_unavailable_dates_1.isInUnavailableDates)(disabledDates, date) || isDateBlockedProps(date);
|
|
27
29
|
};
|
|
28
30
|
const onDateFocus = (0, react_1.useCallback)((date) => {
|
|
29
31
|
setFocusedDate(date);
|
|
@@ -205,6 +207,7 @@ function useDateRangePicker({ changeActiveMonthOnSelect = false, endDate, exactM
|
|
|
205
207
|
setFocusedDate,
|
|
206
208
|
}),
|
|
207
209
|
activeMonths,
|
|
210
|
+
datesConfig,
|
|
208
211
|
firstDayOfWeek,
|
|
209
212
|
focusedDate,
|
|
210
213
|
hoveredDate,
|
|
@@ -220,7 +223,7 @@ function useDateRangePicker({ changeActiveMonthOnSelect = false, endDate, exactM
|
|
|
220
223
|
onDateHover,
|
|
221
224
|
onDateSelect,
|
|
222
225
|
onResetDates,
|
|
223
|
-
unavailableDates,
|
|
226
|
+
unavailableDates: disabledDates,
|
|
224
227
|
};
|
|
225
228
|
}
|
|
226
229
|
exports.useDateRangePicker = useDateRangePicker;
|
package/hooks/use-day.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { KeyboardEvent, RefObject } from "react";
|
|
2
|
+
import { DatesConfig, Flag } from "../utils/types";
|
|
2
3
|
export interface UseDayProps {
|
|
3
4
|
date: Date;
|
|
5
|
+
datesConfig?: DatesConfig[];
|
|
4
6
|
dayRef?: RefObject<HTMLElement>;
|
|
5
7
|
focusedDate: Date | null;
|
|
6
8
|
isDateBlocked: (date: Date) => boolean;
|
|
@@ -12,15 +14,17 @@ export interface UseDayProps {
|
|
|
12
14
|
onDateHover: (date: Date) => void;
|
|
13
15
|
onDateSelect: (date: Date) => void;
|
|
14
16
|
preventScroll?: boolean;
|
|
17
|
+
/** @deprecated */
|
|
15
18
|
unavailableDates: Date[];
|
|
16
19
|
}
|
|
17
20
|
export interface UseDayReturnType {
|
|
18
|
-
|
|
19
|
-
isLastDisabled: boolean;
|
|
21
|
+
flags: Flag[];
|
|
20
22
|
disabledDate: boolean;
|
|
23
|
+
isFirstDisabled: boolean;
|
|
21
24
|
isHovered: boolean;
|
|
22
|
-
isSelected: boolean;
|
|
23
25
|
isInsideRange: boolean;
|
|
26
|
+
isLastDisabled: boolean;
|
|
27
|
+
isSelected: boolean;
|
|
24
28
|
isToday: boolean;
|
|
25
29
|
isWithinHoverRange: boolean;
|
|
26
30
|
onClick?: () => void;
|
|
@@ -28,4 +32,4 @@ export interface UseDayReturnType {
|
|
|
28
32
|
onMouseEnter: () => void;
|
|
29
33
|
tabIndex: number;
|
|
30
34
|
}
|
|
31
|
-
export declare function useDay({ date, dayRef, focusedDate, isDateBlocked, isDateFocused, isDateHovered, isDateInsideRange, isDateSelected, onDateFocus, onDateHover, onDateSelect, preventScroll, unavailableDates, }: UseDayProps): UseDayReturnType;
|
|
35
|
+
export declare function useDay({ date, datesConfig, dayRef, focusedDate, isDateBlocked, isDateFocused, isDateHovered, isDateInsideRange, isDateSelected, onDateFocus, onDateHover, onDateSelect, preventScroll, unavailableDates, }: UseDayProps): UseDayReturnType;
|
package/hooks/use-day.js
CHANGED
|
@@ -8,7 +8,11 @@ const dayjs_1 = __importDefault(require("dayjs"));
|
|
|
8
8
|
const react_1 = require("react");
|
|
9
9
|
const dayjs_en_1 = require("../utils/dayjs-en");
|
|
10
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, }) {
|
|
11
|
+
function useDay({ date, datesConfig, dayRef, focusedDate, isDateBlocked, isDateFocused, isDateHovered, isDateInsideRange, isDateSelected, onDateFocus, onDateHover, onDateSelect, preventScroll, unavailableDates, }) {
|
|
12
|
+
var _a;
|
|
13
|
+
const disabledDatesFromConfig = (_a = datesConfig === null || datesConfig === void 0 ? void 0 : datesConfig.filter((config) => config.isDisabled).flatMap((config) => config.dates)) !== null && _a !== void 0 ? _a : [];
|
|
14
|
+
// merge and filter duplicates
|
|
15
|
+
const disabledDates = [...unavailableDates, ...disabledDatesFromConfig].filter((day, index, self) => index === self.findIndex((d) => d.getTime() === day.getTime()));
|
|
12
16
|
const onClick = (0, react_1.useCallback)(() => onDateSelect(date), [date, onDateSelect]);
|
|
13
17
|
const onMouseEnter = (0, react_1.useCallback)(() => onDateHover(date), [date, onDateHover]);
|
|
14
18
|
const disabled = isDateBlocked(date) && !isDateHovered(date);
|
|
@@ -39,27 +43,40 @@ function useDay({ date, dayRef, focusedDate, isDateBlocked, isDateFocused, isDat
|
|
|
39
43
|
}
|
|
40
44
|
}
|
|
41
45
|
}, [date, onDateFocus]);
|
|
42
|
-
const
|
|
43
|
-
const dateIntervals = (0, get_date_invervals_1.getDateIntervals)(sortedUnavailableDates);
|
|
46
|
+
const dateIntervals = (0, get_date_invervals_1.getDateIntervals)(disabledDates);
|
|
44
47
|
const _isFirstUnavailableDate = () => {
|
|
45
48
|
return dateIntervals.some((interval) => (0, dayjs_1.default)(interval.start).isSame(date, "day"));
|
|
46
49
|
};
|
|
47
50
|
const _isLastUnavailableDate = () => {
|
|
48
51
|
return dateIntervals.some((interval) => (0, dayjs_1.default)(interval.end).isSame(date, "day"));
|
|
49
52
|
};
|
|
53
|
+
const applicableDatesConfigs = datesConfig === null || datesConfig === void 0 ? void 0 : datesConfig.filter((config) => config.dates.some((configDay) => (0, dayjs_1.default)(configDay).isSame(date, "day")));
|
|
54
|
+
const flags = applicableDatesConfigs === null || applicableDatesConfigs === void 0 ? void 0 : applicableDatesConfigs.reduce((acc, curr) => {
|
|
55
|
+
if (!curr.flag) {
|
|
56
|
+
return acc;
|
|
57
|
+
}
|
|
58
|
+
const intervals = (0, get_date_invervals_1.getDateIntervals)(curr.dates);
|
|
59
|
+
acc.push({
|
|
60
|
+
flag: curr.flag,
|
|
61
|
+
isFirst: intervals.some((interval) => (0, dayjs_1.default)(interval.start).isSame(date, "day")),
|
|
62
|
+
isLast: intervals.some((interval) => (0, dayjs_1.default)(interval.end).isSame(date, "day")),
|
|
63
|
+
});
|
|
64
|
+
return acc;
|
|
65
|
+
}, []);
|
|
50
66
|
return {
|
|
67
|
+
flags: flags !== null && flags !== void 0 ? flags : [],
|
|
51
68
|
disabledDate: disabled,
|
|
52
69
|
isFirstDisabled: _isFirstUnavailableDate(),
|
|
53
|
-
isLastDisabled: _isLastUnavailableDate(),
|
|
54
70
|
isHovered: isDateHovered(date),
|
|
55
|
-
isSelected: isDateSelected(date),
|
|
56
71
|
isInsideRange: isDateInsideRange ? isDateInsideRange(date) : false,
|
|
72
|
+
isLastDisabled: _isLastUnavailableDate(),
|
|
73
|
+
isSelected: isDateSelected(date),
|
|
74
|
+
isToday,
|
|
57
75
|
isWithinHoverRange: isDateHovered(date),
|
|
58
76
|
onClick: !disabled ? onClick : undefined,
|
|
59
77
|
onKeyDown,
|
|
60
78
|
onMouseEnter,
|
|
61
79
|
tabIndex: focusedDate === null || isDateFocused(date) ? 0 : -1,
|
|
62
|
-
isToday,
|
|
63
80
|
};
|
|
64
81
|
}
|
|
65
82
|
exports.useDay = useDay;
|
package/hooks/use-day.test.js
CHANGED
|
@@ -15,13 +15,14 @@ beforeAll(() => {
|
|
|
15
15
|
test("useDay", () => {
|
|
16
16
|
const { result } = (0, react_hooks_1.renderHook)(() => (0, use_day_1.useDay)({
|
|
17
17
|
date: new Date("2021-09-05"),
|
|
18
|
-
|
|
18
|
+
datesConfig: [],
|
|
19
19
|
focusedDate: null,
|
|
20
|
-
|
|
20
|
+
isDateBlocked: () => false,
|
|
21
21
|
isDateFocused: () => false,
|
|
22
22
|
isDateHovered: () => false,
|
|
23
|
-
isDateSelected: () => false,
|
|
24
23
|
isDateInsideRange: () => false,
|
|
24
|
+
isDateSelected: () => false,
|
|
25
|
+
onDateFocus: () => undefined,
|
|
25
26
|
onDateHover: () => undefined,
|
|
26
27
|
onDateSelect: () => undefined,
|
|
27
28
|
unavailableDates: [],
|
|
@@ -39,13 +40,14 @@ test("useDay", () => {
|
|
|
39
40
|
test("useDay with unavailableDates", () => {
|
|
40
41
|
const { result } = (0, react_hooks_1.renderHook)(() => (0, use_day_1.useDay)({
|
|
41
42
|
date: new Date("2021-09-05"),
|
|
42
|
-
|
|
43
|
+
datesConfig: [],
|
|
43
44
|
focusedDate: null,
|
|
44
|
-
|
|
45
|
+
isDateBlocked: () => true,
|
|
45
46
|
isDateFocused: () => false,
|
|
46
47
|
isDateHovered: () => false,
|
|
47
|
-
isDateSelected: () => false,
|
|
48
48
|
isDateInsideRange: () => false,
|
|
49
|
+
isDateSelected: () => false,
|
|
50
|
+
onDateFocus: () => undefined,
|
|
49
51
|
onDateHover: () => undefined,
|
|
50
52
|
onDateSelect: () => undefined,
|
|
51
53
|
unavailableDates: [new Date("2021-09-05")],
|
|
@@ -60,6 +62,32 @@ test("useDay with unavailableDates", () => {
|
|
|
60
62
|
expect(result.current.isInsideRange).toBe(false);
|
|
61
63
|
expect(result.current.isWithinHoverRange).toBe(false);
|
|
62
64
|
});
|
|
65
|
+
test("useDay with datesConfig", () => {
|
|
66
|
+
const { result } = (0, react_hooks_1.renderHook)(() => (0, use_day_1.useDay)({
|
|
67
|
+
date: new Date("2021-09-05"),
|
|
68
|
+
datesConfig: [{ dates: [new Date("2021-09-05")], flag: "custom-classname", isDisabled: true }],
|
|
69
|
+
focusedDate: null,
|
|
70
|
+
isDateBlocked: () => true,
|
|
71
|
+
isDateFocused: () => false,
|
|
72
|
+
isDateHovered: () => false,
|
|
73
|
+
isDateInsideRange: () => false,
|
|
74
|
+
isDateSelected: () => false,
|
|
75
|
+
onDateFocus: () => undefined,
|
|
76
|
+
onDateHover: () => undefined,
|
|
77
|
+
onDateSelect: () => undefined,
|
|
78
|
+
unavailableDates: [],
|
|
79
|
+
}));
|
|
80
|
+
expect(result.current.tabIndex).toBe(0);
|
|
81
|
+
expect(result.current.disabledDate).toBe(true);
|
|
82
|
+
expect(result.current.isFirstDisabled).toBe(true);
|
|
83
|
+
expect(result.current.isLastDisabled).toBe(true);
|
|
84
|
+
expect(result.current.isHovered).toBe(false);
|
|
85
|
+
expect(result.current.isToday).toBe(false);
|
|
86
|
+
expect(result.current.isSelected).toBe(false);
|
|
87
|
+
expect(result.current.isInsideRange).toBe(false);
|
|
88
|
+
expect(result.current.isWithinHoverRange).toBe(false);
|
|
89
|
+
expect(result.current.flags).toStrictEqual([{ flag: "custom-classname", isFirst: true, isLast: true }]);
|
|
90
|
+
});
|
|
63
91
|
test("actions", () => {
|
|
64
92
|
let hoveredDate = null;
|
|
65
93
|
let selectedDate = null;
|
|
@@ -68,16 +96,17 @@ test("actions", () => {
|
|
|
68
96
|
const { result: ref } = (0, react_hooks_1.renderHook)(() => (0, react_1.useRef)(null));
|
|
69
97
|
const { result, rerender } = (0, react_hooks_1.renderHook)(() => (0, use_day_1.useDay)({
|
|
70
98
|
date: new Date("2021-09-05"),
|
|
71
|
-
|
|
99
|
+
datesConfig: [],
|
|
100
|
+
dayRef: ref.current,
|
|
72
101
|
focusedDate: null,
|
|
73
|
-
|
|
102
|
+
isDateBlocked: () => false,
|
|
74
103
|
isDateFocused: (date) => (0, dayjs_1.default)(date).isSame(focusedDate, "day"),
|
|
75
104
|
isDateHovered: (date) => (0, dayjs_1.default)(date).isSame(hoveredDate, "day"),
|
|
76
|
-
isDateSelected: (date) => (0, dayjs_1.default)(date).isSame(selectedDate, "day"),
|
|
77
105
|
isDateInsideRange: (date) => (0, dayjs_1.default)(date).isSame(insideRangeDate, "day"),
|
|
106
|
+
isDateSelected: (date) => (0, dayjs_1.default)(date).isSame(selectedDate, "day"),
|
|
107
|
+
onDateFocus: (date) => (focusedDate = date),
|
|
78
108
|
onDateHover: (date) => (hoveredDate = date),
|
|
79
109
|
onDateSelect: (date) => (selectedDate = date),
|
|
80
|
-
dayRef: ref.current,
|
|
81
110
|
unavailableDates: [new Date("2021-09-05")],
|
|
82
111
|
}));
|
|
83
112
|
// hover
|
package/package.json
CHANGED
|
@@ -6,11 +6,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.getDateIntervals = void 0;
|
|
7
7
|
const dayjs_1 = __importDefault(require("dayjs"));
|
|
8
8
|
function getDateIntervals(dates) {
|
|
9
|
+
const sortedDates = dates.slice().sort((a, b) => a.getTime() - b.getTime());
|
|
9
10
|
const intervals = [];
|
|
10
|
-
let currentStart =
|
|
11
|
-
let currentEnd =
|
|
12
|
-
for (let i = 1; i <
|
|
13
|
-
const currentDate =
|
|
11
|
+
let currentStart = sortedDates[0];
|
|
12
|
+
let currentEnd = sortedDates[0];
|
|
13
|
+
for (let i = 1; i < sortedDates.length; i++) {
|
|
14
|
+
const currentDate = sortedDates[i];
|
|
14
15
|
const nextDate = (0, dayjs_1.default)(currentEnd).add(1, "day").toDate();
|
|
15
16
|
// If the current date matches the expected next date, it's contiguous
|
|
16
17
|
if ((0, dayjs_1.default)(currentDate).isSame(nextDate, "day")) {
|
|
@@ -22,7 +23,7 @@ function getDateIntervals(dates) {
|
|
|
22
23
|
currentEnd = currentDate;
|
|
23
24
|
}
|
|
24
25
|
}
|
|
25
|
-
if (
|
|
26
|
+
if (sortedDates[0]) {
|
|
26
27
|
// Push the last interval
|
|
27
28
|
intervals.push({ start: currentStart, end: currentEnd });
|
|
28
29
|
}
|
package/utils/types.d.ts
CHANGED