@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
@@ -9,10 +9,17 @@ exports.useFieldV6TextField = exports.addPositionPropertiesToSections = void 0;
9
9
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
10
10
  var React = _interopRequireWildcard(require("react"));
11
11
  var _RtlProvider = require("@mui/system/RtlProvider");
12
+ var _useEnhancedEffect = _interopRequireDefault(require("@mui/utils/useEnhancedEffect"));
12
13
  var _useEventCallback = _interopRequireDefault(require("@mui/utils/useEventCallback"));
14
+ var _useTimeout = _interopRequireDefault(require("@mui/utils/useTimeout"));
13
15
  var _useForkRef = _interopRequireDefault(require("@mui/utils/useForkRef"));
16
+ var _hooks = require("../../../hooks");
14
17
  var _utils = require("../../utils/utils");
15
18
  var _useField = require("./useField.utils");
19
+ var _useFieldCharacterEditing = require("./useFieldCharacterEditing");
20
+ var _useFieldRootHandleKeyDown = require("./useFieldRootHandleKeyDown");
21
+ var _useFieldState = require("./useFieldState");
22
+ var _useFieldInternalPropsWithDefaults = require("./useFieldInternalPropsWithDefaults");
16
23
  const cleanString = dirtyString => dirtyString.replace(/[\u2066\u2067\u2068\u2069]/g, '');
