@uxf/datepicker 10.8.0 → 11.0.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 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
- ```typescript
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
- ```typescript
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
- ```typescript
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 | type | required | default | description |
284
- |----------------|---------------------------|----------|---------|-------------|
285
- | date | `Date` | yes | | |
286
- | dayRef | `RefObject` | | | |
287
- | focusedDate | `Date \| null` | yes | | |
288
- | isDateBlocked | `(date: Date) => boolean` | yes | | |
289
- | isDateFocused | `(date: Date) => boolean` | yes | | |
290
- | isDateHovered | `(date: Date) => boolean` | yes | | |
291
- | isDateSelected | `(date: Date) => boolean` | yes | | |
292
- | onDateFocus | `(date: Date) => void` | yes | | |
293
- | onDateHover | `(date: Date) => void` | yes | | |
294
- | onDateSelect | `(date: Date) => void` | yes | | |
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
 
@@ -4,6 +4,7 @@ exports.DatePickerContext = void 0;
4
4
  const react_1 = require("react");
5
5
  exports.DatePickerContext = (0, react_1.createContext)({
6
6
  activeMonths: [],
7
+ datesConfig: [],
7
8
  canGoToMonth: () => true,
8
9
  canGoToNextMonth: true,
9
10
  canGoToNextYear: true,
@@ -4,6 +4,7 @@ exports.DateRangePickerContext = void 0;
4
4
  const react_1 = require("react");
5
5
  exports.DateRangePickerContext = (0, react_1.createContext)({
6
6
  activeMonths: [],
7
+ datesConfig: [],
7
8
  canGoToMonth: () => true,
8
9
  canGoToNextMonth: true,
9
10
  canGoToNextYear: true,
@@ -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;
@@ -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)(unavailableDates, date) || isDateBlockedProps(date);
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)(unavailableDates, date) || isDateBlockedProps(date);
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;
@@ -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
- isFirstDisabled: boolean;
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,10 @@ 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
+ const disabledDates = [...unavailableDates, ...disabledDatesFromConfig];
12
15
  const onClick = (0, react_1.useCallback)(() => onDateSelect(date), [date, onDateSelect]);
13
16
  const onMouseEnter = (0, react_1.useCallback)(() => onDateHover(date), [date, onDateHover]);
14
17
  const disabled = isDateBlocked(date) && !isDateHovered(date);
@@ -39,27 +42,40 @@ function useDay({ date, dayRef, focusedDate, isDateBlocked, isDateFocused, isDat
39
42
  }
40
43
  }
41
44
  }, [date, onDateFocus]);
42
- const sortedUnavailableDates = unavailableDates.slice().sort((a, b) => a.getTime() - b.getTime());
43
- const dateIntervals = (0, get_date_invervals_1.getDateIntervals)(sortedUnavailableDates);
45
+ const dateIntervals = (0, get_date_invervals_1.getDateIntervals)(disabledDates);
44
46
  const _isFirstUnavailableDate = () => {
45
47
  return dateIntervals.some((interval) => (0, dayjs_1.default)(interval.start).isSame(date, "day"));
46
48
  };
47
49
  const _isLastUnavailableDate = () => {
48
50
  return dateIntervals.some((interval) => (0, dayjs_1.default)(interval.end).isSame(date, "day"));
49
51
  };
52
+ const applicableDatesConfigs = datesConfig === null || datesConfig === void 0 ? void 0 : datesConfig.filter((config) => config.dates.some((configDay) => (0, dayjs_1.default)(configDay).isSame(date, "day")));
53
+ const flags = applicableDatesConfigs === null || applicableDatesConfigs === void 0 ? void 0 : applicableDatesConfigs.reduce((acc, curr) => {
54
+ if (!curr.flag) {
55
+ return acc;
56
+ }
57
+ const intervals = (0, get_date_invervals_1.getDateIntervals)(curr.dates);
58
+ acc.push({
59
+ flag: curr.flag,
60
+ isFirst: intervals.some((interval) => (0, dayjs_1.default)(interval.start).isSame(date, "day")),
61
+ isLast: intervals.some((interval) => (0, dayjs_1.default)(interval.end).isSame(date, "day")),
62
+ });
63
+ return acc;
64
+ }, []);
50
65
  return {
66
+ flags: flags !== null && flags !== void 0 ? flags : [],
51
67
  disabledDate: disabled,
52
68
  isFirstDisabled: _isFirstUnavailableDate(),
53
- isLastDisabled: _isLastUnavailableDate(),
54
69
  isHovered: isDateHovered(date),
55
- isSelected: isDateSelected(date),
56
70
  isInsideRange: isDateInsideRange ? isDateInsideRange(date) : false,
71
+ isLastDisabled: _isLastUnavailableDate(),
72
+ isSelected: isDateSelected(date),
73
+ isToday,
57
74
  isWithinHoverRange: isDateHovered(date),
58
75
  onClick: !disabled ? onClick : undefined,
59
76
  onKeyDown,
60
77
  onMouseEnter,
61
78
  tabIndex: focusedDate === null || isDateFocused(date) ? 0 : -1,
62
- isToday,
63
79
  };
64
80
  }
65
81
  exports.useDay = useDay;
@@ -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
- isDateBlocked: () => false,
18
+ datesConfig: [],
19
19
  focusedDate: null,
20
- onDateFocus: () => undefined,
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
- isDateBlocked: () => true,
43
+ datesConfig: [],
43
44
  focusedDate: null,
44
- onDateFocus: () => undefined,
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
- isDateBlocked: () => false,
99
+ datesConfig: [],
100
+ dayRef: ref.current,
72
101
  focusedDate: null,
73
- onDateFocus: (date) => (focusedDate = date),
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uxf/datepicker",
3
- "version": "10.8.0",
3
+ "version": "11.0.0",
4
4
  "description": "A set of React hooks to create an awesome datepicker.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -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 = dates[0];
11
- let currentEnd = dates[0];
12
- for (let i = 1; i < dates.length; i++) {
13
- const currentDate = dates[i];
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 (dates[0]) {
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
@@ -4,3 +4,13 @@ export interface MonthType {
4
4
  month: number;
5
5
  date: Date;
6
6
  }
7
+ export type DatesConfig = {
8
+ flag?: string;
9
+ dates: Date[];
10
+ isDisabled?: boolean;
11
+ };
12
+ export type Flag = {
13
+ flag: string;
14
+ isFirst: boolean;
15
+ isLast: boolean;
16
+ };