@mui/x-date-pickers 6.0.3 → 6.0.4

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 (155) hide show
  1. package/AdapterDateFnsJalali/index.js +68 -0
  2. package/AdapterLuxon/index.js +12 -3
  3. package/CHANGELOG.md +61 -0
  4. package/DateCalendar/DateCalendar.types.d.ts +1 -1
  5. package/DateCalendar/PickersCalendarHeader.d.ts +1 -1
  6. package/DateCalendar/index.d.ts +0 -1
  7. package/DateField/DateField.types.d.ts +2 -2
  8. package/DatePicker/DatePickerToolbar.d.ts +1 -1
  9. package/DatePicker/shared.d.ts +2 -2
  10. package/DateTimeField/DateTimeField.types.d.ts +2 -2
  11. package/DateTimePicker/DateTimePickerTabs.d.ts +1 -1
  12. package/DateTimePicker/DateTimePickerToolbar.d.ts +1 -1
  13. package/DateTimePicker/shared.d.ts +1 -2
  14. package/DesktopDatePicker/DesktopDatePicker.types.d.ts +1 -1
  15. package/DesktopDateTimePicker/DesktopDateTimePicker.types.d.ts +1 -1
  16. package/DesktopTimePicker/DesktopTimePicker.types.d.ts +1 -1
  17. package/MobileDatePicker/MobileDatePicker.types.d.ts +1 -1
  18. package/MobileDateTimePicker/MobileDateTimePicker.types.d.ts +1 -1
  19. package/MobileTimePicker/MobileTimePicker.types.d.ts +1 -1
  20. package/PickersLayout/PickersLayout.d.ts +1 -1
  21. package/PickersLayout/PickersLayout.types.d.ts +1 -1
  22. package/PickersLayout/index.d.ts +1 -1
  23. package/PickersLayout/usePickerLayout.d.ts +1 -1
  24. package/README.md +1 -1
  25. package/StaticDatePicker/StaticDatePicker.types.d.ts +2 -1
  26. package/StaticDateTimePicker/StaticDateTimePicker.types.d.ts +2 -1
  27. package/StaticTimePicker/StaticTimePicker.types.d.ts +2 -1
  28. package/TimeClock/Clock.d.ts +1 -1
  29. package/TimeClock/ClockPointer.d.ts +1 -1
  30. package/TimeClock/TimeClock.types.d.ts +1 -1
  31. package/TimeClock/index.d.ts +0 -1
  32. package/TimeField/TimeField.types.d.ts +2 -2
  33. package/TimePicker/TimePickerToolbar.d.ts +1 -1
  34. package/TimePicker/shared.d.ts +1 -2
  35. package/dateViewRenderers/dateViewRenderers.d.ts +1 -1
  36. package/index.js +1 -1
  37. package/internals/components/PickersToolbar.d.ts +1 -1
  38. package/internals/demo/DemoContainer.js +15 -7
  39. package/internals/hooks/useDesktopPicker/useDesktopPicker.d.ts +1 -1
  40. package/internals/hooks/useDesktopPicker/useDesktopPicker.types.d.ts +4 -5
  41. package/internals/hooks/useField/index.d.ts +1 -1
  42. package/internals/hooks/useField/useField.d.ts +2 -1
  43. package/internals/hooks/useField/useField.js +9 -7
  44. package/internals/hooks/useField/useField.types.d.ts +24 -104
  45. package/internals/hooks/useField/useField.utils.d.ts +7 -5
  46. package/internals/hooks/useField/useField.utils.js +68 -50
  47. package/internals/hooks/useField/useFieldCharacterEditing.d.ts +2 -1
  48. package/internals/hooks/useField/useFieldState.d.ts +3 -1
  49. package/internals/hooks/useField/useFieldState.js +88 -62
  50. package/internals/hooks/useIsLandscape.d.ts +1 -1
  51. package/internals/hooks/useMobilePicker/useMobilePicker.d.ts +1 -1
  52. package/internals/hooks/useMobilePicker/useMobilePicker.types.d.ts +4 -5
  53. package/internals/hooks/usePicker/usePicker.d.ts +1 -2
  54. package/internals/hooks/usePicker/usePicker.types.d.ts +1 -2
  55. package/internals/hooks/usePicker/usePickerLayoutProps.d.ts +1 -1
  56. package/internals/hooks/usePicker/usePickerValue.d.ts +2 -1
  57. package/internals/hooks/usePicker/usePickerViews.d.ts +1 -1
  58. package/internals/hooks/useStaticPicker/useStaticPicker.d.ts +1 -1
  59. package/internals/hooks/useStaticPicker/useStaticPicker.types.d.ts +1 -2
  60. package/internals/hooks/useViews.d.ts +1 -1
  61. package/internals/hooks/useViews.js +8 -0
  62. package/internals/hooks/validation/models.d.ts +1 -1
  63. package/internals/hooks/validation/useDateTimeValidation.d.ts +3 -3
  64. package/internals/hooks/validation/useDateValidation.d.ts +2 -2
  65. package/internals/hooks/validation/useTimeValidation.d.ts +2 -2
  66. package/internals/index.d.ts +3 -7
  67. package/internals/index.js +1 -1
  68. package/internals/models/fields.d.ts +2 -20
  69. package/internals/models/index.d.ts +0 -1
  70. package/internals/models/index.js +0 -1
  71. package/internals/models/muiPickersAdapter.d.ts +1 -10
  72. package/internals/models/props/basePickerProps.d.ts +3 -3
  73. package/internals/models/props/tabs.d.ts +1 -1
  74. package/internals/models/props/toolbar.d.ts +1 -1
  75. package/internals/utils/time-utils.d.ts +2 -1
  76. package/internals/utils/utils.d.ts +1 -1
  77. package/internals/utils/utils.js +3 -3
  78. package/internals/utils/validation.d.ts +1 -1
  79. package/internals/utils/valueManagers.d.ts +2 -4
  80. package/internals/utils/valueManagers.js +8 -8
  81. package/internals/utils/views.d.ts +1 -1
  82. package/legacy/AdapterDateFnsJalali/index.js +68 -0
  83. package/legacy/AdapterLuxon/index.js +12 -3
  84. package/legacy/index.js +1 -1
  85. package/legacy/internals/demo/DemoContainer.js +12 -6
  86. package/legacy/internals/hooks/useField/useField.js +10 -8
  87. package/legacy/internals/hooks/useField/useField.utils.js +76 -54
  88. package/legacy/internals/hooks/useField/useFieldState.js +94 -67
  89. package/legacy/internals/hooks/useViews.js +10 -0
  90. package/legacy/internals/index.js +1 -1
  91. package/legacy/internals/models/index.js +0 -1
  92. package/legacy/internals/utils/utils.js +3 -3
  93. package/legacy/internals/utils/valueManagers.js +10 -12
  94. package/legacy/locales/daDK.js +91 -0
  95. package/legacy/locales/nbNO.js +12 -10
  96. package/legacy/locales/svSE.js +12 -10
  97. package/legacy/models/index.js +3 -1
  98. package/locales/daDK.d.ts +51 -0
  99. package/locales/daDK.js +59 -0
  100. package/locales/nbNO.js +8 -10
  101. package/locales/nlNL.d.ts +4 -4
  102. package/locales/svSE.js +8 -10
  103. package/locales/utils/pickersLocaleTextApi.d.ts +2 -1
  104. package/models/fields.d.ts +117 -0
  105. package/models/fields.js +1 -0
  106. package/models/index.d.ts +3 -6
  107. package/models/index.js +3 -1
  108. package/models/validation.d.ts +8 -0
  109. package/models/validation.js +1 -0
  110. package/models/views.js +1 -0
  111. package/modern/AdapterDateFnsJalali/index.js +68 -0
  112. package/modern/AdapterLuxon/index.js +12 -3
  113. package/modern/index.js +1 -1
  114. package/modern/internals/demo/DemoContainer.js +15 -7
  115. package/modern/internals/hooks/useField/useField.js +8 -6
  116. package/modern/internals/hooks/useField/useField.utils.js +68 -50
  117. package/modern/internals/hooks/useField/useFieldState.js +88 -62
  118. package/modern/internals/hooks/useViews.js +8 -0
  119. package/modern/internals/index.js +1 -1
  120. package/modern/internals/models/index.js +0 -1
  121. package/modern/internals/utils/utils.js +3 -3
  122. package/modern/internals/utils/valueManagers.js +8 -8
  123. package/modern/locales/daDK.js +56 -0
  124. package/modern/locales/nbNO.js +8 -10
  125. package/modern/locales/svSE.js +8 -10
  126. package/modern/models/fields.js +1 -0
  127. package/modern/models/index.js +3 -1
  128. package/modern/models/validation.js +1 -0
  129. package/modern/models/views.js +1 -0
  130. package/node/AdapterDateFnsJalali/index.js +68 -0
  131. package/node/AdapterLuxon/index.js +12 -3
  132. package/node/index.js +1 -1
  133. package/node/internals/demo/DemoContainer.js +15 -7
  134. package/node/internals/hooks/useField/useField.js +8 -6
  135. package/node/internals/hooks/useField/useField.utils.js +71 -52
  136. package/node/internals/hooks/useField/useFieldState.js +87 -61
  137. package/node/internals/hooks/useViews.js +8 -0
  138. package/node/internals/index.js +0 -6
  139. package/node/internals/models/index.js +0 -11
  140. package/node/internals/utils/utils.js +3 -3
  141. package/node/internals/utils/valueManagers.js +7 -7
  142. package/node/locales/daDK.js +62 -0
  143. package/node/locales/nbNO.js +8 -10
  144. package/node/locales/svSE.js +8 -10
  145. package/node/models/index.js +33 -0
  146. package/node/models/validation.js +5 -0
  147. package/node/models/views.js +5 -0
  148. package/package.json +1 -1
  149. package/themeAugmentation/props.d.ts +1 -1
  150. package/timeViewRenderers/timeViewRenderers.d.ts +1 -1
  151. /package/{internals/models/views.js → legacy/models/fields.js} +0 -0
  152. /package/legacy/{internals/models/views.js → models/validation.js} +0 -0
  153. /package/{modern/internals → legacy}/models/views.js +0 -0
  154. /package/{internals/models → models}/views.d.ts +0 -0
  155. /package/node/{internals/models/views.js → models/fields.js} +0 -0
