@mui/x-date-pickers 8.0.0-beta.0 → 8.0.0-beta.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 (165) hide show
  1. package/CHANGELOG.md +77 -0
  2. package/DateCalendar/DayCalendar.d.ts +3 -7
  3. package/DateCalendar/DayCalendar.js +16 -8
  4. package/DateCalendar/index.d.ts +0 -1
  5. package/DateField/useDateField.d.ts +1 -1
  6. package/DateField/useDateField.js +2 -16
  7. package/DatePicker/DatePicker.js +1 -0
  8. package/DateTimeField/useDateTimeField.d.ts +1 -1
  9. package/DateTimeField/useDateTimeField.js +2 -16
  10. package/DateTimePicker/DateTimePicker.js +1 -0
  11. package/DesktopDatePicker/DesktopDatePicker.js +1 -0
  12. package/DesktopDateTimePicker/DesktopDateTimePicker.js +1 -0
  13. package/DesktopTimePicker/DesktopTimePicker.js +1 -0
  14. package/MobileDatePicker/MobileDatePicker.js +1 -0
  15. package/MobileDateTimePicker/MobileDateTimePicker.js +1 -0
  16. package/MobileTimePicker/MobileTimePicker.js +1 -0
  17. package/PickersDay/PickersDay.d.ts +1 -72
  18. package/PickersDay/PickersDay.js +30 -28
  19. package/PickersDay/PickersDay.types.d.ts +114 -0
  20. package/PickersDay/PickersDay.types.js +5 -0
  21. package/PickersDay/index.d.ts +1 -1
  22. package/PickersDay/usePickerDayOwnerState.d.ts +14 -0
  23. package/PickersDay/usePickerDayOwnerState.js +40 -0
  24. package/TimeField/useTimeField.d.ts +1 -1
  25. package/TimeField/useTimeField.js +2 -16
  26. package/TimePicker/TimePicker.js +1 -0
  27. package/esm/DateCalendar/DayCalendar.d.ts +3 -7
  28. package/esm/DateCalendar/DayCalendar.js +16 -8
  29. package/esm/DateCalendar/index.d.ts +0 -1
  30. package/esm/DateField/useDateField.d.ts +1 -1
  31. package/esm/DateField/useDateField.js +3 -17
  32. package/esm/DatePicker/DatePicker.js +1 -0
  33. package/esm/DateTimeField/useDateTimeField.d.ts +1 -1
  34. package/esm/DateTimeField/useDateTimeField.js +3 -17
  35. package/esm/DateTimePicker/DateTimePicker.js +1 -0
  36. package/esm/DesktopDatePicker/DesktopDatePicker.js +1 -0
  37. package/esm/DesktopDateTimePicker/DesktopDateTimePicker.js +1 -0
  38. package/esm/DesktopTimePicker/DesktopTimePicker.js +1 -0
  39. package/esm/MobileDatePicker/MobileDatePicker.js +1 -0
  40. package/esm/MobileDateTimePicker/MobileDateTimePicker.js +1 -0
  41. package/esm/MobileTimePicker/MobileTimePicker.js +1 -0
  42. package/esm/PickersDay/PickersDay.d.ts +1 -72
  43. package/esm/PickersDay/PickersDay.js +30 -28
  44. package/esm/PickersDay/PickersDay.types.d.ts +114 -0
  45. package/esm/PickersDay/PickersDay.types.js +1 -0
  46. package/esm/PickersDay/index.d.ts +1 -1
  47. package/esm/PickersDay/usePickerDayOwnerState.d.ts +14 -0
  48. package/esm/PickersDay/usePickerDayOwnerState.js +32 -0
  49. package/esm/TimeField/useTimeField.d.ts +1 -1
  50. package/esm/TimeField/useTimeField.js +3 -17
  51. package/esm/TimePicker/TimePicker.js +1 -0
  52. package/esm/hooks/useSplitFieldProps.d.ts +1 -1
  53. package/esm/index.js +1 -1
  54. package/esm/internals/components/PickerFieldUI.d.ts +5 -5
  55. package/esm/internals/hooks/useField/buildSectionsFromFormat.d.ts +2 -2
  56. package/esm/internals/hooks/useField/buildSectionsFromFormat.js +9 -9
  57. package/esm/internals/hooks/useField/index.d.ts +1 -1
  58. package/esm/internals/hooks/useField/useField.d.ts +2 -4
  59. package/esm/internals/hooks/useField/useField.js +5 -229
  60. package/esm/internals/hooks/useField/useField.types.d.ts +48 -68
  61. package/esm/internals/hooks/useField/useField.utils.d.ts +2 -5
  62. package/esm/internals/hooks/useField/useField.utils.js +7 -92
  63. package/esm/internals/hooks/useField/useFieldCharacterEditing.d.ts +19 -26
  64. package/esm/internals/hooks/useField/useFieldCharacterEditing.js +42 -60
  65. package/esm/internals/hooks/useField/useFieldRootHandleKeyDown.d.ts +16 -0
  66. package/esm/internals/hooks/useField/useFieldRootHandleKeyDown.js +204 -0
  67. package/esm/internals/hooks/useField/useFieldState.d.ts +23 -13
  68. package/esm/internals/hooks/useField/useFieldState.js +103 -30
  69. package/esm/internals/hooks/useField/useFieldV6TextField.d.ts +3 -3
  70. package/esm/internals/hooks/useField/useFieldV6TextField.js +202 -135
  71. package/esm/internals/hooks/useField/useFieldV7TextField.d.ts +3 -2
  72. package/esm/internals/hooks/useField/useFieldV7TextField.js +217 -153
  73. package/esm/internals/hooks/usePicker/usePicker.types.d.ts +1 -0
  74. package/esm/internals/index.d.ts +2 -1
  75. package/esm/internals/index.js +1 -0
  76. package/esm/managers/useDateManager.js +3 -3
  77. package/esm/managers/useDateTimeManager.js +3 -3
  78. package/esm/managers/useTimeManager.js +3 -3
  79. package/esm/models/fields.d.ts +2 -2
  80. package/esm/models/manager.d.ts +3 -2
  81. package/hooks/useSplitFieldProps.d.ts +1 -1
  82. package/index.js +1 -1
  83. package/internals/components/PickerFieldUI.d.ts +5 -5
  84. package/internals/hooks/useField/buildSectionsFromFormat.d.ts +2 -2
  85. package/internals/hooks/useField/buildSectionsFromFormat.js +9 -9
  86. package/internals/hooks/useField/index.d.ts +1 -1
  87. package/internals/hooks/useField/useField.d.ts +2 -4
  88. package/internals/hooks/useField/useField.js +5 -231
  89. package/internals/hooks/useField/useField.types.d.ts +48 -68
  90. package/internals/hooks/useField/useField.utils.d.ts +2 -5
  91. package/internals/hooks/useField/useField.utils.js +8 -94
  92. package/internals/hooks/useField/useFieldCharacterEditing.d.ts +19 -26
  93. package/internals/hooks/useField/useFieldCharacterEditing.js +41 -59
  94. package/internals/hooks/useField/useFieldRootHandleKeyDown.d.ts +16 -0
  95. package/internals/hooks/useField/useFieldRootHandleKeyDown.js +210 -0
  96. package/internals/hooks/useField/useFieldState.d.ts +23 -13
  97. package/internals/hooks/useField/useFieldState.js +102 -29
  98. package/internals/hooks/useField/useFieldV6TextField.d.ts +3 -3
  99. package/internals/hooks/useField/useFieldV6TextField.js +202 -135
  100. package/internals/hooks/useField/useFieldV7TextField.d.ts +3 -2
  101. package/internals/hooks/useField/useFieldV7TextField.js +218 -154
  102. package/internals/hooks/usePicker/usePicker.types.d.ts +1 -0
  103. package/internals/index.d.ts +2 -1
  104. package/internals/index.js +7 -0
  105. package/managers/useDateManager.js +3 -3
  106. package/managers/useDateTimeManager.js +3 -3
  107. package/managers/useTimeManager.js +3 -3
  108. package/models/fields.d.ts +2 -2
  109. package/models/manager.d.ts +3 -2
  110. package/modern/DateCalendar/DayCalendar.d.ts +3 -7
  111. package/modern/DateCalendar/DayCalendar.js +16 -8
  112. package/modern/DateCalendar/index.d.ts +0 -1
  113. package/modern/DateField/useDateField.d.ts +1 -1
  114. package/modern/DateField/useDateField.js +3 -17
  115. package/modern/DatePicker/DatePicker.js +1 -0
  116. package/modern/DateTimeField/useDateTimeField.d.ts +1 -1
  117. package/modern/DateTimeField/useDateTimeField.js +3 -17
  118. package/modern/DateTimePicker/DateTimePicker.js +1 -0
  119. package/modern/DesktopDatePicker/DesktopDatePicker.js +1 -0
  120. package/modern/DesktopDateTimePicker/DesktopDateTimePicker.js +1 -0
  121. package/modern/DesktopTimePicker/DesktopTimePicker.js +1 -0
  122. package/modern/MobileDatePicker/MobileDatePicker.js +1 -0
  123. package/modern/MobileDateTimePicker/MobileDateTimePicker.js +1 -0
  124. package/modern/MobileTimePicker/MobileTimePicker.js +1 -0
  125. package/modern/PickersDay/PickersDay.d.ts +1 -72
  126. package/modern/PickersDay/PickersDay.js +30 -28
  127. package/modern/PickersDay/PickersDay.types.d.ts +114 -0
  128. package/modern/PickersDay/PickersDay.types.js +1 -0
  129. package/modern/PickersDay/index.d.ts +1 -1
  130. package/modern/PickersDay/usePickerDayOwnerState.d.ts +14 -0
  131. package/modern/PickersDay/usePickerDayOwnerState.js +32 -0
  132. package/modern/TimeField/useTimeField.d.ts +1 -1
  133. package/modern/TimeField/useTimeField.js +3 -17
  134. package/modern/TimePicker/TimePicker.js +1 -0
  135. package/modern/hooks/useSplitFieldProps.d.ts +1 -1
  136. package/modern/index.js +1 -1
  137. package/modern/internals/components/PickerFieldUI.d.ts +5 -5
  138. package/modern/internals/hooks/useField/buildSectionsFromFormat.d.ts +2 -2
  139. package/modern/internals/hooks/useField/buildSectionsFromFormat.js +9 -9
  140. package/modern/internals/hooks/useField/index.d.ts +1 -1
  141. package/modern/internals/hooks/useField/useField.d.ts +2 -4
  142. package/modern/internals/hooks/useField/useField.js +5 -229
  143. package/modern/internals/hooks/useField/useField.types.d.ts +48 -68
  144. package/modern/internals/hooks/useField/useField.utils.d.ts +2 -5
  145. package/modern/internals/hooks/useField/useField.utils.js +7 -92
  146. package/modern/internals/hooks/useField/useFieldCharacterEditing.d.ts +19 -26
  147. package/modern/internals/hooks/useField/useFieldCharacterEditing.js +42 -60
  148. package/modern/internals/hooks/useField/useFieldRootHandleKeyDown.d.ts +16 -0
  149. package/modern/internals/hooks/useField/useFieldRootHandleKeyDown.js +204 -0
  150. package/modern/internals/hooks/useField/useFieldState.d.ts +23 -13
  151. package/modern/internals/hooks/useField/useFieldState.js +103 -30
  152. package/modern/internals/hooks/useField/useFieldV6TextField.d.ts +3 -3
  153. package/modern/internals/hooks/useField/useFieldV6TextField.js +202 -135
  154. package/modern/internals/hooks/useField/useFieldV7TextField.d.ts +3 -2
  155. package/modern/internals/hooks/useField/useFieldV7TextField.js +217 -153
  156. package/modern/internals/hooks/usePicker/usePicker.types.d.ts +1 -0
  157. package/modern/internals/index.d.ts +2 -1
  158. package/modern/internals/index.js +1 -0
  159. package/modern/managers/useDateManager.js +3 -3
  160. package/modern/managers/useDateTimeManager.js +3 -3
  161. package/modern/managers/useTimeManager.js +3 -3
  162. package/modern/models/fields.d.ts +2 -2
  163. package/modern/models/manager.d.ts +3 -2
  164. package/package.json +1 -1
  165. package/tsconfig.build.tsbuildinfo +1 -1
