@mui/x-date-pickers 6.18.6 → 6.19.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 (72) hide show
  1. package/AdapterDateFns/AdapterDateFns.d.ts +3 -24
  2. package/AdapterDateFns/AdapterDateFns.js +11 -272
  3. package/AdapterDateFnsBase/AdapterDateFnsBase.d.ts +65 -0
  4. package/AdapterDateFnsBase/AdapterDateFnsBase.js +308 -0
  5. package/AdapterDateFnsBase/index.d.ts +1 -0
  6. package/AdapterDateFnsBase/index.js +1 -0
  7. package/AdapterDateFnsBase/package.json +6 -0
  8. package/AdapterDateFnsV3/AdapterDateFnsV3.d.ts +88 -0
  9. package/AdapterDateFnsV3/AdapterDateFnsV3.js +357 -0
  10. package/AdapterDateFnsV3/index.d.ts +1 -0
  11. package/AdapterDateFnsV3/index.js +1 -0
  12. package/AdapterDateFnsV3/package.json +6 -0
  13. package/AdapterLuxon/AdapterLuxon.d.ts +32 -32
  14. package/CHANGELOG.md +85 -1
  15. package/DateCalendar/DateCalendar.js +6 -4
  16. package/DateCalendar/DateCalendar.types.d.ts +0 -8
  17. package/DigitalClock/DigitalClock.js +3 -2
  18. package/MultiSectionDigitalClock/MultiSectionDigitalClock.js +9 -13
  19. package/MultiSectionDigitalClock/MultiSectionDigitalClockSection.js +8 -12
  20. package/TimeClock/TimeClock.js +3 -2
  21. package/hooks/useClearableField.d.ts +1 -1
  22. package/hooks/useClearableField.js +3 -3
  23. package/index.js +1 -1
  24. package/internals/hooks/useViews.d.ts +4 -4
  25. package/internals/hooks/useViews.js +13 -13
  26. package/internals/models/helpers.d.ts +1 -0
  27. package/internals/models/props/clock.d.ts +0 -9
  28. package/legacy/AdapterDateFns/AdapterDateFns.js +278 -528
  29. package/legacy/AdapterDateFnsBase/AdapterDateFnsBase.js +308 -0
  30. package/legacy/AdapterDateFnsBase/index.js +1 -0
  31. package/legacy/AdapterDateFnsV3/AdapterDateFnsV3.js +376 -0
  32. package/legacy/AdapterDateFnsV3/index.js +1 -0
  33. package/legacy/DateCalendar/DateCalendar.js +6 -4
  34. package/legacy/DigitalClock/DigitalClock.js +3 -2
  35. package/legacy/MultiSectionDigitalClock/MultiSectionDigitalClock.js +9 -13
  36. package/legacy/MultiSectionDigitalClock/MultiSectionDigitalClockSection.js +8 -12
  37. package/legacy/TimeClock/TimeClock.js +3 -2
  38. package/legacy/hooks/useClearableField.js +3 -3
  39. package/legacy/index.js +1 -1
  40. package/legacy/internals/hooks/useViews.js +13 -13
  41. package/legacy/locales/index.js +1 -0
  42. package/locales/index.d.ts +1 -0
  43. package/locales/index.js +1 -0
  44. package/modern/AdapterDateFns/AdapterDateFns.js +11 -271
  45. package/modern/AdapterDateFnsBase/AdapterDateFnsBase.js +307 -0
  46. package/modern/AdapterDateFnsBase/index.js +1 -0
  47. package/modern/AdapterDateFnsV3/AdapterDateFnsV3.js +357 -0
  48. package/modern/AdapterDateFnsV3/index.js +1 -0
  49. package/modern/DateCalendar/DateCalendar.js +6 -4
  50. package/modern/DigitalClock/DigitalClock.js +3 -2
  51. package/modern/MultiSectionDigitalClock/MultiSectionDigitalClock.js +9 -13
  52. package/modern/MultiSectionDigitalClock/MultiSectionDigitalClockSection.js +8 -12
  53. package/modern/TimeClock/TimeClock.js +3 -2
  54. package/modern/hooks/useClearableField.js +3 -3
  55. package/modern/index.js +1 -1
  56. package/modern/internals/hooks/useViews.js +13 -13
  57. package/modern/locales/index.js +1 -0
  58. package/node/AdapterDateFns/AdapterDateFns.js +11 -271
  59. package/node/AdapterDateFnsBase/AdapterDateFnsBase.js +315 -0
  60. package/node/AdapterDateFnsBase/index.js +12 -0
  61. package/node/AdapterDateFnsV3/AdapterDateFnsV3.js +366 -0
  62. package/node/AdapterDateFnsV3/index.js +12 -0
  63. package/node/DateCalendar/DateCalendar.js +6 -4
  64. package/node/DigitalClock/DigitalClock.js +3 -2
  65. package/node/MultiSectionDigitalClock/MultiSectionDigitalClock.js +9 -13
  66. package/node/MultiSectionDigitalClock/MultiSectionDigitalClockSection.js +8 -12
  67. package/node/TimeClock/TimeClock.js +3 -2
  68. package/node/hooks/useClearableField.js +3 -3
  69. package/node/index.js +1 -1
  70. package/node/internals/hooks/useViews.js +13 -13
  71. package/node/locales/index.js +11 -0
  72. package/package.json +2 -2
