@mui/x-date-pickers 7.7.0 → 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 (76) 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 +82 -0
  6. package/DatePicker/DatePicker.js +2 -0
  7. package/DateTimePicker/DateTimePicker.js +2 -0
  8. package/DesktopDatePicker/DesktopDatePicker.js +2 -0
  9. package/DesktopDateTimePicker/DesktopDateTimePicker.js +2 -0
  10. package/DesktopTimePicker/DesktopTimePicker.js +2 -0
  11. package/MobileDatePicker/MobileDatePicker.js +2 -0
  12. package/MobileDateTimePicker/MobileDateTimePicker.js +2 -0
  13. package/MobileTimePicker/MobileTimePicker.js +2 -0
  14. package/MultiSectionDigitalClock/MultiSectionDigitalClock.js +16 -3
  15. package/PickersCalendarHeader/PickersCalendarHeader.js +4 -0
  16. package/PickersCalendarHeader/PickersCalendarHeader.types.d.ts +4 -0
  17. package/PickersLayout/usePickerLayout.js +0 -5
  18. package/StaticDatePicker/StaticDatePicker.js +2 -0
  19. package/StaticDateTimePicker/StaticDateTimePicker.js +2 -0
  20. package/StaticTimePicker/StaticTimePicker.js +2 -0
  21. package/TimePicker/TimePicker.js +2 -0
  22. package/index.js +1 -1
  23. package/internals/components/PickersArrowSwitcher/PickersArrowSwitcher.js +4 -2
  24. package/internals/components/PickersArrowSwitcher/PickersArrowSwitcher.types.d.ts +1 -0
  25. package/internals/hooks/useField/useField.utils.js +2 -1
  26. package/internals/hooks/usePicker/usePickerValue.js +45 -38
  27. package/internals/hooks/usePicker/usePickerValue.types.d.ts +3 -1
  28. package/internals/hooks/usePicker/usePickerViews.js +2 -1
  29. package/locales/daDK.js +15 -19
  30. package/modern/AdapterDateFnsJalaliV3/AdapterDateFnsJalaliV3.js +1 -0
  31. package/modern/AdapterDateFnsV3/AdapterDateFnsV3.js +1 -0
  32. package/modern/DatePicker/DatePicker.js +2 -0
  33. package/modern/DateTimePicker/DateTimePicker.js +2 -0
  34. package/modern/DesktopDatePicker/DesktopDatePicker.js +2 -0
  35. package/modern/DesktopDateTimePicker/DesktopDateTimePicker.js +2 -0
  36. package/modern/DesktopTimePicker/DesktopTimePicker.js +2 -0
  37. package/modern/MobileDatePicker/MobileDatePicker.js +2 -0
  38. package/modern/MobileDateTimePicker/MobileDateTimePicker.js +2 -0
  39. package/modern/MobileTimePicker/MobileTimePicker.js +2 -0
  40. package/modern/MultiSectionDigitalClock/MultiSectionDigitalClock.js +16 -3
  41. package/modern/PickersCalendarHeader/PickersCalendarHeader.js +4 -0
  42. package/modern/PickersLayout/usePickerLayout.js +0 -5
  43. package/modern/StaticDatePicker/StaticDatePicker.js +2 -0
  44. package/modern/StaticDateTimePicker/StaticDateTimePicker.js +2 -0
  45. package/modern/StaticTimePicker/StaticTimePicker.js +2 -0
  46. package/modern/TimePicker/TimePicker.js +2 -0
  47. package/modern/index.js +1 -1
  48. package/modern/internals/components/PickersArrowSwitcher/PickersArrowSwitcher.js +4 -2
  49. package/modern/internals/hooks/useField/useField.utils.js +2 -1
  50. package/modern/internals/hooks/usePicker/usePickerValue.js +45 -38
  51. package/modern/internals/hooks/usePicker/usePickerViews.js +2 -1
  52. package/modern/locales/daDK.js +15 -19
  53. package/node/AdapterDateFnsJalaliV3/AdapterDateFnsJalaliV3.js +1 -0
  54. package/node/AdapterDateFnsV3/AdapterDateFnsV3.js +1 -0
  55. package/node/DatePicker/DatePicker.js +2 -0
  56. package/node/DateTimePicker/DateTimePicker.js +2 -0
  57. package/node/DesktopDatePicker/DesktopDatePicker.js +2 -0
  58. package/node/DesktopDateTimePicker/DesktopDateTimePicker.js +2 -0
  59. package/node/DesktopTimePicker/DesktopTimePicker.js +2 -0
  60. package/node/MobileDatePicker/MobileDatePicker.js +2 -0
  61. package/node/MobileDateTimePicker/MobileDateTimePicker.js +2 -0
  62. package/node/MobileTimePicker/MobileTimePicker.js +2 -0
  63. package/node/MultiSectionDigitalClock/MultiSectionDigitalClock.js +16 -3
  64. package/node/PickersCalendarHeader/PickersCalendarHeader.js +4 -0
  65. package/node/PickersLayout/usePickerLayout.js +0 -5
  66. package/node/StaticDatePicker/StaticDatePicker.js +2 -0
  67. package/node/StaticDateTimePicker/StaticDateTimePicker.js +2 -0
  68. package/node/StaticTimePicker/StaticTimePicker.js +2 -0
  69. package/node/TimePicker/TimePicker.js +2 -0
  70. package/node/index.js +1 -1
  71. package/node/internals/components/PickersArrowSwitcher/PickersArrowSwitcher.js +4 -2
  72. package/node/internals/hooks/useField/useField.utils.js +2 -1
  73. package/node/internals/hooks/usePicker/usePickerValue.js +45 -38
  74. package/node/internals/hooks/usePicker/usePickerViews.js +2 -1
  75. package/node/locales/daDK.js +15 -19
  76. package/package.json +3 -3
