@mui/x-date-pickers 7.0.0-alpha.6 → 7.0.0-alpha.7

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 (41) hide show
  1. package/CHANGELOG.md +185 -3
  2. package/DateCalendar/DateCalendar.js +6 -4
  3. package/DateCalendar/DateCalendar.types.d.ts +0 -8
  4. package/DigitalClock/DigitalClock.js +3 -2
  5. package/MultiSectionDigitalClock/MultiSectionDigitalClock.js +9 -13
  6. package/MultiSectionDigitalClock/MultiSectionDigitalClockSection.js +4 -8
  7. package/TimeClock/TimeClock.js +3 -2
  8. package/index.js +1 -1
  9. package/internals/components/PickersInput/PickersFilledInput.js +2 -2
  10. package/internals/components/PickersInput/PickersStandardInput.js +2 -2
  11. package/internals/hooks/useViews.d.ts +4 -4
  12. package/internals/hooks/useViews.js +13 -13
  13. package/internals/models/props/clock.d.ts +0 -9
  14. package/legacy/DateCalendar/DateCalendar.js +6 -4
  15. package/legacy/DigitalClock/DigitalClock.js +3 -2
  16. package/legacy/MultiSectionDigitalClock/MultiSectionDigitalClock.js +9 -13
  17. package/legacy/MultiSectionDigitalClock/MultiSectionDigitalClockSection.js +4 -8
  18. package/legacy/TimeClock/TimeClock.js +3 -2
  19. package/legacy/index.js +1 -1
  20. package/legacy/internals/components/PickersInput/PickersFilledInput.js +2 -2
  21. package/legacy/internals/components/PickersInput/PickersStandardInput.js +2 -2
  22. package/legacy/internals/hooks/useViews.js +13 -13
  23. package/modern/DateCalendar/DateCalendar.js +6 -4
  24. package/modern/DigitalClock/DigitalClock.js +3 -2
  25. package/modern/MultiSectionDigitalClock/MultiSectionDigitalClock.js +9 -13
  26. package/modern/MultiSectionDigitalClock/MultiSectionDigitalClockSection.js +4 -8
  27. package/modern/TimeClock/TimeClock.js +3 -2
  28. package/modern/index.js +1 -1
  29. package/modern/internals/components/PickersInput/PickersFilledInput.js +2 -2
  30. package/modern/internals/components/PickersInput/PickersStandardInput.js +2 -2
  31. package/modern/internals/hooks/useViews.js +13 -13
  32. package/node/DateCalendar/DateCalendar.js +6 -4
  33. package/node/DigitalClock/DigitalClock.js +3 -2
  34. package/node/MultiSectionDigitalClock/MultiSectionDigitalClock.js +9 -13
  35. package/node/MultiSectionDigitalClock/MultiSectionDigitalClockSection.js +4 -8
  36. package/node/TimeClock/TimeClock.js +3 -2
  37. package/node/index.js +1 -1
  38. package/node/internals/components/PickersInput/PickersFilledInput.js +2 -2
  39. package/node/internals/components/PickersInput/PickersStandardInput.js +2 -2
  40. package/node/internals/hooks/useViews.js +13 -13
  41. package/package.json +5 -5
@@ -140,10 +140,10 @@ export var MultiSectionDigitalClock = /*#__PURE__*/React.forwardRef(function Mul
140
140
  onFocusedViewChange: onFocusedViewChange
141
141
  }),
142
142
  view = _useViews.view,
143
- setValueAndGoToView = _useViews.setValueAndGoToView,
143
+ setValueAndGoToNextView = _useViews.setValueAndGoToNextView,
144
144
  focusedView = _useViews.focusedView;
145
145
  var handleMeridiemValueChange = useEventCallback(function (newValue) {
146
- setValueAndGoToView(newValue, null, 'meridiem');
146
+ setValueAndGoToNextView(newValue, 'finish', 'meridiem');
147
147
  });
148
148
  var _useMeridiemMode = useMeridiemMode(valueOrReferenceDate, ampm, handleMeridiemValueChange, 'finish'),
149
149
  meridiemMode = _useMeridiemMode.meridiemMode,
@@ -223,11 +223,6 @@ export var MultiSectionDigitalClock = /*#__PURE__*/React.forwardRef(function Mul
223
223
  throw new Error('not supported');
224
224
  }
225
225
  }, [ampm, valueOrReferenceDate, disableIgnoringDatePartForTimeValidation, maxTime, meridiemMode, minTime, minutesStep, shouldDisableTime, utils, disableFuture, disablePast, now, views]);
