UNPKG

1.86 kBTypeScriptView Raw
1import React from "react";
2
3import type {
4 DateLib,
5 DateRange,
6 DayPickerProps,
7 Modifiers,
8 PropsRange,
9 Selection
10} from "../types/index.js";
11import { addToRange, dateMatchModifiers } from "../utils/index.js";
12import { rangeIncludesDate } from "../utils/rangeIncludesDate.js";
13
14export function useRange<T extends DayPickerProps>(
15 props: T,
16 dateLib: DateLib
17): Selection<T> {
18 const {
19 disabled,
20 excludeDisabled,
21 selected: initiallySelected,
22 required,
23 onSelect
24 } = props as PropsRange;
25
26 const [selected, setSelected] = React.useState<DateRange | undefined>(
27 initiallySelected
28 );
29
30 // Update the selected date if the `selected` prop changes.
31 React.useEffect(() => {
32 setSelected(initiallySelected);
33 }, [initiallySelected]);
34
35 const isSelected = (date: Date) =>
36 selected && rangeIncludesDate(selected, date, false, dateLib);
37
38 const select = (
39 triggerDate: Date,
40 modifiers: Modifiers,
41 e: React.MouseEvent | React.KeyboardEvent
42 ) => {
43 const { min, max } = props as PropsRange;
44 const newRange = triggerDate
45 ? addToRange(triggerDate, selected, min, max, required, dateLib)
46 : undefined;
47
48 if (newRange?.from && newRange.to) {
49 let newDate = newRange.from;
50 while (dateLib.differenceInCalendarDays(newRange.to, newDate) > 0) {
51 newDate = dateLib.addDays(newDate, 1);
52 if (
53 excludeDisabled &&
54 disabled &&
55 dateMatchModifiers(newDate, disabled, dateLib)
56 ) {
57 // if a disabled days is found, the range is reset
58 newRange.from = triggerDate;
59 newRange.to = undefined;
60 break;
61 }
62 }
63 }
64
65 setSelected(newRange);
66 onSelect?.(newRange, triggerDate, modifiers, e);
67
68 return newRange;
69 };
70
71 return {
72 selected,
73 select,
74 isSelected
75 } as Selection<T>;
76}