1 | /* eslint-disable @typescript-eslint/ban-types */
|
2 | import type { CSSProperties } from "react";
|
3 |
|
4 | import { UI, DayFlag, SelectionState } from "../UI.js";
|
5 | import * as components from "../components/custom-components.js";
|
6 | import {
|
7 | formatCaption,
|
8 | formatDay,
|
9 | formatMonthCaption,
|
10 | formatMonthDropdown,
|
11 | formatWeekdayName,
|
12 | formatWeekNumber,
|
13 | formatYearCaption,
|
14 | formatYearDropdown
|
15 | } from "../formatters/index.js";
|
16 | import {
|
17 | labelDayButton,
|
18 | labelNav,
|
19 | labelGrid,
|
20 | labelGridcell,
|
21 | labelMonthDropdown,
|
22 | labelNext,
|
23 | labelPrevious,
|
24 | labelWeekday,
|
25 | labelWeekNumber,
|
26 | labelWeekNumberHeader,
|
27 | labelYearDropdown
|
28 | } from "../labels/index.js";
|
29 | import { dateLib } from "../lib/index.js";
|
30 |
|
31 | /**
|
32 | * Selection modes supported by DayPicker.
|
33 | *
|
34 | * - `single`: use DayPicker to select single days.
|
35 | * - `multiple`: allow selecting multiple days.
|
36 | * - `range`: use DayPicker to select a range of days.
|
37 | *
|
38 | * @see https://daypicker.dev/docs/selection-modes
|
39 | */
|
40 | export type Mode = "single" | "multiple" | "range";
|
41 |
|
42 | /**
|
43 | * The components that can be changed using the `components` prop.
|
44 | *
|
45 | * @see https://daypicker.dev/guides/custom-components
|
46 | */
|
47 | export type CustomComponents = {
|
48 | /** Render any button element in DayPicker. */
|
49 | Button: typeof components.Button;
|
50 | /** Render the chevron icon used in the navigation buttons and dropdowns. */
|
51 | Chevron: typeof components.Chevron;
|
52 | /** Render the caption label of the month grid. */
|
53 | CaptionLabel: typeof components.CaptionLabel;
|
54 | /** Render the day cell in the month grid. */
|
55 | Day: typeof components.Day;
|
56 | /** Render the button containing the day in the day cell. */
|
57 | DayButton: typeof components.DayButton;
|
58 | /** Render the dropdown element to select years and months. */
|
59 | Dropdown: typeof components.Dropdown;
|
60 | /** Render the container of the dropdowns. */
|
61 | DropdownNav: typeof components.DropdownNav;
|
62 | /** Render the footer element announced by screen readers. */
|
63 | Footer: typeof components.Footer;
|
64 | /** Render the container of the MonthGrid. */
|
65 | Month: typeof components.Month;
|
66 | /** Render the caption of the month grid. */
|
67 | MonthCaption: typeof components.MonthCaption;
|
68 | /** Render the grid of days in a month. */
|
69 | MonthGrid: typeof components.MonthGrid;
|
70 | /** Wrapper of the month grids. */
|
71 | Months: typeof components.Months;
|
72 | /** Render the navigation element with the next and previous buttons. */
|
73 | Nav: typeof components.Nav;
|
74 | /** Render the `<option>` HTML element in the dropdown. */
|
75 | Option: typeof components.Option;
|
76 | /** Render the root element of the calendar. */
|
77 | Root: typeof components.Root;
|
78 | /** Render the select element in the dropdowns. */
|
79 | Select: typeof components.Select;
|
80 | /** Render the weeks section in the month grid. */
|
81 | Weeks: typeof components.Weeks;
|
82 | /** Render the week rows. */
|
83 | Week: typeof components.Week;
|
84 | /** Render the weekday name in the header. */
|
85 | Weekday: typeof components.Weekday;
|
86 | /** Render the row containing the week days. */
|
87 | Weekdays: typeof components.Weekdays;
|
88 | /** Render the cell with the number of the week. */
|
89 | WeekNumber: typeof components.WeekNumber;
|
90 | /** Render the header of the week number column. */
|
91 | WeekNumberHeader: typeof components.WeekNumberHeader;
|
92 | };
|
93 |
|
94 | /** @private */
|
95 | export type DateLib = typeof dateLib;
|
96 |
|
97 | /** Represent a map of formatters used to render localized content. */
|
98 | export type Formatters = {
|
99 | /** Format the caption of a month grid. */
|
100 | formatCaption: typeof formatCaption;
|
101 | /** @deprecated Use {@link Formatters.formatCaption} instead. */
|
102 | formatMonthCaption: typeof formatMonthCaption;
|
103 | /** Format the label in the month dropdown. */
|
104 | formatMonthDropdown: typeof formatMonthDropdown;
|
105 | /** @deprecated Use {@link Formatters.formatYearDropdown} instead. */
|
106 | formatYearCaption: typeof formatYearCaption;
|
107 | /** Format the label in the year dropdown. */
|
108 | formatYearDropdown: typeof formatYearDropdown;
|
109 | /** Format the day in the day cell. */
|
110 | formatDay: typeof formatDay;
|
111 | /** Format the week number. */
|
112 | formatWeekNumber: typeof formatWeekNumber;
|
113 | /** Format the week day name in the header. */
|
114 | formatWeekdayName: typeof formatWeekdayName;
|
115 | };
|
116 |
|
117 | /** Map of functions to translate ARIA labels for the relative elements. */
|
118 | export type Labels = {
|
119 | /** The label for the navigation toolbar. */
|
120 | labelNav: typeof labelNav;
|
121 | /** The label for the month grid. */
|
122 | labelGrid: typeof labelGrid;
|
123 | /** The label for the gridcell, when the calendar is not interactive. */
|
124 | labelGridcell: typeof labelGridcell;
|
125 | /** The label for the month dropdown. */
|
126 | labelMonthDropdown: typeof labelMonthDropdown;
|
127 | /** The label for the year dropdown. */
|
128 | labelYearDropdown: typeof labelYearDropdown;
|
129 | /** The label for the "next month" button. */
|
130 | labelNext: typeof labelNext;
|
131 | /** The label for the "previous month" button. */
|
132 | labelPrevious: typeof labelPrevious;
|
133 | /** The label for the day button.. */
|
134 | labelDayButton: typeof labelDayButton;
|
135 | /** @deprecated Use {@link labelDayButton} instead. */
|
136 | labelDay: typeof labelDayButton;
|
137 | /** The label for the weekday. */
|
138 | labelWeekday: typeof labelWeekday;
|
139 | /** The label for the week number. */
|
140 | labelWeekNumber: typeof labelWeekNumber;
|
141 | /**
|
142 | * Return the label for the column of the week number.
|
143 | *
|
144 | * @since 9.0.0
|
145 | */
|
146 | labelWeekNumberHeader: typeof labelWeekNumberHeader;
|
147 | };
|
148 |
|
149 | /**
|
150 | * A value or a function that matches a specific day.
|
151 | *
|
152 | * @example
|
153 | * // will always match the day
|
154 | * const booleanMatcher: Matcher = true;
|
155 | *
|
156 | * // will match the today's date
|
157 | * const dateMatcher: Matcher = new Date();
|
158 | *
|
159 | * // will match the days in the array
|
160 | * const arrayMatcher: Matcher = [
|
161 | * new Date(2019, 1, 2),
|
162 | * new Date(2019, 1, 4)
|
163 | * ];
|
164 | *
|
165 | * // will match days after the 2nd of February 2019
|
166 | * const afterMatcher: DateAfter = { after: new Date(2019, 1, 2) };
|
167 | *
|
168 | * // will match days before the 2nd of February 2019 }
|
169 | * const beforeMatcher: DateBefore = { before: new Date(2019, 1, 2) };
|
170 | *
|
171 | * // will match Sundays
|
172 | * const dayOfWeekMatcher: DayOfWeek = {
|
173 | * dayOfWeek: 0
|
174 | * };
|
175 | *
|
176 | * // will match the included days, except the two dates
|
177 | * const intervalMatcher: DateInterval = {
|
178 | * after: new Date(2019, 1, 2),
|
179 | * before: new Date(2019, 1, 5)
|
180 | * };
|
181 | *
|
182 | * // will match the included days, including the two dates
|
183 | * const rangeMatcher: DateRange = {
|
184 | * from: new Date(2019, 1, 2),
|
185 | * to: new Date(2019, 1, 5)
|
186 | * };
|
187 | *
|
188 | * // will match when the function return true
|
189 | * const functionMatcher: Matcher = (day: Date) => {
|
190 | * return day.getMonth() === 2; // match when month is March
|
191 | * };
|
192 | */
|
193 | export type Matcher =
|
194 | | boolean
|
195 | | ((date: Date) => boolean)
|
196 | | Date
|
197 | | Date[]
|
198 | | DateRange
|
199 | | DateBefore
|
200 | | DateAfter
|
201 | | DateInterval
|
202 | | DayOfWeek;
|
203 |
|
204 | /**
|
205 | * Match a day falling after the specified date, with the date not included.
|
206 | *
|
207 | * @example
|
208 | * // Match days after the 2nd of February 2019
|
209 | * const matcher: DateAfter = { after: new Date(2019, 1, 2) };
|
210 | */
|
211 | export type DateAfter = { after: Date };
|
212 |
|
213 | /**
|
214 | * Match a day falling before the specified date, with the date not included.
|
215 | *
|
216 | * @example
|
217 | * // Match days before the 2nd of February 2019
|
218 | * const matcher: DateBefore = { before: new Date(2019, 1, 2) };
|
219 | */
|
220 | export type DateBefore = { before: Date };
|
221 |
|
222 | /**
|
223 | * An interval of dates. Differently from {@link DateRange}, the range ends here
|
224 | * are not included.
|
225 | *
|
226 | * @example
|
227 | * // Match the days between the 2nd and the 5th of February 2019
|
228 | * const matcher: DateInterval = {
|
229 | * after: new Date(2019, 1, 2),
|
230 | * before: new Date(2019, 1, 5)
|
231 | * };
|
232 | */
|
233 | export type DateInterval = { before: Date; after: Date };
|
234 |
|
235 | /**
|
236 | * A range of dates. The range can be open. Differently from
|
237 | * {@link DateInterval}, the range ends here are included.
|
238 | *
|
239 | * @example
|
240 | * // Match the days between the 2nd and the 5th of February 2019
|
241 | * const matcher: DateRange = {
|
242 | * from: new Date(2019, 1, 2),
|
243 | * to: new Date(2019, 1, 5)
|
244 | * };
|
245 | */
|
246 | export type DateRange = { from: Date | undefined; to?: Date | undefined };
|
247 |
|
248 | /**
|
249 | * Match dates being one of the specified days of the week (`0-6`, where `0` is
|
250 | * Sunday).
|
251 | *
|
252 | * @example
|
253 | * // Match Sundays
|
254 | * const matcher: DayOfWeek = { dayOfWeek: 0 };
|
255 | * // Match weekends
|
256 | * const matcher: DayOfWeek = { dayOfWeek: [0, 6] };
|
257 | */
|
258 | export type DayOfWeek = { dayOfWeek: number | number[] };
|
259 |
|
260 | /**
|
261 | * The event handler triggered when clicking or interacting with a day.
|
262 | *
|
263 | * @template EventType - The event type that triggered the event (e.g.
|
264 | * `React.MouseEvent`, `React.KeyboardEvent`, etc.).
|
265 | * @param date - The date that has triggered the event.
|
266 | * @param modifiers - The modifiers belonging to the date.
|
267 | * @param e - The DOM event that triggered the event.
|
268 | */
|
269 | export type DayEventHandler<EventType> = (
|
270 | date: Date,
|
271 | modifiers: Modifiers,
|
272 | e: EventType
|
273 | ) => void;
|
274 |
|
275 | /**
|
276 | * The event handler when a month is changed in the calendar.
|
277 | *
|
278 | * ```tsx
|
279 | * <DayPicker onMonthChange={(month) => console.log(month)} />
|
280 | * ```
|
281 | *
|
282 | * @see https://daypicker.dev/docs/navigation
|
283 | */
|
284 | export type MonthChangeEventHandler = (month: Date) => void;
|
285 |
|
286 | /**
|
287 | * The CSS classnames to use for the {@link UI} elements, the
|
288 | * {@link SelectionState} and the {@link DayFlag}.
|
289 | *
|
290 | * @example
|
291 | * const classNames: ClassNames = {
|
292 | * [UI.Root]: "root",
|
293 | * [UI.Outside]: "outside",
|
294 | * [UI.Nav]: "nav"
|
295 | * // etc.
|
296 | * };
|
297 | */
|
298 | export type ClassNames = {
|
299 | [key in UI | SelectionState | DayFlag]: string;
|
300 | };
|
301 |
|
302 | /**
|
303 | * The CSS styles to use for the {@link UI} elements, the {@link SelectionState}
|
304 | * and the {@link DayFlag}.
|
305 | */
|
306 | export type Styles = {
|
307 | [key in UI | SelectionState | DayFlag]: CSSProperties | undefined;
|
308 | };
|
309 |
|
310 | /**
|
311 | * The modifiers that are matching a day in the calendar.
|
312 | *
|
313 | * @example
|
314 | * const modifiers: Modifiers = {
|
315 | * today: false, // the day is not today
|
316 | * selected: true, // the day is selected
|
317 | * weekend: false // the day is not in the weekend
|
318 | * // etc
|
319 | * };
|
320 | */
|
321 | export type Modifiers = Record<string, boolean>;
|
322 |
|
323 | /**
|
324 | * The style to apply to each day element matching a modifier.
|
325 | *
|
326 | * @example
|
327 | * const modifiersStyles: ModifiersStyles = {
|
328 | * today: { color: "red" },
|
329 | * selected: { backgroundColor: "blue" },
|
330 | * weekend: { color: "green" }
|
331 | * };
|
332 | */
|
333 | export type ModifiersStyles = Record<string, CSSProperties>;
|
334 |
|
335 | /**
|
336 | * The classnames to assign to each day element matching a modifier.
|
337 | *
|
338 | * @example
|
339 | * const modifiersClassNames: ModifiersClassNames = {
|
340 | * today: "today", // Use the "today" class for the today's day
|
341 | * selected: "highlight", // Use the "highlight" class for the selected day
|
342 | * weekend: "weekend" // Use the "weekend" class for the weekend days
|
343 | * };
|
344 | */
|
345 | export type ModifiersClassNames = Record<string, string>;
|
346 |
|
347 | /**
|
348 | * The props that have been deprecated since version 9.0.0.
|
349 | *
|
350 | * @private
|
351 | * @since 9.0.0
|
352 | * @see https://daypicker.dev/upgrading
|
353 | */
|
354 | export type V9DeprecatedProps =
|
355 | /** Use `hidden` prop instead. */
|
356 | | "fromDate"
|
357 | /** Use `hidden` prop instead. */
|
358 | | "toDate"
|
359 | /** Use `startMonth` instead. */
|
360 | | "fromMonth"
|
361 | /** Use `endMonth` instead. */
|
362 | | "toMonth"
|
363 | /** Use `startMonth` instead. */
|
364 | | "fromYear"
|
365 | /** Use `endMonth` instead. */
|
366 | | "toYear";
|
367 |
|
368 | /** The direction to move the focus relative to the current focused date. */
|
369 | export type MoveFocusDir = "after" | "before";
|
370 |
|
371 | /** The temporal unit to move the focus by. */
|
372 | export type MoveFocusBy =
|
373 | | "day"
|
374 | | "week"
|
375 | | "startOfWeek"
|
376 | | "endOfWeek"
|
377 | | "month"
|
378 | | "year";
|