@mui/x-date-pickers 7.19.0 → 7.21.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 (125) hide show
  1. package/AdapterDayjs/AdapterDayjs.js +2 -0
  2. package/CHANGELOG.md +224 -43
  3. package/DateCalendar/DateCalendar.js +1 -1
  4. package/DateCalendar/DateCalendar.types.d.ts +1 -1
  5. package/DateField/DateField.types.d.ts +2 -7
  6. package/DateField/index.d.ts +1 -1
  7. package/DatePicker/DatePicker.js +1 -1
  8. package/DatePicker/DatePicker.types.d.ts +8 -1
  9. package/DatePicker/index.d.ts +1 -1
  10. package/DateTimeField/DateTimeField.types.d.ts +2 -7
  11. package/DateTimeField/index.d.ts +1 -1
  12. package/DateTimePicker/DateTimePicker.js +1 -1
  13. package/DateTimePicker/DateTimePicker.types.d.ts +9 -1
  14. package/DateTimePicker/DateTimePickerTabs.js +1 -1
  15. package/DateTimePicker/index.d.ts +1 -1
  16. package/DesktopDatePicker/DesktopDatePicker.js +1 -1
  17. package/DesktopDateTimePicker/DesktopDateTimePicker.js +1 -1
  18. package/DigitalClock/DigitalClock.js +33 -0
  19. package/MobileDatePicker/MobileDatePicker.js +1 -1
  20. package/MobileDateTimePicker/MobileDateTimePicker.js +1 -1
  21. package/MultiSectionDigitalClock/MultiSectionDigitalClockSection.js +32 -1
  22. package/PickersSectionList/PickersSectionList.d.ts +9 -0
  23. package/PickersSectionList/PickersSectionList.js +30 -9
  24. package/StaticDatePicker/StaticDatePicker.js +1 -1
  25. package/StaticDateTimePicker/StaticDateTimePicker.js +1 -1
  26. package/TimeClock/Clock.js +8 -0
  27. package/TimeField/TimeField.types.d.ts +2 -7
  28. package/TimeField/index.d.ts +1 -1
  29. package/TimePicker/TimePicker.types.d.ts +9 -1
  30. package/TimePicker/index.d.ts +1 -1
  31. package/hooks/index.d.ts +2 -0
  32. package/hooks/index.js +3 -1
  33. package/hooks/useParsedFormat.d.ts +15 -0
  34. package/hooks/useParsedFormat.js +43 -0
  35. package/hooks/usePickersContext.d.ts +4 -0
  36. package/hooks/usePickersContext.js +15 -0
  37. package/index.js +1 -1
  38. package/internals/components/PickersProvider.d.ts +34 -0
  39. package/internals/components/PickersProvider.js +26 -0
  40. package/internals/hooks/useDesktopPicker/useDesktopPicker.js +9 -10
  41. package/internals/hooks/useDesktopPicker/useDesktopPicker.types.d.ts +2 -5
  42. package/internals/hooks/useField/buildSectionsFromFormat.d.ts +1 -2
  43. package/internals/hooks/useField/buildSectionsFromFormat.js +4 -5
  44. package/internals/hooks/useField/useField.js +1 -1
  45. package/internals/hooks/useField/useField.utils.d.ts +3 -3
  46. package/internals/hooks/useField/useField.utils.js +13 -13
  47. package/internals/hooks/useField/useFieldCharacterEditing.js +2 -2
  48. package/internals/hooks/useField/useFieldState.js +3 -5
  49. package/internals/hooks/useMobilePicker/useMobilePicker.js +7 -4
  50. package/internals/hooks/usePicker/usePicker.js +10 -1
  51. package/internals/hooks/usePicker/usePicker.types.d.ts +2 -1
  52. package/internals/hooks/usePicker/usePickerOwnerState.d.ts +9 -0
  53. package/internals/hooks/usePicker/usePickerOwnerState.js +13 -0
  54. package/internals/hooks/usePicker/usePickerValue.js +7 -2
  55. package/internals/hooks/usePicker/usePickerValue.types.d.ts +2 -0
  56. package/internals/index.d.ts +1 -0
  57. package/internals/index.js +1 -0
  58. package/internals/utils/utils.d.ts +7 -0
  59. package/internals/utils/utils.js +11 -0
  60. package/models/pickers.d.ts +19 -1
  61. package/modern/AdapterDayjs/AdapterDayjs.js +2 -0
  62. package/modern/DateCalendar/DateCalendar.js +1 -1
  63. package/modern/DatePicker/DatePicker.js +1 -1
  64. package/modern/DateTimePicker/DateTimePicker.js +1 -1
  65. package/modern/DateTimePicker/DateTimePickerTabs.js +1 -1
  66. package/modern/DesktopDatePicker/DesktopDatePicker.js +1 -1
  67. package/modern/DesktopDateTimePicker/DesktopDateTimePicker.js +1 -1
  68. package/modern/DigitalClock/DigitalClock.js +33 -0
  69. package/modern/MobileDatePicker/MobileDatePicker.js +1 -1
  70. package/modern/MobileDateTimePicker/MobileDateTimePicker.js +1 -1
  71. package/modern/MultiSectionDigitalClock/MultiSectionDigitalClockSection.js +32 -1
  72. package/modern/PickersSectionList/PickersSectionList.js +30 -9
  73. package/modern/StaticDatePicker/StaticDatePicker.js +1 -1
  74. package/modern/StaticDateTimePicker/StaticDateTimePicker.js +1 -1
  75. package/modern/TimeClock/Clock.js +8 -0
  76. package/modern/hooks/index.js +3 -1
  77. package/modern/hooks/useParsedFormat.js +43 -0
  78. package/modern/hooks/usePickersContext.js +15 -0
  79. package/modern/index.js +1 -1
  80. package/modern/internals/components/PickersProvider.js +26 -0
  81. package/modern/internals/hooks/useDesktopPicker/useDesktopPicker.js +9 -10
  82. package/modern/internals/hooks/useField/buildSectionsFromFormat.js +4 -5
  83. package/modern/internals/hooks/useField/useField.js +1 -1
  84. package/modern/internals/hooks/useField/useField.utils.js +13 -13
  85. package/modern/internals/hooks/useField/useFieldCharacterEditing.js +2 -2
  86. package/modern/internals/hooks/useField/useFieldState.js +3 -5
  87. package/modern/internals/hooks/useMobilePicker/useMobilePicker.js +7 -4
  88. package/modern/internals/hooks/usePicker/usePicker.js +10 -1
  89. package/modern/internals/hooks/usePicker/usePickerOwnerState.js +13 -0
  90. package/modern/internals/hooks/usePicker/usePickerValue.js +7 -2
  91. package/modern/internals/index.js +1 -0
  92. package/modern/internals/utils/utils.js +11 -0
  93. package/node/AdapterDayjs/AdapterDayjs.js +2 -0
  94. package/node/DateCalendar/DateCalendar.js +1 -1
  95. package/node/DatePicker/DatePicker.js +1 -1
  96. package/node/DateTimePicker/DateTimePicker.js +1 -1
  97. package/node/DateTimePicker/DateTimePickerTabs.js +1 -1
  98. package/node/DesktopDatePicker/DesktopDatePicker.js +1 -1
  99. package/node/DesktopDateTimePicker/DesktopDateTimePicker.js +1 -1
  100. package/node/DigitalClock/DigitalClock.js +33 -0
  101. package/node/MobileDatePicker/MobileDatePicker.js +1 -1
  102. package/node/MobileDateTimePicker/MobileDateTimePicker.js +1 -1
  103. package/node/MultiSectionDigitalClock/MultiSectionDigitalClockSection.js +32 -1
  104. package/node/PickersSectionList/PickersSectionList.js +30 -9
  105. package/node/StaticDatePicker/StaticDatePicker.js +1 -1
  106. package/node/StaticDateTimePicker/StaticDateTimePicker.js +1 -1
  107. package/node/TimeClock/Clock.js +8 -0
  108. package/node/hooks/index.js +15 -1
  109. package/node/hooks/useParsedFormat.js +50 -0
  110. package/node/hooks/usePickersContext.js +21 -0
  111. package/node/index.js +1 -1
  112. package/node/internals/components/PickersProvider.js +34 -0
  113. package/node/internals/hooks/useDesktopPicker/useDesktopPicker.js +7 -9
  114. package/node/internals/hooks/useField/buildSectionsFromFormat.js +4 -5
  115. package/node/internals/hooks/useField/useField.js +1 -1
  116. package/node/internals/hooks/useField/useField.utils.js +13 -13
  117. package/node/internals/hooks/useField/useFieldCharacterEditing.js +2 -2
  118. package/node/internals/hooks/useField/useFieldState.js +3 -5
  119. package/node/internals/hooks/useMobilePicker/useMobilePicker.js +5 -3
  120. package/node/internals/hooks/usePicker/usePicker.js +10 -1
  121. package/node/internals/hooks/usePicker/usePickerOwnerState.js +20 -0
  122. package/node/internals/hooks/usePicker/usePickerValue.js +7 -1
  123. package/node/internals/index.js +7 -0
  124. package/node/internals/utils/utils.js +13 -1
  125. package/package.json +4 -4