@@ -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
  }
@@ -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,
@@ -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);
@@ -138,6 +138,7 @@ class AdapterDateFnsJalali extends _AdapterDateFnsBase.AdapterDateFnsBase {
138
138
  longFormatters: _format.longFormatters,
139
139
  lib: 'date-fns-jalali'
140
140
  });
141
+ // TODO: explicit return types can be removed once there is only one date-fns version supported
141
142
  this.parse = (value, format) => {
142
143
  if (value === '') {
143
144
  return null;
@@ -98,6 +98,7 @@ class AdapterDateFns extends _AdapterDateFnsBase.AdapterDateFnsBase {
98
98
  formats,
99
99
  longFormatters: _format.longFormatters
100
100
  });
101
+ // TODO: explicit return types can be removed once there is only one date-fns version supported
101
102
  this.parse = (value, format) => {
102
103
  if (value === '') {
103
104
  return null;
@@ -176,7 +176,9 @@ process.env.NODE_ENV !== "production" ? DatePicker.propTypes = {
176
176
  /**
177
177
  * Callback fired when the value is accepted.
178
178
  * @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.
179
+ * @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
179
180
  * @param {TValue} value The value that was just accepted.
181
+ * @param {FieldChangeHandlerContext<TError>} context The context containing the validation result of the current value.
180
182
  */
181
183
  onAccept: _propTypes.default.func,
182
184
  /**
@@ -214,7 +214,9 @@ process.env.NODE_ENV !== "production" ? DateTimePicker.propTypes = {
214
214
  /**
215
215
  * Callback fired when the value is accepted.
216
216
  * @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.
217
+ * @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
217
218
  * @param {TValue} value The value that was just accepted.
219
+ * @param {FieldChangeHandlerContext<TError>} context The context containing the validation result of the current value.
218
220
  */
219
221
  onAccept: _propTypes.default.func,
220
222
  /**
@@ -191,7 +191,9 @@ DesktopDatePicker.propTypes = {
191
191
  /**
192
192
  * Callback fired when the value is accepted.
193
193
  * @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.
194
+ * @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
194
195
  * @param {TValue} value The value that was just accepted.
196
+ * @param {FieldChangeHandlerContext<TError>} context The context containing the validation result of the current value.
195
197
  */
196
198
  onAccept: _propTypes.default.func,
197
199
  /**
@@ -314,7 +314,9 @@ DesktopDateTimePicker.propTypes = {
314
314
  /**
315
315
  * Callback fired when the value is accepted.
316
316
  * @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.
317
+ * @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
317
318
  * @param {TValue} value The value that was just accepted.
319
+ * @param {FieldChangeHandlerContext<TError>} context The context containing the validation result of the current value.
318
320
  */
319
321
  onAccept: _propTypes.default.func,
320
322
  /**
@@ -202,7 +202,9 @@ DesktopTimePicker.propTypes = {
202
202
  /**
203
203
  * Callback fired when the value is accepted.
204
204
  * @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.
205
+ * @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
205
206
  * @param {TValue} value The value that was just accepted.
207
+ * @param {FieldChangeHandlerContext<TError>} context The context containing the validation result of the current value.
206
208
  */
207
209
  onAccept: _propTypes.default.func,
208
210
  /**
@@ -188,7 +188,9 @@ MobileDatePicker.propTypes = {
188
188
  /**
189
189
  * Callback fired when the value is accepted.
190
190
  * @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.
191
+ * @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
191
192
  * @param {TValue} value The value that was just accepted.
193
+ * @param {FieldChangeHandlerContext<TError>} context The context containing the validation result of the current value.
192
194
  */
193
195
  onAccept: _propTypes.default.func,
194
196
  /**
@@ -236,7 +236,9 @@ MobileDateTimePicker.propTypes = {
236
236
  /**
237
237
  * Callback fired when the value is accepted.
238
238
  * @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.
239
+ * @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
239
240
  * @param {TValue} value The value that was just accepted.
241
+ * @param {FieldChangeHandlerContext<TError>} context The context containing the validation result of the current value.
240
242
  */
241
243
  onAccept: _propTypes.default.func,
242
244
  /**
@@ -181,7 +181,9 @@ MobileTimePicker.propTypes = {
181
181
  /**
182
182
  * Callback fired when the value is accepted.
183
183
  * @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.
184
+ * @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
184
185
  * @param {TValue} value The value that was just accepted.
186
+ * @param {FieldChangeHandlerContext<TError>} context The context containing the validation result of the current value.
185
187
  */
186
188
  onAccept: _propTypes.default.func,
187
189
  /**
@@ -10,6 +10,7 @@ var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runt
10
10
  var React = _interopRequireWildcard(require("react"));
11
11
  var _clsx = _interopRequireDefault(require("clsx"));
12
12
  var _propTypes = _interopRequireDefault(require("prop-types"));
13
+ var _RtlProvider = require("@mui/system/RtlProvider");
13
14
  var _styles = require("@mui/material/styles");
14
15
  var _useEventCallback = _interopRequireDefault(require("@mui/utils/useEventCallback"));
15
16
  var _composeClasses = _interopRequireDefault(require("@mui/utils/composeClasses"));
@@ -62,6 +63,7 @@ const MultiSectionDigitalClockRoot = (0, _styles.styled)(_PickerViewRoot.PickerV
62
63
  */
63
64
  const MultiSectionDigitalClock = exports.MultiSectionDigitalClock = /*#__PURE__*/React.forwardRef(function MultiSectionDigitalClock(inProps, ref) {
64
65
  const utils = (0, _useUtils.useUtils)();
66
+ const isRtl = (0, _RtlProvider.useRtl)();
65
67
  const props = (0, _styles.useThemeProps)({
66
68
  props: inProps,
67
69
  name: 'MuiMultiSectionDigitalClock'
@@ -304,6 +306,17 @@ const MultiSectionDigitalClock = exports.MultiSectionDigitalClock = /*#__PURE__*
304
306
  throw new Error(`Unknown view: ${viewToBuild} found.`);
305
307
  }
306
308
  }, [now, value, ampm, utils, timeSteps.hours, timeSteps.minutes, timeSteps.seconds, localeText.hoursClockNumberText, localeText.minutesClockNumberText, localeText.secondsClockNumberText, meridiemMode, setValueAndGoToNextView, valueOrReferenceDate, isTimeDisabled, handleMeridiemChange]);
309
+ const viewsToRender = React.useMemo(() => {
310
+ if (!isRtl) {
311
+ return views;
312
+ }
313
+ const digitViews = views.filter(v => v !== 'meridiem');
314
+ const result = digitViews.toReversed();
315
+ if (views.includes('meridiem')) {
316
+ result.push('meridiem');
317
+ }
318
+ return result;
319
+ }, [isRtl, views]);
307
320
  const viewTimeOptions = React.useMemo(() => {
308
321
  return views.reduce((result, currentView) => {
309
322
  return (0, _extends2.default)({}, result, {
@@ -319,9 +332,9 @@ const MultiSectionDigitalClock = exports.MultiSectionDigitalClock = /*#__PURE__*
319
332
  ownerState: ownerState,
320
333
  role: "group"
321
334
  }, other, {
322
- children: Object.entries(viewTimeOptions).map(([timeView, viewOptions]) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_MultiSectionDigitalClockSection.MultiSectionDigitalClockSection, {
323
- items: viewOptions.items,
324
- onChange: viewOptions.onChange,
335
+ children: viewsToRender.map(timeView => /*#__PURE__*/(0, _jsxRuntime.jsx)(_MultiSectionDigitalClockSection.MultiSectionDigitalClockSection, {
336
+ items: viewTimeOptions[timeView].items,
337
+ onChange: viewTimeOptions[timeView].onChange,
325
338
  active: view === timeView,
326
339
  autoFocus: autoFocus ?? focusedView === timeView,
327
340
  disabled: disabled,
@@ -252,6 +252,10 @@ process.env.NODE_ENV !== "production" ? PickersCalendarHeader.propTypes = {
252
252
  * @default `${adapter.formats.month} ${adapter.formats.year}`
253
253
  */
254
254
  format: _propTypes.default.string,
255
+ /**
256
+ * Id of the calendar text element.
257
+ * It is used to establish an `aria-labelledby` relationship with the calendar `grid` element.
258
+ */
255
259
  labelId: _propTypes.default.string,
256
260
  maxDate: _propTypes.default.object.isRequired,
257
261
  minDate: _propTypes.default.object.isRequired,
@@ -62,7 +62,6 @@ const usePickerLayout = props => {
62
62
  const classes = useUtilityClasses(props);
63
63
 
64
64
  // Action bar
65
-
66
65
  const ActionBar = slots?.actionBar ?? _PickersActionBar.PickersActionBar;
67
66
  const actionBarProps = (0, _utils.useSlotProps)({
68
67
  elementType: ActionBar,
@@ -82,7 +81,6 @@ const usePickerLayout = props => {
82
81
  const actionBar = /*#__PURE__*/(0, _jsxRuntime.jsx)(ActionBar, (0, _extends2.default)({}, actionBarProps));
83
82
 
84
83
  // Toolbar
85
-
86
84
  const Toolbar = slots?.toolbar;
87
85
  const toolbarProps = (0, _utils.useSlotProps)({
88
86
  elementType: Toolbar,
@@ -105,11 +103,9 @@ const usePickerLayout = props => {
105
103
  const toolbar = toolbarHasView(toolbarProps) && !!Toolbar ? /*#__PURE__*/(0, _jsxRuntime.jsx)(Toolbar, (0, _extends2.default)({}, toolbarProps)) : null;
106
104
 
107
105
  // Content
108
-
109
106
  const content = children;
110
107
 
111
108
  // Tabs
112
-
113
109
  const Tabs = slots?.tabs;
114
110
  const tabs = view && Tabs ? /*#__PURE__*/(0, _jsxRuntime.jsx)(Tabs, (0, _extends2.default)({
115
111
  view: view,
@@ -118,7 +114,6 @@ const usePickerLayout = props => {
118
114
  }, slotProps?.tabs)) : null;
119
115
 
120
116
  // Shortcuts
121
-
122
117
  const Shortcuts = slots?.shortcuts ?? _PickersShortcuts.PickersShortcuts;
123
118
  const shortcutsProps = (0, _utils.useSlotProps)({
124
119
  elementType: Shortcuts,
@@ -142,7 +142,9 @@ StaticDatePicker.propTypes = {
142
142
  /**
143
143
  * Callback fired when the value is accepted.
144
144
  * @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.
145
+ * @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
145
146
  * @param {TValue} value The value that was just accepted.
147
+ * @param {FieldChangeHandlerContext<TError>} context The context containing the validation result of the current value.
146
148
  */
147
149
  onAccept: _propTypes.default.func,
148
150
  /**
@@ -190,7 +190,9 @@ StaticDateTimePicker.propTypes = {
190
190
  /**
191
191
  * Callback fired when the value is accepted.
192
192
  * @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.
193
+ * @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
193
194
  * @param {TValue} value The value that was just accepted.
195
+ * @param {FieldChangeHandlerContext<TError>} context The context containing the validation result of the current value.
194
196
  */
195
197
  onAccept: _propTypes.default.func,
196
198
  /**
@@ -134,7 +134,9 @@ StaticTimePicker.propTypes = {
134
134
  /**
135
135
  * Callback fired when the value is accepted.
136
136
  * @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.
137
+ * @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
137
138
  * @param {TValue} value The value that was just accepted.
139
+ * @param {FieldChangeHandlerContext<TError>} context The context containing the validation result of the current value.
138
140
  */
139
141
  onAccept: _propTypes.default.func,
140
142
  /**
@@ -166,7 +166,9 @@ process.env.NODE_ENV !== "production" ? TimePicker.propTypes = {
166
166
  /**
167
167
  * Callback fired when the value is accepted.
168
168
  * @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.
169
+ * @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
169
170
  * @param {TValue} value The value that was just accepted.
171
+ * @param {FieldChangeHandlerContext<TError>} context The context containing the validation result of the current value.
170
172
  */
171
173
  onAccept: _propTypes.default.func,
172
174
  /**
package/node/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-date-pickers v7.7.0
2
+ * @mui/x-date-pickers v7.7.1
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -18,7 +18,7 @@ var _IconButton = _interopRequireDefault(require("@mui/material/IconButton"));
18
18
  var _icons = require("../../../icons");
19
19
  var _pickersArrowSwitcherClasses = require("./pickersArrowSwitcherClasses");
20
20
  var _jsxRuntime = require("react/jsx-runtime");
21
- const _excluded = ["children", "className", "slots", "slotProps", "isNextDisabled", "isNextHidden", "onGoToNext", "nextLabel", "isPreviousDisabled", "isPreviousHidden", "onGoToPrevious", "previousLabel"],
21
+ const _excluded = ["children", "className", "slots", "slotProps", "isNextDisabled", "isNextHidden", "onGoToNext", "nextLabel", "isPreviousDisabled", "isPreviousHidden", "onGoToPrevious", "previousLabel", "labelId"],
22
22
  _excluded2 = ["ownerState"],
23
23
  _excluded3 = ["ownerState"];
24
24
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
@@ -82,7 +82,8 @@ const PickersArrowSwitcher = exports.PickersArrowSwitcher = /*#__PURE__*/React.f
82
82
  isPreviousDisabled,
83
83
  isPreviousHidden,
84
84
  onGoToPrevious,
85
- previousLabel
85
+ previousLabel,
86
+ labelId
86
87
  } = props,
87
88
  other = (0, _objectWithoutPropertiesLoose2.default)(props, _excluded);
88
89
  const ownerState = props;
@@ -165,6 +166,7 @@ const PickersArrowSwitcher = exports.PickersArrowSwitcher = /*#__PURE__*/React.f
165
166
  })), children ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_Typography.default, {
166
167
  variant: "subtitle1",
167
168
  component: "span",
169
+ id: labelId,
168
170
  children: children
169
171
  }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(PickersArrowSwitcherSpacer, {
170
172
  className: classes.spacer,
@@ -115,7 +115,8 @@ const applyLocalizedDigits = (valueStr, localizedDigits) => {
115
115
  exports.applyLocalizedDigits = applyLocalizedDigits;
116
116
  const isStringNumber = (valueStr, localizedDigits) => {
117
117
  const nonLocalizedValueStr = removeLocalizedDigits(valueStr, localizedDigits);
118
- return !Number.isNaN(Number(nonLocalizedValueStr));
118
+ // `Number(' ')` returns `0` even if ' ' is not a valid number.
119
+ return nonLocalizedValueStr !== ' ' && !Number.isNaN(Number(nonLocalizedValueStr));
119
120
  };
120
121
 
121
122
  /**
@@ -127,7 +127,7 @@ const usePickerValue = ({
127
127
  const {
128
128
  onAccept,
129
129
  onChange,
130
- value: inValue,
130
+ value: inValueWithoutRenderTimezone,
131
131
  defaultValue: inDefaultValue,
132
132
  closeOnSelect = wrapperVariant === 'desktop',
133
133
  timezone: timezoneProp
@@ -137,15 +137,15 @@ const usePickerValue = ({
137
137
  } = React.useRef(inDefaultValue);
138
138
  const {
139
139
  current: isControlled
140
- } = React.useRef(inValue !== undefined);
140
+ } = React.useRef(inValueWithoutRenderTimezone !== undefined);
141
141
 
142
142
  /* eslint-disable react-hooks/rules-of-hooks, react-hooks/exhaustive-deps */
143
143
  if (process.env.NODE_ENV !== 'production') {
144
144
  React.useEffect(() => {
145
- if (isControlled !== (inValue !== undefined)) {
145
+ if (isControlled !== (inValueWithoutRenderTimezone !== undefined)) {
146
146
  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'));
147
147
  }
148
- }, [inValue]);
148
+ }, [inValueWithoutRenderTimezone]);
149
149
  React.useEffect(() => {
150
150
  if (!isControlled && defaultValue !== inDefaultValue) {
151
151
  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'));
@@ -160,10 +160,21 @@ const usePickerValue = ({
160
160
  isOpen,
161
161
  setIsOpen
162
162
  } = (0, _useOpenState.useOpenState)(props);
163
+ const {
164
+ timezone,
165
+ value: inValueWithTimezoneToRender,
166
+ handleValueChange
167
+ } = (0, _useValueWithTimezone.useValueWithTimezone)({
168
+ timezone: timezoneProp,
169
+ value: inValueWithoutRenderTimezone,
170
+ defaultValue,
171
+ onChange,
172
+ valueManager
173
+ });
163
174
  const [dateState, setDateState] = React.useState(() => {
164
175
  let initialValue;
165
- if (inValue !== undefined) {
166
- initialValue = inValue;
176
+ if (inValueWithTimezoneToRender !== undefined) {
177
+ initialValue = inValueWithTimezoneToRender;
167
178
  } else if (defaultValue !== undefined) {
168
179
  initialValue = defaultValue;
169
180
  } else {
@@ -173,20 +184,10 @@ const usePickerValue = ({
173
184
  draft: initialValue,
174
185
  lastPublishedValue: initialValue,
175
186
  lastCommittedValue: initialValue,
176
- lastControlledValue: inValue,
187
+ lastControlledValue: inValueWithTimezoneToRender,
177
188
  hasBeenModifiedSinceMount: false
178
189
  };
179
190
  });
180
- const {
181
- timezone,
182
- handleValueChange
183
- } = (0, _useValueWithTimezone.useValueWithTimezone)({
184
- timezone: timezoneProp,
185
- value: inValue,
186
- defaultValue,
187
- onChange,
188
- valueManager
189
- });
190
191
  (0, _useValidation.useValidation)((0, _extends2.default)({}, props, {
191
192
  value: dateState.draft,
192
193
  timezone
@@ -208,38 +209,44 @@ const usePickerValue = ({
208
209
  lastCommittedValue: shouldCommit ? action.value : prev.lastCommittedValue,
209
210
  hasBeenModifiedSinceMount: true
210
211
  }));
211
- if (shouldPublish) {
212
- const validationError = action.name === 'setValueFromField' ? action.context.validationError : validator({
213
- adapter,
214
- value: action.value,
215
- props: (0, _extends2.default)({}, props, {
212
+ let cachedContext = null;
213
+ const getContext = () => {
214
+ if (!cachedContext) {
215
+ const validationError = action.name === 'setValueFromField' ? action.context.validationError : validator({
216
+ adapter,
216
217
  value: action.value,
217
- timezone
218
- })
219
- });
220
- const context = {
221
- validationError
222
- };
223
- if (action.name === 'setValueFromShortcut') {
224
- context.shortcut = action.shortcut;
218
+ props: (0, _extends2.default)({}, props, {
219
+ value: action.value,
220
+ timezone
221
+ })
222
+ });
223
+ cachedContext = {
224
+ validationError
225
+ };
226
+ if (action.name === 'setValueFromShortcut') {
227
+ cachedContext.shortcut = action.shortcut;
228
+ }
225
229
  }
226
- handleValueChange(action.value, context);
230
+ return cachedContext;
231
+ };
232
+ if (shouldPublish) {
233
+ handleValueChange(action.value, getContext());
227
234
  }
228
235
  if (shouldCommit && onAccept) {
229
- onAccept(action.value);
236
+ onAccept(action.value, getContext());
230
237
  }
231
238
  if (shouldClose) {
232
239
  setIsOpen(false);
233
240
  }
234
241
  });
235
- if (inValue !== undefined && (dateState.lastControlledValue === undefined || !valueManager.areValuesEqual(utils, dateState.lastControlledValue, inValue))) {
236
- const isUpdateComingFromPicker = valueManager.areValuesEqual(utils, dateState.draft, inValue);
242
+ if (inValueWithTimezoneToRender !== undefined && (dateState.lastControlledValue === undefined || !valueManager.areValuesEqual(utils, dateState.lastControlledValue, inValueWithTimezoneToRender))) {
243
+ const isUpdateComingFromPicker = valueManager.areValuesEqual(utils, dateState.draft, inValueWithTimezoneToRender);
237
244
  setDateState(prev => (0, _extends2.default)({}, prev, {
238
- lastControlledValue: inValue
245
+ lastControlledValue: inValueWithTimezoneToRender
239
246
  }, isUpdateComingFromPicker ? {} : {
240
- lastCommittedValue: inValue,
241
- lastPublishedValue: inValue,
242
- draft: inValue,
247
+ lastCommittedValue: inValueWithTimezoneToRender,
248
+ lastPublishedValue: inValueWithTimezoneToRender,
249
+ draft: inValueWithTimezoneToRender,
243
250
  hasBeenModifiedSinceMount: true
244
251
  }));
245
252
  }