@@ -16,22 +16,20 @@ const svSEPickers = {
16
16
  okButtonLabel: 'OK',
17
17
  todayButtonLabel: 'Idag',
18
18
  // Toolbar titles
19
- // datePickerToolbarTitle: 'Select date',
20
- // dateTimePickerToolbarTitle: 'Select date & time',
21
- // timePickerToolbarTitle: 'Select time',
22
- // dateRangePickerToolbarTitle: 'Select date range',
23
-
19
+ datePickerToolbarTitle: 'Välj datum',
20
+ dateTimePickerToolbarTitle: 'Välj datum & tid',
21
+ timePickerToolbarTitle: 'Välj tid',
22
+ dateRangePickerToolbarTitle: 'Välj datumintervall',
24
23
  // Clock labels
25
24
  clockLabelText: (view, time, adapter) => `Select ${view}. ${time === null ? 'Ingen tid vald' : `Vald tid är ${adapter.format(time, 'fullTime')}`}`,
26
25
  hoursClockNumberText: hours => `${hours} timmar`,
27
26
  minutesClockNumberText: minutes => `${minutes} minuter`,
28
27
  secondsClockNumberText: seconds => `${seconds} sekunder`,
29
28
  // Calendar labels
30
- // calendarWeekNumberHeaderLabel: 'Week number',
31
- // calendarWeekNumberHeaderText: '#',
32
- // calendarWeekNumberAriaLabelText: weekNumber => `Week ${weekNumber}`,
33
- // calendarWeekNumberText: weekNumber => `${weekNumber}`,
34
-
29
+ calendarWeekNumberHeaderLabel: 'Vecka nummer',
30
+ calendarWeekNumberHeaderText: '#',
31
+ calendarWeekNumberAriaLabelText: weekNumber => `Vecka ${weekNumber}`,
32
+ calendarWeekNumberText: weekNumber => `${weekNumber}`,
35
33
  // Open picker labels
36
34
  openDatePickerDialogue: (value, utils) => value !== null && utils.isValid(value) ? `Välj datum, valt datum är ${utils.format(value, 'fullDate')}` : 'Välj datum',
37
35
  openTimePickerDialogue: (value, utils) => value !== null && utils.isValid(value) ? `Välj tid, vald tid är ${utils.format(value, 'fullTime')}` : 'Välj tid',
@@ -0,0 +1 @@
1
+ export {};
@@ -1 +1,3 @@
1
- export {};
1
+ export * from './fields';
2
+ export * from './validation';
3
+ export * from './views';
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -39,6 +39,74 @@ const formatTokenMap = {
39
39
  // Day of the month
40
40
  d: 'day',
41
41
  dd: 'day',
42
+ do: 'day',
43
+ // Day of the week
44
+ E: {
45
+ sectionType: 'weekDay',
46
+ contentType: 'letter'
47
+ },
48
+ EE: {
49
+ sectionType: 'weekDay',
50
+ contentType: 'letter'
51
+ },
52
+ EEE: {
53
+ sectionType: 'weekDay',
54
+ contentType: 'letter'
55
+ },
56
+ EEEE: {
57
+ sectionType: 'weekDay',
58
+ contentType: 'letter'
59
+ },
60
+ EEEEE: {
61
+ sectionType: 'weekDay',
62
+ contentType: 'letter'
63
+ },
64
+ i: 'weekDay',
65
+ ii: 'weekDay',
66
+ iii: {
67
+ sectionType: 'weekDay',
68
+ contentType: 'letter'
69
+ },
70
+ iiii: {
71
+ sectionType: 'weekDay',
72
+ contentType: 'letter'
73
+ },
74
+ e: 'weekDay',
75
+ ee: 'weekDay',
76
+ eee: {
77
+ sectionType: 'weekDay',
78
+ contentType: 'letter'
79
+ },
80
+ eeee: {
81
+ sectionType: 'weekDay',
82
+ contentType: 'letter'
83
+ },
84
+ eeeee: {
85
+ sectionType: 'weekDay',
86
+ contentType: 'letter'
87
+ },
88
+ eeeeee: {
89
+ sectionType: 'weekDay',
90
+ contentType: 'letter'
91
+ },
92
+ c: 'weekDay',
93
+ cc: 'weekDay',
94
+ ccc: {
95
+ sectionType: 'weekDay',
96
+ contentType: 'letter'
97
+ },
98
+ cccc: {
99
+ sectionType: 'weekDay',
100
+ contentType: 'letter'
101
+ },
102
+ ccccc: {
103
+ sectionType: 'weekDay',
104
+ contentType: 'letter'
105
+ },
106
+ cccccc: {
107
+ sectionType: 'weekDay',
108
+ contentType: 'letter'
109
+ },
42
110
  // Meridiem
43
111
  a: 'meridiem',
44
112
  aa: 'meridiem',
@@ -92,12 +92,21 @@ class AdapterLuxon extends _luxon2.default {
92
92
  if (!_luxon.DateTime.expandFormat) {
93
93
  throw Error('Your luxon version does not support `expandFormat`. Consider upgrading it to v3.0.2');
94
94
  }
95
+ // Extract escaped section to avoid entending them
96
+ const longFormatRegexp = /''|'(''|[^'])+('|$)|[^']*/g;
97
+ return format.match(longFormatRegexp).map(token => {
98
+ const firstCharacter = token[0];
99
+ if (firstCharacter === "'") {
100
+ return token;
101
+ }
102
+ return _luxon.DateTime.expandFormat(token, {
103
+ locale: this.locale
104
+ });
105
+ }).join('')
95
106
  // The returned format can contain `yyyyy` which means year between 4 and 6 digits.
96
107
  // This value is supported by luxon parser but not luxon formatter.
97
108
  // To avoid conflicts, we replace it by 4 digits which is enough for most use-cases.
98
- return _luxon.DateTime.expandFormat(format, {
99
- locale: this.locale
100
- }).replace('yyyyy', 'yyyy');
109
+ .replace('yyyyy', 'yyyy');
101
110
  };