@@ -1,120 +1,139 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
1
2
  import * as React from 'react';
2
3
  import useForkRef from '@mui/utils/useForkRef';
3
4
  import useEventCallback from '@mui/utils/useEventCallback';
4
5
  import useEnhancedEffect from '@mui/utils/useEnhancedEffect';
6
+ import useTimeout from '@mui/utils/useTimeout';
5
7
  import useId from '@mui/utils/useId';
6
8
  import { getSectionValueNow, getSectionValueText, parseSelectedSections } from "./useField.utils.js";
7
9
  import { getActiveElement } from "../../utils/utils.js";
10
+ import { useSplitFieldProps } from "../../../hooks/index.js";
8
11
  import { usePickerTranslations } from "../../../hooks/usePickerTranslations.js";
9
12
  import { useUtils } from "../useUtils.js";
10
- export const useFieldV7TextField = params => {
13
+ import { useFieldCharacterEditing } from "./useFieldCharacterEditing.js";
14
+ import { useFieldRootHandleKeyDown } from "./useFieldRootHandleKeyDown.js";
15
+ import { useFieldState } from "./useFieldState.js";
16
+ import { useFieldInternalPropsWithDefaults } from "./useFieldInternalPropsWithDefaults.js";
17
+ export const useFieldV7TextField = parameters => {
18
+ const translations = usePickerTranslations();
19
+ const utils = useUtils();
20
+ const id = useId();
11
21
  const {
12
- internalProps: {
13
- disabled,
14
- readOnly = false,
15
- autoFocus = false,
16
- focused: focusedProp
17
- },
18
- forwardedProps: {
19
- sectionListRef: inSectionListRef,
20
- onBlur,
21
- onClick,
22
- onFocus,
23
- onInput,
24
- onPaste
25
- },
26
- fieldValueManager,
27
- applyCharacterEditing,
28
- resetCharacterQuery,
29
- setSelectedSections,
22
+ props,
23
+ manager,
24
+ skipContextFieldRefAssignment,
25
+ manager: {
26
+ valueType,
27
+ internal_fieldValueManager: fieldValueManager,
28
+ internal_useOpenPickerButtonAriaLabel: useOpenPickerButtonAriaLabel
29
+ }
30
+ } = parameters;
31
+ const {
32
+ internalProps,
33
+ forwardedProps
34
+ } = useSplitFieldProps(props, valueType);
35
+ const internalPropsWithDefaults = useFieldInternalPropsWithDefaults({
36
+ manager,
37
+ internalProps,
38
+ skipContextFieldRefAssignment
39
+ });
40
+ const {
41
+ sectionListRef: sectionListRefProp,
42
+ onBlur,
43
+ onClick,
44
+ onFocus,
45
+ onInput,
46
+ onPaste,
47
+ onKeyDown,
48
+ onClear,
49
+ clearable
50
+ } = forwardedProps;
51
+ const {
52
+ disabled = false,
53
+ readOnly = false,
54
+ autoFocus = false,
55
+ focused: focusedProp,
56
+ unstableFieldRef
57
+ } = internalPropsWithDefaults;
58
+ const sectionListRef = React.useRef(null);
59
+ const handleSectionListRef = useForkRef(sectionListRefProp, sectionListRef);
60
+ const stateResponse = useFieldState({
61
+ manager,
62
+ internalPropsWithDefaults,
63
+ forwardedProps
64
+ });
65
+ const {
66
+ // States and derived states
67
+ areAllSectionsEmpty,
68
+ error,
30
69
  parsedSelectedSections,
70
+ sectionOrder,
71
+ sectionsValueBoundaries,
31
72
  state,
32
- clearActiveSection,
73
+ value,
74
+ // Methods to update the states
33
75
  clearValue,
76
+ clearActiveSection,
77
+ setCharacterQuery,
78
+ setSelectedSections,
34
79
  updateSectionValue,
35
- updateValueFromValueStr,
36
- sectionOrder,
37
- areAllSectionsEmpty,
38
- sectionsValueBoundaries
39
- } = params;
40
- const sectionListRef = React.useRef(null);
41
- const handleSectionListRef = useForkRef(inSectionListRef, sectionListRef);
42
- const translations = usePickerTranslations();
43
- const utils = useUtils();
44
- const id = useId();
80
+ updateValueFromValueStr
81
+ } = stateResponse;
82
+ const applyCharacterEditing = useFieldCharacterEditing({
83
+ stateResponse
84
+ });
85
+ const openPickerAriaLabel = useOpenPickerButtonAriaLabel(value);
45
86
  const [focused, setFocused] = React.useState(false);
46
- const interactions = React.useMemo(() => ({
47
- syncSelectionToDOM: () => {
48
- if (!sectionListRef.current) {
49
- return;
50
- }
51
- const selection = document.getSelection();
52
- if (!selection) {
53
- return;
87
+ function syncSelectionToDOM() {
88
+ if (!sectionListRef.current) {
89
+ return;
90
+ }
91
+ const selection = document.getSelection();
92
+ if (!selection) {
93
+ return;
94
+ }
95
+ if (parsedSelectedSections == null) {
96
+ // If the selection contains an element inside the field, we reset it.
97
+ if (selection.rangeCount > 0 && sectionListRef.current.getRoot().contains(selection.getRangeAt(0).startContainer)) {
98
+ selection.removeAllRanges();
54
99
  }
55
- if (parsedSelectedSections == null) {
56
- // If the selection contains an element inside the field, we reset it.
57
- if (selection.rangeCount > 0 && sectionListRef.current.getRoot().contains(selection.getRangeAt(0).startContainer)) {
58
- selection.removeAllRanges();
59
- }
60
- if (focused) {
61
- sectionListRef.current.getRoot().blur();
62
- }
63
- return;
100
+ if (focused) {
101
+ sectionListRef.current.getRoot().blur();
64
102
  }
103
+ return;
104
+ }
65
105
 
66
- // On multi input range pickers we want to update selection range only for the active input
67
- if (!sectionListRef.current.getRoot().contains(getActiveElement(document))) {
68
- return;
69
- }
70
- const range = new window.Range();
71
- let target;
72
- if (parsedSelectedSections === 'all') {
73
- target = sectionListRef.current.getRoot();
106
+ // On multi input range pickers we want to update selection range only for the active input
107
+ if (!sectionListRef.current.getRoot().contains(getActiveElement(document))) {
108
+ return;
109
+ }
110
+ const range = new window.Range();
111
+ let target;
112
+ if (parsedSelectedSections === 'all') {
113
+ target = sectionListRef.current.getRoot();
114
+ } else {
115
+ const section = state.sections[parsedSelectedSections];
116
+ if (section.type === 'empty') {
117
+ target = sectionListRef.current.getSectionContainer(parsedSelectedSections);
74
118
  } else {
75
- const section = state.sections[parsedSelectedSections];
76
- if (section.type === 'empty') {
77
- target = sectionListRef.current.getSectionContainer(parsedSelectedSections);
78
- } else {
79
- target = sectionListRef.current.getSectionContent(parsedSelectedSections);
80
- }
81
- }
82
- range.selectNodeContents(target);
83
- target.focus();
84
- selection.removeAllRanges();
85
- selection.addRange(range);
86
- },
87
- getActiveSectionIndexFromDOM: () => {
88
- const activeElement = getActiveElement(document);
89
- if (!activeElement || !sectionListRef.current || !sectionListRef.current.getRoot().contains(activeElement)) {
90
- return null;
119
+ target = sectionListRef.current.getSectionContent(parsedSelectedSections);
91
120
  }
92
- return sectionListRef.current.getSectionIndexFromDOMElement(activeElement);
93
- },
94
- focusField: (newSelectedSections = 0) => {
95
- if (!sectionListRef.current ||
96
- // if the field is already focused, we don't need to focus it again
97
- interactions.getActiveSectionIndexFromDOM() != null) {
98
- return;
99
- }
100
- const newParsedSelectedSections = parseSelectedSections(newSelectedSections, state.sections);
101
- setFocused(true);
102
- sectionListRef.current.getSectionContent(newParsedSelectedSections).focus();
103
- },
104
- setSelectedSections: newSelectedSections => {
105
- if (!sectionListRef.current) {
106
- return;
107
- }
108
- const newParsedSelectedSections = parseSelectedSections(newSelectedSections, state.sections);
109
- const newActiveSectionIndex = newParsedSelectedSections === 'all' ? 0 : newParsedSelectedSections;
110
- setFocused(newActiveSectionIndex !== null);
111
- setSelectedSections(newSelectedSections);
112
- },
113
- isFieldFocused: () => {
114
- const activeElement = getActiveElement(document);
115
- return !!sectionListRef.current && sectionListRef.current.getRoot().contains(activeElement);
116
121
  }
117
- }), [parsedSelectedSections, setSelectedSections, state.sections, focused]);
122
+ range.selectNodeContents(target);
123
+ target.focus();
124
+ selection.removeAllRanges();
125
+ selection.addRange(range);
126
+ }
127
+ function focusField(newSelectedSections = 0) {
128
+ if (!sectionListRef.current ||
129
+ // if the field is already focused, we don't need to focus it again
130
+ getActiveSectionIndex(sectionListRef) != null) {
131
+ return;
132
+ }
133
+ const newParsedSelectedSections = parseSelectedSections(newSelectedSections, state.sections);
134
+ setFocused(true);
135
+ sectionListRef.current.getSectionContent(newParsedSelectedSections).focus();
136
+ }
118
137
 
119
138
  /**
120
139
  * If a section content has been updated with a value we don't want to keep,
@@ -126,8 +145,9 @@ export const useFieldV7TextField = params => {
126
145
  }
127
146
  const section = state.sections[sectionIndex];
128
147
  sectionListRef.current.getSectionContent(sectionIndex).innerHTML = section.value || section.placeholder;
129
- interactions.syncSelectionToDOM();
148
+ syncSelectionToDOM();
130
149
  });
150
+ const containerClickTimeout = useTimeout();
131
151
  const handleContainerClick = useEventCallback((event, ...args) => {
132
152
  // The click event on the clear button would propagate to the input, trigger this handler and result in a wrong section selection.
133
153
  // We avoid this by checking if the call of `handleContainerClick` is actually intended, or a side effect.
@@ -137,7 +157,7 @@ export const useFieldV7TextField = params => {
137
157
  setFocused(true);
138
158
  onClick?.(event, ...args);
139
159
  if (parsedSelectedSections === 'all') {
140
- setTimeout(() => {
160
+ containerClickTimeout.start(0, () => {
141
161
  const cursorPosition = document.getSelection().getRangeAt(0).startOffset;
142
162
  if (cursorPosition === 0) {
143
163
  setSelectedSections(sectionOrder.startIndex);
@@ -170,9 +190,8 @@ export const useFieldV7TextField = params => {
170
190
  const target = event.target;
171
191
  const keyPressed = target.textContent ?? '';
172
192
  sectionListRef.current.getRoot().innerHTML = state.sections.map(section => `${section.startSeparator}${section.value || section.placeholder}${section.endSeparator}`).join('');
173
- interactions.syncSelectionToDOM();
193
+ syncSelectionToDOM();
174
194
  if (keyPressed.length === 0 || keyPressed.charCodeAt(0) === 10) {
175
- resetCharacterQuery();
176
195
  clearValue();
177
196
  setSelectedSections('all');
178
197
  } else if (keyPressed.length > 1) {
@@ -195,7 +214,7 @@ export const useFieldV7TextField = params => {
195
214
  }
196
215
  const pastedValue = event.clipboardData.getData('text');
197
216
  event.preventDefault();
198
- resetCharacterQuery();
217
+ setCharacterQuery(null);
199
218
  updateValueFromValueStr(pastedValue);
200
219
  });
201
220
  const handleContainerFocus = useEventCallback(event => {
@@ -252,7 +271,7 @@ export const useFieldV7TextField = params => {
252
271
  const digitsAndLetterOnly = /^(([a-zA-Z]+)|)([0-9]+)(([a-zA-Z]+)|)$/.test(pastedValue);
253
272
  const isValidPastedValue = activeSection.contentType === 'letter' && lettersOnly || activeSection.contentType === 'digit' && digitsOnly || activeSection.contentType === 'digit-with-letter' && digitsAndLetterOnly;
254
273
  if (isValidPastedValue) {
255
- resetCharacterQuery();
274
+ setCharacterQuery(null);
256
275
  updateSectionValue({
257
276
  section: activeSection,
258
277
  newSectionValue: pastedValue,
@@ -261,7 +280,7 @@ export const useFieldV7TextField = params => {
261
280
  }
262
281
  // If the pasted value corresponds to a single section, but not the expected type, we skip the modification
263
282
  else if (!lettersOnly && !digitsOnly) {
264
- resetCharacterQuery();
283
+ setCharacterQuery(null);
265
284
  updateValueFromValueStr(pastedValue);
266
285
  }
267
286
  });
@@ -291,7 +310,6 @@ export const useFieldV7TextField = params => {
291
310
  revertDOMSectionChange(sectionIndex);
292
311
  return;
293
312
  }
294
- resetCharacterQuery();
295
313
  revertDOMSectionChange(sectionIndex);
296
314
  clearActiveSection();
297
315
  return;
@@ -304,33 +322,35 @@ export const useFieldV7TextField = params => {
304
322
  // The DOM value needs to remain the one React is expecting.
305
323
  revertDOMSectionChange(sectionIndex);
306
324
  });
307
- useEnhancedEffect(() => {
308
- if (!focused || !sectionListRef.current) {
309
- return;
310
- }
311
- if (parsedSelectedSections === 'all') {
312
- sectionListRef.current.getRoot().focus();
313
- } else if (typeof parsedSelectedSections === 'number') {
314
- const domElement = sectionListRef.current.getSectionContent(parsedSelectedSections);
315
- if (domElement) {
316
- domElement.focus();
317
- }
325
+ const handleClear = useEventCallback((event, ...args) => {
326
+ event.preventDefault();
327
+ onClear?.(event, ...args);
328
+ clearValue();
329
+ if (!isFieldFocused(sectionListRef)) {
330
+ // setSelectedSections is called internally
331
+ focusField(0);
332
+ } else {
333
+ setSelectedSections(sectionOrder.startIndex);
318
334
  }
319
- }, [parsedSelectedSections, focused]);
320
- const sectionBoundaries = React.useMemo(() => {
321
- return state.sections.reduce((acc, next) => {
322
- acc[next.type] = sectionsValueBoundaries[next.type]({
323
- currentDate: null,
324
- contentType: next.contentType,
325
- format: next.format
326
- });
327
- return acc;
328
- }, {});
329
- }, [sectionsValueBoundaries, state.sections]);
335
+ });
336
+ const handleContainerKeyDown = useFieldRootHandleKeyDown({
337
+ manager,
338
+ internalPropsWithDefaults,
339
+ stateResponse
340
+ });
341
+ const wrappedHandleContainerKeyDown = useEventCallback(event => {
342
+ onKeyDown?.(event);
343
+ handleContainerKeyDown(event);
344
+ });
330
345
  const isContainerEditable = parsedSelectedSections === 'all';
331
346
  const elements = React.useMemo(() => {
332
347
  return state.sections.map((section, index) => {
333
348
  const isEditable = !isContainerEditable && !disabled && !readOnly;
349
+ const sectionBoundaries = sectionsValueBoundaries[section.type]({
350
+ currentDate: fieldValueManager.getDateFromSection(value, section),
351
+ contentType: section.contentType,
352
+ format: section.format
353
+ });
334
354
  return {
335
355
  container: {
336
356
  'data-sectionindex': index,
@@ -344,8 +364,8 @@ export const useFieldV7TextField = params => {
344
364
  'aria-labelledby': `${id}-${section.type}`,
345
365
  'aria-readonly': readOnly,
346
366
  'aria-valuenow': getSectionValueNow(section, utils),
347
- 'aria-valuemin': sectionBoundaries[section.type].minimum,
348
- 'aria-valuemax': sectionBoundaries[section.type].maximum,
367
+ 'aria-valuemin': sectionBoundaries.minimum,
368
+ 'aria-valuemax': sectionBoundaries.maximum,
349
369
  'aria-valuetext': section.value ? getSectionValueText(section, utils) : translations.empty,
350
370
  'aria-label': translations[section.type],
351
371
  'aria-disabled': disabled,
@@ -369,7 +389,7 @@ export const useFieldV7TextField = params => {
369
389
  }
370
390
  };
371
391
  });
372
- }, [state.sections, getInputContentFocusHandler, handleInputContentPaste, handleInputContentDragOver, handleInputContentInput, getInputContainerClickHandler, handleInputContentMouseUp, disabled, readOnly, isContainerEditable, translations, utils, sectionBoundaries, id]);
392
+ }, [disabled, fieldValueManager, getInputContainerClickHandler, getInputContentFocusHandler, handleInputContentDragOver, handleInputContentInput, handleInputContentMouseUp, handleInputContentPaste, id, isContainerEditable, readOnly, sectionsValueBoundaries, state.sections, translations, utils, value]);
373
393
  const handleValueStrChange = useEventCallback(event => {
374
394
  updateValueFromValueStr(event.target.value);
375
395
  });
@@ -383,28 +403,72 @@ export const useFieldV7TextField = params => {
383
403
  }
384
404
  }, []); // eslint-disable-line react-hooks/exhaustive-deps
385
405
 
386
- return {
387
- interactions,
388
- returnedValue: {
389
- // Forwarded
390
- autoFocus,
391
- readOnly,
392
- focused: focusedProp ?? focused,
393
- sectionListRef: handleSectionListRef,
394
- onBlur: handleContainerBlur,
395
- onClick: handleContainerClick,
396
- onFocus: handleContainerFocus,
397
- onInput: handleContainerInput,
398
- onPaste: handleContainerPaste,
399
- // Additional
400
- enableAccessibleFieldDOMStructure: true,
401
- elements,
402
- // TODO v7: Try to set to undefined when there is a section selected.
403
- tabIndex: parsedSelectedSections === 0 ? -1 : 0,
404
- contentEditable: isContainerEditable,
405
- value: valueStr,
406
- onChange: handleValueStrChange,
407
- areAllSectionsEmpty
406
+ useEnhancedEffect(() => {
407
+ if (!focused || !sectionListRef.current) {
408
+ return;
409
+ }
410
+ if (parsedSelectedSections === 'all') {
411
+ sectionListRef.current.getRoot().focus();
412
+ } else if (typeof parsedSelectedSections === 'number') {
413
+ const domElement = sectionListRef.current.getSectionContent(parsedSelectedSections);
414
+ if (domElement) {
415
+ domElement.focus();
416
+ }
408
417
  }
409
- };
410
- };
418
+ }, [parsedSelectedSections, focused]);
419
+ useEnhancedEffect(() => {
420
+ syncSelectionToDOM();
421
+ });
422
+ React.useImperativeHandle(unstableFieldRef, () => ({
423
+ getSections: () => state.sections,
424
+ getActiveSectionIndex: () => getActiveSectionIndex(sectionListRef),
425
+ setSelectedSections: newSelectedSections => {
426
+ if (!sectionListRef.current) {
427
+ return;
428
+ }
429
+ const newParsedSelectedSections = parseSelectedSections(newSelectedSections, state.sections);
430
+ const newActiveSectionIndex = newParsedSelectedSections === 'all' ? 0 : newParsedSelectedSections;
431
+ setFocused(newActiveSectionIndex !== null);
432
+ setSelectedSections(newSelectedSections);
433
+ },
434
+ focusField,
435
+ isFieldFocused: () => isFieldFocused(sectionListRef)
436
+ }));
437
+ return _extends({}, forwardedProps, {
438
+ error,
439
+ clearable: Boolean(clearable && !areAllSectionsEmpty && !readOnly && !disabled),
440
+ focused: focusedProp ?? focused,
441
+ sectionListRef: handleSectionListRef,
442
+ onBlur: handleContainerBlur,
443
+ onClick: handleContainerClick,
444
+ onFocus: handleContainerFocus,
445
+ onInput: handleContainerInput,
446
+ onPaste: handleContainerPaste,
447
+ onKeyDown: wrappedHandleContainerKeyDown,
448
+ onClear: handleClear,
449
+ // Additional
450
+ enableAccessibleFieldDOMStructure: true,
451
+ elements,
452
+ // TODO v7: Try to set to undefined when there is a section selected.
453
+ tabIndex: parsedSelectedSections === 0 ? -1 : 0,
454
+ contentEditable: isContainerEditable,
455
+ value: valueStr,
456
+ onChange: handleValueStrChange,
457
+ areAllSectionsEmpty,
458
+ disabled,
459
+ readOnly,
460
+ autoFocus,
461
+ openPickerAriaLabel
462
+ });
463
+ };
464
+ function getActiveSectionIndex(sectionListRef) {
465
+ const activeElement = getActiveElement(document);
466
+ if (!activeElement || !sectionListRef.current || !sectionListRef.current.getRoot().contains(activeElement)) {
467
+ return null;
468
+ }
469
+ return sectionListRef.current.getSectionIndexFromDOMElement(activeElement);
470
+ }
471
+ function isFieldFocused(sectionListRef) {
472
+ const activeElement = getActiveElement(document);
473
+ return !!sectionListRef.current && sectionListRef.current.getRoot().contains(activeElement);
474
+ }
@@ -89,6 +89,7 @@ export interface UsePickerNonStaticProps extends Omit<PickerFieldPrivateContextV
89
89
  format?: string;
90
90
  /**
91
91
  * If `true`, the button to open the Picker will not be rendered (it will only render the field).
92
+ * @deprecated Use the [field component](https://next.mui.com/x/react-date-pickers/fields/) instead.
92
93
  * @default false
93
94
  */
94
95
  disableOpenPicker?: boolean;
@@ -26,7 +26,7 @@ export { DAY_MARGIN, DIALOG_WIDTH, VIEW_HEIGHT, MULTI_SECTION_CLOCK_SECTION_WIDT
26
26
  export { useControlledValue } from "./hooks/useControlledValue.js";
27
27
  export type { DesktopOnlyPickerProps } from './hooks/useDesktopPicker';
28
28
  export { useField, useFieldInternalPropsWithDefaults, createDateStrForV7HiddenInputFromSections, createDateStrForV6InputFromSections } from "./hooks/useField/index.js";
29
- export type { UseFieldInternalProps, UseFieldParams, UseFieldResponse, FieldValueManager, FieldChangeHandler, FieldChangeHandlerContext } from './hooks/useField';
29
+ export type { UseFieldInternalProps, UseFieldParameters, UseFieldReturnValue, FieldValueManager, FieldChangeHandler, FieldChangeHandlerContext } from './hooks/useField';
30
30
  export { useFieldOwnerState } from "./hooks/useFieldOwnerState.js";
31
31
  export type { MobileOnlyPickerProps } from './hooks/useMobilePicker';
32
32
  export { useNullableFieldPrivateContext } from "./hooks/useNullableFieldPrivateContext.js";
@@ -65,6 +65,7 @@ export type { DayCalendarProps, DayCalendarSlots, DayCalendarSlotProps, Exported
65
65
  export type { ExportedDateCalendarProps } from '../DateCalendar/DateCalendar.types';
66
66
  export { useCalendarState } from "../DateCalendar/useCalendarState.js";
67
67
  export { DateTimePickerToolbarOverrideContext } from "../DateTimePicker/DateTimePickerToolbar.js";
68
+ export { usePickerDayOwnerState } from "../PickersDay/usePickerDayOwnerState.js";
68
69
  export { getDateFieldInternalPropsDefaults } from "../managers/useDateManager.js";
69
70
  export { getTimeFieldInternalPropsDefaults } from "../managers/useTimeManager.js";
70
71
  export { getDateTimeFieldInternalPropsDefaults } from "../managers/useDateTimeManager.js";
@@ -33,6 +33,7 @@ export { applyDefaultViewProps } from "./utils/views.js";
33
33
  export { DayCalendar } from "../DateCalendar/DayCalendar.js";
34
34
  export { useCalendarState } from "../DateCalendar/useCalendarState.js";
35
35
  export { DateTimePickerToolbarOverrideContext } from "../DateTimePicker/DateTimePickerToolbar.js";
36
+ export { usePickerDayOwnerState } from "../PickersDay/usePickerDayOwnerState.js";
36
37
  export { getDateFieldInternalPropsDefaults } from "../managers/useDateManager.js";
37
38
  export { getTimeFieldInternalPropsDefaults } from "../managers/useTimeManager.js";
38
39
  export { getDateTimeFieldInternalPropsDefaults } from "../managers/useDateTimeManager.js";
@@ -29,13 +29,13 @@ export function useDateManager(parameters = {}) {
29
29
  internal_useOpenPickerButtonAriaLabel: useOpenPickerButtonAriaLabel
30
30
  }), [enableAccessibleFieldDOMStructure]);
31
31
  }
32
- function useOpenPickerButtonAriaLabel() {
32
+ function useOpenPickerButtonAriaLabel(value) {
33
33
  const utils = useUtils();
34
34
  const translations = usePickerTranslations();
35
- return React.useCallback(value => {
35
+ return React.useMemo(() => {
36
36
  const formattedValue = utils.isValid(value) ? utils.format(value, 'fullDate') : null;
37
37
  return translations.openDatePickerDialogue(formattedValue);
38
- }, [translations, utils]);
38
+ }, [value, translations, utils]);
39
39
  }
40
40
 
41
41
  /**
@@ -29,13 +29,13 @@ export function useDateTimeManager(parameters = {}) {
29
29
  internal_useOpenPickerButtonAriaLabel: useOpenPickerButtonAriaLabel
30
30
  }), [enableAccessibleFieldDOMStructure]);
31
31
  }
32
- function useOpenPickerButtonAriaLabel() {
32
+ function useOpenPickerButtonAriaLabel(value) {
33
33
  const utils = useUtils();
34
34
  const translations = usePickerTranslations();
35
- return React.useCallback(value => {
35
+ return React.useMemo(() => {
36
36
  const formattedValue = utils.isValid(value) ? utils.format(value, 'fullDate') : null;
37
37
  return translations.openDatePickerDialogue(formattedValue);
38
- }, [translations, utils]);
38
+ }, [value, translations, utils]);
39
39
  }
40
40
 
41
41
  /**
@@ -28,14 +28,14 @@ export function useTimeManager(parameters = {}) {
28
28
  }), [ampm, enableAccessibleFieldDOMStructure]);
29
29
  }
30
30
  function createUseOpenPickerButtonAriaLabel(ampm) {
31
- return function useOpenPickerButtonAriaLabel() {
31
+ return function useOpenPickerButtonAriaLabel(value) {
32
32
  const utils = useUtils();
33
33
  const translations = usePickerTranslations();
34
- return React.useCallback(value => {
34
+ return React.useMemo(() => {
35
35
  const formatKey = ampm ?? utils.is12HourCycleInCurrentLocale() ? 'fullTime12h' : 'fullTime24h';
36
36
  const formattedValue = utils.isValid(value) ? utils.format(value, formatKey) : null;
37
37
  return translations.openTimePickerDialogue(formattedValue);
38
- }, [translations, utils]);
38
+ }, [value, translations, utils]);
39
39
  };
40
40
  }
41
41
 
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { TextFieldProps } from '@mui/material/TextField';
3
3
  import type { ExportedPickersSectionListProps } from '../PickersSectionList';
4
- import type { UseFieldInternalProps, UseFieldResponse } from '../internals/hooks/useField';
4
+ import type { UseFieldInternalProps, UseFieldReturnValue } from '../internals/hooks/useField';
5
5
  import type { PickersTextFieldProps } from '../PickersTextField';
6
6
  import { BaseSingleInputFieldProps, FieldRangeSection, PickerRangeValue, PickerValidValue } from "../internals/models/index.js";
7
7
  import { PickerOwnerState } from "./pickers.js";
@@ -131,7 +131,7 @@ export type PickerFieldSlotProps<TValue extends PickerValidValue, TEnableAccessi
131
131
  * Props the text field receives when used inside a single input Picker.
132
132
  * Only contains what the MUI components are passing to the text field, not what users can pass using the `props.slotProps.field` and `props.slotProps.textField`.
133
133
  */
134
- export type BaseSingleInputPickersTextFieldProps<TEnableAccessibleFieldDOMStructure extends boolean> = Omit<UseFieldResponse<TEnableAccessibleFieldDOMStructure, BaseSingleInputFieldProps>, 'slots' | 'slotProps' | 'clearable' | 'onClear' | 'openPickerButtonPosition' | 'clearButtonPosition' | 'openPickerAriaLabel'>;
134
+ export type BaseSingleInputPickersTextFieldProps<TEnableAccessibleFieldDOMStructure extends boolean> = Omit<UseFieldReturnValue<TEnableAccessibleFieldDOMStructure, BaseSingleInputFieldProps>, 'slots' | 'slotProps' | 'clearable' | 'onClear' | 'openPickerButtonPosition' | 'clearButtonPosition' | 'openPickerAriaLabel'>;
135
135
  /**
136
136
  * Props the built-in text field component can receive.
137
137
  */
@@ -72,9 +72,10 @@ export interface PickerManager<TValue extends PickerValidValue, TEnableAccessibl
72
72
  internal_applyDefaultsToFieldInternalProps: (parameters: ApplyDefaultsToFieldInternalPropsParameters<TFieldInternalProps>) => UseFieldInternalProps<TValue, TEnableAccessibleFieldDOMStructure, TError> & TValidationProps;
73
73
  /**
74
74
  * Returns a hook that creates the aria-label to apply on the button that opens the Picker.
75
- * @returns {(value: TValue) => string} The method to create the aria-label to apply on the button that opens the Picker.
75
+ * @param {TValue} value The value of the Picker.
76
+ * @returns {string} The aria-label to apply on the button that opens the Picker.
76
77
  */
77
- internal_useOpenPickerButtonAriaLabel: () => (value: TValue) => string;
78
+ internal_useOpenPickerButtonAriaLabel: (value: TValue) => string;
78
79
  }
79
80
  interface ApplyDefaultsToFieldInternalPropsParameters<TFieldInternalProps extends {}> extends UseLocalizationContextReturnValue {
80
81
  internalProps: TFieldInternalProps;
@@ -1,7 +1,7 @@
1
1
  import { DATE_TIME_VALIDATION_PROP_NAMES, DATE_VALIDATION_PROP_NAMES, TIME_VALIDATION_PROP_NAMES } from "../validation/extractValidationProps.js";
2
2
  import { PickerValueType } from "../models/common.js";
3
3
  declare const SHARED_FIELD_INTERNAL_PROP_NAMES: readonly ["value", "defaultValue", "referenceDate", "format", "formatDensity", "onChange", "timezone", "onError", "shouldRespectLeadingZeros", "selectedSections", "onSelectedSectionsChange", "unstableFieldRef", "unstableStartFieldRef", "unstableEndFieldRef", "enableAccessibleFieldDOMStructure", "disabled", "readOnly", "dateSeparator", "autoFocus", "focused"];
4
- type InternalPropNames<TValueType extends PickerValueType> = (typeof SHARED_FIELD_INTERNAL_PROP_NAMES)[number] | (TValueType extends 'date' | 'date-time' ? (typeof DATE_VALIDATION_PROP_NAMES)[number] : never) | (TValueType extends 'time' | 'date-time' ? (typeof TIME_VALIDATION_PROP_NAMES)[number] : never) | (TValueType extends 'date-time' ? (typeof DATE_TIME_VALIDATION_PROP_NAMES)[number] : never);
4
+ export type InternalPropNames<TValueType extends PickerValueType> = (typeof SHARED_FIELD_INTERNAL_PROP_NAMES)[number] | (TValueType extends 'date' | 'date-time' ? (typeof DATE_VALIDATION_PROP_NAMES)[number] : never) | (TValueType extends 'time' | 'date-time' ? (typeof TIME_VALIDATION_PROP_NAMES)[number] : never) | (TValueType extends 'date-time' ? (typeof DATE_TIME_VALIDATION_PROP_NAMES)[number] : never);
5
5
  /**
6
6
  * Split the props received by the field component into:
7
7
  * - `internalProps` which are used by the various hooks called by the field component.
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-date-pickers v8.0.0-beta.0
2
+ * @mui/x-date-pickers v8.0.0-beta.1
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -6,9 +6,9 @@ import { SvgIconProps } from '@mui/material/SvgIcon';
6
6
  import { MakeOptional, SlotComponentPropsFromProps } from '@mui/x-internals/types';
7
7
  import { FieldOwnerState } from "../../models/index.js";
8
8
  import { UseFieldOwnerStateParameters } from "../hooks/useFieldOwnerState.js";
9
- import type { UseFieldResponse } from '../hooks/useField';
9
+ import type { UseFieldReturnValue, UseFieldProps } from '../hooks/useField';
10
10
  import { PickersTextFieldProps } from "../../PickersTextField/index.js";
11
- export declare const cleanFieldResponse: <TFieldResponse extends MakeOptional<UseFieldResponse<any, ExportedPickerFieldUIProps & {
11
+ export declare const cleanFieldResponse: <TFieldResponse extends MakeOptional<UseFieldReturnValue<any, ExportedPickerFieldUIProps & {
12
12
  [key: string]: any;
13
13
  }>, "onClear" | "clearable">>({
14
14
  enableAccessibleFieldDOMStructure,
@@ -22,7 +22,7 @@ export declare const PickerFieldUIContext: React.Context<PickerFieldUIContextVal
22
22
  * Adds the button to open the Picker and the button to clear the value of the field.
23
23
  * @ignore - internal component.
24
24
  */
25
- export declare function PickerFieldUI(props: PickerFieldUIProps): React.JSX.Element;
25
+ export declare function PickerFieldUI<TEnableAccessibleFieldDOMStructure extends boolean, TProps extends UseFieldProps<TEnableAccessibleFieldDOMStructure>>(props: PickerFieldUIProps<TEnableAccessibleFieldDOMStructure, TProps>): React.JSX.Element;
26
26
  export interface ExportedPickerFieldUIProps {
27
27
  /**
28
28
  * If `true`, a clear button will be shown in the field allowing value clearing.
@@ -46,7 +46,7 @@ export interface ExportedPickerFieldUIProps {
46
46
  */
47
47
  openPickerButtonPosition?: 'start' | 'end';
48
48
  }
49
- export interface PickerFieldUIProps {
49
+ export interface PickerFieldUIProps<TEnableAccessibleFieldDOMStructure extends boolean, TProps extends UseFieldProps<TEnableAccessibleFieldDOMStructure>> {
50
50
  /**
51
51
  * Overridable component slots.
52
52
  * @default {}
@@ -60,7 +60,7 @@ export interface PickerFieldUIProps {
60
60
  /**
61
61
  * Object returned by the `useField` hook or one of its wrapper (for example `useDateField`).
62
62
  */
63
- fieldResponse: UseFieldResponse<any, any>;
63
+ fieldResponse: UseFieldReturnValue<TEnableAccessibleFieldDOMStructure, TProps>;
64
64
  /**
65
65
  * The component to use to render the Picker opening icon if none is provided in the Picker's slots.
66
66
  */