@mui/x-date-pickers 5.0.0-beta.7 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/AdapterDateFns/index.d.ts +7 -1
  2. package/AdapterDateFns/index.js +51 -1
  3. package/AdapterDayjs/index.d.ts +12 -1
  4. package/AdapterDayjs/index.js +45 -1
  5. package/CHANGELOG.md +78 -1
  6. package/CalendarPicker/CalendarPicker.d.ts +4 -1
  7. package/CalendarPicker/CalendarPicker.js +40 -10
  8. package/CalendarPicker/DayPicker.d.ts +2 -1
  9. package/CalendarPicker/DayPicker.js +100 -4
  10. package/CalendarPicker/PickersCalendarHeader.d.ts +8 -0
  11. package/CalendarPicker/useCalendarState.d.ts +10 -4
  12. package/CalendarPicker/useCalendarState.js +4 -3
  13. package/ClockPicker/ClockPicker.d.ts +3 -8
  14. package/DateField/DateField.interfaces.d.ts +4 -4
  15. package/DateField/index.d.ts +1 -1
  16. package/DateField/useDateField.d.ts +1 -1
  17. package/DateField/useDateField.js +35 -4
  18. package/DateTimePicker/DateTimePicker.js +2 -1
  19. package/DateTimePicker/DateTimePickerTabs.d.ts +20 -4
  20. package/DateTimePicker/DateTimePickerTabs.js +34 -5
  21. package/DateTimePicker/DateTimePickerToolbar.js +54 -68
  22. package/DateTimePicker/index.d.ts +2 -0
  23. package/DateTimePicker/index.js +2 -1
  24. package/DateTimePicker/shared.d.ts +2 -1
  25. package/DesktopDateTimePicker/DesktopDateTimePicker.js +13 -5
  26. package/MobileDateTimePicker/MobileDateTimePicker.js +13 -5
  27. package/MonthPicker/MonthPicker.d.ts +4 -0
  28. package/MonthPicker/MonthPicker.js +87 -10
  29. package/MonthPicker/PickersMonth.d.ts +6 -2
  30. package/MonthPicker/PickersMonth.js +23 -4
  31. package/PickersDay/PickersDay.d.ts +4 -2
  32. package/PickersDay/PickersDay.js +13 -74
  33. package/StaticDateTimePicker/StaticDateTimePicker.js +12 -5
  34. package/YearPicker/PickersYear.d.ts +3 -0
  35. package/YearPicker/PickersYear.js +11 -4
  36. package/YearPicker/YearPicker.d.ts +3 -0
  37. package/YearPicker/YearPicker.js +42 -8
  38. package/index.js +1 -1
  39. package/internals/components/CalendarOrClockPicker/CalendarOrClockPicker.d.ts +8 -0
  40. package/internals/components/CalendarOrClockPicker/CalendarOrClockPicker.js +26 -4
  41. package/internals/components/CalendarOrClockPicker/useFocusManagement.d.ts +10 -0
  42. package/internals/components/CalendarOrClockPicker/useFocusManagement.js +18 -0
  43. package/internals/components/PickersArrowSwitcher.d.ts +16 -0
  44. package/internals/components/PickersModalDialog.d.ts +2 -2
  45. package/internals/components/PureDateInput.d.ts +4 -0
  46. package/internals/components/PureDateInput.js +1 -1
  47. package/internals/components/wrappers/WrapperProps.d.ts +8 -0
  48. package/internals/hooks/useField/index.d.ts +1 -1
  49. package/internals/hooks/useField/useField.d.ts +2 -2
  50. package/internals/hooks/useField/useField.interfaces.d.ts +24 -20
  51. package/internals/hooks/useField/useField.js +44 -15
  52. package/internals/hooks/useField/useField.utils.d.ts +8 -8
  53. package/internals/hooks/useField/useField.utils.js +14 -52
  54. package/internals/hooks/validation/useDateValidation.d.ts +1 -0
  55. package/internals/hooks/validation/useDateValidation.js +1 -3
  56. package/internals/index.d.ts +0 -2
  57. package/internals/index.js +0 -1
  58. package/internals/models/muiPickersAdapter.d.ts +8 -0
  59. package/internals/models/props/baseToolbarProps.d.ts +0 -1
  60. package/internals-fields/index.d.ts +2 -0
  61. package/internals-fields/index.js +3 -0
  62. package/internals-fields/package.json +6 -0
  63. package/legacy/AdapterDateFns/index.js +76 -1
  64. package/legacy/AdapterDayjs/index.js +74 -1
  65. package/legacy/CalendarPicker/CalendarPicker.js +49 -9
  66. package/legacy/CalendarPicker/DayPicker.js +109 -5
  67. package/legacy/CalendarPicker/useCalendarState.js +4 -3
  68. package/legacy/DateField/useDateField.js +33 -4
  69. package/legacy/DateTimePicker/DateTimePicker.js +2 -1
  70. package/legacy/DateTimePicker/DateTimePickerTabs.js +34 -5
  71. package/legacy/DateTimePicker/DateTimePickerToolbar.js +60 -74
  72. package/legacy/DateTimePicker/index.js +2 -1
  73. package/legacy/DesktopDateTimePicker/DesktopDateTimePicker.js +15 -4
  74. package/legacy/MobileDateTimePicker/MobileDateTimePicker.js +15 -4
  75. package/legacy/MonthPicker/MonthPicker.js +100 -8
  76. package/legacy/MonthPicker/PickersMonth.js +28 -3
  77. package/legacy/PickersDay/PickersDay.js +22 -75
  78. package/legacy/StaticDateTimePicker/StaticDateTimePicker.js +14 -4
  79. package/legacy/YearPicker/PickersYear.js +16 -3
  80. package/legacy/YearPicker/YearPicker.js +50 -8
  81. package/legacy/index.js +1 -1
  82. package/legacy/internals/components/CalendarOrClockPicker/CalendarOrClockPicker.js +25 -3
  83. package/legacy/internals/components/CalendarOrClockPicker/useFocusManagement.js +27 -0
  84. package/legacy/internals/components/PureDateInput.js +1 -1
  85. package/legacy/internals/hooks/useField/useField.js +64 -26
  86. package/legacy/internals/hooks/useField/useField.utils.js +14 -52
  87. package/legacy/internals/hooks/validation/useDateValidation.js +1 -3
  88. package/legacy/internals/index.js +0 -1
  89. package/legacy/internals-fields/index.js +3 -0
  90. package/modern/AdapterDateFns/index.js +51 -1
  91. package/modern/AdapterDayjs/index.js +43 -1
  92. package/modern/CalendarPicker/CalendarPicker.js +40 -10
  93. package/modern/CalendarPicker/DayPicker.js +100 -4
  94. package/modern/CalendarPicker/useCalendarState.js +4 -3
  95. package/modern/DateField/useDateField.js +35 -4
  96. package/modern/DateTimePicker/DateTimePicker.js +2 -1
  97. package/modern/DateTimePicker/DateTimePickerTabs.js +34 -5
  98. package/modern/DateTimePicker/DateTimePickerToolbar.js +54 -68
  99. package/modern/DateTimePicker/index.js +2 -1
  100. package/modern/DesktopDateTimePicker/DesktopDateTimePicker.js +13 -5
  101. package/modern/MobileDateTimePicker/MobileDateTimePicker.js +13 -5
  102. package/modern/MonthPicker/MonthPicker.js +87 -10
  103. package/modern/MonthPicker/PickersMonth.js +21 -4
  104. package/modern/PickersDay/PickersDay.js +13 -74
  105. package/modern/StaticDateTimePicker/StaticDateTimePicker.js +12 -5
  106. package/modern/YearPicker/PickersYear.js +11 -4
  107. package/modern/YearPicker/YearPicker.js +42 -8
  108. package/modern/index.js +1 -1
  109. package/modern/internals/components/CalendarOrClockPicker/CalendarOrClockPicker.js +24 -4
  110. package/modern/internals/components/CalendarOrClockPicker/useFocusManagement.js +18 -0
  111. package/modern/internals/components/PureDateInput.js +1 -1
  112. package/modern/internals/hooks/useField/useField.js +42 -15
  113. package/modern/internals/hooks/useField/useField.utils.js +14 -52
  114. package/modern/internals/hooks/validation/useDateValidation.js +1 -3
  115. package/modern/internals/index.js +0 -1
  116. package/modern/internals-fields/index.js +3 -0
  117. package/node/AdapterDateFns/index.js +57 -6
  118. package/node/AdapterDayjs/index.js +49 -6
  119. package/node/CalendarPicker/CalendarPicker.js +39 -9
  120. package/node/CalendarPicker/DayPicker.js +100 -3
  121. package/node/CalendarPicker/useCalendarState.js +4 -3
  122. package/node/DateField/useDateField.js +35 -3
  123. package/node/DateTimePicker/DateTimePicker.js +2 -1
  124. package/node/DateTimePicker/DateTimePickerTabs.js +32 -4
  125. package/node/DateTimePicker/DateTimePickerToolbar.js +54 -70
  126. package/node/DateTimePicker/index.js +9 -1
  127. package/node/DesktopDateTimePicker/DesktopDateTimePicker.js +13 -5
  128. package/node/MobileDateTimePicker/MobileDateTimePicker.js +13 -5
  129. package/node/MonthPicker/MonthPicker.js +87 -9
  130. package/node/MonthPicker/PickersMonth.js +26 -6
  131. package/node/PickersDay/PickersDay.js +12 -73
  132. package/node/StaticDateTimePicker/StaticDateTimePicker.js +13 -5
  133. package/node/YearPicker/PickersYear.js +11 -4
  134. package/node/YearPicker/YearPicker.js +43 -8
  135. package/node/index.js +1 -1
  136. package/node/internals/components/CalendarOrClockPicker/CalendarOrClockPicker.js +27 -4
  137. package/node/internals/components/CalendarOrClockPicker/useFocusManagement.js +32 -0
  138. package/node/internals/components/PureDateInput.js +1 -1
  139. package/node/internals/hooks/useField/useField.js +44 -15
  140. package/node/internals/hooks/useField/useField.utils.js +16 -56
  141. package/node/internals/hooks/validation/useDateValidation.js +3 -1
  142. package/node/internals/index.js +0 -26
  143. package/node/internals-fields/index.js +31 -0
  144. package/package.json +1 -1
