@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
@@ -4,6 +4,7 @@ import * as React from 'react';
4
4
  import PropTypes from 'prop-types';
5
5
  import { useTheme, styled, useThemeProps } from '@mui/material/styles';
6
6
  import { unstable_composeClasses as composeClasses } from '@mui/material';
7
+ import { useControlled } from '@mui/material/utils';
7
8
  import clsx from 'clsx';
8
9
  import { PickersYear } from './PickersYear';
9
10
  import { useUtils, useNow, useDefaultDates } from '../internals/hooks/useUtils';
@@ -66,7 +67,10 @@ export var YearPicker = /*#__PURE__*/React.forwardRef(function YearPicker(inProp
66
67
  onChange = props.onChange,
67
68
  readOnly = props.readOnly,
68
69
  shouldDisableYear = props.shouldDisableYear,
69
- disableHighlightToday = props.disableHighlightToday;
70
+ disableHighlightToday = props.disableHighlightToday,
71
+ onYearFocus = props.onYearFocus,
72
+ hasFocus = props.hasFocus,
73
+ onFocusedViewChange = props.onFocusedViewChange;
70
74
  var ownerState = props;
71
75
  var classes = useUtilityClasses(ownerState);
72
76
  var selectedDateOrToday = date != null ? date : now;
@@ -84,11 +88,30 @@ export var YearPicker = /*#__PURE__*/React.forwardRef(function YearPicker(inProp
84
88
  var wrapperVariant = React.useContext(WrapperVariantContext);
85
89
  var selectedYearRef = React.useRef(null);
86
90
 
87
- var _React$useState = React.useState(currentYear),
91
+ var _React$useState = React.useState(function () {
92
+ return currentYear || utils.getYear(now);
93
+ }),
88
94
  _React$useState2 = _slicedToArray(_React$useState, 2),
89
95
  focusedYear = _React$useState2[0],
90
96
  setFocusedYear = _React$useState2[1];
91
97
 
98
+ var _useControlled = useControlled({
99
+ name: 'YearPicker',
100
+ state: 'hasFocus',
101
+ controlled: hasFocus,
102
+ default: autoFocus
103
+ }),
104
+ _useControlled2 = _slicedToArray(_useControlled, 2),
105
+ internalHasFocus = _useControlled2[0],
106
+ setInternalHasFocus = _useControlled2[1];
107
+
108
+ var changeHasFocus = React.useCallback(function (newHasFocus) {
109
+ setInternalHasFocus(newHasFocus);
110
+
111
+ if (onFocusedViewChange) {
112
+ onFocusedViewChange(newHasFocus);
113
+ }
114
+ }, [setInternalHasFocus, onFocusedViewChange]);
92
115
  var isYearDisabled = React.useCallback(function (dateToValidate) {
93
116
  if (disablePast && utils.isBeforeYear(dateToValidate, now)) {
94
117
  return true;
@@ -127,11 +150,17 @@ export var YearPicker = /*#__PURE__*/React.forwardRef(function YearPicker(inProp
127
150
  var focusYear = React.useCallback(function (year) {
128
151
  if (!isYearDisabled(utils.setYear(selectedDateOrToday, year))) {
129
152
  setFocusedYear(year);
153
+ changeHasFocus(true);
154
+ onYearFocus == null ? void 0 : onYearFocus(year);
130
155
  }
131
- }, [selectedDateOrToday, isYearDisabled, utils]);
156
+ }, [isYearDisabled, utils, selectedDateOrToday, changeHasFocus, onYearFocus]);
157
+ React.useEffect(function () {
158
+ setFocusedYear(function (prevFocusedYear) {
159
+ return currentYear !== null && prevFocusedYear !== currentYear ? currentYear : prevFocusedYear;
160
+ });
161
+ }, [currentYear]);
132
162
  var yearsInRow = wrapperVariant === 'desktop' ? 4 : 3;
133
-
134
- var handleKeyDown = function handleKeyDown(event, year) {
163
+ var handleKeyDown = React.useCallback(function (event, year) {
135
164
  switch (event.key) {
136
165
  case 'ArrowUp':
137
166
  focusYear(year - yearsInRow);
@@ -156,8 +185,15 @@ export var YearPicker = /*#__PURE__*/React.forwardRef(function YearPicker(inProp
156
185
  default:
157
186
  break;
158
187
  }
159
- };
160
-
188
+ }, [focusYear, theme.direction, yearsInRow]);
189
+ var handleFocus = React.useCallback(function (event, year) {
190
+ focusYear(year);
191
+ }, [focusYear]);
192
+ var handleBlur = React.useCallback(function (event, year) {
193
+ if (focusedYear === year) {
194
+ changeHasFocus(false);
195
+ }
196
+ }, [focusedYear, changeHasFocus]);
161
197
  var nowYear = utils.getYear(now);
162
198
  return /*#__PURE__*/_jsx(YearPickerRoot, {
163
199
  ref: ref,
@@ -171,9 +207,12 @@ export var YearPicker = /*#__PURE__*/React.forwardRef(function YearPicker(inProp
171
207
  value: yearNumber,
172
208
  onClick: handleYearSelection,
173
209
  onKeyDown: handleKeyDown,
174
- autoFocus: autoFocus && yearNumber === focusedYear,
210
+ autoFocus: internalHasFocus && yearNumber === focusedYear,
175
211
  ref: selected ? selectedYearRef : undefined,
176
212
  disabled: disabled || isYearDisabled(year),
213
+ tabIndex: yearNumber === focusedYear ? 0 : -1,
214
+ onFocus: handleFocus,
215
+ onBlur: handleBlur,
177
216
  "aria-current": nowYear === yearNumber ? 'date' : undefined,
178
217
  children: utils.format(year, 'year')
179
218
  }, utils.format(year, 'year'));
@@ -208,6 +247,7 @@ process.env.NODE_ENV !== "production" ? YearPicker.propTypes = {
208
247
  * @default false
209
248
  */
210
249
  disablePast: PropTypes.bool,
250
+ hasFocus: PropTypes.bool,
211
251
 
212
252
  /**
213
253
  * Maximal selectable date. @DateIOType
@@ -220,6 +260,8 @@ process.env.NODE_ENV !== "production" ? YearPicker.propTypes = {
220
260
  minDate: PropTypes.any,
221
261
  onChange: PropTypes.func.isRequired,
222
262
  onFocusedDayChange: PropTypes.func,
263
+ onFocusedViewChange: PropTypes.func,
264
+ onYearFocus: PropTypes.func,
223
265
  readOnly: PropTypes.bool,
224
266
 
225
267
  /**
package/legacy/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,6 +1,6 @@
1
1
  import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
2
2
  import _extends from "@babel/runtime/helpers/esm/extends";
3
- var _excluded = ["autoFocus", "className", "parsedValue", "DateInputProps", "isMobileKeyboardViewOpen", "onDateChange", "onViewChange", "openTo", "orientation", "showToolbar", "toggleMobileKeyboardView", "ToolbarComponent", "toolbarFormat", "toolbarPlaceholder", "toolbarTitle", "views"];
3
+ var _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 var MobileKeyboardInputView = styled('div')({
@@ -37,6 +38,8 @@ var isTimePickerView = function isTimePickerView(view) {
37
38
  };
38
39
 
39
40
  export function CalendarOrClockPicker(props) {
41
+ var _other$components, _other$componentsProp;
42
+
40
43
  var autoFocus = props.autoFocus,
41
44
  className = props.className,
42
45
  parsedValue = props.parsedValue,
@@ -56,11 +59,16 @@ export function CalendarOrClockPicker(props) {
56
59
  toolbarPlaceholder = props.toolbarPlaceholder,
57
60
  toolbarTitle = props.toolbarTitle,
58
61
  views = props.views,
62
+ dateRangeIcon = props.dateRangeIcon,
63
+ timeIcon = props.timeIcon,
64
+ hideTabs = props.hideTabs,
59
65
  other = _objectWithoutProperties(props, _excluded);
60
66
 
67
+ var TabsComponent = (_other$components = other.components) == null ? void 0 : _other$components.Tabs;
61
68
  var isLandscape = useIsLandscape(views, orientation);
62
69
  var wrapperVariant = React.useContext(WrapperVariantContext);
63
70
  var toShowToolbar = showToolbar != null ? showToolbar : wrapperVariant !== 'desktop';
71
+ var showTabs = !hideTabs && typeof window !== 'undefined' && window.innerHeight > 667;
64
72
  var handleDateChange = React.useCallback(function (newDate, selectionState) {
65
73
  onDateChange(newDate, wrapperVariant, selectionState);
66
74
  }, [onDateChange, wrapperVariant]);
@@ -85,6 +93,13 @@ export function CalendarOrClockPicker(props) {
85
93
  setOpenView = _useViews.setOpenView,
86
94
  handleChangeAndOpenNext = _useViews.handleChangeAndOpenNext;
87
95
 
96
+ var _useFocusManagement = useFocusManagement({
97
+ autoFocus: autoFocus,
98
+ openView: openView
99
+ }),
100
+ focusedView = _useFocusManagement.focusedView,
101
+ setFocusedView = _useFocusManagement.setFocusedView;
102
+
88
103
  return /*#__PURE__*/_jsxs(PickerRoot, {
89
104
  ownerState: {
90
105
  isLandscape: isLandscape
@@ -101,7 +116,12 @@ export function CalendarOrClockPicker(props) {
101
116
  toolbarPlaceholder: toolbarPlaceholder,
102
117
  isMobileKeyboardViewOpen: isMobileKeyboardViewOpen,
103
118
  toggleMobileKeyboardView: toggleMobileKeyboardView
104
- })), /*#__PURE__*/_jsx(PickerViewRoot, {
119
+ })), showTabs && !!TabsComponent && /*#__PURE__*/_jsx(TabsComponent, _extends({
120
+ dateRangeIcon: dateRangeIcon,
121
+ timeIcon: timeIcon,
122
+ view: openView,
123
+ onChange: setOpenView
124
+ }, (_other$componentsProp = other.componentsProps) == null ? void 0 : _other$componentsProp.tabs)), /*#__PURE__*/_jsx(PickerViewRoot, {
105
125
  children: isMobileKeyboardViewOpen ? /*#__PURE__*/_jsx(MobileKeyboardInputView, {
106
126
  children: /*#__PURE__*/_jsx(KeyboardDateInput, _extends({}, DateInputProps, {
107
127
  ignoreInvalidInputs: true,
@@ -116,7 +136,9 @@ export function CalendarOrClockPicker(props) {
116
136
  onChange: handleChangeAndOpenNext,
117
137
  view: openView // Unclear why the predicate `isDatePickerView` does not imply the casted type
118
138
  ,
119
- views: views.filter(isDatePickerView)
139
+ views: views.filter(isDatePickerView),
140
+ focusedView: focusedView,
141
+ onFocusedViewChange: setFocusedView
120
142
  }, other)), isTimePickerView(openView) && /*#__PURE__*/_jsx(ClockPicker, _extends({}, other, {
121
143
  autoFocus: autoFocus,
122
144
  date: parsedValue,
@@ -0,0 +1,27 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
+ import * as React from 'react';
3
+ export var useFocusManagement = function useFocusManagement(_ref) {
4
+ var autoFocus = _ref.autoFocus,
5
+ openView = _ref.openView;
6
+
7
+ var _React$useState = React.useState(autoFocus ? openView : null),
8
+ _React$useState2 = _slicedToArray(_React$useState, 2),
9
+ focusedView = _React$useState2[0],
10
+ setFocusedView = _React$useState2[1];
11
+
12
+ var setFocusedViewCallback = React.useCallback(function (view) {
13
+ return function (newHasFocus) {
14
+ if (newHasFocus) {
15
+ setFocusedView(view);
16
+ } else {
17
+ setFocusedView(function (prevFocusedView) {
18
+ return view === prevFocusedView ? null : prevFocusedView;
19
+ });
20
+ }
21
+ };
22
+ }, []);
23
+ return {
24
+ focusedView: focusedView,
25
+ setFocusedView: setFocusedViewCallback
26
+ };
27
+ };
@@ -44,7 +44,7 @@ export var PureDateInput = /*#__PURE__*/React.forwardRef(function PureDateInput(
44
44
  'aria-label': getOpenDialogAriaText(rawValue, utils),
45
45
  value: inputValue
46
46
  }, !props.readOnly && {
47
- onClick: onOpen
47
+ onMouseDown: onOpen
48
48
  }, {
49
49
  onKeyDown: onSpaceOrEnter(onOpen)
50
50
  })
@@ -1,7 +1,8 @@
1
+ import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
1
2
  import _extends from "@babel/runtime/helpers/esm/extends";
2
3
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
3
4
  import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
4
- var _excluded = ["value", "defaultValue", "onChange", "onError", "format", "readOnly"];
5
+ var _excluded = ["onClick", "onKeyDown", "onFocus", "onBlur"];
5
6
  import * as React from 'react';
6
7
  import useEnhancedEffect from '@mui/utils/useEnhancedEffect';
7
8
  import useEventCallback from '@mui/utils/useEventCallback';
@@ -10,23 +11,33 @@ import { useUtils } from '../useUtils';
10
11
  import { cleanTrailingZeroInNumericSectionValue, getMonthsMatchingQuery, getSectionValueNumericBoundaries, getSectionVisibleValue, adjustDateSectionValue, adjustInvalidDateSectionValue, setSectionValue } from './useField.utils';
11
12
  export var useField = function useField(params) {
12
13
  var utils = useUtils();
14
+
15
+ if (!utils.formatTokenMap) {
16
+ throw new Error('This adapter is not compatible with the field components');
17
+ }
18
+
13
19
  var inputRef = React.useRef(null);
14
20
 
15
- var _params$props = params.props,
16
- valueProp = _params$props.value,
17
- defaultValue = _params$props.defaultValue,
18
- onChange = _params$props.onChange,
19
- onError = _params$props.onError,
20
- _params$props$format = _params$props.format,
21
- format = _params$props$format === void 0 ? utils.formats.keyboardDate : _params$props$format,
22
- _params$props$readOnl = _params$props.readOnly,
23
- readOnly = _params$props$readOnl === void 0 ? false : _params$props$readOnl,
24
- otherProps = _objectWithoutProperties(_params$props, _excluded),
21
+ var _params$internalProps = params.internalProps,
22
+ valueProp = _params$internalProps.value,
23
+ defaultValue = _params$internalProps.defaultValue,
24
+ onChange = _params$internalProps.onChange,
25
+ _params$internalProps2 = _params$internalProps.format,
26
+ format = _params$internalProps2 === void 0 ? utils.formats.keyboardDate : _params$internalProps2,
27
+ _params$internalProps3 = _params$internalProps.readOnly,
28
+ readOnly = _params$internalProps3 === void 0 ? false : _params$internalProps3,
29
+ _params$forwardedProp = params.forwardedProps,
30
+ onClick = _params$forwardedProp.onClick,
31
+ onKeyDown = _params$forwardedProp.onKeyDown,
32
+ onFocus = _params$forwardedProp.onFocus,
33
+ onBlur = _params$forwardedProp.onBlur,
34
+ otherForwardedProps = _objectWithoutProperties(_params$forwardedProp, _excluded),
25
35
  valueManager = params.valueManager,
26
36
  fieldValueManager = params.fieldValueManager,
27
37
  validator = params.validator;
28
38
 
29
39
  var firstDefaultValue = React.useRef(defaultValue);
40
+ var focusTimeoutRef = React.useRef(undefined);
30
41
  var valueParsed = React.useMemo(function () {
31
42
  var _ref, _firstDefaultValue$cu;
32
43
 
@@ -79,6 +90,12 @@ export var useField = function useField(params) {
79
90
  };
80
91
 
81
92
  var handleInputClick = useEventCallback(function () {
93
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
94
+ args[_key] = arguments[_key];
95
+ }
96
+
97
+ onClick == null ? void 0 : onClick.apply(void 0, _toConsumableArray(args));
98
+
82
99
  if (state.sections.length === 0) {
83
100
  return;
84
101
  }
@@ -91,7 +108,33 @@ export var useField = function useField(params) {
91
108
  var sectionIndex = nextSectionIndex === -1 ? state.sections.length - 1 : nextSectionIndex - 1;
92
109
  updateSelectedSections(sectionIndex);
93
110
  });
111
+ var handleInputFocus = useEventCallback(function () {
112
+ for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
113
+ args[_key2] = arguments[_key2];
114
+ }
115
+
116
+ onFocus == null ? void 0 : onFocus.apply(void 0, _toConsumableArray(args));
117
+ focusTimeoutRef.current = setTimeout(function () {
118
+ var _inputRef$current$sel2, _inputRef$current2, _inputRef$current$sel3, _inputRef$current3;
119
+
120
+ if (((_inputRef$current$sel2 = (_inputRef$current2 = inputRef.current) == null ? void 0 : _inputRef$current2.selectionEnd) != null ? _inputRef$current$sel2 : 0) - ((_inputRef$current$sel3 = (_inputRef$current3 = inputRef.current) == null ? void 0 : _inputRef$current3.selectionStart) != null ? _inputRef$current$sel3 : 0) === 0) {
121
+ handleInputClick();
122
+ } else {
123
+ updateSelectedSections(0, state.sections.length - 1);
124
+ }
125
+ });
126
+ });
127
+ var handleInputBlur = useEventCallback(function () {
128
+ for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
129
+ args[_key3] = arguments[_key3];
130
+ }
131
+
132
+ onBlur == null ? void 0 : onBlur.apply(void 0, _toConsumableArray(args));
133
+ updateSelectedSections();
134
+ });
94
135
  var handleInputKeyDown = useEventCallback(function (event) {
136
+ onKeyDown == null ? void 0 : onKeyDown(event);
137
+
95
138
  if (!inputRef.current || state.sections.length === 0) {
96
139
  return;
97
140
  } // eslint-disable-next-line default-case
@@ -248,13 +291,6 @@ export var useField = function useField(params) {
248
291
  }
249
292
  }
250
293
  });
251
- var handleInputFocus = useEventCallback(function () {
252
- // TODO: Avoid applying focus when focus is caused by a click
253
- updateSelectedSections(0, state.sections.length - 1);
254
- });
255
- var handleInputBlur = useEventCallback(function () {
256
- return updateSelectedSections();
257
- });
258
294
  useEnhancedEffect(function () {
259
295
  if (!inputRef.current || state.selectedSectionIndexes == null) {
260
296
  return;
@@ -282,26 +318,28 @@ export var useField = function useField(params) {
282
318
  });
283
319
  }
284
320
  }, [valueParsed]); // eslint-disable-line react-hooks/exhaustive-deps
285
- // TODO: Support `isSameError`.
286
321
  // TODO: Make validation work with TDate instead of TInputDate
287
322
 
288
- var validationError = useValidation(_extends({}, params.props, {
323
+ var validationError = useValidation(_extends({}, params.internalProps, {
289
324
  value: state.valueParsed
290
- }), validator, function () {
291
- return true;
292
- });
325
+ }), validator, fieldValueManager.isSameError);
293
326
  var inputError = React.useMemo(function () {
294
327
  return fieldValueManager.hasError(validationError);
295
328
  }, [fieldValueManager, validationError]);
329
+ React.useEffect(function () {
330
+ return function () {
331
+ return window.clearTimeout(focusTimeoutRef.current);
332
+ };
333
+ }, []);
296
334
  return {
297
- inputProps: _extends({
335
+ inputProps: _extends({}, otherForwardedProps, {
298
336
  value: state.valueStr,
299
337
  onClick: handleInputClick,
300
- onKeyDown: handleInputKeyDown,
301
338
  onFocus: handleInputFocus,
302
339
  onBlur: handleInputBlur,
340
+ onKeyDown: handleInputKeyDown,
303
341
  error: inputError
304
- }, otherProps),
342
+ }),
305
343
  inputRef: inputRef
306
344
  };
307
345
  };
@@ -1,39 +1,14 @@
1
1
  import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
2
2
  import _extends from "@babel/runtime/helpers/esm/extends";
3
- import defaultLocale from 'date-fns/locale/en-US'; // @ts-ignore
4
-
5
- import longFormatters from 'date-fns/_lib/format/longFormatters';
6
3
  // TODO: Improve and test with different calendars (move to date-io ?)
7
- export var getDateSectionNameFromFormat = function getDateSectionNameFromFormat(format) {
8
- if (['MMMM', 'MM'].includes(format)) {
9
- return 'month';
10
- }
11
-
12
- if (['y', 'yy', 'yyy', 'yyyy'].includes(format)) {
13
- return 'year';
14
- }
15
-
16
- if (['dd'].includes(format)) {
17
- return 'day';
18
- }
19
-
20
- if (['h', 'H', 'hh', 'HH'].includes(format)) {
21
- return 'hour';
22
- }
23
-
24
- if (['mm'].includes(format)) {
25
- return 'minute';
26
- }
27
-
28
- if (['ss'].includes(format)) {
29
- return 'second';
30
- }
4
+ export var getDateSectionNameFromFormatToken = function getDateSectionNameFromFormatToken(utils, formatToken) {
5
+ var dateSectionName = utils.formatTokenMap[formatToken];
31
6
 
32
- if (['a', 'aa', 'aaa'].includes(format)) {
33
- return 'am-pm';
7
+ if (dateSectionName == null) {
8
+ throw new Error("getDatePartNameFromFormat doesn't understand the format ".concat(formatToken));
34
9
  }
35
10
 
36
- throw new Error("getDatePartNameFromFormat don't understand the format ".concat(format));
11
+ return dateSectionName;
37
12
  };
38
13
 
39
14
  var getDeltaFromKeyCode = function getDeltaFromKeyCode(keyCode) {
@@ -55,12 +30,12 @@ var getDeltaFromKeyCode = function getDeltaFromKeyCode(keyCode) {
55
30
  }
56
31
  };
57
32
 
58
- export var adjustDateSectionValue = function adjustDateSectionValue(utils, date, datePartName, keyCode) {
33
+ export var adjustDateSectionValue = function adjustDateSectionValue(utils, date, dateSectionName, keyCode) {
59
34
  var delta = getDeltaFromKeyCode(keyCode);
60
35
  var isStart = keyCode === 'Home';
61
36
  var isEnd = keyCode === 'End';
62
37
 
63
- switch (datePartName) {
38
+ switch (dateSectionName) {
64
39
  case 'day':
65
40
  {
66
41
  if (isStart) {
@@ -299,24 +274,11 @@ var formatDateWithPlaceholder = function formatDateWithPlaceholder(utils, date,
299
274
 
300
275
  export var splitFormatIntoSections = function splitFormatIntoSections(utils, format, date) {
301
276
  var currentTokenValue = '';
302
- var sections = []; // Copy pasted from the `getFormatHelperText` in the date-fns adapter
303
- // Would need to be turned into an adapter method
304
-
305
- var longFormatRegexp = /P+p+|P+|p+|''|'(''|[^'])+('|$)|./g;
306
- var locale = utils.locale || defaultLocale;
307
- var cleanFormat = format.match(longFormatRegexp).map(function (token) {
308
- var firstCharacter = token[0];
309
-
310
- if (firstCharacter === 'p' || firstCharacter === 'P') {
311
- var longFormatter = longFormatters[firstCharacter];
312
- return longFormatter(token, locale.formatLong, {});
313
- }
314
-
315
- return token;
316
- }).join('');
277
+ var sections = [];
278
+ var expandedFormat = utils.expandFormat(format);
317
279
 
318
- for (var i = 0; i < cleanFormat.length; i += 1) {
319
- var char = cleanFormat[i];
280
+ for (var i = 0; i < expandedFormat.length; i += 1) {
281
+ var char = expandedFormat[i];
320
282
 
321
283
  if (!char.match(/([A-zÀ-ú]+)/g)) {
322
284
  if (currentTokenValue === '') {
@@ -328,7 +290,7 @@ export var splitFormatIntoSections = function splitFormatIntoSections(utils, for
328
290
  sections[sections.length - 1].separator += currentTokenValue;
329
291
  currentTokenValue = '';
330
292
  } else {
331
- var dateSectionName = getDateSectionNameFromFormat(currentTokenValue);
293
+ var dateSectionName = getDateSectionNameFromFormatToken(utils, currentTokenValue);
332
294
  sections.push({
333
295
  formatValue: currentTokenValue,
334
296
  value: dateForCurrentToken,
@@ -344,13 +306,13 @@ export var splitFormatIntoSections = function splitFormatIntoSections(utils, for
344
306
  currentTokenValue += char;
345
307
  }
346
308
 
347
- if (i === cleanFormat.length - 1) {
309
+ if (i === expandedFormat.length - 1) {
348
310
  var _dateForCurrentToken = formatDateWithPlaceholder(utils, date, currentTokenValue);
349
311
 
350
312
  if (_dateForCurrentToken === currentTokenValue) {
351
313
  sections[sections.length - 1].separator += currentTokenValue;
352
314
  } else {
353
- var _dateSectionName = getDateSectionNameFromFormat(currentTokenValue);
315
+ var _dateSectionName = getDateSectionNameFromFormatToken(utils, currentTokenValue);
354
316
 
355
317
  sections.push({
356
318
  formatValue: currentTokenValue,
@@ -59,11 +59,9 @@ export var useIsDayDisabled = function useIsDayDisabled(_ref2) {
59
59
  }) !== null;
60
60
  }, [adapter, shouldDisableDate, minDate, maxDate, disableFuture, disablePast]);
61
61
  };
62
-
63
- var isSameDateError = function isSameDateError(a, b) {
62
+ export var isSameDateError = function isSameDateError(a, b) {
64
63
  return a === b;
65
64
  };
66
-
67
65
  export var useDateValidation = function useDateValidation(props) {
68
66
  return useValidation(props, validateDate, isSameDateError);
69
67
  };
@@ -7,7 +7,6 @@ export { PickersToolbar, pickersToolbarClasses } from './components/PickersToolb
7
7
  export { PickersToolbarButton } from './components/PickersToolbarButton';
8
8
  export { WrapperVariantContext } from './components/wrappers/WrapperVariantContext';
9
9
  export { DAY_MARGIN } from './constants/dimensions';
10
- export { useField, createDateStrFromSections, addPositionPropertiesToSections, splitFormatIntoSections } from './hooks/useField';
11
10
  export { useMaskedInput } from './hooks/useMaskedInput';
12
11
  export { usePickerState } from './hooks/usePickerState';
13
12
  export { useDefaultDates, useUtils, useLocaleText } from './hooks/useUtils';
@@ -0,0 +1,3 @@
1
+ // We don't add those exports to the regular `@mui/x-date-pickers/internals`,
2
+ // Because they rely on date-fns, which is not used by all applications.
3
+ export { useField, createDateStrFromSections, addPositionPropertiesToSections, splitFormatIntoSections } from '../internals/hooks/useField';
@@ -1 +1,51 @@
1
- export { default as AdapterDateFns } from '@date-io/date-fns';
1
+ import BaseAdapterDateFns from '@date-io/date-fns';
2
+ import defaultLocale from 'date-fns/locale/en-US'; // @ts-ignore
3
+
4
+ import longFormatters from 'date-fns/_lib/format/longFormatters';
5
+ const formatTokenMap = {
6
+ y: 'year',
7
+ yy: 'year',
8
+ yyy: 'year',
9
+ yyyy: 'year',
10
+ MMMM: 'month',
11
+ MM: 'month',
12
+ DD: 'day',
13
+ d: 'day',
14
+ dd: 'day',
15
+ H: 'hour',
16
+ HH: 'hour',
17
+ h: 'hour',
18
+ hh: 'hour',
19
+ mm: 'minute',
20
+ ss: 'second',
21
+ a: 'am-pm',
22
+ aa: 'am-pm',
23
+ aaa: 'am-pm'
24
+ };
25
+ export class AdapterDateFns extends BaseAdapterDateFns {
26
+ constructor(...args) {
27
+ super(...args);
28
+ this.formatTokenMap = formatTokenMap;
29
+
30
+ this.expandFormat = format => {
31
+ const longFormatRegexp = /P+p+|P+|p+|''|'(''|[^'])+('|$)|./g; // @see https://github.com/date-fns/date-fns/blob/master/src/format/index.js#L31
32
+
33
+ return format.match(longFormatRegexp).map(token => {
34
+ const firstCharacter = token[0];
35
+
36
+ if (firstCharacter === 'p' || firstCharacter === 'P') {
37
+ const longFormatter = longFormatters[firstCharacter];
38
+ const locale = this.locale || defaultLocale;
39
+ return longFormatter(token, locale.formatLong, {});
40
+ }
41
+
42
+ return token;
43
+ }).join('');
44
+ };
45
+
46
+ this.getFormatHelperText = format => {
47
+ return this.expandFormat(format).replace(/(aaa|aa|a)/g, '(a|p)m').toLocaleLowerCase();
48
+ };
49
+ }
50
+
51
+ }
@@ -1 +1,43 @@
1
- export { default as AdapterDayjs } from '@date-io/dayjs';
1
+ import BaseAdapterDayjs from '@date-io/dayjs';
2
+ const formatTokenMap = {
3
+ YY: 'year',
4
+ YYYY: 'year',
5
+ M: 'month',
6
+ MM: 'month',
7
+ MMM: 'month',
8
+ MMMM: 'month',
9
+ D: 'day',
10
+ DD: 'day',
11
+ H: 'hour',
12
+ HH: 'hour',
13
+ h: 'hour',
14
+ hh: 'hour',
15
+ m: 'minute',
16
+ mm: 'minute',
17
+ s: 'second',
18
+ ss: 'second',
19
+ A: 'am-pm',
20
+ a: 'am-pm'
21
+ };
22
+ export class AdapterDayjs extends BaseAdapterDayjs {
23
+ constructor(...args) {
24
+ super(...args);
25
+ this.formatTokenMap = formatTokenMap;
26
+
27
+ this.expandFormat = format => {
28
+ const localeFormats = this.rawDayJsInstance.Ls[this.locale || 'en']?.formats; // @see https://github.com/iamkun/dayjs/blob/dev/src/plugin/localizedFormat/index.js
29
+
30
+ const t = formatBis => formatBis.replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g, (_, a, b) => a || b.slice(1));
31
+
32
+ return format.replace(/(\[[^\]]+])|(LTS?|l{1,4}|L{1,4})/g, (_, a, b) => {
33
+ const B = b && b.toUpperCase();
34
+ return a || localeFormats[b] || t(localeFormats[B]);
35
+ });
36
+ };
37
+
38
+ this.getFormatHelperText = format => {
39
+ return this.expandFormat(format).replace(/a/gi, '(a|p)m').toLocaleLowerCase();
40
+ };
41
+ }
42
+
43
+ }