@gravity-ui/date-components 1.6.0 → 2.1.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 (279) hide show
  1. package/dist/cjs/components/Calendar/Calendar.d.ts +6 -5
  2. package/dist/cjs/components/Calendar/Calendar.js +4 -4
  3. package/dist/cjs/components/Calendar/index.d.ts +6 -6
  4. package/dist/cjs/components/Calendar/index.js +5 -5
  5. package/dist/cjs/components/{CalendarBase → CalendarView}/Calendar.css +9 -6
  6. package/dist/cjs/components/{CalendarBase/CalendarBase.d.ts → CalendarView/CalendarView.d.ts} +2 -2
  7. package/dist/cjs/components/{CalendarBase/CalendarBase.js → CalendarView/CalendarView.js} +4 -3
  8. package/dist/{esm/components/CalendarBase → cjs/components/CalendarView}/hooks/types.d.ts +37 -31
  9. package/dist/cjs/components/{CalendarBase → CalendarView}/hooks/useCalendarCellProps.js +1 -2
  10. package/dist/cjs/components/{CalendarBase → CalendarView}/hooks/useCalendarGridProps.d.ts +2 -2
  11. package/dist/cjs/components/{CalendarBase → CalendarView}/hooks/useCalendarProps.js +17 -0
  12. package/dist/{esm/components/CalendarBase → cjs/components/CalendarView}/hooks/useCalendarState.d.ts +1 -1
  13. package/dist/cjs/components/{CalendarBase → CalendarView}/hooks/useCalendarState.js +45 -23
  14. package/dist/cjs/components/CalendarView/hooks/useRangeCalendarState.d.ts +8 -0
  15. package/dist/cjs/components/{CalendarBase → CalendarView}/hooks/useRangeCalendarState.js +25 -14
  16. package/dist/cjs/components/CalendarView/i18n/en.json +7 -0
  17. package/dist/cjs/components/CalendarView/i18n/index.d.ts +1 -0
  18. package/dist/cjs/components/CalendarView/i18n/ru.json +7 -0
  19. package/dist/cjs/components/DateField/DateField.d.ts +1 -4
  20. package/dist/cjs/components/DateField/DateField.js +3 -1
  21. package/dist/cjs/components/DateField/hooks/useBaseDateFieldState.d.ts +97 -0
  22. package/dist/cjs/components/DateField/hooks/useBaseDateFieldState.js +316 -0
  23. package/dist/cjs/components/DateField/hooks/useDateFieldProps.d.ts +6 -3
  24. package/dist/cjs/components/DateField/hooks/useDateFieldProps.js +14 -12
  25. package/dist/cjs/components/DateField/hooks/useDateFieldState.d.ts +2 -65
  26. package/dist/cjs/components/DateField/hooks/useDateFieldState.js +98 -410
  27. package/dist/cjs/components/DateField/index.d.ts +1 -0
  28. package/dist/cjs/components/DateField/index.js +1 -0
  29. package/dist/cjs/components/DateField/utils.d.ts +10 -1
  30. package/dist/cjs/components/DateField/utils.js +114 -2
  31. package/dist/cjs/components/DatePicker/DatePicker.d.ts +4 -4
  32. package/dist/cjs/components/DatePicker/DatePicker.js +8 -6
  33. package/dist/cjs/components/DatePicker/MobileCalendar.css +7 -32
  34. package/dist/cjs/components/DatePicker/MobileCalendar.d.ts +0 -5
  35. package/dist/cjs/components/DatePicker/MobileCalendar.js +18 -20
  36. package/dist/cjs/components/DatePicker/StubButton.css +26 -0
  37. package/dist/cjs/components/DatePicker/StubButton.d.ts +8 -0
  38. package/dist/cjs/components/DatePicker/StubButton.js +12 -0
  39. package/dist/cjs/components/DatePicker/hooks/useDatePickerProps.js +7 -17
  40. package/dist/cjs/components/DatePicker/hooks/useDatePickerState.d.ts +5 -4
  41. package/dist/cjs/components/DatePicker/hooks/useDatePickerState.js +71 -56
  42. package/dist/cjs/components/RangeCalendar/RangeCalendar.d.ts +3 -3
  43. package/dist/cjs/components/RangeCalendar/RangeCalendar.js +4 -4
  44. package/dist/cjs/components/RangeDateField/RangeDateField.css +4 -0
  45. package/dist/cjs/components/RangeDateField/RangeDateField.d.ts +12 -0
  46. package/dist/cjs/components/RangeDateField/RangeDateField.js +25 -0
  47. package/dist/cjs/components/RangeDateField/hooks/useRangeDateFieldState.d.ts +9 -0
  48. package/dist/cjs/components/RangeDateField/hooks/useRangeDateFieldState.js +227 -0
  49. package/dist/cjs/components/RangeDateField/index.d.ts +2 -0
  50. package/dist/cjs/components/RangeDateField/index.js +5 -0
  51. package/dist/cjs/components/RangeDateField/utils/createPlaceholderRangeValue.d.ts +5 -0
  52. package/dist/cjs/components/RangeDateField/utils/createPlaceholderRangeValue.js +9 -0
  53. package/dist/cjs/components/RangeDateField/utils/getRangeEditableSections.d.ts +5 -0
  54. package/dist/cjs/components/RangeDateField/utils/getRangeEditableSections.js +42 -0
  55. package/dist/cjs/components/RangeDateField/utils/index.d.ts +3 -0
  56. package/dist/cjs/components/RangeDateField/utils/index.js +6 -0
  57. package/dist/cjs/components/RangeDateField/utils/isValidRange.d.ts +3 -0
  58. package/dist/cjs/components/RangeDateField/utils/isValidRange.js +8 -0
  59. package/dist/cjs/components/RelativeDateField/RelativeDateField.d.ts +2 -2
  60. package/dist/cjs/components/RelativeDateField/RelativeDateField.js +5 -2
  61. package/dist/cjs/components/RelativeDateField/hooks/useRelativeDateFieldProps.js +5 -11
  62. package/dist/cjs/components/RelativeDateField/hooks/useRelativeDateFieldState.d.ts +3 -1
  63. package/dist/cjs/components/RelativeDateField/hooks/useRelativeDateFieldState.js +5 -4
  64. package/dist/cjs/components/RelativeDatePicker/RelativeDatePicker.css +3 -0
  65. package/dist/cjs/components/RelativeDatePicker/RelativeDatePicker.d.ts +2 -2
  66. package/dist/cjs/components/RelativeDatePicker/RelativeDatePicker.js +15 -2
  67. package/dist/cjs/components/RelativeDatePicker/hooks/useRelativeDatePickerProps.js +35 -27
  68. package/dist/cjs/components/RelativeDatePicker/hooks/useRelativeDatePickerState.d.ts +2 -2
  69. package/dist/cjs/components/RelativeDatePicker/hooks/useRelativeDatePickerState.js +12 -16
  70. package/dist/cjs/components/RelativeRangeDatePicker/RelativeRangeDatePicker.css +56 -0
  71. package/dist/cjs/components/RelativeRangeDatePicker/RelativeRangeDatePicker.d.ts +27 -0
  72. package/dist/cjs/components/RelativeRangeDatePicker/RelativeRangeDatePicker.js +90 -0
  73. package/dist/cjs/components/RelativeRangeDatePicker/components/PickerDialog/PickerDialog.css +32 -0
  74. package/dist/cjs/components/RelativeRangeDatePicker/components/PickerDialog/PickerDialog.d.ts +14 -0
  75. package/dist/cjs/components/RelativeRangeDatePicker/components/PickerDialog/PickerDialog.js +43 -0
  76. package/dist/cjs/components/RelativeRangeDatePicker/components/PickerDialog/i18n/en.json +8 -0
  77. package/dist/cjs/components/RelativeRangeDatePicker/components/PickerDialog/i18n/index.d.ts +1 -0
  78. package/dist/cjs/components/RelativeRangeDatePicker/components/PickerDialog/i18n/index.js +9 -0
  79. package/dist/cjs/components/RelativeRangeDatePicker/components/PickerDialog/i18n/ru.json +8 -0
  80. package/dist/cjs/components/RelativeRangeDatePicker/components/PickerDialog/useRelativeRangeDatePickerDialogState.d.ts +16 -0
  81. package/dist/cjs/components/RelativeRangeDatePicker/components/PickerDialog/useRelativeRangeDatePickerDialogState.js +104 -0
  82. package/dist/cjs/components/RelativeRangeDatePicker/components/Presets/Presets.css +26 -0
  83. package/dist/cjs/components/RelativeRangeDatePicker/components/Presets/Presets.d.ts +18 -0
  84. package/dist/cjs/components/RelativeRangeDatePicker/components/Presets/Presets.js +67 -0
  85. package/dist/cjs/components/RelativeRangeDatePicker/components/Presets/PresetsDoc.css +14 -0
  86. package/dist/cjs/components/RelativeRangeDatePicker/components/Presets/PresetsDoc.d.ts +7 -0
  87. package/dist/cjs/components/RelativeRangeDatePicker/components/Presets/PresetsDoc.js +90 -0
  88. package/dist/cjs/components/RelativeRangeDatePicker/components/Presets/defaultPresets.d.ts +9 -0
  89. package/dist/cjs/components/RelativeRangeDatePicker/components/Presets/defaultPresets.js +186 -0
  90. package/dist/cjs/components/RelativeRangeDatePicker/components/Presets/i18n/en.json +40 -0
  91. package/dist/cjs/components/RelativeRangeDatePicker/components/Presets/i18n/index.d.ts +1 -0
  92. package/dist/cjs/components/RelativeRangeDatePicker/components/Presets/i18n/index.js +9 -0
  93. package/dist/cjs/components/RelativeRangeDatePicker/components/Presets/i18n/ru.json +40 -0
  94. package/dist/cjs/components/RelativeRangeDatePicker/components/Presets/utils.d.ts +16 -0
  95. package/dist/cjs/components/RelativeRangeDatePicker/components/Presets/utils.js +85 -0
  96. package/dist/cjs/components/RelativeRangeDatePicker/components/Zones/Zones.css +3 -0
  97. package/dist/cjs/components/RelativeRangeDatePicker/components/Zones/Zones.d.ts +9 -0
  98. package/dist/cjs/components/RelativeRangeDatePicker/components/Zones/Zones.js +62 -0
  99. package/dist/cjs/components/RelativeRangeDatePicker/components/Zones/i18n/en.json +4 -0
  100. package/dist/cjs/components/RelativeRangeDatePicker/components/Zones/i18n/index.d.ts +1 -0
  101. package/dist/cjs/components/RelativeRangeDatePicker/components/Zones/i18n/index.js +9 -0
  102. package/dist/cjs/components/RelativeRangeDatePicker/components/Zones/i18n/ru.json +4 -0
  103. package/dist/cjs/components/RelativeRangeDatePicker/hooks/useRelativeRangeDatePickerState.d.ts +26 -0
  104. package/dist/cjs/components/RelativeRangeDatePicker/hooks/useRelativeRangeDatePickerState.js +58 -0
  105. package/dist/cjs/components/RelativeRangeDatePicker/i18n/en.json +8 -0
  106. package/dist/cjs/components/RelativeRangeDatePicker/i18n/index.d.ts +1 -0
  107. package/dist/cjs/components/RelativeRangeDatePicker/i18n/index.js +9 -0
  108. package/dist/cjs/components/RelativeRangeDatePicker/i18n/ru.json +8 -0
  109. package/dist/cjs/components/RelativeRangeDatePicker/index.d.ts +4 -0
  110. package/dist/cjs/components/RelativeRangeDatePicker/index.js +8 -0
  111. package/dist/cjs/components/RelativeRangeDatePicker/utils.d.ts +15 -0
  112. package/dist/cjs/components/RelativeRangeDatePicker/utils.js +53 -0
  113. package/dist/cjs/components/index.d.ts +3 -0
  114. package/dist/cjs/components/index.js +2 -0
  115. package/dist/cjs/components/types/datePicker.d.ts +5 -2
  116. package/dist/cjs/components/types/events.d.ts +4 -4
  117. package/dist/cjs/components/types/inputs.d.ts +10 -9
  118. package/dist/cjs/components/utils/dates.d.ts +1 -2
  119. package/dist/cjs/components/utils/useDefaultTimeZone.d.ts +2 -0
  120. package/dist/cjs/components/utils/useDefaultTimeZone.js +15 -0
  121. package/dist/cjs/components/utils/validation/datePicker.d.ts +6 -0
  122. package/dist/cjs/components/utils/validation/datePicker.js +30 -0
  123. package/dist/cjs/components/utils/validation/i18n/en.json +6 -0
  124. package/dist/cjs/components/utils/validation/i18n/index.d.ts +1 -0
  125. package/dist/cjs/components/utils/validation/i18n/index.js +9 -0
  126. package/dist/cjs/components/utils/validation/i18n/ru.json +6 -0
  127. package/dist/esm/components/Calendar/Calendar.d.ts +6 -5
  128. package/dist/esm/components/Calendar/Calendar.js +4 -4
  129. package/dist/esm/components/Calendar/index.d.ts +6 -6
  130. package/dist/esm/components/Calendar/index.js +5 -5
  131. package/dist/esm/components/{CalendarBase → CalendarView}/Calendar.css +9 -6
  132. package/dist/esm/components/{CalendarBase/CalendarBase.d.ts → CalendarView/CalendarView.d.ts} +2 -2
  133. package/dist/esm/components/{CalendarBase/CalendarBase.js → CalendarView/CalendarView.js} +3 -2
  134. package/dist/{cjs/components/CalendarBase → esm/components/CalendarView}/hooks/types.d.ts +37 -31
  135. package/dist/esm/components/{CalendarBase → CalendarView}/hooks/useCalendarCellProps.js +1 -2
  136. package/dist/esm/components/{CalendarBase → CalendarView}/hooks/useCalendarGridProps.d.ts +2 -2
  137. package/dist/esm/components/{CalendarBase → CalendarView}/hooks/useCalendarGridProps.js +0 -1
  138. package/dist/esm/components/{CalendarBase → CalendarView}/hooks/useCalendarProps.js +17 -0
  139. package/dist/{cjs/components/CalendarBase → esm/components/CalendarView}/hooks/useCalendarState.d.ts +1 -1
  140. package/dist/esm/components/{CalendarBase → CalendarView}/hooks/useCalendarState.js +46 -24
  141. package/dist/esm/components/CalendarView/hooks/useRangeCalendarState.d.ts +8 -0
  142. package/dist/esm/components/{CalendarBase → CalendarView}/hooks/useRangeCalendarState.js +24 -13
  143. package/dist/esm/components/CalendarView/i18n/en.json +7 -0
  144. package/dist/esm/components/CalendarView/i18n/index.d.ts +1 -0
  145. package/dist/esm/components/CalendarView/i18n/ru.json +7 -0
  146. package/dist/esm/components/DateField/DateField.d.ts +1 -4
  147. package/dist/esm/components/DateField/DateField.js +4 -2
  148. package/dist/esm/components/DateField/hooks/useBaseDateFieldState.d.ts +97 -0
  149. package/dist/esm/components/DateField/hooks/useBaseDateFieldState.js +311 -0
  150. package/dist/esm/components/DateField/hooks/useDateFieldProps.d.ts +6 -3
  151. package/dist/esm/components/DateField/hooks/useDateFieldProps.js +14 -12
  152. package/dist/esm/components/DateField/hooks/useDateFieldState.d.ts +2 -65
  153. package/dist/esm/components/DateField/hooks/useDateFieldState.js +97 -409
  154. package/dist/esm/components/DateField/index.d.ts +1 -0
  155. package/dist/esm/components/DateField/index.js +1 -0
  156. package/dist/esm/components/DateField/utils.d.ts +10 -1
  157. package/dist/esm/components/DateField/utils.js +105 -2
  158. package/dist/esm/components/DatePicker/DatePicker.d.ts +4 -4
  159. package/dist/esm/components/DatePicker/DatePicker.js +10 -8
  160. package/dist/esm/components/DatePicker/MobileCalendar.css +7 -32
  161. package/dist/esm/components/DatePicker/MobileCalendar.d.ts +0 -5
  162. package/dist/esm/components/DatePicker/MobileCalendar.js +17 -18
  163. package/dist/esm/components/DatePicker/StubButton.css +26 -0
  164. package/dist/esm/components/DatePicker/StubButton.d.ts +8 -0
  165. package/dist/esm/components/DatePicker/StubButton.js +8 -0
  166. package/dist/esm/components/DatePicker/hooks/useDatePickerProps.js +7 -17
  167. package/dist/esm/components/DatePicker/hooks/useDatePickerState.d.ts +5 -4
  168. package/dist/esm/components/DatePicker/hooks/useDatePickerState.js +71 -56
  169. package/dist/esm/components/RangeCalendar/RangeCalendar.d.ts +3 -3
  170. package/dist/esm/components/RangeCalendar/RangeCalendar.js +4 -4
  171. package/dist/esm/components/RangeDateField/RangeDateField.css +4 -0
  172. package/dist/esm/components/RangeDateField/RangeDateField.d.ts +12 -0
  173. package/dist/esm/components/RangeDateField/RangeDateField.js +21 -0
  174. package/dist/esm/components/RangeDateField/hooks/useRangeDateFieldState.d.ts +9 -0
  175. package/dist/esm/components/RangeDateField/hooks/useRangeDateFieldState.js +222 -0
  176. package/dist/esm/components/RangeDateField/index.d.ts +2 -0
  177. package/dist/esm/components/RangeDateField/index.js +2 -0
  178. package/dist/esm/components/RangeDateField/utils/createPlaceholderRangeValue.d.ts +5 -0
  179. package/dist/esm/components/RangeDateField/utils/createPlaceholderRangeValue.js +5 -0
  180. package/dist/esm/components/RangeDateField/utils/getRangeEditableSections.d.ts +5 -0
  181. package/dist/esm/components/RangeDateField/utils/getRangeEditableSections.js +38 -0
  182. package/dist/esm/components/RangeDateField/utils/index.d.ts +3 -0
  183. package/dist/esm/components/RangeDateField/utils/index.js +3 -0
  184. package/dist/esm/components/RangeDateField/utils/isValidRange.d.ts +3 -0
  185. package/dist/esm/components/RangeDateField/utils/isValidRange.js +4 -0
  186. package/dist/esm/components/RelativeDateField/RelativeDateField.d.ts +2 -2
  187. package/dist/esm/components/RelativeDateField/RelativeDateField.js +5 -2
  188. package/dist/esm/components/RelativeDateField/hooks/useRelativeDateFieldProps.js +5 -11
  189. package/dist/esm/components/RelativeDateField/hooks/useRelativeDateFieldState.d.ts +3 -1
  190. package/dist/esm/components/RelativeDateField/hooks/useRelativeDateFieldState.js +5 -4
  191. package/dist/esm/components/RelativeDatePicker/RelativeDatePicker.css +3 -0
  192. package/dist/esm/components/RelativeDatePicker/RelativeDatePicker.d.ts +2 -2
  193. package/dist/esm/components/RelativeDatePicker/RelativeDatePicker.js +17 -4
  194. package/dist/esm/components/RelativeDatePicker/hooks/useRelativeDatePickerProps.js +35 -27
  195. package/dist/esm/components/RelativeDatePicker/hooks/useRelativeDatePickerState.d.ts +2 -2
  196. package/dist/esm/components/RelativeDatePicker/hooks/useRelativeDatePickerState.js +12 -16
  197. package/dist/esm/components/RelativeRangeDatePicker/RelativeRangeDatePicker.css +56 -0
  198. package/dist/esm/components/RelativeRangeDatePicker/RelativeRangeDatePicker.d.ts +27 -0
  199. package/dist/esm/components/RelativeRangeDatePicker/RelativeRangeDatePicker.js +85 -0
  200. package/dist/esm/components/RelativeRangeDatePicker/components/PickerDialog/PickerDialog.css +32 -0
  201. package/dist/esm/components/RelativeRangeDatePicker/components/PickerDialog/PickerDialog.d.ts +14 -0
  202. package/dist/esm/components/RelativeRangeDatePicker/components/PickerDialog/PickerDialog.js +39 -0
  203. package/dist/esm/components/RelativeRangeDatePicker/components/PickerDialog/i18n/en.json +8 -0
  204. package/dist/esm/components/RelativeRangeDatePicker/components/PickerDialog/i18n/index.d.ts +1 -0
  205. package/dist/esm/components/RelativeRangeDatePicker/components/PickerDialog/i18n/index.js +5 -0
  206. package/dist/esm/components/RelativeRangeDatePicker/components/PickerDialog/i18n/ru.json +8 -0
  207. package/dist/esm/components/RelativeRangeDatePicker/components/PickerDialog/useRelativeRangeDatePickerDialogState.d.ts +16 -0
  208. package/dist/esm/components/RelativeRangeDatePicker/components/PickerDialog/useRelativeRangeDatePickerDialogState.js +99 -0
  209. package/dist/esm/components/RelativeRangeDatePicker/components/Presets/Presets.css +26 -0
  210. package/dist/esm/components/RelativeRangeDatePicker/components/Presets/Presets.d.ts +18 -0
  211. package/dist/esm/components/RelativeRangeDatePicker/components/Presets/Presets.js +62 -0
  212. package/dist/esm/components/RelativeRangeDatePicker/components/Presets/PresetsDoc.css +14 -0
  213. package/dist/esm/components/RelativeRangeDatePicker/components/Presets/PresetsDoc.d.ts +7 -0
  214. package/dist/esm/components/RelativeRangeDatePicker/components/Presets/PresetsDoc.js +85 -0
  215. package/dist/esm/components/RelativeRangeDatePicker/components/Presets/defaultPresets.d.ts +9 -0
  216. package/dist/esm/components/RelativeRangeDatePicker/components/Presets/defaultPresets.js +183 -0
  217. package/dist/esm/components/RelativeRangeDatePicker/components/Presets/i18n/en.json +40 -0
  218. package/dist/esm/components/RelativeRangeDatePicker/components/Presets/i18n/index.d.ts +1 -0
  219. package/dist/esm/components/RelativeRangeDatePicker/components/Presets/i18n/index.js +5 -0
  220. package/dist/esm/components/RelativeRangeDatePicker/components/Presets/i18n/ru.json +40 -0
  221. package/dist/esm/components/RelativeRangeDatePicker/components/Presets/utils.d.ts +16 -0
  222. package/dist/esm/components/RelativeRangeDatePicker/components/Presets/utils.js +78 -0
  223. package/dist/esm/components/RelativeRangeDatePicker/components/Zones/Zones.css +3 -0
  224. package/dist/esm/components/RelativeRangeDatePicker/components/Zones/Zones.d.ts +9 -0
  225. package/dist/esm/components/RelativeRangeDatePicker/components/Zones/Zones.js +58 -0
  226. package/dist/esm/components/RelativeRangeDatePicker/components/Zones/i18n/en.json +4 -0
  227. package/dist/esm/components/RelativeRangeDatePicker/components/Zones/i18n/index.d.ts +1 -0
  228. package/dist/esm/components/RelativeRangeDatePicker/components/Zones/i18n/index.js +5 -0
  229. package/dist/esm/components/RelativeRangeDatePicker/components/Zones/i18n/ru.json +4 -0
  230. package/dist/esm/components/RelativeRangeDatePicker/hooks/useRelativeRangeDatePickerState.d.ts +26 -0
  231. package/dist/esm/components/RelativeRangeDatePicker/hooks/useRelativeRangeDatePickerState.js +53 -0
  232. package/dist/esm/components/RelativeRangeDatePicker/i18n/en.json +8 -0
  233. package/dist/esm/components/RelativeRangeDatePicker/i18n/index.d.ts +1 -0
  234. package/dist/esm/components/RelativeRangeDatePicker/i18n/index.js +5 -0
  235. package/dist/esm/components/RelativeRangeDatePicker/i18n/ru.json +8 -0
  236. package/dist/esm/components/RelativeRangeDatePicker/index.d.ts +4 -0
  237. package/dist/esm/components/RelativeRangeDatePicker/index.js +3 -0
  238. package/dist/esm/components/RelativeRangeDatePicker/utils.d.ts +15 -0
  239. package/dist/esm/components/RelativeRangeDatePicker/utils.js +46 -0
  240. package/dist/esm/components/index.d.ts +3 -0
  241. package/dist/esm/components/index.js +2 -0
  242. package/dist/esm/components/types/datePicker.d.ts +5 -2
  243. package/dist/esm/components/types/events.d.ts +4 -4
  244. package/dist/esm/components/types/inputs.d.ts +10 -9
  245. package/dist/esm/components/utils/dates.d.ts +1 -2
  246. package/dist/esm/components/utils/useDefaultTimeZone.d.ts +2 -0
  247. package/dist/esm/components/utils/useDefaultTimeZone.js +10 -0
  248. package/dist/esm/components/utils/validation/datePicker.d.ts +6 -0
  249. package/dist/esm/components/utils/validation/datePicker.js +26 -0
  250. package/dist/esm/components/utils/validation/i18n/en.json +6 -0
  251. package/dist/esm/components/utils/validation/i18n/index.d.ts +1 -0
  252. package/dist/esm/components/utils/validation/i18n/index.js +5 -0
  253. package/dist/esm/components/utils/validation/i18n/ru.json +6 -0
  254. package/package.json +28 -28
  255. package/dist/cjs/components/CalendarBase/hooks/useRangeCalendarState.d.ts +0 -7
  256. package/dist/cjs/components/CalendarBase/i18n/en.json +0 -4
  257. package/dist/cjs/components/CalendarBase/i18n/index.d.ts +0 -1
  258. package/dist/cjs/components/CalendarBase/i18n/ru.json +0 -4
  259. package/dist/cjs/components/hooks/useControlledState.d.ts +0 -1
  260. package/dist/cjs/components/hooks/useControlledState.js +0 -28
  261. package/dist/esm/components/CalendarBase/hooks/useRangeCalendarState.d.ts +0 -7
  262. package/dist/esm/components/CalendarBase/i18n/en.json +0 -4
  263. package/dist/esm/components/CalendarBase/i18n/index.d.ts +0 -1
  264. package/dist/esm/components/CalendarBase/i18n/ru.json +0 -4
  265. package/dist/esm/components/hooks/useControlledState.d.ts +0 -1
  266. package/dist/esm/components/hooks/useControlledState.js +0 -23
  267. /package/dist/cjs/components/{CalendarBase → CalendarView}/hooks/types.js +0 -0
  268. /package/dist/cjs/components/{CalendarBase → CalendarView}/hooks/useCalendarCellProps.d.ts +0 -0
  269. /package/dist/cjs/components/{CalendarBase → CalendarView}/hooks/useCalendarGridProps.js +0 -0
  270. /package/dist/cjs/components/{CalendarBase → CalendarView}/hooks/useCalendarProps.d.ts +0 -0
  271. /package/dist/cjs/components/{CalendarBase → CalendarView}/i18n/index.js +0 -0
  272. /package/dist/cjs/components/{CalendarBase → CalendarView}/utils.d.ts +0 -0
  273. /package/dist/cjs/components/{CalendarBase → CalendarView}/utils.js +0 -0
  274. /package/dist/esm/components/{CalendarBase → CalendarView}/hooks/types.js +0 -0
  275. /package/dist/esm/components/{CalendarBase → CalendarView}/hooks/useCalendarCellProps.d.ts +0 -0
  276. /package/dist/esm/components/{CalendarBase → CalendarView}/hooks/useCalendarProps.d.ts +0 -0
  277. /package/dist/esm/components/{CalendarBase → CalendarView}/i18n/index.js +0 -0
  278. /package/dist/esm/components/{CalendarBase → CalendarView}/utils.d.ts +0 -0
  279. /package/dist/esm/components/{CalendarBase → CalendarView}/utils.js +0 -0
