@mui/x-date-pickers 8.0.0-beta.1 → 8.0.0-beta.2

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 (114) hide show
  1. package/CHANGELOG.md +94 -0
  2. package/DateCalendar/DateCalendar.js +4 -8
  3. package/DateCalendar/DayCalendar.js +2 -2
  4. package/DatePicker/shared.js +3 -9
  5. package/DateTimePicker/shared.js +3 -13
  6. package/MonthCalendar/MonthCalendar.js +4 -9
  7. package/PickersSectionList/PickersSectionList.d.ts +1 -1
  8. package/PickersSectionList/PickersSectionList.types.d.ts +2 -6
  9. package/TimePicker/shared.js +3 -3
  10. package/YearCalendar/YearCalendar.js +4 -10
  11. package/esm/DateCalendar/DateCalendar.js +6 -10
  12. package/esm/DateCalendar/DayCalendar.js +2 -2
  13. package/esm/DatePicker/shared.js +3 -9
  14. package/esm/DateTimePicker/shared.js +4 -14
  15. package/esm/MonthCalendar/MonthCalendar.js +6 -11
  16. package/esm/PickersSectionList/PickersSectionList.d.ts +1 -1
  17. package/esm/PickersSectionList/PickersSectionList.types.d.ts +2 -6
  18. package/esm/TimePicker/shared.js +3 -3
  19. package/esm/YearCalendar/YearCalendar.js +5 -11
  20. package/esm/index.js +1 -1
  21. package/esm/internals/hooks/useField/syncSelectionToDOM.d.ts +9 -0
  22. package/esm/internals/hooks/useField/syncSelectionToDOM.js +50 -0
  23. package/esm/internals/hooks/useField/useField.types.d.ts +8 -1
  24. package/esm/internals/hooks/useField/useField.utils.d.ts +1 -3
  25. package/esm/internals/hooks/useField/useField.utils.js +0 -57
  26. package/esm/internals/hooks/useField/useFieldHiddenInputProps.d.ts +20 -0
  27. package/esm/internals/hooks/useField/useFieldHiddenInputProps.js +31 -0
  28. package/esm/internals/hooks/useField/useFieldInternalPropsWithDefaults.js +8 -10
  29. package/esm/internals/hooks/useField/useFieldRootHandleKeyDown.js +1 -0
  30. package/esm/internals/hooks/useField/useFieldRootProps.d.ts +32 -0
  31. package/esm/internals/hooks/useField/useFieldRootProps.js +150 -0
  32. package/esm/internals/hooks/useField/useFieldSectionContainerProps.d.ts +15 -0
  33. package/esm/internals/hooks/useField/useFieldSectionContainerProps.js +29 -0
  34. package/esm/internals/hooks/useField/useFieldSectionContentProps.d.ts +23 -0
  35. package/esm/internals/hooks/useField/useFieldSectionContentProps.js +226 -0
  36. package/esm/internals/hooks/useField/useFieldV7TextField.js +76 -307
  37. package/esm/internals/index.d.ts +4 -4
  38. package/esm/internals/index.js +3 -3
  39. package/esm/locales/deDE.js +2 -3
  40. package/esm/managers/useDateManager.d.ts +4 -13
  41. package/esm/managers/useDateManager.js +18 -28
  42. package/esm/managers/useDateTimeManager.d.ts +4 -13
  43. package/esm/managers/useDateTimeManager.js +23 -33
  44. package/esm/managers/useTimeManager.d.ts +4 -13
  45. package/esm/managers/useTimeManager.js +14 -24
  46. package/esm/models/manager.d.ts +3 -8
  47. package/esm/validation/validateDate.js +3 -4
  48. package/index.js +1 -1
  49. package/internals/hooks/useField/syncSelectionToDOM.d.ts +9 -0
  50. package/internals/hooks/useField/syncSelectionToDOM.js +56 -0
  51. package/internals/hooks/useField/useField.types.d.ts +8 -1
  52. package/internals/hooks/useField/useField.utils.d.ts +1 -3
  53. package/internals/hooks/useField/useField.utils.js +2 -61
  54. package/internals/hooks/useField/useFieldHiddenInputProps.d.ts +20 -0
  55. package/internals/hooks/useField/useFieldHiddenInputProps.js +39 -0
  56. package/internals/hooks/useField/useFieldInternalPropsWithDefaults.js +8 -10
  57. package/internals/hooks/useField/useFieldRootHandleKeyDown.js +1 -0
  58. package/internals/hooks/useField/useFieldRootProps.d.ts +32 -0
  59. package/internals/hooks/useField/useFieldRootProps.js +156 -0
  60. package/internals/hooks/useField/useFieldSectionContainerProps.d.ts +15 -0
  61. package/internals/hooks/useField/useFieldSectionContainerProps.js +37 -0
  62. package/internals/hooks/useField/useFieldSectionContentProps.d.ts +23 -0
  63. package/internals/hooks/useField/useFieldSectionContentProps.js +234 -0
  64. package/internals/hooks/useField/useFieldV7TextField.js +75 -306
  65. package/internals/index.d.ts +4 -4
  66. package/internals/index.js +18 -18
  67. package/locales/deDE.js +2 -3
  68. package/managers/useDateManager.d.ts +4 -13
  69. package/managers/useDateManager.js +18 -28
  70. package/managers/useDateTimeManager.d.ts +4 -13
  71. package/managers/useDateTimeManager.js +23 -33
  72. package/managers/useTimeManager.d.ts +4 -13
  73. package/managers/useTimeManager.js +15 -25
  74. package/models/manager.d.ts +3 -8
  75. package/modern/DateCalendar/DateCalendar.js +6 -10
  76. package/modern/DateCalendar/DayCalendar.js +2 -2
  77. package/modern/DatePicker/shared.js +3 -9
  78. package/modern/DateTimePicker/shared.js +4 -14
  79. package/modern/MonthCalendar/MonthCalendar.js +6 -11
  80. package/modern/PickersSectionList/PickersSectionList.d.ts +1 -1
  81. package/modern/PickersSectionList/PickersSectionList.types.d.ts +2 -6
  82. package/modern/TimePicker/shared.js +3 -3
  83. package/modern/YearCalendar/YearCalendar.js +5 -11
  84. package/modern/index.js +1 -1
  85. package/modern/internals/hooks/useField/syncSelectionToDOM.d.ts +9 -0
  86. package/modern/internals/hooks/useField/syncSelectionToDOM.js +50 -0
  87. package/modern/internals/hooks/useField/useField.types.d.ts +8 -1
  88. package/modern/internals/hooks/useField/useField.utils.d.ts +1 -3
  89. package/modern/internals/hooks/useField/useField.utils.js +0 -57
  90. package/modern/internals/hooks/useField/useFieldHiddenInputProps.d.ts +20 -0
  91. package/modern/internals/hooks/useField/useFieldHiddenInputProps.js +31 -0
  92. package/modern/internals/hooks/useField/useFieldInternalPropsWithDefaults.js +8 -10
  93. package/modern/internals/hooks/useField/useFieldRootHandleKeyDown.js +1 -0
  94. package/modern/internals/hooks/useField/useFieldRootProps.d.ts +32 -0
  95. package/modern/internals/hooks/useField/useFieldRootProps.js +150 -0
  96. package/modern/internals/hooks/useField/useFieldSectionContainerProps.d.ts +15 -0
  97. package/modern/internals/hooks/useField/useFieldSectionContainerProps.js +29 -0
  98. package/modern/internals/hooks/useField/useFieldSectionContentProps.d.ts +23 -0
  99. package/modern/internals/hooks/useField/useFieldSectionContentProps.js +226 -0
  100. package/modern/internals/hooks/useField/useFieldV7TextField.js +76 -307
  101. package/modern/internals/index.d.ts +4 -4
  102. package/modern/internals/index.js +3 -3
  103. package/modern/locales/deDE.js +2 -3
  104. package/modern/managers/useDateManager.d.ts +4 -13
  105. package/modern/managers/useDateManager.js +18 -28
  106. package/modern/managers/useDateTimeManager.d.ts +4 -13
  107. package/modern/managers/useDateTimeManager.js +23 -33
  108. package/modern/managers/useTimeManager.d.ts +4 -13
  109. package/modern/managers/useTimeManager.js +14 -24
  110. package/modern/models/manager.d.ts +3 -8
  111. package/modern/validation/validateDate.js +3 -4
  112. package/package.json +2 -2
  113. package/tsconfig.build.tsbuildinfo +1 -1
  114. package/validation/validateDate.js +3 -4
