1 | import React from "react";
|
2 |
|
3 | import type { DeprecatedUI } from "../UI.js";
|
4 | import type { Locale } from "../lib/dateLib.js";
|
5 |
|
6 | import type {
|
7 | ClassNames,
|
8 | ModifiersClassNames,
|
9 | Styles,
|
10 | ModifiersStyles,
|
11 | CustomComponents,
|
12 | Matcher,
|
13 | Labels,
|
14 | Formatters,
|
15 | MonthChangeEventHandler,
|
16 | DayEventHandler,
|
17 | Modifiers,
|
18 | DateRange,
|
19 | Mode,
|
20 | DateLib
|
21 | } from "./shared.js";
|
22 |
|
23 | /**
|
24 | * The props for the `<DayPicker />` component.
|
25 | *
|
26 | * @group DayPicker
|
27 | */
|
28 | export type DayPickerProps = PropsBase &
|
29 | (
|
30 | | PropsSingle
|
31 | | PropsSingleRequired
|
32 | | PropsMulti
|
33 | | PropsMultiRequired
|
34 | | PropsRange
|
35 | | PropsRangeRequired
|
36 | | { mode?: undefined; required?: undefined }
|
37 | );
|
38 |
|
39 | /**
|
40 | * Props for customizing the calendar, handling localization, and managing
|
41 | * events. These exclude the selection mode props.
|
42 | *
|
43 | * @group DayPicker
|
44 | * @see https://daypicker.dev/api/interfaces/PropsBase
|
45 | */
|
46 | export interface PropsBase {
|
47 | /**
|
48 | * Enable the selection of single day, multiple days or a range of days.
|
49 | *
|
50 | * @see https://daypicker.dev/docs/selection-modes
|
51 | */
|
52 | mode?: Mode | undefined;
|
53 | /**
|
54 | * Whether the selection is required.
|
55 | *
|
56 | * @see https://daypicker.dev/docs/selection-modes
|
57 | */
|
58 | required?: boolean | undefined;
|
59 |
|
60 | /** Class name to add to the root element */
|
61 | className?: string;
|
62 | /**
|
63 | * Change the class names used by DayPicker.
|
64 | *
|
65 | * Use this prop when you need to change the default class names — for example
|
66 | * when importing the style via CSS modules or when using a CSS framework.
|
67 | *
|
68 | * @see https://daypicker.dev/docs/styling
|
69 | */
|
70 | classNames?: Partial<ClassNames> & Partial<DeprecatedUI<string>>;
|
71 | /**
|
72 | * Change the class name for the day matching the `modifiers`.
|
73 | *
|
74 | * @see https://daypicker.dev/guides/custom-modifiers
|
75 | */
|
76 | modifiersClassNames?: ModifiersClassNames;
|
77 | /** Style to apply to the root element. */
|
78 | style?: React.CSSProperties;
|
79 | /**
|
80 | * Change the inline styles of the HTML elements.
|
81 | *
|
82 | * @see https://daypicker.dev/docs/styling
|
83 | */
|
84 | styles?: Partial<Styles> & Partial<DeprecatedUI<React.CSSProperties>>;
|
85 | /**
|
86 | * Change the class name for the day matching the {@link modifiers}.
|
87 | *
|
88 | * @see https://daypicker.dev/guides/custom-modifiers
|
89 | */
|
90 | modifiersStyles?: ModifiersStyles;
|
91 | /** A unique id to add to the root element. */
|
92 | id?: string;
|
93 | /**
|
94 | * The initial month to show in the calendar.
|
95 | *
|
96 | * Use this prop to let DayPicker control the current month. If you need to
|
97 | * set the month programmatically, use {@link month} and {@link onMonthChange}.
|
98 | *
|
99 | * @defaultValue The current month
|
100 | * @see https://daypicker.dev/docs/navigation
|
101 | */
|
102 | defaultMonth?: Date;
|
103 | /**
|
104 | * The month displayed in the calendar.
|
105 | *
|
106 | * As opposed to `defaultMonth`, use this prop with `onMonthChange` to change
|
107 | * the month programmatically.
|
108 | *
|
109 | * @see https://daypicker.dev/docs/navigation
|
110 | */
|
111 | month?: Date;
|
112 | /**
|
113 | * The number of displayed months.
|
114 | *
|
115 | * @defaultValue 1
|
116 | * @see https://daypicker.dev/docs/customization#multiplemonths
|
117 | */
|
118 | numberOfMonths?: number;
|
119 | /**
|
120 | * The earliest month to start the month navigation.
|
121 | *
|
122 | * @since 9.0.0
|
123 | * @see https://daypicker.dev/docs/navigation#start-and-end-dates
|
124 | */
|
125 | startMonth?: Date | undefined;
|
126 | /**
|
127 | * @private
|
128 | * @deprecated This prop has been removed. Use `hidden={{ before: date }}`
|
129 | * instead.
|
130 | * @see https://daypicker.dev/docs/navigation#start-and-end-dates
|
131 | */
|
132 | fromDate?: Date | undefined;
|
133 | /**
|
134 | * @private
|
135 | * @deprecated This prop has been renamed to `startMonth`.
|
136 | * @see https://daypicker.dev/docs/navigation#start-and-end-dates
|
137 | */
|
138 | fromMonth?: Date | undefined;
|
139 | /**
|
140 | * @private
|
141 | * @deprecated Use `startMonth` instead. E.g. `startMonth={new Date(year,
|
142 | * 0)}`.
|
143 | * @see https://daypicker.dev/docs/navigation#start-and-end-dates
|
144 | */
|
145 | fromYear?: number | undefined;
|
146 |
|
147 | /**
|
148 | * The latest month to end the month navigation.
|
149 | *
|
150 | * @since 9.0.0
|
151 | * @see https://daypicker.dev/docs/navigation#start-and-end-dates
|
152 | */
|
153 | endMonth?: Date;
|
154 | /**
|
155 | * @private
|
156 | * @deprecated This prop has been removed. Use `hidden={{ after: date }}`
|
157 | * instead.
|
158 | * @see https://daypicker.dev/docs/navigation#start-and-end-dates
|
159 | */
|
160 | toDate?: Date;
|
161 | /**
|
162 | * @private
|
163 | * @deprecated This prop has been renamed to `endMonth`.
|
164 | * @see https://daypicker.dev/docs/navigation#start-and-end-dates
|
165 | */
|
166 | toMonth?: Date;
|
167 | /**
|
168 | * @private
|
169 | * @deprecated Use `endMonth` instead. E.g. `endMonth={new Date(year, 0)}`.
|
170 | * @see https://daypicker.dev/docs/navigation#start-and-end-dates
|
171 | */
|
172 | toYear?: number;
|
173 |
|
174 | /**
|
175 | * Paginate the month navigation displaying the `numberOfMonths` at time.
|
176 | *
|
177 | * @see https://daypicker.dev/docs/customization#multiplemonths
|
178 | */
|
179 | pagedNavigation?: boolean;
|
180 | /**
|
181 | * Render the months in reversed order (when {@link numberOfMonths} is set) to
|
182 | * display the most recent month first.
|
183 | *
|
184 | * @see https://daypicker.dev/docs/customization#multiplemonths
|
185 | */
|
186 | reverseMonths?: boolean;
|
187 | /**
|
188 | * Hide the navigation buttons. This prop won't disable the navigation: to
|
189 | * disable the navigation, use {@link disableNavigation}.
|
190 | *
|
191 | * @since 9.0.0
|
192 | * @see https://daypicker.dev/docs/navigation#hidenavigation
|
193 | */
|
194 | hideNavigation?: boolean;
|
195 | /**
|
196 | * Disable the navigation between months. This prop won't hide the navigation:
|
197 | * to hide the navigation, use {@link hideNavigation}.
|
198 | *
|
199 | * @see https://daypicker.dev/docs/navigation#disablenavigation
|
200 | */
|
201 | disableNavigation?: boolean;
|
202 | /**
|
203 | * Show dropdowns to navigate between months or years.
|
204 | *
|
205 | * - `true`: display the dropdowns for both month and year
|
206 | * - `label`: display the month and the year as a label. Change the label with
|
207 | * the `formatCaption` formatter.
|
208 | * - `month`: display only the dropdown for the months
|
209 | * - `year`: display only the dropdown for the years
|
210 | *
|
211 | * **Note:** showing the dropdown will set the start/end months
|
212 | * {@link fromYear} to the 100 years ago, and {@link toYear} to the current
|
213 | * year.
|
214 | *
|
215 | * @see https://daypicker.dev/docs/customization#caption-layouts
|
216 | */
|
217 | captionLayout?: "label" | "dropdown" | "dropdown-months" | "dropdown-years";
|
218 | /**
|
219 | * Display always 6 weeks per each month, regardless the month’s number of
|
220 | * weeks. Weeks will be filled with the days from the next month.
|
221 | *
|
222 | * @see https://daypicker.dev/docs/customization#fixed-weeks
|
223 | */
|
224 | fixedWeeks?: boolean;
|
225 | /**
|
226 | * Hide the row displaying the weekday row header.
|
227 | *
|
228 | * @since 9.0.0
|
229 | */
|
230 | hideWeekdays?: boolean;
|
231 | /**
|
232 | * Show the outside days (days falling in the next or the previous month).
|
233 | *
|
234 | * @see https://daypicker.dev/docs/customization#outside-days
|
235 | */
|
236 | showOutsideDays?: boolean;
|
237 | /**
|
238 | * Show the week numbers column. Weeks are numbered according to the local
|
239 | * week index.
|
240 | *
|
241 | * - To use ISO week numbering, use the `ISOWeek` prop.
|
242 | * - To change how the week numbers are displayed, use the `formatters` prop.
|
243 | *
|
244 | * @see https://daypicker.dev/docs/customization#showweeknumber
|
245 | */
|
246 | showWeekNumber?: boolean;
|
247 | /**
|
248 | * Use ISO week dates instead of the locale setting. Setting this prop will
|
249 | * ignore `weekStartsOn` and `firstWeekContainsDate`.
|
250 | *
|
251 | * Use the
|
252 | * [react-day-picker/utc](https://daypicker.dev/docs/localization#utc-dates)
|
253 | * to set the calendar to UTC.
|
254 | *
|
255 | * @see https://daypicker.dev/docs/localization#iso-week-dates
|
256 | * @see https://en.wikipedia.org/wiki/ISO_week_date
|
257 | */
|
258 | ISOWeek?: boolean;
|
259 | /**
|
260 | * Change the components used for rendering the calendar elements.
|
261 | *
|
262 | * @see https://daypicker.dev/guides/custom-components
|
263 | */
|
264 | components?: Partial<CustomComponents>;
|
265 | /**
|
266 | * Add a footer to the calendar, acting as live region.
|
267 | *
|
268 | * Use this prop to communicate the calendar's status to screen readers.
|
269 | * Prefer strings over complex UI elements.
|
270 | *
|
271 | * @see https://daypicker.dev/docs/accessibility#footer
|
272 | */
|
273 | footer?: React.ReactNode | string;
|
274 | /**
|
275 | * When a selection mode is set, DayPicker will focus the first selected day
|
276 | * (if set) or the today's date (if not disabled).
|
277 | *
|
278 | * Use this prop when you need to focus DayPicker after a user actions, for
|
279 | * improved accessibility.
|
280 | *
|
281 | * @see https://daypicker.dev/docs/accessibility#autofocus
|
282 | */
|
283 | autoFocus?: boolean;
|
284 | /**
|
285 | * Apply the `disabled` modifier to the matching days.
|
286 | *
|
287 | * @see https://daypicker.dev/docs/selection-modes#disabling-dates
|
288 | */
|
289 | disabled?: Matcher | Matcher[] | undefined;
|
290 | /**
|
291 | * Apply the `hidden` modifier to the matching days. Will hide them from the
|
292 | * calendar.
|
293 | *
|
294 | * @see https://daypicker.dev/guides/custom-modifiers#hidden-modifier
|
295 | */
|
296 | hidden?: Matcher | Matcher[] | undefined;
|
297 | /**
|
298 | * The today’s date. Default is the current date. This date will get the
|
299 | * `today` modifier to style the day.
|
300 | *
|
301 | * @see https://daypicker.dev/guides/custom-modifiers#today-modifier
|
302 | */
|
303 | today?: Date;
|
304 | /**
|
305 | * Add modifiers to the matching days.
|
306 | *
|
307 | * @see https://daypicker.dev/guides/custom-modifiers
|
308 | */
|
309 | modifiers?: Record<string, Matcher | Matcher[] | undefined> | undefined;
|
310 | /**
|
311 | * Labels creators to override the defaults. Use this prop to customize the
|
312 | * aria-label attributes in DayPicker.
|
313 | *
|
314 | * @see https://daypicker.dev/docs/translation#aria-labels
|
315 | */
|
316 | labels?: Partial<Labels>;
|
317 | /**
|
318 | * Formatters used to format dates to strings. Use this prop to override the
|
319 | * default functions.
|
320 | *
|
321 | * @see https://daypicker.dev/docs/translation#custom-formatters
|
322 | */
|
323 | formatters?: Partial<Formatters>;
|
324 | /**
|
325 | * The text direction of the calendar. Use `ltr` for left-to-right (default)
|
326 | * or `rtl` for right-to-left.
|
327 | *
|
328 | * @see https://daypicker.dev/docs/translation#rtl-text-direction
|
329 | */
|
330 | dir?: HTMLDivElement["dir"];
|
331 | /**
|
332 | * A cryptographic nonce ("number used once") which can be used by Content
|
333 | * Security Policy for the inline `style` attributes.
|
334 | */
|
335 | nonce?: HTMLDivElement["nonce"];
|
336 | /** Add a `title` attribute to the container element. */
|
337 | title?: HTMLDivElement["title"];
|
338 | /** Add the language tag to the container element. */
|
339 | lang?: HTMLDivElement["lang"];
|
340 | /**
|
341 | * The locale object used to localize dates. Pass a locale from `date-fns` to
|
342 | * localize the calendar.
|
343 | *
|
344 | * @example
|
345 | * import { es } from "date-fns/locale";
|
346 | * <DayPicker locale={es} />
|
347 | *
|
348 | * @defaultValue enUS - The English locale default of `date-fns`.
|
349 | * @see https://daypicker.dev/docs/localization
|
350 | */
|
351 | locale?: Partial<Locale> | undefined;
|
352 | /**
|
353 | * The index of the first day of the week (0 - Sunday). Overrides the locale's
|
354 | * one.
|
355 | *
|
356 | * @see https://daypicker.dev/docs/localization#first-date-of-the-week
|
357 | */
|
358 | weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | undefined;
|
359 | /**
|
360 | * The day of January, which is always in the first week of the year.
|
361 | *
|
362 | * @see https://daypicker.dev/docs/localization#first-week-contains-date
|
363 | */
|
364 | firstWeekContainsDate?: 1 | 4;
|
365 | /**
|
366 | * Enable `DD` and `DDDD` for week year tokens when formatting or parsing
|
367 | * dates.
|
368 | *
|
369 | * @see https://date-fns.org/docs/Unicode-Tokens
|
370 | */
|
371 | useAdditionalWeekYearTokens?: boolean | undefined;
|
372 | /**
|
373 | * Enable `YY` and `YYYY` for day of year tokens when formatting or parsing
|
374 | * dates.
|
375 | *
|
376 | * @see https://date-fns.org/docs/Unicode-Tokens
|
377 | */
|
378 | useAdditionalDayOfYearTokens?: boolean | undefined;
|
379 |
|
380 | /**
|
381 | * Event fired when the user navigates between months.
|
382 | *
|
383 | * @see https://daypicker.dev/docs/navigation#onmonthchange
|
384 | */
|
385 | onMonthChange?: MonthChangeEventHandler;
|
386 |
|
387 | /**
|
388 | * Event handler when the next month button is clicked.
|
389 | *
|
390 | * @see https://daypicker.dev/docs/navigation
|
391 | */
|
392 | onNextClick?: MonthChangeEventHandler;
|
393 | /**
|
394 | * Event handler when the previous month button is clicked.
|
395 | *
|
396 | * @see https://daypicker.dev/docs/navigation
|
397 | */
|
398 | onPrevClick?: MonthChangeEventHandler;
|
399 | /**
|
400 | * Event handler when a week number is clicked
|
401 | *
|
402 | * @private
|
403 | * @deprecated Use a custom `WeekNumber` component instead.
|
404 | * @see https://daypicker.dev/docs/customization#showweeknumber
|
405 | */
|
406 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
407 | onWeekNumberClick?: any;
|
408 |
|
409 | /** Event handler when a day is clicked. */
|
410 | onDayClick?: DayEventHandler<React.MouseEvent>;
|
411 | /** Event handler when a day is focused. */
|
412 | onDayFocus?: DayEventHandler<React.FocusEvent>;
|
413 | /** Event handler when a day is blurred. */
|
414 | onDayBlur?: DayEventHandler<React.FocusEvent>;
|
415 | /** Event handler when a key is pressed on a day. */
|
416 | onDayKeyDown?: DayEventHandler<React.KeyboardEvent>;
|
417 | /** Event handler when the mouse enters a day. */
|
418 | onDayMouseEnter?: DayEventHandler<React.MouseEvent>;
|
419 | /** Event handler when the mouse leaves a day. */
|
420 | onDayMouseLeave?: DayEventHandler<React.MouseEvent>;
|
421 |
|
422 | /**
|
423 | * Replace the default date library with a custom one.
|
424 | *
|
425 | * @private
|
426 | * @since 9.0.0
|
427 | * @experimental
|
428 | */
|
429 | dateLib?: Partial<DateLib> | undefined;
|
430 |
|
431 | /**
|
432 | * @private
|
433 | * @deprecated Use a custom `DayButton` component instead.
|
434 | */
|
435 | onDayKeyUp?: DayEventHandler<React.KeyboardEvent>;
|
436 | /**
|
437 | * @private
|
438 | * @deprecated Use a custom `DayButton` component instead.
|
439 | */
|
440 | onDayKeyPress?: DayEventHandler<React.KeyboardEvent>;
|
441 | /**
|
442 | * @private
|
443 | * @deprecated Use a custom `DayButton` component instead.
|
444 | */
|
445 | onDayPointerEnter?: DayEventHandler<React.PointerEvent>;
|
446 | /**
|
447 | * @private
|
448 | * @deprecated Use a custom `DayButton` component instead.
|
449 | */
|
450 | onDayPointerLeave?: DayEventHandler<React.PointerEvent>;
|
451 | /**
|
452 | * @private
|
453 | * @deprecated Use a custom `DayButton` component instead.
|
454 | */
|
455 | onDayTouchCancel?: DayEventHandler<React.TouchEvent>;
|
456 | /**
|
457 | * @private
|
458 | * @deprecated Use a custom `DayButton` component instead.
|
459 | */
|
460 | onDayTouchEnd?: DayEventHandler<React.TouchEvent>;
|
461 | /**
|
462 | * @private
|
463 | * @deprecated Use a custom `DayButton` component instead.
|
464 | */
|
465 | onDayTouchMove?: DayEventHandler<React.TouchEvent>;
|
466 | /**
|
467 | * @private
|
468 | * @deprecated Use a custom `DayButton` component instead.
|
469 | */
|
470 | onDayTouchStart?: DayEventHandler<React.TouchEvent>;
|
471 | }
|
472 | /**
|
473 | * The props when the single selection is required.
|
474 | *
|
475 | * @see https://daypicker.dev/docs/selection-modes#single-mode
|
476 | */
|
477 | export interface PropsSingleRequired {
|
478 | mode: "single";
|
479 | required: true;
|
480 | /** The selected date. */
|
481 | selected: Date | undefined;
|
482 | /** Event handler when a day is selected. */
|
483 | onSelect?: (
|
484 | selected: Date,
|
485 | triggerDate: Date,
|
486 | modifiers: Modifiers,
|
487 | e: React.MouseEvent | React.KeyboardEvent
|
488 | ) => void | undefined;
|
489 | }
|
490 | /**
|
491 | * The props when the single selection is optional.
|
492 | *
|
493 | * @see https://daypicker.dev/docs/selection-modes#single-mode
|
494 | */
|
495 | export interface PropsSingle {
|
496 | mode: "single";
|
497 | required?: false | undefined;
|
498 | /** The selected date. */
|
499 | selected?: Date | undefined;
|
500 | /** Event handler when a day is selected. */
|
501 | onSelect?: (
|
502 | selected: Date | undefined,
|
503 | triggerDate: Date,
|
504 | modifiers: Modifiers,
|
505 | e: React.MouseEvent | React.KeyboardEvent
|
506 | ) => void;
|
507 | }
|
508 | /**
|
509 | * The props when the multiple selection is required.
|
510 | *
|
511 | * @see https://daypicker.dev/docs/selection-modes#multiple-mode
|
512 | */
|
513 | export interface PropsMultiRequired {
|
514 | mode: "multiple";
|
515 | required: true;
|
516 | /** The selected dates. */
|
517 | selected: Date[] | undefined;
|
518 | /** Event handler when days are selected. */
|
519 | onSelect?: (
|
520 | selected: Date[],
|
521 | triggerDate: Date,
|
522 | modifiers: Modifiers,
|
523 | e: React.MouseEvent | React.KeyboardEvent
|
524 | ) => void;
|
525 | /** The minimum number of selectable days. */
|
526 | min?: number;
|
527 | /** The maximum number of selectable days. */
|
528 | max?: number;
|
529 | }
|
530 | /**
|
531 | * The props when the multiple selection is optional.
|
532 | *
|
533 | * @see https://daypicker.dev/docs/selection-modes#multiple-mode
|
534 | */
|
535 | export interface PropsMulti {
|
536 | mode: "multiple";
|
537 | required?: false | undefined;
|
538 | /** The selected dates. */
|
539 | selected?: Date[] | undefined;
|
540 | /** Event handler when days are selected. */
|
541 | onSelect?: (
|
542 | selected: Date[] | undefined,
|
543 | triggerDate: Date,
|
544 | modifiers: Modifiers,
|
545 | e: React.MouseEvent | React.KeyboardEvent
|
546 | ) => void;
|
547 | /** The minimum number of selectable days. */
|
548 | min?: number;
|
549 | /** The maximum number of selectable days. */
|
550 | max?: number;
|
551 | }
|
552 | /**
|
553 | * The props when the range selection is required.
|
554 | *
|
555 | * @see https://daypicker.dev/docs/selection-modes#range-mode
|
556 | */
|
557 | export interface PropsRangeRequired {
|
558 | mode: "range";
|
559 | required: true;
|
560 | disabled?: Matcher | Matcher[] | undefined;
|
561 | /**
|
562 | * When `true`, the range will reset when including a disabled day.
|
563 | *
|
564 | * @since V9.0.2
|
565 | */
|
566 | excludeDisabled?: boolean | undefined;
|
567 | /** The selected range. */
|
568 | selected: DateRange | undefined;
|
569 | /** Event handler when a range is selected. */
|
570 | onSelect?: (
|
571 | selected: DateRange,
|
572 | triggerDate: Date,
|
573 | modifiers: Modifiers,
|
574 | e: React.MouseEvent | React.KeyboardEvent
|
575 | ) => void;
|
576 | /** The minimum number of days to include in the range. */
|
577 | min?: number;
|
578 | /** The maximum number of days to include in the range. */
|
579 | max?: number;
|
580 | }
|
581 | /**
|
582 | * The props when the range selection is optional.
|
583 | *
|
584 | * @see https://daypicker.dev/docs/selection-modes#range-mode
|
585 | */
|
586 | export interface PropsRange {
|
587 | mode: "range";
|
588 | required?: false | undefined;
|
589 | disabled?: Matcher | Matcher[] | undefined;
|
590 | /**
|
591 | * When `true`, the range will reset when including a disabled day.
|
592 | *
|
593 | * @since V9.0.2
|
594 | */
|
595 | excludeDisabled?: boolean | undefined;
|
596 | /** The selected range. */
|
597 | selected?: DateRange | undefined;
|
598 | /** Event handler when the selection changes. */
|
599 | onSelect?: (
|
600 | selected: DateRange | undefined,
|
601 | triggerDate: Date,
|
602 | modifiers: Modifiers,
|
603 | e: React.MouseEvent | React.KeyboardEvent
|
604 | ) => void | undefined;
|
605 | /** The minimum number of days to include in the range. */
|
606 | min?: number;
|
607 | /** The maximum number of days to include in the range. */
|
608 | max?: number;
|
609 | }
|