@@ -125,7 +125,7 @@ export const MultiSectionDigitalClock = /*#__PURE__*/React.forwardRef(function M
125
125
  }, [ampm, inViews]);
126
126
  const {
127
127
  view,
128
- setValueAndGoToView,
128
+ setValueAndGoToNextView,
129
129
  focusedView
130
130
  } = useViews({
131
131
  view: inView,
@@ -137,7 +137,7 @@ export const MultiSectionDigitalClock = /*#__PURE__*/React.forwardRef(function M
137
137
  onFocusedViewChange
138
138
  });
139
139
  const handleMeridiemValueChange = useEventCallback(newValue => {
140
- setValueAndGoToView(newValue, null, 'meridiem');
140
+ setValueAndGoToNextView(newValue, 'finish', 'meridiem');
141
141
  });
142
142
  const {
143
143
  meridiemMode,
@@ -221,11 +221,6 @@ export const MultiSectionDigitalClock = /*#__PURE__*/React.forwardRef(function M
221
221
  throw new Error('not supported');
222
222
  }
223
223
  }, [ampm, valueOrReferenceDate, disableIgnoringDatePartForTimeValidation, maxTime, meridiemMode, minTime, minutesStep, shouldDisableClock, shouldDisableTime, utils, disableFuture, disablePast, now, views]);