@@ -3,9 +3,13 @@ declare const classes: Record<"root" | "selected", string>;
3
3
  export interface MonthProps {
4
4
  children: React.ReactNode;
5
5
  disabled?: boolean;
6
- onSelect: (value: any) => void;
6
+ onSelect: (value: number) => void;
7
7
  selected?: boolean;
8
- value: any;
8
+ value: number;
9
+ hasFocus: boolean;
10
+ onBlur: (event: React.FocusEvent, month: number) => void;
11
+ onFocus: (event: React.FocusEvent, month: number) => void;
12
+ tabIndex: number;
9
13
  }
10
14
  export declare type PickersMonthClassKey = keyof typeof classes;
11
15
  /**
@@ -1,11 +1,12 @@
1
1
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
2
2
  import _extends from "@babel/runtime/helpers/esm/extends";
3
- const _excluded = ["disabled", "onSelect", "selected", "value"];
3
+ const _excluded = ["disabled", "onSelect", "selected", "value", "tabIndex", "hasFocus", "onFocus", "onBlur"];
4
4
  import * as React from 'react';
5
5
  import clsx from 'clsx';
6
6
  import Typography from '@mui/material/Typography';
7
7
  import { styled, alpha } from '@mui/material/styles';
8
8
  import { generateUtilityClasses } from '@mui/material';
9
+ import { unstable_useEnhancedEffect as useEnhancedEffect } from '@mui/material/utils';
9
10
  import { onSpaceOrEnter } from '../internals/utils/utils';
10
11
  import { jsx as _jsx } from "react/jsx-runtime";
11
12
  const classes = generateUtilityClasses('PrivatePickersMonth', ['root', 'selected']);
@@ -40,16 +41,23 @@ const PickersMonthRoot = styled(Typography)(({
40
41
  }
41
42
  }
42
43
  }));
44
+
45
+ const noop = () => {};
43
46
  /**
44
47
  * @ignore - do not document.
45
48
  */
