@mui/x-date-pickers 7.6.2 → 7.7.1

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 (105) hide show
  1. package/AdapterDateFnsJalaliV3/AdapterDateFnsJalaliV3.d.ts +48 -48
  2. package/AdapterDateFnsJalaliV3/AdapterDateFnsJalaliV3.js +1 -0
  3. package/AdapterDateFnsV3/AdapterDateFnsV3.d.ts +47 -47
  4. package/AdapterDateFnsV3/AdapterDateFnsV3.js +1 -0
  5. package/CHANGELOG.md +163 -0
  6. package/DateCalendar/DateCalendar.js +3 -3
  7. package/DateCalendar/DateCalendar.types.d.ts +4 -4
  8. package/DateCalendar/DayCalendar.d.ts +3 -4
  9. package/DatePicker/DatePicker.js +2 -0
  10. package/DateTimePicker/DateTimePicker.js +2 -0
  11. package/DesktopDatePicker/DesktopDatePicker.js +2 -0
  12. package/DesktopDateTimePicker/DesktopDateTimePicker.js +2 -0
  13. package/DesktopTimePicker/DesktopTimePicker.js +2 -0
  14. package/MobileDatePicker/MobileDatePicker.js +2 -0
  15. package/MobileDateTimePicker/MobileDateTimePicker.js +2 -0
  16. package/MobileTimePicker/MobileTimePicker.js +2 -0
  17. package/MonthCalendar/MonthCalendar.js +17 -3
  18. package/MonthCalendar/MonthCalendar.types.d.ts +25 -0
  19. package/MonthCalendar/PickersMonth.d.ts +4 -0
  20. package/MonthCalendar/PickersMonth.js +38 -21
  21. package/MonthCalendar/index.d.ts +1 -1
  22. package/MultiSectionDigitalClock/MultiSectionDigitalClock.js +16 -3
  23. package/PickersCalendarHeader/PickersCalendarHeader.js +4 -0
  24. package/PickersCalendarHeader/PickersCalendarHeader.types.d.ts +5 -1
  25. package/PickersLayout/usePickerLayout.js +0 -5
  26. package/StaticDatePicker/StaticDatePicker.js +2 -0
  27. package/StaticDateTimePicker/StaticDateTimePicker.js +2 -0
  28. package/StaticTimePicker/StaticTimePicker.js +2 -0
  29. package/TimePicker/TimePicker.js +2 -0
  30. package/YearCalendar/PickersYear.d.ts +3 -0
  31. package/YearCalendar/PickersYear.js +34 -22
  32. package/YearCalendar/YearCalendar.js +17 -3
  33. package/YearCalendar/YearCalendar.types.d.ts +25 -0
  34. package/YearCalendar/index.d.ts +1 -1
  35. package/index.js +1 -1
  36. package/internals/components/PickersArrowSwitcher/PickersArrowSwitcher.js +4 -2
  37. package/internals/components/PickersArrowSwitcher/PickersArrowSwitcher.types.d.ts +1 -0
  38. package/internals/hooks/useField/useField.utils.js +2 -1
  39. package/internals/hooks/usePicker/usePickerValue.js +45 -38
  40. package/internals/hooks/usePicker/usePickerValue.types.d.ts +3 -1
  41. package/internals/hooks/usePicker/usePickerViews.js +2 -1
  42. package/locales/daDK.js +15 -19
  43. package/locales/faIR.js +19 -22
  44. package/locales/koKR.js +2 -2
  45. package/modern/AdapterDateFnsJalaliV3/AdapterDateFnsJalaliV3.js +1 -0
  46. package/modern/AdapterDateFnsV3/AdapterDateFnsV3.js +1 -0
  47. package/modern/DateCalendar/DateCalendar.js +3 -3
  48. package/modern/DatePicker/DatePicker.js +2 -0
  49. package/modern/DateTimePicker/DateTimePicker.js +2 -0
  50. package/modern/DesktopDatePicker/DesktopDatePicker.js +2 -0
  51. package/modern/DesktopDateTimePicker/DesktopDateTimePicker.js +2 -0
  52. package/modern/DesktopTimePicker/DesktopTimePicker.js +2 -0
  53. package/modern/MobileDatePicker/MobileDatePicker.js +2 -0
  54. package/modern/MobileDateTimePicker/MobileDateTimePicker.js +2 -0
  55. package/modern/MobileTimePicker/MobileTimePicker.js +2 -0
  56. package/modern/MonthCalendar/MonthCalendar.js +17 -3
  57. package/modern/MonthCalendar/PickersMonth.js +38 -21
  58. package/modern/MultiSectionDigitalClock/MultiSectionDigitalClock.js +16 -3
  59. package/modern/PickersCalendarHeader/PickersCalendarHeader.js +4 -0
  60. package/modern/PickersLayout/usePickerLayout.js +0 -5
  61. package/modern/StaticDatePicker/StaticDatePicker.js +2 -0
  62. package/modern/StaticDateTimePicker/StaticDateTimePicker.js +2 -0
  63. package/modern/StaticTimePicker/StaticTimePicker.js +2 -0
  64. package/modern/TimePicker/TimePicker.js +2 -0
  65. package/modern/YearCalendar/PickersYear.js +34 -22
  66. package/modern/YearCalendar/YearCalendar.js +17 -3
  67. package/modern/index.js +1 -1
  68. package/modern/internals/components/PickersArrowSwitcher/PickersArrowSwitcher.js +4 -2
  69. package/modern/internals/hooks/useField/useField.utils.js +2 -1
  70. package/modern/internals/hooks/usePicker/usePickerValue.js +45 -38
  71. package/modern/internals/hooks/usePicker/usePickerViews.js +2 -1
  72. package/modern/locales/daDK.js +15 -19
  73. package/modern/locales/faIR.js +19 -22
  74. package/modern/locales/koKR.js +2 -2
  75. package/node/AdapterDateFnsJalaliV3/AdapterDateFnsJalaliV3.js +1 -0
  76. package/node/AdapterDateFnsV3/AdapterDateFnsV3.js +1 -0
  77. package/node/DateCalendar/DateCalendar.js +3 -3
  78. package/node/DatePicker/DatePicker.js +2 -0
  79. package/node/DateTimePicker/DateTimePicker.js +2 -0
  80. package/node/DesktopDatePicker/DesktopDatePicker.js +2 -0
  81. package/node/DesktopDateTimePicker/DesktopDateTimePicker.js +2 -0
  82. package/node/DesktopTimePicker/DesktopTimePicker.js +2 -0
  83. package/node/MobileDatePicker/MobileDatePicker.js +2 -0
  84. package/node/MobileDateTimePicker/MobileDateTimePicker.js +2 -0
  85. package/node/MobileTimePicker/MobileTimePicker.js +2 -0
  86. package/node/MonthCalendar/MonthCalendar.js +17 -3
  87. package/node/MonthCalendar/PickersMonth.js +40 -23
  88. package/node/MultiSectionDigitalClock/MultiSectionDigitalClock.js +16 -3
  89. package/node/PickersCalendarHeader/PickersCalendarHeader.js +4 -0
  90. package/node/PickersLayout/usePickerLayout.js +0 -5
  91. package/node/StaticDatePicker/StaticDatePicker.js +2 -0
  92. package/node/StaticDateTimePicker/StaticDateTimePicker.js +2 -0
  93. package/node/StaticTimePicker/StaticTimePicker.js +2 -0
  94. package/node/TimePicker/TimePicker.js +2 -0
  95. package/node/YearCalendar/PickersYear.js +34 -22
  96. package/node/YearCalendar/YearCalendar.js +17 -3
  97. package/node/index.js +1 -1
  98. package/node/internals/components/PickersArrowSwitcher/PickersArrowSwitcher.js +4 -2
  99. package/node/internals/hooks/useField/useField.utils.js +2 -1
  100. package/node/internals/hooks/usePicker/usePickerValue.js +45 -38
  101. package/node/internals/hooks/usePicker/usePickerViews.js +2 -1
  102. package/node/locales/daDK.js +15 -19
  103. package/node/locales/faIR.js +19 -22
  104. package/node/locales/koKR.js +2 -2
  105. package/package.json +4 -4