@@ -1,9 +1,9 @@
1
1
  import * as React from 'react';
2
2
  import { SlotComponentProps } from '@mui/utils';
3
3
  import TextField from '@mui/material/TextField';
4
- import { DateTimeValidationError, FieldSection, PickerValidDate, BuiltInFieldTextFieldProps, BaseSingleInputFieldProps } from '../models';
4
+ import { DateTimeValidationError, FieldSection, PickerValidDate, BuiltInFieldTextFieldProps } from '../models';
5
5
  import { UseFieldInternalProps } from '../internals/hooks/useField';
6
- import { DefaultizedProps, MakeOptional } from '../internals/models/helpers';
6
+ import { MakeOptional } from '../internals/models/helpers';
7
7
  import { BaseDateValidationProps, BaseTimeValidationProps, DateTimeValidationProps, DayValidationProps, MonthValidationProps, TimeValidationProps, YearValidationProps } from '../internals/models/validation';
8
8
  import { ExportedUseClearableFieldProps, UseClearableFieldSlots, UseClearableFieldSlotProps } from '../hooks/useClearableField';
9
9
  export interface UseDateTimeFieldProps<TDate extends PickerValidDate, TEnableAccessibleFieldDOMStructure extends boolean> extends MakeOptional<UseFieldInternalProps<TDate | null, TDate, FieldSection, TEnableAccessibleFieldDOMStructure, DateTimeValidationError>, 'format'>, DayValidationProps<TDate>, MonthValidationProps<TDate>, YearValidationProps<TDate>, BaseDateValidationProps<TDate>, TimeValidationProps<TDate>, BaseTimeValidationProps, DateTimeValidationProps<TDate>, ExportedUseClearableFieldProps {
@@ -13,11 +13,6 @@ export interface UseDateTimeFieldProps<TDate extends PickerValidDate, TEnableAcc
13
13
  */
14
14
  ampm?: boolean;
15
15
  }