@@ -3,28 +3,24 @@ import * as React from 'react';
3
3
  import useForkRef from '@mui/utils/useForkRef';
4
4
  import useEventCallback from '@mui/utils/useEventCallback';
5
5
  import useEnhancedEffect from '@mui/utils/useEnhancedEffect';
6
- import useTimeout from '@mui/utils/useTimeout';
7
- import useId from '@mui/utils/useId';
8
- import { getSectionValueNow, getSectionValueText, parseSelectedSections } from "./useField.utils.js";
6
+ import { parseSelectedSections } from "./useField.utils.js";
9
7
  import { getActiveElement } from "../../utils/utils.js";
10
8
  import { useSplitFieldProps } from "../../../hooks/index.js";
11
- import { usePickerTranslations } from "../../../hooks/usePickerTranslations.js";
12
- import { useUtils } from "../useUtils.js";
13
9
  import { useFieldCharacterEditing } from "./useFieldCharacterEditing.js";
14
- import { useFieldRootHandleKeyDown } from "./useFieldRootHandleKeyDown.js";
15
10
  import { useFieldState } from "./useFieldState.js";
16
11
  import { useFieldInternalPropsWithDefaults } from "./useFieldInternalPropsWithDefaults.js";
12
+ import { syncSelectionToDOM } from "./syncSelectionToDOM.js";
13
+ import { useFieldRootProps } from "./useFieldRootProps.js";
14
+ import { useFieldHiddenInputProps } from "./useFieldHiddenInputProps.js";
15
+ import { useFieldSectionContainerProps } from "./useFieldSectionContainerProps.js";
16
+ import { useFieldSectionContentProps } from "./useFieldSectionContentProps.js";
17
17
  export const useFieldV7TextField = parameters => {
18
- const translations = usePickerTranslations();
19
- const utils = useUtils();
20
- const id = useId();
21
18
  const {
22
19
  props,
23
20
  manager,
24
21
  skipContextFieldRefAssignment,
25
22
  manager: {
26
23
  valueType,
27
- internal_fieldValueManager: fieldValueManager,
28
24
  internal_useOpenPickerButtonAriaLabel: useOpenPickerButtonAriaLabel
29
25
  }
30
26
  } = parameters;
@@ -57,6 +53,13 @@ export const useFieldV7TextField = parameters => {
57
53
  } = internalPropsWithDefaults;
58
54
  const sectionListRef = React.useRef(null);
59
55
  const handleSectionListRef = useForkRef(sectionListRefProp, sectionListRef);
56
+ const domGetters = React.useMemo(() => ({
57
+ isReady: () => sectionListRef.current != null,
58
+ getRoot: () => sectionListRef.current.getRoot(),
59
+ getSectionContainer: sectionIndex => sectionListRef.current.getSectionContainer(sectionIndex),
60
+ getSectionContent: sectionIndex => sectionListRef.current.getSectionContent(sectionIndex),
61
+ getSectionIndexFromDOMElement: element => sectionListRef.current.getSectionIndexFromDOMElement(element)
62
+ }), [sectionListRef]);
60
63
  const stateResponse = useFieldState({
61
64
  manager,
62
65
  internalPropsWithDefaults,
@@ -68,62 +71,17 @@ export const useFieldV7TextField = parameters => {
68
71
  error,
69
72
  parsedSelectedSections,
70
73
  sectionOrder,
71
- sectionsValueBoundaries,
72
74
  state,
73
75
  value,
74
76
  // Methods to update the states
75
77
  clearValue,
76
- clearActiveSection,
77
- setCharacterQuery,
78
- setSelectedSections,
79
- updateSectionValue,
80
- updateValueFromValueStr
78
+ setSelectedSections
81
79
  } = stateResponse;
82
80
  const applyCharacterEditing = useFieldCharacterEditing({
83
81
  stateResponse
84
82
  });
85
83
  const openPickerAriaLabel = useOpenPickerButtonAriaLabel(value);
86
84
  const [focused, setFocused] = React.useState(false);
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();
99
- }
100
- if (focused) {
101
- sectionListRef.current.getRoot().blur();
102
- }
103
- return;
104
- }
105
-
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);
118
- } else {
119
- target = sectionListRef.current.getSectionContent(parsedSelectedSections);
120
- }
121
- }
122
- range.selectNodeContents(target);
123
- target.focus();
124
- selection.removeAllRanges();
125
- selection.addRange(range);
126
- }
127
85
  function focusField(newSelectedSections = 0) {
128
86
  if (!sectionListRef.current ||
129
87
  // if the field is already focused, we don't need to focus it again
@@ -134,193 +92,53 @@ export const useFieldV7TextField = parameters => {
134
92
  setFocused(true);
135
93
  sectionListRef.current.getSectionContent(newParsedSelectedSections).focus();
136
94
  }
137
-
138
- /**
139
- * If a section content has been updated with a value we don't want to keep,
140
- * Then we need to imperatively revert it (we can't let React do it because the value did not change in his internal representation).
141
- */
142
- const revertDOMSectionChange = useEventCallback(sectionIndex => {
143
- if (!sectionListRef.current) {
144
- return;
145
- }
146
- const section = state.sections[sectionIndex];
147
- sectionListRef.current.getSectionContent(sectionIndex).innerHTML = section.value || section.placeholder;
148
- syncSelectionToDOM();
95
+ const rootProps = useFieldRootProps({
96
+ manager,
97
+ internalPropsWithDefaults,
98
+ stateResponse,
99
+ applyCharacterEditing,
100
+ focused,
101
+ setFocused,
102
+ domGetters
149
103
  });
150
- const containerClickTimeout = useTimeout();
151
- const handleContainerClick = useEventCallback((event, ...args) => {
152
- // The click event on the clear button would propagate to the input, trigger this handler and result in a wrong section selection.
153
- // We avoid this by checking if the call of `handleContainerClick` is actually intended, or a side effect.
154
- if (event.isDefaultPrevented() || !sectionListRef.current) {
155
- return;
156
- }
157
- setFocused(true);
158
- onClick?.(event, ...args);
159
- if (parsedSelectedSections === 'all') {
160
- containerClickTimeout.start(0, () => {
161
- const cursorPosition = document.getSelection().getRangeAt(0).startOffset;
162
- if (cursorPosition === 0) {
163
- setSelectedSections(sectionOrder.startIndex);
164
- return;
165
- }
166
- let sectionIndex = 0;
167
- let cursorOnStartOfSection = 0;
168
- while (cursorOnStartOfSection < cursorPosition && sectionIndex < state.sections.length) {
169
- const section = state.sections[sectionIndex];
170
- sectionIndex += 1;
171
- cursorOnStartOfSection += `${section.startSeparator}${section.value || section.placeholder}${section.endSeparator}`.length;
172
- }
173
- setSelectedSections(sectionIndex - 1);
174
- });
175
- } else if (!focused) {
176
- setFocused(true);
177
- setSelectedSections(sectionOrder.startIndex);
178
- } else {
179
- const hasClickedOnASection = sectionListRef.current.getRoot().contains(event.target);
180
- if (!hasClickedOnASection) {
181
- setSelectedSections(sectionOrder.startIndex);
182
- }
183
- }
104
+ const hiddenInputProps = useFieldHiddenInputProps({
105
+ manager,
106
+ stateResponse
184
107
  });
185
- const handleContainerInput = useEventCallback(event => {
186
- onInput?.(event);
187
- if (!sectionListRef.current || parsedSelectedSections !== 'all') {
188
- return;
189
- }
190
- const target = event.target;
191
- const keyPressed = target.textContent ?? '';
192
- sectionListRef.current.getRoot().innerHTML = state.sections.map(section => `${section.startSeparator}${section.value || section.placeholder}${section.endSeparator}`).join('');
193
- syncSelectionToDOM();
194
- if (keyPressed.length === 0 || keyPressed.charCodeAt(0) === 10) {
195
- clearValue();
196
- setSelectedSections('all');
197
- } else if (keyPressed.length > 1) {
198
- updateValueFromValueStr(keyPressed);
199
- } else {
200
- if (parsedSelectedSections === 'all') {
201
- setSelectedSections(0);
202
- }
203
- applyCharacterEditing({
204
- keyPressed,
205
- sectionIndex: 0
206
- });
207
- }
108
+ const createSectionContainerProps = useFieldSectionContainerProps({
109
+ stateResponse
208
110
  });
209
- const handleContainerPaste = useEventCallback(event => {
210
- onPaste?.(event);
211
- if (readOnly || parsedSelectedSections !== 'all') {
212
- event.preventDefault();
213
- return;
214
- }
215
- const pastedValue = event.clipboardData.getData('text');
216
- event.preventDefault();
217
- setCharacterQuery(null);
218
- updateValueFromValueStr(pastedValue);
111
+ const createSectionContentProps = useFieldSectionContentProps({
112
+ manager,
113
+ stateResponse,
114
+ applyCharacterEditing,
115
+ internalPropsWithDefaults,
116
+ domGetters,
117
+ focused
219
118
  });
220
- const handleContainerFocus = useEventCallback(event => {
221
- onFocus?.(event);
222
- if (focused || !sectionListRef.current) {
223
- return;
224
- }
225
- const activeElement = getActiveElement(document);
226
- setFocused(true);
227
- const isFocusInsideASection = sectionListRef.current.getSectionIndexFromDOMElement(activeElement) != null;
228
- if (!isFocusInsideASection) {
229
- setSelectedSections(sectionOrder.startIndex);
230
- }
119
+ const handleRootKeyDown = useEventCallback(event => {
120
+ onKeyDown?.(event);
121
+ rootProps.onKeyDown(event);
231
122
  });
232
- const handleContainerBlur = useEventCallback(event => {
123
+ const handleRootBlur = useEventCallback(event => {
233
124
  onBlur?.(event);
234
- setTimeout(() => {
235
- if (!sectionListRef.current) {
236
- return;
237
- }
238
- const activeElement = getActiveElement(document);
239
- const shouldBlur = !sectionListRef.current.getRoot().contains(activeElement);
240
- if (shouldBlur) {
241
- setFocused(false);
242
- setSelectedSections(null);
243
- }
244
- });
125
+ rootProps.onBlur(event);
245
126
  });
246
- const getInputContainerClickHandler = useEventCallback(sectionIndex => event => {
247
- // The click event on the clear button would propagate to the input, trigger this handler and result in a wrong section selection.
248
- // We avoid this by checking if the call to this function is actually intended, or a side effect.
249
- if (event.isDefaultPrevented()) {
250
- return;
251
- }
252
- setSelectedSections(sectionIndex);
253
- });
254
- const handleInputContentMouseUp = useEventCallback(event => {
255
- // Without this, the browser will remove the selected when clicking inside an already-selected section.
256
- event.preventDefault();
127
+ const handleRootFocus = useEventCallback(event => {
128
+ onFocus?.(event);
129
+ rootProps.onFocus(event);
257
130
  });
258
- const getInputContentFocusHandler = useEventCallback(sectionIndex => () => {
259
- setSelectedSections(sectionIndex);
131
+ const handleRootClick = useEventCallback(event => {
132
+ onClick?.(event);
133
+ rootProps.onClick(event);
260
134
  });
261
- const handleInputContentPaste = useEventCallback(event => {
262
- // prevent default to avoid the input `onInput` handler being called
263
- event.preventDefault();
264
- if (readOnly || disabled || typeof parsedSelectedSections !== 'number') {
265
- return;
266
- }
267
- const activeSection = state.sections[parsedSelectedSections];
268
- const pastedValue = event.clipboardData.getData('text');
269
- const lettersOnly = /^[a-zA-Z]+$/.test(pastedValue);
270
- const digitsOnly = /^[0-9]+$/.test(pastedValue);
271
- const digitsAndLetterOnly = /^(([a-zA-Z]+)|)([0-9]+)(([a-zA-Z]+)|)$/.test(pastedValue);
272
- const isValidPastedValue = activeSection.contentType === 'letter' && lettersOnly || activeSection.contentType === 'digit' && digitsOnly || activeSection.contentType === 'digit-with-letter' && digitsAndLetterOnly;
273
- if (isValidPastedValue) {
274
- setCharacterQuery(null);
275
- updateSectionValue({
276
- section: activeSection,
277
- newSectionValue: pastedValue,
278
- shouldGoToNextSection: true
279
- });
280
- }
281
- // If the pasted value corresponds to a single section, but not the expected type, we skip the modification
282
- else if (!lettersOnly && !digitsOnly) {
283
- setCharacterQuery(null);
284
- updateValueFromValueStr(pastedValue);
285
- }
286
- });
287
- const handleInputContentDragOver = useEventCallback(event => {
288
- event.preventDefault();
289
- event.dataTransfer.dropEffect = 'none';
135
+ const handleRootPaste = useEventCallback(event => {
136
+ onPaste?.(event);
137
+ rootProps.onPaste(event);
290
138
  });
291
- const handleInputContentInput = useEventCallback(event => {
292
- if (!sectionListRef.current) {
293
- return;
294
- }
295
- const target = event.target;
296
- const keyPressed = target.textContent ?? '';
297
- const sectionIndex = sectionListRef.current.getSectionIndexFromDOMElement(target);
298
- const section = state.sections[sectionIndex];
299
- if (readOnly || !sectionListRef.current) {
300
- revertDOMSectionChange(sectionIndex);
301
- return;
302
- }
303
- if (keyPressed.length === 0) {
304
- if (section.value === '') {
305
- revertDOMSectionChange(sectionIndex);
306
- return;
307
- }
308
- const inputType = event.nativeEvent.inputType;
309
- if (inputType === 'insertParagraph' || inputType === 'insertLineBreak') {
310
- revertDOMSectionChange(sectionIndex);
311
- return;
312
- }
313
- revertDOMSectionChange(sectionIndex);
314
- clearActiveSection();
315
- return;
316
- }
317
- applyCharacterEditing({
318
- keyPressed,
319
- sectionIndex
320
- });
321
-
322
- // The DOM value needs to remain the one React is expecting.
323
- revertDOMSectionChange(sectionIndex);
139
+ const handleRootInput = useEventCallback(event => {
140
+ onInput?.(event);
141
+ rootProps.onInput(event);
324
142
  });
325
143
  const handleClear = useEventCallback((event, ...args) => {
326
144
  event.preventDefault();
@@ -333,67 +151,18 @@ export const useFieldV7TextField = parameters => {
333
151
  setSelectedSections(sectionOrder.startIndex);
334
152
  }
335
153
  });
336
- const handleContainerKeyDown = useFieldRootHandleKeyDown({
337
- manager,
338
- internalPropsWithDefaults,
339
- stateResponse
340
- });
341
- const wrappedHandleContainerKeyDown = useEventCallback(event => {
342
- onKeyDown?.(event);
343
- handleContainerKeyDown(event);
344
- });
345
- const isContainerEditable = parsedSelectedSections === 'all';
346
154
  const elements = React.useMemo(() => {
347
- return state.sections.map((section, index) => {
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
- });
354
- return {
355
- container: {
356
- 'data-sectionindex': index,
357
- onClick: getInputContainerClickHandler(index)
358
- },
359
- content: {
360
- tabIndex: isContainerEditable || index > 0 ? -1 : 0,
361
- contentEditable: !isContainerEditable && !disabled && !readOnly,
362
- role: 'spinbutton',
363
- id: `${id}-${section.type}`,
364
- 'aria-labelledby': `${id}-${section.type}`,
365
- 'aria-readonly': readOnly,
366
- 'aria-valuenow': getSectionValueNow(section, utils),
367
- 'aria-valuemin': sectionBoundaries.minimum,
368
- 'aria-valuemax': sectionBoundaries.maximum,
369
- 'aria-valuetext': section.value ? getSectionValueText(section, utils) : translations.empty,
370
- 'aria-label': translations[section.type],
371
- 'aria-disabled': disabled,
372
- spellCheck: isEditable ? false : undefined,
373
- autoCapitalize: isEditable ? 'off' : undefined,
374
- autoCorrect: isEditable ? 'off' : undefined,
375
- [parseInt(React.version, 10) >= 17 ? 'enterKeyHint' : 'enterkeyhint']: isEditable ? 'next' : undefined,
376
- children: section.value || section.placeholder,
377
- onInput: handleInputContentInput,
378
- onPaste: handleInputContentPaste,
379
- onFocus: getInputContentFocusHandler(index),
380
- onDragOver: handleInputContentDragOver,
381
- onMouseUp: handleInputContentMouseUp,
382
- inputMode: section.contentType === 'letter' ? 'text' : 'numeric'
383
- },
384
- before: {
385
- children: section.startSeparator
386
- },
387
- after: {
388
- children: section.endSeparator
389
- }
390
- };
391
- });
392
- }, [disabled, fieldValueManager, getInputContainerClickHandler, getInputContentFocusHandler, handleInputContentDragOver, handleInputContentInput, handleInputContentMouseUp, handleInputContentPaste, id, isContainerEditable, readOnly, sectionsValueBoundaries, state.sections, translations, utils, value]);
393
- const handleValueStrChange = useEventCallback(event => {
394
- updateValueFromValueStr(event.target.value);
395
- });
396
- const valueStr = React.useMemo(() => areAllSectionsEmpty ? '' : fieldValueManager.getV7HiddenInputValueFromSections(state.sections), [areAllSectionsEmpty, state.sections, fieldValueManager]);
155
+ return state.sections.map((section, sectionIndex) => ({
156
+ container: createSectionContainerProps(sectionIndex),
157
+ content: createSectionContentProps(section, sectionIndex),
158
+ before: {
159
+ children: section.startSeparator
160
+ },
161
+ after: {
162
+ children: section.endSeparator
163
+ }
164
+ }));
165
+ }, [state.sections, createSectionContainerProps, createSectionContentProps]);
397
166
  React.useEffect(() => {
398
167
  if (sectionListRef.current == null) {
399
168
  throw new Error(['MUI X: The `sectionListRef` prop has not been initialized by `PickersSectionList`', 'You probably tried to pass a component to the `textField` slot that contains an `<input />` element instead of a `PickersSectionList`.', '', 'If you want to keep using an `<input />` HTML element for the editing, please remove the `enableAccessibleFieldDOMStructure` prop from your Picker or Field component:', '', '<DatePicker slots={{ textField: MyCustomTextField }} />', '', 'Learn more about the field accessible DOM structure on the MUI documentation: https://mui.com/x/react-date-pickers/fields/#fields-to-edit-a-single-element'].join('\n'));
@@ -417,7 +186,11 @@ export const useFieldV7TextField = parameters => {
417
186
  }
418
187
  }, [parsedSelectedSections, focused]);
419
188
  useEnhancedEffect(() => {
420
- syncSelectionToDOM();
189
+ syncSelectionToDOM({
190
+ focused,
191
+ domGetters,
192
+ stateResponse
193
+ });
421
194
  });
422
195
  React.useImperativeHandle(unstableFieldRef, () => ({
423
196
  getSections: () => state.sections,
@@ -434,26 +207,22 @@ export const useFieldV7TextField = parameters => {
434
207
  focusField,
435
208
  isFieldFocused: () => isFieldFocused(sectionListRef)
436
209
  }));
437
- return _extends({}, forwardedProps, {
210
+ return _extends({}, forwardedProps, rootProps, {
211
+ onBlur: handleRootBlur,
212
+ onClick: handleRootClick,
213
+ onFocus: handleRootFocus,
214
+ onInput: handleRootInput,
215
+ onPaste: handleRootPaste,
216
+ onKeyDown: handleRootKeyDown,
217
+ onClear: handleClear
218
+ }, hiddenInputProps, {
438
219
  error,
439
220
  clearable: Boolean(clearable && !areAllSectionsEmpty && !readOnly && !disabled),
440
221
  focused: focusedProp ?? focused,
441
222
  sectionListRef: handleSectionListRef,
442
- onBlur: handleContainerBlur,
443
- onClick: handleContainerClick,
444
- onFocus: handleContainerFocus,
445
- onInput: handleContainerInput,
446
- onPaste: handleContainerPaste,
447
- onKeyDown: wrappedHandleContainerKeyDown,
448
- onClear: handleClear,
449
223
  // Additional
450
224
  enableAccessibleFieldDOMStructure: true,
451
225
  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
226
  areAllSectionsEmpty,
458
227
  disabled,
459
228
  readOnly,
@@ -42,7 +42,7 @@ export { useLocalizationContext, useDefaultDates, useUtils, useNow } from "./hoo
42
42
  export type { ExportedUseViewsOptions, UseViewsOptions } from './hooks/useViews';
43
43
  export { useViews } from "./hooks/useViews.js";
44
44
  export { usePreviousMonthDisabled, useNextMonthDisabled } from "./hooks/date-helpers-hooks.js";
45
- export type { PickerAnyManager, PickerManagerFieldInternalProps, PickerManagerEnableAccessibleFieldDOMStructure, PickerManagerError, PickerValueManager } from './models/manager';
45
+ export type { PickerAnyManager, PickerManagerFieldInternalProps, PickerManagerFieldInternalPropsWithDefaults, PickerManagerEnableAccessibleFieldDOMStructure, PickerManagerError, PickerValueManager } from './models/manager';
46
46
  export type { RangePosition } from './models/pickers';
47
47
  export type { BaseSingleInputFieldProps, FieldRangeSection } from './models/fields';
48
48
  export type { BasePickerProps, BasePickerInputProps } from './models/props/basePickerProps';
@@ -66,6 +66,6 @@ export type { ExportedDateCalendarProps } from '../DateCalendar/DateCalendar.typ
66
66
  export { useCalendarState } from "../DateCalendar/useCalendarState.js";
67
67
  export { DateTimePickerToolbarOverrideContext } from "../DateTimePicker/DateTimePickerToolbar.js";
68
68
  export { usePickerDayOwnerState } from "../PickersDay/usePickerDayOwnerState.js";
69
- export { getDateFieldInternalPropsDefaults } from "../managers/useDateManager.js";
70
- export { getTimeFieldInternalPropsDefaults } from "../managers/useTimeManager.js";
71
- export { getDateTimeFieldInternalPropsDefaults } from "../managers/useDateTimeManager.js";
69
+ export { useApplyDefaultValuesToDateValidationProps } from "../managers/useDateManager.js";
70
+ export { useApplyDefaultValuesToTimeValidationProps } from "../managers/useTimeManager.js";
71
+ export { useApplyDefaultValuesToDateTimeValidationProps } from "../managers/useDateTimeManager.js";
@@ -34,6 +34,6 @@ export { DayCalendar } from "../DateCalendar/DayCalendar.js";
34
34
  export { useCalendarState } from "../DateCalendar/useCalendarState.js";
35
35
  export { DateTimePickerToolbarOverrideContext } from "../DateTimePicker/DateTimePickerToolbar.js";
36
36
  export { usePickerDayOwnerState } from "../PickersDay/usePickerDayOwnerState.js";
37
- export { getDateFieldInternalPropsDefaults } from "../managers/useDateManager.js";
38
- export { getTimeFieldInternalPropsDefaults } from "../managers/useTimeManager.js";
39
- export { getDateTimeFieldInternalPropsDefaults } from "../managers/useDateTimeManager.js";
37
+ export { useApplyDefaultValuesToDateValidationProps } from "../managers/useDateManager.js";
38
+ export { useApplyDefaultValuesToTimeValidationProps } from "../managers/useTimeManager.js";
39
+ export { useApplyDefaultValuesToDateTimeValidationProps } from "../managers/useDateTimeManager.js";
@@ -31,8 +31,7 @@ const deDEPickers = {
31
31
  dateTimePickerToolbarTitle: 'Datum & Uhrzeit auswählen',
32
32
  timePickerToolbarTitle: 'Uhrzeit auswählen',
33
33
  dateRangePickerToolbarTitle: 'Datumsbereich auswählen',
34
- // timeRangePickerToolbarTitle: 'Select time range',
35
-
34
+ timeRangePickerToolbarTitle: 'Zeitspanne auswählen',
36
35
  // Clock labels
37
36
  clockLabelText: (view, formattedTime) => `${timeViews[view] ?? view} auswählen. ${!formattedTime ? 'Keine Uhrzeit ausgewählt' : `Gewählte Uhrzeit ist ${formattedTime}`}`,
38
37
  hoursClockNumberText: hours => `${hours} ${timeViews.hours}`,
@@ -48,7 +47,7 @@ const deDEPickers = {
48
47
  // Open Picker labels
49
48
  openDatePickerDialogue: formattedDate => formattedDate ? `Datum auswählen, gewähltes Datum ist ${formattedDate}` : 'Datum auswählen',
50
49
  openTimePickerDialogue: formattedTime => formattedTime ? `Uhrzeit auswählen, gewählte Uhrzeit ist ${formattedTime}` : 'Uhrzeit auswählen',
51
- // openRangePickerDialogue: formattedRange => formattedRange ? `Choose range, selected range is ${formattedRange}` : 'Choose range',
50
+ openRangePickerDialogue: formattedRange => formattedRange ? `Zeitspanne auswählen, die aktuell ausgewählte Zeitspanne ist ${formattedRange}` : 'Zeitspanne auswählen',
52
51
  fieldClearLabel: 'Wert leeren',
53
52
  // Table labels
54
53
  timeTableLabel: 'Uhrzeit auswählen',
@@ -1,23 +1,14 @@
1
1
  import type { MakeOptional } from '@mui/x-internals/types';
2
2
  import { PickerManager, DateValidationError } from "../models/index.js";
3
3
  import { UseFieldInternalProps } from "../internals/hooks/useField/index.js";
4
- import { MuiPickersAdapterContextValue } from "../LocalizationProvider/LocalizationProvider.js";
5
- import { ExportedValidateDateProps, ValidateDatePropsToDefault, ValidateDateProps } from "../validation/validateDate.js";
6
- import { PickerManagerFieldInternalPropsWithDefaults, PickerValue } from "../internals/models/index.js";
4
+ import { ExportedValidateDateProps, ValidateDateProps } from "../validation/validateDate.js";
5
+ import { PickerValue } from "../internals/models/index.js";
7
6
  export declare function useDateManager<TEnableAccessibleFieldDOMStructure extends boolean = true>(parameters?: UseDateManagerParameters<TEnableAccessibleFieldDOMStructure>): UseDateManagerReturnValue<TEnableAccessibleFieldDOMStructure>;
8
- /**
9
- * Private utility function to get the default internal props for the fields with date editing.
10
- * Is used by the `useDateManager` and `useDateRangeManager` hooks.
11
- */
12
- export declare function getDateFieldInternalPropsDefaults(parameters: GetDateFieldInternalPropsDefaultsParameters): GetDateFieldInternalPropsDefaultsReturnValue;
7
+ type SharedDateAndDateRangeValidationProps = 'disablePast' | 'disableFuture' | 'minDate' | 'maxDate';
8
+ export declare function useApplyDefaultValuesToDateValidationProps(props: Pick<ExportedValidateDateProps, SharedDateAndDateRangeValidationProps>): Pick<ValidateDateProps, SharedDateAndDateRangeValidationProps>;
13
9
  export interface UseDateManagerParameters<TEnableAccessibleFieldDOMStructure extends boolean> {
14
10
  enableAccessibleFieldDOMStructure?: TEnableAccessibleFieldDOMStructure;
15
11
  }
16
12
  export type UseDateManagerReturnValue<TEnableAccessibleFieldDOMStructure extends boolean> = PickerManager<PickerValue, TEnableAccessibleFieldDOMStructure, DateValidationError, ValidateDateProps, DateManagerFieldInternalProps<TEnableAccessibleFieldDOMStructure>>;
17
13
  export interface DateManagerFieldInternalProps<TEnableAccessibleFieldDOMStructure extends boolean> extends MakeOptional<UseFieldInternalProps<PickerValue, TEnableAccessibleFieldDOMStructure, DateValidationError>, 'format'>, ExportedValidateDateProps {}
18
- type DateManagerFieldPropsToDefault = 'format' | ValidateDatePropsToDefault;
19
- interface GetDateFieldInternalPropsDefaultsParameters extends Pick<MuiPickersAdapterContextValue, 'defaultDates' | 'utils'> {
20
- internalProps: Pick<DateManagerFieldInternalProps<true>, DateManagerFieldPropsToDefault>;
21
- }
22
- interface GetDateFieldInternalPropsDefaultsReturnValue extends Pick<PickerManagerFieldInternalPropsWithDefaults<UseDateManagerReturnValue<true>>, DateManagerFieldPropsToDefault> {}
23
14
  export {};
@@ -5,7 +5,7 @@ import * as React from 'react';
5
5
  import { applyDefaultDate } from "../internals/utils/date-utils.js";
6
6
  import { singleItemFieldValueManager, singleItemValueManager } from "../internals/utils/valueManagers.js";
7
7
  import { validateDate } from "../validation/index.js";
8
- import { useUtils } from "../internals/hooks/useUtils.js";
8
+ import { useDefaultDates, useUtils } from "../internals/hooks/useUtils.js";
9
9
  import { usePickerTranslations } from "../hooks/usePickerTranslations.js";
10
10
  export function useDateManager(parameters = {}) {
11
11
  const {
@@ -17,15 +17,7 @@ export function useDateManager(parameters = {}) {
17
17
  internal_valueManager: singleItemValueManager,
18
18
  internal_fieldValueManager: singleItemFieldValueManager,
19
19
  internal_enableAccessibleFieldDOMStructure: enableAccessibleFieldDOMStructure,
20
- internal_applyDefaultsToFieldInternalProps: ({
21
- internalProps,
22
- utils,
23
- defaultDates
24
- }) => _extends({}, internalProps, getDateFieldInternalPropsDefaults({
25
- defaultDates,
26
- utils,
27
- internalProps
28
- })),
20
+ internal_useApplyDefaultValuesToFieldInternalProps: useApplyDefaultValuesToDateFieldInternalProps,
29
21
  internal_useOpenPickerButtonAriaLabel: useOpenPickerButtonAriaLabel
30
22
  }), [enableAccessibleFieldDOMStructure]);
31
23
  }
@@ -37,22 +29,20 @@ function useOpenPickerButtonAriaLabel(value) {
37
29
  return translations.openDatePickerDialogue(formattedValue);
38
30
  }, [value, translations, utils]);
39
31
  }
40
-
41
- /**
42
- * Private utility function to get the default internal props for the fields with date editing.
43
- * Is used by the `useDateManager` and `useDateRangeManager` hooks.
44
- */
45
- export function getDateFieldInternalPropsDefaults(parameters) {
46
- const {
47
- defaultDates,
48
- utils,
49
- internalProps
50
- } = parameters;
51
- return {
52
- format: internalProps.format ?? utils.formats.keyboardDate,
53
- disablePast: internalProps.disablePast ?? false,
54
- disableFuture: internalProps.disableFuture ?? false,
55
- minDate: applyDefaultDate(utils, internalProps.minDate, defaultDates.minDate),
56
- maxDate: applyDefaultDate(utils, internalProps.maxDate, defaultDates.maxDate)
57
- };
32
+ function useApplyDefaultValuesToDateFieldInternalProps(internalProps) {
33
+ const utils = useUtils();
34
+ const validationProps = useApplyDefaultValuesToDateValidationProps(internalProps);
35
+ return React.useMemo(() => _extends({}, internalProps, validationProps, {
36
+ format: internalProps.format ?? utils.formats.keyboardDate
37
+ }), [internalProps, validationProps, utils]);
38
+ }
39
+ export function useApplyDefaultValuesToDateValidationProps(props) {
40
+ const utils = useUtils();
41
+ const defaultDates = useDefaultDates();
42
+ return React.useMemo(() => ({
43
+ disablePast: props.disablePast ?? false,
44
+ disableFuture: props.disableFuture ?? false,
45
+ minDate: applyDefaultDate(utils, props.minDate, defaultDates.minDate),
46
+ maxDate: applyDefaultDate(utils, props.maxDate, defaultDates.maxDate)
47
+ }), [props.minDate, props.maxDate, props.disableFuture, props.disablePast, utils, defaultDates]);
58
48
  }
@@ -1,24 +1,15 @@
1
1
  import type { MakeOptional } from '@mui/x-internals/types';
2
2
  import { PickerManager, DateTimeValidationError } from "../models/index.js";
3
3
  import { UseFieldInternalProps } from "../internals/hooks/useField/index.js";
4
- import { MuiPickersAdapterContextValue } from "../LocalizationProvider/LocalizationProvider.js";
5
4
  import { AmPmProps } from "../internals/models/props/time.js";
6
- import { ExportedValidateDateTimeProps, ValidateDateTimeProps, ValidateDateTimePropsToDefault } from "../validation/validateDateTime.js";
7
- import { PickerManagerFieldInternalPropsWithDefaults, PickerValue } from "../internals/models/index.js";
5
+ import { ExportedValidateDateTimeProps, ValidateDateTimeProps } from "../validation/validateDateTime.js";
6
+ import { PickerValue } from "../internals/models/index.js";
8
7
  export declare function useDateTimeManager<TEnableAccessibleFieldDOMStructure extends boolean = true>(parameters?: UseDateTimeManagerParameters<TEnableAccessibleFieldDOMStructure>): UseDateTimeManagerReturnValue<TEnableAccessibleFieldDOMStructure>;
9
- /**
10
- * Private utility function to get the default internal props for the field with date time editing.
11
- * Is used by the `useDateTimeManager` and `useDateTimeRangeManager` hooks.
12
- */
13
- export declare function getDateTimeFieldInternalPropsDefaults(parameters: GetDateTimeFieldInternalPropsDefaultsParameters): GetDateTimeFieldInternalPropsDefaultsReturnValue;
8
+ type SharedDateTimeAndDateTimeRangeValidationProps = 'disablePast' | 'disableFuture' | 'minTime' | 'maxTime' | 'minDate' | 'maxDate';
9
+ export declare function useApplyDefaultValuesToDateTimeValidationProps(props: Pick<ExportedValidateDateTimeProps, SharedDateTimeAndDateTimeRangeValidationProps | 'minDateTime' | 'maxDateTime'>): Pick<ValidateDateTimeProps, SharedDateTimeAndDateTimeRangeValidationProps>;
14
10
  export interface UseDateTimeManagerParameters<TEnableAccessibleFieldDOMStructure extends boolean> {
15
11
  enableAccessibleFieldDOMStructure?: TEnableAccessibleFieldDOMStructure;
16
12
  }
17
13
  export type UseDateTimeManagerReturnValue<TEnableAccessibleFieldDOMStructure extends boolean> = PickerManager<PickerValue, TEnableAccessibleFieldDOMStructure, DateTimeValidationError, ValidateDateTimeProps, DateTimeManagerFieldInternalProps<TEnableAccessibleFieldDOMStructure>>;
18
14
  export interface DateTimeManagerFieldInternalProps<TEnableAccessibleFieldDOMStructure extends boolean> extends MakeOptional<UseFieldInternalProps<PickerValue, TEnableAccessibleFieldDOMStructure, DateTimeValidationError>, 'format'>, ExportedValidateDateTimeProps, AmPmProps {}
19
- type DateTimeManagerFieldPropsToDefault = 'format' | 'minTime' | 'maxTime' | ValidateDateTimePropsToDefault;
20
- interface GetDateTimeFieldInternalPropsDefaultsParameters extends Pick<MuiPickersAdapterContextValue, 'defaultDates' | 'utils'> {
21
- internalProps: Pick<DateTimeManagerFieldInternalProps<true>, DateTimeManagerFieldPropsToDefault | 'minDateTime' | 'maxDateTime' | 'ampm'>;
22
- }
23
- interface GetDateTimeFieldInternalPropsDefaultsReturnValue extends Pick<PickerManagerFieldInternalPropsWithDefaults<UseDateTimeManagerReturnValue<true>>, DateTimeManagerFieldPropsToDefault | 'disableIgnoringDatePartForTimeValidation'> {}
24
15
  export {};