@mui/x-date-pickers 6.0.2 → 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 (234) hide show
  1. package/AdapterDateFns/index.js +1 -0
  2. package/AdapterDateFnsJalali/index.js +69 -0
  3. package/AdapterDayjs/index.js +5 -0
  4. package/AdapterLuxon/index.js +13 -3
  5. package/AdapterMoment/index.js +5 -0
  6. package/AdapterMomentHijri/index.js +5 -0
  7. package/AdapterMomentJalaali/index.js +5 -0
  8. package/CHANGELOG.md +119 -5
  9. package/DateCalendar/DateCalendar.types.d.ts +1 -1
  10. package/DateCalendar/PickersCalendarHeader.d.ts +1 -1
  11. package/DateCalendar/index.d.ts +0 -1
  12. package/DateField/DateField.js +4 -0
  13. package/DateField/DateField.types.d.ts +2 -2
  14. package/DateField/useDateField.js +5 -3
  15. package/DatePicker/DatePickerToolbar.d.ts +1 -1
  16. package/DatePicker/shared.d.ts +2 -2
  17. package/DateTimeField/DateTimeField.js +4 -0
  18. package/DateTimeField/DateTimeField.types.d.ts +2 -2
  19. package/DateTimeField/useDateTimeField.js +5 -3
  20. package/DateTimePicker/DateTimePickerTabs.d.ts +1 -1
  21. package/DateTimePicker/DateTimePickerToolbar.d.ts +1 -1
  22. package/DateTimePicker/shared.d.ts +1 -2
  23. package/DesktopDatePicker/DesktopDatePicker.types.d.ts +1 -1
  24. package/DesktopDateTimePicker/DesktopDateTimePicker.types.d.ts +1 -1
  25. package/DesktopTimePicker/DesktopTimePicker.types.d.ts +1 -1
  26. package/MobileDatePicker/MobileDatePicker.types.d.ts +1 -1
  27. package/MobileDateTimePicker/MobileDateTimePicker.types.d.ts +1 -1
  28. package/MobileTimePicker/MobileTimePicker.types.d.ts +1 -1
  29. package/PickersDay/PickersDay.js +4 -4
  30. package/PickersLayout/PickersLayout.d.ts +1 -1
  31. package/PickersLayout/PickersLayout.types.d.ts +1 -1
  32. package/PickersLayout/index.d.ts +1 -1
  33. package/PickersLayout/usePickerLayout.d.ts +1 -1
  34. package/README.md +1 -1
  35. package/StaticDatePicker/StaticDatePicker.types.d.ts +2 -1
  36. package/StaticDateTimePicker/StaticDateTimePicker.types.d.ts +2 -1
  37. package/StaticTimePicker/StaticTimePicker.types.d.ts +2 -1
  38. package/TimeClock/Clock.d.ts +1 -1
  39. package/TimeClock/ClockPointer.d.ts +1 -1
  40. package/TimeClock/TimeClock.types.d.ts +1 -1
  41. package/TimeClock/index.d.ts +0 -1
  42. package/TimeField/TimeField.js +4 -0
  43. package/TimeField/TimeField.types.d.ts +2 -2
  44. package/TimeField/useTimeField.js +5 -3
  45. package/TimePicker/TimePickerToolbar.d.ts +1 -1
  46. package/TimePicker/shared.d.ts +1 -2
  47. package/dateViewRenderers/dateViewRenderers.d.ts +1 -1
  48. package/index.d.ts +1 -6
  49. package/index.js +4 -2
  50. package/internals/components/PickersToolbar.d.ts +1 -1
  51. package/internals/demo/DemoContainer.js +15 -7
  52. package/internals/hooks/useDesktopPicker/useDesktopPicker.d.ts +1 -1
  53. package/internals/hooks/useDesktopPicker/useDesktopPicker.types.d.ts +7 -7
  54. package/internals/hooks/useField/index.d.ts +2 -2
  55. package/internals/hooks/useField/index.js +1 -1
  56. package/internals/hooks/useField/useField.d.ts +3 -2
  57. package/internals/hooks/useField/useField.js +61 -30
  58. package/internals/hooks/useField/useField.types.d.ts +48 -116
  59. package/internals/hooks/useField/useField.utils.d.ts +7 -5
  60. package/internals/hooks/useField/useField.utils.js +68 -50
  61. package/internals/hooks/useField/useFieldCharacterEditing.d.ts +2 -1
  62. package/internals/hooks/useField/useFieldState.d.ts +4 -3
  63. package/internals/hooks/useField/useFieldState.js +86 -65
  64. package/internals/hooks/useIsLandscape.d.ts +1 -1
  65. package/internals/hooks/useMobilePicker/useMobilePicker.d.ts +1 -1
  66. package/internals/hooks/useMobilePicker/useMobilePicker.types.d.ts +7 -7
  67. package/internals/hooks/usePicker/usePicker.d.ts +2 -2
  68. package/internals/hooks/usePicker/usePicker.types.d.ts +4 -4
  69. package/internals/hooks/usePicker/usePickerLayoutProps.d.ts +1 -1
  70. package/internals/hooks/usePicker/usePickerValue.d.ts +9 -8
  71. package/internals/hooks/usePicker/usePickerValue.js +7 -11
  72. package/internals/hooks/usePicker/usePickerViews.d.ts +1 -1
  73. package/internals/hooks/useStaticPicker/useStaticPicker.d.ts +1 -1
  74. package/internals/hooks/useStaticPicker/useStaticPicker.types.d.ts +2 -2
  75. package/internals/hooks/useViews.d.ts +1 -1
  76. package/internals/hooks/useViews.js +8 -0
  77. package/internals/hooks/validation/models.d.ts +1 -1
  78. package/internals/hooks/validation/useDateTimeValidation.d.ts +3 -3
  79. package/internals/hooks/validation/useDateValidation.d.ts +2 -2
  80. package/internals/hooks/validation/useTimeValidation.d.ts +2 -2
  81. package/internals/index.d.ts +4 -8
  82. package/internals/index.js +2 -2
  83. package/internals/models/fields.d.ts +2 -20
  84. package/internals/models/index.d.ts +0 -1
  85. package/internals/models/index.js +0 -1
  86. package/internals/models/muiPickersAdapter.d.ts +1 -10
  87. package/internals/models/props/basePickerProps.d.ts +3 -3
  88. package/internals/models/props/tabs.d.ts +1 -1
  89. package/internals/models/props/toolbar.d.ts +1 -1
  90. package/internals/utils/date-utils.d.ts +1 -0
  91. package/internals/utils/date-utils.js +6 -0
  92. package/internals/utils/time-utils.d.ts +2 -1
  93. package/internals/utils/utils.d.ts +1 -1
  94. package/internals/utils/utils.js +3 -3
  95. package/internals/utils/validation.d.ts +1 -1
  96. package/internals/utils/valueManagers.d.ts +2 -4
  97. package/internals/utils/valueManagers.js +11 -12
  98. package/internals/utils/views.d.ts +1 -1
  99. package/legacy/AdapterDateFns/index.js +1 -0
  100. package/legacy/AdapterDateFnsJalali/index.js +69 -0
  101. package/legacy/AdapterDayjs/index.js +5 -0
  102. package/legacy/AdapterLuxon/index.js +13 -3
  103. package/legacy/AdapterMoment/index.js +5 -0
  104. package/legacy/AdapterMomentHijri/index.js +5 -0
  105. package/legacy/AdapterMomentJalaali/index.js +5 -0
  106. package/legacy/DateField/DateField.js +4 -0
  107. package/legacy/DateField/useDateField.js +4 -2
  108. package/legacy/DateTimeField/DateTimeField.js +4 -0
  109. package/legacy/DateTimeField/useDateTimeField.js +4 -2
  110. package/legacy/PickersDay/PickersDay.js +4 -4
  111. package/legacy/TimeField/TimeField.js +4 -0
  112. package/legacy/TimeField/useTimeField.js +4 -2
  113. package/legacy/index.js +4 -2
  114. package/legacy/internals/demo/DemoContainer.js +12 -6
  115. package/legacy/internals/hooks/useField/index.js +1 -1
  116. package/legacy/internals/hooks/useField/useField.js +86 -44
  117. package/legacy/internals/hooks/useField/useField.utils.js +76 -54
  118. package/legacy/internals/hooks/useField/useFieldState.js +92 -72
  119. package/legacy/internals/hooks/usePicker/usePickerValue.js +9 -13
  120. package/legacy/internals/hooks/useViews.js +10 -0
  121. package/legacy/internals/index.js +2 -2
  122. package/legacy/internals/models/index.js +0 -1
  123. package/legacy/internals/utils/date-utils.js +6 -0
  124. package/legacy/internals/utils/utils.js +3 -3
  125. package/legacy/internals/utils/valueManagers.js +12 -19
  126. package/legacy/locales/daDK.js +91 -0
  127. package/legacy/locales/faIR.js +33 -16
  128. package/legacy/locales/nbNO.js +12 -10
  129. package/legacy/locales/nlNL.js +12 -10
  130. package/legacy/locales/plPL.js +12 -10
  131. package/legacy/locales/svSE.js +12 -10
  132. package/legacy/models/index.js +3 -0
  133. package/legacy/tests/describeValue/testPickerOpenCloseLifeCycle.js +2 -3
  134. package/locales/daDK.d.ts +51 -0
  135. package/locales/daDK.js +59 -0
  136. package/locales/faIR.js +13 -16
  137. package/locales/nbNO.js +8 -10
  138. package/locales/nlNL.d.ts +4 -4
  139. package/locales/nlNL.js +8 -10
  140. package/locales/plPL.js +8 -10
  141. package/locales/svSE.js +8 -10
  142. package/locales/utils/pickersLocaleTextApi.d.ts +2 -1
  143. package/models/fields.d.ts +117 -0
  144. package/models/fields.js +1 -0
  145. package/models/index.d.ts +3 -0
  146. package/models/index.js +3 -0
  147. package/models/package.json +6 -0
  148. package/models/validation.d.ts +8 -0
  149. package/models/validation.js +1 -0
  150. package/models/views.js +1 -0
  151. package/modern/AdapterDateFns/index.js +1 -0
  152. package/modern/AdapterDateFnsJalali/index.js +69 -0
  153. package/modern/AdapterDayjs/index.js +5 -0
  154. package/modern/AdapterLuxon/index.js +13 -3
  155. package/modern/AdapterMoment/index.js +5 -0
  156. package/modern/AdapterMomentHijri/index.js +5 -0
  157. package/modern/AdapterMomentJalaali/index.js +5 -0
  158. package/modern/DateField/DateField.js +4 -0
  159. package/modern/DateField/useDateField.js +5 -3
  160. package/modern/DateTimeField/DateTimeField.js +4 -0
  161. package/modern/DateTimeField/useDateTimeField.js +5 -3
  162. package/modern/PickersDay/PickersDay.js +4 -4
  163. package/modern/TimeField/TimeField.js +4 -0
  164. package/modern/TimeField/useTimeField.js +5 -3
  165. package/modern/index.js +4 -2
  166. package/modern/internals/demo/DemoContainer.js +15 -7
  167. package/modern/internals/hooks/useField/index.js +1 -1
  168. package/modern/internals/hooks/useField/useField.js +59 -29
  169. package/modern/internals/hooks/useField/useField.utils.js +68 -50
  170. package/modern/internals/hooks/useField/useFieldState.js +86 -65
  171. package/modern/internals/hooks/usePicker/usePickerValue.js +7 -11
  172. package/modern/internals/hooks/useViews.js +8 -0
  173. package/modern/internals/index.js +2 -2
  174. package/modern/internals/models/index.js +0 -1
  175. package/modern/internals/utils/date-utils.js +6 -0
  176. package/modern/internals/utils/utils.js +3 -3
  177. package/modern/internals/utils/valueManagers.js +11 -12
  178. package/modern/locales/daDK.js +56 -0
  179. package/modern/locales/faIR.js +13 -16
  180. package/modern/locales/nbNO.js +8 -10
  181. package/modern/locales/nlNL.js +8 -10
  182. package/modern/locales/plPL.js +8 -10
  183. package/modern/locales/svSE.js +8 -10
  184. package/modern/models/fields.js +1 -0
  185. package/modern/models/index.js +3 -0
  186. package/modern/models/validation.js +1 -0
  187. package/modern/models/views.js +1 -0
  188. package/modern/tests/describeValue/testPickerOpenCloseLifeCycle.js +2 -3
  189. package/node/AdapterDateFns/index.js +1 -0
  190. package/node/AdapterDateFnsJalali/index.js +69 -0
  191. package/node/AdapterDayjs/index.js +5 -0
  192. package/node/AdapterLuxon/index.js +13 -3
  193. package/node/AdapterMoment/index.js +5 -0
  194. package/node/AdapterMomentHijri/index.js +5 -0
  195. package/node/AdapterMomentJalaali/index.js +5 -0
  196. package/node/DateField/DateField.js +4 -0
  197. package/node/DateField/useDateField.js +5 -3
  198. package/node/DateTimeField/DateTimeField.js +4 -0
  199. package/node/DateTimeField/useDateTimeField.js +5 -3
  200. package/node/PickersDay/PickersDay.js +4 -4
  201. package/node/TimeField/TimeField.js +4 -0
  202. package/node/TimeField/useTimeField.js +5 -3
  203. package/node/index.js +14 -2
  204. package/node/internals/demo/DemoContainer.js +15 -7
  205. package/node/internals/hooks/useField/index.js +0 -6
  206. package/node/internals/hooks/useField/useField.js +58 -28
  207. package/node/internals/hooks/useField/useField.utils.js +71 -52
  208. package/node/internals/hooks/useField/useFieldState.js +85 -64
  209. package/node/internals/hooks/usePicker/usePickerValue.js +7 -11
  210. package/node/internals/hooks/useViews.js +8 -0
  211. package/node/internals/index.js +6 -12
  212. package/node/internals/models/index.js +0 -11
  213. package/node/internals/utils/date-utils.js +9 -2
  214. package/node/internals/utils/utils.js +3 -3
  215. package/node/internals/utils/valueManagers.js +9 -10
  216. package/node/locales/daDK.js +62 -0
  217. package/node/locales/faIR.js +13 -16
  218. package/node/locales/nbNO.js +8 -10
  219. package/node/locales/nlNL.js +8 -10
  220. package/node/locales/plPL.js +8 -10
  221. package/node/locales/svSE.js +8 -10
  222. package/node/models/index.js +38 -0
  223. package/node/models/validation.js +5 -0
  224. package/node/models/views.js +5 -0
  225. package/node/tests/describeValue/testPickerOpenCloseLifeCycle.js +2 -3
  226. package/package.json +2 -2
  227. package/tests/describeValue/testPickerOpenCloseLifeCycle.js +2 -3
  228. package/themeAugmentation/props.d.ts +1 -1
  229. package/timeViewRenderers/timeViewRenderers.d.ts +1 -1
  230. /package/{internals/models/views.js → legacy/models/fields.js} +0 -0
  231. /package/legacy/{internals/models/views.js → models/validation.js} +0 -0
  232. /package/{modern/internals → legacy}/models/views.js +0 -0
  233. /package/{internals/models → models}/views.d.ts +0 -0
  234. /package/node/{internals/models/views.js → models/fields.js} +0 -0