@@ -119,7 +119,7 @@ export const usePickerValue = ({
119
119
  const {
120
120
  onAccept,
121
121
  onChange,
122
- value: inValue,
122
+ value: inValueWithoutRenderTimezone,
123
123
  defaultValue: inDefaultValue,
124
124
  closeOnSelect = wrapperVariant === 'desktop',
125
125
  timezone: timezoneProp
@@ -129,15 +129,15 @@ export const usePickerValue = ({
129
129
  } = React.useRef(inDefaultValue);
130
130
  const {
131
131
  current: isControlled
132
- } = React.useRef(inValue !== undefined);
132
+ } = React.useRef(inValueWithoutRenderTimezone !== undefined);
133
133
 
134
134
  /* eslint-disable react-hooks/rules-of-hooks, react-hooks/exhaustive-deps */
135
135
  if (process.env.NODE_ENV !== 'production') {
136
136
  React.useEffect(() => {
137
- if (isControlled !== (inValue !== undefined)) {
137
+ if (isControlled !== (inValueWithoutRenderTimezone !== undefined)) {
138
138
  console.error([`MUI X: A component is changing the ${isControlled ? '' : 'un'}controlled value of a picker to be ${isControlled ? 'un' : ''}controlled.`, 'Elements should not switch from uncontrolled to controlled (or vice versa).', `Decide between using a controlled or uncontrolled value` + 'for the lifetime of the component.', "The nature of the state is determined during the first render. It's considered controlled if the value is not `undefined`.", 'More info: https://fb.me/react-controlled-components'].join('\n'));
139
139
  }
140
- }, [inValue]);
140
+ }, [inValueWithoutRenderTimezone]);
141
141
  React.useEffect(() => {
142
142
  if (!isControlled && defaultValue !== inDefaultValue) {
143
143
  console.error([`MUI X: A component is changing the defaultValue of an uncontrolled picker after being initialized. ` + `To suppress this warning opt to use a controlled value.`].join('\n'));
@@ -152,10 +152,21 @@ export const usePickerValue = ({
152
152
  isOpen,
153
153
  setIsOpen
154
154
  } = useOpenState(props);
155
+ const {
156
+ timezone,
157
+ value: inValueWithTimezoneToRender,
158
+ handleValueChange
159
+ } = useValueWithTimezone({
160
+ timezone: timezoneProp,
161
+ value: inValueWithoutRenderTimezone,
162
+ defaultValue,
163
+ onChange,
164
+ valueManager
165
+ });
155
166
  const [dateState, setDateState] = React.useState(() => {
156
167
  let initialValue;
157
- if (inValue !== undefined) {
158
- initialValue = inValue;
168
+ if (inValueWithTimezoneToRender !== undefined) {
169
+ initialValue = inValueWithTimezoneToRender;
159
170
  } else if (defaultValue !== undefined) {
160
171
  initialValue = defaultValue;
161
172
  } else {
@@ -165,20 +176,10 @@ export const usePickerValue = ({
165
176
  draft: initialValue,
166
177
  lastPublishedValue: initialValue,
167
178
  lastCommittedValue: initialValue,
168
- lastControlledValue: inValue,
179
+ lastControlledValue: inValueWithTimezoneToRender,
169
180
  hasBeenModifiedSinceMount: false
170
181
  };
171
182
  });
172
- const {
173
- timezone,
174
- handleValueChange
175
- } = useValueWithTimezone({
176
- timezone: timezoneProp,
177
- value: inValue,
178
- defaultValue,
179
- onChange,
180
- valueManager
181
- });
182
183
  useValidation(_extends({}, props, {
183
184
  value: dateState.draft,
184
185
  timezone
@@ -200,38 +201,44 @@ export const usePickerValue = ({
200
201
  lastCommittedValue: shouldCommit ? action.value : prev.lastCommittedValue,
201
202
  hasBeenModifiedSinceMount: true
202
203
  }));
203
- if (shouldPublish) {
204
- const validationError = action.name === 'setValueFromField' ? action.context.validationError : validator({
205
- adapter,
206
- value: action.value,
207
- props: _extends({}, props, {
204
+ let cachedContext = null;
205
+ const getContext = () => {
206
+ if (!cachedContext) {
207
+ const validationError = action.name === 'setValueFromField' ? action.context.validationError : validator({
208
+ adapter,
208
209
  value: action.value,
209
- timezone
210
- })
211
- });
212
- const context = {
213
- validationError
214
- };
215
- if (action.name === 'setValueFromShortcut') {
216
- context.shortcut = action.shortcut;
210
+ props: _extends({}, props, {
211
+ value: action.value,
212
+ timezone
213
+ })
214
+ });
215
+ cachedContext = {
216
+ validationError
217
+ };
218
+ if (action.name === 'setValueFromShortcut') {
219
+ cachedContext.shortcut = action.shortcut;
220
+ }
217
221
  }
218
- handleValueChange(action.value, context);
222
+ return cachedContext;
223
+ };
224
+ if (shouldPublish) {
225
+ handleValueChange(action.value, getContext());
219
226
  }
220
227
  if (shouldCommit && onAccept) {
221
- onAccept(action.value);
228
+ onAccept(action.value, getContext());
222
229
  }
223
230
  if (shouldClose) {
224
231
  setIsOpen(false);
225
232
  }
226
233
  });
227
- if (inValue !== undefined && (dateState.lastControlledValue === undefined || !valueManager.areValuesEqual(utils, dateState.lastControlledValue, inValue))) {
228
- const isUpdateComingFromPicker = valueManager.areValuesEqual(utils, dateState.draft, inValue);
234
+ if (inValueWithTimezoneToRender !== undefined && (dateState.lastControlledValue === undefined || !valueManager.areValuesEqual(utils, dateState.lastControlledValue, inValueWithTimezoneToRender))) {
235
+ const isUpdateComingFromPicker = valueManager.areValuesEqual(utils, dateState.draft, inValueWithTimezoneToRender);
229
236
  setDateState(prev => _extends({}, prev, {
230
- lastControlledValue: inValue
237
+ lastControlledValue: inValueWithTimezoneToRender
231
238
  }, isUpdateComingFromPicker ? {} : {
232
- lastCommittedValue: inValue,
233
- lastPublishedValue: inValue,
234
- draft: inValue,
239
+ lastCommittedValue: inValueWithTimezoneToRender,
240
+ lastPublishedValue: inValueWithTimezoneToRender,
241
+ draft: inValueWithTimezoneToRender,
235
242
  hasBeenModifiedSinceMount: true
236
243
  }));
237
244
  }
@@ -193,9 +193,11 @@ export interface UsePickerValueBaseProps<TValue, TError> {
193
193
  /**
194
194
  * Callback fired when the value is accepted.
195
195
  * @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.
196
+ * @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
196
197
  * @param {TValue} value The value that was just accepted.
198
+ * @param {FieldChangeHandlerContext<TError>} context The context containing the validation result of the current value.
197
199
  */
198
- onAccept?: (value: TValue) => void;
200
+ onAccept?: (value: TValue, context: PickerChangeHandlerContext<TError>) => void;
199
201
  /**
200
202
  * Callback fired when the error associated to the current value changes.
201
203
  * If the error has a non-null value, then the `TextField` will be rendered in `error` state.
@@ -39,6 +39,7 @@ export const usePickerViews = ({
39
39
  onClose
40
40
  } = propsFromPickerValue;
41
41
  const {
42
+ view: inView,
42
43
  views,
43
44
  openTo,
44
45
  onViewChange,
@@ -54,7 +55,7 @@ export const usePickerViews = ({
54
55
  setFocusedView,
55
56
  setValueAndGoToNextView
56
57
  } = useViews({
57
- view: undefined,
58
+ view: inView,
58
59
  views,
59
60
  openTo,
60
61
  onChange,
package/locales/daDK.js CHANGED
@@ -17,11 +17,10 @@ const daDKPickers = {
17
17
  // DateRange labels
18
18
  start: 'Start',
19
19
  end: 'Slut',
20
- // startDate: 'Start date',
21
- // startTime: 'Start time',
22
- // endDate: 'End date',
23
- // endTime: 'End time',
24
-
20
+ startDate: 'Start dato',
21
+ startTime: 'Start tid',
22
+ endDate: 'Slut date',
23
+ endTime: 'Slut tid',
25
24
  // Action bar
26
25
  cancelButtonLabel: 'Annuller',
27
26
  clearButtonLabel: 'Ryd',
@@ -47,8 +46,7 @@ const daDKPickers = {
47
46
  // Open picker labels
48
47
  openDatePickerDialogue: (value, utils) => value !== null && utils.isValid(value) ? `Vælg dato, valgte dato er ${utils.format(value, 'fullDate')}` : 'Vælg dato',
49
48
  openTimePickerDialogue: (value, utils) => value !== null && utils.isValid(value) ? `Vælg tidspunkt, valgte tidspunkt er ${utils.format(value, 'fullTime')}` : 'Vælg tidspunkt',
50
- // fieldClearLabel: 'Clear value',
51
-
49
+ fieldClearLabel: 'ryd felt',
52
50
  // Table labels
53
51
  timeTableLabel: 'vælg tidspunkt',
54
52
  dateTableLabel: 'vælg dato',
@@ -60,19 +58,17 @@ const daDKPickers = {
60
58
  fieldHoursPlaceholder: () => 'hh',
61
59
  fieldMinutesPlaceholder: () => 'mm',
62
60
  fieldSecondsPlaceholder: () => 'ss',
63
- fieldMeridiemPlaceholder: () => 'aa'
64
-
61
+ fieldMeridiemPlaceholder: () => 'aa',
65
62
  // View names
66
- // year: 'Year',
67
- // month: 'Month',
68
- // day: 'Day',
69
- // weekDay: 'Week day',
70
- // hours: 'Hours',
71
- // minutes: 'Minutes',
72
- // seconds: 'Seconds',
73
- // meridiem: 'Meridiem',
74
-
63
+ year: 'år',
64
+ month: 'måned',
65
+ day: 'dag',
66
+ weekDay: 'ugedag',
67
+ hours: 'timer',
68
+ minutes: 'minutter',
69
+ seconds: 'sekunder',
70
+ meridiem: 'middag',
75
71
  // Common
76
- // empty: 'Empty',
72
+ empty: 'tom'
77
73
  };
78
74
  export const daDK = getPickersLocalization(daDKPickers);
package/locales/faIR.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { getPickersLocalization } from './utils/getPickersLocalization';
2
2
  const timeViews = {
3
- hours: 'ساعت ها',
4
- minutes: 'دقیقه ها',
5
- seconds: 'ثانیه ها',
3
+ hours: 'ساعت‌ها',
4
+ minutes: 'دقیقه‌ها',
5
+ seconds: 'ثانیه‌ها',
6
6
  meridiem: 'بعد از ظهر'
7
7
  };
8
8
  const faIRPickers = {
@@ -16,11 +16,10 @@ const faIRPickers = {
16
16
  // DateRange labels
17
17
  start: 'شروع',
18
18
  end: 'پایان',
19
- // startDate: 'Start date',
20
- // startTime: 'Start time',
21
- // endDate: 'End date',
22
- // endTime: 'End time',
23
-
19
+ startDate: 'تاریخ شروع',
20
+ startTime: 'ساعت شروع',
21
+ endDate: 'تاریخ پایان',
22
+ endTime: 'ساعت پایان',
24
23
  // Action bar
25
24
  cancelButtonLabel: 'لغو',
26
25
  clearButtonLabel: 'پاک کردن',
@@ -33,9 +32,9 @@ const faIRPickers = {
33
32
  dateRangePickerToolbarTitle: 'محدوده تاریخ را انتخاب کنید',
34
33
  // Clock labels
35
34
  clockLabelText: (view, time, adapter) => ` را انتخاب کنید ${timeViews[view]}. ${time === null ? 'هیچ ساعتی انتخاب نشده است' : `ساعت انتخاب ${adapter.format(time, 'fullTime')} می باشد`}`,
36
- hoursClockNumberText: hours => `${hours} ساعت ها`,
37
- minutesClockNumberText: minutes => `${minutes} دقیقه ها`,
38
- secondsClockNumberText: seconds => `${seconds} ثانیه ها`,
35
+ hoursClockNumberText: hours => `${hours} ساعت‌ها`,
36
+ minutesClockNumberText: minutes => `${minutes} دقیقه‌ها`,
37
+ secondsClockNumberText: seconds => `${seconds} ثانیه‌ها`,
39
38
  // Digital clock labels
40
39
  selectViewText: view => ` را انتخاب کنید ${timeViews[view]}`,
41
40
  // Calendar labels
@@ -44,10 +43,9 @@ const faIRPickers = {
44
43
  calendarWeekNumberAriaLabelText: weekNumber => `هفته ${weekNumber}`,
45
44
  calendarWeekNumberText: weekNumber => `${weekNumber}`,
46
45
  // Open picker labels
47
- openDatePickerDialogue: (value, utils) => value !== null && utils.isValid(value) ? `تاریخ را انتخاب کنید، تاریخ انتخاب شده ${utils.format(value, 'fullDate')} می باشد` : 'تاریخ را انتخاب کنید',
48
- openTimePickerDialogue: (value, utils) => value !== null && utils.isValid(value) ? `ساعت را انتخاب کنید، ساعت انتخاب شده ${utils.format(value, 'fullTime')} می باشد` : 'ساعت را انتخاب کنید',
49
- // fieldClearLabel: 'Clear value',
50
-
46
+ openDatePickerDialogue: (value, utils) => value !== null && utils.isValid(value) ? `تاریخ را انتخاب کنید، تاریخ انتخاب شده ${utils.format(value, 'fullDate')} می‌باشد` : 'تاریخ را انتخاب کنید',
47
+ openTimePickerDialogue: (value, utils) => value !== null && utils.isValid(value) ? `ساعت را انتخاب کنید، ساعت انتخاب شده ${utils.format(value, 'fullTime')} می‌باشد` : 'ساعت را انتخاب کنید',
48
+ fieldClearLabel: 'پاک کردن مقدار',
51
49
  // Table labels
52
50
  timeTableLabel: 'انتخاب تاریخ',
53
51
  dateTableLabel: 'انتخاب ساعت',
@@ -64,13 +62,12 @@ const faIRPickers = {
64
62
  year: 'سال',
65
63
  month: 'ماه',
66
64
  day: 'روز',
67
- // weekDay: 'Week day',
68
- hours: 'ساعت ها',
69
- minutes: 'دقیقه ها',
70
- seconds: 'ثانیه ها'
71
- // meridiem: 'Meridiem',
72
-
65
+ weekDay: 'روز هفته',
66
+ hours: 'ساعت‌ها',
67
+ minutes: 'دقیقه‌ها',
68
+ seconds: 'ثانیه‌ها',
69
+ meridiem: 'نیم‌روز',
73
70
  // Common
74
- // empty: 'Empty',
71
+ empty: 'خالی'
75
72
  };
76
73
  export const faIR = getPickersLocalization(faIRPickers);
package/locales/koKR.js CHANGED
@@ -3,7 +3,7 @@ const views = {
3
3
  hours: '시간을',
4
4
  minutes: '분을',
5
5
  seconds: '초를',
6
- meridiem: '메리디엠'
6
+ meridiem: '오전/오후를'
7
7
  };
8
8
  const koKRPickers = {
9
9
  // Calendar navigation
@@ -33,7 +33,7 @@ const koKRPickers = {
33
33
  dateRangePickerToolbarTitle: '날짜 범위 선택하기',
34
34
  // Clock labels
35
35
  clockLabelText: (view, time, adapter) => `${views[view]} 선택하세요. ${time === null ? '시간을 선택하지 않았습니다.' : `현재 선택된 시간은 ${adapter.format(time, 'fullTime')}입니다.`}`,
36
- hoursClockNumberText: hours => `${hours}시간`,
36
+ hoursClockNumberText: hours => `${hours}시`,
37
37
  minutesClockNumberText: minutes => `${minutes}분`,
38
38
  secondsClockNumberText: seconds => `${seconds}초`,
39
39
  // Digital clock labels
@@ -130,6 +130,7 @@ export class AdapterDateFnsJalali extends AdapterDateFnsBase {
130
130
  longFormatters,
131
131
  lib: 'date-fns-jalali'
132
132
  });
133
+ // TODO: explicit return types can be removed once there is only one date-fns version supported
133
134
  this.parse = (value, format) => {
134
135
  if (value === '') {
135
136
  return null;
@@ -90,6 +90,7 @@ export class AdapterDateFns extends AdapterDateFnsBase {
90
90
  formats,
91
91
  longFormatters
92
92
  });
93
+ // TODO: explicit return types can be removed once there is only one date-fns version supported
93
94
  this.parse = (value, format) => {
94
95
  if (value === '') {
95
96
  return null;
@@ -272,7 +272,9 @@ export const DateCalendar = /*#__PURE__*/React.forwardRef(function DateCalendar(
272
272
  readOnly,
273
273
  disabled,
274
274
  timezone,
275
- gridLabelId
275
+ gridLabelId,
276
+ slots,
277
+ slotProps
276
278
  };
277
279
  const prevOpenViewRef = React.useRef(view);
278
280
  React.useEffect(() => {
@@ -333,8 +335,6 @@ export const DateCalendar = /*#__PURE__*/React.forwardRef(function DateCalendar(
333
335
  fixedWeekNumber: fixedWeekNumber,
334
336
  dayOfWeekFormatter: dayOfWeekFormatter,
335
337
  displayWeekNumber: displayWeekNumber,
336
- slots: slots,
337
- slotProps: slotProps,
338
338
  loading: loading,
339
339
  renderLoading: renderLoading
340
340
  }))]
@@ -167,7 +167,9 @@ process.env.NODE_ENV !== "production" ? DatePicker.propTypes = {
167
167
  /**
168
168
  * Callback fired when the value is accepted.
169
169
  * @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.
170
+ * @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
170
171
  * @param {TValue} value The value that was just accepted.
172
+ * @param {FieldChangeHandlerContext<TError>} context The context containing the validation result of the current value.
171
173
  */
172
174
  onAccept: PropTypes.func,
173
175
  /**
@@ -205,7 +205,9 @@ process.env.NODE_ENV !== "production" ? DateTimePicker.propTypes = {
205
205
  /**
206
206
  * Callback fired when the value is accepted.
207
207
  * @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.
208
+ * @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
208
209
  * @param {TValue} value The value that was just accepted.
210
+ * @param {FieldChangeHandlerContext<TError>} context The context containing the validation result of the current value.
209
211
  */
210
212
  onAccept: PropTypes.func,
211
213
  /**
@@ -182,7 +182,9 @@ DesktopDatePicker.propTypes = {
182
182
  /**
183
183
  * Callback fired when the value is accepted.
184
184
  * @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.
185
+ * @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
185
186
  * @param {TValue} value The value that was just accepted.
187
+ * @param {FieldChangeHandlerContext<TError>} context The context containing the validation result of the current value.
186
188
  */
187
189
  onAccept: PropTypes.func,
188
190
  /**
@@ -305,7 +305,9 @@ DesktopDateTimePicker.propTypes = {
305
305
  /**
306
306
  * Callback fired when the value is accepted.
307
307
  * @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.
308
+ * @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
308
309
  * @param {TValue} value The value that was just accepted.
310
+ * @param {FieldChangeHandlerContext<TError>} context The context containing the validation result of the current value.
309
311
  */
310
312
  onAccept: PropTypes.func,
311
313
  /**
@@ -193,7 +193,9 @@ DesktopTimePicker.propTypes = {
193
193
  /**
194
194
  * Callback fired when the value is accepted.
195
195
  * @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.
196
+ * @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
196
197
  * @param {TValue} value The value that was just accepted.
198
+ * @param {FieldChangeHandlerContext<TError>} context The context containing the validation result of the current value.
197
199
  */
198
200
  onAccept: PropTypes.func,
199
201
  /**
@@ -179,7 +179,9 @@ MobileDatePicker.propTypes = {
179
179
  /**
180
180
  * Callback fired when the value is accepted.
181
181
  * @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.
182
+ * @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
182
183
  * @param {TValue} value The value that was just accepted.
184
+ * @param {FieldChangeHandlerContext<TError>} context The context containing the validation result of the current value.
183
185
  */
184
186
  onAccept: PropTypes.func,
185
187
  /**
@@ -227,7 +227,9 @@ MobileDateTimePicker.propTypes = {
227
227
  /**
228
228
  * Callback fired when the value is accepted.
229
229
  * @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.
230
+ * @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
230
231
  * @param {TValue} value The value that was just accepted.
232
+ * @param {FieldChangeHandlerContext<TError>} context The context containing the validation result of the current value.
231
233
  */
232
234
  onAccept: PropTypes.func,
233
235
  /**
@@ -172,7 +172,9 @@ MobileTimePicker.propTypes = {
172
172
  /**
173
173
  * Callback fired when the value is accepted.
174
174
  * @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.
175
+ * @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
175
176
  * @param {TValue} value The value that was just accepted.
177
+ * @param {FieldChangeHandlerContext<TError>} context The context containing the validation result of the current value.
176
178
  */
177
179
  onAccept: PropTypes.func,
178
180
  /**
@@ -1,6 +1,6 @@
1
1
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
2
2
  import _extends from "@babel/runtime/helpers/esm/extends";
3
- const _excluded = ["className", "value", "defaultValue", "referenceDate", "disabled", "disableFuture", "disablePast", "maxDate", "minDate", "onChange", "shouldDisableMonth", "readOnly", "disableHighlightToday", "autoFocus", "onMonthFocus", "hasFocus", "onFocusedViewChange", "monthsPerRow", "timezone", "gridLabelId"];
3
+ const _excluded = ["className", "value", "defaultValue", "referenceDate", "disabled", "disableFuture", "disablePast", "maxDate", "minDate", "onChange", "shouldDisableMonth", "readOnly", "disableHighlightToday", "autoFocus", "onMonthFocus", "hasFocus", "onFocusedViewChange", "monthsPerRow", "timezone", "gridLabelId", "slots", "slotProps"];
4
4
  import * as React from 'react';
5
5
  import PropTypes from 'prop-types';
6
6
  import clsx from 'clsx';
@@ -83,7 +83,9 @@ export const MonthCalendar = /*#__PURE__*/React.forwardRef(function MonthCalenda
83
83
  onFocusedViewChange,
84
84
  monthsPerRow = 3,
85
85
  timezone: timezoneProp,
86
- gridLabelId
86
+ gridLabelId,
87
+ slots,
88
+ slotProps
87
89
  } = props,
88
90
  other = _objectWithoutPropertiesLoose(props, _excluded);
89
91
  const {
@@ -218,12 +220,14 @@ export const MonthCalendar = /*#__PURE__*/React.forwardRef(function MonthCalenda
218
220
  onKeyDown: handleKeyDown,
219
221
  autoFocus: internalHasFocus && monthNumber === focusedMonth,
220
222
  disabled: isDisabled,
221
- tabIndex: monthNumber === focusedMonth ? 0 : -1,
223
+ tabIndex: monthNumber === focusedMonth && !isDisabled ? 0 : -1,
222
224
  onFocus: handleMonthFocus,
223
225
  onBlur: handleMonthBlur,
224
226
  "aria-current": todayMonth === monthNumber ? 'date' : undefined,
225
227
  "aria-label": monthLabel,
226
228
  monthsPerRow: monthsPerRow,
229
+ slots: slots,
230
+ slotProps: slotProps,
227
231
  children: monthText
228
232
  }, monthText);
229
233
  })
@@ -303,6 +307,16 @@ process.env.NODE_ENV !== "production" ? MonthCalendar.propTypes = {
303
307
  * @returns {boolean} If `true`, the month will be disabled.
304
308
  */
305
309
  shouldDisableMonth: PropTypes.func,
310
+ /**
311
+ * The props used for each component slot.
312
+ * @default {}
313
+ */
314
+ slotProps: PropTypes.object,
315
+ /**
316
+ * Overridable component slots.
317
+ * @default {}
318
+ */
319
+ slots: PropTypes.object,
306
320
  /**
307
321
  * The system prop that allows defining system overrides as well as additional CSS styles.
308
322
  */
@@ -1,9 +1,12 @@
1
1
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
2
2
  import _extends from "@babel/runtime/helpers/esm/extends";
3
- const _excluded = ["autoFocus", "children", "disabled", "selected", "value", "tabIndex", "onClick", "onKeyDown", "onFocus", "onBlur", "aria-current", "aria-label", "monthsPerRow"];
3
+ const _excluded = ["autoFocus", "className", "children", "disabled", "selected", "value", "tabIndex", "onClick", "onKeyDown", "onFocus", "onBlur", "aria-current", "aria-label", "monthsPerRow", "slots", "slotProps"];
4
4
  import * as React from 'react';
5
+ import clsx from 'clsx';
5
6
  import { styled, alpha, useThemeProps } from '@mui/material/styles';
6
- import { unstable_composeClasses as composeClasses, unstable_useEnhancedEffect as useEnhancedEffect } from '@mui/utils';
7
+ import { useSlotProps } from '@mui/base/utils';
8
+ import composeClasses from '@mui/utils/composeClasses';
9
+ import useEnhancedEffect from '@mui/utils/useEnhancedEffect';
7
10
  import { getPickersMonthUtilityClass, pickersMonthClasses } from './pickersMonthClasses';
8
11
  import { jsx as _jsx } from "react/jsx-runtime";
9
12
  const useUtilityClasses = ownerState => {
@@ -36,7 +39,7 @@ const PickersMonthRoot = styled('div', {
36
39
  }
37
40
  }]
38
41
  });
39
- const PickersMonthButton = styled('button', {
42
+ const MonthCalendarButton = styled('button', {
40
43
  name: 'MuiPickersMonth',
41
44
  slot: 'MonthButton',
42
45
  overridesResolver: (_, styles) => [styles.monthButton, {
@@ -89,6 +92,7 @@ export const PickersMonth = /*#__PURE__*/React.memo(function PickersMonth(inProp
89
92
  });
90
93
  const {
91
94
  autoFocus,
95
+ className,
92
96
  children,
93
97
  disabled,
94
98
  selected,
@@ -101,35 +105,48 @@ export const PickersMonth = /*#__PURE__*/React.memo(function PickersMonth(inProp
101
105
  'aria-current': ariaCurrent,
102
106
  'aria-label': ariaLabel
103
107
  // We don't want to forward this prop to the root element
108
+ ,
109
+
110
+ slots,
111
+ slotProps
104
112
  } = props,
105
113
  other = _objectWithoutPropertiesLoose(props, _excluded);
106
114
  const ref = React.useRef(null);
107
115
  const classes = useUtilityClasses(props);
116
+
117
+ // We can't forward the `autoFocus` to the button because it is a native button, not a MUI Button
108
118
  useEnhancedEffect(() => {
109
119
  if (autoFocus) {
120
+ // `ref.current` being `null` would be a bug in MUI.
110
121
  ref.current?.focus();
111
122
  }
112
123
  }, [autoFocus]);
113
- return /*#__PURE__*/_jsx(PickersMonthRoot, _extends({
114
- className: classes.root,
115
- ownerState: props
116
- }, other, {
117
- children: /*#__PURE__*/_jsx(PickersMonthButton, {
118
- ref: ref,
119
- disabled: disabled,
120
- type: "button",
121
- role: "radio",
122
- tabIndex: disabled ? -1 : tabIndex,
123
- "aria-current": ariaCurrent,
124
- "aria-checked": selected,
125
- "aria-label": ariaLabel,
124
+ const MonthButton = slots?.monthButton ?? MonthCalendarButton;
125
+ const monthButtonProps = useSlotProps({
126
+ elementType: MonthButton,
127
+ externalSlotProps: slotProps?.monthButton,
128
+ additionalProps: {
129
+ children,
130
+ disabled,
131
+ tabIndex,
132
+ ref,
133
+ type: 'button',
134
+ role: 'radio',
135
+ 'aria-current': ariaCurrent,
136
+ 'aria-checked': selected,
137
+ 'aria-label': ariaLabel,
126
138
  onClick: event => onClick(event, value),
127
139
  onKeyDown: event => onKeyDown(event, value),
128
140
  onFocus: event => onFocus(event, value),
129
- onBlur: event => onBlur(event, value),
130
- className: classes.monthButton,
131
- ownerState: props,
132
- children: children
133
- })
141
+ onBlur: event => onBlur(event, value)
142
+ },
143
+ ownerState: props,
144
+ className: classes.monthButton
145
+ });
146
+ return /*#__PURE__*/_jsx(PickersMonthRoot, _extends({
147
+ className: clsx(classes.root, className),
148
+ ownerState: props
149
+ }, other, {
150
+ children: /*#__PURE__*/_jsx(MonthButton, _extends({}, monthButtonProps))
134
151
  }));
135
152
  });
@@ -4,6 +4,7 @@ const _excluded = ["ampm", "timeSteps", "autoFocus", "slots", "slotProps", "valu
4
4
  import * as React from 'react';
5
5
  import clsx from 'clsx';
6
6
  import PropTypes from 'prop-types';
7
+ import { useRtl } from '@mui/system/RtlProvider';
7
8
  import { styled, useThemeProps } from '@mui/material/styles';
8
9
  import useEventCallback from '@mui/utils/useEventCallback';
9
10
  import composeClasses from '@mui/utils/composeClasses';
@@ -53,6 +54,7 @@ const MultiSectionDigitalClockRoot = styled(PickerViewRoot, {
53
54
  */
54
55
  export const MultiSectionDigitalClock = /*#__PURE__*/React.forwardRef(function MultiSectionDigitalClock(inProps, ref) {
55
56
  const utils = useUtils();
57
+ const isRtl = useRtl();
56
58
  const props = useThemeProps({
57
59
  props: inProps,
58
60
  name: 'MuiMultiSectionDigitalClock'
@@ -295,6 +297,17 @@ export const MultiSectionDigitalClock = /*#__PURE__*/React.forwardRef(function M
295
297
  throw new Error(`Unknown view: ${viewToBuild} found.`);
296
298
  }
297
299
  }, [now, value, ampm, utils, timeSteps.hours, timeSteps.minutes, timeSteps.seconds, localeText.hoursClockNumberText, localeText.minutesClockNumberText, localeText.secondsClockNumberText, meridiemMode, setValueAndGoToNextView, valueOrReferenceDate, isTimeDisabled, handleMeridiemChange]);
300
+ const viewsToRender = React.useMemo(() => {
301
+ if (!isRtl) {
302
+ return views;
303
+ }
304
+ const digitViews = views.filter(v => v !== 'meridiem');
305
+ const result = digitViews.toReversed();
306
+ if (views.includes('meridiem')) {
307
+ result.push('meridiem');
308
+ }
309
+ return result;
310
+ }, [isRtl, views]);
298
311
  const viewTimeOptions = React.useMemo(() => {
299
312
  return views.reduce((result, currentView) => {
300
313
  return _extends({}, result, {
@@ -310,9 +323,9 @@ export const MultiSectionDigitalClock = /*#__PURE__*/React.forwardRef(function M
310
323
  ownerState: ownerState,
311
324
  role: "group"
312
325
  }, other, {
313
- children: Object.entries(viewTimeOptions).map(([timeView, viewOptions]) => /*#__PURE__*/_jsx(MultiSectionDigitalClockSection, {
314
- items: viewOptions.items,
315
- onChange: viewOptions.onChange,
326
+ children: viewsToRender.map(timeView => /*#__PURE__*/_jsx(MultiSectionDigitalClockSection, {
327
+ items: viewTimeOptions[timeView].items,
328
+ onChange: viewTimeOptions[timeView].onChange,
316
329
  active: view === timeView,
317
330
  autoFocus: autoFocus ?? focusedView === timeView,
318
331
  disabled: disabled,