@mui/x-date-pickers 7.19.0 → 7.20.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 (109) hide show
  1. package/CHANGELOG.md +105 -13
  2. package/DateCalendar/DateCalendar.js +1 -1
  3. package/DateCalendar/DateCalendar.types.d.ts +1 -1
  4. package/DateField/DateField.types.d.ts +2 -7
  5. package/DateField/index.d.ts +1 -1
  6. package/DatePicker/DatePicker.js +1 -1
  7. package/DatePicker/DatePicker.types.d.ts +8 -1
  8. package/DatePicker/index.d.ts +1 -1
  9. package/DateTimeField/DateTimeField.types.d.ts +2 -7
  10. package/DateTimeField/index.d.ts +1 -1
  11. package/DateTimePicker/DateTimePicker.js +1 -1
  12. package/DateTimePicker/DateTimePicker.types.d.ts +9 -1
  13. package/DateTimePicker/DateTimePickerTabs.js +1 -1
  14. package/DateTimePicker/index.d.ts +1 -1
  15. package/DesktopDatePicker/DesktopDatePicker.js +1 -1
  16. package/DesktopDateTimePicker/DesktopDateTimePicker.js +1 -1
  17. package/DigitalClock/DigitalClock.js +39 -0
  18. package/MobileDatePicker/MobileDatePicker.js +1 -1
  19. package/MobileDateTimePicker/MobileDateTimePicker.js +1 -1
  20. package/MultiSectionDigitalClock/MultiSectionDigitalClockSection.js +38 -1
  21. package/StaticDatePicker/StaticDatePicker.js +1 -1
  22. package/StaticDateTimePicker/StaticDateTimePicker.js +1 -1
  23. package/TimeClock/Clock.js +8 -0
  24. package/TimeField/TimeField.types.d.ts +2 -7
  25. package/TimeField/index.d.ts +1 -1
  26. package/TimePicker/TimePicker.types.d.ts +9 -1
  27. package/TimePicker/index.d.ts +1 -1
  28. package/hooks/index.d.ts +2 -0
  29. package/hooks/index.js +3 -1
  30. package/hooks/useParsedFormat.d.ts +15 -0
  31. package/hooks/useParsedFormat.js +43 -0
  32. package/hooks/usePickersContext.d.ts +4 -0
  33. package/hooks/usePickersContext.js +15 -0
  34. package/index.js +1 -1
  35. package/internals/components/PickersProvider.d.ts +34 -0
  36. package/internals/components/PickersProvider.js +26 -0
  37. package/internals/hooks/useDesktopPicker/useDesktopPicker.js +7 -4
  38. package/internals/hooks/useField/buildSectionsFromFormat.d.ts +1 -2
  39. package/internals/hooks/useField/buildSectionsFromFormat.js +4 -5
  40. package/internals/hooks/useField/useField.utils.d.ts +3 -3
  41. package/internals/hooks/useField/useField.utils.js +13 -13
  42. package/internals/hooks/useField/useFieldCharacterEditing.js +2 -2
  43. package/internals/hooks/useField/useFieldState.js +3 -5
  44. package/internals/hooks/useMobilePicker/useMobilePicker.js +7 -4
  45. package/internals/hooks/usePicker/usePicker.js +3 -1
  46. package/internals/hooks/usePicker/usePickerValue.js +7 -2
  47. package/internals/hooks/usePicker/usePickerValue.types.d.ts +2 -0
  48. package/internals/index.d.ts +1 -0
  49. package/internals/index.js +1 -0
  50. package/internals/utils/utils.d.ts +7 -0
  51. package/internals/utils/utils.js +11 -0
  52. package/models/pickers.d.ts +1 -1
  53. package/modern/DateCalendar/DateCalendar.js +1 -1
  54. package/modern/DatePicker/DatePicker.js +1 -1
  55. package/modern/DateTimePicker/DateTimePicker.js +1 -1
  56. package/modern/DateTimePicker/DateTimePickerTabs.js +1 -1
  57. package/modern/DesktopDatePicker/DesktopDatePicker.js +1 -1
  58. package/modern/DesktopDateTimePicker/DesktopDateTimePicker.js +1 -1
  59. package/modern/DigitalClock/DigitalClock.js +39 -0
  60. package/modern/MobileDatePicker/MobileDatePicker.js +1 -1
  61. package/modern/MobileDateTimePicker/MobileDateTimePicker.js +1 -1
  62. package/modern/MultiSectionDigitalClock/MultiSectionDigitalClockSection.js +38 -1
  63. package/modern/StaticDatePicker/StaticDatePicker.js +1 -1
  64. package/modern/StaticDateTimePicker/StaticDateTimePicker.js +1 -1
  65. package/modern/TimeClock/Clock.js +8 -0
  66. package/modern/hooks/index.js +3 -1
  67. package/modern/hooks/useParsedFormat.js +43 -0
  68. package/modern/hooks/usePickersContext.js +15 -0
  69. package/modern/index.js +1 -1
  70. package/modern/internals/components/PickersProvider.js +26 -0
  71. package/modern/internals/hooks/useDesktopPicker/useDesktopPicker.js +7 -4
  72. package/modern/internals/hooks/useField/buildSectionsFromFormat.js +4 -5
  73. package/modern/internals/hooks/useField/useField.utils.js +13 -13
  74. package/modern/internals/hooks/useField/useFieldCharacterEditing.js +2 -2
  75. package/modern/internals/hooks/useField/useFieldState.js +3 -5
  76. package/modern/internals/hooks/useMobilePicker/useMobilePicker.js +7 -4
  77. package/modern/internals/hooks/usePicker/usePicker.js +3 -1
  78. package/modern/internals/hooks/usePicker/usePickerValue.js +7 -2
  79. package/modern/internals/index.js +1 -0
  80. package/modern/internals/utils/utils.js +11 -0
  81. package/node/DateCalendar/DateCalendar.js +1 -1
  82. package/node/DatePicker/DatePicker.js +1 -1
  83. package/node/DateTimePicker/DateTimePicker.js +1 -1
  84. package/node/DateTimePicker/DateTimePickerTabs.js +1 -1
  85. package/node/DesktopDatePicker/DesktopDatePicker.js +1 -1
  86. package/node/DesktopDateTimePicker/DesktopDateTimePicker.js +1 -1
  87. package/node/DigitalClock/DigitalClock.js +39 -0
  88. package/node/MobileDatePicker/MobileDatePicker.js +1 -1
  89. package/node/MobileDateTimePicker/MobileDateTimePicker.js +1 -1
  90. package/node/MultiSectionDigitalClock/MultiSectionDigitalClockSection.js +38 -1
  91. package/node/StaticDatePicker/StaticDatePicker.js +1 -1
  92. package/node/StaticDateTimePicker/StaticDateTimePicker.js +1 -1
  93. package/node/TimeClock/Clock.js +8 -0
  94. package/node/hooks/index.js +15 -1
  95. package/node/hooks/useParsedFormat.js +50 -0
  96. package/node/hooks/usePickersContext.js +21 -0
  97. package/node/index.js +1 -1
  98. package/node/internals/components/PickersProvider.js +34 -0
  99. package/node/internals/hooks/useDesktopPicker/useDesktopPicker.js +5 -3
  100. package/node/internals/hooks/useField/buildSectionsFromFormat.js +4 -5
  101. package/node/internals/hooks/useField/useField.utils.js +13 -13
  102. package/node/internals/hooks/useField/useFieldCharacterEditing.js +2 -2
  103. package/node/internals/hooks/useField/useFieldState.js +3 -5
  104. package/node/internals/hooks/useMobilePicker/useMobilePicker.js +5 -3
  105. package/node/internals/hooks/usePicker/usePicker.js +3 -1
  106. package/node/internals/hooks/usePicker/usePickerValue.js +7 -1
  107. package/node/internals/index.js +7 -0
  108. package/node/internals/utils/utils.js +13 -1
  109. package/package.json +4 -4