16
- /**
17
- * Props the field can receive when used inside a date time picker.
18
- * (`DateTimePicker`, `DesktopDateTimePicker` or `MobileDateTimePicker` component).
19
- */
20
- export type DateTimeFieldInPickerProps<TDate extends PickerValidDate, TEnableAccessibleFieldDOMStructure extends boolean> = DefaultizedProps<UseDateTimeFieldProps<TDate, TEnableAccessibleFieldDOMStructure>, 'format' | 'timezone' | 'ampm' | keyof BaseDateValidationProps<TDate> | keyof BaseTimeValidationProps> & BaseSingleInputFieldProps<TDate | null, TDate, FieldSection, false, DateTimeValidationError>;
21
16
  export type UseDateTimeFieldComponentProps<TDate extends PickerValidDate, TEnableAccessibleFieldDOMStructure extends boolean, TChildProps extends {}> = Omit<TChildProps, keyof UseDateTimeFieldProps<TDate, TEnableAccessibleFieldDOMStructure>> & UseDateTimeFieldProps<TDate, TEnableAccessibleFieldDOMStructure>;
22
17
  export type DateTimeFieldProps<TDate extends PickerValidDate, TEnableAccessibleFieldDOMStructure extends boolean = false> = UseDateTimeFieldComponentProps<TDate, TEnableAccessibleFieldDOMStructure, BuiltInFieldTextFieldProps<TEnableAccessibleFieldDOMStructure>> & {
23
18
  /**
@@ -1,3 +1,3 @@
1
1
  export { DateTimeField } from './DateTimeField';
2
2
  export { useDateTimeField as unstable_useDateTimeField } from './useDateTimeField';
3
- export type { UseDateTimeFieldProps, UseDateTimeFieldComponentProps, DateTimeFieldProps, DateTimeFieldInPickerProps, } from './DateTimeField.types';
3
+ export type { UseDateTimeFieldProps, UseDateTimeFieldComponentProps, DateTimeFieldProps, } from './DateTimeField.types';
@@ -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
  /**
@@ -1,7 +1,10 @@
1
+ import { UseDateTimeFieldProps } from '../DateTimeField';
1
2
  import { DesktopDateTimePickerProps, DesktopDateTimePickerSlots, DesktopDateTimePickerSlotProps } from '../DesktopDateTimePicker';
2
3
  import { DateOrTimeViewWithMeridiem } from '../internals/models';
4
+ import { DefaultizedProps } from '../internals/models/helpers';
5
+ import { BaseDateValidationProps, BaseTimeValidationProps } from '../internals/models/validation';
3
6
  import { MobileDateTimePickerProps, MobileDateTimePickerSlots, MobileDateTimePickerSlotProps } from '../MobileDateTimePicker';
4
- import { PickerValidDate } from '../models';
7
+ import { BaseSingleInputFieldProps, DateTimeValidationError, FieldSection, PickerValidDate } from '../models';
5
8
  import { ExportedYearCalendarProps } from '../YearCalendar/YearCalendar.types';
6
9
  export interface DateTimePickerSlots<TDate extends PickerValidDate> extends DesktopDateTimePickerSlots<TDate>, MobileDateTimePickerSlots<TDate, DateOrTimeViewWithMeridiem> {
7
10
  }
@@ -30,3 +33,8 @@ export interface DateTimePickerProps<TDate extends PickerValidDate, TEnableAcces
30
33
  */
31
34
  yearsPerRow?: 3 | 4;
32
35
  }
