File size: 2,799 Bytes
cf86710
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import type { DayPickerProps } from "./props.js";
import type { DateRange, Mode, Modifiers } from "./shared.js";

export type Selection<T extends DayPickerProps> = {
  /** The selected date(s). */
  selected: SelectedValue<T> | undefined;
  /** Set a selection. */
  select: SelectHandler<T> | undefined;
  /** Whether the given date is selected. */
  isSelected: (date: Date) => boolean;
};

export type SelectedSingle<T extends { required?: boolean }> =
  T["required"] extends true ? Date : Date | undefined;
export type SelectedMulti<T extends { required?: boolean }> =
  T["required"] extends true ? Date[] : Date[] | undefined;
export type SelectedRange<T extends { required?: boolean }> =
  T["required"] extends true ? DateRange : DateRange | undefined;

/**
 * Represents the selected value based on the selection mode.
 *
 * @example
 *   // Single selection mode
 *   const selected: SelectedValue<{ mode: "single" }> = new Date();
 *
 *   // Multiple selection mode
 *   const selected: SelectedValue<{ mode: "multiple" }> = [
 *     new Date(),
 *     new Date(),
 *   ];
 *
 *   // Range selection mode
 *   const selected: SelectedValue<{ mode: "range" }> = {
 *     from: new Date(),
 *     to: new Date(),
 *   };
 */
export type SelectedValue<T> = T extends { mode: "single"; required?: boolean }
  ? SelectedSingle<T>
  : T extends { mode: "multiple"; required?: boolean }
    ? SelectedMulti<T>
    : T extends { mode: "range"; required?: boolean }
      ? SelectedRange<T>
      : undefined;

export type SelectHandlerSingle<T extends { required?: boolean | undefined }> =
  (
    triggerDate: Date,
    modifiers: Modifiers,
    e: React.MouseEvent | React.KeyboardEvent,
  ) => T["required"] extends true ? Date : Date | undefined;

export type SelectHandlerMulti<T extends { required?: boolean | undefined }> = (
  triggerDate: Date,
  modifiers: Modifiers,
  e: React.MouseEvent | React.KeyboardEvent,
) => T["required"] extends true ? Date[] : Date[] | undefined;

export type SelectHandlerRange<T extends { required?: boolean | undefined }> = (
  triggerDate: Date,
  modifiers: Modifiers,
  e: React.MouseEvent | React.KeyboardEvent,
) => T["required"] extends true ? DateRange : DateRange | undefined;

/**
 * The handler to set a selection based on the mode.
 *
 * @example
 *   const handleSelect: SelectHandler<{ mode: "single" }> = (
 *     triggerDate,
 *     modifiers,
 *     e,
 *   ) => {
 *     console.log("Selected date:", triggerDate);
 *   };
 */
export type SelectHandler<
  T extends { mode?: Mode | undefined; required?: boolean | undefined },
> = T extends {
  mode: "single";
}
  ? SelectHandlerSingle<T>
  : T extends { mode: "multiple" }
    ? SelectHandlerMulti<T>
    : T extends { mode: "range" }
      ? SelectHandlerRange<T>
      : undefined;