@@ -1,9 +1,9 @@
1
1
  import * as React from 'react';
2
- import { FieldSectionType, MuiPickersAdapter } from '../../models';
2
+ import { MuiPickersAdapter } from '../../models';
3
+ import { FieldSectionType, FieldSection, FieldSelectedSections } from '../../../models';
3
4
  import type { PickerValueManager } from '../usePicker';
4
5
  import { InferError, Validator } from '../validation/useValidation';
5
- import { PickersLocaleText } from '../../../locales/utils/pickersLocaleTextApi';
6
- export interface UseFieldParams<TValue, TDate, TSection extends FieldSection, TForwardedProps extends UseFieldForwardedProps, TInternalProps extends UseFieldInternalProps<any, any>> {
6
+ export interface UseFieldParams<TValue, TDate, TSection extends FieldSection, TForwardedProps extends UseFieldForwardedProps, TInternalProps extends UseFieldInternalProps<any, any, any>> {
7
7
  inputRef?: React.Ref<HTMLInputElement>;
8
8
  forwardedProps: TForwardedProps;
9
9
  internalProps: TInternalProps;
@@ -12,7 +12,7 @@ export interface UseFieldParams<TValue, TDate, TSection extends FieldSection, TF
12
12
  validator: Validator<TValue, TDate, InferError<TInternalProps>, UseFieldValidationProps<TValue, TInternalProps>>;
13
13
  valueType: FieldValueType;
14
14
  }
15
- export interface UseFieldInternalProps<TValue, TError> {
15
+ export interface UseFieldInternalProps<TValue, TSection extends FieldSection, TError> {
16
16
  /**
17
17
  * The selected value.
18
18
  * Used when the component is controlled.
@@ -63,6 +63,28 @@ export interface UseFieldInternalProps<TValue, TError> {
63
63
  * @param {FieldSelectedSections} newValue The new selected sections.
64
64
  */
65
65
  onSelectedSectionsChange?: (newValue: FieldSelectedSections) => void;
66
+ /**
67
+ * The ref object used to imperatively interact with the field.
68
+ */
69
+ unstableFieldRef?: React.Ref<FieldRef<TSection>>;
70
+ }
71
+ export interface FieldRef<TSection extends FieldSection> {
72
+ /**
73
+ * Returns the sections of the current value.
74
+ * @returns {TSection[]} The sections of the current value.
75
+ */
76
+ getSections: () => TSection[];
77
+ /**
78
+ * Returns the index of the active section (the first focused section).
79
+ * If no section is active, returns `null`.
80
+ * @returns {number | null} The index of the active section.
81
+ */
82
+ getActiveSectionIndex: () => number | null;
83
+ /**
84
+ * Updates the selected sections.
85
+ * @param {FieldSelectedSections} selectedSections The sections to select.
86
+ */
87
+ setSelectedSections: (selectedSections: FieldSelectedSections) => void;
66
88
  }
67
89
  export interface UseFieldForwardedProps {
68
90
  onKeyDown?: React.KeyboardEventHandler;
@@ -81,76 +103,6 @@ export type UseFieldResponse<TForwardedProps extends UseFieldForwardedProps> = O
81
103
  readOnly: boolean;
82
104
  autoComplete: 'off';
83
105
  };
84
- export interface FieldSection {
85
- /**
86
- * Value of the section, as rendered inside the input.
87
- * For example, in the date `May 25, 1995`, the value of the month section is "May".
88
- */
89
- value: string;
90
- /**
91
- * Format token used to parse the value of this section from the date object.
92
- * For example, in the format `MMMM D, YYYY`, the format of the month section is "MMMM".
93
- */
94
- format: string;
95
- /**
96
- * Placeholder rendered when the value of this section is empty.
97
- */
98
- placeholder: string;
99
- /**
100
- * Type of the section.
101
- */
102
- type: FieldSectionType;
103
- /**
104
- * Type of content of the section.
105
- * Will determine if we should apply a digit-based editing or a letter-based editing.
106
- */
107
- contentType: 'digit' | 'letter';
108
- /**
109
- * If `true`, the value of this section is supposed to have leading zeroes.
110
- * For example, the value `1` should be rendered as "01" instead of "1".
111
- */
112
- hasLeadingZeros: boolean;
113
- /**
114
- * If `true`, the section value has been modified since the last time the sections were generated from a valid date.
115
- * When we can generate a valid date from the section, we don't directly pass it to `onChange`,
116
- * Otherwise, we would lose all the information contained in the original date, things like:
117
- * - time if the format does not contain it
118
- * - timezone / UTC
119
- *
120
- * To avoid losing that information, we transfer the values of the modified sections from the newly generated date to the original date.
121
- */
122
- modified: boolean;
123
- /**
124
- * Start index of the section in the format
125
- */
126
- start: number;
127
- /**
128
- * End index of the section in the format
129
- */
130
- end: number;
131
- /**
132
- * Start index of the section value in the input.
133
- * Takes into account invisible unicode characters such as \u2069 but does not include them
134
- */
135
- startInInput: number;
136
- /**
137
- * End index of the section value in the input.
138
- * Takes into account invisible unicode characters such as \u2069 but does not include them
139
- */
140
- endInInput: number;
141
- /**
142
- * Separator displayed before the value of the section in the input.
143
- * If it contains escaped characters, then it must not have the escaping characters.
144
- * For example, on Day.js, the `year` section of the format `YYYY [year]` has an end separator equal to `year` not `[year]`
145
- */
146
- startSeparator: string;
147
- /**
148
- * Separator displayed after the value of the section in the input.
149
- * If it contains escaped characters, then it must not have the escaping characters.
150
- * For example, on Day.js, the `year` section of the format `[year] YYYY` has a start separator equal to `[year]`
151
- */
152
- endSeparator: string;
153
- }
154
106
  export type FieldSectionWithoutPosition<TSection extends FieldSection = FieldSection> = Omit<TSection, 'start' | 'end' | 'startInInput' | 'endInInput'>;
155
107
  export type FieldSectionValueBoundaries<TDate, SectionType extends FieldSectionType> = {
156
108
  minimum: number;
@@ -170,25 +122,32 @@ export interface FieldChangeHandlerContext<TError> {
170
122
  validationError: TError;
171
123
  }
172
124
  /**
173
- * Object used to access and update the active value.
125
+ * Object used to access and update the active date (i.e: the date containing the active section).
174
126
  * Mainly useful in the range fields where we need to update the date containing the active section without impacting the other one.
175
127
  */
176
- interface FieldActiveDateManager<TValue, TDate> {
128
+ interface FieldActiveDateManager<TValue, TDate, TSection extends FieldSection> {
177
129
  /**
178
- * Date containing the current active section.
130
+ * Active date from `state.value`.
179
131
  */
180
- activeDate: TDate | null;
132
+ date: TDate | null;
181
133
  /**
182
- * Reference date containing the current active section.
134
+ * Active date from the `state.referenceValue`.
183
135
  */
184
- referenceActiveDate: TDate;
136
+ referenceDate: TDate;
137
+ /**
138
+ * @template TSection
139
+ * @param {TSection[]} sections The sections of the full value.
140
+ * @returns {TSection[]} The sections of the active date.
141
+ * Get the sections of the active date.
142
+ */
143
+ getSections: (sections: TSection[]) => TSection[];
185
144
  /**
186
145
  * Creates the new value and reference value based on the new active date and the current state.
187
146
  * @template TValue, TDate
188
147
  * @param {TDate | null} newActiveDate The new value of the date containing the active section.
189
148
  * @returns {Pick<UseFieldState<TValue, any>, 'value' | 'referenceValue'>} The new value and reference value to publish and store in the state.
190
149
  */
191
- getNewValueFromNewActiveDate: (newActiveDate: TDate | null) => Pick<UseFieldState<TValue, any>, 'value' | 'referenceValue'>;
150
+ getNewValuesFromNewActiveDate: (newActiveDate: TDate | null) => Pick<UseFieldState<TValue, any>, 'value' | 'referenceValue'>;
192
151
  }
193
152
  export type FieldSelectedSectionsIndexes = {
194
153
  startIndex: number;
@@ -199,49 +158,36 @@ export type FieldSelectedSectionsIndexes = {
199
158
  */
200
159
  shouldSelectBoundarySelectors?: boolean;
201
160
  };
202
- export type FieldSelectedSections = number | FieldSectionType | null | 'all' | {
203
- startIndex: number;
204
- endIndex: number;
205
- };
206
161
  export interface FieldValueManager<TValue, TDate, TSection extends FieldSection, TError> {
207
162
  /**
208
163
  * Creates the section list from the current value.
209
164
  * The `prevSections` are used on the range fields to avoid losing the sections of a partially filled date when editing the other date.
210
165
  * @template TValue, TDate, TSection
211
166
  * @param {MuiPickersAdapter<TDate>} utils The utils to manipulate the date.
212
- * @param {PickersLocaleText<TDate>} localeText The localization object to generate the placeholders.
213
- * @param {TSection[] | null} sections The sections to use as a fallback if a date is null or invalid.
214
167
  * @param {TValue} value The current value to generate sections from.
215
- * @param {string} format The date format.
168
+ * @param {TSection[] | null} fallbackSections The sections to use as a fallback if a date is null or invalid.
169
+ * @param {boolean} isRTL `true` if the direction is "right to left".
170
+ * @param {(date: TDate) => FieldSectionWithoutPosition[]} getSectionsFromDate Returns the sections of the given date.
216
171
  * @returns {TSection[]} The new section list.
217
172
  */
218
- getSectionsFromValue: (utils: MuiPickersAdapter<TDate>, localeText: PickersLocaleText<TDate>, sections: TSection[] | null, value: TValue, format: string) => TSection[];
173
+ getSectionsFromValue: (utils: MuiPickersAdapter<TDate>, value: TValue, fallbackSections: TSection[] | null, isRTL: boolean, getSectionsFromDate: (date: TDate) => FieldSectionWithoutPosition[]) => TSection[];
219
174
  /**
220
175
  * Creates the string value to render in the input based on the current section list.
221
176
  * @template TSection
222
177
  * @param {TSection[]} sections The current section list.
178
+ * @param {boolean} isRTL `true` is the current orientation is "right to left"
223
179
  * @returns {string} The string value to render in the input.
224
180
  */
225
- getValueStrFromSections: (sections: TSection[]) => string;
226
- /**
227
- * Filter the section list to only keep the sections in the same date as the active section.
228
- * On a single date field does nothing.
229
- * On a range date range, returns the sections of the start date if editing the start date and the end date otherwise.
230
- * @template TSection
231
- * @param {TSection[]} sections The full section list.
232
- * @param {TSection} activeSection The active section.
233
- * @returns {TSection[]} The sections in the same date as the active section.
234
- */
235
- getActiveDateSections: (sections: TSection[], activeSection: TSection) => TSection[];
181
+ getValueStrFromSections: (sections: TSection[], isRTL: boolean) => string;
236
182
  /**
237
183
  * Returns the manager of the active date.
238
184
  * @template TValue, TDate, TSection
239
185
  * @param {MuiPickersAdapter<TDate>} utils The utils to manipulate the date.
240
186
  * @param {UseFieldState<TValue, TSection>} state The current state of the field.
241
187
  * @param {TSection} activeSection The active section.
242
- * @returns {FieldActiveDateManager<TValue, TDate>} The manager of the active date.
188
+ * @returns {FieldActiveDateManager<TValue, TDate, TSection>} The manager of the active date.
243
189
  */
244
- getActiveDateManager: (utils: MuiPickersAdapter<TDate>, state: UseFieldState<TValue, TSection>, activeSection: TSection) => FieldActiveDateManager<TValue, TDate>;
190
+ getActiveDateManager: (utils: MuiPickersAdapter<TDate>, state: UseFieldState<TValue, TSection>, activeSection: TSection) => FieldActiveDateManager<TValue, TDate, TSection>;
245
191
  /**
246
192
  * Parses a string version (most of the time coming from the input).
247
193
  * This method should only be used when the change does not come from a single section.
@@ -269,16 +215,6 @@ export interface FieldValueManager<TValue, TDate, TSection extends FieldSection,
269
215
  * @returns {boolean} `true` if the current error is not empty.
270
216
  */
271
217
  hasError: (error: TError) => boolean;
272
- /**
273
- * Return a description of sections display order. This description is useful in RTL mode.
274
- * @template TDate
275
- * @param {MuiPickersAdapter<TDate>} utils The utils to manipulate the date.
276
- * @param {PickersLocaleText<TDate>} localeText The translation object.
277
- * @param {string} format The format from which sections are computed.
278
- * @param {boolean} isRTL Is the field in right-to-left orientation.
279
- * @returns {SectionOrdering} The description of sections order from left to right.
280
- */
281
- getSectionOrder: (utils: MuiPickersAdapter<TDate>, localeText: PickersLocaleText<TDate>, format: string, isRTL: boolean) => SectionOrdering;
282
218
  }
283
219
  export interface UseFieldState<TValue, TSection extends FieldSection> {
284
220
  value: TValue;
@@ -287,10 +223,6 @@ export interface UseFieldState<TValue, TSection extends FieldSection> {
287
223
  * It is updated whenever we have a valid date (for the range picker we update only the portion of the range that is valid).
288
224
  */
289
225
  referenceValue: TValue;
290
- /**
291
- * A localized format string built from sections.
292
- */
293
- placeholder: string;
294
226
  sections: TSection[];
295
227
  /**
296
228
  * Android `onChange` behavior when the input selection is not empty is quite different from a desktop behavior.
@@ -1,13 +1,15 @@
1
- import { FieldSection, AvailableAdjustKeyCode, FieldSectionsValueBoundaries, SectionOrdering, FieldValueType, FieldSectionWithoutPosition, FieldSectionValueBoundaries } from './useField.types';
2
- import { MuiPickersAdapter, FieldSectionType } from '../../models';
1
+ import { AvailableAdjustKeyCode, FieldSectionsValueBoundaries, SectionOrdering, FieldValueType, FieldSectionWithoutPosition, FieldSectionValueBoundaries } from './useField.types';
2
+ import { MuiPickersAdapter } from '../../models';
3
+ import { FieldSectionType, FieldSection } from '../../../models';
3
4
  import { PickersLocaleText } from '../../../locales/utils/pickersLocaleTextApi';
4
5
  export declare const getDateSectionConfigFromFormatToken: <TDate>(utils: MuiPickersAdapter<TDate>, formatToken: string) => Pick<FieldSection, 'type' | 'contentType'>;
5
6
  export declare const getDaysInWeekStr: <TDate>(utils: MuiPickersAdapter<TDate>, format: string) => string[];
6
7
  export declare const getLetterEditingOptions: <TDate>(utils: MuiPickersAdapter<TDate>, sectionType: FieldSectionType, format: string) => string[];
7
8
  export declare const cleanDigitSectionValue: <TDate>(utils: MuiPickersAdapter<TDate>, value: number, sectionType: FieldSectionType, format: string, hasLeadingZeros: boolean, sectionBoundaries: FieldSectionValueBoundaries<TDate, any>) => string;
8
9
  export declare const adjustSectionValue: <TDate, TSection extends FieldSection>(utils: MuiPickersAdapter<TDate>, section: TSection, keyCode: AvailableAdjustKeyCode, sectionsValueBoundaries: FieldSectionsValueBoundaries<TDate>, activeDate: TDate | null) => string;
10
+ export declare const getSectionVisibleValue: (section: FieldSectionWithoutPosition, target: 'input-rtl' | 'input-ltr' | 'non-input') => string;
9
11
  export declare const cleanString: (dirtyString: string) => string;
10
- export declare const addPositionPropertiesToSections: <TSection extends FieldSection>(sections: FieldSectionWithoutPosition<TSection>[]) => TSection[];
12
+ export declare const addPositionPropertiesToSections: <TSection extends FieldSection>(sections: FieldSectionWithoutPosition<TSection>[], isRTL: boolean) => TSection[];
11
13
  export declare const changeSectionValueFormat: <TDate>(utils: MuiPickersAdapter<TDate>, valueStr: string, currentFormat: string, newFormat: string) => string;
12
14
  export declare const doesSectionHaveLeadingZeros: <TDate>(utils: MuiPickersAdapter<TDate>, contentType: 'digit' | 'letter', sectionType: FieldSectionType, format: string) => boolean;
13
15
  export declare const splitFormatIntoSections: <TDate>(utils: MuiPickersAdapter<TDate>, localeText: PickersLocaleText<TDate>, format: string, date: TDate | null) => FieldSectionWithoutPosition<FieldSection>[];
@@ -16,10 +18,10 @@ export declare const splitFormatIntoSections: <TDate>(utils: MuiPickersAdapter<T
16
18
  * To make sure that the parsing works, we are building a format and a date without any separator.
17
19
  */
18
20
  export declare const getDateFromDateSections: <TDate>(utils: MuiPickersAdapter<TDate>, sections: FieldSection[]) => TDate | null;
19
- export declare const createDateStrForInputFromSections: (sections: FieldSection[]) => string;
21
+ export declare const createDateStrForInputFromSections: (sections: FieldSection[], isRTL: boolean) => string;
20
22
  export declare const getSectionsBoundaries: <TDate>(utils: MuiPickersAdapter<TDate>) => FieldSectionsValueBoundaries<TDate>;
21
23
  export declare const validateSections: <TSection extends FieldSection>(sections: TSection[], valueType: FieldValueType) => void;
22
24
  export declare const mergeDateIntoReferenceDate: <TDate>(utils: MuiPickersAdapter<TDate>, dateToTransferFrom: TDate, sections: FieldSectionWithoutPosition[], referenceDate: TDate, shouldLimitToEditedSections: boolean) => TDate;
23
25
  export declare const isAndroid: () => boolean;
24
- export declare const clampDaySection: <TDate, TSection extends FieldSection>(utils: MuiPickersAdapter<TDate>, sections: TSection[], sectionsValueBoundaries: FieldSectionsValueBoundaries<TDate>) => TSection[] | null;
26
+ export declare const clampDaySectionIfPossible: <TDate, TSection extends FieldSection>(utils: MuiPickersAdapter<TDate>, sections: TSection[], sectionsValueBoundaries: FieldSectionsValueBoundaries<TDate>) => TSection[] | null;
25
27
  export declare const getSectionOrder: (sections: FieldSectionWithoutPosition[], isRTL: boolean) => SectionOrdering;
@@ -147,32 +147,31 @@ export const adjustSectionValue = (utils, section, keyCode, sectionsValueBoundar
147
147
  }
148
148
  return adjustLetterSection();
149
149
  };
150
- const getSectionVisibleValue = (section, willBeRenderedInInput) => {
151
- const value = section.value || section.placeholder;
150
+ export const getSectionVisibleValue = (section, target) => {
151
+ let value = section.value || section.placeholder;
152
152
 
153
153
  // In the input, we add an empty character at the end of each section without leading zeros.
154
154
  // This makes sure that `onChange` will always be fired.
155
155
  // Otherwise, when your input value equals `1/dd/yyyy` (format `M/DD/YYYY` on DayJs),
156
156
  // If you press `1`, on the first section, the new value is also `1/dd/yyyy`,
157
157
  // So the browser will not fire the input `onChange`.
158
- // Adding the ltr mark is not a problem because it's only for digit (which are always ltr)
159
- // The \u2068 and \u2069 are cleaned, but not the \u200e to notice that an update with same digit occurs
160
- if (willBeRenderedInInput && section.contentType === 'digit' && !section.hasLeadingZeros && value.length === 1) {
161
- return `\u2068${value}\u200e\u2069`;
158
+ const shouldAddInvisibleSpace = ['input-rtl', 'input-ltr'].includes(target) && section.contentType === 'digit' && !section.hasLeadingZeros && value.length === 1;
159
+ if (shouldAddInvisibleSpace) {
160
+ value = `${value}\u200e`;
162
161
  }
163
- if (willBeRenderedInInput) {
164
- return `\u2068${value}\u2069`;
162
+ if (target === 'input-rtl') {
163
+ value = `\u2068${value}\u2069`;
165
164
  }
166
165
  return value;
167
166
  };
168
167
  export const cleanString = dirtyString => dirtyString.replace(/[\u2066\u2067\u2068\u2069]/g, '');
169
- export const addPositionPropertiesToSections = sections => {
168
+ export const addPositionPropertiesToSections = (sections, isRTL) => {
170
169
  let position = 0;
171
- let positionInInput = 1;
170
+ let positionInInput = isRTL ? 1 : 0;
172
171
  const newSections = [];
173
172
  for (let i = 0; i < sections.length; i += 1) {
174
173
  const section = sections[i];
175
- const renderedValue = getSectionVisibleValue(section, true);
174
+ const renderedValue = getSectionVisibleValue(section, isRTL ? 'input-rtl' : 'input-ltr');
176
175
  const sectionStr = `${section.startSeparator}${renderedValue}${section.endSeparator}`;
177
176
  const sectionLength = cleanString(sectionStr).length;
178
177
  const sectionLengthInInput = sectionStr.length;
@@ -317,10 +316,6 @@ export const splitFormatIntoSections = (utils, localeText, format, date) => {
317
316
  if (token === '') {
318
317
  return null;
319
318
  }
320
- const expandedToken = utils.expandFormat(token);
321
- if (expandedToken !== token) {
322
- return expandedToken;
323
- }
324
319
  const sectionConfig = getDateSectionConfigFromFormatToken(utils, token);
325
320
  const sectionValue = date == null || !utils.isValid(date) ? '' : utils.formatByString(date, token);
326
321
  const hasLeadingZeros = doesSectionHaveLeadingZeros(utils, sectionConfig.contentType, sectionConfig.type, token);
@@ -335,39 +330,50 @@ export const splitFormatIntoSections = (utils, localeText, format, date) => {
335
330
  }));
336
331
  return null;
337
332
  };
338
- const splitFormat = token => {
339
- const escapedParts = getEscapedPartsFromFormat(utils, token);
340
- let currentTokenValue = '';
341
- for (let i = 0; i < token.length; i += 1) {
342
- const escapedPartOfCurrentChar = escapedParts.find(escapeIndex => escapeIndex.start <= i && escapeIndex.end >= i);
343
- const char = token[i];
344
- const isEscapedChar = escapedPartOfCurrentChar != null;
345
- if (!isEscapedChar && char.match(/([A-Za-z]+)/)) {
346
- currentTokenValue += char;
347
- } else {
348
- // If we are on the opening or closing character of an escaped part of the format,
349
- // Then we ignore this character.
350
- const isEscapeBoundary = isEscapedChar && (escapedPartOfCurrentChar == null ? void 0 : escapedPartOfCurrentChar.start) === i || (escapedPartOfCurrentChar == null ? void 0 : escapedPartOfCurrentChar.end) === i;
351
- if (!isEscapeBoundary) {
352
- const expandedToken = commitToken(currentTokenValue);
353
- if (expandedToken != null) {
354
- splitFormat(expandedToken);
355
- }
356
- currentTokenValue = '';
357
- if (sections.length === 0) {
358
- startSeparator += char;
359
- } else {
360
- sections[sections.length - 1].endSeparator += char;
361
- }
333
+
334
+ // Expand the provided format
335
+ let formatExpansionOverflow = 10;
336
+ let prevFormat = format;
337
+ let nextFormat = utils.expandFormat(format);
338
+ while (nextFormat !== prevFormat) {
339
+ prevFormat = nextFormat;
340
+ nextFormat = utils.expandFormat(prevFormat);
341
+ formatExpansionOverflow -= 1;
342
+ if (formatExpansionOverflow < 0) {
343
+ 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');
344
+ }
345
+ }
346
+ const expandedFormat = nextFormat;
347
+
348
+ // Get start/end indexes of escaped sections
349
+ const escapedParts = getEscapedPartsFromFormat(utils, expandedFormat);
350
+
351
+ // This RegExp test if the beginning of a string correspond to a supported token
352
+ const isTokenStartRegExp = new RegExp(`^(${Object.keys(utils.formatTokenMap).join('|')})`);
353
+ let currentTokenValue = '';
354
+ for (let i = 0; i < expandedFormat.length; i += 1) {
355
+ const escapedPartOfCurrentChar = escapedParts.find(escapeIndex => escapeIndex.start <= i && escapeIndex.end >= i);
356
+ const char = expandedFormat[i];
357
+ const isEscapedChar = escapedPartOfCurrentChar != null;
358
+ const potentialToken = `${currentTokenValue}${expandedFormat.slice(i)}`;
359
+ if (!isEscapedChar && char.match(/([A-Za-z]+)/) && isTokenStartRegExp.test(potentialToken)) {
360
+ currentTokenValue += char;
361
+ } else {
362
+ // If we are on the opening or closing character of an escaped part of the format,
363
+ // Then we ignore this character.
364
+ const isEscapeBoundary = isEscapedChar && (escapedPartOfCurrentChar == null ? void 0 : escapedPartOfCurrentChar.start) === i || (escapedPartOfCurrentChar == null ? void 0 : escapedPartOfCurrentChar.end) === i;
365
+ if (!isEscapeBoundary) {
366
+ commitToken(currentTokenValue);
367
+ currentTokenValue = '';
368
+ if (sections.length === 0) {
369
+ startSeparator += char;
370
+ } else {
371
+ sections[sections.length - 1].endSeparator += char;
362
372
  }
363
373
  }
364
374
  }
365
- const expandedToken = commitToken(currentTokenValue);
366
- if (expandedToken != null) {
367
- splitFormat(expandedToken);
368
- }
369
- };
370
- splitFormat(format);
375
+ }
376
+ commitToken(currentTokenValue);
371
377
  return sections.map(section => {
372
378
  const cleanSeparator = separator => {
373
379
  let cleanedSeparator = separator;
@@ -401,22 +407,26 @@ export const getDateFromDateSections = (utils, sections) => {
401
407
  const shouldSkip = shouldSkipWeekDays && section.type === 'weekDay';
402
408
  if (!shouldSkip) {
403
409
  sectionFormats.push(section.format);
404
- sectionValues.push(getSectionVisibleValue(section, false));
410
+ sectionValues.push(getSectionVisibleValue(section, 'non-input'));
405
411
  }
406
412
  }
407
413
  const formatWithoutSeparator = sectionFormats.join(' ');
408
414
  const dateWithoutSeparatorStr = sectionValues.join(' ');
409
415
  return utils.parse(dateWithoutSeparatorStr, formatWithoutSeparator);
410
416
  };
411
- export const createDateStrForInputFromSections = sections => {
412
- const formattedArray = sections.map(section => `${section.startSeparator}${getSectionVisibleValue(section, true)}${section.endSeparator}`);
417
+ export const createDateStrForInputFromSections = (sections, isRTL) => {
418
+ const formattedSections = sections.map(section => `${section.startSeparator}${getSectionVisibleValue(section, isRTL ? 'input-rtl' : 'input-ltr')}${section.endSeparator}`);
419
+ const dateStr = formattedSections.join('');
420
+ if (!isRTL) {
421
+ return dateStr;
422
+ }
413
423
 
414
424
  // \u2066: start left-to-right isolation
415
425
  // \u2067: start right-to-left isolation
416
426
  // \u2068: start first strong character isolation
417
427
  // \u2069: pop isolation
418
428
  // wrap into an isolated group such that separators can split the string in smaller ones by adding \u2069\u2068
419
- return `\u2066${formattedArray.join('')}\u2069`;
429
+ return `\u2066${dateStr}\u2069`;
420
430
  };
421
431
  export const getSectionsBoundaries = utils => {
422
432
  const today = utils.date();
@@ -583,7 +593,15 @@ export const mergeDateIntoReferenceDate = (utils, dateToTransferFrom, sections,
583
593
  return mergedDate;
584
594
  }, referenceDate);
585
595
  export const isAndroid = () => navigator.userAgent.toLowerCase().indexOf('android') > -1;
586
- export const clampDaySection = (utils, sections, sectionsValueBoundaries) => {
596
+ export const clampDaySectionIfPossible = (utils, sections, sectionsValueBoundaries) => {
597
+ // We can only clamp the day value if:
598
+ // 1. if all the sections are filled (except the week day section which can be empty)
599
+ // 2. there is a day section
600
+ const canClamp = sections.every(section => section.type === 'weekDay' || section.value !== '') && sections.some(section => section.type === 'day');
601
+ if (!canClamp) {
602
+ return null;
603
+ }
604
+
587
605
  // We try to generate a valid date representing the start of the month of the invalid date typed by the user.
588
606
  const sectionsForStartOfMonth = sections.map(section => {
589
607
  if (section.type !== 'day') {
@@ -1,4 +1,5 @@
1
- import { FieldSectionsValueBoundaries, FieldSection } from './useField.types';
1
+ import { FieldSection } from '../../../models';
2
+ import { FieldSectionsValueBoundaries } from './useField.types';
2
3
  import { UpdateSectionValueParams } from './useFieldState';
3
4
  interface ApplyCharacterEditingParams {
4
5
  keyPressed: string;
@@ -1,4 +1,5 @@
1
- import { FieldSection, UseFieldForwardedProps, UseFieldInternalProps, UseFieldParams, UseFieldState, FieldSelectedSectionsIndexes, FieldSelectedSections } from './useField.types';
1
+ import { UseFieldForwardedProps, UseFieldInternalProps, UseFieldParams, UseFieldState, FieldSelectedSectionsIndexes } from './useField.types';
2
+ import { FieldSection, FieldSelectedSections } from '../../../models';
2
3
  export interface UpdateSectionValueParams<TSection extends FieldSection> {
3
4
  /**
4
5
  * The section on which we want to apply the new value.
@@ -13,7 +14,7 @@ export interface UpdateSectionValueParams<TSection extends FieldSection> {
13
14
  */
14
15
  shouldGoToNextSection: boolean;
15
16
  }
16
- export declare const useFieldState: <TValue, TDate, TSection extends FieldSection, TForwardedProps extends UseFieldForwardedProps, TInternalProps extends UseFieldInternalProps<any, any>>(params: UseFieldParams<TValue, TDate, TSection, TForwardedProps, TInternalProps>) => {
17
+ export declare const useFieldState: <TValue, TDate, TSection extends FieldSection, TForwardedProps extends UseFieldForwardedProps, TInternalProps extends UseFieldInternalProps<any, any, any>>(params: UseFieldParams<TValue, TDate, TSection, TForwardedProps, TInternalProps>) => {
17
18
  state: UseFieldState<TValue, TSection>;
18
19
  selectedSectionIndexes: FieldSelectedSectionsIndexes | null;
19
20
  setSelectedSections: (newSelectedSections: FieldSelectedSections) => void;
@@ -22,6 +23,6 @@ export declare const useFieldState: <TValue, TDate, TSection extends FieldSectio
22
23
  updateSectionValue: ({ activeSection, newSectionValue, shouldGoToNextSection, }: UpdateSectionValueParams<TSection>) => void;
23
24
  updateValueFromValueStr: (valueStr: string) => void;
24
25
  setTempAndroidValueStr: (tempValueStrAndroid: string | null) => void;
25
- sectionOrder: import("./useField.types").SectionOrdering;
26
26
  sectionsValueBoundaries: import("./useField.types").FieldSectionsValueBoundaries<TDate>;
27
+ placeholder: string;
27
28
  };