@mui/x-date-pickers 6.7.0 → 6.9.0

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 (276) hide show
  1. package/AdapterDayjs/AdapterDayjs.d.ts +5 -1
  2. package/AdapterDayjs/AdapterDayjs.js +42 -15
  3. package/AdapterLuxon/AdapterLuxon.d.ts +1 -0
  4. package/AdapterLuxon/AdapterLuxon.js +12 -5
  5. package/AdapterMoment/AdapterMoment.js +18 -9
  6. package/CHANGELOG.md +145 -5541
  7. package/DateCalendar/DateCalendar.js +49 -21
  8. package/DateCalendar/DateCalendar.types.d.ts +8 -3
  9. package/DateCalendar/DayCalendar.d.ts +3 -1
  10. package/DateCalendar/DayCalendar.js +24 -17
  11. package/DateCalendar/PickersCalendarHeader.js +6 -3
  12. package/DateCalendar/useCalendarState.d.ts +5 -3
  13. package/DateCalendar/useCalendarState.js +41 -17
  14. package/DateCalendar/useIsDateDisabled.d.ts +1 -1
  15. package/DateCalendar/useIsDateDisabled.js +5 -3
  16. package/DateField/DateField.js +9 -1
  17. package/DatePicker/DatePicker.js +9 -1
  18. package/DateTimeField/DateTimeField.js +9 -1
  19. package/DateTimePicker/DateTimePicker.js +9 -1
  20. package/DesktopDatePicker/DesktopDatePicker.js +9 -1
  21. package/DesktopDateTimePicker/DesktopDateTimePicker.js +9 -1
  22. package/DesktopTimePicker/DesktopTimePicker.js +8 -0
  23. package/DigitalClock/DigitalClock.js +28 -15
  24. package/MobileDatePicker/MobileDatePicker.js +9 -1
  25. package/MobileDateTimePicker/MobileDateTimePicker.js +9 -1
  26. package/MobileTimePicker/MobileTimePicker.js +8 -0
  27. package/MonthCalendar/MonthCalendar.js +57 -24
  28. package/MonthCalendar/MonthCalendar.types.d.ts +8 -2
  29. package/MultiSectionDigitalClock/MultiSectionDigitalClock.js +28 -15
  30. package/MultiSectionDigitalClock/MultiSectionDigitalClockSection.js +1 -1
  31. package/PickersLayout/PickersLayout.js +1 -0
  32. package/PickersLayout/usePickerLayout.js +4 -3
  33. package/PickersShortcuts/PickersShortcuts.d.ts +12 -2
  34. package/PickersShortcuts/PickersShortcuts.js +10 -2
  35. package/PickersShortcuts/index.d.ts +1 -1
  36. package/StaticDatePicker/StaticDatePicker.js +9 -1
  37. package/StaticDateTimePicker/StaticDateTimePicker.js +9 -1
  38. package/StaticTimePicker/StaticTimePicker.js +8 -0
  39. package/TimeClock/TimeClock.js +27 -15
  40. package/TimeField/TimeField.js +9 -1
  41. package/TimePicker/TimePicker.js +8 -0
  42. package/YearCalendar/YearCalendar.js +55 -22
  43. package/YearCalendar/YearCalendar.types.d.ts +8 -2
  44. package/dateTimeViewRenderers/dateTimeViewRenderers.d.ts +1 -1
  45. package/dateTimeViewRenderers/dateTimeViewRenderers.js +5 -2
  46. package/dateViewRenderers/dateViewRenderers.d.ts +1 -1
  47. package/dateViewRenderers/dateViewRenderers.js +4 -2
  48. package/index.js +1 -1
  49. package/internals/hooks/date-helpers-hooks.d.ts +4 -2
  50. package/internals/hooks/date-helpers-hooks.js +8 -6
  51. package/internals/hooks/useDesktopPicker/useDesktopPicker.js +2 -0
  52. package/internals/hooks/useField/useField.d.ts +3 -1
  53. package/internals/hooks/useField/useField.js +23 -7
  54. package/internals/hooks/useField/useField.types.d.ts +6 -4
  55. package/internals/hooks/useField/useField.utils.d.ts +13 -11
  56. package/internals/hooks/useField/useField.utils.js +55 -43
  57. package/internals/hooks/useField/useFieldCharacterEditing.d.ts +3 -2
  58. package/internals/hooks/useField/useFieldCharacterEditing.js +6 -5
  59. package/internals/hooks/useField/useFieldState.d.ts +1 -0
  60. package/internals/hooks/useField/useFieldState.js +33 -23
  61. package/internals/hooks/useMobilePicker/useMobilePicker.js +2 -0
  62. package/internals/hooks/usePicker/usePickerValue.js +45 -9
  63. package/internals/hooks/usePicker/usePickerValue.types.d.ts +22 -6
  64. package/internals/hooks/usePicker/usePickerViews.d.ts +2 -1
  65. package/internals/hooks/usePicker/usePickerViews.js +7 -2
  66. package/internals/hooks/useUtils.d.ts +3 -2
  67. package/internals/hooks/useUtils.js +5 -2
  68. package/internals/hooks/useValueWithTimezone.d.ts +33 -0
  69. package/internals/hooks/useValueWithTimezone.js +69 -0
  70. package/internals/index.d.ts +1 -0
  71. package/internals/index.js +1 -0
  72. package/internals/models/props/clock.d.ts +2 -2
  73. package/internals/utils/date-utils.d.ts +4 -4
  74. package/internals/utils/date-utils.js +4 -12
  75. package/internals/utils/fields.js +1 -1
  76. package/internals/utils/getDefaultReferenceDate.d.ts +12 -3
  77. package/internals/utils/getDefaultReferenceDate.js +4 -4
  78. package/internals/utils/validation/extractValidationProps.d.ts +1 -1
  79. package/internals/utils/validation/validateDate.d.ts +3 -2
  80. package/internals/utils/validation/validateDate.js +14 -6
  81. package/internals/utils/validation/validateTime.d.ts +3 -2
  82. package/internals/utils/validation/validateTime.js +8 -8
  83. package/internals/utils/valueManagers.js +2 -1
  84. package/legacy/AdapterDayjs/AdapterDayjs.js +45 -16
  85. package/legacy/AdapterLuxon/AdapterLuxon.js +13 -6
  86. package/legacy/AdapterMoment/AdapterMoment.js +18 -9
  87. package/legacy/DateCalendar/DateCalendar.js +47 -24
  88. package/legacy/DateCalendar/DayCalendar.js +24 -17
  89. package/legacy/DateCalendar/PickersCalendarHeader.js +6 -3
  90. package/legacy/DateCalendar/useCalendarState.js +40 -17
  91. package/legacy/DateCalendar/useIsDateDisabled.js +5 -3
  92. package/legacy/DateField/DateField.js +9 -1
  93. package/legacy/DatePicker/DatePicker.js +9 -1
  94. package/legacy/DateTimeField/DateTimeField.js +9 -1
  95. package/legacy/DateTimePicker/DateTimePicker.js +9 -1
  96. package/legacy/DesktopDatePicker/DesktopDatePicker.js +9 -1
  97. package/legacy/DesktopDateTimePicker/DesktopDateTimePicker.js +9 -1
  98. package/legacy/DesktopTimePicker/DesktopTimePicker.js +8 -0
  99. package/legacy/DigitalClock/DigitalClock.js +26 -16
  100. package/legacy/MobileDatePicker/MobileDatePicker.js +9 -1
  101. package/legacy/MobileDateTimePicker/MobileDateTimePicker.js +9 -1
  102. package/legacy/MobileTimePicker/MobileTimePicker.js +8 -0
  103. package/legacy/MonthCalendar/MonthCalendar.js +61 -32
  104. package/legacy/MultiSectionDigitalClock/MultiSectionDigitalClock.js +27 -16
  105. package/legacy/MultiSectionDigitalClock/MultiSectionDigitalClockSection.js +1 -1
  106. package/legacy/PickersLayout/PickersLayout.js +1 -0
  107. package/legacy/PickersLayout/usePickerLayout.js +3 -2
  108. package/legacy/PickersShortcuts/PickersShortcuts.js +10 -2
  109. package/legacy/StaticDatePicker/StaticDatePicker.js +9 -1
  110. package/legacy/StaticDateTimePicker/StaticDateTimePicker.js +9 -1
  111. package/legacy/StaticTimePicker/StaticTimePicker.js +8 -0
  112. package/legacy/TimeClock/TimeClock.js +25 -18
  113. package/legacy/TimeField/TimeField.js +9 -1
  114. package/legacy/TimePicker/TimePicker.js +8 -0
  115. package/legacy/YearCalendar/YearCalendar.js +59 -30
  116. package/legacy/dateTimeViewRenderers/dateTimeViewRenderers.js +5 -2
  117. package/legacy/dateViewRenderers/dateViewRenderers.js +4 -2
  118. package/legacy/index.js +1 -1
  119. package/legacy/internals/hooks/date-helpers-hooks.js +8 -6
  120. package/legacy/internals/hooks/useDesktopPicker/useDesktopPicker.js +2 -0
  121. package/legacy/internals/hooks/useField/useField.js +22 -6
  122. package/legacy/internals/hooks/useField/useField.utils.js +56 -44
  123. package/legacy/internals/hooks/useField/useFieldCharacterEditing.js +6 -5
  124. package/legacy/internals/hooks/useField/useFieldState.js +42 -33
  125. package/legacy/internals/hooks/useMobilePicker/useMobilePicker.js +2 -0
  126. package/legacy/internals/hooks/usePicker/usePickerValue.js +46 -9
  127. package/legacy/internals/hooks/usePicker/usePickerViews.js +7 -2
  128. package/legacy/internals/hooks/useUtils.js +5 -2
  129. package/legacy/internals/hooks/useValueWithTimezone.js +81 -0
  130. package/legacy/internals/index.js +1 -0
  131. package/legacy/internals/utils/date-utils.js +5 -13
  132. package/legacy/internals/utils/fields.js +1 -1
  133. package/legacy/internals/utils/getDefaultReferenceDate.js +4 -4
  134. package/legacy/internals/utils/validation/validateDate.js +12 -6
  135. package/legacy/internals/utils/validation/validateTime.js +8 -8
  136. package/legacy/internals/utils/valueManagers.js +3 -0
  137. package/legacy/locales/csCZ.js +2 -2
  138. package/legacy/locales/elGR.js +93 -0
  139. package/legacy/locales/index.js +1 -0
  140. package/legacy/tests/describeAdapters/describeAdapters.js +3 -1
  141. package/legacy/tests/describeGregorianAdapter/testCalculations.js +69 -27
  142. package/legacy/tests/describeJalaliAdapter/testCalculations.js +21 -0
  143. package/legacy/timeViewRenderers/timeViewRenderers.js +12 -6
  144. package/locales/csCZ.js +2 -2
  145. package/locales/elGR.d.ts +53 -0
  146. package/locales/elGR.js +57 -0
  147. package/locales/index.d.ts +1 -0
  148. package/locales/index.js +1 -0
  149. package/models/adapters.d.ts +2 -2
  150. package/models/timezone.d.ts +10 -0
  151. package/modern/AdapterDayjs/AdapterDayjs.js +41 -15
  152. package/modern/AdapterLuxon/AdapterLuxon.js +12 -4
  153. package/modern/AdapterMoment/AdapterMoment.js +18 -9
  154. package/modern/DateCalendar/DateCalendar.js +49 -21
  155. package/modern/DateCalendar/DayCalendar.js +24 -17
  156. package/modern/DateCalendar/PickersCalendarHeader.js +6 -3
  157. package/modern/DateCalendar/useCalendarState.js +41 -16
  158. package/modern/DateCalendar/useIsDateDisabled.js +5 -3
  159. package/modern/DateField/DateField.js +9 -1
  160. package/modern/DatePicker/DatePicker.js +9 -1
  161. package/modern/DateTimeField/DateTimeField.js +9 -1
  162. package/modern/DateTimePicker/DateTimePicker.js +9 -1
  163. package/modern/DesktopDatePicker/DesktopDatePicker.js +9 -1
  164. package/modern/DesktopDateTimePicker/DesktopDateTimePicker.js +9 -1
  165. package/modern/DesktopTimePicker/DesktopTimePicker.js +8 -0
  166. package/modern/DigitalClock/DigitalClock.js +28 -15
  167. package/modern/MobileDatePicker/MobileDatePicker.js +9 -1
  168. package/modern/MobileDateTimePicker/MobileDateTimePicker.js +9 -1
  169. package/modern/MobileTimePicker/MobileTimePicker.js +8 -0
  170. package/modern/MonthCalendar/MonthCalendar.js +57 -24
  171. package/modern/MultiSectionDigitalClock/MultiSectionDigitalClock.js +28 -15
  172. package/modern/MultiSectionDigitalClock/MultiSectionDigitalClockSection.js +1 -1
  173. package/modern/PickersLayout/PickersLayout.js +1 -0
  174. package/modern/PickersLayout/usePickerLayout.js +4 -3
  175. package/modern/PickersShortcuts/PickersShortcuts.js +10 -2
  176. package/modern/StaticDatePicker/StaticDatePicker.js +9 -1
  177. package/modern/StaticDateTimePicker/StaticDateTimePicker.js +9 -1
  178. package/modern/StaticTimePicker/StaticTimePicker.js +8 -0
  179. package/modern/TimeClock/TimeClock.js +27 -15
  180. package/modern/TimeField/TimeField.js +9 -1
  181. package/modern/TimePicker/TimePicker.js +8 -0
  182. package/modern/YearCalendar/YearCalendar.js +55 -22
  183. package/modern/dateTimeViewRenderers/dateTimeViewRenderers.js +5 -2
  184. package/modern/dateViewRenderers/dateViewRenderers.js +4 -2
  185. package/modern/index.js +1 -1
  186. package/modern/internals/hooks/date-helpers-hooks.js +8 -6
  187. package/modern/internals/hooks/useDesktopPicker/useDesktopPicker.js +2 -0
  188. package/modern/internals/hooks/useField/useField.js +23 -7
  189. package/modern/internals/hooks/useField/useField.utils.js +55 -43
  190. package/modern/internals/hooks/useField/useFieldCharacterEditing.js +6 -5
  191. package/modern/internals/hooks/useField/useFieldState.js +33 -22
  192. package/modern/internals/hooks/useMobilePicker/useMobilePicker.js +2 -0
  193. package/modern/internals/hooks/usePicker/usePickerValue.js +45 -9
  194. package/modern/internals/hooks/usePicker/usePickerViews.js +7 -2
  195. package/modern/internals/hooks/useUtils.js +5 -2
  196. package/modern/internals/hooks/useValueWithTimezone.js +68 -0
  197. package/modern/internals/index.js +1 -0
  198. package/modern/internals/utils/date-utils.js +4 -12
  199. package/modern/internals/utils/fields.js +1 -1
  200. package/modern/internals/utils/getDefaultReferenceDate.js +4 -4
  201. package/modern/internals/utils/validation/validateDate.js +14 -6
  202. package/modern/internals/utils/validation/validateTime.js +8 -8
  203. package/modern/internals/utils/valueManagers.js +2 -1
  204. package/modern/locales/csCZ.js +2 -2
  205. package/modern/locales/elGR.js +57 -0
  206. package/modern/locales/index.js +1 -0
  207. package/modern/tests/describeAdapters/describeAdapters.js +3 -1
  208. package/modern/tests/describeGregorianAdapter/testCalculations.js +69 -27
  209. package/modern/tests/describeJalaliAdapter/testCalculations.js +21 -0
  210. package/modern/timeViewRenderers/timeViewRenderers.js +12 -6
  211. package/node/AdapterDayjs/AdapterDayjs.js +41 -15
  212. package/node/AdapterLuxon/AdapterLuxon.js +12 -4
  213. package/node/AdapterMoment/AdapterMoment.js +18 -9
  214. package/node/DateCalendar/DateCalendar.js +48 -20
  215. package/node/DateCalendar/DayCalendar.js +24 -17
  216. package/node/DateCalendar/PickersCalendarHeader.js +6 -3
  217. package/node/DateCalendar/useCalendarState.js +41 -16
  218. package/node/DateCalendar/useIsDateDisabled.js +5 -3
  219. package/node/DateField/DateField.js +9 -1
  220. package/node/DatePicker/DatePicker.js +9 -1
  221. package/node/DateTimeField/DateTimeField.js +9 -1
  222. package/node/DateTimePicker/DateTimePicker.js +9 -1
  223. package/node/DesktopDatePicker/DesktopDatePicker.js +9 -1
  224. package/node/DesktopDateTimePicker/DesktopDateTimePicker.js +9 -1
  225. package/node/DesktopTimePicker/DesktopTimePicker.js +8 -0
  226. package/node/DigitalClock/DigitalClock.js +28 -15
  227. package/node/MobileDatePicker/MobileDatePicker.js +9 -1
  228. package/node/MobileDateTimePicker/MobileDateTimePicker.js +9 -1
  229. package/node/MobileTimePicker/MobileTimePicker.js +8 -0
  230. package/node/MonthCalendar/MonthCalendar.js +57 -24
  231. package/node/MultiSectionDigitalClock/MultiSectionDigitalClock.js +28 -15
  232. package/node/MultiSectionDigitalClock/MultiSectionDigitalClockSection.js +1 -1
  233. package/node/PickersLayout/PickersLayout.js +1 -0
  234. package/node/PickersLayout/usePickerLayout.js +4 -3
  235. package/node/PickersShortcuts/PickersShortcuts.js +10 -2
  236. package/node/StaticDatePicker/StaticDatePicker.js +9 -1
  237. package/node/StaticDateTimePicker/StaticDateTimePicker.js +9 -1
  238. package/node/StaticTimePicker/StaticTimePicker.js +8 -0
  239. package/node/TimeClock/TimeClock.js +26 -14
  240. package/node/TimeField/TimeField.js +9 -1
  241. package/node/TimePicker/TimePicker.js +8 -0
  242. package/node/YearCalendar/YearCalendar.js +55 -22
  243. package/node/dateTimeViewRenderers/dateTimeViewRenderers.js +5 -2
  244. package/node/dateViewRenderers/dateViewRenderers.js +4 -2
  245. package/node/index.js +1 -1
  246. package/node/internals/hooks/date-helpers-hooks.js +8 -6
  247. package/node/internals/hooks/useDesktopPicker/useDesktopPicker.js +2 -0
  248. package/node/internals/hooks/useField/useField.js +23 -7
  249. package/node/internals/hooks/useField/useField.utils.js +55 -43
  250. package/node/internals/hooks/useField/useFieldCharacterEditing.js +6 -5
  251. package/node/internals/hooks/useField/useFieldState.js +33 -22
  252. package/node/internals/hooks/useMobilePicker/useMobilePicker.js +2 -0
  253. package/node/internals/hooks/usePicker/usePickerValue.js +44 -9
  254. package/node/internals/hooks/usePicker/usePickerViews.js +7 -2
  255. package/node/internals/hooks/useUtils.js +5 -2
  256. package/node/internals/hooks/useValueWithTimezone.js +79 -0
  257. package/node/internals/index.js +7 -0
  258. package/node/internals/utils/date-utils.js +5 -14
  259. package/node/internals/utils/fields.js +1 -1
  260. package/node/internals/utils/getDefaultReferenceDate.js +5 -4
  261. package/node/internals/utils/validation/validateDate.js +14 -6
  262. package/node/internals/utils/validation/validateTime.js +8 -8
  263. package/node/internals/utils/valueManagers.js +2 -1
  264. package/node/locales/csCZ.js +2 -2
  265. package/node/locales/elGR.js +64 -0
  266. package/node/locales/index.js +11 -0
  267. package/node/tests/describeAdapters/describeAdapters.js +3 -1
  268. package/node/tests/describeGregorianAdapter/testCalculations.js +69 -27
  269. package/node/tests/describeJalaliAdapter/testCalculations.js +21 -0
  270. package/node/timeViewRenderers/timeViewRenderers.js +12 -6
  271. package/package.json +2 -2
  272. package/tests/describeAdapters/describeAdapters.js +3 -1
  273. package/tests/describeGregorianAdapter/testCalculations.js +69 -27
  274. package/tests/describeJalaliAdapter/testCalculations.js +21 -0
  275. package/timeViewRenderers/timeViewRenderers.d.ts +3 -3
  276. package/timeViewRenderers/timeViewRenderers.js +12 -6