46
49
 
50
+
47
51
  export const PickersMonth = props => {
48
52
  const {
49
53
  disabled,
50
54
  onSelect,
51
55
  selected,
52
- value
56
+ value,
57
+ tabIndex,
58
+ hasFocus,
59
+ onFocus = noop,
60
+ onBlur = noop
53
61
  } = props,
54
62
  other = _objectWithoutPropertiesLoose(props, _excluded);
55
63
 
@@ -57,15 +65,26 @@ export const PickersMonth = props => {
57
65
  onSelect(value);
58
66
  };
59
67
 
68
+ const ref = React.useRef(null);
69
+ useEnhancedEffect(() => {
70
+ if (hasFocus) {
71
+ var _ref$current;
72
+
73
+ (_ref$current = ref.current) == null ? void 0 : _ref$current.focus();
74
+ }
75
+ }, [hasFocus]);
60
76
  return /*#__PURE__*/_jsx(PickersMonthRoot, _extends({
77
+ ref: ref,
61
78
  component: "button",
62
79
  type: "button",
63
80
  className: clsx(classes.root, selected && classes.selected),
64
- tabIndex: disabled ? -1 : 0,
81
+ tabIndex: tabIndex,
65
82
  onClick: handleSelection,
66
83
  onKeyDown: onSpaceOrEnter(handleSelection),
67
84
  color: selected ? 'primary' : undefined,
68
85
  variant: selected ? 'h5' : 'subtitle1',
69
- disabled: disabled
86
+ disabled: disabled,
87
+ onFocus: event => onFocus(event, value),
88
+ onBlur: event => onBlur(event, value)
70
89
  }, other));
71
90
  };
@@ -5,7 +5,7 @@ import { Theme } from '@mui/material/styles';
5
5
  import { ExtendMui } from '../internals/models/helpers';
6
6
  import { PickerSelectionState } from '../internals/hooks/usePickerState';
7
7
  import { PickersDayClasses } from './pickersDayClasses';
