@mui/x-date-pickers 8.29.0 → 8.29.3

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 (36) hide show
  1. package/CHANGELOG.md +176 -1
  2. package/PickersTextField/PickersFilledInput/PickersFilledInput.js +1 -0
  3. package/PickersTextField/PickersFilledInput/PickersFilledInput.mjs +1 -0
  4. package/PickersTextField/PickersInput/PickersInput.js +1 -0
  5. package/PickersTextField/PickersInput/PickersInput.mjs +1 -0
  6. package/PickersTextField/PickersInputBase/PickersInputBase.js +20 -20
  7. package/PickersTextField/PickersInputBase/PickersInputBase.mjs +20 -20
  8. package/PickersTextField/PickersInputBase/PickersInputBase.types.d.mts +1 -0
  9. package/PickersTextField/PickersInputBase/PickersInputBase.types.d.ts +1 -0
  10. package/PickersTextField/PickersInputBase/pickersInputBaseClasses.js +1 -1
  11. package/PickersTextField/PickersInputBase/pickersInputBaseClasses.mjs +1 -1
  12. package/PickersTextField/PickersOutlinedInput/PickersOutlinedInput.js +12 -8
  13. package/PickersTextField/PickersOutlinedInput/PickersOutlinedInput.mjs +12 -8
  14. package/PickersTextField/PickersTextField.js +4 -1
  15. package/PickersTextField/PickersTextField.mjs +4 -1
  16. package/index.js +1 -1
  17. package/index.mjs +1 -1
  18. package/internals/hooks/useField/useField.types.d.mts +1 -0
  19. package/internals/hooks/useField/useField.types.d.ts +1 -0
  20. package/internals/hooks/useField/useField.utils.d.mts +0 -1
  21. package/internals/hooks/useField/useField.utils.d.ts +0 -1
  22. package/internals/hooks/useField/useField.utils.js +2 -2
  23. package/internals/hooks/useField/useField.utils.mjs +1 -1
  24. package/internals/hooks/useField/useFieldRootProps.d.mts +1 -0
  25. package/internals/hooks/useField/useFieldRootProps.d.ts +1 -0
  26. package/internals/hooks/useField/useFieldRootProps.js +135 -8
  27. package/internals/hooks/useField/useFieldRootProps.mjs +135 -8
  28. package/internals/hooks/useField/useFieldSectionContainerProps.js +23 -4
  29. package/internals/hooks/useField/useFieldSectionContainerProps.mjs +22 -4
  30. package/internals/hooks/useField/useFieldSectionContentProps.d.mts +2 -2
  31. package/internals/hooks/useField/useFieldSectionContentProps.d.ts +2 -2
  32. package/internals/hooks/useField/useFieldSectionContentProps.js +14 -11
  33. package/internals/hooks/useField/useFieldSectionContentProps.mjs +14 -11
  34. package/internals/hooks/useField/useFieldV7TextField.js +13 -0
  35. package/internals/hooks/useField/useFieldV7TextField.mjs +13 -0
  36. package/package.json +182 -182
@@ -24,6 +24,7 @@ interface UseFieldRootPropsReturnValue {
24
24
  onBlur: React.FocusEventHandler<HTMLDivElement>;
25
25
  onFocus: React.FocusEventHandler<HTMLDivElement>;
26
26
  onClick: React.MouseEventHandler<HTMLDivElement>;
27
+ onMouseDown: React.MouseEventHandler<HTMLDivElement>;
27
28
  onPaste: React.ClipboardEventHandler<HTMLDivElement>;
28
29
  onInput: React.FormEventHandler<HTMLDivElement>;
29
30
  contentEditable: boolean;
@@ -50,14 +50,22 @@ function useFieldRootProps(parameters) {
50
50
  stateResponse
51
51
  });
52
52
  const containerClickTimeout = (0, _useTimeout.default)();