@@ -256,7 +256,7 @@ process.env.NODE_ENV !== "production" ? DatePicker.propTypes = {
256
256
  /**
257
257
  * Component displaying when passed `loading` true.
258
258
  * @returns {React.ReactNode} The node to render when loading.
259
- * @default () => <span data-mui-test="loading-progress">...</span>
259
+ * @default () => <span>...</span>
260
260
  */
261
261
  renderLoading: PropTypes.func,
262
262
  /**
@@ -294,7 +294,7 @@ process.env.NODE_ENV !== "production" ? DateTimePicker.propTypes = {
294
294
  /**
295
295
  * Component displaying when passed `loading` true.
296
296
  * @returns {React.ReactNode} The node to render when loading.
297
- * @default () => <span data-mui-test="loading-progress">...</span>
297
+ * @default () => <span>...</span>
298
298
  */
299
299
  renderLoading: PropTypes.func,
300
300
  /**
@@ -87,7 +87,7 @@ const DateTimePickerTabs = function DateTimePickerTabs(inProps) {
87
87
  variant: "fullWidth",
88
88
  value: viewToTab(view),
89
89
  onChange: handleChange,
90
- className: clsx(classes.root, className),
90
+ className: clsx(className, classes.root),
91
91
  sx: sx,
92
92
  children: [/*#__PURE__*/_jsx(Tab, {
93
93
  value: "date",
@@ -277,7 +277,7 @@ DesktopDatePicker.propTypes = {
277
277
  /**
278
278
  * Component displaying when passed `loading` true.
279
279
  * @returns {React.ReactNode} The node to render when loading.
280
- * @default () => <span data-mui-test="loading-progress">...</span>
280
+ * @default () => <span>...</span>
281
281
  */
282
282
  renderLoading: PropTypes.func,
283
283
  /**
@@ -402,7 +402,7 @@ DesktopDateTimePicker.propTypes = {
402
402
  /**
403
403
  * Component displaying when passed `loading` true.
404
404
  * @returns {React.ReactNode} The node to render when loading.
405
- * @default () => <span data-mui-test="loading-progress">...</span>
405
+ * @default () => <span>...</span>
406
406
  */
407
407
  renderLoading: PropTypes.func,
408
408
  /**
@@ -23,6 +23,7 @@ import { DIGITAL_CLOCK_VIEW_HEIGHT } from "../internals/constants/dimensions.js"
23
23
  import { useControlledValueWithTimezone } from "../internals/hooks/useValueWithTimezone.js";
24
24
  import { singleItemValueManager } from "../internals/utils/valueManagers.js";
25
25
  import { useClockReferenceDate } from "../internals/hooks/useClockReferenceDate.js";
26
+ import { getFocusedListItemIndex } from "../internals/utils/utils.js";
26
27
  import { jsx as _jsx } from "react/jsx-runtime";
27
28
  const useUtilityClasses = ownerState => {
28
29
  const {
@@ -104,6 +105,7 @@ export const DigitalClock = /*#__PURE__*/React.forwardRef(function DigitalClock(
104
105
  const utils = useUtils();
105
106
  const containerRef = React.useRef(null);
106
107
  const handleRef = useForkRef(ref, containerRef);
108
+ const listRef = React.useRef(null);
107
109
  const props = useThemeProps({
108
110
  props: inProps,
109
111
  name: 'MuiDigitalClock'
@@ -236,15 +238,52 @@ export const DigitalClock = /*#__PURE__*/React.forwardRef(function DigitalClock(
236
238
  }, (_, index) => utils.addMinutes(startOfDay, timeStep * (index + 1)))];
237
239
  }, [valueOrReferenceDate, timeStep, utils]);
238
240
  const focusedOptionIndex = timeOptions.findIndex(option => utils.isEqual(option, valueOrReferenceDate));
241
+ const handleKeyDown = event => {
242
+ switch (event.key) {
243
+ case 'PageUp':
244
+ {
245
+ if (!listRef.current) {
246
+ return;
247
+ }
248
+ const newIndex = getFocusedListItemIndex(listRef.current) - 5;
249
+ const children = listRef.current?.children;
250
+ const newFocusedIndex = Math.max(0, newIndex);
251
+ const childToFocus = children[newFocusedIndex];
252
+ if (childToFocus) {
253
+ childToFocus.focus();
254
+ }
255
+ event.preventDefault();
256
+ break;
257
+ }
258
+ case 'PageDown':
259
+ {
260
+ if (!listRef.current) {
261
+ return;
262
+ }
263
+ const newIndex = getFocusedListItemIndex(listRef.current) + 5;
264
+ const children = listRef.current?.children;
265
+ const newFocusedIndex = Math.min(children.length - 1, newIndex);
266
+ const childToFocus = children[newFocusedIndex];
267
+ if (childToFocus) {
268
+ childToFocus.focus();
269
+ }
270
+ event.preventDefault();
271
+ break;
272
+ }
273
+ default:
274
+ }
275
+ };
239
276
  return /*#__PURE__*/_jsx(DigitalClockRoot, _extends({
240
277
  ref: handleRef,
241
278
  className: clsx(classes.root, className),
242
279
  ownerState: ownerState
243
280
  }, other, {
244
281
  children: /*#__PURE__*/_jsx(DigitalClockList, {
282
+ ref: listRef,
245
283
  role: "listbox",
246
284
  "aria-label": translations.timePickerToolbarTitle,
247
285
  className: classes.list,
286
+ onKeyDown: handleKeyDown,
248
287
  children: timeOptions.map((option, index) => {
249
288
  if (skipDisabled && isTimeDisabled(option)) {
250
289
  return null;
@@ -274,7 +274,7 @@ MobileDatePicker.propTypes = {
274
274
  /**
275
275
  * Component displaying when passed `loading` true.
276
276
  * @returns {React.ReactNode} The node to render when loading.
277
- * @default () => <span data-mui-test="loading-progress">...</span>
277
+ * @default () => <span>...</span>
278
278
  */
279
279
  renderLoading: PropTypes.func,
280
280
  /**
@@ -322,7 +322,7 @@ MobileDateTimePicker.propTypes = {
322
322
  /**
323
323
  * Component displaying when passed `loading` true.
324
324
  * @returns {React.ReactNode} The node to render when loading.
325
- * @default () => <span data-mui-test="loading-progress">...</span>
325
+ * @default () => <span>...</span>
326
326
  */
327
327
  renderLoading: PropTypes.func,
328
328
  /**
@@ -10,6 +10,7 @@ import MenuItem from '@mui/material/MenuItem';
10
10
  import useForkRef from '@mui/utils/useForkRef';
11
11
  import { getMultiSectionDigitalClockSectionUtilityClass } from "./multiSectionDigitalClockSectionClasses.js";
12
12
  import { DIGITAL_CLOCK_VIEW_HEIGHT, MULTI_SECTION_CLOCK_SECTION_WIDTH } from "../internals/constants/dimensions.js";
13
+ import { getFocusedListItemIndex } from "../internals/utils/utils.js";
13
14
  import { jsx as _jsx } from "react/jsx-runtime";
14
15
  const useUtilityClasses = ownerState => {
15
16
  const {
@@ -138,12 +139,48 @@ export const MultiSectionDigitalClockSection = /*#__PURE__*/React.forwardRef(fun
138
139
  containerRef.current.scrollTop = offsetTop - 4;
139
140
  });
140
141
  const focusedOptionIndex = items.findIndex(item => item.isFocused(item.value));
142
+ const handleKeyDown = event => {
143
+ switch (event.key) {
144
+ case 'PageUp':
145
+ {
146
+ if (!containerRef.current) {
147
+ return;
148
+ }
149
+ const newIndex = getFocusedListItemIndex(containerRef.current) - 5;
150
+ const children = containerRef.current?.children;
151
+ const newFocusedIndex = Math.max(0, newIndex);
152
+ const childToFocus = children[newFocusedIndex];
153
+ if (childToFocus) {
154
+ childToFocus.focus();
155
+ }
156
+ event.preventDefault();
157
+ break;
158
+ }
159
+ case 'PageDown':
160
+ {
161
+ if (!containerRef.current) {
162
+ return;
163
+ }
164
+ const newIndex = getFocusedListItemIndex(containerRef.current) + 5;
165
+ const children = containerRef.current?.children;
166
+ const newFocusedIndex = Math.min(children.length - 1, newIndex);
167
+ const childToFocus = children[newFocusedIndex];
168
+ if (childToFocus) {
169
+ childToFocus.focus();
170
+ }
171
+ event.preventDefault();
172
+ break;
173
+ }
174
+ default:
175
+ }
176
+ };
141
177
  return /*#__PURE__*/_jsx(MultiSectionDigitalClockSectionRoot, _extends({
142
178
  ref: handleRef,
143
179
  className: clsx(classes.root, className),
144
180
  ownerState: ownerState,
145
181
  autoFocusItem: autoFocus && active,
146
- role: "listbox"
182
+ role: "listbox",
183
+ onKeyDown: handleKeyDown
147
184
  }, other, {
148
185
  children: items.map((option, index) => {
149
186
  const isItemDisabled = option.isDisabled?.(option.value);
@@ -208,7 +208,7 @@ StaticDatePicker.propTypes = {
208
208
  /**
209
209
  * Component displaying when passed `loading` true.
210
210
  * @returns {React.ReactNode} The node to render when loading.
211
- * @default () => <span data-mui-test="loading-progress">...</span>
211
+ * @default () => <span>...</span>
212
212
  */
213
213
  renderLoading: PropTypes.func,
214
214
  /**
@@ -256,7 +256,7 @@ StaticDateTimePicker.propTypes = {
256
256
  /**
257
257
  * Component displaying when passed `loading` true.
258
258
  * @returns {React.ReactNode} The node to render when loading.
259
- * @default () => <span data-mui-test="loading-progress">...</span>
259
+ * @default () => <span>...</span>
260
260
  */
261
261
  renderLoading: PropTypes.func,
262
262
  /**
@@ -274,6 +274,14 @@ export function Clock(inProps) {
274
274
  handleValueChange(viewValue - keyboardControlStep, 'partial');
275
275
  event.preventDefault();
276
276
  break;
277
+ case 'PageUp':
278
+ handleValueChange(viewValue + 5, 'partial');
279
+ event.preventDefault();
280
+ break;
281
+ case 'PageDown':
282
+ handleValueChange(viewValue - 5, 'partial');
283
+ event.preventDefault();
284
+ break;
277
285
  case 'Enter':
278
286
  case ' ':
279
287
  handleValueChange(viewValue, 'finish');
@@ -1,3 +1,5 @@
1
1
  export { useClearableField } from "./useClearableField.js";
2
2
  export { usePickersTranslations } from "./usePickersTranslations.js";
3
- export { useSplitFieldProps } from "./useSplitFieldProps.js";
3
+ export { useSplitFieldProps } from "./useSplitFieldProps.js";
4
+ export { useParsedFormat } from "./useParsedFormat.js";
5
+ export { usePickersContext } from "./usePickersContext.js";
@@ -0,0 +1,43 @@
1
+ 'use client';
2
+
3
+ import * as React from 'react';
4
+ import { useRtl } from '@mui/system/RtlProvider';
5
+ import { useUtils } from "../internals/hooks/useUtils.js";
6
+ import { buildSectionsFromFormat } from "../internals/hooks/useField/buildSectionsFromFormat.js";
7
+ import { getLocalizedDigits } from "../internals/hooks/useField/useField.utils.js";
8
+ import { usePickersTranslations } from "./usePickersTranslations.js";
9
+ /**
10
+ * Returns the parsed format to be rendered in the field when there is no value or in other parts of the Picker.
11
+ * This format is localized (e.g: `AAAA` for the year with the French locale) and cannot be parsed by your date library.
12
+ * @param {object} The parameters needed to build the placeholder.
13
+ * @param {string} params.format Format of the date to use.
14
+ * @param {'dense' | 'spacious'} params.formatDensity Density of the format (setting `formatDensity` to `"spacious"` will add a space before and after each `/`, `-` and `.` character).
15
+ * @param {boolean} params.shouldRespectLeadingZeros If `true`, the format will respect the leading zeroes, if `false`, the format will always add leading zeroes.
16
+ * @returns
17
+ */
18
+ export const useParsedFormat = parameters => {
19
+ const {
20
+ format,
21
+ formatDensity = 'dense',
22
+ shouldRespectLeadingZeros = false
23
+ } = parameters;
24
+ const utils = useUtils();
25
+ const isRtl = useRtl();
26
+ const translations = usePickersTranslations();
27
+ const localizedDigits = React.useMemo(() => getLocalizedDigits(utils), [utils]);
28
+ return React.useMemo(() => {
29
+ const sections = buildSectionsFromFormat({
30
+ utils,
31
+ format,
32
+ formatDensity,
33
+ isRtl,
34
+ shouldRespectLeadingZeros,
35
+ localeText: translations,
36
+ localizedDigits,
37
+ date: null,
38
+ // TODO v9: Make sure we still don't reverse in `buildSectionsFromFormat` when using `useParsedFormat`.
39
+ enableAccessibleFieldDOMStructure: false
40
+ });
41
+ return sections.map(section => `${section.startSeparator}${section.placeholder}${section.endSeparator}`).join('');
42
+ }, [utils, isRtl, translations, localizedDigits, format, formatDensity, shouldRespectLeadingZeros]);
43
+ };
@@ -0,0 +1,15 @@
1
+ 'use client';
2
+
3
+ import * as React from 'react';
4
+ import { PickersContext } from "../internals/components/PickersProvider.js";
5
+
6
+ /**
7
+ * Returns the context passed by the picker that wraps the current component.
8
+ */
9
+ export const usePickersContext = () => {
10
+ const value = React.useContext(PickersContext);
11
+ if (value == null) {
12
+ throw new Error(['MUI X: The `usePickersContext` can only be called in fields that are used as a slot of a picker component'].join('\n'));
13
+ }
14
+ return value;
15
+ };
package/modern/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-date-pickers v7.19.0
2
+ * @mui/x-date-pickers v7.20.0
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -0,0 +1,26 @@
1
+ import * as React from 'react';
2
+ import { LocalizationProvider } from "../../LocalizationProvider/index.js";
3
+ import { jsx as _jsx } from "react/jsx-runtime";
4
+ export const PickersContext = /*#__PURE__*/React.createContext(null);
5
+
6
+ /**
7
+ * Provides the context for the various parts of a picker component:
8
+ * - contextValue: the context for the picker sub-components.
9
+ * - localizationProvider: the translations passed through the props and through a parent LocalizationProvider.
10
+ *
11
+ * @ignore - do not document.
12
+ */
13
+ export function PickersProvider(props) {
14
+ const {
15
+ contextValue,
16
+ localeText,
17
+ children
18
+ } = props;
19
+ return /*#__PURE__*/_jsx(PickersContext.Provider, {
20
+ value: contextValue,
21
+ children: /*#__PURE__*/_jsx(LocalizationProvider, {
22
+ localeText: localeText,
23
+ children: children
24
+ })
25
+ });
26
+ }
@@ -11,15 +11,16 @@ import useForkRef from '@mui/utils/useForkRef';
11
11
  import useId from '@mui/utils/useId';
12
12
  import { PickersPopper } from "../../components/PickersPopper.js";
13
13
  import { usePicker } from "../usePicker/index.js";
14
- import { LocalizationProvider } from "../../../LocalizationProvider/index.js";
15
14
  import { PickersLayout } from "../../../PickersLayout/index.js";
16
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
15
+ import { PickersProvider } from "../../components/PickersProvider.js";
16
+
17
17
  /**
18
18
  * Hook managing all the single-date desktop pickers:
19
19
  * - DesktopDatePicker
20
20
  * - DesktopDateTimePicker
21
21
  * - DesktopTimePicker
22
22
  */
23
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
23
24
  export const useDesktopPicker = _ref => {
24
25
  let {
25
26
  props,
@@ -57,7 +58,8 @@ export const useDesktopPicker = _ref => {
57
58
  layoutProps,
58
59
  renderCurrentView,
59
60
  shouldRestoreFocus,
60
- fieldProps: pickerFieldProps
61
+ fieldProps: pickerFieldProps,
62
+ contextValue
61
63
  } = usePicker(_extends({}, pickerParams, {
62
64
  props,
63
65
  fieldRef,
@@ -161,7 +163,8 @@ export const useDesktopPicker = _ref => {
161
163
  }, innerSlotProps?.popper)
162
164
  });
163
165
  const handleFieldRef = useForkRef(fieldRef, fieldProps.unstableFieldRef);
164
- const renderPicker = () => /*#__PURE__*/_jsxs(LocalizationProvider, {
166
+ const renderPicker = () => /*#__PURE__*/_jsxs(PickersProvider, {
167
+ contextValue: contextValue,
165
168
  localeText: localeText,
166
169
  children: [/*#__PURE__*/_jsx(Field, _extends({}, fieldProps, {
167
170
  slots: slotsForField,
@@ -38,12 +38,12 @@ const getEscapedPartsFromFormat = ({
38
38
  }
39
39
  return escapedParts;
40
40
  };
41
- const getSectionPlaceholder = (utils, timezone, localeText, sectionConfig, sectionFormat) => {
41
+ const getSectionPlaceholder = (utils, localeText, sectionConfig, sectionFormat) => {
42
42
  switch (sectionConfig.type) {
43
43
  case 'year':
44
44
  {
45
45
  return localeText.fieldYearPlaceholder({
46
- digitAmount: utils.formatByString(utils.date(undefined, timezone), sectionFormat).length,
46
+ digitAmount: utils.formatByString(utils.date(undefined, 'default'), sectionFormat).length,
47
47
  format: sectionFormat
48
48
  });
49
49
  }
@@ -99,7 +99,6 @@ const getSectionPlaceholder = (utils, timezone, localeText, sectionConfig, secti
99
99
  };
100
100
  const createSection = ({
101
101
  utils,
102
- timezone,
103
102
  date,
104
103
  shouldRespectLeadingZeros,
105
104
  localeText,
@@ -112,7 +111,7 @@ const createSection = ({
112
111
  throw new Error('MUI X: Should not call `commitToken` with an empty token');
113
112
  }
114
113
  const sectionConfig = getDateSectionConfigFromFormatToken(utils, token);
115
- const hasLeadingZerosInFormat = doesSectionFormatHaveLeadingZeros(utils, timezone, sectionConfig.contentType, sectionConfig.type, token);
114
+ const hasLeadingZerosInFormat = doesSectionFormatHaveLeadingZeros(utils, sectionConfig.contentType, sectionConfig.type, token);
116
115
  const hasLeadingZerosInInput = shouldRespectLeadingZeros ? hasLeadingZerosInFormat : sectionConfig.contentType === 'digit';
117
116
  const isValidDate = date != null && utils.isValid(date);
118
117
  let sectionValue = isValidDate ? utils.formatByString(date, token) : '';
@@ -134,7 +133,7 @@ const createSection = ({
134
133
  format: token,
135
134
  maxLength,
136
135
  value: sectionValue,
137
- placeholder: getSectionPlaceholder(utils, timezone, localeText, sectionConfig, token),
136
+ placeholder: getSectionPlaceholder(utils, localeText, sectionConfig, token),
138
137
  hasLeadingZerosInFormat,
139
138
  hasLeadingZerosInInput,
140
139
  startSeparator,
@@ -31,9 +31,9 @@ const getDeltaFromKeyCode = keyCode => {
31
31
  return 0;
32
32
  }
33
33
  };
34
- export const getDaysInWeekStr = (utils, timezone, format) => {
34
+ export const getDaysInWeekStr = (utils, format) => {
35
35
  const elements = [];
36
- const now = utils.date(undefined, timezone);
36
+ const now = utils.date(undefined, 'default');
37
37
  const startDate = utils.startOfWeek(now);
38
38
  const endDate = utils.endOfWeek(now);
39
39
  let current = startDate;
@@ -51,7 +51,7 @@ export const getLetterEditingOptions = (utils, timezone, sectionType, format) =>
51
51
  }
52
52
  case 'weekDay':
53
53
  {
54
- return getDaysInWeekStr(utils, timezone, format);
54
+ return getDaysInWeekStr(utils, format);
55
55
  }
56
56
  case 'meridiem':
57
57
  {
@@ -234,17 +234,17 @@ export const changeSectionValueFormat = (utils, valueStr, currentFormat, newForm
234
234
  }
235
235
  return utils.formatByString(utils.parse(valueStr, currentFormat), newFormat);
236
236
  };
237
- const isFourDigitYearFormat = (utils, timezone, format) => utils.formatByString(utils.date(undefined, timezone), format).length === 4;
238
- export const doesSectionFormatHaveLeadingZeros = (utils, timezone, contentType, sectionType, format) => {
237
+ const isFourDigitYearFormat = (utils, format) => utils.formatByString(utils.date(undefined, 'system'), format).length === 4;
238
+ export const doesSectionFormatHaveLeadingZeros = (utils, contentType, sectionType, format) => {
239
239
  if (contentType !== 'digit') {
240
240
  return false;
241
241
  }
242
- const now = utils.date(undefined, timezone);
242
+ const now = utils.date(undefined, 'default');
243
243
  switch (sectionType) {
244
244
  // We can't use `changeSectionValueFormat`, because `utils.parse('1', 'YYYY')` returns `1971` instead of `1`.
245
245
  case 'year':
246
246
  {
247
- if (isFourDigitYearFormat(utils, timezone, format)) {
247
+ if (isFourDigitYearFormat(utils, format)) {
248
248
  const formatted0001 = utils.formatByString(utils.setYear(now, 1), format);
249
249
  return formatted0001 === '0001';
250
250
  }
@@ -350,7 +350,7 @@ export const getSectionsBoundaries = (utils, localizedDigits, timezone) => {
350
350
  format
351
351
  }) => ({
352
352
  minimum: 0,
353
- maximum: isFourDigitYearFormat(utils, timezone, format) ? 9999 : 99
353
+ maximum: isFourDigitYearFormat(utils, format) ? 9999 : 99
354
354
  }),
355
355
  month: () => ({
356
356
  minimum: 1,
@@ -369,7 +369,7 @@ export const getSectionsBoundaries = (utils, localizedDigits, timezone) => {
369
369
  contentType
370
370
  }) => {
371
371
  if (contentType === 'digit') {
372
- const daysInWeek = getDaysInWeekStr(utils, timezone, format).map(Number);
372
+ const daysInWeek = getDaysInWeekStr(utils, format).map(Number);
373
373
  return {
374
374
  minimum: Math.min(...daysInWeek),
375
375
  maximum: Math.max(...daysInWeek)
@@ -435,7 +435,7 @@ export const validateSections = (sections, valueType) => {
435
435
  }
436
436
  }
437
437
  };
438
- const transferDateSectionValue = (utils, timezone, section, dateToTransferFrom, dateToTransferTo) => {
438
+ const transferDateSectionValue = (utils, section, dateToTransferFrom, dateToTransferTo) => {
439
439
  switch (section.type) {
440
440
  case 'year':
441
441
  {
@@ -447,7 +447,7 @@ const transferDateSectionValue = (utils, timezone, section, dateToTransferFrom,
447
447
  }
448
448
  case 'weekDay':
449
449
  {
450
- const formattedDaysInWeek = getDaysInWeekStr(utils, timezone, section.format);
450
+ const formattedDaysInWeek = getDaysInWeekStr(utils, section.format);
451
451
  const dayInWeekStrOfActiveDate = utils.formatByString(dateToTransferFrom, section.format);
452
452
  const dayInWeekOfActiveDate = formattedDaysInWeek.indexOf(dayInWeekStrOfActiveDate);
453
453
  const dayInWeekOfNewSectionValue = formattedDaysInWeek.indexOf(section.value);
@@ -499,11 +499,11 @@ const reliableSectionModificationOrder = {
499
499
  meridiem: 8,
500
500
  empty: 9
501
501
  };
502
- export const mergeDateIntoReferenceDate = (utils, timezone, dateToTransferFrom, sections, referenceDate, shouldLimitToEditedSections) =>
502
+ export const mergeDateIntoReferenceDate = (utils, dateToTransferFrom, sections, referenceDate, shouldLimitToEditedSections) =>
503
503
  // cloning sections before sort to avoid mutating it
504
504
  [...sections].sort((a, b) => reliableSectionModificationOrder[a.type] - reliableSectionModificationOrder[b.type]).reduce((mergedDate, section) => {
505
505
  if (!shouldLimitToEditedSections || section.modified) {
506
- return transferDateSectionValue(utils, timezone, section, dateToTransferFrom, mergedDate);
506
+ return transferDateSectionValue(utils, section, dateToTransferFrom, mergedDate);
507
507
  }
508
508
  return mergedDate;
509
509
  }, referenceDate);
@@ -199,7 +199,7 @@ export const useFieldCharacterEditing = ({
199
199
  // When editing a letter-format month and the user presses a digit,
200
200
  // We can support the numeric editing by using the digit-format month and re-formatting the result.
201
201
  if (activeSection.type === 'month') {
202
- const hasLeadingZerosInFormat = doesSectionFormatHaveLeadingZeros(utils, timezone, 'digit', 'month', 'MM');
202
+ const hasLeadingZerosInFormat = doesSectionFormatHaveLeadingZeros(utils, 'digit', 'month', 'MM');
203
203
  const response = getNewSectionValue(queryValue, {
204
204
  type: activeSection.type,
205
205
  format: 'MM',
@@ -224,7 +224,7 @@ export const useFieldCharacterEditing = ({
224
224
  if (isQueryResponseWithoutValue(response)) {
225
225
  return response;
226
226
  }
227
- const formattedValue = getDaysInWeekStr(utils, timezone, activeSection.format)[Number(response.sectionValue) - 1];
227
+ const formattedValue = getDaysInWeekStr(utils, activeSection.format)[Number(response.sectionValue) - 1];
228
228
  return _extends({}, response, {
229
229
  sectionValue: formattedValue
230
230
  });
@@ -48,7 +48,6 @@ export const useFieldState = params => {
48
48
  const sectionsValueBoundaries = React.useMemo(() => getSectionsBoundaries(utils, localizedDigits, timezone), [utils, localizedDigits, timezone]);
49
49
  const getSectionsFromValue = React.useCallback((value, fallbackSections = null) => fieldValueManager.getSectionsFromValue(utils, value, fallbackSections, date => buildSectionsFromFormat({
50
50
  utils,
51
- timezone,
52
51
  localeText: translations,
53
52
  localizedDigits,
54
53
  format,
@@ -57,7 +56,7 @@ export const useFieldState = params => {
57
56
  shouldRespectLeadingZeros,
58
57
  enableAccessibleFieldDOMStructure,
59
58
  isRtl
60
- })), [fieldValueManager, format, translations, localizedDigits, isRtl, shouldRespectLeadingZeros, utils, formatDensity, timezone, enableAccessibleFieldDOMStructure]);
59
+ })), [fieldValueManager, format, translations, localizedDigits, isRtl, shouldRespectLeadingZeros, utils, formatDensity, enableAccessibleFieldDOMStructure]);
61
60
  const [state, setState] = React.useState(() => {
62
61
  const sections = getSectionsFromValue(valueFromTheOutside);
63
62
  validateSections(sections, valueType);
@@ -154,7 +153,6 @@ export const useFieldState = params => {
154
153
  }
155
154
  const sections = buildSectionsFromFormat({
156
155
  utils,
157
- timezone,
158
156
  localeText: translations,
159
157
  localizedDigits,
160
158
  format,
@@ -164,7 +162,7 @@ export const useFieldState = params => {
164
162
  enableAccessibleFieldDOMStructure,
165
163
  isRtl
166
164
  });
167
- return mergeDateIntoReferenceDate(utils, timezone, date, sections, referenceDate, false);
165
+ return mergeDateIntoReferenceDate(utils, date, sections, referenceDate, false);
168
166
  };
169
167
  const newValue = fieldValueManager.parseValueStr(valueStr, state.referenceValue, parseDateStr);
170
168
  const newReferenceValue = fieldValueManager.updateReferenceValue(utils, newValue, state.referenceValue);
@@ -202,7 +200,7 @@ export const useFieldState = params => {
202
200
  * This makes sure that we don't lose some information of the initial date (like the time on a date field).
203
201
  */
204
202
  if (newActiveDate != null && utils.isValid(newActiveDate)) {
205
- const mergedDate = mergeDateIntoReferenceDate(utils, timezone, newActiveDate, newActiveDateSections, activeDateManager.referenceDate, true);
203
+ const mergedDate = mergeDateIntoReferenceDate(utils, newActiveDate, newActiveDateSections, activeDateManager.referenceDate, true);
206
204
  values = activeDateManager.getNewValuesFromNewActiveDate(mergedDate);
207
205
  shouldPublish = true;
208
206
  } else {
@@ -8,15 +8,16 @@ import useId from '@mui/utils/useId';
8
8
  import { PickersModalDialog } from "../../components/PickersModalDialog.js";
9
9
  import { usePicker } from "../usePicker/index.js";
10
10
  import { onSpaceOrEnter } from "../../utils/utils.js";
11
- import { LocalizationProvider } from "../../../LocalizationProvider/index.js";
12
11
  import { PickersLayout } from "../../../PickersLayout/index.js";
13
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
12
+ import { PickersProvider } from "../../components/PickersProvider.js";
13
+
14
14
  /**
15
15
  * Hook managing all the single-date mobile pickers:
16
16
  * - MobileDatePicker
17
17
  * - MobileDateTimePicker
18
18
  * - MobileTimePicker
19
19
  */
20
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
20
21
  export const useMobilePicker = _ref => {
21
22
  let {
22
23
  props,
@@ -49,7 +50,8 @@ export const useMobilePicker = _ref => {
49
50
  actions,
50
51
  layoutProps,
51
52
  renderCurrentView,
52
- fieldProps: pickerFieldProps
53
+ fieldProps: pickerFieldProps,
54
+ contextValue
53
55
  } = usePicker(_extends({}, pickerParams, {
54
56
  props,
55
57
  fieldRef,
@@ -110,7 +112,8 @@ export const useMobilePicker = _ref => {
110
112
  }, innerSlotProps?.mobilePaper)
111
113
  });
112
114
  const handleFieldRef = useForkRef(fieldRef, fieldProps.unstableFieldRef);
113
- const renderPicker = () => /*#__PURE__*/_jsxs(LocalizationProvider, {
115
+ const renderPicker = () => /*#__PURE__*/_jsxs(PickersProvider, {
116
+ contextValue: contextValue,
114
117
  localeText: localeText,
115
118
  children: [/*#__PURE__*/_jsx(Field, _extends({}, fieldProps, {
116
119
  slots: slotsForField,
@@ -49,6 +49,8 @@ export const usePicker = ({
49
49
  hasUIView: pickerViewsResponse.hasUIView,
50
50
  shouldRestoreFocus: pickerViewsResponse.shouldRestoreFocus,
51
51
  // Picker layout
52
- layoutProps: pickerLayoutResponse.layoutProps
52
+ layoutProps: pickerLayoutResponse.layoutProps,
53
+ // Picker context
54
+ contextValue: pickerValueResponse.contextValue
53
55
  };
54
56
  };
@@ -5,7 +5,6 @@ import { useOpenState } from "../useOpenState.js";
5
5
  import { useLocalizationContext, useUtils } from "../useUtils.js";
6
6
  import { useValidation } from "../../../validation/index.js";
7
7
  import { useValueWithTimezone } from "../useValueWithTimezone.js";
8
-
9
8
  /**
10
9
  * Decide if the new value should be published
11
10
  * The published value will be passed to `onChange` if defined.
@@ -334,11 +333,17 @@ export const usePickerValue = ({
334
333
  onSelectShortcut: handleSelectShortcut,
335
334
  isValid
336
335
  });
336
+ const contextValue = React.useMemo(() => ({
337
+ onOpen: handleOpen,
338
+ onClose: handleClose,
339
+ open: isOpen
340
+ }), [isOpen, handleClose, handleOpen]);
337
341
  return {
338
342
  open: isOpen,
339
343
  fieldProps: fieldResponse,
340
344
  viewProps: viewResponse,
341
345
  layoutProps: layoutResponse,
342
- actions
346
+ actions,
347
+ contextValue
343
348
  };
344
349
  };
@@ -1,4 +1,5 @@
1
1
  export { PickersArrowSwitcher } from "./components/PickersArrowSwitcher/PickersArrowSwitcher.js";
2
+ export { PickersProvider } from "./components/PickersProvider.js";
2
3
  export { PickersModalDialog } from "./components/PickersModalDialog.js";
3
4
  export { PickersPopper } from "./components/PickersPopper.js";
4
5
  export { PickersToolbar } from "./components/PickersToolbar.js";