36
+ /**
37
+ * Props the field can receive when used inside a date time picker.
38
+ * (`DateTimePicker`, `DesktopDateTimePicker` or `MobileDateTimePicker` component).
39
+ */
40
+ export type DateTimePickerFieldProps<TDate extends PickerValidDate, TEnableAccessibleFieldDOMStructure extends boolean = false> = DefaultizedProps<UseDateTimeFieldProps<TDate, TEnableAccessibleFieldDOMStructure>, 'format' | 'timezone' | 'ampm' | keyof BaseDateValidationProps<TDate> | keyof BaseTimeValidationProps> & BaseSingleInputFieldProps<TDate | null, TDate, FieldSection, false, DateTimeValidationError>;
@@ -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",
@@ -1,5 +1,5 @@
1
1
  export { DateTimePicker } from './DateTimePicker';
2
- export type { DateTimePickerProps, DateTimePickerSlots, DateTimePickerSlotProps, } from './DateTimePicker.types';
2
+ export type { DateTimePickerProps, DateTimePickerSlots, DateTimePickerSlotProps, DateTimePickerFieldProps, } from './DateTimePicker.types';
3
3
  export { DateTimePickerTabs } from './DateTimePickerTabs';
4
4
  export type { DateTimePickerTabsProps } from './DateTimePickerTabs';
5
5
  export { dateTimePickerTabsClasses } from './dateTimePickerTabsClasses';