17
24
  const addPositionPropertiesToSections = (sections, localizedDigits, isRtl) => {
18
25
  let position = 0;
@@ -42,116 +49,82 @@ const addPositionPropertiesToSections = (sections, localizedDigits, isRtl) => {
42
49
  return newSections;
43
50
  };
44
51
  exports.addPositionPropertiesToSections = addPositionPropertiesToSections;
45
- const useFieldV6TextField = params => {
52
+ const useFieldV6TextField = parameters => {
46
53
  const isRtl = (0, _RtlProvider.useRtl)();
47
- const focusTimeoutRef = React.useRef(undefined);
48
- const selectionSyncTimeoutRef = React.useRef(undefined);
54
+ const focusTimeout = (0, _useTimeout.default)();
55
+ const selectionSyncTimeout = (0, _useTimeout.default)();
49
56
  const {
50
- forwardedProps: {
51
- onFocus,
52
- onClick,
53
- onPaste,
54
- onBlur,
55
- inputRef: inputRefProp,
56
- placeholder: inPlaceholder
57
- },
58
- internalProps: {
59
- readOnly = false,
60
- disabled = false,
61
- focused
62
- },
63
- parsedSelectedSections,
57
+ props,
58
+ manager,
59
+ skipContextFieldRefAssignment,
60
+ manager: {
61
+ valueType,
62
+ internal_valueManager: valueManager,
63
+ internal_fieldValueManager: fieldValueManager,
64
+ internal_useOpenPickerButtonAriaLabel: useOpenPickerButtonAriaLabel
65
+ }
66
+ } = parameters;
67
+ const {
68
+ internalProps,
69
+ forwardedProps
70
+ } = (0, _hooks.useSplitFieldProps)(props, valueType);
71
+ const internalPropsWithDefaults = (0, _useFieldInternalPropsWithDefaults.useFieldInternalPropsWithDefaults)({
72
+ manager,
73
+ internalProps,
74
+ skipContextFieldRefAssignment
75
+ });
76
+ const {
77
+ onFocus,
78
+ onClick,
79
+ onPaste,
80
+ onBlur,
81
+ onKeyDown,
82
+ onClear,
83
+ clearable,
84
+ inputRef: inputRefProp,
85
+ placeholder: inPlaceholder
86
+ } = forwardedProps;
87
+ const {
88
+ readOnly = false,
89
+ disabled = false,
90
+ autoFocus = false,
91
+ focused,
92
+ unstableFieldRef
93
+ } = internalPropsWithDefaults;
94
+ const inputRef = React.useRef(null);
95
+ const handleRef = (0, _useForkRef.default)(inputRefProp, inputRef);
96
+ const stateResponse = (0, _useFieldState.useFieldState)({
97
+ manager,
98
+ internalPropsWithDefaults,
99
+ forwardedProps
100
+ });
101
+ const {
102
+ // States and derived states
64
103
  activeSectionIndex,
104
+ areAllSectionsEmpty,
105
+ error,
106
+ localizedDigits,
107
+ parsedSelectedSections,
108
+ sectionOrder,
65
109
  state,
66
- fieldValueManager,
67
- valueManager,
68
- applyCharacterEditing,
69
- resetCharacterQuery,
70
- updateSectionValue,
71
- updateValueFromValueStr,
72
- clearActiveSection,
110
+ value,
111
+ // Methods to update the states
73
112
  clearValue,
74
- setTempAndroidValueStr,
113
+ clearActiveSection,
114
+ setCharacterQuery,
75
115
  setSelectedSections,
76
- getSectionsFromValue,
77
- areAllSectionsEmpty,
78
- localizedDigits
79
- } = params;
80
- const inputRef = React.useRef(null);
81
- const handleRef = (0, _useForkRef.default)(inputRefProp, inputRef);
116
+ setTempAndroidValueStr,
117
+ updateSectionValue,
118
+ updateValueFromValueStr,
119
+ // Utilities methods
120
+ getSectionsFromValue
121
+ } = stateResponse;
122
+ const applyCharacterEditing = (0, _useFieldCharacterEditing.useFieldCharacterEditing)({
123
+ stateResponse
124
+ });
125
+ const openPickerAriaLabel = useOpenPickerButtonAriaLabel(value);
82
126
  const sections = React.useMemo(() => addPositionPropertiesToSections(state.sections, localizedDigits, isRtl), [state.sections, localizedDigits, isRtl]);
83
- const interactions = React.useMemo(() => ({
84
- syncSelectionToDOM: () => {
85
- if (!inputRef.current) {
86
- return;
87
- }
88
- if (parsedSelectedSections == null) {
89
- if (inputRef.current.scrollLeft) {
90
- // Ensure that input content is not marked as selected.
91
- // setting selection range to 0 causes issues in Safari.
92
- // https://bugs.webkit.org/show_bug.cgi?id=224425
93
- inputRef.current.scrollLeft = 0;
94
- }
95
- return;
96
- }
97
-
98
- // On multi input range pickers we want to update selection range only for the active input
99
- // This helps to avoid the focus jumping on Safari https://github.com/mui/mui-x/issues/9003
100
- // because WebKit implements the `setSelectionRange` based on the spec: https://bugs.webkit.org/show_bug.cgi?id=224425
101
- if (inputRef.current !== (0, _utils.getActiveElement)(document)) {
102
- return;
103
- }
104
-
105
- // Fix scroll jumping on iOS browser: https://github.com/mui/mui-x/issues/8321
106
- const currentScrollTop = inputRef.current.scrollTop;
107
- if (parsedSelectedSections === 'all') {
108
- inputRef.current.select();
109
- } else {
110
- const selectedSection = sections[parsedSelectedSections];
111
- const selectionStart = selectedSection.type === 'empty' ? selectedSection.startInInput - selectedSection.startSeparator.length : selectedSection.startInInput;
112
- const selectionEnd = selectedSection.type === 'empty' ? selectedSection.endInInput + selectedSection.endSeparator.length : selectedSection.endInInput;
113
- if (selectionStart !== inputRef.current.selectionStart || selectionEnd !== inputRef.current.selectionEnd) {
114
- if (inputRef.current === (0, _utils.getActiveElement)(document)) {
115
- inputRef.current.setSelectionRange(selectionStart, selectionEnd);
116
- }
117
- }
118
- clearTimeout(selectionSyncTimeoutRef.current);
119
- selectionSyncTimeoutRef.current = setTimeout(() => {
120
- // handle case when the selection is not updated correctly
121
- // could happen on Android
122
- if (inputRef.current && inputRef.current === (0, _utils.getActiveElement)(document) &&
123
- // The section might loose all selection, where `selectionStart === selectionEnd`
124
- // https://github.com/mui/mui-x/pull/13652
125
- inputRef.current.selectionStart === inputRef.current.selectionEnd && (inputRef.current.selectionStart !== selectionStart || inputRef.current.selectionEnd !== selectionEnd)) {
126
- interactions.syncSelectionToDOM();
127
- }
128
- });
129
- }
130
-
131
- // Even reading this variable seems to do the trick, but also setting it just to make use of it
132
- inputRef.current.scrollTop = currentScrollTop;
133
- },
134
- getActiveSectionIndexFromDOM: () => {
135
- const browserStartIndex = inputRef.current.selectionStart ?? 0;
136
- const browserEndIndex = inputRef.current.selectionEnd ?? 0;
137
- if (browserStartIndex === 0 && browserEndIndex === 0) {
138
- return null;
139
- }
140
- const nextSectionIndex = browserStartIndex <= sections[0].startInInput ? 1 // Special case if browser index is in invisible characters at the beginning.
141
- : sections.findIndex(section => section.startInInput - section.startSeparator.length > browserStartIndex);
142
- return nextSectionIndex === -1 ? sections.length - 1 : nextSectionIndex - 1;
143
- },
144
- focusField: (newSelectedSection = 0) => {
145
- if ((0, _utils.getActiveElement)(document) === inputRef.current) {
146
- return;
147
- }
148
- inputRef.current?.focus();
149
- setSelectedSections(newSelectedSection);
150
- },
151
- setSelectedSections: newSelectedSections => setSelectedSections(newSelectedSections),
152
- isFieldFocused: () => inputRef.current === (0, _utils.getActiveElement)(document)
153
- }), [inputRef, parsedSelectedSections, sections, setSelectedSections]);
154
- const syncSelectionFromDOM = () => {
127
+ function syncSelectionFromDOM() {
155
128
  const browserStartIndex = inputRef.current.selectionStart ?? 0;
156
129
  let nextSectionIndex;
157
130
  if (browserStartIndex <= sections[0].startInInput) {
@@ -165,13 +138,19 @@ const useFieldV6TextField = params => {
165
138
  }
166
139
  const sectionIndex = nextSectionIndex === -1 ? sections.length - 1 : nextSectionIndex - 1;
167
140
  setSelectedSections(sectionIndex);
168
- };
141
+ }
142
+ function focusField(newSelectedSection = 0) {
143
+ if ((0, _utils.getActiveElement)(document) === inputRef.current) {
144
+ return;
145
+ }
146
+ inputRef.current?.focus();
147
+ setSelectedSections(newSelectedSection);
148
+ }
169
149
  const handleInputFocus = (0, _useEventCallback.default)(event => {
170
150
  onFocus?.(event);
171
151
  // The ref is guaranteed to be resolved at this point.
172
152
  const input = inputRef.current;
173
- clearTimeout(focusTimeoutRef.current);
174
- focusTimeoutRef.current = setTimeout(() => {
153
+ focusTimeout.start(0, () => {
175
154
  // The ref changed, the component got remounted, the focus event is no longer relevant.
176
155
  if (!input || input !== inputRef.current) {
177
156
  return;
@@ -213,7 +192,7 @@ const useFieldV6TextField = params => {
213
192
  const digitsAndLetterOnly = /^(([a-zA-Z]+)|)([0-9]+)(([a-zA-Z]+)|)$/.test(pastedValue);
214
193
  const isValidPastedValue = activeSection.contentType === 'letter' && lettersOnly || activeSection.contentType === 'digit' && digitsOnly || activeSection.contentType === 'digit-with-letter' && digitsAndLetterOnly;
215
194
  if (isValidPastedValue) {
216
- resetCharacterQuery();
195
+ setCharacterQuery(null);
217
196
  updateSectionValue({
218
197
  section: activeSection,
219
198
  newSectionValue: pastedValue,
@@ -227,7 +206,7 @@ const useFieldV6TextField = params => {
227
206
  return;
228
207
  }
229
208
  }
230
- resetCharacterQuery();
209
+ setCharacterQuery(null);
231
210
  updateValueFromValueStr(pastedValue);
232
211
  });
233
212
  const handleContainerBlur = (0, _useEventCallback.default)(event => {
@@ -240,7 +219,6 @@ const useFieldV6TextField = params => {
240
219
  }
241
220
  const targetValue = event.target.value;
242
221
  if (targetValue === '') {
243
- resetCharacterQuery();
244
222
  clearValue();
245
223
  return;
246
224
  }
@@ -290,7 +268,6 @@ const useFieldV6TextField = params => {
290
268
  if ((0, _useField.isAndroid)()) {
291
269
  setTempAndroidValueStr(valueStr);
292
270
  }
293
- resetCharacterQuery();
294
271
  clearActiveSection();
295
272
  return;
296
273
  }
@@ -299,6 +276,26 @@ const useFieldV6TextField = params => {
299
276
  sectionIndex: activeSectionIndex
300
277
  });
301
278
  });
279
+ const handleClear = (0, _useEventCallback.default)((event, ...args) => {
280
+ event.preventDefault();
281
+ onClear?.(event, ...args);
282
+ clearValue();
283
+ if (!isFieldFocused(inputRef)) {
284
+ // setSelectedSections is called internally
285
+ focusField(0);
286
+ } else {
287
+ setSelectedSections(sectionOrder.startIndex);
288
+ }
289
+ });
290
+ const handleContainerKeyDown = (0, _useFieldRootHandleKeyDown.useFieldRootHandleKeyDown)({
291
+ manager,
292
+ internalPropsWithDefaults,
293
+ stateResponse
294
+ });
295
+ const wrappedHandleContainerKeyDown = (0, _useEventCallback.default)(event => {
296
+ onKeyDown?.(event);
297
+ handleContainerKeyDown(event);
298
+ });
302
299
  const placeholder = React.useMemo(() => {
303
300
  if (inPlaceholder !== undefined) {
304
301
  return inPlaceholder;
@@ -311,12 +308,60 @@ const useFieldV6TextField = params => {
311
308
  if (inputRef.current && inputRef.current === (0, _utils.getActiveElement)(document)) {
312
309
  setSelectedSections('all');
313
310
  }
314
- return () => {
315
- clearTimeout(focusTimeoutRef.current);
316
- clearTimeout(selectionSyncTimeoutRef.current);
317
- };
318
311
  }, []); // eslint-disable-line react-hooks/exhaustive-deps
319
312
 
313
+ (0, _useEnhancedEffect.default)(() => {
314
+ function syncSelectionToDOM() {
315
+ if (!inputRef.current) {
316
+ return;
317
+ }
318
+ if (parsedSelectedSections == null) {
319
+ if (inputRef.current.scrollLeft) {
320
+ // Ensure that input content is not marked as selected.
321
+ // setting selection range to 0 causes issues in Safari.
322
+ // https://bugs.webkit.org/show_bug.cgi?id=224425
323
+ inputRef.current.scrollLeft = 0;
324
+ }
325
+ return;
326
+ }
327
+
328
+ // On multi input range pickers we want to update selection range only for the active input
329
+ // This helps to avoid the focus jumping on Safari https://github.com/mui/mui-x/issues/9003
330
+ // because WebKit implements the `setSelectionRange` based on the spec: https://bugs.webkit.org/show_bug.cgi?id=224425
331
+ if (inputRef.current !== (0, _utils.getActiveElement)(document)) {
332
+ return;
333
+ }
334
+
335
+ // Fix scroll jumping on iOS browser: https://github.com/mui/mui-x/issues/8321
336
+ const currentScrollTop = inputRef.current.scrollTop;
337
+ if (parsedSelectedSections === 'all') {
338
+ inputRef.current.select();
339
+ } else {
340
+ const selectedSection = sections[parsedSelectedSections];
341
+ const selectionStart = selectedSection.type === 'empty' ? selectedSection.startInInput - selectedSection.startSeparator.length : selectedSection.startInInput;
342
+ const selectionEnd = selectedSection.type === 'empty' ? selectedSection.endInInput + selectedSection.endSeparator.length : selectedSection.endInInput;
343
+ if (selectionStart !== inputRef.current.selectionStart || selectionEnd !== inputRef.current.selectionEnd) {
344
+ if (inputRef.current === (0, _utils.getActiveElement)(document)) {
345
+ inputRef.current.setSelectionRange(selectionStart, selectionEnd);
346
+ }
347
+ }
348
+ selectionSyncTimeout.start(0, () => {
349
+ // handle case when the selection is not updated correctly
350
+ // could happen on Android
351
+ if (inputRef.current && inputRef.current === (0, _utils.getActiveElement)(document) &&
352
+ // The section might loose all selection, where `selectionStart === selectionEnd`
353
+ // https://github.com/mui/mui-x/pull/13652
354
+ inputRef.current.selectionStart === inputRef.current.selectionEnd && (inputRef.current.selectionStart !== selectionStart || inputRef.current.selectionEnd !== selectionEnd)) {
355
+ syncSelectionToDOM();
356
+ }
357
+ });
358
+ }
359
+
360
+ // Even reading this variable seems to do the trick, but also setting it just to make use of it
361
+ inputRef.current.scrollTop = currentScrollTop;
362
+ }
363
+ syncSelectionToDOM();
364
+ });
320
365
  const inputMode = React.useMemo(() => {
321
366
  if (activeSectionIndex == null) {
322
367
  return 'text';
@@ -328,25 +373,47 @@ const useFieldV6TextField = params => {
328
373
  }, [activeSectionIndex, state.sections]);
329
374
  const inputHasFocus = inputRef.current && inputRef.current === (0, _utils.getActiveElement)(document);
330
375
  const shouldShowPlaceholder = !inputHasFocus && areAllSectionsEmpty;
331
- return {
332
- interactions,
333
- returnedValue: {
334
- // Forwarded
335
- readOnly,
336
- onBlur: handleContainerBlur,
337
- onClick: handleInputClick,
338
- onFocus: handleInputFocus,
339
- onPaste: handleInputPaste,
340
- inputRef: handleRef,
341
- // Additional
342
- enableAccessibleFieldDOMStructure: false,
343
- placeholder,
344
- inputMode,
345
- autoComplete: 'off',
346
- value: shouldShowPlaceholder ? '' : valueStr,
347
- onChange: handleInputChange,
348
- focused
349
- }
350
- };
376
+ React.useImperativeHandle(unstableFieldRef, () => ({
377
+ getSections: () => state.sections,
378
+ getActiveSectionIndex: () => {
379
+ const browserStartIndex = inputRef.current.selectionStart ?? 0;
380
+ const browserEndIndex = inputRef.current.selectionEnd ?? 0;
381
+ if (browserStartIndex === 0 && browserEndIndex === 0) {
382
+ return null;
383
+ }
384
+ const nextSectionIndex = browserStartIndex <= sections[0].startInInput ? 1 // Special case if browser index is in invisible characters at the beginning.
385
+ : sections.findIndex(section => section.startInInput - section.startSeparator.length > browserStartIndex);
386
+ return nextSectionIndex === -1 ? sections.length - 1 : nextSectionIndex - 1;
387
+ },
388
+ setSelectedSections: newSelectedSections => setSelectedSections(newSelectedSections),
389
+ focusField,
390
+ isFieldFocused: () => isFieldFocused(inputRef)
391
+ }));
392
+ return (0, _extends2.default)({}, forwardedProps, {
393
+ error,
394
+ clearable: Boolean(clearable && !areAllSectionsEmpty && !readOnly && !disabled),
395
+ onBlur: handleContainerBlur,
396
+ onClick: handleInputClick,
397
+ onFocus: handleInputFocus,
398
+ onPaste: handleInputPaste,
399
+ onKeyDown: wrappedHandleContainerKeyDown,
400
+ onClear: handleClear,
401
+ inputRef: handleRef,
402
+ // Additional
403
+ enableAccessibleFieldDOMStructure: false,
404
+ placeholder,
405
+ inputMode,
406
+ autoComplete: 'off',
407
+ value: shouldShowPlaceholder ? '' : valueStr,
408
+ onChange: handleInputChange,
409
+ focused,
410
+ disabled,
411
+ readOnly,
412
+ autoFocus,
413
+ openPickerAriaLabel
414
+ });
351
415
  };
352
- exports.useFieldV6TextField = useFieldV6TextField;
416
+ exports.useFieldV6TextField = useFieldV6TextField;
417
+ function isFieldFocused(inputRef) {
418
+ return inputRef.current === (0, _utils.getActiveElement)(document);
419
+ }
@@ -1,2 +1,3 @@
1
- import { UseFieldTextField } from "./useField.types.js";
2
- export declare const useFieldV7TextField: UseFieldTextField<true>;
1
+ import { UseFieldParameters, UseFieldProps, UseFieldReturnValue } from "./useField.types.js";
2
+ import { PickerValidValue } from "../../models/index.js";
3
+ export declare const useFieldV7TextField: <TValue extends PickerValidValue, TError, TValidationProps extends {}, TProps extends UseFieldProps<true>>(parameters: UseFieldParameters<TValue, true, TError, TValidationProps, TProps>) => UseFieldReturnValue<true, TProps>;