@@ -32,9 +32,9 @@ const getDeltaFromKeyCode = keyCode => {
32
32
  return 0;
33
33
  }
34
34
  };
35
- export const getDaysInWeekStr = (utils, format) => {
35
+ export const getDaysInWeekStr = (utils, timezone, format) => {
36
36
  const elements = [];
37
- const now = utils.date();
37
+ const now = utils.dateWithTimezone(undefined, timezone);
38
38
  const startDate = utils.startOfWeek(now);
39
39
  const endDate = utils.endOfWeek(now);
40
40
  let current = startDate;
@@ -44,19 +44,19 @@ export const getDaysInWeekStr = (utils, format) => {
44
44
  }
45
45
  return elements.map(weekDay => utils.formatByString(weekDay, format));
46
46
  };
47
- export const getLetterEditingOptions = (utils, sectionType, format) => {
47
+ export const getLetterEditingOptions = (utils, timezone, sectionType, format) => {
48
48
  switch (sectionType) {
49
49
  case 'month':
50
50
  {
51
- return getMonthsInYear(utils, utils.date()).map(month => utils.formatByString(month, format));
51
+ return getMonthsInYear(utils, utils.dateWithTimezone(undefined, timezone)).map(month => utils.formatByString(month, format));
52
52
  }
53
53
  case 'weekDay':
54
54
  {
55
- return getDaysInWeekStr(utils, format);
55
+ return getDaysInWeekStr(utils, timezone, format);
56
56
  }
57
57
  case 'meridiem':
58
58
  {
59
- const now = utils.date();
59
+ const now = utils.dateWithTimezone(undefined, timezone);
60
60
  return [utils.startOfDay(now), utils.endOfDay(now)].map(date => utils.formatByString(date, format));
61
61
  }
62
62
  default:
@@ -77,7 +77,7 @@ export const cleanLeadingZeros = (utils, valueStr, size) => {
77
77
  }
78
78
  return cleanValueStr;
79
79
  };
80
- export const cleanDigitSectionValue = (utils, value, sectionBoundaries, section) => {
80
+ export const cleanDigitSectionValue = (utils, timezone, value, sectionBoundaries, section) => {
81
81
  if (process.env.NODE_ENV !== 'production') {
82
82
  if (section.type !== 'day' && section.contentType === 'digit-with-letter') {
83
83
  throw new Error([`MUI: The token "${section.format}" is a digit format with letter in it.'
@@ -96,7 +96,7 @@ export const cleanDigitSectionValue = (utils, value, sectionBoundaries, section)
96
96
  }
97
97
  return valueStr;
98
98
  };
99
- export const adjustSectionValue = (utils, section, keyCode, sectionsValueBoundaries, activeDate) => {
99
+ export const adjustSectionValue = (utils, timezone, section, keyCode, sectionsValueBoundaries, activeDate, stepsAttribues) => {
100
100
  const delta = getDeltaFromKeyCode(keyCode);
101
101
  const isStart = keyCode === 'Home';
102
102
  const isEnd = keyCode === 'End';
@@ -107,28 +107,39 @@ export const adjustSectionValue = (utils, section, keyCode, sectionsValueBoundar
107
107
  format: section.format,
108
108
  contentType: section.contentType
109
109
  });
110
- const getCleanValue = value => cleanDigitSectionValue(utils, value, sectionBoundaries, section);
110
+ const getCleanValue = value => cleanDigitSectionValue(utils, timezone, value, sectionBoundaries, section);
111
+ const step = section.type === 'minutes' && stepsAttribues?.minutesStep ? stepsAttribues.minutesStep : 1;
112
+ const currentSectionValue = parseInt(section.value, 10);
113
+ let newSectionValueNumber = currentSectionValue + delta * step;
111
114
  if (shouldSetAbsolute) {
112
115
  if (section.type === 'year' && !isEnd && !isStart) {
113
- return utils.formatByString(utils.date(), section.format);
116
+ return utils.formatByString(utils.dateWithTimezone(undefined, timezone), section.format);
114
117
  }
115
118
  if (delta > 0 || isStart) {
116
- return getCleanValue(sectionBoundaries.minimum);
119
+ newSectionValueNumber = sectionBoundaries.minimum;
120
+ } else {
121
+ newSectionValueNumber = sectionBoundaries.maximum;
122
+ }
123
+ }
124
+ if (newSectionValueNumber % step !== 0) {
125
+ if (delta < 0 || isStart) {
126
+ newSectionValueNumber += step - (step + newSectionValueNumber) % step; // for JS -3 % 5 = -3 (should be 2)
127
+ }
128
+
129
+ if (delta > 0 || isEnd) {
130
+ newSectionValueNumber -= newSectionValueNumber % step;
117
131
  }
118
- return getCleanValue(sectionBoundaries.maximum);
119
132
  }
120
- const currentSectionValue = parseInt(section.value, 10);
121
- const newSectionValueNumber = currentSectionValue + delta;
122
133
  if (newSectionValueNumber > sectionBoundaries.maximum) {
123
- return getCleanValue(sectionBoundaries.minimum);
134
+ return getCleanValue(sectionBoundaries.minimum + (newSectionValueNumber - sectionBoundaries.maximum - 1) % (sectionBoundaries.maximum - sectionBoundaries.minimum + 1));
124
135
  }
125
136
  if (newSectionValueNumber < sectionBoundaries.minimum) {
126
- return getCleanValue(sectionBoundaries.maximum);
137
+ return getCleanValue(sectionBoundaries.maximum - (sectionBoundaries.minimum - newSectionValueNumber - 1) % (sectionBoundaries.maximum - sectionBoundaries.minimum + 1));
127
138
  }
128
139
  return getCleanValue(newSectionValueNumber);
129
140
  };
130
141
  const adjustLetterSection = () => {
131
- const options = getLetterEditingOptions(utils, section.type, section.format);
142
+ const options = getLetterEditingOptions(utils, timezone, section.type, section.format);
132
143
  if (options.length === 0) {
133
144
  return section.value;
134
145
  }
@@ -196,12 +207,12 @@ export const addPositionPropertiesToSections = (sections, isRTL) => {
196
207
  }
197
208
  return newSections;
198
209
  };
199
- const getSectionPlaceholder = (utils, localeText, sectionConfig, currentTokenValue) => {
210
+ const getSectionPlaceholder = (utils, timezone, localeText, sectionConfig, currentTokenValue) => {
200
211
  switch (sectionConfig.type) {
201
212
  case 'year':
202
213
  {
203
214
  return localeText.fieldYearPlaceholder({
204
- digitAmount: utils.formatByString(utils.date(), currentTokenValue).length
215
+ digitAmount: utils.formatByString(utils.dateWithTimezone(undefined, timezone), currentTokenValue).length
205
216
  });
206
217
  }
207
218
  case 'month':
@@ -250,45 +261,46 @@ export const changeSectionValueFormat = (utils, valueStr, currentFormat, newForm
250
261
  }
251
262
  return utils.formatByString(utils.parse(valueStr, currentFormat), newFormat);
252
263
  };
253
- const isFourDigitYearFormat = (utils, format) => utils.formatByString(utils.date(), format).length === 4;
254
- export const doesSectionFormatHaveLeadingZeros = (utils, contentType, sectionType, format) => {
264
+ const isFourDigitYearFormat = (utils, timezone, format) => utils.formatByString(utils.dateWithTimezone(undefined, timezone), format).length === 4;
265
+ export const doesSectionFormatHaveLeadingZeros = (utils, timezone, contentType, sectionType, format) => {
255
266
  if (contentType !== 'digit') {
256
267
  return false;
257
268
  }
269
+ const now = utils.dateWithTimezone(undefined, timezone);
258
270
  switch (sectionType) {
259
271
  // We can't use `changeSectionValueFormat`, because `utils.parse('1', 'YYYY')` returns `1971` instead of `1`.
260
272
  case 'year':
261
273
  {
262
- if (isFourDigitYearFormat(utils, format)) {
263
- const formatted0001 = utils.formatByString(utils.setYear(utils.date(), 1), format);
274
+ if (isFourDigitYearFormat(utils, timezone, format)) {
275
+ const formatted0001 = utils.formatByString(utils.setYear(now, 1), format);
264
276
  return formatted0001 === '0001';
265
277
  }
266
- const formatted2001 = utils.formatByString(utils.setYear(utils.date(), 2001), format);
278
+ const formatted2001 = utils.formatByString(utils.setYear(now, 2001), format);
267
279
  return formatted2001 === '01';
268
280
  }
269
281
  case 'month':
270
282
  {
271
- return utils.formatByString(utils.startOfYear(utils.date()), format).length > 1;
283
+ return utils.formatByString(utils.startOfYear(now), format).length > 1;
272
284
  }
273
285
  case 'day':
274
286
  {
275
- return utils.formatByString(utils.startOfMonth(utils.date()), format).length > 1;
287
+ return utils.formatByString(utils.startOfMonth(now), format).length > 1;
276
288
  }
277
289
  case 'weekDay':
278
290
  {
279
- return utils.formatByString(utils.startOfWeek(utils.date()), format).length > 1;
291
+ return utils.formatByString(utils.startOfWeek(now), format).length > 1;
280
292
  }
281
293
  case 'hours':
282
294
  {
283
- return utils.formatByString(utils.setHours(utils.date(), 1), format).length > 1;
295
+ return utils.formatByString(utils.setHours(now, 1), format).length > 1;
284
296
  }
285
297
  case 'minutes':
286
298
  {
287
- return utils.formatByString(utils.setMinutes(utils.date(), 1), format).length > 1;
299
+ return utils.formatByString(utils.setMinutes(now, 1), format).length > 1;
288
300
  }
289
301
  case 'seconds':
290
302
  {
291
- return utils.formatByString(utils.setMinutes(utils.date(), 1), format).length > 1;
303
+ return utils.formatByString(utils.setMinutes(now, 1), format).length > 1;
292
304
  }
293
305
  default:
294
306
  {
@@ -313,7 +325,7 @@ const getEscapedPartsFromFormat = (utils, format) => {
313
325
  }
314
326
  return escapedParts;
315
327
  };
316
- export const splitFormatIntoSections = (utils, localeText, format, date, formatDensity, shouldRespectLeadingZeros, isRTL) => {
328
+ export const splitFormatIntoSections = (utils, timezone, localeText, format, date, formatDensity, shouldRespectLeadingZeros, isRTL) => {
317
329
  let startSeparator = '';
318
330
  const sections = [];
319
331
  const now = utils.date();
@@ -322,7 +334,7 @@ export const splitFormatIntoSections = (utils, localeText, format, date, formatD
322
334
  return null;
323
335
  }
324
336
  const sectionConfig = getDateSectionConfigFromFormatToken(utils, token);
325
- const hasLeadingZerosInFormat = doesSectionFormatHaveLeadingZeros(utils, sectionConfig.contentType, sectionConfig.type, token);
337
+ const hasLeadingZerosInFormat = doesSectionFormatHaveLeadingZeros(utils, timezone, sectionConfig.contentType, sectionConfig.type, token);
326
338
  const hasLeadingZerosInInput = shouldRespectLeadingZeros ? hasLeadingZerosInFormat : sectionConfig.contentType === 'digit';
327
339
  const isValidDate = date != null && utils.isValid(date);
328
340
  let sectionValue = isValidDate ? utils.formatByString(date, token) : '';
@@ -344,7 +356,7 @@ export const splitFormatIntoSections = (utils, localeText, format, date, formatD
344
356
  format: token,
345
357
  maxLength,
346
358
  value: sectionValue,
347
- placeholder: getSectionPlaceholder(utils, localeText, sectionConfig, token),
359
+ placeholder: getSectionPlaceholder(utils, timezone, localeText, sectionConfig, token),
348
360
  hasLeadingZeros: hasLeadingZerosInFormat,
349
361
  hasLeadingZerosInFormat,
350
362
  hasLeadingZerosInInput,
@@ -455,8 +467,8 @@ export const createDateStrForInputFromSections = (sections, isRTL) => {
455
467
  // wrap into an isolated group such that separators can split the string in smaller ones by adding \u2069\u2068
456
468
  return `\u2066${dateStr}\u2069`;
457
469
  };
458
- export const getSectionsBoundaries = utils => {
459
- const today = utils.date();
470
+ export const getSectionsBoundaries = (utils, timezone) => {
471
+ const today = utils.dateWithTimezone(undefined, timezone);
460
472
  const endOfYear = utils.endOfYear(today);
461
473
  const {
462
474
  maxDaysInMonth,
@@ -479,7 +491,7 @@ export const getSectionsBoundaries = utils => {
479
491
  format
480
492
  }) => ({
481
493
  minimum: 0,
482
- maximum: isFourDigitYearFormat(utils, format) ? 9999 : 99
494
+ maximum: isFourDigitYearFormat(utils, timezone, format) ? 9999 : 99
483
495
  }),
484
496
  month: () => ({
485
497
  minimum: 1,
@@ -498,7 +510,7 @@ export const getSectionsBoundaries = utils => {
498
510
  contentType
499
511
  }) => {
500
512
  if (contentType === 'digit') {
501
- const daysInWeek = getDaysInWeekStr(utils, format).map(Number);
513
+ const daysInWeek = getDaysInWeekStr(utils, timezone, format).map(Number);
502
514
  return {
503
515
  minimum: Math.min(...daysInWeek),
504
516
  maximum: Math.max(...daysInWeek)
@@ -560,7 +572,7 @@ export const validateSections = (sections, valueType) => {
560
572
  }
561
573
  }
562
574
  };
563
- const transferDateSectionValue = (utils, section, dateToTransferFrom, dateToTransferTo) => {
575
+ const transferDateSectionValue = (utils, timezone, section, dateToTransferFrom, dateToTransferTo) => {
564
576
  switch (section.type) {
565
577
  case 'year':
566
578
  {
@@ -572,7 +584,7 @@ const transferDateSectionValue = (utils, section, dateToTransferFrom, dateToTran
572
584
  }
573
585
  case 'weekDay':
574
586
  {
575
- const formattedDaysInWeek = getDaysInWeekStr(utils, section.format);
587
+ const formattedDaysInWeek = getDaysInWeekStr(utils, timezone, section.format);
576
588
  const dayInWeekStrOfActiveDate = utils.formatByString(dateToTransferFrom, section.format);
577
589
  const dayInWeekOfActiveDate = formattedDaysInWeek.indexOf(dayInWeekStrOfActiveDate);
578
590
  const dayInWeekOfNewSectionValue = formattedDaysInWeek.indexOf(section.value);
@@ -623,16 +635,16 @@ const reliableSectionModificationOrder = {
623
635
  seconds: 7,
624
636
  meridiem: 8
625
637
  };
626
- export const mergeDateIntoReferenceDate = (utils, dateToTransferFrom, sections, referenceDate, shouldLimitToEditedSections) =>
638
+ export const mergeDateIntoReferenceDate = (utils, timezone, dateToTransferFrom, sections, referenceDate, shouldLimitToEditedSections) =>
627
639
  // cloning sections before sort to avoid mutating it
628
640
  [...sections].sort((a, b) => reliableSectionModificationOrder[a.type] - reliableSectionModificationOrder[b.type]).reduce((mergedDate, section) => {
629
641
  if (!shouldLimitToEditedSections || section.modified) {
630
- return transferDateSectionValue(utils, section, dateToTransferFrom, mergedDate);
642
+ return transferDateSectionValue(utils, timezone, section, dateToTransferFrom, mergedDate);
631
643
  }
632
644
  return mergedDate;
633
645
  }, referenceDate);
634
646
  export const isAndroid = () => navigator.userAgent.toLowerCase().indexOf('android') > -1;
635
- export const clampDaySectionIfPossible = (utils, sections, sectionsValueBoundaries) => {
647
+ export const clampDaySectionIfPossible = (utils, timezone, sections, sectionsValueBoundaries) => {
636
648
  // We can only clamp the day value if:
637
649
  // 1. if all the sections are filled (except the week day section which can be empty)
638
650
  // 2. there is a day section
@@ -652,7 +664,7 @@ export const clampDaySectionIfPossible = (utils, sections, sectionsValueBoundari
652
664
  contentType: section.contentType
653
665
  });
654
666
  return _extends({}, section, {
655
- value: cleanDigitSectionValue(utils, dayBoundaries.minimum, dayBoundaries, section)
667
+ value: cleanDigitSectionValue(utils, timezone, dayBoundaries.minimum, dayBoundaries, section)
656
668
  });
657
669
  });
658
670
  const startOfMonth = getDateFromDateSections(utils, sectionsForStartOfMonth);
@@ -40,7 +40,8 @@ export const useFieldCharacterEditing = ({
40
40
  sections,
41
41
  updateSectionValue,
42
42
  sectionsValueBoundaries,
43
- setTempAndroidValueStr
43
+ setTempAndroidValueStr,
44
+ timezone
44
45
  }) => {
45
46
  const utils = useUtils();
46
47
  const [query, setQuery] = React.useState(null);
@@ -109,7 +110,7 @@ export const useFieldCharacterEditing = ({
109
110
  };
110
111
  };
111
112
  const testQueryOnFormatAndFallbackFormat = (queryValue, activeSection, fallbackFormat, formatFallbackValue) => {
112
- const getOptions = format => getLetterEditingOptions(utils, activeSection.type, format);
113
+ const getOptions = format => getLetterEditingOptions(utils, timezone, activeSection.type, format);
113
114
  if (activeSection.contentType === 'letter') {
114
115
  return findMatchingOptions(activeSection.format, getOptions(activeSection.format), queryValue);
115
116
  }
@@ -182,7 +183,7 @@ export const useFieldCharacterEditing = ({
182
183
  };
183
184
  }
184
185
  const shouldGoToNextSection = Number(`${queryValue}0`) > sectionBoundaries.maximum || queryValue.length === sectionBoundaries.maximum.toString().length;
185
- const newSectionValue = cleanDigitSectionValue(utils, queryValueNumber, sectionBoundaries, section);
186
+ const newSectionValue = cleanDigitSectionValue(utils, timezone, queryValueNumber, sectionBoundaries, section);
186
187
  return {
187
188
  sectionValue: newSectionValue,
188
189
  shouldGoToNextSection
@@ -196,7 +197,7 @@ export const useFieldCharacterEditing = ({
196
197
  // When editing a letter-format month and the user presses a digit,
197
198
  // We can support the numeric editing by using the digit-format month and re-formatting the result.
198
199
  if (activeSection.type === 'month') {
199
- const hasLeadingZerosInFormat = doesSectionFormatHaveLeadingZeros(utils, 'digit', 'month', 'MM');
200
+ const hasLeadingZerosInFormat = doesSectionFormatHaveLeadingZeros(utils, timezone, 'digit', 'month', 'MM');
200
201
  const response = getNewSectionValue(queryValue, {
201
202
  type: activeSection.type,
202
203
  format: 'MM',
@@ -221,7 +222,7 @@ export const useFieldCharacterEditing = ({
221
222
  if (isQueryResponseWithoutValue(response)) {
222
223
  return response;
223
224
  }
224
- const formattedValue = getDaysInWeekStr(utils, activeSection.format)[Number(response.sectionValue) - 1];
225
+ const formattedValue = getDaysInWeekStr(utils, timezone, activeSection.format)[Number(response.sectionValue) - 1];
225
226
  return _extends({}, response, {
226
227
  sectionValue: formattedValue
227
228
  });
@@ -4,6 +4,7 @@ import useControlled from '@mui/utils/useControlled';
4
4
  import { useTheme } from '@mui/material/styles';
5
5
  import { useUtils, useLocaleText, useLocalizationContext } from '../useUtils';
6
6
  import { addPositionPropertiesToSections, splitFormatIntoSections, clampDaySectionIfPossible, mergeDateIntoReferenceDate, getSectionsBoundaries, validateSections, getDateFromDateSections } from './useField.utils';
7
+ import { useValueWithTimezone } from '../useValueWithTimezone';
7
8
  import { getSectionTypeGranularity } from '../../utils/getDefaultReferenceDate';
8
9
  export const useFieldState = params => {
9
10
  const utils = useUtils();
@@ -26,13 +27,23 @@ export const useFieldState = params => {
26
27
  formatDensity = 'dense',
27
28
  selectedSections: selectedSectionsProp,
28
29
  onSelectedSectionsChange,
29
- shouldRespectLeadingZeros = false
30
+ shouldRespectLeadingZeros = false,
31
+ timezone: timezoneProp
30
32
  }
31
33
  } = params;
32
- const firstDefaultValue = React.useRef(defaultValue);
33
- const valueFromTheOutside = valueProp ?? firstDefaultValue.current ?? valueManager.emptyValue;
34
- const sectionsValueBoundaries = React.useMemo(() => getSectionsBoundaries(utils), [utils]);
35
- const getSectionsFromValue = React.useCallback((value, fallbackSections = null) => fieldValueManager.getSectionsFromValue(utils, value, fallbackSections, isRTL, date => splitFormatIntoSections(utils, localeText, format, date, formatDensity, shouldRespectLeadingZeros, isRTL)), [fieldValueManager, format, localeText, isRTL, shouldRespectLeadingZeros, utils, formatDensity]);
34
+ const {
35
+ timezone,
36
+ value: valueFromTheOutside,
37
+ handleValueChange
38
+ } = useValueWithTimezone({
39
+ timezone: timezoneProp,
40
+ value: valueProp,
41
+ defaultValue,
42
+ onChange,
43
+ valueManager
44
+ });
45
+ const sectionsValueBoundaries = React.useMemo(() => getSectionsBoundaries(utils, timezone), [utils, timezone]);
46
+ const getSectionsFromValue = React.useCallback((value, fallbackSections = null) => fieldValueManager.getSectionsFromValue(utils, value, fallbackSections, isRTL, date => splitFormatIntoSections(utils, timezone, localeText, format, date, formatDensity, shouldRespectLeadingZeros, isRTL)), [fieldValueManager, format, localeText, isRTL, shouldRespectLeadingZeros, utils, formatDensity, timezone]);
36
47
  const placeholder = React.useMemo(() => fieldValueManager.getValueStrFromSections(getSectionsFromValue(valueManager.emptyValue), isRTL), [fieldValueManager, getSectionsFromValue, valueManager.emptyValue, isRTL]);
37
48
  const [state, setState] = React.useState(() => {
38
49
  const sections = getSectionsFromValue(valueFromTheOutside);
@@ -47,10 +58,10 @@ export const useFieldState = params => {
47
58
  const referenceValue = valueManager.getInitialReferenceValue({
48
59
  referenceDate: referenceDateProp,
49
60
  value: valueFromTheOutside,
50
- valueType,
51
61
  utils,
52
62
  props: internalProps,
53
- granularity
63
+ granularity,
64
+ timezone
54
65
  });
55
66
  return _extends({}, stateWithoutReferenceDate, {
56
67
  referenceValue
@@ -106,18 +117,17 @@ export const useFieldState = params => {
106
117
  referenceValue,
107
118
  tempValueStrAndroid: null
108
119
  }));
109
- if (onChange) {
110
- const context = {
111
- validationError: validator({
112
- adapter,
120
+ const context = {
121
+ validationError: validator({
122
+ adapter,
123
+ value,
124
+ props: _extends({}, internalProps, {
113
125
  value,
114
- props: _extends({}, internalProps, {
115
- value
116
- })
126
+ timezone
117
127
  })
118
- };
119
- onChange(value, context);
120
- }
128
+ })
129
+ };
130
+ handleValueChange(value, context);
121
131
  };
122
132
  const setSectionValue = (sectionIndex, newSectionValue) => {
123
133
  const newSections = [...state.sections];
@@ -168,8 +178,8 @@ export const useFieldState = params => {
168
178
  if (date == null || !utils.isValid(date)) {
169
179
  return null;
170
180
  }
171
- const sections = splitFormatIntoSections(utils, localeText, format, date, formatDensity, shouldRespectLeadingZeros, isRTL);
172
- return mergeDateIntoReferenceDate(utils, date, sections, referenceDate, false);
181
+ const sections = splitFormatIntoSections(utils, timezone, localeText, format, date, formatDensity, shouldRespectLeadingZeros, isRTL);
182
+ return mergeDateIntoReferenceDate(utils, timezone, date, sections, referenceDate, false);
173
183
  };
174
184
  const newValue = fieldValueManager.parseValueStr(valueStr, state.referenceValue, parseDateStr);
175
185
  const newReferenceValue = fieldValueManager.updateReferenceValue(utils, newValue, state.referenceValue);
@@ -208,7 +218,7 @@ export const useFieldState = params => {
208
218
  * This can be useful if the month has fewer days than the day value currently provided.
209
219
  */
210
220
  if (!utils.isValid(newActiveDate)) {
211
- const clampedSections = clampDaySectionIfPossible(utils, newActiveDateSections, sectionsValueBoundaries);
221
+ const clampedSections = clampDaySectionIfPossible(utils, timezone, newActiveDateSections, sectionsValueBoundaries);
212
222
  if (clampedSections != null) {
213
223
  shouldRegenSections = true;
214
224
  newActiveDate = getDateFromDateSections(utils, clampedSections);
@@ -223,7 +233,7 @@ export const useFieldState = params => {
223
233
  * This makes sure that we don't lose some information of the initial date (like the time on a date field).
224
234
  */
225
235
  if (newActiveDate != null && utils.isValid(newActiveDate)) {
226
- const mergedDate = mergeDateIntoReferenceDate(utils, newActiveDate, newActiveDateSections, activeDateManager.referenceDate, true);
236
+ const mergedDate = mergeDateIntoReferenceDate(utils, timezone, newActiveDate, newActiveDateSections, activeDateManager.referenceDate, true);
227
237
  values = activeDateManager.getNewValuesFromNewActiveDate(mergedDate);
228
238
  shouldPublish = true;
229
239
  } else {
@@ -287,6 +297,7 @@ export const useFieldState = params => {
287
297
  updateValueFromValueStr,
288
298
  setTempAndroidValueStr,
289
299
  sectionsValueBoundaries,
290
- placeholder
300
+ placeholder,
301
+ timezone
291
302
  };
292
303
  };
@@ -32,6 +32,7 @@ export const useMobilePicker = _ref => {
32
32
  sx,
33
33
  format,
34
34
  formatDensity,
35
+ timezone,
35
36
  label,
36
37
  inputRef,
37
38
  readOnly,
@@ -71,6 +72,7 @@ export const useMobilePicker = _ref => {
71
72
  sx,
72
73
  format,
73
74
  formatDensity,
75
+ timezone,
74
76
  label
75
77
  }),
76
78
  ownerState: props
@@ -5,6 +5,8 @@ import useEventCallback from '@mui/utils/useEventCallback';
5
5
  import { useOpenState } from '../useOpenState';
6
6
  import { useLocalizationContext, useUtils } from '../useUtils';
7
7
  import { useValidation } from '../useValidation';
8
+ import { useValueWithTimezone } from '../useValueWithTimezone';
9
+
8
10
  /**
9
11
  * Decide if the new value should be published
10
12
  * The published value will be passed to `onChange` if defined.
@@ -38,6 +40,14 @@ const shouldPublishValue = params => {
38
40
  }
39
41
  return hasChanged(dateState.lastPublishedValue);
40
42
  }
43
+ if (action.name === 'setValueFromShortcut' && action.changeImportance === 'accept') {
44
+ // On the first view,
45
+ // If the value is not controlled, then clicking on any value (including the one equal to `defaultValue`) should call `onChange`
46
+ if (isCurrentValueTheDefaultValue) {
47
+ return true;
48
+ }
49
+ return hasChanged(dateState.lastPublishedValue);
50
+ }
41
51
  return false;
42
52
  };
43
53
 
@@ -71,6 +81,9 @@ const shouldCommitValue = params => {
71
81
  }
72
82
  return hasChanged(dateState.lastCommittedValue);
73
83
  }
84
+ if (action.name === 'setValueFromShortcut') {
85
+ return action.changeImportance === 'accept' && hasChanged(dateState.lastCommittedValue);
86
+ }
74
87
  return false;
75
88
  };
76
89
 
@@ -88,6 +101,9 @@ const shouldClosePicker = params => {
88
101
  if (action.name === 'setValueFromView') {
89
102
  return action.selectionState === 'finish' && closeOnSelect;
90
103
  }
104
+ if (action.name === 'setValueFromShortcut') {
105
+ return action.changeImportance === 'accept';
106
+ }
91
107
  return false;
92
108
  };
93
109
 
@@ -108,7 +124,8 @@ export const usePickerValue = ({
108
124
  defaultValue: inDefaultValue,
109
125
  closeOnSelect = wrapperVariant === 'desktop',
110
126
  selectedSections: selectedSectionsProp,
111
- onSelectedSectionsChange
127
+ onSelectedSectionsChange,
128
+ timezone: timezoneProp
112
129
  } = props;
113
130
  const {
114
131
  current: defaultValue
@@ -161,8 +178,19 @@ export const usePickerValue = ({
161
178
  hasBeenModifiedSinceMount: false
162
179
  };
163
180
  });
181
+ const {
182
+ timezone,
183
+ handleValueChange
184
+ } = useValueWithTimezone({
185
+ timezone: timezoneProp,
186
+ value: inValue,
187
+ defaultValue,
188
+ onChange,
189
+ valueManager
190
+ });
164
191
  useValidation(_extends({}, props, {
165
- value: dateState.draft
192
+ value: dateState.draft,
193
+ timezone
166
194
  }), validator, valueManager.isSameError, valueManager.defaultErrorState);
167
195
  const updateDate = useEventCallback(action => {
168
196
  const updaterParams = {
@@ -181,18 +209,19 @@ export const usePickerValue = ({
181
209
  lastCommittedValue: shouldCommit ? action.value : prev.lastCommittedValue,
182
210
  hasBeenModifiedSinceMount: true
183
211
  }));
184
- if (shouldPublish && onChange) {
212
+ if (shouldPublish) {
185
213
  const validationError = action.name === 'setValueFromField' ? action.context.validationError : validator({
186
214
  adapter,
187
215
  value: action.value,
188
216
  props: _extends({}, props, {
189
- value: action.value
217
+ value: action.value,
218
+ timezone
190
219
  })
191
220
  });
192
221
  const context = {
193
222
  validationError
194
223
  };
195
- onChange(action.value, context);
224
+ handleValueChange(action.value, context);
196
225
  }
197
226
  if (shouldCommit && onAccept) {
198
227
  onAccept(action.value);
@@ -242,7 +271,7 @@ export const usePickerValue = ({
242
271
  });
243
272
  const handleSetToday = useEventCallback(() => {
244
273
  updateDate({
245
- value: valueManager.getTodayValue(utils, valueType),
274
+ value: valueManager.getTodayValue(utils, timezone, valueType),
246
275
  name: 'setValueFromAction',
247
276
  pickerAction: 'today'
248
277
  });
@@ -254,7 +283,12 @@ export const usePickerValue = ({
254
283
  value: newValue,
255
284
  selectionState
256
285
  }));
257
- const handleChangeField = useEventCallback((newValue, context) => updateDate({
286
+ const handleSelectShortcut = useEventCallback((newValue, changeImportance) => updateDate({
287
+ name: 'setValueFromShortcut',
288
+ value: newValue,
289
+ changeImportance: changeImportance ?? 'accept'
290
+ }));
291
+ const handleChangeFromField = useEventCallback((newValue, context) => updateDate({
258
292
  name: 'setValueFromField',
259
293
  value: newValue,
260
294
  context
@@ -274,7 +308,7 @@ export const usePickerValue = ({
274
308
  };
275
309
  const fieldResponse = {
276
310
  value: dateState.draft,
277
- onChange: handleChangeField,
311
+ onChange: handleChangeFromField,
278
312
  selectedSections,
279
313
  onSelectedSectionsChange: handleFieldSelectedSectionsChange
280
314
  };
@@ -291,7 +325,8 @@ export const usePickerValue = ({
291
325
  adapter,
292
326
  value: testedValue,
293
327
  props: _extends({}, props, {
294
- value: testedValue
328
+ value: testedValue,
329
+ timezone
295
330
  })
296
331
  });
297
332
  return !valueManager.hasError(error);
@@ -299,6 +334,7 @@ export const usePickerValue = ({
299
334
  const layoutResponse = _extends({}, actions, {
300
335
  value: viewValue,
301
336
  onChange: handleChange,
337
+ onSelectShortcut: handleSelectShortcut,
302
338
  isValid
303
339
  });
304
340
  return {
@@ -43,7 +43,8 @@ export const usePickerViews = ({
43
43
  openTo,
44
44
  onViewChange,
45
45
  disableOpenPicker,
46
- viewRenderers
46
+ viewRenderers,
47
+ timezone
47
48
  } = props;
48
49
  const propsToForwardToView = _objectWithoutPropertiesLoose(props, _excluded);
49
50
  const {
@@ -95,11 +96,14 @@ export const usePickerViews = ({
95
96
  setPopperView(view);
96
97
  }
97
98
  useEnhancedEffect(() => {
99
+ // Handle case of `DateTimePicker` without time renderers
98
100
  if (currentViewMode === 'field' && open) {
99
101
  onClose();
100
- onSelectedSectionsChange('hours');
101
102
  setTimeout(() => {
103
+ // focusing the input before the range selection is done
104
+ // calling `onSelectedSectionsChange` outside of timeout results in an inconsistent behavior between Safari And Chrome
102
105
  inputRef?.current.focus();
106
+ onSelectedSectionsChange(view);
103
107
  });
104
108
  }
105
109
  }, [view]); // eslint-disable-line react-hooks/exhaustive-deps
@@ -144,6 +148,7 @@ export const usePickerViews = ({
144
148
  }
145
149
  return renderer(_extends({}, propsToForwardToView, additionalViewProps, propsFromPickerValue, {
146
150
  views,
151
+ timezone,
147
152
  onChange: setValueAndGoToNextView,
148
153
  view: popperView,
149
154
  onViewChange: setView,
@@ -18,8 +18,11 @@ export const useLocalizationContext = () => {
18
18
  export const useUtils = () => useLocalizationContext().utils;
19
19
  export const useDefaultDates = () => useLocalizationContext().defaultDates;
20
20
  export const useLocaleText = () => useLocalizationContext().localeText;
21
- export const useNow = () => {
21
+ export const useNow = timezone => {
22
22
  const utils = useUtils();
23
- const now = React.useRef(utils.date());
23
+ const now = React.useRef();
24
+ if (now.current === undefined) {
25
+ now.current = utils.dateWithTimezone(undefined, timezone);
26
+ }
24
27
  return now.current;
25
28
  };