226
- var handleSectionChange = useEventCallback(function (sectionView, newValue) {
227
- var viewIndex = views.indexOf(sectionView);
228
- var nextView = views[viewIndex + 1];
229
- setValueAndGoToView(newValue, nextView, sectionView);
230
- });
231
226
  var buildViewProps = React.useCallback(function (viewToBuild) {
232
227
  switch (viewToBuild) {
233
228
  case 'hours':
@@ -235,7 +230,7 @@ export var MultiSectionDigitalClock = /*#__PURE__*/React.forwardRef(function Mul
235
230
  return {
236
231
  onChange: function onChange(hours) {
237
232
  var valueWithMeridiem = convertValueToMeridiem(hours, meridiemMode, ampm);
238
- handleSectionChange('hours', utils.setHours(valueOrReferenceDate, valueWithMeridiem));
233
+ setValueAndGoToNextView(utils.setHours(valueOrReferenceDate, valueWithMeridiem), 'finish', 'hours');
239
234
  },
240
235
  items: getHourSectionOptions({
241
236
  now: now,
@@ -255,7 +250,7 @@ export var MultiSectionDigitalClock = /*#__PURE__*/React.forwardRef(function Mul
255
250
  {
256
251
  return {
257
252
  onChange: function onChange(minutes) {
258
- handleSectionChange('minutes', utils.setMinutes(valueOrReferenceDate, minutes));
253
+ setValueAndGoToNextView(utils.setMinutes(valueOrReferenceDate, minutes), 'finish', 'minutes');
259
254
  },
260
255
  items: getTimeSectionOptions({
261
256
  value: utils.getMinutes(valueOrReferenceDate),
@@ -276,7 +271,7 @@ export var MultiSectionDigitalClock = /*#__PURE__*/React.forwardRef(function Mul
276
271
  {
277
272
  return {
278
273
  onChange: function onChange(seconds) {
279
- handleSectionChange('seconds', utils.setSeconds(valueOrReferenceDate, seconds));
274
+ setValueAndGoToNextView(utils.setSeconds(valueOrReferenceDate, seconds), 'finish', 'seconds');
280
275
  },
281
276
  items: getTimeSectionOptions({
282
277
  value: utils.getSeconds(valueOrReferenceDate),
@@ -325,7 +320,7 @@ export var MultiSectionDigitalClock = /*#__PURE__*/React.forwardRef(function Mul
325
320
  default:
326
321
  throw new Error("Unknown view: ".concat(viewToBuild, " found."));
327
322
  }
328
- }, [now, value, ampm, utils, timeSteps.hours, timeSteps.minutes, timeSteps.seconds, localeText.hoursClockNumberText, localeText.minutesClockNumberText, localeText.secondsClockNumberText, meridiemMode, handleSectionChange, valueOrReferenceDate, disabled, isTimeDisabled, handleMeridiemChange]);
323
+ }, [now, value, ampm, utils, timeSteps.hours, timeSteps.minutes, timeSteps.seconds, localeText.hoursClockNumberText, localeText.minutesClockNumberText, localeText.secondsClockNumberText, meridiemMode, setValueAndGoToNextView, valueOrReferenceDate, disabled, isTimeDisabled, handleMeridiemChange]);
329
324
  var viewTimeOptions = React.useMemo(function () {
330
325
  return views.reduce(function (result, currentView) {
331
326
  return _extends({}, result, _defineProperty({}, currentView, buildViewProps(currentView)));
@@ -426,8 +421,9 @@ process.env.NODE_ENV !== "production" ? MultiSectionDigitalClock.propTypes = {
426
421
  minutesStep: PropTypes.number,
427
422
  /**
428
423
  * Callback fired when the value changes.
429
- * @template TDate, TView
430
- * @param {TDate | null} value The new value.
424
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
425
+ * @template TView The view type. Will be one of date or time views.
426
+ * @param {TValue} value The new value.
431
427
  * @param {PickerSelectionState | undefined} selectionState Indicates if the date selection is complete.
432
428
  * @param {TView | undefined} selectedView Indicates the view in which the selection has been made.
433
429
  */
@@ -47,7 +47,7 @@ var MultiSectionDigitalClockSectionRoot = styled(MenuList, {
47
47
  '&:not(:first-of-type)': {
48
48
  borderLeft: "1px solid ".concat((theme.vars || theme).palette.divider)
49
49
  },
50
- '&:after': {
50
+ '&::after': {
51
51
  display: 'block',
52
52
  content: '""',
53
53
  // subtracting the height of one item, extra margin and borders to make sure the max height is correct
@@ -121,17 +121,13 @@ export var MultiSectionDigitalClockSection = /*#__PURE__*/React.forwardRef(funct
121
121
  return;
122
122
  }
123
123
  var activeItem = containerRef.current.querySelector('[role="option"][tabindex="0"], [role="option"][aria-selected="true"]');
124
+ if (active && autoFocus && activeItem) {
125
+ activeItem.focus();
126
+ }
124
127
  if (!activeItem || previousActive.current === activeItem) {
125
- // Handle setting the ref to null if the selected item is ever reset via UI
126
- if (previousActive.current !== activeItem) {
127
- previousActive.current = activeItem;
128
- }
129
128
  return;
130
129
  }
131
130
  previousActive.current = activeItem;
132
- if (active && autoFocus) {
133
- activeItem.focus();
134
- }
135
131
  var offsetTop = activeItem.offsetTop;
136
132
 
137
133
  // Subtracting the 4px of extra margin intended for the first visible section item
@@ -395,8 +395,9 @@ process.env.NODE_ENV !== "production" ? TimeClock.propTypes = {
395
395
  minutesStep: PropTypes.number,
396
396
  /**
397
397
  * Callback fired when the value changes.
398
- * @template TDate, TView
399
- * @param {TDate | null} value The new value.
398
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
399
+ * @template TView The view type. Will be one of date or time views.
400
+ * @param {TValue} value The new value.
400
401
  * @param {PickerSelectionState | undefined} selectionState Indicates if the date selection is complete.
401
402
  * @param {TView | undefined} selectedView Indicates the view in which the selection has been made.
402
403
  */
package/legacy/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-date-pickers v7.0.0-alpha.6
2
+ * @mui/x-date-pickers v7.0.0-alpha.7
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -44,7 +44,7 @@ var FilledInputRoot = styled(PickersInputRoot, {
44
44
  }), "&.".concat(pickersFilledInputClasses.disabled), {
45
45
  backgroundColor: theme.vars ? theme.vars.palette.FilledInput.disabledBg : disabledBackground
46
46
  }), !ownerState.disableUnderline && _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({
47
- '&:after': {
47
+ '&::after': {
48
48
  borderBottom: "2px solid ".concat((_palette = (theme.vars || theme).palette[ownerState.color || 'primary']) == null ? void 0 : _palette.main),
49
49
  left: 0,
50
50
  bottom: 0,
@@ -67,7 +67,7 @@ var FilledInputRoot = styled(PickersInputRoot, {
67
67
  '&:before, &:after': {
68
68
  borderBottomColor: (theme.vars || theme).palette.error.main
69
69
  }
70
- }), '&:before', {
70
+ }), '&::before', {
71
71
  borderBottom: "1px solid ".concat(theme.vars ? "rgba(".concat(theme.vars.palette.common.onBackgroundChannel, " / ").concat(theme.vars.opacity.inputUnderline, ")") : bottomLineColor),
72
72
  left: 0,
73
73
  bottom: 0,
@@ -28,7 +28,7 @@ var StandardInputRoot = styled(PickersInputRoot, {
28
28
  marginTop: 16
29
29
  }
30
30
  }, !ownerState.disableUnderline && _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({
31
- '&:after': {
31
+ '&::after': {
32
32
  background: 'red',
33
33
  borderBottom: "2px solid ".concat((theme.vars || theme).palette[ownerState.color].main),
34
34
  left: 0,
@@ -52,7 +52,7 @@ var StandardInputRoot = styled(PickersInputRoot, {
52
52
  '&:before, &:after': {
53
53
  borderBottomColor: (theme.vars || theme).palette.error.main
54
54
  }
55
- }), '&:before', {
55
+ }), '&::before', {
56
56
  borderBottom: "1px solid ".concat(bottomLineColor),
57
57
  left: 0,
58
58
  bottom: 0,
@@ -74,11 +74,12 @@ export function useViews(_ref) {
74
74
  onFocusedViewChange == null || onFocusedViewChange(viewToFocus, hasFocus);
75
75
  });
76
76
  var handleChangeView = useEventCallback(function (newView) {
77
+ // always keep the focused view in sync
78
+ handleFocusedViewChange(newView, true);
77
79
  if (newView === view) {
78
80
  return;
79
81
  }
80
82
  setView(newView);
81
- handleFocusedViewChange(newView, true);
82
83
  if (onViewChange) {
83
84
  onViewChange(newView);
84
85
  }
@@ -87,7 +88,6 @@ export function useViews(_ref) {
87
88
  if (nextView) {
88
89
  handleChangeView(nextView);
89
90
  }
90
- handleFocusedViewChange(nextView, true);
91
91
  });
92
92
  var setValueAndGoToNextView = useEventCallback(function (value, currentViewSelectionState, selectedView) {
93
93
  var isSelectionFinishedOnCurrentView = currentViewSelectionState === 'finish';
@@ -96,18 +96,19 @@ export function useViews(_ref) {
96
96
  // but when it's not the final view given all `views` -> overall selection state should be `partial`.
97
97
  views.indexOf(selectedView) < views.length - 1 : Boolean(nextView);
98
98
  var globalSelectionState = isSelectionFinishedOnCurrentView && hasMoreViews ? 'partial' : currentViewSelectionState;
99
- onChange(value, globalSelectionState);
100
- if (isSelectionFinishedOnCurrentView) {
99
+ onChange(value, globalSelectionState, selectedView);
100
+ // Detects if the selected view is not the active one.
101
+ // Can happen if multiple views are displayed, like in `DesktopDateTimePicker` or `MultiSectionDigitalClock`.
102
+ if (selectedView && selectedView !== view) {
103
+ var nextViewAfterSelected = views[views.indexOf(selectedView) + 1];
104
+ if (nextViewAfterSelected) {
105
+ // move to next view after the selected one
106
+ handleChangeView(nextViewAfterSelected);
107
+ }
108
+ } else if (isSelectionFinishedOnCurrentView) {
101
109
  goToNextView();
102
110
  }
103
111
  });
104
- var setValueAndGoToView = useEventCallback(function (value, newView, selectedView) {
105
- onChange(value, newView ? 'partial' : 'finish', selectedView);
106
- if (newView) {
107
- handleChangeView(newView);
108
- handleFocusedViewChange(newView, true);
109
- }
110
- });
111
112
  return {
112
113
  view: view,
113
114
  setView: handleChangeView,
@@ -118,7 +119,6 @@ export function useViews(_ref) {
118
119
  // Always return up-to-date default view instead of the initial one (i.e. defaultView.current)
119
120
  defaultView: views.includes(openTo) ? openTo : views[0],
120
121
  goToNextView: goToNextView,
121
- setValueAndGoToNextView: setValueAndGoToNextView,
122
- setValueAndGoToView: setValueAndGoToView
122
+ setValueAndGoToNextView: setValueAndGoToNextView
123
123
  };
124
124
  }
@@ -252,9 +252,9 @@ export const DateCalendar = /*#__PURE__*/React.forwardRef(function DateCalendar(
252
252
  const handleSelectedDayChange = useEventCallback(day => {
253
253
  if (day) {
254
254
  // If there is a date already selected, then we want to keep its time
255
- return handleValueChange(mergeDateAndTime(utils, day, value ?? referenceDate), 'finish');
255
+ return handleValueChange(mergeDateAndTime(utils, day, value ?? referenceDate), 'finish', view);
256
256
  }
257
- return handleValueChange(day, 'finish');
257
+ return handleValueChange(day, 'finish', view);
258
258
  });
259
259
  React.useEffect(() => {
260
260
  if (value != null && utils.isValid(value)) {
@@ -423,9 +423,11 @@ process.env.NODE_ENV !== "production" ? DateCalendar.propTypes = {
423
423
  monthsPerRow: PropTypes.oneOf([3, 4]),
424
424
  /**
425
425
  * Callback fired when the value changes.
426
- * @template TDate
427
- * @param {TDate | null} value The new value.
426
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
427
+ * @template TView The view type. Will be one of date or time views.
428
+ * @param {TValue} value The new value.
428
429
  * @param {PickerSelectionState | undefined} selectionState Indicates if the date selection is complete.
430
+ * @param {TView | undefined} selectedView Indicates the view in which the selection has been made.
429
431
  */
430
432
  onChange: PropTypes.func,
431
433
  /**
@@ -327,8 +327,9 @@ process.env.NODE_ENV !== "production" ? DigitalClock.propTypes = {
327
327
  minutesStep: PropTypes.number,
328
328
  /**
329
329
  * Callback fired when the value changes.
330
- * @template TDate, TView
331
- * @param {TDate | null} value The new value.
330
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
331
+ * @template TView The view type. Will be one of date or time views.
332
+ * @param {TValue} value The new value.
332
333
  * @param {PickerSelectionState | undefined} selectionState Indicates if the date selection is complete.
333
334
  * @param {TView | undefined} selectedView Indicates the view in which the selection has been made.
334
335
  */
@@ -122,7 +122,7 @@ export const MultiSectionDigitalClock = /*#__PURE__*/React.forwardRef(function M
122
122
  }, [ampm, inViews]);
123
123
  const {
124
124
  view,
125
- setValueAndGoToView,
125
+ setValueAndGoToNextView,
126
126
  focusedView
127
127
  } = useViews({
128
128
  view: inView,
@@ -134,7 +134,7 @@ export const MultiSectionDigitalClock = /*#__PURE__*/React.forwardRef(function M
134
134
  onFocusedViewChange
135
135
  });
136
136
  const handleMeridiemValueChange = useEventCallback(newValue => {
137
- setValueAndGoToView(newValue, null, 'meridiem');
137
+ setValueAndGoToNextView(newValue, 'finish', 'meridiem');
138
138
  });
139
139
  const {
140
140
  meridiemMode,
@@ -215,11 +215,6 @@ export const MultiSectionDigitalClock = /*#__PURE__*/React.forwardRef(function M
215
215
  throw new Error('not supported');
216
216
  }
217
217
  }, [ampm, valueOrReferenceDate, disableIgnoringDatePartForTimeValidation, maxTime, meridiemMode, minTime, minutesStep, shouldDisableTime, utils, disableFuture, disablePast, now, views]);
218
- const handleSectionChange = useEventCallback((sectionView, newValue) => {
219
- const viewIndex = views.indexOf(sectionView);
220
- const nextView = views[viewIndex + 1];
221
- setValueAndGoToView(newValue, nextView, sectionView);
222
- });
223
218
  const buildViewProps = React.useCallback(viewToBuild => {
224
219
  switch (viewToBuild) {
225
220
  case 'hours':
@@ -227,7 +222,7 @@ export const MultiSectionDigitalClock = /*#__PURE__*/React.forwardRef(function M
227
222
  return {
228
223
  onChange: hours => {
229
224
  const valueWithMeridiem = convertValueToMeridiem(hours, meridiemMode, ampm);
230
- handleSectionChange('hours', utils.setHours(valueOrReferenceDate, valueWithMeridiem));
225
+ setValueAndGoToNextView(utils.setHours(valueOrReferenceDate, valueWithMeridiem), 'finish', 'hours');
231
226
  },
232
227
  items: getHourSectionOptions({
233
228
  now,
@@ -245,7 +240,7 @@ export const MultiSectionDigitalClock = /*#__PURE__*/React.forwardRef(function M
245
240
  {
246
241
  return {
247
242
  onChange: minutes => {
248
- handleSectionChange('minutes', utils.setMinutes(valueOrReferenceDate, minutes));
243
+ setValueAndGoToNextView(utils.setMinutes(valueOrReferenceDate, minutes), 'finish', 'minutes');
249
244
  },
250
245
  items: getTimeSectionOptions({
251
246
  value: utils.getMinutes(valueOrReferenceDate),
@@ -262,7 +257,7 @@ export const MultiSectionDigitalClock = /*#__PURE__*/React.forwardRef(function M
262
257
  {
263
258
  return {
264
259
  onChange: seconds => {
265
- handleSectionChange('seconds', utils.setSeconds(valueOrReferenceDate, seconds));
260
+ setValueAndGoToNextView(utils.setSeconds(valueOrReferenceDate, seconds), 'finish', 'seconds');
266
261
  },
267
262
  items: getTimeSectionOptions({
268
263
  value: utils.getSeconds(valueOrReferenceDate),
@@ -299,7 +294,7 @@ export const MultiSectionDigitalClock = /*#__PURE__*/React.forwardRef(function M
299
294
  default:
300
295
  throw new Error(`Unknown view: ${viewToBuild} found.`);
301
296
  }
302
- }, [now, value, ampm, utils, timeSteps.hours, timeSteps.minutes, timeSteps.seconds, localeText.hoursClockNumberText, localeText.minutesClockNumberText, localeText.secondsClockNumberText, meridiemMode, handleSectionChange, valueOrReferenceDate, disabled, isTimeDisabled, handleMeridiemChange]);
297
+ }, [now, value, ampm, utils, timeSteps.hours, timeSteps.minutes, timeSteps.seconds, localeText.hoursClockNumberText, localeText.minutesClockNumberText, localeText.secondsClockNumberText, meridiemMode, setValueAndGoToNextView, valueOrReferenceDate, disabled, isTimeDisabled, handleMeridiemChange]);
303
298
  const viewTimeOptions = React.useMemo(() => {
304
299
  return views.reduce((result, currentView) => {
305
300
  return _extends({}, result, {
@@ -397,8 +392,9 @@ process.env.NODE_ENV !== "production" ? MultiSectionDigitalClock.propTypes = {
397
392
  minutesStep: PropTypes.number,
398
393
  /**
399
394
  * Callback fired when the value changes.
400
- * @template TDate, TView
401
- * @param {TDate | null} value The new value.
395
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
396
+ * @template TView The view type. Will be one of date or time views.
397
+ * @param {TValue} value The new value.
402
398
  * @param {PickerSelectionState | undefined} selectionState Indicates if the date selection is complete.
403
399
  * @param {TView | undefined} selectedView Indicates the view in which the selection has been made.
404
400
  */
@@ -47,7 +47,7 @@ const MultiSectionDigitalClockSectionRoot = styled(MenuList, {
47
47
  '&:not(:first-of-type)': {
48
48
  borderLeft: `1px solid ${(theme.vars || theme).palette.divider}`
49
49
  },
50
- '&:after': {
50
+ '&::after': {
51
51
  display: 'block',
52
52
  content: '""',
53
53
  // subtracting the height of one item, extra margin and borders to make sure the max height is correct
@@ -116,17 +116,13 @@ export const MultiSectionDigitalClockSection = /*#__PURE__*/React.forwardRef(fun
116
116
  return;
117
117
  }
118
118
  const activeItem = containerRef.current.querySelector('[role="option"][tabindex="0"], [role="option"][aria-selected="true"]');
119
+ if (active && autoFocus && activeItem) {
120
+ activeItem.focus();
121
+ }
119
122
  if (!activeItem || previousActive.current === activeItem) {
120
- // Handle setting the ref to null if the selected item is ever reset via UI
121
- if (previousActive.current !== activeItem) {
122
- previousActive.current = activeItem;
123
- }
124
123
  return;
125
124
  }
126
125
  previousActive.current = activeItem;
127
- if (active && autoFocus) {
128
- activeItem.focus();
129
- }
130
126
  const offsetTop = activeItem.offsetTop;
131
127
 
132
128
  // Subtracting the 4px of extra margin intended for the first visible section item
@@ -383,8 +383,9 @@ process.env.NODE_ENV !== "production" ? TimeClock.propTypes = {
383
383
  minutesStep: PropTypes.number,
384
384
  /**
385
385
  * Callback fired when the value changes.
386
- * @template TDate, TView
387
- * @param {TDate | null} value The new value.
386
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
387
+ * @template TView The view type. Will be one of date or time views.
388
+ * @param {TValue} value The new value.
388
389
  * @param {PickerSelectionState | undefined} selectionState Indicates if the date selection is complete.
389
390
  * @param {TView | undefined} selectedView Indicates the view in which the selection has been made.
390
391
  */
package/modern/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-date-pickers v7.0.0-alpha.6
2
+ * @mui/x-date-pickers v7.0.0-alpha.7
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -43,7 +43,7 @@ const FilledInputRoot = styled(PickersInputRoot, {
43
43
  backgroundColor: theme.vars ? theme.vars.palette.FilledInput.disabledBg : disabledBackground
44
44
  }
45
45
  }, !ownerState.disableUnderline && {
46
- '&:after': {
46
+ '&::after': {
47
47
  borderBottom: `2px solid ${(theme.vars || theme).palette[ownerState.color || 'primary']?.main}`,
48
48
  left: 0,
49
49
  bottom: 0,
@@ -68,7 +68,7 @@ const FilledInputRoot = styled(PickersInputRoot, {
68
68
  borderBottomColor: (theme.vars || theme).palette.error.main
69
69
  }
70
70
  },
71
- '&:before': {
71
+ '&::before': {
72
72
  borderBottom: `1px solid ${theme.vars ? `rgba(${theme.vars.palette.common.onBackgroundChannel} / ${theme.vars.opacity.inputUnderline})` : bottomLineColor}`,
73
73
  left: 0,
74
74
  bottom: 0,
@@ -26,7 +26,7 @@ const StandardInputRoot = styled(PickersInputRoot, {
26
26
  marginTop: 16
27
27
  }
28
28
  }, !ownerState.disableUnderline && {
29
- '&:after': {
29
+ '&::after': {
30
30
  background: 'red',
31
31
  borderBottom: `2px solid ${(theme.vars || theme).palette[ownerState.color].main}`,
32
32
  left: 0,
@@ -52,7 +52,7 @@ const StandardInputRoot = styled(PickersInputRoot, {
52
52
  borderBottomColor: (theme.vars || theme).palette.error.main
53
53
  }
54
54
  },
55
- '&:before': {
55
+ '&::before': {
56
56
  borderBottom: `1px solid ${bottomLineColor}`,
57
57
  left: 0,
58
58
  bottom: 0,
@@ -63,11 +63,12 @@ export function useViews({
63
63
  onFocusedViewChange?.(viewToFocus, hasFocus);
64
64
  });
65
65
  const handleChangeView = useEventCallback(newView => {
66
+ // always keep the focused view in sync
67
+ handleFocusedViewChange(newView, true);
66
68
  if (newView === view) {
67
69
  return;
68
70
  }
69
71
  setView(newView);
70
- handleFocusedViewChange(newView, true);
71
72
  if (onViewChange) {
72
73
  onViewChange(newView);
73
74
  }
@@ -76,7 +77,6 @@ export function useViews({
76
77
  if (nextView) {
77
78
  handleChangeView(nextView);
78
79
  }
79
- handleFocusedViewChange(nextView, true);
80
80
  });
81
81
  const setValueAndGoToNextView = useEventCallback((value, currentViewSelectionState, selectedView) => {
82
82
  const isSelectionFinishedOnCurrentView = currentViewSelectionState === 'finish';
@@ -85,18 +85,19 @@ export function useViews({
85
85
  // but when it's not the final view given all `views` -> overall selection state should be `partial`.
86
86
  views.indexOf(selectedView) < views.length - 1 : Boolean(nextView);
87
87
  const globalSelectionState = isSelectionFinishedOnCurrentView && hasMoreViews ? 'partial' : currentViewSelectionState;
88
- onChange(value, globalSelectionState);
89
- if (isSelectionFinishedOnCurrentView) {
88
+ onChange(value, globalSelectionState, selectedView);
89
+ // Detects if the selected view is not the active one.
90
+ // Can happen if multiple views are displayed, like in `DesktopDateTimePicker` or `MultiSectionDigitalClock`.
91
+ if (selectedView && selectedView !== view) {
92
+ const nextViewAfterSelected = views[views.indexOf(selectedView) + 1];
93
+ if (nextViewAfterSelected) {
94
+ // move to next view after the selected one
95
+ handleChangeView(nextViewAfterSelected);
96
+ }
97
+ } else if (isSelectionFinishedOnCurrentView) {
90
98
  goToNextView();
91
99
  }
92
100
  });
93
- const setValueAndGoToView = useEventCallback((value, newView, selectedView) => {
94
- onChange(value, newView ? 'partial' : 'finish', selectedView);
95
- if (newView) {
96
- handleChangeView(newView);
97
- handleFocusedViewChange(newView, true);
98
- }
99
- });
100
101
  return {
101
102
  view,
102
103
  setView: handleChangeView,
@@ -107,7 +108,6 @@ export function useViews({
107
108
  // Always return up-to-date default view instead of the initial one (i.e. defaultView.current)
108
109
  defaultView: views.includes(openTo) ? openTo : views[0],
109
110
  goToNextView,
110
- setValueAndGoToNextView,
111
- setValueAndGoToView
111
+ setValueAndGoToNextView
112
112
  };
113
113
  }
@@ -260,9 +260,9 @@ const DateCalendar = exports.DateCalendar = /*#__PURE__*/React.forwardRef(functi
260
260
  const handleSelectedDayChange = (0, _utils2.unstable_useEventCallback)(day => {
261
261
  if (day) {
262
262
  // If there is a date already selected, then we want to keep its time
263
- return handleValueChange((0, _dateUtils.mergeDateAndTime)(utils, day, value ?? referenceDate), 'finish');
263
+ return handleValueChange((0, _dateUtils.mergeDateAndTime)(utils, day, value ?? referenceDate), 'finish', view);
264
264
  }
265
- return handleValueChange(day, 'finish');
265
+ return handleValueChange(day, 'finish', view);
266
266
  });
267
267
  React.useEffect(() => {
268
268
  if (value != null && utils.isValid(value)) {
@@ -431,9 +431,11 @@ process.env.NODE_ENV !== "production" ? DateCalendar.propTypes = {
431
431
  monthsPerRow: _propTypes.default.oneOf([3, 4]),
432
432
  /**
433
433
  * Callback fired when the value changes.
434
- * @template TDate
435
- * @param {TDate | null} value The new value.
434
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
435
+ * @template TView The view type. Will be one of date or time views.
436
+ * @param {TValue} value The new value.
436
437
  * @param {PickerSelectionState | undefined} selectionState Indicates if the date selection is complete.
438
+ * @param {TView | undefined} selectedView Indicates the view in which the selection has been made.
437
439
  */
438
440
  onChange: _propTypes.default.func,
439
441
  /**
@@ -336,8 +336,9 @@ process.env.NODE_ENV !== "production" ? DigitalClock.propTypes = {
336
336
  minutesStep: _propTypes.default.number,
337
337
  /**
338
338
  * Callback fired when the value changes.
339
- * @template TDate, TView
340
- * @param {TDate | null} value The new value.
339
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
340
+ * @template TView The view type. Will be one of date or time views.
341
+ * @param {TValue} value The new value.
341
342
  * @param {PickerSelectionState | undefined} selectionState Indicates if the date selection is complete.
342
343
  * @param {TView | undefined} selectedView Indicates the view in which the selection has been made.
343
344
  */
@@ -131,7 +131,7 @@ const MultiSectionDigitalClock = exports.MultiSectionDigitalClock = /*#__PURE__*
131
131
  }, [ampm, inViews]);
132
132
  const {
133
133
  view,
134
- setValueAndGoToView,
134
+ setValueAndGoToNextView,
135
135
  focusedView
136
136
  } = (0, _useViews.useViews)({
137
137
  view: inView,
@@ -143,7 +143,7 @@ const MultiSectionDigitalClock = exports.MultiSectionDigitalClock = /*#__PURE__*
143
143
  onFocusedViewChange
144
144
  });
145
145
  const handleMeridiemValueChange = (0, _useEventCallback.default)(newValue => {
146
- setValueAndGoToView(newValue, null, 'meridiem');
146
+ setValueAndGoToNextView(newValue, 'finish', 'meridiem');
147
147
  });
148
148
  const {
149
149
  meridiemMode,
@@ -224,11 +224,6 @@ const MultiSectionDigitalClock = exports.MultiSectionDigitalClock = /*#__PURE__*
224
224
  throw new Error('not supported');
225
225
  }
226
226
  }, [ampm, valueOrReferenceDate, disableIgnoringDatePartForTimeValidation, maxTime, meridiemMode, minTime, minutesStep, shouldDisableTime, utils, disableFuture, disablePast, now, views]);
227
- const handleSectionChange = (0, _useEventCallback.default)((sectionView, newValue) => {
228
- const viewIndex = views.indexOf(sectionView);
229
- const nextView = views[viewIndex + 1];
230
- setValueAndGoToView(newValue, nextView, sectionView);
231
- });
232
227
  const buildViewProps = React.useCallback(viewToBuild => {
233
228
  switch (viewToBuild) {
234
229
  case 'hours':
@@ -236,7 +231,7 @@ const MultiSectionDigitalClock = exports.MultiSectionDigitalClock = /*#__PURE__*
236
231
  return {
237
232
  onChange: hours => {
238
233
  const valueWithMeridiem = (0, _timeUtils.convertValueToMeridiem)(hours, meridiemMode, ampm);
239
- handleSectionChange('hours', utils.setHours(valueOrReferenceDate, valueWithMeridiem));
234
+ setValueAndGoToNextView(utils.setHours(valueOrReferenceDate, valueWithMeridiem), 'finish', 'hours');
240
235
  },
241
236
  items: (0, _MultiSectionDigitalClock.getHourSectionOptions)({
242
237
  now,
@@ -254,7 +249,7 @@ const MultiSectionDigitalClock = exports.MultiSectionDigitalClock = /*#__PURE__*
254
249
  {
255
250
  return {
256
251
  onChange: minutes => {
257
- handleSectionChange('minutes', utils.setMinutes(valueOrReferenceDate, minutes));
252
+ setValueAndGoToNextView(utils.setMinutes(valueOrReferenceDate, minutes), 'finish', 'minutes');
258
253
  },
259
254
  items: (0, _MultiSectionDigitalClock.getTimeSectionOptions)({
260
255
  value: utils.getMinutes(valueOrReferenceDate),
@@ -271,7 +266,7 @@ const MultiSectionDigitalClock = exports.MultiSectionDigitalClock = /*#__PURE__*
271
266
  {
272
267
  return {
273
268
  onChange: seconds => {
274
- handleSectionChange('seconds', utils.setSeconds(valueOrReferenceDate, seconds));
269
+ setValueAndGoToNextView(utils.setSeconds(valueOrReferenceDate, seconds), 'finish', 'seconds');
275
270
  },
276
271
  items: (0, _MultiSectionDigitalClock.getTimeSectionOptions)({
277
272
  value: utils.getSeconds(valueOrReferenceDate),
@@ -308,7 +303,7 @@ const MultiSectionDigitalClock = exports.MultiSectionDigitalClock = /*#__PURE__*
308
303
  default:
309
304
  throw new Error(`Unknown view: ${viewToBuild} found.`);
310
305
  }
311
- }, [now, value, ampm, utils, timeSteps.hours, timeSteps.minutes, timeSteps.seconds, localeText.hoursClockNumberText, localeText.minutesClockNumberText, localeText.secondsClockNumberText, meridiemMode, handleSectionChange, valueOrReferenceDate, disabled, isTimeDisabled, handleMeridiemChange]);
306
+ }, [now, value, ampm, utils, timeSteps.hours, timeSteps.minutes, timeSteps.seconds, localeText.hoursClockNumberText, localeText.minutesClockNumberText, localeText.secondsClockNumberText, meridiemMode, setValueAndGoToNextView, valueOrReferenceDate, disabled, isTimeDisabled, handleMeridiemChange]);
312
307
  const viewTimeOptions = React.useMemo(() => {
313
308
  return views.reduce((result, currentView) => {
314
309
  return (0, _extends2.default)({}, result, {
@@ -406,8 +401,9 @@ process.env.NODE_ENV !== "production" ? MultiSectionDigitalClock.propTypes = {
406
401
  minutesStep: _propTypes.default.number,
407
402
  /**
408
403
  * Callback fired when the value changes.
409
- * @template TDate, TView
410
- * @param {TDate | null} value The new value.
404
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
405
+ * @template TView The view type. Will be one of date or time views.
406
+ * @param {TValue} value The new value.
411
407
  * @param {PickerSelectionState | undefined} selectionState Indicates if the date selection is complete.
412
408
  * @param {TView | undefined} selectedView Indicates the view in which the selection has been made.
413
409
  */
@@ -56,7 +56,7 @@ const MultiSectionDigitalClockSectionRoot = (0, _styles.styled)(_MenuList.defaul
56
56
  '&:not(:first-of-type)': {
57
57
  borderLeft: `1px solid ${(theme.vars || theme).palette.divider}`
58
58
  },
59
- '&:after': {
59
+ '&::after': {
60
60
  display: 'block',
61
61
  content: '""',
62
62
  // subtracting the height of one item, extra margin and borders to make sure the max height is correct
@@ -125,17 +125,13 @@ const MultiSectionDigitalClockSection = exports.MultiSectionDigitalClockSection
125
125
  return;
126
126
  }
127
127
  const activeItem = containerRef.current.querySelector('[role="option"][tabindex="0"], [role="option"][aria-selected="true"]');
128
+ if (active && autoFocus && activeItem) {
129
+ activeItem.focus();
130
+ }
128
131
  if (!activeItem || previousActive.current === activeItem) {
129
- // Handle setting the ref to null if the selected item is ever reset via UI
130
- if (previousActive.current !== activeItem) {
131
- previousActive.current = activeItem;
132
- }
133
132
  return;
134
133
  }
135
134
  previousActive.current = activeItem;
136
- if (active && autoFocus) {
137
- activeItem.focus();
138
- }
139
135
  const offsetTop = activeItem.offsetTop;
140
136
 
141
137
  // Subtracting the 4px of extra margin intended for the first visible section item