@@ -1,5 +1,17 @@
1
- import { dateTime, settings } from '@gravity-ui/date-utils';
1
+ import React from 'react';
2
+ import { dateTime, isValid, settings } from '@gravity-ui/date-utils';
3
+ import { mergeDateTime } from '../utils/dates';
2
4
  import { i18n } from './i18n';
5
+ export const EDITABLE_SEGMENTS = {
6
+ year: true,
7
+ month: true,
8
+ day: true,
9
+ hour: true,
10
+ minute: true,
11
+ second: true,
12
+ dayPeriod: true,
13
+ weekday: true,
14
+ };
3
15
  export function expandFormat(format) {
4
16
  const localeFormats = settings.getLocaleData().formats;
5
17
  const getShortLocalizedFormatFromLongLocalizedFormat = (formatBis) => formatBis.replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g, (_, escapeSequence, localizedFormat) => escapeSequence || localizedFormat.slice(1));
@@ -311,7 +323,7 @@ export function splitFormatIntoSections(format) {
311
323
  let isSeparator = false;
312
324
  let isInEscapeBoundary = false;
313
325
  for (let i = 0; i < expandedFormat.length; i++) {
314
- const char = expandedFormat[i];
326
+ const char = expandedFormat[i] || '';
315
327
  if (isInEscapeBoundary) {
316
328
  if (char === escapedCharacters.end) {
317
329
  isInEscapeBoundary = false;
@@ -408,3 +420,94 @@ function getSectionOptions(section, token) {
408
420
  export function cleanString(dirtyString) {
409
421
  return dirtyString.replace(/[\u2066\u2067\u2068\u2069]/g, '');
410
422
  }
423
+ export function getEditableSections(sections, value, validSegments) {
424
+ let position = 1;
425
+ const newSections = [];
426
+ let previousEditableSection = -1;
427
+ for (let i = 0; i < sections.length; i++) {
428
+ const section = sections[i];
429
+ if (!section) {
430
+ continue;
431
+ }
432
+ const newSection = toEditableSection(section, value, validSegments, position, previousEditableSection);
433
+ newSections.push(newSection);
434
+ if (isEditableSection(section)) {
435
+ for (let j = Math.max(0, previousEditableSection); j <= i; j++) {
436
+ const prevSection = newSections[j];
437
+ if (prevSection) {
438
+ prevSection.nextEditableSection = i;
439
+ if (prevSection.previousEditableSection === -1) {
440
+ prevSection.previousEditableSection = i;
441
+ }
442
+ }
443
+ }
444
+ previousEditableSection = i;
445
+ }
446
+ position += newSection.textValue.length;
447
+ }
448
+ return newSections;
449
+ }
450
+ export function isEditableSection(section) {
451
+ var _a;
452
+ return (_a = EDITABLE_SEGMENTS[section.type]) !== null && _a !== void 0 ? _a : false;
453
+ }
454
+ export function toEditableSection(section, value, validSegments, position, previousEditableSection) {
455
+ const isEditable = isEditableSection(section);
456
+ let renderedValue = section.placeholder;
457
+ if ((isEditable && validSegments[section.type]) || section.type === 'timeZoneName') {
458
+ renderedValue = value.format(section.format);
459
+ if (section.contentType === 'digit' && renderedValue.length < section.placeholder.length) {
460
+ renderedValue = renderedValue.padStart(section.placeholder.length, '0');
461
+ }
462
+ }
463
+ // use bidirectional context to allow the browser autodetect text direction
464
+ renderedValue = '\u2068' + renderedValue + '\u2069';
465
+ const sectionLength = renderedValue.length;
466
+ const newSection = Object.assign(Object.assign(Object.assign({}, section), { value: getSectionValue(section, value), textValue: renderedValue, start: position, end: position + sectionLength, modified: false, previousEditableSection, nextEditableSection: previousEditableSection }), getSectionLimits(section, value));
467
+ return newSection;
468
+ }
469
+ export function getCurrentEditableSectionIndex(sections, selectedSections) {
470
+ const currentIndex = selectedSections === 'all' || selectedSections === -1 ? 0 : selectedSections;
471
+ const section = sections[currentIndex];
472
+ if (section && !EDITABLE_SEGMENTS[section.type]) {
473
+ return section.nextEditableSection;
474
+ }
475
+ return section ? currentIndex : -1;
476
+ }
477
+ export function formatSections(sections) {
478
+ // use ltr direction context to get predictable navigation inside input
479
+ return '\u2066' + sections.map((s) => s.textValue).join('') + '\u2069';
480
+ }
481
+ function parseDate(options) {
482
+ let date = dateTime(options);
483
+ if (!isValid(date)) {
484
+ date = dateTime(Object.assign(Object.assign({}, options), { format: undefined }));
485
+ }
486
+ return date;
487
+ }
488
+ function isDateStringWithTimeZone(str) {
489
+ return /z$/i.test(str) || /[+-]\d\d:\d\d$/.test(str);
490
+ }
491
+ export function parseDateFromString(str, format, timeZone) {
492
+ let date = parseDate({ input: str, format, timeZone });
493
+ if (isValid(date)) {
494
+ if (timeZone && !isDateStringWithTimeZone(str)) {
495
+ const time = parseDate({ input: str, format });
496
+ date = mergeDateTime(date, time);
497
+ }
498
+ }
499
+ return date;
500
+ }
501
+ export function isAllSegmentsValid(allSegments, validSegments) {
502
+ return Object.keys(allSegments).every((key) => validSegments[key]);
503
+ }
504
+ export function useFormatSections(format) {
505
+ const usedFormat = format;
506
+ const [sections, setSections] = React.useState(() => splitFormatIntoSections(usedFormat));
507
+ const [previousFormat, setFormat] = React.useState(usedFormat);
508
+ if (usedFormat !== previousFormat) {
509
+ setFormat(usedFormat);
510
+ setSections(splitFormatIntoSections(usedFormat));
511
+ }
512
+ return sections;
513
+ }
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
- import { type CalendarProps } from '../Calendar';
3
- import type { AccessibilityProps, DateFieldBase, DomProps, FocusableProps, KeyboardEvents, StyleProps, TextInputProps } from '../types';
2
+ import type { CalendarProps } from '../Calendar';
3
+ import type { AccessibilityProps, DateFieldBase, DomProps, FocusableProps, InputDOMProps, KeyboardEvents, StyleProps, TextInputProps } from '../types';
4
4
  import './DatePicker.css';
5
- export interface DatePickerProps extends DateFieldBase, TextInputProps, FocusableProps, KeyboardEvents, DomProps, StyleProps, AccessibilityProps {
5
+ export interface DatePickerProps extends DateFieldBase, TextInputProps, FocusableProps, KeyboardEvents, DomProps, InputDOMProps, StyleProps, AccessibilityProps {
6
6
  children?: (props: CalendarProps) => React.ReactNode;
7
7
  }
8
- export declare function DatePicker({ value, defaultValue, onUpdate, className, ...props }: DatePickerProps): import("react/jsx-runtime").JSX.Element;
8
+ export declare function DatePicker({ className, ...props }: DatePickerProps): import("react/jsx-runtime").JSX.Element;
@@ -1,22 +1,24 @@
1
1
  import { __rest } from "tslib";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import React from 'react';
4
- import { Calendar as CalendarIcon } from '@gravity-ui/icons';
4
+ import { Calendar as CalendarIcon, Clock as ClockIcon } from '@gravity-ui/icons';
5
5
  import { Button, Icon, Popup, TextInput, useMobile } from '@gravity-ui/uikit';
6
6
  import { Calendar } from '../Calendar';
7
7
  import { DateField } from '../DateField';
8
- import { MobileCalendar, MobileCalendarIcon } from './MobileCalendar';
8
+ import { MobileCalendar } from './MobileCalendar';
9
+ import { StubButton } from './StubButton';
9
10
  import { useDatePickerProps } from './hooks/useDatePickerProps';
10
11
  import { useDatePickerState } from './hooks/useDatePickerState';
11
12
  import { b } from './utils';
12
13
  import './DatePicker.css';
13
14
  export function DatePicker(_a) {
14
- var { value, defaultValue, onUpdate, className } = _a, props = __rest(_a, ["value", "defaultValue", "onUpdate", "className"]);
15
+ var { className } = _a, props = __rest(_a, ["className"]);
15
16
  const anchorRef = React.useRef(null);
16
- const state = useDatePickerState(Object.assign(Object.assign({}, props), { value,
17
- defaultValue,
18
- onUpdate }));
17
+ const state = useDatePickerState(props);
19
18
  const { groupProps, fieldProps, calendarButtonProps, popupProps, calendarProps, timeInputProps } = useDatePickerProps(state, props);
20
- const [isMobile] = useMobile();
21
- return (_jsxs("div", Object.assign({ className: b(null, className) }, groupProps, { children: [isMobile ? (_jsx(MobileCalendar, { props: props, state: state })) : (_jsx("div", { ref: anchorRef, className: b('popup-anchor'), children: _jsx(Popup, Object.assign({ anchorRef: anchorRef }, popupProps, { children: _jsxs("div", { className: b('popup-content'), children: [typeof props.children === 'function' ? (props.children(calendarProps)) : (_jsx(Calendar, Object.assign({}, calendarProps))), state.hasTime && (_jsx("div", { className: b('time-field-wrapper'), children: _jsx(DateField, Object.assign({}, timeInputProps)) }))] }) })) })), _jsx(TextInput, Object.assign({}, fieldProps, { className: b('field', { mobile: isMobile }), hasClear: !isMobile && fieldProps.hasClear, rightContent: isMobile ? (_jsx(MobileCalendarIcon, { props: props, state: state })) : (_jsx(Button, Object.assign({}, calendarButtonProps, { children: _jsx(Icon, { data: CalendarIcon }) }))) }))] })));
19
+ const isMobile = useMobile();
20
+ const isOnlyTime = state.hasTime && !state.hasDate;
21
+ return (_jsxs("div", Object.assign({ className: b(null, className) }, groupProps, { children: [isMobile ? (_jsx(MobileCalendar, { props: props, state: state })) : (!isOnlyTime && (_jsx("div", { ref: anchorRef, className: b('popup-anchor'), children: _jsx(Popup, Object.assign({ anchorRef: anchorRef }, popupProps, { children: _jsxs("div", { className: b('popup-content'), children: [typeof props.children === 'function' ? (props.children(calendarProps)) : (_jsx(Calendar, Object.assign({}, calendarProps))), state.hasTime && (_jsx("div", { className: b('time-field-wrapper'), children: _jsx(DateField, Object.assign({}, timeInputProps)) }))] }) })) }))), _jsx(TextInput, Object.assign({}, fieldProps, { className: b('field', { mobile: isMobile }), hasClear: !isMobile && fieldProps.hasClear, endContent: _jsxs(React.Fragment, { children: [!isMobile && !isOnlyTime && (_jsx(Button, Object.assign({}, calendarButtonProps, { children: _jsx(Icon, { data: CalendarIcon }) }))), !isMobile && isOnlyTime && (_jsx(StubButton, { size: calendarButtonProps.size, icon: ClockIcon })), isMobile && (_jsx(StubButton, { size: calendarButtonProps.size, icon: isOnlyTime ? ClockIcon : CalendarIcon }))] }) })), _jsx("input", { type: "text", hidden: true, name: props.name, value: state.value ? state.value.toISOString() : '',
22
+ // Ignore React warning
23
+ onChange: () => { } })] })));
22
24
  }
@@ -1,35 +1,10 @@
1
1
  .g-date-mobile-calendar {
2
- position: relative;
3
- display: inline-block;
4
- width: 24px;
5
- height: 24px;
6
- }
7
- .g-date-mobile-calendar_size_xs {
8
- width: 20px;
9
- height: 20px;
10
- }
11
- .g-date-mobile-calendar_size_m {
12
- width: 28px;
13
- height: 28px;
14
- }
15
- .g-date-mobile-calendar_size_l {
16
- width: 36px;
17
- height: 36px;
18
- }
19
- .g-date-mobile-calendar__button {
20
- position: absolute;
21
- inset: 0;
22
- display: flex;
23
- justify-content: center;
24
- align-items: center;
25
- }
26
- .g-date-mobile-calendar__input {
27
2
  position: absolute;
28
3
  z-index: 1;
29
- top: 0;
30
- left: 0;
4
+ inset-block-start: 0;
5
+ inset-inline-start: 0;
31
6
  box-sizing: border-box;
32
- width: 100%;
7
+ min-width: 100%;
33
8
  height: 100%;
34
9
  margin: 0;
35
10
  padding: 0;
@@ -37,11 +12,11 @@
37
12
  opacity: 0;
38
13
  border: none;
39
14
  }
40
- .g-date-mobile-calendar__input::-webkit-calendar-picker-indicator {
15
+ .g-date-mobile-calendar::-webkit-calendar-picker-indicator {
41
16
  position: absolute;
42
- top: 0;
43
- left: 0;
44
- width: 100%;
17
+ inset-block-start: 0;
18
+ inset-inline-start: 0;
19
+ min-width: 100%;
45
20
  height: 100%;
46
21
  margin: 0;
47
22
  padding: 0;
@@ -6,9 +6,4 @@ interface MobileCalendarProps {
6
6
  state: DatePickerState;
7
7
  }
8
8
  export declare function MobileCalendar({ props, state }: MobileCalendarProps): import("react/jsx-runtime").JSX.Element;
9
- interface MobileCalendarIconProps {
10
- props: DatePickerProps;
11
- state: DatePickerState;
12
- }
13
- export declare function MobileCalendarIcon({ props }: MobileCalendarIconProps): import("react/jsx-runtime").JSX.Element;
14
9
  export {};
@@ -1,13 +1,11 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { dateTime } from '@gravity-ui/date-utils';
3
- import { Calendar as CalendarIcon } from '@gravity-ui/icons';
4
- import { Icon } from '@gravity-ui/uikit';
5
3
  import { block } from '../../utils/cn';
6
4
  import { createPlaceholderValue, mergeDateTime } from '../utils/dates';
7
- import { getButtonSizeForInput } from '../utils/getButtonSizeForInput';
8
5
  import './MobileCalendar.css';
9
6
  const b = block('mobile-calendar');
10
7
  export function MobileCalendar({ props, state }) {
8
+ var _a, _b;
11
9
  let type = 'date';
12
10
  if (state.hasTime && state.hasDate) {
13
11
  type = 'datetime-local';
@@ -15,31 +13,35 @@ export function MobileCalendar({ props, state }) {
15
13
  else if (state.hasTime) {
16
14
  type = 'time';
17
15
  }
18
- return (_jsx("input", { className: b('input'), disabled: props.disabled, type: type, value: formatNative(state.value || props.placeholderValue, type), id: props.id, min: formatNative(props.minValue, type), max: formatNative(props.maxValue, type), tabIndex: -1, onChange: (e) => {
16
+ return (_jsx("input", { className: b(), disabled: props.disabled, type: type, value: formatNative(state.dateFieldState.displayValue, type), id: props.id, min: formatNative((_a = props.minValue) === null || _a === void 0 ? void 0 : _a.timeZone(state.timeZone), type), max: formatNative((_b = props.maxValue) === null || _b === void 0 ? void 0 : _b.timeZone(state.timeZone), type), tabIndex: -1, onChange: (e) => {
17
+ var _a, _b;
19
18
  if (props.readOnly) {
20
19
  return;
21
20
  }
22
21
  const newValue = e.target.value;
23
22
  if (newValue) {
24
- const localDate = dateTime({ input: newValue, format: getDateFormat(type) });
23
+ const localDate = dateTime({
24
+ input: newValue,
25
+ format: getDateFormat(type),
26
+ timeZone: 'system',
27
+ }).timeZone(state.timeZone, true);
25
28
  let newDate = state.hasDate
26
- ? dateTime({
27
- input: newValue,
28
- format: getDateFormat(type),
29
- timeZone: props.timeZone,
30
- })
29
+ ? localDate
31
30
  : createPlaceholderValue({
32
- placeholderValue: props.placeholderValue,
33
- timeZone: props.timeZone,
31
+ placeholderValue: (_a = props.placeholderValue) === null || _a === void 0 ? void 0 : _a.timeZone(state.timeZone),
32
+ timeZone: state.timeZone,
34
33
  });
35
34
  if (state.hasTime) {
36
35
  newDate = mergeDateTime(newDate, localDate);
37
36
  }
38
- else if (state.dateValue) {
39
- newDate = mergeDateTime(newDate, state.dateValue);
37
+ else if (state.value) {
38
+ newDate = mergeDateTime(newDate, state.value.timeZone(state.timeZone));
40
39
  }
41
40
  else {
42
- newDate = newDate.set('hours', 0).set('minutes', 0).set('seconds', 0);
41
+ newDate = mergeDateTime(newDate, createPlaceholderValue({
42
+ placeholderValue: (_b = props.placeholderValue) === null || _b === void 0 ? void 0 : _b.timeZone(state.timeZone),
43
+ timeZone: state.timeZone,
44
+ }));
43
45
  }
44
46
  state.setValue(newDate);
45
47
  }
@@ -48,9 +50,6 @@ export function MobileCalendar({ props, state }) {
48
50
  }
49
51
  } }));
50
52
  }
51
- export function MobileCalendarIcon({ props }) {
52
- return (_jsx("span", { className: b({ size: getButtonSizeForInput(props.size) }), children: _jsx("span", { className: b('button'), children: _jsx(Icon, { data: CalendarIcon }) }) }));
53
- }
54
53
  function getDateFormat(type) {
55
54
  switch (type) {
56
55
  case 'time': {
@@ -0,0 +1,26 @@
1
+ .g-date-stub-button {
2
+ position: relative;
3
+ display: inline-block;
4
+ width: 24px;
5
+ height: 24px;
6
+ }
7
+ .g-date-stub-button_size_xs {
8
+ width: 20px;
9
+ height: 20px;
10
+ }
11
+ .g-date-stub-button_size_m {
12
+ width: 28px;
13
+ height: 28px;
14
+ }
15
+ .g-date-stub-button_size_l {
16
+ width: 36px;
17
+ height: 36px;
18
+ }
19
+ .g-date-stub-button__icon {
20
+ position: absolute;
21
+ inset: 0;
22
+ display: flex;
23
+ justify-content: center;
24
+ align-items: center;
25
+ color: var(--g-color-text-secondary);
26
+ }
@@ -0,0 +1,8 @@
1
+ import type { ButtonSize, IconData } from '@gravity-ui/uikit';
2
+ import './StubButton.css';
3
+ interface StubButtonProps {
4
+ size?: ButtonSize;
5
+ icon: IconData;
6
+ }
7
+ export declare function StubButton({ size, icon }: StubButtonProps): import("react/jsx-runtime").JSX.Element;
8
+ export {};
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Icon } from '@gravity-ui/uikit';
3
+ import { block } from '../../utils/cn';
4
+ import './StubButton.css';
5
+ const b = block('stub-button');
6
+ export function StubButton({ size, icon }) {
7
+ return (_jsx("span", { className: b({ size }), children: _jsx("span", { className: b('icon'), children: _jsx(Icon, { data: icon }) }) }));
8
+ }
@@ -6,7 +6,6 @@ import { getButtonSizeForInput } from '../../utils/getButtonSizeForInput';
6
6
  import { mergeProps } from '../../utils/mergeProps';
7
7
  import { i18n } from '../i18n';
8
8
  export function useDatePickerProps(state, _a) {
9
- var _b;
10
9
  var { onFocus, onBlur } = _a, props = __rest(_a, ["onFocus", "onBlur"]);
11
10
  const [isActive, setActive] = React.useState(false);
12
11
  const { focusWithinProps } = useFocusWithin({
@@ -20,15 +19,6 @@ export function useDatePickerProps(state, _a) {
20
19
  },
21
20
  });
22
21
  const { inputProps } = useDateFieldProps(state.dateFieldState, props);
23
- let error;
24
- let validationState = props.validationState;
25
- if (validationState) {
26
- error = validationState === 'invalid' ? props.errorMessage || true : undefined;
27
- }
28
- else {
29
- validationState = state.dateFieldState.validationState;
30
- error = validationState === 'invalid';
31
- }
32
22
  const inputRef = React.useRef(null);
33
23
  const handleRef = useForkRef(inputRef, inputProps.controlRef);
34
24
  const calendarRef = React.useRef(null);
@@ -40,9 +30,10 @@ export function useDatePickerProps(state, _a) {
40
30
  (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
41
31
  });
42
32
  }
33
+ const onlyTime = state.hasTime && !state.hasDate;
43
34
  return {
44
35
  groupProps: Object.assign(Object.assign({ ref: groupRef, tabIndex: -1, role: 'group' }, focusWithinProps), { style: props.style, 'aria-disabled': state.disabled || undefined, onKeyDown: (e) => {
45
- if (e.altKey && (e.key === 'ArrowDown' || e.key === 'ArrowUp')) {
36
+ if (!onlyTime && e.altKey && (e.key === 'ArrowDown' || e.key === 'ArrowUp')) {
46
37
  e.preventDefault();
47
38
  e.stopPropagation();
48
39
  state.setOpen(true);
@@ -50,7 +41,7 @@ export function useDatePickerProps(state, _a) {
50
41
  } }),
51
42
  fieldProps: mergeProps(inputProps, state.dateFieldState.isEmpty && !isActive && props.placeholder
52
43
  ? { value: '' }
53
- : undefined, { controlRef: handleRef, error }),
44
+ : undefined, { controlRef: handleRef }),
54
45
  calendarButtonProps: {
55
46
  ref: calendarButtonRef,
56
47
  size: getButtonSizeForInput(props.size),
@@ -81,7 +72,6 @@ export function useDatePickerProps(state, _a) {
81
72
  focusInput();
82
73
  }
83
74
  },
84
- // @ts-expect-error focusTrap in popup was introduced in a newer version of uikit
85
75
  focusTrap: true,
86
76
  },
87
77
  calendarProps: {
@@ -96,20 +86,20 @@ export function useDatePickerProps(state, _a) {
96
86
  focusInput();
97
87
  }
98
88
  },
99
- defaultFocusedValue: (_b = state.dateValue) !== null && _b !== void 0 ? _b : undefined,
100
- value: state.dateValue,
89
+ value: state.dateFieldState.displayValue,
101
90
  minValue: props.minValue,
102
91
  maxValue: props.maxValue,
103
92
  isDateUnavailable: props.isDateUnavailable,
104
- timeZone: props.timeZone,
93
+ timeZone: state.timeZone,
105
94
  },
106
95
  timeInputProps: {
107
96
  value: state.timeValue,
97
+ placeholderValue: state.dateFieldState.displayValue,
108
98
  onUpdate: state.setTimeValue,
109
99
  format: state.timeFormat,
110
100
  readOnly: state.readOnly,
111
101
  disabled: state.disabled,
112
- timeZone: props.timeZone,
102
+ timeZone: state.timeZone,
113
103
  hasClear: props.hasClear,
114
104
  size: props.size,
115
105
  },
@@ -6,21 +6,21 @@ export interface DatePickerState {
6
6
  /** The currently selected date. */
7
7
  value: DateTime | null;
8
8
  /** Sets the selected date. */
9
- setValue(value: DateTime | null): void;
9
+ setValue: (value: DateTime | null) => void;
10
10
  /**
11
11
  * The date portion of the value. This may be set prior to `value` if the user has
12
12
  * selected a date but has not yet selected a time.
13
13
  */
14
14
  dateValue: DateTime | null;
15
15
  /** Sets the date portion of the value. */
16
- setDateValue(value: DateTime): void;
16
+ setDateValue: (value: DateTime) => void;
17
17
  /**
18
18
  * The time portion of the value. This may be set prior to `value` if the user has
19
19
  * selected a time but has not yet selected a date.
20
20
  */
21
21
  timeValue: DateTime | null;
22
22
  /** Sets the time portion of the value. */
23
- setTimeValue(value: DateTime | null): void;
23
+ setTimeValue: (value: DateTime | null) => void;
24
24
  /** Whether the field is read only. */
25
25
  readOnly?: boolean;
26
26
  /** Whether the field is disabled. */
@@ -33,10 +33,11 @@ export interface DatePickerState {
33
33
  hasTime: boolean;
34
34
  /** Format of the time when rendered in the input. */
35
35
  timeFormat?: string;
36
+ timeZone: string;
36
37
  /** Whether the calendar popover is currently open. */
37
38
  isOpen: boolean;
38
39
  /** Sets whether the calendar popover is open. */
39
- setOpen(isOpen: boolean): void;
40
+ setOpen: (isOpen: boolean) => void;
40
41
  dateFieldState: DateFieldState;
41
42
  }
42
43
  export interface DatePickerStateOptions extends DateFieldBase {
@@ -1,65 +1,74 @@
1
1
  import React from 'react';
2
+ import { useControlledState } from '@gravity-ui/uikit';
2
3
  import { useDateFieldState } from '../../DateField';
3
- import { splitFormatIntoSections } from '../../DateField/utils';
4
- import { useControlledState } from '../../hooks/useControlledState';
5
4
  import { createPlaceholderValue, mergeDateTime } from '../../utils/dates';
5
+ import { useDefaultTimeZone } from '../../utils/useDefaultTimeZone';
6
6
  export function useDatePickerState(props) {
7
+ var _a;
7
8
  const { disabled, readOnly } = props;
8
9
  const [isOpen, setOpen] = React.useState(false);
9
- const [value, setValue] = useControlledState(props.value, props.defaultValue, props.onUpdate);
10
+ const [value, setValue] = useControlledState(props.value, (_a = props.defaultValue) !== null && _a !== void 0 ? _a : null, props.onUpdate);
10
11
  const [selectedDateInner, setSelectedDate] = React.useState(null);
11
12
  const [selectedTimeInner, setSelectedTime] = React.useState(null);
13
+ const inputTimeZone = useDefaultTimeZone(props.value || props.defaultValue || props.placeholderValue);
14
+ const timeZone = props.timeZone || inputTimeZone;
12
15
  let selectedDate = selectedDateInner;
13
16
  let selectedTime = selectedTimeInner;
14
17
  const format = props.format || 'L';
15
- const { hasDate, hasTime, timeFormat } = React.useMemo(() => {
16
- const sections = splitFormatIntoSections(format);
17
- let hasDate = false;
18
- let hasHours = false;
19
- let hasMinutes = false;
20
- let hasSeconds = false;
21
- for (const s of sections) {
22
- hasHours || (hasHours = s.type === 'hour');
23
- hasMinutes || (hasMinutes = s.type === 'minute');
24
- hasSeconds || (hasSeconds = s.type === 'second');
25
- hasDate || (hasDate = ['day', 'month', 'year'].includes(s.type));
26
- }
27
- return {
28
- hasTime: hasHours || hasMinutes || hasSeconds,
29
- timeFormat: hasSeconds ? 'LTS' : 'LT',
30
- hasDate,
31
- };
32
- }, [format]);
33
- if (value) {
34
- selectedDate = value;
35
- if (hasTime) {
36
- selectedTime = value;
37
- }
38
- }
39
18
  const commitValue = (date, time) => {
40
19
  if (disabled || readOnly) {
41
20
  return;
42
21
  }
43
- setValue(mergeDateTime(date, time));
22
+ setValue(mergeDateTime(date, time).timeZone(inputTimeZone));
44
23
  setSelectedDate(null);
45
24
  setSelectedTime(null);
46
25
  };
26
+ const dateFieldState = useDateFieldState({
27
+ value,
28
+ onUpdate(date) {
29
+ if (date) {
30
+ commitValue(date, date);
31
+ }
32
+ else {
33
+ setValue(null);
34
+ }
35
+ },
36
+ disabled,
37
+ readOnly,
38
+ validationState: props.validationState,
39
+ minValue: props.minValue,
40
+ maxValue: props.maxValue,
41
+ isDateUnavailable: props.isDateUnavailable,
42
+ format,
43
+ placeholderValue: props.placeholderValue,
44
+ timeZone,
45
+ });
46
+ const timeFormat = React.useMemo(() => {
47
+ const hasSeconds = dateFieldState.sections.some((s) => s.type === 'second');
48
+ return hasSeconds ? 'LTS' : 'LT';
49
+ }, [dateFieldState.sections]);
50
+ if (value) {
51
+ selectedDate = value.timeZone(timeZone);
52
+ if (dateFieldState.hasTime) {
53
+ selectedTime = value.timeZone(timeZone);
54
+ }
55
+ }
47
56
  // Intercept setValue to make sure the Time section is not changed by date selection in Calendar
48
57
  const selectDate = (newValue) => {
49
58
  if (disabled || readOnly) {
50
59
  return;
51
60
  }
52
- const shouldClose = !hasTime;
53
- if (hasTime) {
61
+ const shouldClose = !dateFieldState.hasTime;
62
+ if (dateFieldState.hasTime) {
54
63
  if (selectedTime || shouldClose) {
55
- commitValue(newValue, selectedTime || getPlaceholderTime(props.placeholderValue, props.timeZone));
64
+ commitValue(newValue, selectedTime || newValue);
56
65
  }
57
66
  else {
58
67
  setSelectedDate(newValue);
59
68
  }
60
69
  }
61
70
  else {
62
- setValue(newValue);
71
+ commitValue(newValue, newValue);
63
72
  }
64
73
  if (shouldClose) {
65
74
  setOpen(false);
@@ -69,29 +78,33 @@ export function useDatePickerState(props) {
69
78
  if (disabled || readOnly) {
70
79
  return;
71
80
  }
81
+ const newTime = newValue !== null && newValue !== void 0 ? newValue : createPlaceholderValue({
82
+ placeholderValue: props.placeholderValue,
83
+ timeZone,
84
+ });
72
85
  if (selectedDate) {
73
- commitValue(selectedDate, newValue);
86
+ commitValue(selectedDate, newTime);
74
87
  }
75
88
  else {
76
- setSelectedTime(newValue);
89
+ setSelectedTime(newTime);
77
90
  }
78
91
  };
79
- const dateFieldState = useDateFieldState({
80
- value: value !== null && value !== void 0 ? value : null,
81
- onUpdate: setValue,
82
- disabled,
83
- readOnly,
84
- validationState: props.validationState,
85
- minValue: props.minValue,
86
- maxValue: props.maxValue,
87
- isDateUnavailable: props.isDateUnavailable,
88
- format,
89
- placeholderValue: props.placeholderValue,
90
- timeZone: props.timeZone,
91
- });
92
+ if (dateFieldState.hasTime && !selectedTime) {
93
+ selectedTime = dateFieldState.displayValue;
94
+ }
92
95
  return {
93
- value: value !== null && value !== void 0 ? value : null,
94
- setValue,
96
+ value,
97
+ setValue(newDate) {
98
+ if (props.readOnly || props.disabled) {
99
+ return;
100
+ }
101
+ if (newDate) {
102
+ setValue(newDate.timeZone(inputTimeZone));
103
+ }
104
+ else {
105
+ setValue(null);
106
+ }
107
+ },
95
108
  dateValue: selectedDate,
96
109
  timeValue: selectedTime,
97
110
  setDateValue: selectDate,
@@ -99,19 +112,21 @@ export function useDatePickerState(props) {
99
112
  disabled,
100
113
  readOnly,
101
114
  format,
102
- hasDate,
103
- hasTime,
115
+ hasDate: dateFieldState.hasDate,
116
+ hasTime: dateFieldState.hasTime,
104
117
  timeFormat,
118
+ timeZone,
105
119
  isOpen,
106
120
  setOpen(newIsOpen) {
107
- if (!newIsOpen && !value && selectedDate && hasTime) {
108
- commitValue(selectedDate, selectedTime || getPlaceholderTime(props.placeholderValue, props.timeZone));
121
+ if (!newIsOpen && !value && selectedDate && dateFieldState.hasTime) {
122
+ commitValue(selectedDate, selectedTime ||
123
+ createPlaceholderValue({
124
+ placeholderValue: props.placeholderValue,
125
+ timeZone: inputTimeZone,
126
+ }));
109
127
  }
110
128
  setOpen(newIsOpen);
111
129
  },
112
130
  dateFieldState,
113
131
  };
114
132
  }
115
- function getPlaceholderTime(placeholderValue, timeZone) {
116
- return createPlaceholderValue({ placeholderValue, timeZone });
117
- }