@@ -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,46 @@ 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
+ const newIndex = getFocusedListItemIndex(listRef.current) - 5;
246
+ const children = listRef.current.children;
247
+ const newFocusedIndex = Math.max(0, newIndex);
248
+ const childToFocus = children[newFocusedIndex];
249
+ if (childToFocus) {
250
+ childToFocus.focus();
251
+ }
252
+ event.preventDefault();
253
+ break;
254
+ }
255
+ case 'PageDown':
256
+ {
257
+ const newIndex = getFocusedListItemIndex(listRef.current) + 5;
258
+ const children = listRef.current.children;
259
+ const newFocusedIndex = Math.min(children.length - 1, newIndex);
260
+ const childToFocus = children[newFocusedIndex];
261
+ if (childToFocus) {
262
+ childToFocus.focus();
263
+ }
264
+ event.preventDefault();
265
+ break;
266
+ }
267
+ default:
268
+ }
269
+ };
239
270
  return /*#__PURE__*/_jsx(DigitalClockRoot, _extends({
240
271
  ref: handleRef,
241
272
  className: clsx(classes.root, className),
242
273
  ownerState: ownerState
243
274
  }, other, {
244
275
  children: /*#__PURE__*/_jsx(DigitalClockList, {
276
+ ref: listRef,
245
277
  role: "listbox",
246
278
  "aria-label": translations.timePickerToolbarTitle,
247
279
  className: classes.list,
280
+ onKeyDown: handleKeyDown,
248
281
  children: timeOptions.map((option, index) => {
249
282
  if (skipDisabled && isTimeDisabled(option)) {
250
283
  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,42 @@ 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
+ const newIndex = getFocusedListItemIndex(containerRef.current) - 5;
147
+ const children = containerRef.current.children;
148
+ const newFocusedIndex = Math.max(0, newIndex);
149
+ const childToFocus = children[newFocusedIndex];
150
+ if (childToFocus) {
151
+ childToFocus.focus();
152
+ }
153
+ event.preventDefault();
154
+ break;
155
+ }
156
+ case 'PageDown':
157
+ {
158
+ const newIndex = getFocusedListItemIndex(containerRef.current) + 5;
159
+ const children = containerRef.current.children;
160
+ const newFocusedIndex = Math.min(children.length - 1, newIndex);
161
+ const childToFocus = children[newFocusedIndex];
162
+ if (childToFocus) {
163
+ childToFocus.focus();
164
+ }
165
+ event.preventDefault();
166
+ break;
167
+ }
168
+ default:
169
+ }
170
+ };
141
171
  return /*#__PURE__*/_jsx(MultiSectionDigitalClockSectionRoot, _extends({
142
172
  ref: handleRef,
143
173
  className: clsx(classes.root, className),
144
174
  ownerState: ownerState,
145
175
  autoFocusItem: autoFocus && active,
146
- role: "listbox"
176
+ role: "listbox",
177
+ onKeyDown: handleKeyDown
147
178
  }, other, {
148
179
  children: items.map((option, index) => {
149
180
  const isItemDisabled = option.isDisabled?.(option.value);
@@ -7,5 +7,14 @@ export declare const PickersSectionListSectionContent: import("@emotion/styled")
7
7
  type PickersSectionListComponent = ((props: PickersSectionListProps & React.RefAttributes<HTMLDivElement>) => React.JSX.Element) & {
8
8
  propTypes?: any;
9
9
  };
10
+ /**
11
+ * Demos:
12
+ *
13
+ * - [Custom field](https://mui.com/x/react-date-pickers/custom-field/)
14
+ *
15
+ * API:
16
+ *
17
+ * - [PickersSectionList API](https://mui.com/x/api/date-pickers/pickers-section-list/)
18
+ */
10
19
  declare const PickersSectionList: PickersSectionListComponent;
11
20
  export { PickersSectionList };
@@ -49,15 +49,6 @@ const useUtilityClasses = ownerState => {
49
49
  };
50
50
  return composeClasses(slots, getPickersSectionListUtilityClass, classes);
51
51
  };
52
- /**
53
- * Demos:
54
- *
55
- * - [Custom field](https://mui.com/x/react-date-pickers/custom-field/)
56
- *
57
- * API:
58
- *
59
- * - [PickersSectionList API](https://mui.com/x/api/date-pickers/pickers-section-list/)
60
- */
61
52
  function PickersSection(props) {
62
53
  const {
63
54
  slots,
@@ -105,6 +96,36 @@ function PickersSection(props) {
105
96
  children: [/*#__PURE__*/_jsx(SectionSeparator, _extends({}, sectionSeparatorBeforeProps)), /*#__PURE__*/_jsx(SectionContent, _extends({}, sectionContentProps)), /*#__PURE__*/_jsx(SectionSeparator, _extends({}, sectionSeparatorAfterProps))]
106
97
  }));
107
98
  }
99
+ process.env.NODE_ENV !== "production" ? PickersSection.propTypes = {
100
+ // ----------------------------- Warning --------------------------------
101
+ // | These PropTypes are generated from the TypeScript type definitions |
102
+ // | To update them edit the TypeScript types and run "pnpm proptypes" |
103
+ // ----------------------------------------------------------------------
104
+ classes: PropTypes.object.isRequired,
105
+ element: PropTypes.shape({
106
+ after: PropTypes.object.isRequired,
107
+ before: PropTypes.object.isRequired,
108
+ container: PropTypes.object.isRequired,
109
+ content: PropTypes.object.isRequired
110
+ }).isRequired,
111
+ /**
112
+ * The props used for each component slot.
113
+ */
114
+ slotProps: PropTypes.object,
115
+ /**
116
+ * Overridable component slots.
117
+ */
118
+ slots: PropTypes.object
119
+ } : void 0;
120
+ /**
121
+ * Demos:
122
+ *
123
+ * - [Custom field](https://mui.com/x/react-date-pickers/custom-field/)
124
+ *
125
+ * API:
126
+ *
127
+ * - [PickersSectionList API](https://mui.com/x/api/date-pickers/pickers-section-list/)
128
+ */
108
129
  const PickersSectionList = /*#__PURE__*/React.forwardRef(function PickersSectionList(inProps, ref) {
109
130
  const props = useThemeProps({
110
131
  props: inProps,
@@ -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');
@@ -2,9 +2,9 @@ import * as React from 'react';
2
2
  import { SlotComponentProps } from '@mui/utils';
3
3
  import TextField from '@mui/material/TextField';
4
4
  import { UseFieldInternalProps } from '../internals/hooks/useField';
5
- import { DefaultizedProps, MakeOptional } from '../internals/models/helpers';
5
+ import { MakeOptional } from '../internals/models/helpers';
6
6
  import { BaseTimeValidationProps, TimeValidationProps } from '../internals/models/validation';
7
- import { FieldSection, PickerValidDate, TimeValidationError, BuiltInFieldTextFieldProps, BaseSingleInputFieldProps } from '../models';
7
+ import { FieldSection, PickerValidDate, TimeValidationError, BuiltInFieldTextFieldProps } from '../models';
8
8
  import { ExportedUseClearableFieldProps, UseClearableFieldSlots, UseClearableFieldSlotProps } from '../hooks/useClearableField';
9
9
  export interface UseTimeFieldProps<TDate extends PickerValidDate, TEnableAccessibleFieldDOMStructure extends boolean> extends MakeOptional<UseFieldInternalProps<TDate | null, TDate, FieldSection, TEnableAccessibleFieldDOMStructure, TimeValidationError>, 'format'>, TimeValidationProps<TDate>, BaseTimeValidationProps, ExportedUseClearableFieldProps {
10
10
  /**
@@ -13,11 +13,6 @@ export interface UseTimeFieldProps<TDate extends PickerValidDate, TEnableAccessi
13
13
  */
14
14
  ampm?: boolean;
15
15
  }
16
- /**
17
- * Props the field can receive when used inside a time picker.
18
- * (`TimePicker`, `DesktopTimePicker` or `MobileTimePicker` component).
19
- */
20
- export type TimeFieldInPickerProps<TDate extends PickerValidDate, TEnableAccessibleFieldDOMStructure extends boolean> = DefaultizedProps<UseTimeFieldProps<TDate, TEnableAccessibleFieldDOMStructure>, 'format' | 'timezone' | 'ampm' | keyof BaseTimeValidationProps> & BaseSingleInputFieldProps<TDate | null, TDate, FieldSection, false, TimeValidationError>;
21
16
  export type UseTimeFieldComponentProps<TDate extends PickerValidDate, TEnableAccessibleFieldDOMStructure extends boolean, TChildProps extends {}> = Omit<TChildProps, keyof UseTimeFieldProps<TDate, TEnableAccessibleFieldDOMStructure>> & UseTimeFieldProps<TDate, TEnableAccessibleFieldDOMStructure>;
22
17
  export type TimeFieldProps<TDate extends PickerValidDate, TEnableAccessibleFieldDOMStructure extends boolean = false> = UseTimeFieldComponentProps<TDate, TEnableAccessibleFieldDOMStructure, BuiltInFieldTextFieldProps<TEnableAccessibleFieldDOMStructure>> & {
23
18
  /**
@@ -1,3 +1,3 @@
1
1
  export { TimeField } from './TimeField';
2
2
  export { useTimeField as unstable_useTimeField } from './useTimeField';
3
- export type { UseTimeFieldProps, UseTimeFieldComponentProps, TimeFieldProps, TimeFieldInPickerProps, } from './TimeField.types';
3
+ export type { UseTimeFieldProps, UseTimeFieldComponentProps, TimeFieldProps, } from './TimeField.types';
@@ -1,7 +1,10 @@
1
1
  import { DesktopTimePickerProps, DesktopTimePickerSlots, DesktopTimePickerSlotProps } from '../DesktopTimePicker';
2
2
  import { TimeViewWithMeridiem } from '../internals/models';
3
+ import { DefaultizedProps } from '../internals/models/helpers';
4
+ import { BaseTimeValidationProps } from '../internals/models/validation';
3
5
  import { MobileTimePickerProps, MobileTimePickerSlots, MobileTimePickerSlotProps } from '../MobileTimePicker';
4
- import { PickerValidDate } from '../models';
6
+ import { BaseSingleInputFieldProps, FieldSection, PickerValidDate, TimeValidationError } from '../models';
7
+ import { UseTimeFieldProps } from '../TimeField';
5
8
  export interface TimePickerSlots<TDate extends PickerValidDate> extends DesktopTimePickerSlots<TDate>, MobileTimePickerSlots<TDate, TimeViewWithMeridiem> {
6
9
  }
7
10
  export interface TimePickerSlotProps<TDate extends PickerValidDate, TEnableAccessibleFieldDOMStructure extends boolean> extends DesktopTimePickerSlotProps<TDate, TEnableAccessibleFieldDOMStructure>, MobileTimePickerSlotProps<TDate, TimeViewWithMeridiem, TEnableAccessibleFieldDOMStructure> {
@@ -24,3 +27,8 @@ export interface TimePickerProps<TDate extends PickerValidDate, TEnableAccessibl
24
27
  */
25
28
  slotProps?: TimePickerSlotProps<TDate, TEnableAccessibleFieldDOMStructure>;
26
29
  }
30
+ /**
31
+ * Props the field can receive when used inside a time picker.
32
+ * (`TimePicker`, `DesktopTimePicker` or `MobileTimePicker` component).
33
+ */
34
+ export type TimePickerFieldProps<TDate extends PickerValidDate, TEnableAccessibleFieldDOMStructure extends boolean = false> = DefaultizedProps<UseTimeFieldProps<TDate, TEnableAccessibleFieldDOMStructure>, 'format' | 'timezone' | 'ampm' | keyof BaseTimeValidationProps> & BaseSingleInputFieldProps<TDate | null, TDate, FieldSection, false, TimeValidationError>;
@@ -1,5 +1,5 @@
1
1
  export { TimePicker } from './TimePicker';
2
- export type { TimePickerProps, TimePickerSlots, TimePickerSlotProps } from './TimePicker.types';
2
+ export type { TimePickerProps, TimePickerSlots, TimePickerSlotProps, TimePickerFieldProps, } from './TimePicker.types';
3
3
  export { TimePickerToolbar } from './TimePickerToolbar';
4
4
  export type { TimePickerToolbarProps } from './TimePickerToolbar';
5
5
  export { timePickerToolbarClasses } from './timePickerToolbarClasses';
package/hooks/index.d.ts CHANGED
@@ -2,3 +2,5 @@ export { useClearableField } from './useClearableField';
2
2
  export type { ExportedUseClearableFieldProps, UseClearableFieldSlots, UseClearableFieldSlotProps, UseClearableFieldResponse, } from './useClearableField';
3
3
  export { usePickersTranslations } from './usePickersTranslations';
4
4
  export { useSplitFieldProps } from './useSplitFieldProps';
5
+ export { useParsedFormat } from './useParsedFormat';
6
+ export { usePickersContext } from './usePickersContext';
package/hooks/index.js CHANGED
@@ -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,15 @@
1
+ import { PickerValidDate } from '../models';
2
+ import type { UseFieldInternalProps } from '../internals/hooks/useField';
3
+ interface UseParsedFormatParameters extends Pick<UseFieldInternalProps<any, any, any, any, any>, 'format' | 'formatDensity' | 'shouldRespectLeadingZeros'> {
4
+ }
5
+ /**
6
+ * Returns the parsed format to be rendered in the field when there is no value or in other parts of the Picker.
7
+ * This format is localized (e.g: `AAAA` for the year with the French locale) and cannot be parsed by your date library.
8
+ * @param {object} The parameters needed to build the placeholder.
9
+ * @param {string} params.format Format of the date to use.
10
+ * @param {'dense' | 'spacious'} params.formatDensity Density of the format (setting `formatDensity` to `"spacious"` will add a space before and after each `/`, `-` and `.` character).
11
+ * @param {boolean} params.shouldRespectLeadingZeros If `true`, the format will respect the leading zeroes, if `false`, the format will always add leading zeroes.
12
+ * @returns
13
+ */
14
+ export declare const useParsedFormat: <TDate extends PickerValidDate>(parameters: UseParsedFormatParameters) => string;
15
+ export {};
@@ -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,4 @@
1
+ /**
2
+ * Returns the context passed by the picker that wraps the current component.
3
+ */
4
+ export declare const usePickersContext: () => import("../internals/components/PickersProvider").PickersContextValue;
@@ -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/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-date-pickers v7.19.0
2
+ * @mui/x-date-pickers v7.21.0
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -0,0 +1,34 @@
1
+ import * as React from 'react';
2
+ import { PickerValidDate } from '../../models';
3
+ import { PickersInputLocaleText } from '../../locales';
4
+ export declare const PickersContext: React.Context<PickersContextValue | null>;
5
+ /**
6
+ * Provides the context for the various parts of a picker component:
7
+ * - contextValue: the context for the picker sub-components.
8
+ * - localizationProvider: the translations passed through the props and through a parent LocalizationProvider.
9
+ *
10
+ * @ignore - do not document.
11
+ */
12
+ export declare function PickersProvider<TDate extends PickerValidDate>(props: PickersFieldProviderProps<TDate>): React.JSX.Element;
13
+ interface PickersFieldProviderProps<TDate extends PickerValidDate> {
14
+ contextValue: PickersContextValue;
15
+ localeText: PickersInputLocaleText<TDate> | undefined;
16
+ children: React.ReactNode;
17
+ }
18
+ export interface PickersContextValue {
19
+ /**
20
+ * Open the picker.
21
+ * @param {React.UIEvent} event The DOM event that triggered the change.
22
+ */
23
+ onOpen: (event: React.UIEvent) => void;
24
+ /**
25
+ * Close the picker.
26
+ * @param {React.UIEvent} event The DOM event that triggered the change.
27
+ */
28
+ onClose: (event: React.UIEvent) => void;
29
+ /**
30
+ * `true` if the picker is open, `false` otherwise.
31
+ */
32
+ open: boolean;
33
+ }
34
+ export {};
@@ -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,9 @@ export const useDesktopPicker = _ref => {
57
58
  layoutProps,
58
59
  renderCurrentView,
59
60
  shouldRestoreFocus,
60
- fieldProps: pickerFieldProps
61
+ fieldProps: pickerFieldProps,
62
+ contextValue,
63
+ ownerState
61
64
  } = usePicker(_extends({}, pickerParams, {
62
65
  props,
63
66
  fieldRef,
@@ -65,11 +68,6 @@ export const useDesktopPicker = _ref => {
65
68
  additionalViewProps: {},
66
69
  wrapperVariant: 'desktop'
67
70
  }));
68
-
69
- // TODO v8: Apply this ownerState to all the slots in this hook.
70
- const ownerStateV8 = {
71
- open
72
- };
73
71
  const InputAdornment = slots.inputAdornment ?? MuiInputAdornment;
74
72
  const _useSlotProps = useSlotProps({
75
73
  elementType: InputAdornment,
@@ -97,7 +95,7 @@ export const useDesktopPicker = _ref => {
97
95
  const openPickerIconProps = useSlotProps({
98
96
  elementType: OpenPickerIcon,
99
97
  externalSlotProps: innerSlotProps?.openPickerIcon,
100
- ownerState: ownerStateV8
98
+ ownerState
101
99
  });
102
100
  const Field = slots.field;
103
101
  const fieldProps = useSlotProps({
@@ -161,7 +159,8 @@ export const useDesktopPicker = _ref => {
161
159
  }, innerSlotProps?.popper)
162
160
  });
163
161
  const handleFieldRef = useForkRef(fieldRef, fieldProps.unstableFieldRef);
164
- const renderPicker = () => /*#__PURE__*/_jsxs(LocalizationProvider, {
162
+ const renderPicker = () => /*#__PURE__*/_jsxs(PickersProvider, {
163
+ contextValue: contextValue,
165
164
  localeText: localeText,
166
165
  children: [/*#__PURE__*/_jsx(Field, _extends({}, fieldProps, {
167
166
  slots: slotsForField,