8
- export interface PickersDayProps<TDate> extends ExtendMui<ButtonBaseProps> {
8
+ export interface PickersDayProps<TDate> extends Omit<ExtendMui<ButtonBaseProps>, 'onKeyDown' | 'onFocus' | 'onBlur'> {
9
9
  /**
10
10
  * Override or extend the styles applied to the component.
11
11
  */
@@ -30,7 +30,9 @@ export interface PickersDayProps<TDate> extends ExtendMui<ButtonBaseProps> {
30
30
  */
31
31
  disableMargin?: boolean;
32
32
  isAnimating?: boolean;
33
- onDayFocus?: (day: TDate) => void;
33
+ onFocus?: (event: React.FocusEvent<HTMLButtonElement>, day: TDate) => void;
34
+ onBlur?: (event: React.FocusEvent<HTMLButtonElement>, day: TDate) => void;
35
+ onKeyDown?: (event: React.KeyboardEvent<HTMLButtonElement>, day: TDate) => void;
34
36
  onDaySelect: (day: TDate, isFinish: PickerSelectionState) => void;
35
37
  /**
36
38
  * If `true`, day is outside of month and will be hidden.
@@ -1,13 +1,13 @@
1
1
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
2
2
  import _extends from "@babel/runtime/helpers/esm/extends";
3
- const _excluded = ["autoFocus", "className", "day", "disabled", "disableHighlightToday", "disableMargin", "hidden", "isAnimating", "onClick", "onDayFocus", "onDaySelect", "onFocus", "onKeyDown", "onMouseDown", "outsideCurrentMonth", "selected", "showDaysOutsideCurrentMonth", "children", "today"];
3
+ const _excluded = ["autoFocus", "className", "day", "disabled", "disableHighlightToday", "disableMargin", "hidden", "isAnimating", "onClick", "onDaySelect", "onFocus", "onBlur", "onKeyDown", "onMouseDown", "outsideCurrentMonth", "selected", "showDaysOutsideCurrentMonth", "children", "today"];
4
4
  import * as React from 'react';
5
5
  import PropTypes from 'prop-types';
6
6
  import clsx from 'clsx';
7
7
  import ButtonBase from '@mui/material/ButtonBase';
8
8
  import { unstable_useEnhancedEffect as useEnhancedEffect } from '@mui/utils';
9
9
  import { unstable_composeClasses as composeClasses } from '@mui/material';
10
- import { useTheme, alpha, styled, useThemeProps } from '@mui/material/styles';
10
+ import { alpha, styled, useThemeProps } from '@mui/material/styles';
11
11
  import { useForkRef } from '@mui/material/utils';
12
12
  import { useUtils } from '../internals/hooks/useUtils';
13
13
  import { DAY_SIZE, DAY_MARGIN } from '../internals/constants/dimensions';
@@ -121,10 +121,10 @@ const PickersDayRaw = /*#__PURE__*/React.forwardRef(function PickersDay(inProps,
121
121
  disableMargin = false,
122
122
  isAnimating,
123
123
  onClick,
124
- onDayFocus = noop,
125
124
  onDaySelect,
126
- onFocus,
127
- onKeyDown,
125
+ onFocus = noop,
126
+ onBlur = noop,
127
+ onKeyDown = noop,
128
128
  onMouseDown,
129
129
  outsideCurrentMonth,
130
130
  selected = false,
@@ -155,20 +155,9 @@ const PickersDayRaw = /*#__PURE__*/React.forwardRef(function PickersDay(inProps,
155
155
  // ref.current being null would be a bug in MUI
156
156
  ref.current.focus();
157
157
  }
158
- }, [autoFocus, disabled, isAnimating, outsideCurrentMonth]);
159
-
160
- const handleFocus = event => {
161
- if (onDayFocus) {
162
- onDayFocus(day);
163
- }
164
-
165
- if (onFocus) {
166
- onFocus(event);
167
- }
168
- }; // For day outside of current month, move focus from mouseDown to mouseUp
158
+ }, [autoFocus, disabled, isAnimating, outsideCurrentMonth]); // For day outside of current month, move focus from mouseDown to mouseUp
169
159
  // Goal: have the onClick ends before sliding to the new month
170
160
 
171
-
172
161
  const handleMouseDown = event => {
173
162
  if (onMouseDown) {
174
163
  onMouseDown(event);
@@ -193,59 +182,6 @@ const PickersDayRaw = /*#__PURE__*/React.forwardRef(function PickersDay(inProps,
193
182
  }
194
183
  };
195
184
 
196
- const theme = useTheme();
197
-
198
- function handleKeyDown(event) {
199
- if (onKeyDown !== undefined) {
200
- onKeyDown(event);
201
- }
202
-
203
- switch (event.key) {
204
- case 'ArrowUp':
205
- onDayFocus(utils.addDays(day, -7));
206
- event.preventDefault();
207
- break;
208
-
209
- case 'ArrowDown':
210
- onDayFocus(utils.addDays(day, 7));
211
- event.preventDefault();
212
- break;
213
-
214
- case 'ArrowLeft':
215
- onDayFocus(utils.addDays(day, theme.direction === 'ltr' ? -1 : 1));
216
- event.preventDefault();
217
- break;
218
-
219
- case 'ArrowRight':
220
- onDayFocus(utils.addDays(day, theme.direction === 'ltr' ? 1 : -1));
221
- event.preventDefault();
222
- break;
223
-
224
- case 'Home':
225
- onDayFocus(utils.startOfWeek(day));
226
- event.preventDefault();
227
- break;
228
-
229
- case 'End':
230
- onDayFocus(utils.endOfWeek(day));
231
- event.preventDefault();
232
- break;
233
-
234
- case 'PageUp':
235
- onDayFocus(utils.getNextMonth(day));
236
- event.preventDefault();
237
- break;
238
-
239
- case 'PageDown':
240
- onDayFocus(utils.getPreviousMonth(day));
241
- event.preventDefault();
242
- break;
243
-
244
- default:
245
- break;
246
- }
247
- }
248
-
249
185
  if (outsideCurrentMonth && !showDaysOutsideCurrentMonth) {
250
186
  return /*#__PURE__*/_jsx(PickersDayFiller, {
251
187
  className: clsx(classes.root, classes.hiddenDaySpacingFiller, className),
@@ -261,8 +197,9 @@ const PickersDayRaw = /*#__PURE__*/React.forwardRef(function PickersDay(inProps,
261
197
  centerRipple: true,
262
198
  disabled: disabled,
263
199
  tabIndex: selected ? 0 : -1,
264
- onFocus: handleFocus,
265
- onKeyDown: handleKeyDown,
200
+ onKeyDown: event => onKeyDown(event, day),
201
+ onFocus: event => onFocus(event, day),
202
+ onBlur: event => onBlur(event, day),
266
203
  onClick: handleClick,
267
204
  onMouseDown: handleMouseDown
268
205
  }, other, {
@@ -270,7 +207,7 @@ const PickersDayRaw = /*#__PURE__*/React.forwardRef(function PickersDay(inProps,
270
207
  }));
271
208
  });
272
209
  export const areDayPropsEqual = (prevProps, nextProps) => {
273
- return prevProps.autoFocus === nextProps.autoFocus && prevProps.isAnimating === nextProps.isAnimating && prevProps.today === nextProps.today && prevProps.disabled === nextProps.disabled && prevProps.selected === nextProps.selected && prevProps.disableMargin === nextProps.disableMargin && prevProps.showDaysOutsideCurrentMonth === nextProps.showDaysOutsideCurrentMonth && prevProps.disableHighlightToday === nextProps.disableHighlightToday && prevProps.className === nextProps.className && prevProps.outsideCurrentMonth === nextProps.outsideCurrentMonth && prevProps.onDayFocus === nextProps.onDayFocus && prevProps.onDaySelect === nextProps.onDaySelect;
210
+ return prevProps.autoFocus === nextProps.autoFocus && prevProps.isAnimating === nextProps.isAnimating && prevProps.today === nextProps.today && prevProps.disabled === nextProps.disabled && prevProps.selected === nextProps.selected && prevProps.disableMargin === nextProps.disableMargin && prevProps.showDaysOutsideCurrentMonth === nextProps.showDaysOutsideCurrentMonth && prevProps.disableHighlightToday === nextProps.disableHighlightToday && prevProps.className === nextProps.className && prevProps.outsideCurrentMonth === nextProps.outsideCurrentMonth && prevProps.onFocus === nextProps.onFocus && prevProps.onBlur === nextProps.onBlur && prevProps.onDaySelect === nextProps.onDaySelect;
274
211
  };
275
212
  process.env.NODE_ENV !== "production" ? PickersDayRaw.propTypes = {
276
213
  // ----------------------------- Warning --------------------------------
@@ -306,8 +243,10 @@ process.env.NODE_ENV !== "production" ? PickersDayRaw.propTypes = {
306
243
  */
307
244
  disableMargin: PropTypes.bool,
308
245
  isAnimating: PropTypes.bool,
309
- onDayFocus: PropTypes.func,
246
+ onBlur: PropTypes.func,
310
247
  onDaySelect: PropTypes.func.isRequired,
248
+ onFocus: PropTypes.func,
249
+ onKeyDown: PropTypes.func,
311
250
 
312
251
  /**
313
252
  * If `true`, day is outside of month and will be hidden.
@@ -1,6 +1,6 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
- const _excluded = ["displayStaticWrapperAs", "onChange", "ToolbarComponent", "value", "components", "componentsProps"];
3
+ const _excluded = ["displayStaticWrapperAs", "onChange", "ToolbarComponent", "value", "components", "componentsProps", "hideTabs"];
4
4
  import * as React from 'react';
5
5
  import PropTypes from 'prop-types';
6
6
  import { useDateTimePickerDefaultizedProps, dateTimePickerValueManager } from '../DateTimePicker/shared';
@@ -9,6 +9,7 @@ import { PickerStaticWrapper } from '../internals/components/PickerStaticWrapper
9
9
  import { CalendarOrClockPicker } from '../internals/components/CalendarOrClockPicker';
10
10
  import { useDateTimeValidation } from '../internals/hooks/validation/useDateTimeValidation';
11
11
  import { usePickerState } from '../internals/hooks/usePickerState';
12
+ import { DateTimePickerTabs } from '../DateTimePicker';
12
13
  import { jsx as _jsx } from "react/jsx-runtime";
13
14
 
14
15
  /**
@@ -28,8 +29,9 @@ export const StaticDateTimePicker = /*#__PURE__*/React.forwardRef(function Stati
28
29
  const {
29
30
  displayStaticWrapperAs = 'mobile',
30
31
  ToolbarComponent = DateTimePickerToolbar,
31
- components,
32
- componentsProps
32
+ components: providedComponents,
33
+ componentsProps,
34
+ hideTabs = displayStaticWrapperAs === 'desktop'
33
35
  } = props,
34
36
  other = _objectWithoutPropertiesLoose(props, _excluded);
35
37
 
@@ -39,6 +41,9 @@ export const StaticDateTimePicker = /*#__PURE__*/React.forwardRef(function Stati
39
41
  wrapperProps
40
42
  } = usePickerState(props, dateTimePickerValueManager);
41
43
  const validationError = useDateTimeValidation(props) !== null;
44
+ const components = React.useMemo(() => _extends({
45
+ Tabs: DateTimePickerTabs
46
+ }, providedComponents), [providedComponents]);
42
47
 
43
48
  const DateInputProps = _extends({}, inputProps, other, {
44
49
  ref,
@@ -57,7 +62,8 @@ export const StaticDateTimePicker = /*#__PURE__*/React.forwardRef(function Stati
57
62
  ToolbarComponent: ToolbarComponent,
58
63
  DateInputProps: DateInputProps,
59
64
  components: components,
60
- componentsProps: componentsProps
65
+ componentsProps: componentsProps,
66
+ hideTabs: hideTabs
61
67
  }, other))
62
68
  }));
63
69
  });
@@ -213,7 +219,8 @@ process.env.NODE_ENV !== "production" ? StaticDateTimePicker.propTypes = {
213
219
  getViewSwitchingButtonText: PropTypes.func,
214
220
 
215
221
  /**
216
- * To show tabs.
222
+ * Toggles visibility of date time switching tabs
223
+ * @default false for mobile, true for desktop
217
224
  */
218
225
  hideTabs: PropTypes.bool,
219
226
  ignoreInvalidInputs: PropTypes.bool,
@@ -16,6 +16,9 @@ export interface YearProps {
16
16
  onKeyDown: (event: React.KeyboardEvent, value: number) => void;
17
17
  selected: boolean;
18
18
  value: number;
19
+ tabIndex: number;
20
+ onFocus: (event: React.FocusEvent, year: number) => void;
21
+ onBlur: (event: React.FocusEvent, year: number) => void;
19
22
  }
20
23
  export declare function getPickersYearUtilityClass(slot: string): string;
21
24
  export declare type PickersYearClassKey = keyof NonNullable<YearProps['classes']>;
@@ -1,6 +1,6 @@
1
1
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
2
2
  import _extends from "@babel/runtime/helpers/esm/extends";
3
- const _excluded = ["autoFocus", "className", "children", "disabled", "onClick", "onKeyDown", "selected", "value"];
3
+ const _excluded = ["autoFocus", "className", "children", "disabled", "onClick", "onKeyDown", "value", "tabIndex", "onFocus", "onBlur"];
4
4
  import * as React from 'react';
5
5
  import clsx from 'clsx';
6
6
  import { useForkRef, capitalize } from '@mui/material/utils';
@@ -64,10 +64,13 @@ const PickersYearButton = styled('button')(({
64
64
  }
65
65
  }
66
66
  }));
67
+
68
+ const noop = () => {};
67
69
  /**
68
70
  * @ignore - internal component.
69
71
  */
70
72
 
73
+
71
74
  export const PickersYear = /*#__PURE__*/React.forwardRef(function PickersYear(props, forwardedRef) {
72
75
  const {
73
76
  autoFocus,
@@ -76,8 +79,10 @@ export const PickersYear = /*#__PURE__*/React.forwardRef(function PickersYear(pr
76
79
  disabled,
77
80
  onClick,
78
81
  onKeyDown,
79
- selected,
80
- value
82
+ value,
83
+ tabIndex,
84
+ onFocus = noop,
85
+ onBlur = noop
81
86
  } = props,
82
87
  other = _objectWithoutPropertiesLoose(props, _excluded);
83
88
 
@@ -104,9 +109,11 @@ export const PickersYear = /*#__PURE__*/React.forwardRef(function PickersYear(pr
104
109
  ref: refHandle,
105
110
  disabled: disabled,
106
111
  type: "button",
107
- tabIndex: selected ? 0 : -1,
112
+ tabIndex: disabled ? -1 : tabIndex,
108
113
  onClick: event => onClick(event, value),
109
114
  onKeyDown: event => onKeyDown(event, value),
115
+ onFocus: event => onFocus(event, value),
116
+ onBlur: event => onBlur(event, value),
110
117
  className: classes.yearButton,
111
118
  ownerState: ownerState
112
119
  }, other, {
@@ -16,6 +16,9 @@ export interface YearPickerProps<TDate> extends YearValidationProps<TDate>, Base
16
16
  * @default false
17
17
  */
18
18
  disableHighlightToday?: boolean;
19
+ onYearFocus?: (year: number) => void;
20
+ hasFocus?: boolean;
21
+ onFocusedViewChange?: (newHasFocus: boolean) => void;
19
22
  }
20
23
  declare type YearPickerComponent = (<TDate>(props: YearPickerProps<TDate>) => JSX.Element) & {
21
24
  propTypes?: any;
@@ -3,6 +3,7 @@ import * as React from 'react';
3
3
  import PropTypes from 'prop-types';
4
4
  import { useTheme, styled, useThemeProps } from '@mui/material/styles';
5
5
  import { unstable_composeClasses as composeClasses } from '@mui/material';
6
+ import { useControlled } from '@mui/material/utils';
6
7
  import clsx from 'clsx';
7
8
  import { PickersYear } from './PickersYear';
8
9
  import { useUtils, useNow, useDefaultDates } from '../internals/hooks/useUtils';
@@ -66,7 +67,10 @@ export const YearPicker = /*#__PURE__*/React.forwardRef(function YearPicker(inPr
66
67
  onChange,
67
68
  readOnly,
68
69
  shouldDisableYear,
69
- disableHighlightToday
70
+ disableHighlightToday,
71
+ onYearFocus,
72
+ hasFocus,
73
+ onFocusedViewChange
70
74
  } = props;
71
75
  const ownerState = props;
72
76
  const classes = useUtilityClasses(ownerState);
@@ -84,7 +88,20 @@ export const YearPicker = /*#__PURE__*/React.forwardRef(function YearPicker(inPr
84
88
  }, [now, date, utils, disableHighlightToday]);
85
89
  const wrapperVariant = React.useContext(WrapperVariantContext);
86
90
  const selectedYearRef = React.useRef(null);
87
- const [focusedYear, setFocusedYear] = React.useState(currentYear);
91
+ const [focusedYear, setFocusedYear] = React.useState(() => currentYear || utils.getYear(now));
92
+ const [internalHasFocus, setInternalHasFocus] = useControlled({
93
+ name: 'YearPicker',
94
+ state: 'hasFocus',
95
+ controlled: hasFocus,
96
+ default: autoFocus
97
+ });
98
+ const changeHasFocus = React.useCallback(newHasFocus => {
99
+ setInternalHasFocus(newHasFocus);
100
+
101
+ if (onFocusedViewChange) {
102
+ onFocusedViewChange(newHasFocus);
103
+ }
104
+ }, [setInternalHasFocus, onFocusedViewChange]);
88
105
  const isYearDisabled = React.useCallback(dateToValidate => {
89
106
  if (disablePast && utils.isBeforeYear(dateToValidate, now)) {
90
107
  return true;
@@ -121,11 +138,15 @@ export const YearPicker = /*#__PURE__*/React.forwardRef(function YearPicker(inPr
121
138
  const focusYear = React.useCallback(year => {
122
139
  if (!isYearDisabled(utils.setYear(selectedDateOrToday, year))) {
123
140
  setFocusedYear(year);
141
+ changeHasFocus(true);
142
+ onYearFocus == null ? void 0 : onYearFocus(year);
124
143
  }
125
- }, [selectedDateOrToday, isYearDisabled, utils]);
144
+ }, [isYearDisabled, utils, selectedDateOrToday, changeHasFocus, onYearFocus]);
145
+ React.useEffect(() => {
146
+ setFocusedYear(prevFocusedYear => currentYear !== null && prevFocusedYear !== currentYear ? currentYear : prevFocusedYear);
147
+ }, [currentYear]);
126
148
  const yearsInRow = wrapperVariant === 'desktop' ? 4 : 3;
127
-
128
- const handleKeyDown = (event, year) => {
149
+ const handleKeyDown = React.useCallback((event, year) => {
129
150
  switch (event.key) {
130
151
  case 'ArrowUp':
131
152
  focusYear(year - yearsInRow);
@@ -150,8 +171,15 @@ export const YearPicker = /*#__PURE__*/React.forwardRef(function YearPicker(inPr
150
171
  default:
151
172
  break;
152
173
  }
153
- };
154
-
174
+ }, [focusYear, theme.direction, yearsInRow]);
175
+ const handleFocus = React.useCallback((event, year) => {
176
+ focusYear(year);
177
+ }, [focusYear]);
178
+ const handleBlur = React.useCallback((event, year) => {
179
+ if (focusedYear === year) {
180
+ changeHasFocus(false);
181
+ }
182
+ }, [focusedYear, changeHasFocus]);
155
183
  const nowYear = utils.getYear(now);
156
184
  return /*#__PURE__*/_jsx(YearPickerRoot, {
157
185
  ref: ref,
@@ -165,9 +193,12 @@ export const YearPicker = /*#__PURE__*/React.forwardRef(function YearPicker(inPr
165
193
  value: yearNumber,
166
194
  onClick: handleYearSelection,
167
195
  onKeyDown: handleKeyDown,
168
- autoFocus: autoFocus && yearNumber === focusedYear,
196
+ autoFocus: internalHasFocus && yearNumber === focusedYear,
169
197
  ref: selected ? selectedYearRef : undefined,
170
198
  disabled: disabled || isYearDisabled(year),
199
+ tabIndex: yearNumber === focusedYear ? 0 : -1,
200
+ onFocus: handleFocus,
201
+ onBlur: handleBlur,
171
202
  "aria-current": nowYear === yearNumber ? 'date' : undefined,
172
203
  children: utils.format(year, 'year')
173
204
  }, utils.format(year, 'year'));
@@ -202,6 +233,7 @@ process.env.NODE_ENV !== "production" ? YearPicker.propTypes = {
202
233
  * @default false
203
234
  */
204
235
  disablePast: PropTypes.bool,
236
+ hasFocus: PropTypes.bool,
205
237
 
206
238
  /**
207
239
  * Maximal selectable date. @DateIOType
@@ -214,6 +246,8 @@ process.env.NODE_ENV !== "production" ? YearPicker.propTypes = {
214
246
  minDate: PropTypes.any,
215
247
  onChange: PropTypes.func.isRequired,
216
248
  onFocusedDayChange: PropTypes.func,
249
+ onFocusedViewChange: PropTypes.func,
250
+ onYearFocus: PropTypes.func,
217
251
  readOnly: PropTypes.bool,
218
252
 
219
253
  /**
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /** @license MUI v5.0.0-beta.7
1
+ /** @license MUI v5.0.0
2
2
  *
3
3
  * This source code is licensed under the MIT license found in the
4
4
  * LICENSE file in the root directory of this source tree.
@@ -1,4 +1,5 @@
1
1
  import * as React from 'react';
2
+ import { DateTimePickerTabsProps } from '../../../DateTimePicker';
2
3
  import { ExportedClockPickerProps } from '../../../ClockPicker/ClockPicker';
3
4
  import { CalendarPickerSlotsComponent, CalendarPickerSlotsComponentsProps, ExportedCalendarPickerProps } from '../../../CalendarPicker/CalendarPicker';
4
5
  import { DateInputPropsLike } from '../wrappers/WrapperProps';
@@ -7,8 +8,14 @@ import { BasePickerProps } from '../../models/props/basePickerProps';
7
8
  import { CalendarOrClockPickerView } from '../../models';
8
9
  import { BaseToolbarProps } from '../../models/props/baseToolbarProps';
9
10
  export interface CalendarOrClockPickerSlotsComponent extends CalendarPickerSlotsComponent {
11
+ /**
12
+ * Tabs enabling toggling between date and time pickers.
13
+ * @default DateTimePickerTabs
14
+ */
15
+ Tabs: React.ElementType<DateTimePickerTabsProps>;
10
16
  }
11
17
  export interface CalendarOrClockPickerSlotsComponentsProps extends CalendarPickerSlotsComponentsProps {
18
+ tabs: Omit<DateTimePickerTabsProps, 'onChange' | 'view'>;
12
19
  }
13
20
  export interface ExportedCalendarOrClockPickerProps<TDate, View extends CalendarOrClockPickerView> extends Omit<BasePickerProps<any, TDate | null>, 'value' | 'onChange'>, Omit<ExportedCalendarPickerProps<TDate>, 'onViewChange' | 'openTo' | 'view'>, ExportedClockPickerProps<TDate> {
14
21
  dateRangeIcon?: React.ReactNode;
@@ -40,6 +47,7 @@ export interface ExportedCalendarOrClockPickerProps<TDate, View extends Calendar
40
47
  toolbarFormat?: string;
41
48
  toolbarPlaceholder?: React.ReactNode;
42
49
  toolbarTitle?: React.ReactNode;
50
+ hideTabs?: boolean;
43
51
  }
44
52
  export interface CalendarOrClockPickerProps<TDate, View extends CalendarOrClockPickerView> extends ExportedCalendarOrClockPickerProps<TDate, View>, PickerStatePickerProps<TDate | null> {
45
53
  autoFocus?: boolean;
@@ -1,6 +1,6 @@
1
1
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
2
2
  import _extends from "@babel/runtime/helpers/esm/extends";
3
- const _excluded = ["autoFocus", "className", "parsedValue", "DateInputProps", "isMobileKeyboardViewOpen", "onDateChange", "onViewChange", "openTo", "orientation", "showToolbar", "toggleMobileKeyboardView", "ToolbarComponent", "toolbarFormat", "toolbarPlaceholder", "toolbarTitle", "views"];
3
+ const _excluded = ["autoFocus", "className", "parsedValue", "DateInputProps", "isMobileKeyboardViewOpen", "onDateChange", "onViewChange", "openTo", "orientation", "showToolbar", "toggleMobileKeyboardView", "ToolbarComponent", "toolbarFormat", "toolbarPlaceholder", "toolbarTitle", "views", "dateRangeIcon", "timeIcon", "hideTabs"];
4
4
  import * as React from 'react';
5
5
  import { styled } from '@mui/material/styles';
6
6
  import { useViews } from '../../hooks/useViews';
@@ -10,6 +10,7 @@ import { KeyboardDateInput } from '../KeyboardDateInput';
10
10
  import { useIsLandscape } from '../../hooks/useIsLandscape';
11
11
  import { WrapperVariantContext } from '../wrappers/WrapperVariantContext';
12
12
  import { PickerViewRoot } from '../PickerViewRoot';
13
+ import { useFocusManagement } from './useFocusManagement';
13
14
  import { jsx as _jsx } from "react/jsx-runtime";
14
15
  import { jsxs as _jsxs } from "react/jsx-runtime";
15
16
  export const MobileKeyboardInputView = styled('div')({
@@ -32,6 +33,8 @@ const isDatePickerView = view => view === 'year' || view === 'month' || view ===
32
33
  const isTimePickerView = view => view === 'hours' || view === 'minutes' || view === 'seconds';
33
34
 
34
35
  export function CalendarOrClockPicker(props) {
36
+ var _other$components, _other$componentsProp;
37
+
35
38
  const {
36
39
  autoFocus,
37
40
  parsedValue,
@@ -47,13 +50,18 @@ export function CalendarOrClockPicker(props) {
47
50
  toolbarFormat,
48
51
  toolbarPlaceholder,
49
52
  toolbarTitle,
50
- views
53
+ views,
54
+ dateRangeIcon,
55
+ timeIcon,
56
+ hideTabs
51
57
  } = props,
52
58
  other = _objectWithoutPropertiesLoose(props, _excluded);
53
59
 
60
+ const TabsComponent = (_other$components = other.components) == null ? void 0 : _other$components.Tabs;
54
61
  const isLandscape = useIsLandscape(views, orientation);
55
62
  const wrapperVariant = React.useContext(WrapperVariantContext);
56
63
  const toShowToolbar = showToolbar != null ? showToolbar : wrapperVariant !== 'desktop';
64
+ const showTabs = !hideTabs && typeof window !== 'undefined' && window.innerHeight > 667;
57
65
  const handleDateChange = React.useCallback((newDate, selectionState) => {
58
66
  onDateChange(newDate, wrapperVariant, selectionState);
59
67
  }, [onDateChange, wrapperVariant]);
@@ -77,6 +85,13 @@ export function CalendarOrClockPicker(props) {
77
85
  onChange: handleDateChange,
78
86
  onViewChange: handleViewChange
79
87
  });
88
+ const {
89
+ focusedView,
90
+ setFocusedView
91
+ } = useFocusManagement({
92
+ autoFocus,
93
+ openView
94
+ });
80
95
  return /*#__PURE__*/_jsxs(PickerRoot, {
81
96
  ownerState: {
82
97
  isLandscape
@@ -93,7 +108,12 @@ export function CalendarOrClockPicker(props) {
93
108
  toolbarPlaceholder: toolbarPlaceholder,
94
109
  isMobileKeyboardViewOpen: isMobileKeyboardViewOpen,
95
110
  toggleMobileKeyboardView: toggleMobileKeyboardView
96
- })), /*#__PURE__*/_jsx(PickerViewRoot, {
111
+ })), showTabs && !!TabsComponent && /*#__PURE__*/_jsx(TabsComponent, _extends({
112
+ dateRangeIcon: dateRangeIcon,
113
+ timeIcon: timeIcon,
114
+ view: openView,
115
+ onChange: setOpenView
116
+ }, (_other$componentsProp = other.componentsProps) == null ? void 0 : _other$componentsProp.tabs)), /*#__PURE__*/_jsx(PickerViewRoot, {
97
117
  children: isMobileKeyboardViewOpen ? /*#__PURE__*/_jsx(MobileKeyboardInputView, {
98
118
  children: /*#__PURE__*/_jsx(KeyboardDateInput, _extends({}, DateInputProps, {
99
119
  ignoreInvalidInputs: true,
@@ -108,7 +128,9 @@ export function CalendarOrClockPicker(props) {
108
128
  onChange: handleChangeAndOpenNext,
109
129
  view: openView // Unclear why the predicate `isDatePickerView` does not imply the casted type
110
130
  ,
111
- views: views.filter(isDatePickerView)
131
+ views: views.filter(isDatePickerView),
132
+ focusedView: focusedView,
133
+ onFocusedViewChange: setFocusedView
112
134
  }, other)), isTimePickerView(openView) && /*#__PURE__*/_jsx(ClockPicker, _extends({}, other, {
113
135
  autoFocus: autoFocus,
114
136
  date: parsedValue,
@@ -0,0 +1,10 @@
1
+ import { CalendarPickerView } from '../../models/views';
2
+ interface FocusStateInput {
3
+ autoFocus?: boolean;
4
+ openView: any;
5
+ }
6
+ export declare const useFocusManagement: ({ autoFocus, openView }: FocusStateInput) => {
7
+ focusedView: CalendarPickerView | null;
8
+ setFocusedView: (view: CalendarPickerView) => (newHasFocus: boolean) => void;
9
+ };
10
+ export {};
@@ -0,0 +1,18 @@
1
+ import * as React from 'react';
2
+ export const useFocusManagement = ({
3
+ autoFocus,
4
+ openView
5
+ }) => {
6
+ const [focusedView, setFocusedView] = React.useState(autoFocus ? openView : null);
7
+ const setFocusedViewCallback = React.useCallback(view => newHasFocus => {
8
+ if (newHasFocus) {
9
+ setFocusedView(view);
10
+ } else {
11
+ setFocusedView(prevFocusedView => view === prevFocusedView ? null : prevFocusedView);
12
+ }
13
+ }, []);
14
+ return {
15
+ focusedView,
16
+ setFocusedView: setFocusedViewCallback
17
+ };
18
+ };
@@ -1,8 +1,24 @@
1
1
  import * as React from 'react';
2
2
  export interface PickersArrowSwitcherSlotsComponent {
3
+ /**
4
+ * Button allowing to switch to the left view.
5
+ * @default IconButton
6
+ */
3
7
  LeftArrowButton: React.ElementType;
8
+ /**
9
+ * Icon displayed in the left view switch button.
10
+ * @default ArrowLeft
11
+ */
4
12
  LeftArrowIcon: React.ElementType;
13
+ /**
14
+ * Button allowing to switch to the right view.
15
+ * @default IconButton
16
+ */
5
17
  RightArrowButton: React.ElementType;
18
+ /**
19
+ * Icon displayed in the right view switch button.
20
+ * @default ArrowRight
21
+ */
6
22
  RightArrowIcon: React.ElementType;
7
23
  }
8
24
  export interface PickersArrowSwitcherSlotsComponentsProps {