UNPKG

1.76 kBTypeScriptView Raw
1import React from "react";
2
3import type {
4 DateLib,
5 DayPickerProps,
6 Modifiers,
7 PropsMulti,
8 Selection
9} from "../types/index.js";
10
11export function useMulti<T extends DayPickerProps>(
12 props: T,
13 dateLib: DateLib
14): Selection<T> {
15 const {
16 selected: initiallySelected,
17 required,
18 onSelect,
19 mode
20 } = props as PropsMulti;
21 const [selected, setSelected] = React.useState<Date[] | undefined>(
22 initiallySelected
23 );
24
25 const { isSameDay } = dateLib;
26
27 // Update the selected date if the selected value from props changes.
28 React.useEffect(() => {
29 setSelected(initiallySelected);
30 }, [mode, initiallySelected]);
31
32 const isSelected = (date: Date) => {
33 return selected?.some((d) => isSameDay(d, date)) ?? false;
34 };
35
36 const { min, max } = props as PropsMulti;
37
38 const select = (
39 triggerDate: Date,
40 modifiers: Modifiers,
41 e: React.MouseEvent | React.KeyboardEvent
42 ) => {
43 let newDates: Date[] | undefined = [...(selected ?? [])];
44 if (isSelected(triggerDate)) {
45 if (selected?.length === min) {
46 // Min value reached, do nothing
47 return;
48 }
49 if (required && selected?.length === 1) {
50 // Required value already selected do nothing
51 return;
52 }
53 newDates = selected?.filter((d) => !isSameDay(d, triggerDate));
54 } else {
55 if (selected?.length === max) {
56 // Max value reached, reset the selection to date
57 newDates = [triggerDate];
58 } else {
59 // Add the date to the selection
60 newDates = [...newDates, triggerDate];
61 }
62 }
63 onSelect?.(newDates, triggerDate, modifiers, e);
64 setSelected(newDates);
65 return newDates;
66 };
67
68 return {
69 selected,
70 select,
71 isSelected
72 } as Selection<T>;
73}