224
- const handleSectionChange = useEventCallback((sectionView, newValue) => {
225
- const viewIndex = views.indexOf(sectionView);
226
- const nextView = views[viewIndex + 1];
227
- setValueAndGoToView(newValue, nextView, sectionView);
228
- });
229
224
  const buildViewProps = React.useCallback(viewToBuild => {
230
225
  switch (viewToBuild) {
231
226
  case 'hours':
@@ -233,7 +228,7 @@ export const MultiSectionDigitalClock = /*#__PURE__*/React.forwardRef(function M
233
228
  return {
234
229
  onChange: hours => {
235
230
  const valueWithMeridiem = convertValueToMeridiem(hours, meridiemMode, ampm);
236
- handleSectionChange('hours', utils.setHours(valueOrReferenceDate, valueWithMeridiem));
231
+ setValueAndGoToNextView(utils.setHours(valueOrReferenceDate, valueWithMeridiem), 'finish', 'hours');
237
232
  },
238
233
  items: getHourSectionOptions({
239
234
  now,
@@ -250,7 +245,7 @@ export const MultiSectionDigitalClock = /*#__PURE__*/React.forwardRef(function M
250
245
  {
251
246
  return {
252
247
  onChange: minutes => {
253
- handleSectionChange('minutes', utils.setMinutes(valueOrReferenceDate, minutes));
248
+ setValueAndGoToNextView(utils.setMinutes(valueOrReferenceDate, minutes), 'finish', 'minutes');
254
249
  },
255
250
  items: getTimeSectionOptions({
256
251
  value: utils.getMinutes(valueOrReferenceDate),
@@ -267,7 +262,7 @@ export const MultiSectionDigitalClock = /*#__PURE__*/React.forwardRef(function M
267
262
  {
268
263
  return {
269
264
  onChange: seconds => {
270
- handleSectionChange('seconds', utils.setSeconds(valueOrReferenceDate, seconds));
265
+ setValueAndGoToNextView(utils.setSeconds(valueOrReferenceDate, seconds), 'finish', 'seconds');
271
266
  },
272
267
  items: getTimeSectionOptions({
273
268
  value: utils.getSeconds(valueOrReferenceDate),
@@ -302,7 +297,7 @@ export const MultiSectionDigitalClock = /*#__PURE__*/React.forwardRef(function M
302
297
  default:
303
298
  throw new Error(`Unknown view: ${viewToBuild} found.`);
304
299
  }
305
- }, [now, value, ampm, utils, timeSteps.hours, timeSteps.minutes, timeSteps.seconds, localeText.hoursClockNumberText, localeText.minutesClockNumberText, localeText.secondsClockNumberText, meridiemMode, handleSectionChange, valueOrReferenceDate, disabled, isTimeDisabled, handleMeridiemChange]);
300
+ }, [now, value, ampm, utils, timeSteps.hours, timeSteps.minutes, timeSteps.seconds, localeText.hoursClockNumberText, localeText.minutesClockNumberText, localeText.secondsClockNumberText, meridiemMode, setValueAndGoToNextView, valueOrReferenceDate, disabled, isTimeDisabled, handleMeridiemChange]);
306
301
  const viewTimeOptions = React.useMemo(() => {
307
302
  return views.reduce((result, currentView) => {
308
303
  return _extends({}, result, {
@@ -412,8 +407,9 @@ process.env.NODE_ENV !== "production" ? MultiSectionDigitalClock.propTypes = {
412
407
  minutesStep: PropTypes.number,
413
408
  /**
414
409
  * Callback fired when the value changes.
415
- * @template TDate, TView
416
- * @param {TDate | null} value The new value.
410
+ * @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.
411
+ * @template TView The view type. Will be one of date or time views.
412
+ * @param {TValue} value The new value.
417
413
  * @param {PickerSelectionState | undefined} selectionState Indicates if the date selection is complete.
418
414
  * @param {TView | undefined} selectedView Indicates the view in which the selection has been made.
419
415
  */
@@ -89,7 +89,7 @@ export const MultiSectionDigitalClockSection = /*#__PURE__*/React.forwardRef(fun
89
89
  var _slots$digitalClockSe;
90
90
  const containerRef = React.useRef(null);
91
91
  const handleRef = useForkRef(ref, containerRef);
92
- const previousSelected = React.useRef(null);
92
+ const previousActive = React.useRef(null);
93
93
  const props = useThemeProps({
94
94
  props: inProps,
95
95
  name: 'MuiMultiSectionDigitalClockSection'
@@ -116,19 +116,15 @@ export const MultiSectionDigitalClockSection = /*#__PURE__*/React.forwardRef(fun
116
116
  if (containerRef.current === null) {
117
117
  return;
118
118
  }
119
- const selectedItem = containerRef.current.querySelector('[role="option"][aria-selected="true"]');
120
- if (!selectedItem || previousSelected.current === selectedItem) {
121
- // Handle setting the ref to null if the selected item is ever reset via UI
122
- if (previousSelected.current !== selectedItem) {
123
- previousSelected.current = selectedItem;
124
- }
125
- return;
119
+ const activeItem = containerRef.current.querySelector('[role="option"][aria-selected="true"]');
120
+ if (active && autoFocus && activeItem) {
121
+ activeItem.focus();
126
122
  }
127
- previousSelected.current = selectedItem;
128
- if (active && autoFocus) {
129
- selectedItem.focus();
123
+ if (!activeItem || previousActive.current === activeItem) {
124
+ return;
130
125
  }
131
- const offsetTop = selectedItem.offsetTop;
126
+ previousActive.current = activeItem;
127
+ const offsetTop = activeItem.offsetTop;
132
128
 
133
129
  // Subtracting the 4px of extra margin intended for the first visible section item
134
130
  containerRef.current.scrollTop = offsetTop - 4;
@@ -404,8 +404,9 @@ process.env.NODE_ENV !== "production" ? TimeClock.propTypes = {
404
404
  minutesStep: PropTypes.number,
405
405
  /**
406
406
  * Callback fired when the value changes.
407
- * @template TDate, TView
408
- * @param {TDate | null} value The new value.
407
+ * @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.
408
+ * @template TView The view type. Will be one of date or time views.
409
+ * @param {TValue} value The new value.
409
410
  * @param {PickerSelectionState | undefined} selectionState Indicates if the date selection is complete.
410
411
  * @param {TView | undefined} selectedView Indicates the view in which the selection has been made.
411
412
  */
@@ -18,7 +18,7 @@ export declare const useClearableField: <TFieldProps extends FieldsTextFieldProp
18
18
  endAdornment?: React.ReactNode;
19
19
  } | undefined, TFieldSlotsComponents extends FieldSlotsComponents, TFieldSlotsComponentsProps extends FieldSlotsComponentsProps>({ clearable, fieldProps: forwardedFieldProps, InputProps: ForwardedInputProps, onClear, slots, slotProps, components, componentsProps, }: UseClearableFieldProps<TFieldProps, TInputProps, TFieldSlotsComponents, TFieldSlotsComponentsProps>) => {
20
20
  InputProps: TInputProps & {
21
- endAdornment: string | number | boolean | Iterable<React.ReactNode> | React.JSX.Element | null | undefined;
21
+ endAdornment: React.JSX.Element;
22
22
  };
23
23
  fieldProps: TFieldProps;
24
24
  };
@@ -40,8 +40,8 @@ export const useClearableField = ({
40
40
  ownerState: {}
41
41
  });
42
42
  const InputProps = _extends({}, ForwardedInputProps, {
43
- endAdornment: clearable ? /*#__PURE__*/_jsxs(React.Fragment, {
44
- children: [/*#__PURE__*/_jsx(InputAdornment, {
43
+ endAdornment: /*#__PURE__*/_jsxs(React.Fragment, {
44
+ children: [clearable && /*#__PURE__*/_jsx(InputAdornment, {
45
45
  position: "end",
46
46
  sx: {
47
47
  marginRight: ForwardedInputProps != null && ForwardedInputProps.endAdornment ? -1 : -1.5
@@ -53,7 +53,7 @@ export const useClearableField = ({
53
53
  }, endClearIconProps))
54
54
  }))
55
55
  }), ForwardedInputProps == null ? void 0 : ForwardedInputProps.endAdornment]
56
- }) : ForwardedInputProps == null ? void 0 : ForwardedInputProps.endAdornment
56
+ })
57
57
  });
58
58
  const fieldProps = _extends({}, forwardedFieldProps, {
59
59
  sx: [{
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-date-pickers v6.18.6
2
+ * @mui/x-date-pickers v6.19.0
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -5,7 +5,8 @@ export type PickerOnChangeFn<TDate> = (date: TDate | null, selectionState?: Pick
5
5
  export interface UseViewsOptions<TValue, TView extends DateOrTimeViewWithMeridiem> {
6
6
  /**
7
7
  * Callback fired when the value changes.
8
- * @template TValue
8
+ * @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.
9
+ * @template TView The view type. Will be one of date or time views.
9
10
  * @param {TValue} value The new value.
10
11
  * @param {PickerSelectionState | undefined} selectionState Indicates if the date selection is complete.
11
12
  * @param {TView | undefined} selectedView Indicates the view in which the selection has been made.
@@ -52,7 +53,7 @@ export interface UseViewsOptions<TValue, TView extends DateOrTimeViewWithMeridie
52
53
  */
53
54
  onFocusedViewChange?: (view: TView, hasFocus: boolean) => void;
54
55
  }
55
- export interface ExportedUseViewsOptions<TView extends DateOrTimeViewWithMeridiem> extends MakeOptional<Omit<UseViewsOptions<any, TView>, 'onChange'>, 'openTo' | 'views'> {
56
+ export interface ExportedUseViewsOptions<TView extends DateOrTimeViewWithMeridiem> extends MakeOptional<UseViewsOptions<any, TView>, 'onChange' | 'openTo' | 'views'> {
56
57
  }
57
58
  interface UseViewsResponse<TValue, TView extends DateOrTimeViewWithMeridiem> {
58
59
  view: TView;
@@ -63,8 +64,7 @@ interface UseViewsResponse<TValue, TView extends DateOrTimeViewWithMeridiem> {
63
64
  previousView: TView | null;
64
65
  defaultView: TView;
65
66
  goToNextView: () => void;
66
- setValueAndGoToNextView: (value: TValue, currentViewSelectionState?: PickerSelectionState) => void;
67
- setValueAndGoToView: (value: TValue, newView: TView | null, selectedView: TView) => void;
67
+ setValueAndGoToNextView: (value: TValue, currentViewSelectionState?: PickerSelectionState, selectedView?: TView) => void;
68
68
  }
69
69
  export declare function useViews<TValue, TView extends DateOrTimeViewWithMeridiem>({ onChange, onViewChange, openTo, view: inView, views, autoFocus, focusedView: inFocusedView, onFocusedViewChange, }: UseViewsOptions<TValue, TView>): UseViewsResponse<TValue, TView>;
70
70
  export {};
@@ -65,11 +65,12 @@ export function useViews({
65
65
  onFocusedViewChange == null || onFocusedViewChange(viewToFocus, hasFocus);
66
66
  });
67
67
  const handleChangeView = useEventCallback(newView => {
68
+ // always keep the focused view in sync
69
+ handleFocusedViewChange(newView, true);
68
70
  if (newView === view) {
69
71
  return;
70
72
  }
71
73
  setView(newView);
72
- handleFocusedViewChange(newView, true);
73
74
  if (onViewChange) {
74
75
  onViewChange(newView);
75
76
  }
@@ -78,7 +79,6 @@ export function useViews({
78
79
  if (nextView) {
79
80
  handleChangeView(nextView);
80
81
  }
81
- handleFocusedViewChange(nextView, true);
82
82
  });
83
83
  const setValueAndGoToNextView = useEventCallback((value, currentViewSelectionState, selectedView) => {
84
84
  const isSelectionFinishedOnCurrentView = currentViewSelectionState === 'finish';
@@ -87,18 +87,19 @@ export function useViews({
87
87
  // but we it's not the final view given all `views` -> overall selection state should be `partial`.
88
88
  views.indexOf(selectedView) < views.length - 1 : Boolean(nextView);
89
89
  const globalSelectionState = isSelectionFinishedOnCurrentView && hasMoreViews ? 'partial' : currentViewSelectionState;
90
- onChange(value, globalSelectionState);
91
- if (isSelectionFinishedOnCurrentView) {
90
+ onChange(value, globalSelectionState, selectedView);
91
+ // Detects if the selected view is not the active one.
92
+ // Can happen if multiple views are displayed, like in `DesktopDateTimePicker` or `MultiSectionDigitalClock`.
93
+ if (selectedView && selectedView !== view) {
94
+ const nextViewAfterSelected = views[views.indexOf(selectedView) + 1];
95
+ if (nextViewAfterSelected) {
96
+ // move to next view after the selected one
97
+ handleChangeView(nextViewAfterSelected);
98
+ }
99
+ } else if (isSelectionFinishedOnCurrentView) {
92
100
  goToNextView();
93
101
  }
94
102
  });
95
- const setValueAndGoToView = useEventCallback((value, newView, selectedView) => {
96
- onChange(value, newView ? 'partial' : 'finish', selectedView);
97
- if (newView) {
98
- handleChangeView(newView);
99
- handleFocusedViewChange(newView, true);
100
- }
101
- });
102
103
  return {
103
104
  view,
104
105
  setView: handleChangeView,
@@ -109,7 +110,6 @@ export function useViews({
109
110
  // Always return up to date default view instead of the initial one (i.e. defaultView.current)
110
111
  defaultView: views.includes(openTo) ? openTo : views[0],
111
112
  goToNextView,
112
- setValueAndGoToNextView,
113
- setValueAndGoToView
113
+ setValueAndGoToNextView
114
114
  };
115
115
  }
@@ -5,4 +5,5 @@
5
5
  */
6
6
  export type ExtendMui<C, Removals extends keyof C = never> = Omit<C, 'classes' | 'theme' | Removals>;
7
7
  export type MakeOptional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
8
+ export type MakeRequired<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>;
8
9
  export type DefaultizedProps<P extends {}, RequiredProps extends keyof P, AdditionalProps extends {} = {}> = Omit<P, RequiredProps | keyof AdditionalProps> & Required<Pick<P, RequiredProps>> & AdditionalProps;
@@ -1,6 +1,5 @@
1
1
  import { SxProps, Theme } from '@mui/material/styles';
2
2
  import { BaseTimeValidationProps, TimeValidationProps } from '../validation';
3
- import { PickerSelectionState } from '../../hooks/usePicker/usePickerValue.types';
4
3
  import { TimeStepOptions, TimezoneProps } from '../../../models';
5
4
  import type { ExportedDigitalClockProps } from '../../../DigitalClock/DigitalClock.types';
6
5
  import type { ExportedMultiSectionDigitalClockProps } from '../../../MultiSectionDigitalClock/MultiSectionDigitalClock.types';
@@ -29,14 +28,6 @@ export interface BaseClockProps<TDate, TView extends TimeViewWithMeridiem> exten
29
28
  * Used when the component is not controlled.
30
29
  */
31
30
  defaultValue?: TDate | null;
32
- /**
33
- * Callback fired when the value changes.
34
- * @template TDate, TView
35
- * @param {TDate | null} value The new value.
36
- * @param {PickerSelectionState | undefined} selectionState Indicates if the date selection is complete.
37
- * @param {TView | undefined} selectedView Indicates the view in which the selection has been made.
38
- */
39
- onChange?: (value: TDate | null, selectionState?: PickerSelectionState, selectedView?: TView) => void;
40
31
  /**
41
32
  * If `true`, the picker views and text field are disabled.
42
33
  * @default false