53
- const handleClick = (0, _useEventCallback.default)(event => {
53
+ const handleClick = (0, _useEventCallback.default)(() => {
54
54
  if (disabled || !domGetters.isReady()) {
55
55
  return;
56
56
  }
57
- setFocused(true);
58
57
  if (parsedSelectedSections === 'all') {
58
+ setFocused(true);
59
59
  containerClickTimeout.start(0, () => {
60
- const cursorPosition = document.getSelection().getRangeAt(0).startOffset;
60
+ // `getSelection`/`getRangeAt` can be unset transiently (e.g. focus
61
+ // moved before this 0-tick callback ran). Fall back to the first
62
+ // section in that case.
63
+ const selection = document.getSelection();
64
+ if (!selection || selection.rangeCount === 0) {
65
+ setSelectedSections(sectionOrder.startIndex);
66
+ return;
67
+ }
68
+ const cursorPosition = selection.getRangeAt(0).startOffset;
61
69
  if (cursorPosition === 0) {
62
70
  setSelectedSections(sectionOrder.startIndex);
63
71
  return;
@@ -71,15 +79,83 @@ function useFieldRootProps(parameters) {
71
79
  }
72
80
  setSelectedSections(sectionIndex - 1);
73
81
  });
74
- } else if (!focused) {
82
+ return;
83
+ }
84
+
85
+ // For trusted pointer input, `handleMouseDown` already ran and set the
86
+ // section. This branch only matters for `click` events that arrive
87
+ // without a preceding `mousedown` (programmatic `element.click()`, some
88
+ // assistive-technology activations, synthetic event sequences in tests).
89
+ // Fall back to the first section so the field doesn't enter a "focused
90
+ // but no active section" state.
91
+ if (!focused) {
75
92
  setFocused(true);
76
- setSelectedSections(sectionOrder.startIndex);
77
- } else {
78
- const hasClickedOnASection = domGetters.getRoot().contains(event.target);
79
- if (!hasClickedOnASection) {
93
+ if (parsedSelectedSections == null) {
94
+ setSelectedSections(sectionOrder.startIndex);
95
+ }
96
+ }
97
+ });
98
+
99
+ // Replaces Chromium's focus delegation with an explicit section focus on
100
+ // every primary mousedown inside the sections container. The CSS gate
101
+ // (`WebkitUserModify: read-only` while not `:focus-within`) can make the
102
+ // section's contenteditable span temporarily non-focusable, in which case
103
+ // Chromium falls back to the sections-container `tabindex=0` and our
104
+ // `handleFocus` then runs the "no active section" fallback, briefly
105
+ // selecting the first section before the click bubble corrects it.
106
+ // Setting the target section here (and letting `syncSelectionToDOM` move
107
+ // focus via `.focus()`, which works even with the user-modify rule
108
+ // active) skips that race entirely.
109
+ const handleMouseDown = (0, _useEventCallback.default)(event => {
110
+ if (disabled || !domGetters.isReady() || parsedSelectedSections === 'all') {
111
+ return;
112
+ }
113
+ if (event.button !== 0) {
114
+ return;
115
+ }
116
+ const target = event.target;
117
+ const sectionListRoot = domGetters.getRoot();
118
+ const isInsideSectionList = sectionListRoot.contains(target);
119
+ // Only the field root is ours outside the sections container: it is the
120
+ // target of a padding click. The adornments keep their own behavior.
121
+ if (!isInsideSectionList && target !== event.currentTarget) {
122
+ return;
123
+ }
124
+ const sectionElement = isInsideSectionList ? target.closest('[data-sectionindex]') : null;
125
+
126
+ // Blank space is the field padding and the area past the sections. Mimic
127
+ // the native date input: first section on entry, keep it afterwards.
128
+ // `preventDefault` is what keeps it, by stopping both the browser blur and
129
+ // Chromium's focus delegation.
130
+ const isBlankSpaceClick = sectionElement == null && (!isInsideSectionList || isPointOutsideSections(sectionListRoot, event.clientX));
131
+ if (isBlankSpaceClick) {
132
+ event.preventDefault();
133
+ if (!focused) {
134
+ setFocused(true);
80
135
  setSelectedSections(sectionOrder.startIndex);
81
136
  }
137
+ return;
82
138
  }
139
+
140
+ // Prefer the visually-containing section (matches Chromium's
141
+ // delegation + section container `onClick`), fall back to the
142
+ // closest-by-distance section for clicks on the container padding.
143
+ const parsedIndex = sectionElement ? Number(sectionElement.dataset.sectionindex) : findClosestSectionIndexToPoint(sectionListRoot, event.clientX);
144
+ // `Number(undefined) === NaN` and `NaN == null === false`, so guard
145
+ // explicitly here even though `data-sectionindex` is set by
146
+ // `useFieldSectionContainerProps` for every section in practice.
147
+ if (parsedIndex == null || !Number.isInteger(parsedIndex)) {
148
+ return;
149
+ }
150
+ event.preventDefault();
151
+ setFocused(true);
152
+ // `mousedown` is now authoritative for pointer section selection. The
153
+ // section container's own `onClick` deduplicates against the resulting
154
+ // `parsedSelectedSections` on the click bubble (see
155
+ // `useFieldSectionContainerProps`), so we always select here and let that
156
+ // guard absorb the redundant call -- matching the pre-PR
157
+ // `onSelectedSectionsChange` invocation count.
158
+ setSelectedSections(parsedIndex);
83
159
  });
84
160
  const handleInput = (0, _useEventCallback.default)(event => {
85
161
  if (!domGetters.isReady() || parsedSelectedSections !== 'all') {
@@ -148,10 +224,61 @@ function useFieldRootProps(parameters) {
148
224
  onBlur: handleBlur,
149
225
  onFocus: handleFocus,
150
226
  onClick: handleClick,
227
+ onMouseDown: handleMouseDown,
151
228
  onPaste: handlePaste,
152
229
  onInput: handleInput,
153
230
  // Other
154
231
  contentEditable: parsedSelectedSections === 'all',
155
232
  tabIndex: internalPropsWithDefaults.disabled || parsedSelectedSections === 0 ? -1 : 0 // TODO: Try to set to undefined when there is a section selected.
156
233
  };
234
+ }
235
+
236
+ /**
237
+ * Slop on each side of the sections, so a click that just misses the outermost
238
+ * one still selects it. Under half a digit at the default font size.
239
+ */
240
+ const BLANK_SPACE_TOLERANCE = 4;
241
+
242
+ /**
243
+ * Returns `true` when `clientX` sits past the sections on either side.
244
+ * Horizontal only: a click in the container's vertical padding still belongs to
245
+ * the section above or below it.
246
+ */
247
+ function isPointOutsideSections(root, clientX) {
248
+ const sections = root.querySelectorAll('[data-sectionindex]');
249
+ if (sections.length === 0) {
250
+ return false;
251
+ }
252
+ let left = Infinity;
253
+ let right = -Infinity;
254
+ for (let i = 0; i < sections.length; i += 1) {
255
+ const rect = sections[i].getBoundingClientRect();
256
+ left = Math.min(left, rect.left);
257
+ right = Math.max(right, rect.right);
258
+ }
259
+ return clientX < left - BLANK_SPACE_TOLERANCE || clientX > right + BLANK_SPACE_TOLERANCE;
260
+ }
261
+
262
+ /**
263
+ * Returns the index of the section whose horizontal center is closest to `clientX`.
264
+ * Returns `null` if the field renders no `[role="spinbutton"]` descendants
265
+ * (defensive -- every section content span sets `role="spinbutton"` in practice).
266
+ */
267
+ function findClosestSectionIndexToPoint(root, clientX) {
268
+ const sections = root.querySelectorAll('[role="spinbutton"]');
269
+ if (sections.length === 0) {
270
+ return null;
271
+ }
272
+ let closestIndex = 0;
273
+ let closestDistance = Infinity;
274
+ for (let i = 0; i < sections.length; i += 1) {
275
+ const rect = sections[i].getBoundingClientRect();
276
+ const center = (rect.left + rect.right) / 2;
277
+ const distance = Math.abs(clientX - center);
278
+ if (distance < closestDistance) {
279
+ closestDistance = distance;
280
+ closestIndex = i;
281
+ }
282
+ }
283
+ return closestIndex;
157
284
  }
@@ -44,14 +44,22 @@ export function useFieldRootProps(parameters) {
44
44
  stateResponse
45
45
  });
46
46
  const containerClickTimeout = useTimeout();
47
- const handleClick = useEventCallback(event => {
47
+ const handleClick = useEventCallback(() => {
48
48
  if (disabled || !domGetters.isReady()) {
49
49
  return;
50
50
  }
51
- setFocused(true);
52
51
  if (parsedSelectedSections === 'all') {
52
+ setFocused(true);
53
53
  containerClickTimeout.start(0, () => {
54
- const cursorPosition = document.getSelection().getRangeAt(0).startOffset;
54
+ // `getSelection`/`getRangeAt` can be unset transiently (e.g. focus
55
+ // moved before this 0-tick callback ran). Fall back to the first
56
+ // section in that case.
57
+ const selection = document.getSelection();
58
+ if (!selection || selection.rangeCount === 0) {
59
+ setSelectedSections(sectionOrder.startIndex);
60
+ return;
61
+ }
62
+ const cursorPosition = selection.getRangeAt(0).startOffset;
55
63
  if (cursorPosition === 0) {
56
64
  setSelectedSections(sectionOrder.startIndex);
57
65
  return;
@@ -65,15 +73,83 @@ export function useFieldRootProps(parameters) {
65
73
  }
66
74
  setSelectedSections(sectionIndex - 1);
67
75
  });
68
- } else if (!focused) {
76
+ return;
77
+ }
78
+
79
+ // For trusted pointer input, `handleMouseDown` already ran and set the
80
+ // section. This branch only matters for `click` events that arrive
81
+ // without a preceding `mousedown` (programmatic `element.click()`, some
82
+ // assistive-technology activations, synthetic event sequences in tests).
83
+ // Fall back to the first section so the field doesn't enter a "focused
84
+ // but no active section" state.
85
+ if (!focused) {
69
86
  setFocused(true);
70
- setSelectedSections(sectionOrder.startIndex);
71
- } else {
72
- const hasClickedOnASection = domGetters.getRoot().contains(event.target);
73
- if (!hasClickedOnASection) {
87
+ if (parsedSelectedSections == null) {
88
+ setSelectedSections(sectionOrder.startIndex);
89
+ }
90
+ }
91
+ });
92
+
93
+ // Replaces Chromium's focus delegation with an explicit section focus on
94
+ // every primary mousedown inside the sections container. The CSS gate
95
+ // (`WebkitUserModify: read-only` while not `:focus-within`) can make the
96
+ // section's contenteditable span temporarily non-focusable, in which case
97
+ // Chromium falls back to the sections-container `tabindex=0` and our
98
+ // `handleFocus` then runs the "no active section" fallback, briefly
99
+ // selecting the first section before the click bubble corrects it.
100
+ // Setting the target section here (and letting `syncSelectionToDOM` move
101
+ // focus via `.focus()`, which works even with the user-modify rule
102
+ // active) skips that race entirely.
103
+ const handleMouseDown = useEventCallback(event => {
104
+ if (disabled || !domGetters.isReady() || parsedSelectedSections === 'all') {
105
+ return;
106
+ }
107
+ if (event.button !== 0) {
108
+ return;
109
+ }
110
+ const target = event.target;
111
+ const sectionListRoot = domGetters.getRoot();
112
+ const isInsideSectionList = sectionListRoot.contains(target);
113
+ // Only the field root is ours outside the sections container: it is the
114
+ // target of a padding click. The adornments keep their own behavior.
115
+ if (!isInsideSectionList && target !== event.currentTarget) {
116
+ return;
117
+ }
118
+ const sectionElement = isInsideSectionList ? target.closest('[data-sectionindex]') : null;
119
+
120
+ // Blank space is the field padding and the area past the sections. Mimic
121
+ // the native date input: first section on entry, keep it afterwards.
122
+ // `preventDefault` is what keeps it, by stopping both the browser blur and
123
+ // Chromium's focus delegation.
124
+ const isBlankSpaceClick = sectionElement == null && (!isInsideSectionList || isPointOutsideSections(sectionListRoot, event.clientX));
125
+ if (isBlankSpaceClick) {
126
+ event.preventDefault();
127
+ if (!focused) {
128
+ setFocused(true);
74
129
  setSelectedSections(sectionOrder.startIndex);
75
130
  }
131
+ return;
76
132
  }
133
+
134
+ // Prefer the visually-containing section (matches Chromium's
135
+ // delegation + section container `onClick`), fall back to the
136
+ // closest-by-distance section for clicks on the container padding.
137
+ const parsedIndex = sectionElement ? Number(sectionElement.dataset.sectionindex) : findClosestSectionIndexToPoint(sectionListRoot, event.clientX);
138
+ // `Number(undefined) === NaN` and `NaN == null === false`, so guard
139
+ // explicitly here even though `data-sectionindex` is set by
140
+ // `useFieldSectionContainerProps` for every section in practice.
141
+ if (parsedIndex == null || !Number.isInteger(parsedIndex)) {
142
+ return;
143
+ }
144
+ event.preventDefault();
145
+ setFocused(true);
146
+ // `mousedown` is now authoritative for pointer section selection. The
147
+ // section container's own `onClick` deduplicates against the resulting
148
+ // `parsedSelectedSections` on the click bubble (see
149
+ // `useFieldSectionContainerProps`), so we always select here and let that
150
+ // guard absorb the redundant call -- matching the pre-PR
151
+ // `onSelectedSectionsChange` invocation count.
152
+ setSelectedSections(parsedIndex);
77
153
  });
78
154
  const handleInput = useEventCallback(event => {
79
155
  if (!domGetters.isReady() || parsedSelectedSections !== 'all') {
@@ -142,10 +218,61 @@ export function useFieldRootProps(parameters) {
142
218
  onBlur: handleBlur,
143
219
  onFocus: handleFocus,
144
220
  onClick: handleClick,
221
+ onMouseDown: handleMouseDown,
145
222
  onPaste: handlePaste,
146
223
  onInput: handleInput,
147
224
  // Other
148
225
  contentEditable: parsedSelectedSections === 'all',
149
226
  tabIndex: internalPropsWithDefaults.disabled || parsedSelectedSections === 0 ? -1 : 0 // TODO: Try to set to undefined when there is a section selected.
150
227
  };
228
+ }
229
+
230
+ /**
231
+ * Slop on each side of the sections, so a click that just misses the outermost
232
+ * one still selects it. Under half a digit at the default font size.
233
+ */
234
+ const BLANK_SPACE_TOLERANCE = 4;
235
+
236
+ /**
237
+ * Returns `true` when `clientX` sits past the sections on either side.
238
+ * Horizontal only: a click in the container's vertical padding still belongs to
239
+ * the section above or below it.
240
+ */
241
+ function isPointOutsideSections(root, clientX) {
242
+ const sections = root.querySelectorAll('[data-sectionindex]');
243
+ if (sections.length === 0) {
244
+ return false;
245
+ }
246
+ let left = Infinity;
247
+ let right = -Infinity;
248
+ for (let i = 0; i < sections.length; i += 1) {
249
+ const rect = sections[i].getBoundingClientRect();
250
+ left = Math.min(left, rect.left);
251
+ right = Math.max(right, rect.right);
252
+ }
253
+ return clientX < left - BLANK_SPACE_TOLERANCE || clientX > right + BLANK_SPACE_TOLERANCE;
254
+ }
255
+
256
+ /**
257
+ * Returns the index of the section whose horizontal center is closest to `clientX`.
258
+ * Returns `null` if the field renders no `[role="spinbutton"]` descendants
259
+ * (defensive -- every section content span sets `role="spinbutton"` in practice).
260
+ */
261
+ function findClosestSectionIndexToPoint(root, clientX) {
262
+ const sections = root.querySelectorAll('[role="spinbutton"]');
263
+ if (sections.length === 0) {
264
+ return null;
265
+ }
266
+ let closestIndex = 0;
267
+ let closestDistance = Infinity;
268
+ for (let i = 0; i < sections.length; i += 1) {
269
+ const rect = sections[i].getBoundingClientRect();
270
+ const center = (rect.left + rect.right) / 2;
271
+ const distance = Math.abs(clientX - center);
272
+ if (distance < closestDistance) {
273
+ closestDistance = distance;
274
+ closestIndex = i;
275
+ }
276
+ }
277
+ return closestIndex;
151
278
  }
@@ -1,11 +1,13 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
3
4
  var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
4
5
  Object.defineProperty(exports, "__esModule", {
5
6
  value: true
6
7
  });
7
8
  exports.useFieldSectionContainerProps = useFieldSectionContainerProps;
8
9
  var React = _interopRequireWildcard(require("react"));
10
+ var _useEventCallback = _interopRequireDefault(require("@mui/utils/useEventCallback"));
9
11
  /**
10
12
  * Generate the props to pass to the container element of each section of the field.
11
13
  * It is not used by the non-accessible DOM structure (with an <input /> element for editing).
@@ -16,6 +18,8 @@ var React = _interopRequireWildcard(require("react"));
16
18
  function useFieldSectionContainerProps(parameters) {
17
19
  const {
18
20
  stateResponse: {
21
+ // States and derived states
22
+ parsedSelectedSections,
19
23
  // Methods to update the states
20
24
  setSelectedSections
21
25
  },
@@ -23,16 +27,31 @@ function useFieldSectionContainerProps(parameters) {
23
27
  disabled = false
24
28
  }
25
29
  } = parameters;
26
- const createHandleClick = React.useCallback(sectionIndex => event => {
30
+
31
+ // A single stable handler shared by every section, rather than a per-index
32
+ // factory. The section index is read from the container's `data-sectionindex`
33
+ // at click time.
34
+ const handleClick = (0, _useEventCallback.default)(event => {
27
35
  // The click event on the clear button would propagate to the input, trigger this handler and result in a wrong section selection.
28
36
  // We avoid this by checking if the call to this function is actually intended, or a side effect.
29
37
  if (disabled || event.isDefaultPrevented()) {
30
38
  return;
31
39
  }
40
+ const sectionIndex = Number(event.currentTarget.dataset.sectionindex);
41
+ if (!Number.isInteger(sectionIndex)) {
42
+ return;
43
+ }
44
+
45
+ // For pointer input the `mousedown` handler already selected the section
46
+ // before this click bubbles, so bail to avoid a redundant
47
+ // `onSelectedSectionsChange` invocation.
48
+ if (parsedSelectedSections === sectionIndex) {
49
+ return;
50
+ }
32
51
  setSelectedSections(sectionIndex);
33
- }, [disabled, setSelectedSections]);
52
+ });
34
53
  return React.useCallback(sectionIndex => ({
35
54
  'data-sectionindex': sectionIndex,
36
- onClick: createHandleClick(sectionIndex)
37
- }), [createHandleClick]);
55
+ onClick: handleClick
56
+ }), [handleClick]);
38
57
  }
@@ -1,4 +1,5 @@
1
1
  import * as React from 'react';
2
+ import useEventCallback from '@mui/utils/useEventCallback';
2
3
  /**
3
4
  * Generate the props to pass to the container element of each section of the field.
4
5
  * It is not used by the non-accessible DOM structure (with an <input /> element for editing).
@@ -9,6 +10,8 @@ import * as React from 'react';
9
10
  export function useFieldSectionContainerProps(parameters) {
10
11
  const {
11
12
  stateResponse: {
13
+ // States and derived states
14
+ parsedSelectedSections,
12
15
  // Methods to update the states
13
16
  setSelectedSections
14
17
  },
@@ -16,16 +19,31 @@ export function useFieldSectionContainerProps(parameters) {
16
19
  disabled = false
17
20
  }
18
21
  } = parameters;
19
- const createHandleClick = React.useCallback(sectionIndex => event => {
22
+
23
+ // A single stable handler shared by every section, rather than a per-index
24
+ // factory. The section index is read from the container's `data-sectionindex`
25
+ // at click time.
26
+ const handleClick = useEventCallback(event => {
20
27
  // The click event on the clear button would propagate to the input, trigger this handler and result in a wrong section selection.
21
28
  // We avoid this by checking if the call to this function is actually intended, or a side effect.
22
29
  if (disabled || event.isDefaultPrevented()) {
23
30
  return;
24
31
  }
32
+ const sectionIndex = Number(event.currentTarget.dataset.sectionindex);
33
+ if (!Number.isInteger(sectionIndex)) {
34
+ return;
35
+ }
36
+
37
+ // For pointer input the `mousedown` handler already selected the section
38
+ // before this click bubbles, so bail to avoid a redundant
39
+ // `onSelectedSectionsChange` invocation.
40
+ if (parsedSelectedSections === sectionIndex) {
41
+ return;
42
+ }
25
43
  setSelectedSections(sectionIndex);
26
- }, [disabled, setSelectedSections]);
44
+ });
27
45
  return React.useCallback(sectionIndex => ({
28
46
  'data-sectionindex': sectionIndex,
29
- onClick: createHandleClick(sectionIndex)
30
- }), [createHandleClick]);
47
+ onClick: handleClick
48
+ }), [handleClick]);
31
49
  }
@@ -1,8 +1,8 @@
1
1
  import { UseFieldStateReturnValue } from "./useFieldState.mjs";
2
2
  import { FieldSection, PickerManager } from "../../../models/index.mjs";
3
3
  import { UseFieldDOMGetters, UseFieldInternalProps } from "./useField.types.mjs";
4
- import { UseFieldCharacterEditingReturnValue } from "./useFieldCharacterEditing.mjs";
5
- import { PickersSectionElement } from "../../../PickersSectionList/index.mjs";
4
+ import type { UseFieldCharacterEditingReturnValue } from "./useFieldCharacterEditing.mjs";
5
+ import type { PickersSectionElement } from "../../../PickersSectionList/index.mjs";
6
6
  /**
7
7
  * Generate the props to pass to the content element of each section of the field.
8
8
  * It is not used by the non-accessible DOM structure (with an <input /> element for editing).
@@ -1,8 +1,8 @@
1
1
  import { UseFieldStateReturnValue } from "./useFieldState.js";
2
2
  import { FieldSection, PickerManager } from "../../../models/index.js";
3
3
  import { UseFieldDOMGetters, UseFieldInternalProps } from "./useField.types.js";
4
- import { UseFieldCharacterEditingReturnValue } from "./useFieldCharacterEditing.js";
5
- import { PickersSectionElement } from "../../../PickersSectionList/index.js";
4
+ import type { UseFieldCharacterEditingReturnValue } from "./useFieldCharacterEditing.js";
5
+ import type { PickersSectionElement } from "../../../PickersSectionList/index.js";
6
6
  /**
7
7
  * Generate the props to pass to the content element of each section of the field.
8
8
  * It is not used by the non-accessible DOM structure (with an <input /> element for editing).
@@ -10,6 +10,7 @@ var React = _interopRequireWildcard(require("react"));
10
10
  var _useEventCallback = _interopRequireDefault(require("@mui/utils/useEventCallback"));
11
11
  var _hooks = require("../../../hooks");
12
12
  var _syncSelectionToDOM = require("./syncSelectionToDOM");
13
+ var _useField = require("./useField.utils");
13
14
  /**
14
15
  * Generate the props to pass to the content element of each section of the field.
15
16
  * It is not used by the non-accessible DOM structure (with an <input /> element for editing).
@@ -34,6 +35,7 @@ function useFieldSectionContentProps(parameters) {
34
35
  sectionsValueBoundaries,
35
36
  state,
36
37
  value,
38
+ localizedDigits,
37
39
  // Methods to update the states
38
40
  clearActiveSection,
39
41
  setCharacterQuery,
@@ -154,10 +156,10 @@ function useFieldSectionContentProps(parameters) {
154
156
  onFocus: createFocusHandler(sectionIndex),
155
157
  // Aria attributes
156
158
  'aria-readonly': readOnly,
157
- 'aria-valuenow': getSectionValueNow(section, adapter),
159
+ 'aria-valuenow': getSectionValueNow(section, adapter, localizedDigits),
158
160
  'aria-valuemin': sectionBoundaries.minimum,
159
161
  'aria-valuemax': sectionBoundaries.maximum,
160
- 'aria-valuetext': section.value ? getSectionValueText(section, adapter) : translations.empty,
162
+ 'aria-valuetext': section.value ? getSectionValueText(section, adapter, localizedDigits) : translations.empty,
161
163
  'aria-label': translations[section.type],
162
164
  'aria-disabled': disabled,
163
165
  // Other
@@ -173,9 +175,9 @@ function useFieldSectionContentProps(parameters) {
173
175
  children: section.value || section.placeholder,
174
176
  inputMode: section.contentType === 'letter' ? 'text' : 'numeric'
175
177
  };
176
- }, [sectionsValueBoundaries, isContainerEditable, disabled, readOnly, isEditable, translations, adapter, handleInput, handlePaste, handleMouseUp, handleDragOver, createFocusHandler, fieldValueManager, value]);
178
+ }, [sectionsValueBoundaries, isContainerEditable, disabled, readOnly, isEditable, translations, adapter, localizedDigits, handleInput, handlePaste, handleMouseUp, handleDragOver, createFocusHandler, fieldValueManager, value]);
177
179
  }
178
- function getSectionValueText(section, adapter) {
180
+ function getSectionValueText(section, adapter, localizedDigits) {
179
181
  if (!section.value) {
180
182
  return undefined;
181
183
  }
@@ -183,7 +185,7 @@ function getSectionValueText(section, adapter) {
183
185
  case 'month':
184
186
  {
185
187
  if (section.contentType === 'digit') {
186
- const dateWithMonth = adapter.setMonth(adapter.date(), Number(section.value) - 1);
188
+ const dateWithMonth = adapter.setMonth(adapter.date(), Number((0, _useField.removeLocalizedDigits)(section.value, localizedDigits)) - 1);
187
189
  return adapter.isValid(dateWithMonth) ? adapter.format(dateWithMonth, 'month') : '';
188
190
  }
189
191
  const parsedDate = adapter.parse(section.value, section.format);
@@ -191,7 +193,7 @@ function getSectionValueText(section, adapter) {
191
193
  }
192
194
  case 'day':
193
195
  if (section.contentType === 'digit') {
194
- const dateWithDay = adapter.setDate(adapter.startOfYear(adapter.date()), Number(section.value));
196
+ const dateWithDay = adapter.setDate(adapter.startOfYear(adapter.date()), Number((0, _useField.removeLocalizedDigits)(section.value, localizedDigits)));
195
197
  return adapter.isValid(dateWithDay) ? adapter.format(dateWithDay, 'dayOfMonthFull') : '';
196
198
  }
197
199
  return section.value;
@@ -202,10 +204,11 @@ function getSectionValueText(section, adapter) {
202
204
  return undefined;
203
205
  }
204
206
  }
205
- function getSectionValueNow(section, adapter) {
207
+ function getSectionValueNow(section, adapter, localizedDigits) {
206
208
  if (!section.value) {
207
209
  return undefined;
208
210
  }
211
+ const nonLocalizedValue = (0, _useField.removeLocalizedDigits)(section.value, localizedDigits);
209
212
  switch (section.type) {
210
213
  case 'weekDay':
211
214
  {
@@ -213,7 +216,7 @@ function getSectionValueNow(section, adapter) {
213
216
  // TODO: improve by resolving the week day number from a letter week day
214
217
  return undefined;
215
218
  }
216
- return Number(section.value);
219
+ return Number(nonLocalizedValue);
217
220
  }
218
221
  case 'meridiem':
219
222
  {
@@ -224,16 +227,16 @@ function getSectionValueNow(section, adapter) {
224
227
  return undefined;
225
228
  }
226
229
  case 'day':
227
- return section.contentType === 'digit-with-letter' ? parseInt(section.value, 10) : Number(section.value);
230
+ return section.contentType === 'digit-with-letter' ? parseInt(nonLocalizedValue, 10) : Number(nonLocalizedValue);
228
231
  case 'month':
229
232
  {
230
233
  if (section.contentType === 'digit') {
231
- return Number(section.value);
234
+ return Number(nonLocalizedValue);
232
235
  }
233
236
  const parsedDate = adapter.parse(section.value, section.format);
234
237
  return parsedDate ? adapter.getMonth(parsedDate) + 1 : undefined;
235
238
  }
236
239
  default:
237
- return section.contentType !== 'letter' ? Number(section.value) : undefined;
240
+ return section.contentType !== 'letter' ? Number(nonLocalizedValue) : undefined;
238
241
  }
239
242
  }