102
111
  // Redefined here just to show how it can be written using expandFormat
103
112
  this.getFormatHelperText = format => {
package/node/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-date-pickers v6.0.3
2
+ * @mui/x-date-pickers v6.0.4
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -109,14 +109,22 @@ function DemoContainer(props) {
109
109
  if (childrenTypes.has('UI-view')) {
110
110
  // noop
111
111
  } else if (childrenTypes.has('single-input-range-field')) {
112
- sx = (0, _extends2.default)({}, sx, {
113
- [`& > .${_TextField.textFieldClasses.root}`]: {
114
- minWidth: {
115
- xs: 300,
116
- md: 400
112
+ if (!childrenSupportedSections.has('date-time')) {
113
+ sx = (0, _extends2.default)({}, sx, {
114
+ [`& > .${_TextField.textFieldClasses.root}`]: {
115
+ minWidth: 300
117
116
  }
118
- }
119
- });
117
+ });
118
+ } else {
119
+ sx = (0, _extends2.default)({}, sx, {
120
+ [`& > .${_TextField.textFieldClasses.root}`]: {
121
+ minWidth: {
122
+ xs: 300,
123
+ md: 400
124
+ }
125
+ }
126
+ });
127
+ }
120
128
  } else if (childrenSupportedSections.has('date-time')) {
121
129
  sx = (0, _extends2.default)({}, sx, {
122
130
  [`& > .${_TextField.textFieldClasses.root}`]: {
@@ -32,7 +32,8 @@ const useField = params => {
32
32
  updateSectionValue,
33
33
  updateValueFromValueStr,
34
34
  setTempAndroidValueStr,
35
- sectionsValueBoundaries
35
+ sectionsValueBoundaries,
36
+ placeholder
36
37
  } = (0, _useFieldState.useFieldState)(params);
37
38
  const {
38
39
  applyCharacterEditing,
@@ -68,7 +69,8 @@ const useField = params => {
68
69
  const handleRef = (0, _useForkRef.default)(inputRefProp, inputRef);
69
70
  const focusTimeoutRef = React.useRef(undefined);
70
71
  const theme = (0, _styles.useTheme)();
71
- const sectionOrder = React.useMemo(() => (0, _useField.getSectionOrder)(state.sections, theme.direction === 'rtl'), [theme.direction, state.sections]);
72
+ const isRTL = theme.direction === 'rtl';
73
+ const sectionOrder = React.useMemo(() => (0, _useField.getSectionOrder)(state.sections, isRTL), [state.sections, isRTL]);
72
74
  const syncSelectionFromDOM = () => {
73
75
  if (readOnly) {
74
76
  setSelectedSections(null);
@@ -159,7 +161,7 @@ const useField = params => {
159
161
  if (selectedSectionIndexes.startIndex === 0 && selectedSectionIndexes.endIndex === state.sections.length - 1) {
160
162
  keyPressed = cleanValueStr;
161
163
  } else {
162
- const prevValueStr = (0, _useField.cleanString)(fieldValueManager.getValueStrFromSections(state.sections));
164
+ const prevValueStr = (0, _useField.cleanString)(fieldValueManager.getValueStrFromSections(state.sections, isRTL));
163
165
  let startOfDiffIndex = -1;
164
166
  let endOfDiffIndex = -1;
165
167
  for (let i = 0; i < prevValueStr.length; i += 1) {
@@ -264,7 +266,7 @@ const useField = params => {
264
266
  }
265
267
  const activeSection = state.sections[selectedSectionIndexes.startIndex];
266
268
  const activeDateManager = fieldValueManager.getActiveDateManager(utils, state, activeSection);
267
- const newSectionValue = (0, _useField.adjustSectionValue)(utils, activeSection, event.key, sectionsValueBoundaries, activeDateManager.activeDate);
269
+ const newSectionValue = (0, _useField.adjustSectionValue)(utils, activeSection, event.key, sectionsValueBoundaries, activeDateManager.date);
268
270
  updateSectionValue({
269
271
  activeSection,
270
272
  newSectionValue,
@@ -330,7 +332,7 @@ const useField = params => {
330
332
  }
331
333
  }, [state.tempValueStrAndroid]); // eslint-disable-line react-hooks/exhaustive-deps
332
334
 
333
- const valueStr = React.useMemo(() => state.tempValueStrAndroid ?? fieldValueManager.getValueStrFromSections(state.sections), [state.sections, fieldValueManager, state.tempValueStrAndroid]);
335
+ const valueStr = React.useMemo(() => state.tempValueStrAndroid ?? fieldValueManager.getValueStrFromSections(state.sections, isRTL), [state.sections, fieldValueManager, state.tempValueStrAndroid, isRTL]);
334
336
  const inputMode = React.useMemo(() => {
335
337
  if (selectedSectionIndexes == null) {
336
338
  return 'text';
@@ -357,7 +359,7 @@ const useField = params => {
357
359
  setSelectedSections: activeSectionIndex => setSelectedSections(activeSectionIndex)
358
360
  }));
359
361
  return (0, _extends2.default)({
360
- placeholder: state.placeholder,
362
+ placeholder,
361
363
  autoComplete: 'off'
362
364
  }, otherForwardedProps, {
363
365
  value: shouldShowPlaceholder ? '' : valueStr,
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.validateSections = exports.splitFormatIntoSections = exports.mergeDateIntoReferenceDate = exports.isAndroid = exports.getSectionsBoundaries = exports.getSectionOrder = exports.getLetterEditingOptions = exports.getDaysInWeekStr = exports.getDateSectionConfigFromFormatToken = exports.getDateFromDateSections = exports.doesSectionHaveLeadingZeros = exports.createDateStrForInputFromSections = exports.cleanString = exports.cleanDigitSectionValue = exports.clampDaySection = exports.changeSectionValueFormat = exports.adjustSectionValue = exports.addPositionPropertiesToSections = void 0;
7
+ exports.validateSections = exports.splitFormatIntoSections = exports.mergeDateIntoReferenceDate = exports.isAndroid = exports.getSectionsBoundaries = exports.getSectionVisibleValue = exports.getSectionOrder = exports.getLetterEditingOptions = exports.getDaysInWeekStr = exports.getDateSectionConfigFromFormatToken = exports.getDateFromDateSections = exports.doesSectionHaveLeadingZeros = exports.createDateStrForInputFromSections = exports.cleanString = exports.cleanDigitSectionValue = exports.clampDaySectionIfPossible = exports.changeSectionValueFormat = exports.adjustSectionValue = exports.addPositionPropertiesToSections = void 0;
8
8
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
9
  const getDateSectionConfigFromFormatToken = (utils, formatToken) => {
10
10
  const config = utils.formatTokenMap[formatToken];
@@ -159,33 +159,33 @@ const adjustSectionValue = (utils, section, keyCode, sectionsValueBoundaries, ac
159
159
  return adjustLetterSection();
160
160
  };
161
161
  exports.adjustSectionValue = adjustSectionValue;
162
- const getSectionVisibleValue = (section, willBeRenderedInInput) => {
163
- const value = section.value || section.placeholder;
162
+ const getSectionVisibleValue = (section, target) => {
163
+ let value = section.value || section.placeholder;
164
164
 
165
165
  // In the input, we add an empty character at the end of each section without leading zeros.
166
166
  // This makes sure that `onChange` will always be fired.
167
167
  // Otherwise, when your input value equals `1/dd/yyyy` (format `M/DD/YYYY` on DayJs),
168
168
  // If you press `1`, on the first section, the new value is also `1/dd/yyyy`,
169
169
  // So the browser will not fire the input `onChange`.
170
- // Adding the ltr mark is not a problem because it's only for digit (which are always ltr)
171
- // The \u2068 and \u2069 are cleaned, but not the \u200e to notice that an update with same digit occurs
172
- if (willBeRenderedInInput && section.contentType === 'digit' && !section.hasLeadingZeros && value.length === 1) {
173
- return `\u2068${value}\u200e\u2069`;
170
+ const shouldAddInvisibleSpace = ['input-rtl', 'input-ltr'].includes(target) && section.contentType === 'digit' && !section.hasLeadingZeros && value.length === 1;
171
+ if (shouldAddInvisibleSpace) {
172
+ value = `${value}\u200e`;
174
173
  }
175
- if (willBeRenderedInInput) {
176
- return `\u2068${value}\u2069`;
174
+ if (target === 'input-rtl') {
175
+ value = `\u2068${value}\u2069`;
177
176
  }
178
177
  return value;
179
178
  };
179
+ exports.getSectionVisibleValue = getSectionVisibleValue;
180
180
  const cleanString = dirtyString => dirtyString.replace(/[\u2066\u2067\u2068\u2069]/g, '');
181
181
  exports.cleanString = cleanString;
182
- const addPositionPropertiesToSections = sections => {
182
+ const addPositionPropertiesToSections = (sections, isRTL) => {
183
183
  let position = 0;
184
- let positionInInput = 1;
184
+ let positionInInput = isRTL ? 1 : 0;
185
185
  const newSections = [];
186
186
  for (let i = 0; i < sections.length; i += 1) {
187
187
  const section = sections[i];
188
- const renderedValue = getSectionVisibleValue(section, true);
188
+ const renderedValue = getSectionVisibleValue(section, isRTL ? 'input-rtl' : 'input-ltr');
189
189
  const sectionStr = `${section.startSeparator}${renderedValue}${section.endSeparator}`;
190
190
  const sectionLength = cleanString(sectionStr).length;
191
191
  const sectionLengthInInput = sectionStr.length;
@@ -333,10 +333,6 @@ const splitFormatIntoSections = (utils, localeText, format, date) => {
333
333
  if (token === '') {
334
334
  return null;
335
335
  }
336
- const expandedToken = utils.expandFormat(token);
337
- if (expandedToken !== token) {
338
- return expandedToken;
339
- }
340
336
  const sectionConfig = getDateSectionConfigFromFormatToken(utils, token);
341
337
  const sectionValue = date == null || !utils.isValid(date) ? '' : utils.formatByString(date, token);
342
338
  const hasLeadingZeros = doesSectionHaveLeadingZeros(utils, sectionConfig.contentType, sectionConfig.type, token);
@@ -351,39 +347,50 @@ const splitFormatIntoSections = (utils, localeText, format, date) => {
351
347
  }));
352
348
  return null;
353
349
  };
354
- const splitFormat = token => {
355
- const escapedParts = getEscapedPartsFromFormat(utils, token);
356
- let currentTokenValue = '';
357
- for (let i = 0; i < token.length; i += 1) {
358
- const escapedPartOfCurrentChar = escapedParts.find(escapeIndex => escapeIndex.start <= i && escapeIndex.end >= i);
359
- const char = token[i];
360
- const isEscapedChar = escapedPartOfCurrentChar != null;
361
- if (!isEscapedChar && char.match(/([A-Za-z]+)/)) {
362
- currentTokenValue += char;
363
- } else {
364
- // If we are on the opening or closing character of an escaped part of the format,
365
- // Then we ignore this character.
366
- const isEscapeBoundary = isEscapedChar && escapedPartOfCurrentChar?.start === i || escapedPartOfCurrentChar?.end === i;
367
- if (!isEscapeBoundary) {
368
- const expandedToken = commitToken(currentTokenValue);
369
- if (expandedToken != null) {
370
- splitFormat(expandedToken);
371
- }
372
- currentTokenValue = '';
373
- if (sections.length === 0) {
374
- startSeparator += char;
375
- } else {
376
- sections[sections.length - 1].endSeparator += char;
377
- }
350
+
351
+ // Expand the provided format
352
+ let formatExpansionOverflow = 10;
353
+ let prevFormat = format;
354
+ let nextFormat = utils.expandFormat(format);
355
+ while (nextFormat !== prevFormat) {
356
+ prevFormat = nextFormat;
357
+ nextFormat = utils.expandFormat(prevFormat);
358
+ formatExpansionOverflow -= 1;
359
+ if (formatExpansionOverflow < 0) {
360
+ throw new Error('MUI: The format expansion seems to be enter in an infinite loop. Please open an issue with the format passed to the picker component');
361
+ }
362
+ }
363
+ const expandedFormat = nextFormat;
364
+
365
+ // Get start/end indexes of escaped sections
366
+ const escapedParts = getEscapedPartsFromFormat(utils, expandedFormat);
367
+
368
+ // This RegExp test if the beginning of a string correspond to a supported token
369
+ const isTokenStartRegExp = new RegExp(`^(${Object.keys(utils.formatTokenMap).join('|')})`);
370
+ let currentTokenValue = '';
371
+ for (let i = 0; i < expandedFormat.length; i += 1) {
372
+ const escapedPartOfCurrentChar = escapedParts.find(escapeIndex => escapeIndex.start <= i && escapeIndex.end >= i);
373
+ const char = expandedFormat[i];
374
+ const isEscapedChar = escapedPartOfCurrentChar != null;
375
+ const potentialToken = `${currentTokenValue}${expandedFormat.slice(i)}`;
376
+ if (!isEscapedChar && char.match(/([A-Za-z]+)/) && isTokenStartRegExp.test(potentialToken)) {
377
+ currentTokenValue += char;
378
+ } else {
379
+ // If we are on the opening or closing character of an escaped part of the format,
380
+ // Then we ignore this character.
381
+ const isEscapeBoundary = isEscapedChar && escapedPartOfCurrentChar?.start === i || escapedPartOfCurrentChar?.end === i;
382
+ if (!isEscapeBoundary) {
383
+ commitToken(currentTokenValue);
384
+ currentTokenValue = '';
385
+ if (sections.length === 0) {
386
+ startSeparator += char;
387
+ } else {
388
+ sections[sections.length - 1].endSeparator += char;
378
389
  }
379
390
  }
380
391
  }
381
- const expandedToken = commitToken(currentTokenValue);
382
- if (expandedToken != null) {
383
- splitFormat(expandedToken);
384
- }
385
- };
386
- splitFormat(format);
392
+ }
393
+ commitToken(currentTokenValue);
387
394
  return sections.map(section => {
388
395
  const cleanSeparator = separator => {
389
396
  let cleanedSeparator = separator;
@@ -418,7 +425,7 @@ const getDateFromDateSections = (utils, sections) => {
418
425
  const shouldSkip = shouldSkipWeekDays && section.type === 'weekDay';
419
426
  if (!shouldSkip) {
420
427
  sectionFormats.push(section.format);
421
- sectionValues.push(getSectionVisibleValue(section, false));
428
+ sectionValues.push(getSectionVisibleValue(section, 'non-input'));
422
429
  }
423
430
  }
424
431
  const formatWithoutSeparator = sectionFormats.join(' ');
@@ -426,15 +433,19 @@ const getDateFromDateSections = (utils, sections) => {
426
433
  return utils.parse(dateWithoutSeparatorStr, formatWithoutSeparator);
427
434
  };
428
435
  exports.getDateFromDateSections = getDateFromDateSections;
429
- const createDateStrForInputFromSections = sections => {
430
- const formattedArray = sections.map(section => `${section.startSeparator}${getSectionVisibleValue(section, true)}${section.endSeparator}`);
436
+ const createDateStrForInputFromSections = (sections, isRTL) => {
437
+ const formattedSections = sections.map(section => `${section.startSeparator}${getSectionVisibleValue(section, isRTL ? 'input-rtl' : 'input-ltr')}${section.endSeparator}`);
438
+ const dateStr = formattedSections.join('');
439
+ if (!isRTL) {
440
+ return dateStr;
441
+ }
431
442
 
432
443
  // \u2066: start left-to-right isolation
433
444
  // \u2067: start right-to-left isolation
434
445
  // \u2068: start first strong character isolation
435
446
  // \u2069: pop isolation
436
447
  // wrap into an isolated group such that separators can split the string in smaller ones by adding \u2069\u2068
437
- return `\u2066${formattedArray.join('')}\u2069`;
448
+ return `\u2066${dateStr}\u2069`;
438
449
  };
439
450
  exports.createDateStrForInputFromSections = createDateStrForInputFromSections;
440
451
  const getSectionsBoundaries = utils => {
@@ -606,7 +617,15 @@ const mergeDateIntoReferenceDate = (utils, dateToTransferFrom, sections, referen
606
617
  exports.mergeDateIntoReferenceDate = mergeDateIntoReferenceDate;
607
618
  const isAndroid = () => navigator.userAgent.toLowerCase().indexOf('android') > -1;
608
619
  exports.isAndroid = isAndroid;
609
- const clampDaySection = (utils, sections, sectionsValueBoundaries) => {
620
+ const clampDaySectionIfPossible = (utils, sections, sectionsValueBoundaries) => {
621
+ // We can only clamp the day value if:
622
+ // 1. if all the sections are filled (except the week day section which can be empty)
623
+ // 2. there is a day section
624
+ const canClamp = sections.every(section => section.type === 'weekDay' || section.value !== '') && sections.some(section => section.type === 'day');
625
+ if (!canClamp) {
626
+ return null;
627
+ }
628
+
610
629
  // We try to generate a valid date representing the start of the month of the invalid date typed by the user.
611
630
  const sectionsForStartOfMonth = sections.map(section => {
612
631
  if (section.type !== 'day') {
@@ -646,7 +665,7 @@ const clampDaySection = (utils, sections, sectionsValueBoundaries) => {
646
665
  });
647
666
  });
648
667
  };
649
- exports.clampDaySection = clampDaySection;
668
+ exports.clampDaySectionIfPossible = clampDaySectionIfPossible;
650
669
  const getSectionOrder = (sections, isRTL) => {
651
670
  const neighbors = {};
652
671
  if (!isRTL) {