rn-grid-date-time-picker 1.0.0 → 1.2.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 (384) hide show
  1. package/CHANGELOG.md +86 -0
  2. package/README.md +100 -638
  3. package/lib/commonjs/adapters/utcMidnight.js +15 -6
  4. package/lib/commonjs/adapters/utcMidnight.js.map +1 -1
  5. package/lib/commonjs/components/DateTimePicker.js +484 -85
  6. package/lib/commonjs/components/DateTimePicker.js.map +1 -1
  7. package/lib/commonjs/components/calendar/Calendar.js +21 -7
  8. package/lib/commonjs/components/calendar/Calendar.js.map +1 -1
  9. package/lib/commonjs/components/calendar/CalendarHeader.js +46 -6
  10. package/lib/commonjs/components/calendar/CalendarHeader.js.map +1 -1
  11. package/lib/commonjs/components/calendar/CalendarSwitch.js +150 -0
  12. package/lib/commonjs/components/calendar/CalendarSwitch.js.map +1 -0
  13. package/lib/commonjs/components/calendar/DayCell.js +8 -3
  14. package/lib/commonjs/components/calendar/DayCell.js.map +1 -1
  15. package/lib/commonjs/components/calendar/DayGrid.js +13 -2
  16. package/lib/commonjs/components/calendar/DayGrid.js.map +1 -1
  17. package/lib/commonjs/components/calendar/PeriodGrid.js +3 -1
  18. package/lib/commonjs/components/calendar/PeriodGrid.js.map +1 -1
  19. package/lib/commonjs/components/calendar/calendarStyles.js +3 -2
  20. package/lib/commonjs/components/calendar/calendarStyles.js.map +1 -1
  21. package/lib/commonjs/components/calendar/localeNames.js +46 -24
  22. package/lib/commonjs/components/calendar/localeNames.js.map +1 -1
  23. package/lib/commonjs/components/calendar/selection.js +9 -1
  24. package/lib/commonjs/components/calendar/selection.js.map +1 -1
  25. package/lib/commonjs/components/container/DefaultSheet.js +42 -11
  26. package/lib/commonjs/components/container/DefaultSheet.js.map +1 -1
  27. package/lib/commonjs/components/container/PickerContainer.js +4 -0
  28. package/lib/commonjs/components/container/PickerContainer.js.map +1 -1
  29. package/lib/commonjs/components/container/PickerLayout.js +1 -1
  30. package/lib/commonjs/components/container/PickerLayout.js.map +1 -1
  31. package/lib/commonjs/components/container/containerStyles.js +12 -4
  32. package/lib/commonjs/components/container/containerStyles.js.map +1 -1
  33. package/lib/commonjs/components/field/RangeFields.js +5 -1
  34. package/lib/commonjs/components/field/RangeFields.js.map +1 -1
  35. package/lib/commonjs/components/field/SegmentedInput.js +8 -3
  36. package/lib/commonjs/components/field/SegmentedInput.js.map +1 -1
  37. package/lib/commonjs/components/field/ValueField.js +64 -8
  38. package/lib/commonjs/components/field/ValueField.js.map +1 -1
  39. package/lib/commonjs/components/field/fieldStyles.js +17 -0
  40. package/lib/commonjs/components/field/fieldStyles.js.map +1 -1
  41. package/lib/commonjs/components/field/fieldText.js +29 -13
  42. package/lib/commonjs/components/field/fieldText.js.map +1 -1
  43. package/lib/commonjs/components/hooks/useBottomInset.js +32 -0
  44. package/lib/commonjs/components/hooks/useBottomInset.js.map +1 -0
  45. package/lib/commonjs/components/hooks/useKeyboardFold.js +36 -13
  46. package/lib/commonjs/components/hooks/useKeyboardFold.js.map +1 -1
  47. package/lib/commonjs/components/hooks/useOpenPicker.js +39 -17
  48. package/lib/commonjs/components/hooks/useOpenPicker.js.map +1 -1
  49. package/lib/commonjs/components/hooks/useTypedSegments.js +6 -2
  50. package/lib/commonjs/components/hooks/useTypedSegments.js.map +1 -1
  51. package/lib/commonjs/components/theme/defaultStrings.js +13 -3
  52. package/lib/commonjs/components/theme/defaultStrings.js.map +1 -1
  53. package/lib/commonjs/components/theme/direction.js +17 -0
  54. package/lib/commonjs/components/theme/direction.js.map +1 -0
  55. package/lib/commonjs/components/theme/numerals.js +16 -0
  56. package/lib/commonjs/components/theme/numerals.js.map +1 -0
  57. package/lib/commonjs/components/theme/styleKeys.js +10 -2
  58. package/lib/commonjs/components/theme/styleKeys.js.map +1 -1
  59. package/lib/commonjs/components/theme/tokens.js +4 -0
  60. package/lib/commonjs/components/theme/tokens.js.map +1 -1
  61. package/lib/commonjs/components/time/TimeRow.js +10 -2
  62. package/lib/commonjs/components/time/TimeRow.js.map +1 -1
  63. package/lib/commonjs/components/time/TypedTime.js +3 -1
  64. package/lib/commonjs/components/time/TypedTime.js.map +1 -1
  65. package/lib/commonjs/components/time/Wheel.js +20 -3
  66. package/lib/commonjs/components/time/Wheel.js.map +1 -1
  67. package/lib/commonjs/components/time/timeStyles.js +4 -5
  68. package/lib/commonjs/components/time/timeStyles.js.map +1 -1
  69. package/lib/commonjs/components/types.js +10 -0
  70. package/lib/commonjs/components/types.js.map +1 -1
  71. package/lib/commonjs/core/calendarSystem.js +123 -22
  72. package/lib/commonjs/core/calendarSystem.js.map +1 -1
  73. package/lib/commonjs/core/digits.js +25 -0
  74. package/lib/commonjs/core/digits.js.map +1 -0
  75. package/lib/commonjs/core/draft.js +31 -10
  76. package/lib/commonjs/core/draft.js.map +1 -1
  77. package/lib/commonjs/core/locale.js +20 -4
  78. package/lib/commonjs/core/locale.js.map +1 -1
  79. package/lib/commonjs/core/numerals.js +46 -0
  80. package/lib/commonjs/core/numerals.js.map +1 -0
  81. package/lib/commonjs/core/segmentEditor.js +9 -0
  82. package/lib/commonjs/core/segmentEditor.js.map +1 -1
  83. package/lib/commonjs/core/segments.js +2 -11
  84. package/lib/commonjs/core/segments.js.map +1 -1
  85. package/lib/commonjs/core/selectionRules.js +2 -1
  86. package/lib/commonjs/core/selectionRules.js.map +1 -1
  87. package/lib/commonjs/core/timeEntry.js +7 -91
  88. package/lib/commonjs/core/timeEntry.js.map +1 -1
  89. package/lib/commonjs/icons/index.js +5 -1
  90. package/lib/commonjs/icons/index.js.map +1 -1
  91. package/lib/commonjs/index.js +20 -0
  92. package/lib/commonjs/index.js.map +1 -1
  93. package/lib/module/adapters/utcMidnight.js +14 -5
  94. package/lib/module/adapters/utcMidnight.js.map +1 -1
  95. package/lib/module/components/DateTimePicker.js +490 -91
  96. package/lib/module/components/DateTimePicker.js.map +1 -1
  97. package/lib/module/components/calendar/Calendar.js +25 -11
  98. package/lib/module/components/calendar/Calendar.js.map +1 -1
  99. package/lib/module/components/calendar/CalendarHeader.js +47 -7
  100. package/lib/module/components/calendar/CalendarHeader.js.map +1 -1
  101. package/lib/module/components/calendar/CalendarSwitch.js +145 -0
  102. package/lib/module/components/calendar/CalendarSwitch.js.map +1 -0
  103. package/lib/module/components/calendar/DayCell.js +8 -3
  104. package/lib/module/components/calendar/DayCell.js.map +1 -1
  105. package/lib/module/components/calendar/DayGrid.js +14 -3
  106. package/lib/module/components/calendar/DayGrid.js.map +1 -1
  107. package/lib/module/components/calendar/PeriodGrid.js +3 -1
  108. package/lib/module/components/calendar/PeriodGrid.js.map +1 -1
  109. package/lib/module/components/calendar/calendarStyles.js +3 -2
  110. package/lib/module/components/calendar/calendarStyles.js.map +1 -1
  111. package/lib/module/components/calendar/localeNames.js +46 -24
  112. package/lib/module/components/calendar/localeNames.js.map +1 -1
  113. package/lib/module/components/calendar/selection.js +7 -0
  114. package/lib/module/components/calendar/selection.js.map +1 -1
  115. package/lib/module/components/container/DefaultSheet.js +42 -12
  116. package/lib/module/components/container/DefaultSheet.js.map +1 -1
  117. package/lib/module/components/container/PickerContainer.js +4 -0
  118. package/lib/module/components/container/PickerContainer.js.map +1 -1
  119. package/lib/module/components/container/PickerLayout.js +1 -1
  120. package/lib/module/components/container/PickerLayout.js.map +1 -1
  121. package/lib/module/components/container/containerStyles.js +11 -3
  122. package/lib/module/components/container/containerStyles.js.map +1 -1
  123. package/lib/module/components/field/RangeFields.js +5 -1
  124. package/lib/module/components/field/RangeFields.js.map +1 -1
  125. package/lib/module/components/field/SegmentedInput.js +8 -3
  126. package/lib/module/components/field/SegmentedInput.js.map +1 -1
  127. package/lib/module/components/field/ValueField.js +66 -10
  128. package/lib/module/components/field/ValueField.js.map +1 -1
  129. package/lib/module/components/field/fieldStyles.js +17 -0
  130. package/lib/module/components/field/fieldStyles.js.map +1 -1
  131. package/lib/module/components/field/fieldText.js +28 -11
  132. package/lib/module/components/field/fieldText.js.map +1 -1
  133. package/lib/module/components/hooks/useBottomInset.js +27 -0
  134. package/lib/module/components/hooks/useBottomInset.js.map +1 -0
  135. package/lib/module/components/hooks/useKeyboardFold.js +33 -12
  136. package/lib/module/components/hooks/useKeyboardFold.js.map +1 -1
  137. package/lib/module/components/hooks/useOpenPicker.js +39 -17
  138. package/lib/module/components/hooks/useOpenPicker.js.map +1 -1
  139. package/lib/module/components/hooks/useTypedSegments.js +6 -2
  140. package/lib/module/components/hooks/useTypedSegments.js.map +1 -1
  141. package/lib/module/components/theme/defaultStrings.js +11 -2
  142. package/lib/module/components/theme/defaultStrings.js.map +1 -1
  143. package/lib/module/components/theme/direction.js +13 -0
  144. package/lib/module/components/theme/direction.js.map +1 -0
  145. package/lib/module/components/theme/numerals.js +12 -0
  146. package/lib/module/components/theme/numerals.js.map +1 -0
  147. package/lib/module/components/theme/styleKeys.js +10 -2
  148. package/lib/module/components/theme/styleKeys.js.map +1 -1
  149. package/lib/module/components/theme/tokens.js +4 -0
  150. package/lib/module/components/theme/tokens.js.map +1 -1
  151. package/lib/module/components/time/TimeRow.js +11 -3
  152. package/lib/module/components/time/TimeRow.js.map +1 -1
  153. package/lib/module/components/time/TypedTime.js +3 -1
  154. package/lib/module/components/time/TypedTime.js.map +1 -1
  155. package/lib/module/components/time/Wheel.js +18 -2
  156. package/lib/module/components/time/Wheel.js.map +1 -1
  157. package/lib/module/components/time/timeStyles.js +4 -5
  158. package/lib/module/components/time/timeStyles.js.map +1 -1
  159. package/lib/module/components/types.js +10 -0
  160. package/lib/module/components/types.js.map +1 -1
  161. package/lib/module/core/calendarSystem.js +118 -19
  162. package/lib/module/core/calendarSystem.js.map +1 -1
  163. package/lib/module/core/digits.js +20 -0
  164. package/lib/module/core/digits.js.map +1 -0
  165. package/lib/module/core/draft.js +29 -9
  166. package/lib/module/core/draft.js.map +1 -1
  167. package/lib/module/core/locale.js +18 -3
  168. package/lib/module/core/locale.js.map +1 -1
  169. package/lib/module/core/numerals.js +39 -0
  170. package/lib/module/core/numerals.js.map +1 -0
  171. package/lib/module/core/segmentEditor.js +9 -0
  172. package/lib/module/core/segmentEditor.js.map +1 -1
  173. package/lib/module/core/segments.js +0 -8
  174. package/lib/module/core/segments.js.map +1 -1
  175. package/lib/module/core/selectionRules.js +2 -1
  176. package/lib/module/core/selectionRules.js.map +1 -1
  177. package/lib/module/core/timeEntry.js +7 -89
  178. package/lib/module/core/timeEntry.js.map +1 -1
  179. package/lib/module/icons/index.js +5 -1
  180. package/lib/module/icons/index.js.map +1 -1
  181. package/lib/module/index.js +2 -0
  182. package/lib/module/index.js.map +1 -1
  183. package/lib/typescript/commonjs/src/adapters/utcMidnight.d.ts.map +1 -1
  184. package/lib/typescript/commonjs/src/components/DateTimePicker.d.ts.map +1 -1
  185. package/lib/typescript/commonjs/src/components/calendar/Calendar.d.ts +8 -4
  186. package/lib/typescript/commonjs/src/components/calendar/Calendar.d.ts.map +1 -1
  187. package/lib/typescript/commonjs/src/components/calendar/CalendarHeader.d.ts.map +1 -1
  188. package/lib/typescript/commonjs/src/components/calendar/CalendarSwitch.d.ts +26 -0
  189. package/lib/typescript/commonjs/src/components/calendar/CalendarSwitch.d.ts.map +1 -0
  190. package/lib/typescript/commonjs/src/components/calendar/DayCell.d.ts +1 -1
  191. package/lib/typescript/commonjs/src/components/calendar/DayCell.d.ts.map +1 -1
  192. package/lib/typescript/commonjs/src/components/calendar/DayGrid.d.ts +2 -0
  193. package/lib/typescript/commonjs/src/components/calendar/DayGrid.d.ts.map +1 -1
  194. package/lib/typescript/commonjs/src/components/calendar/PeriodGrid.d.ts.map +1 -1
  195. package/lib/typescript/commonjs/src/components/calendar/calendarStyles.d.ts +1 -1
  196. package/lib/typescript/commonjs/src/components/calendar/calendarStyles.d.ts.map +1 -1
  197. package/lib/typescript/commonjs/src/components/calendar/localeNames.d.ts +8 -3
  198. package/lib/typescript/commonjs/src/components/calendar/localeNames.d.ts.map +1 -1
  199. package/lib/typescript/commonjs/src/components/calendar/selection.d.ts +2 -0
  200. package/lib/typescript/commonjs/src/components/calendar/selection.d.ts.map +1 -1
  201. package/lib/typescript/commonjs/src/components/container/DefaultSheet.d.ts +10 -2
  202. package/lib/typescript/commonjs/src/components/container/DefaultSheet.d.ts.map +1 -1
  203. package/lib/typescript/commonjs/src/components/container/PickerContainer.d.ts.map +1 -1
  204. package/lib/typescript/commonjs/src/components/container/containerStyles.d.ts +6 -0
  205. package/lib/typescript/commonjs/src/components/container/containerStyles.d.ts.map +1 -1
  206. package/lib/typescript/commonjs/src/components/field/RangeFields.d.ts +5 -0
  207. package/lib/typescript/commonjs/src/components/field/RangeFields.d.ts.map +1 -1
  208. package/lib/typescript/commonjs/src/components/field/SegmentedInput.d.ts.map +1 -1
  209. package/lib/typescript/commonjs/src/components/field/ValueField.d.ts +7 -0
  210. package/lib/typescript/commonjs/src/components/field/ValueField.d.ts.map +1 -1
  211. package/lib/typescript/commonjs/src/components/field/fieldStyles.d.ts +15 -0
  212. package/lib/typescript/commonjs/src/components/field/fieldStyles.d.ts.map +1 -1
  213. package/lib/typescript/commonjs/src/components/field/fieldText.d.ts +14 -5
  214. package/lib/typescript/commonjs/src/components/field/fieldText.d.ts.map +1 -1
  215. package/lib/typescript/commonjs/src/components/hooks/useBottomInset.d.ts +8 -0
  216. package/lib/typescript/commonjs/src/components/hooks/useBottomInset.d.ts.map +1 -0
  217. package/lib/typescript/commonjs/src/components/hooks/useKeyboardFold.d.ts +10 -2
  218. package/lib/typescript/commonjs/src/components/hooks/useKeyboardFold.d.ts.map +1 -1
  219. package/lib/typescript/commonjs/src/components/hooks/useOpenPicker.d.ts +2 -1
  220. package/lib/typescript/commonjs/src/components/hooks/useOpenPicker.d.ts.map +1 -1
  221. package/lib/typescript/commonjs/src/components/hooks/useTypedSegments.d.ts +3 -2
  222. package/lib/typescript/commonjs/src/components/hooks/useTypedSegments.d.ts.map +1 -1
  223. package/lib/typescript/commonjs/src/components/theme/defaultStrings.d.ts +13 -2
  224. package/lib/typescript/commonjs/src/components/theme/defaultStrings.d.ts.map +1 -1
  225. package/lib/typescript/commonjs/src/components/theme/direction.d.ts +8 -0
  226. package/lib/typescript/commonjs/src/components/theme/direction.d.ts.map +1 -0
  227. package/lib/typescript/commonjs/src/components/theme/numerals.d.ts +7 -0
  228. package/lib/typescript/commonjs/src/components/theme/numerals.d.ts.map +1 -0
  229. package/lib/typescript/commonjs/src/components/theme/styleKeys.d.ts +1 -1
  230. package/lib/typescript/commonjs/src/components/theme/styleKeys.d.ts.map +1 -1
  231. package/lib/typescript/commonjs/src/components/theme/tokens.d.ts +3 -1
  232. package/lib/typescript/commonjs/src/components/theme/tokens.d.ts.map +1 -1
  233. package/lib/typescript/commonjs/src/components/time/TimeRow.d.ts.map +1 -1
  234. package/lib/typescript/commonjs/src/components/time/TypedTime.d.ts.map +1 -1
  235. package/lib/typescript/commonjs/src/components/time/Wheel.d.ts +5 -0
  236. package/lib/typescript/commonjs/src/components/time/Wheel.d.ts.map +1 -1
  237. package/lib/typescript/commonjs/src/components/time/timeStyles.d.ts +0 -2
  238. package/lib/typescript/commonjs/src/components/time/timeStyles.d.ts.map +1 -1
  239. package/lib/typescript/commonjs/src/components/types.d.ts +84 -4
  240. package/lib/typescript/commonjs/src/components/types.d.ts.map +1 -1
  241. package/lib/typescript/commonjs/src/core/calendarSystem.d.ts +20 -5
  242. package/lib/typescript/commonjs/src/core/calendarSystem.d.ts.map +1 -1
  243. package/lib/typescript/commonjs/src/core/digits.d.ts +3 -0
  244. package/lib/typescript/commonjs/src/core/digits.d.ts.map +1 -0
  245. package/lib/typescript/commonjs/src/core/draft.d.ts +12 -1
  246. package/lib/typescript/commonjs/src/core/draft.d.ts.map +1 -1
  247. package/lib/typescript/commonjs/src/core/locale.d.ts +6 -0
  248. package/lib/typescript/commonjs/src/core/locale.d.ts.map +1 -1
  249. package/lib/typescript/commonjs/src/core/numerals.d.ts +15 -0
  250. package/lib/typescript/commonjs/src/core/numerals.d.ts.map +1 -0
  251. package/lib/typescript/commonjs/src/core/segmentEditor.d.ts.map +1 -1
  252. package/lib/typescript/commonjs/src/core/segments.d.ts +0 -2
  253. package/lib/typescript/commonjs/src/core/segments.d.ts.map +1 -1
  254. package/lib/typescript/commonjs/src/core/selectionRules.d.ts +3 -2
  255. package/lib/typescript/commonjs/src/core/selectionRules.d.ts.map +1 -1
  256. package/lib/typescript/commonjs/src/core/timeEntry.d.ts +4 -24
  257. package/lib/typescript/commonjs/src/core/timeEntry.d.ts.map +1 -1
  258. package/lib/typescript/commonjs/src/icons/index.d.ts.map +1 -1
  259. package/lib/typescript/commonjs/src/index.d.ts +7 -3
  260. package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
  261. package/lib/typescript/module/src/adapters/utcMidnight.d.ts.map +1 -1
  262. package/lib/typescript/module/src/components/DateTimePicker.d.ts.map +1 -1
  263. package/lib/typescript/module/src/components/calendar/Calendar.d.ts +8 -4
  264. package/lib/typescript/module/src/components/calendar/Calendar.d.ts.map +1 -1
  265. package/lib/typescript/module/src/components/calendar/CalendarHeader.d.ts.map +1 -1
  266. package/lib/typescript/module/src/components/calendar/CalendarSwitch.d.ts +26 -0
  267. package/lib/typescript/module/src/components/calendar/CalendarSwitch.d.ts.map +1 -0
  268. package/lib/typescript/module/src/components/calendar/DayCell.d.ts +1 -1
  269. package/lib/typescript/module/src/components/calendar/DayCell.d.ts.map +1 -1
  270. package/lib/typescript/module/src/components/calendar/DayGrid.d.ts +2 -0
  271. package/lib/typescript/module/src/components/calendar/DayGrid.d.ts.map +1 -1
  272. package/lib/typescript/module/src/components/calendar/PeriodGrid.d.ts.map +1 -1
  273. package/lib/typescript/module/src/components/calendar/calendarStyles.d.ts +1 -1
  274. package/lib/typescript/module/src/components/calendar/calendarStyles.d.ts.map +1 -1
  275. package/lib/typescript/module/src/components/calendar/localeNames.d.ts +8 -3
  276. package/lib/typescript/module/src/components/calendar/localeNames.d.ts.map +1 -1
  277. package/lib/typescript/module/src/components/calendar/selection.d.ts +2 -0
  278. package/lib/typescript/module/src/components/calendar/selection.d.ts.map +1 -1
  279. package/lib/typescript/module/src/components/container/DefaultSheet.d.ts +10 -2
  280. package/lib/typescript/module/src/components/container/DefaultSheet.d.ts.map +1 -1
  281. package/lib/typescript/module/src/components/container/PickerContainer.d.ts.map +1 -1
  282. package/lib/typescript/module/src/components/container/containerStyles.d.ts +6 -0
  283. package/lib/typescript/module/src/components/container/containerStyles.d.ts.map +1 -1
  284. package/lib/typescript/module/src/components/field/RangeFields.d.ts +5 -0
  285. package/lib/typescript/module/src/components/field/RangeFields.d.ts.map +1 -1
  286. package/lib/typescript/module/src/components/field/SegmentedInput.d.ts.map +1 -1
  287. package/lib/typescript/module/src/components/field/ValueField.d.ts +7 -0
  288. package/lib/typescript/module/src/components/field/ValueField.d.ts.map +1 -1
  289. package/lib/typescript/module/src/components/field/fieldStyles.d.ts +15 -0
  290. package/lib/typescript/module/src/components/field/fieldStyles.d.ts.map +1 -1
  291. package/lib/typescript/module/src/components/field/fieldText.d.ts +14 -5
  292. package/lib/typescript/module/src/components/field/fieldText.d.ts.map +1 -1
  293. package/lib/typescript/module/src/components/hooks/useBottomInset.d.ts +8 -0
  294. package/lib/typescript/module/src/components/hooks/useBottomInset.d.ts.map +1 -0
  295. package/lib/typescript/module/src/components/hooks/useKeyboardFold.d.ts +10 -2
  296. package/lib/typescript/module/src/components/hooks/useKeyboardFold.d.ts.map +1 -1
  297. package/lib/typescript/module/src/components/hooks/useOpenPicker.d.ts +2 -1
  298. package/lib/typescript/module/src/components/hooks/useOpenPicker.d.ts.map +1 -1
  299. package/lib/typescript/module/src/components/hooks/useTypedSegments.d.ts +3 -2
  300. package/lib/typescript/module/src/components/hooks/useTypedSegments.d.ts.map +1 -1
  301. package/lib/typescript/module/src/components/theme/defaultStrings.d.ts +13 -2
  302. package/lib/typescript/module/src/components/theme/defaultStrings.d.ts.map +1 -1
  303. package/lib/typescript/module/src/components/theme/direction.d.ts +8 -0
  304. package/lib/typescript/module/src/components/theme/direction.d.ts.map +1 -0
  305. package/lib/typescript/module/src/components/theme/numerals.d.ts +7 -0
  306. package/lib/typescript/module/src/components/theme/numerals.d.ts.map +1 -0
  307. package/lib/typescript/module/src/components/theme/styleKeys.d.ts +1 -1
  308. package/lib/typescript/module/src/components/theme/styleKeys.d.ts.map +1 -1
  309. package/lib/typescript/module/src/components/theme/tokens.d.ts +3 -1
  310. package/lib/typescript/module/src/components/theme/tokens.d.ts.map +1 -1
  311. package/lib/typescript/module/src/components/time/TimeRow.d.ts.map +1 -1
  312. package/lib/typescript/module/src/components/time/TypedTime.d.ts.map +1 -1
  313. package/lib/typescript/module/src/components/time/Wheel.d.ts +5 -0
  314. package/lib/typescript/module/src/components/time/Wheel.d.ts.map +1 -1
  315. package/lib/typescript/module/src/components/time/timeStyles.d.ts +0 -2
  316. package/lib/typescript/module/src/components/time/timeStyles.d.ts.map +1 -1
  317. package/lib/typescript/module/src/components/types.d.ts +84 -4
  318. package/lib/typescript/module/src/components/types.d.ts.map +1 -1
  319. package/lib/typescript/module/src/core/calendarSystem.d.ts +20 -5
  320. package/lib/typescript/module/src/core/calendarSystem.d.ts.map +1 -1
  321. package/lib/typescript/module/src/core/digits.d.ts +3 -0
  322. package/lib/typescript/module/src/core/digits.d.ts.map +1 -0
  323. package/lib/typescript/module/src/core/draft.d.ts +12 -1
  324. package/lib/typescript/module/src/core/draft.d.ts.map +1 -1
  325. package/lib/typescript/module/src/core/locale.d.ts +6 -0
  326. package/lib/typescript/module/src/core/locale.d.ts.map +1 -1
  327. package/lib/typescript/module/src/core/numerals.d.ts +15 -0
  328. package/lib/typescript/module/src/core/numerals.d.ts.map +1 -0
  329. package/lib/typescript/module/src/core/segmentEditor.d.ts.map +1 -1
  330. package/lib/typescript/module/src/core/segments.d.ts +0 -2
  331. package/lib/typescript/module/src/core/segments.d.ts.map +1 -1
  332. package/lib/typescript/module/src/core/selectionRules.d.ts +3 -2
  333. package/lib/typescript/module/src/core/selectionRules.d.ts.map +1 -1
  334. package/lib/typescript/module/src/core/timeEntry.d.ts +4 -24
  335. package/lib/typescript/module/src/core/timeEntry.d.ts.map +1 -1
  336. package/lib/typescript/module/src/icons/index.d.ts.map +1 -1
  337. package/lib/typescript/module/src/index.d.ts +7 -3
  338. package/lib/typescript/module/src/index.d.ts.map +1 -1
  339. package/package.json +22 -7
  340. package/src/adapters/utcMidnight.ts +14 -5
  341. package/src/components/DateTimePicker.tsx +607 -108
  342. package/src/components/calendar/Calendar.tsx +54 -16
  343. package/src/components/calendar/CalendarHeader.tsx +41 -9
  344. package/src/components/calendar/CalendarSwitch.tsx +170 -0
  345. package/src/components/calendar/DayCell.tsx +16 -4
  346. package/src/components/calendar/DayGrid.tsx +18 -3
  347. package/src/components/calendar/PeriodGrid.tsx +3 -1
  348. package/src/components/calendar/calendarStyles.ts +3 -2
  349. package/src/components/calendar/localeNames.ts +52 -22
  350. package/src/components/calendar/selection.ts +8 -0
  351. package/src/components/container/DefaultSheet.tsx +60 -14
  352. package/src/components/container/PickerContainer.tsx +4 -0
  353. package/src/components/container/PickerLayout.tsx +1 -1
  354. package/src/components/container/containerStyles.ts +12 -3
  355. package/src/components/field/RangeFields.tsx +12 -2
  356. package/src/components/field/SegmentedInput.tsx +8 -3
  357. package/src/components/field/ValueField.tsx +94 -18
  358. package/src/components/field/fieldStyles.ts +6 -0
  359. package/src/components/field/fieldText.ts +68 -15
  360. package/src/components/hooks/useBottomInset.ts +33 -0
  361. package/src/components/hooks/useKeyboardFold.ts +41 -13
  362. package/src/components/hooks/useOpenPicker.ts +41 -18
  363. package/src/components/hooks/useTypedSegments.ts +7 -3
  364. package/src/components/theme/defaultStrings.ts +29 -4
  365. package/src/components/theme/direction.ts +12 -0
  366. package/src/components/theme/numerals.ts +11 -0
  367. package/src/components/theme/styleKeys.ts +18 -1
  368. package/src/components/theme/tokens.ts +5 -1
  369. package/src/components/time/TimeRow.tsx +23 -3
  370. package/src/components/time/TypedTime.tsx +3 -1
  371. package/src/components/time/Wheel.tsx +19 -5
  372. package/src/components/time/timeStyles.ts +2 -3
  373. package/src/components/types.ts +86 -4
  374. package/src/core/calendarSystem.ts +145 -21
  375. package/src/core/digits.ts +21 -0
  376. package/src/core/draft.ts +41 -13
  377. package/src/core/locale.ts +20 -3
  378. package/src/core/numerals.ts +35 -0
  379. package/src/core/segmentEditor.ts +13 -0
  380. package/src/core/segments.ts +0 -8
  381. package/src/core/selectionRules.ts +3 -2
  382. package/src/core/timeEntry.ts +6 -96
  383. package/src/icons/index.tsx +3 -1
  384. package/src/index.tsx +12 -2
@@ -6,16 +6,22 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = void 0;
7
7
  var _react = _interopRequireWildcard(require("react"));
8
8
  var _luxon = require("luxon");
9
+ var _reactNative = require("react-native");
9
10
  var _index = require("../adapters/index.js");
10
11
  var _calendarDate = require("../core/calendarDate.js");
11
12
  var _constraints = require("../core/constraints.js");
12
13
  var _draft = require("../core/draft.js");
13
14
  var _calendarSystem = require("../core/calendarSystem.js");
14
15
  var _locale = require("../core/locale.js");
16
+ var _numerals = require("../core/numerals.js");
15
17
  var _selectionRules = require("../core/selectionRules.js");
16
18
  var _timeEntry = require("../core/timeEntry.js");
17
19
  var _Calendar = _interopRequireDefault(require("./calendar/Calendar.js"));
20
+ var _CalendarSwitch = _interopRequireDefault(require("./calendar/CalendarSwitch.js"));
18
21
  var _localeNames = require("./calendar/localeNames.js");
22
+ var _direction = require("./theme/direction.js");
23
+ var _numerals2 = require("./theme/numerals.js");
24
+ var _selection = require("./calendar/selection.js");
19
25
  var _PickerContainer = _interopRequireDefault(require("./container/PickerContainer.js"));
20
26
  var _fieldText = require("./field/fieldText.js");
21
27
  var _FieldMessages = _interopRequireDefault(require("./field/FieldMessages.js"));
@@ -34,10 +40,36 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
34
40
  var cache;
35
41
  function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var r, c, a = Object.defineProperty, n = { __proto__: null, default: e }; if (Object(e) !== e) return n; if (cache || "function" != typeof WeakMap || (cache = new WeakMap()), cache) { if (cache.has(e)) return cache.get(e); cache.set(e, n); } for (c in e) "default" !== c && {}.hasOwnProperty.call(e, c) && ((r = a && Object.getOwnPropertyDescriptor(e, c)) && (r.get || r.set) ? a(n, c, r) : n[c] = e[c]); return n; }
36
42
  /** Same day and time (or both without a time). */const sameValue = (a, b) => (0, _calendarDate.isSameDay)(a.date, b.date) && (a.time?.hour ?? -1) === (b.time?.hour ?? -1) && (a.time?.minute ?? -1) === (b.time?.minute ?? -1);
43
+ const ALL_SYSTEMS = ['gregory', 'hijri', 'dual'];
44
+ const RTL = {
45
+ direction: 'rtl'
46
+ };
47
+
48
+ /** The same kind of selection with nothing in it. */
49
+ const emptySelection = sel => sel.kind === 'single' ? {
50
+ kind: 'single',
51
+ day: null
52
+ } : sel.kind === 'range' ? {
53
+ kind: 'range',
54
+ from: null,
55
+ to: null
56
+ } : {
57
+ ...sel,
58
+ days: []
59
+ };
37
60
 
38
61
  /** Minute steps that divide the hour. */
39
62
  const MINUTE_STEPS = [1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30, 60];
40
63
 
64
+ /** A folded calendar stays mounted, so it comes back on the month and view it showed. */
65
+ const FOLDED = {
66
+ display: 'none'
67
+ };
68
+
69
+ /** The later / earlier of a limit and a bound; the bound when there's no limit. */
70
+ const later = (a, b) => a && (0, _calendarDate.compareCalendarDates)(a, b) > 0 ? a : b;
71
+ const earlier = (a, b) => a && (0, _calendarDate.compareCalendarDates)(a, b) < 0 ? a : b;
72
+
41
73
  /**
42
74
  * A date & time picker: a value field that opens a sheet (or an inline panel)
43
75
  * with a calendar and, for date-time values, a time row. Single, range and
@@ -77,6 +109,7 @@ const DateTimePicker = props => {
77
109
  disabled = false,
78
110
  readOnly = false,
79
111
  allowTyping,
112
+ hideCalendarOnKeyboard = true,
80
113
  allowFieldTyping,
81
114
  allowClear,
82
115
  errorMessage,
@@ -108,6 +141,11 @@ const DateTimePicker = props => {
108
141
  initialVisibleDate,
109
142
  enableMonthSwipe = true,
110
143
  calendarSystem,
144
+ calendarSwitch,
145
+ onCalendarSystemChange,
146
+ dualDefaultTab = 'gregory',
147
+ hijriLocale = 'ar-SA',
148
+ renderCalendarSwitch,
111
149
  showToday = false,
112
150
  showHolidays = true,
113
151
  onVisibleMonthChange,
@@ -115,6 +153,7 @@ const DateTimePicker = props => {
115
153
  validate,
116
154
  yearRange: yearRangeProp = _types.DEFAULT_YEAR_RANGE,
117
155
  locale,
156
+ numerals: numeralsProp,
118
157
  timeZone,
119
158
  now,
120
159
  timeFormat: timeFormatProp,
@@ -134,6 +173,7 @@ const DateTimePicker = props => {
134
173
  theme,
135
174
  styles,
136
175
  strings: stringOverrides,
176
+ hijriStrings: hijriOverrides,
137
177
  testID
138
178
  } = props;
139
179
  const tokens = (0, _react.useMemo)(() => (0, _tokens.buildTokens)(theme),
@@ -144,6 +184,69 @@ const DateTimePicker = props => {
144
184
  const firstDayOfWeek = firstDayProp ?? (0, _locale.deriveFirstDayOfWeek)(loc);
145
185
  // Month and year picks are for single dates only.
146
186
  const precision = type === 'date' && mode === 'single' ? precisionProp : 'day';
187
+ // The calendars the switch offers: none for month and year picks (always
188
+ // Gregorian), or when the platform has no Hijri calendar.
189
+ const switchKey = Array.isArray(calendarSwitch) ? calendarSwitch.join(',') : String(!!calendarSwitch);
190
+ const switchSystems = (0, _react.useMemo)(() => {
191
+ if (!calendarSwitch || precision !== 'day' || !(0, _calendarSystem.isHijriSupported)()) return null;
192
+ const list = calendarSwitch === true ? ALL_SYSTEMS : ALL_SYSTEMS.filter(x => calendarSwitch.includes(x)).sort((a, b) => calendarSwitch.indexOf(a) - calendarSwitch.indexOf(b));
193
+ return list.length > 1 ? list : null;
194
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- the list is compared by content
195
+ }, [switchKey, precision]);
196
+ const startSystem = () => {
197
+ const wanted = calendarSystem ?? 'gregory';
198
+ return switchSystems && !switchSystems.includes(wanted) ? switchSystems[0] ?? wanted : wanted;
199
+ };
200
+ // The switch changes this; a new calendarSystem prop starts over from it.
201
+ const [chosenSystem, setChosenSystem] = (0, _react.useState)(startSystem);
202
+ // The calendar the props open on, which a value from outside counts as
203
+ // picked in. The switch's own choice coming back as the calendarSystem prop
204
+ // (onCalendarSystemChange={setSystem}) isn't a new one.
205
+ const [openedOn, setOpenedOn] = (0, _react.useState)(startSystem);
206
+ const echo = (0, _react.useRef)(null);
207
+ (0, _react.useEffect)(() => {
208
+ const next = startSystem();
209
+ const own = echo.current === next;
210
+ echo.current = null;
211
+ if (own) return;
212
+ setChosenSystem(next);
213
+ setOpenedOn(next);
214
+ },
215
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- only when the props change
216
+ [calendarSystem, switchKey]);
217
+ // Month and year picks are Gregorian whatever the calendar system.
218
+ const system = precision === 'day' ? (0, _calendarSystem.resolveCalendarSystem)(chosenSystem) : 'gregory';
219
+ // A dual calendar shows one of its two tabs; each open starts on dualDefaultTab.
220
+ const [dualTab, setDualTab] = (0, _react.useState)(dualDefaultTab);
221
+ /** The calendar on screen. */
222
+ const shownSystem = system === 'dual' ? dualTab : system;
223
+ // A value from outside counts as picked in the calendar the props open on,
224
+ // not the one the user has since chosen in the switch.
225
+ const propSystem = precision === 'day' ? (0, _calendarSystem.resolveCalendarSystem)(openedOn) : 'gregory';
226
+ const outsideSystem = propSystem === 'dual' ? dualDefaultTab : propSystem;
227
+ // Picks say which calendar they were made in only when one can be Hijri.
228
+ const hijriInPlay = switchSystems !== null || system !== 'gregory';
229
+ /**
230
+ * The digits for one calendar: a Hijri calendar (and a date picked in it)
231
+ * shows Arabic digits (١٢٣) in any language; a Gregorian one shows 0–9.
232
+ * `numerals` sets both.
233
+ */
234
+ const digitsFor = sys => {
235
+ const kind = numeralsProp ?? (sys === 'hijri' ? 'arabic' : 'latin');
236
+ if (kind === 'arabic') return _numerals.arabicDigits;
237
+ if (kind === 'latin') return _numerals.latinDigits;
238
+ return (0, _numerals.localeDigits)(sys === 'hijri' ? hijriLocale : loc);
239
+ };
240
+ /**
241
+ * The strings for one calendar. A Hijri one takes `hijriStrings` first, then
242
+ * AM / PM in `hijriLocale` (ص / م), then `strings`.
243
+ */
244
+ const hijriStrings = (0, _react.useMemo)(() => ({
245
+ ...strings,
246
+ ...(0, _calendarSystem.hijriPeriods)(hijriLocale),
247
+ ...(0, _defaultStrings.compactStrings)(hijriOverrides)
248
+ }), [strings, hijriLocale, hijriOverrides]);
249
+ const stringsFor = sys => sys === 'hijri' ? hijriStrings : strings;
147
250
  const monthNames = (0, _react.useMemo)(() => (0, _localeNames.localeNames)(loc).monthsLong, [loc]);
148
251
  /** A month or year pick shown as text: "March 2026" or "2026". */
149
252
  const periodText = v => {
@@ -207,7 +310,7 @@ const DateTimePicker = props => {
207
310
  const {
208
311
  isOpen: sheetOpen,
209
312
  open,
210
- close
313
+ close: closePicker
211
314
  } = (0, _useOpenPicker.useOpenPicker)({
212
315
  disabled,
213
316
  readOnly,
@@ -217,7 +320,7 @@ const DateTimePicker = props => {
217
320
  onClose
218
321
  });
219
322
  const isOpen = isInline || sheetOpen;
220
- const keyboardUp = (0, _useKeyboardFold.useKeyboardFold)(isOpen);
323
+ const keyboardUp = (0, _useKeyboardFold.useKeyboardFold)(isOpen && hideCalendarOnKeyboard);
221
324
  // The picker's own boxes that have focus. Inline, another field on the
222
325
  // screen can raise the keyboard, so the calendar folds only for these.
223
326
  const [focusedParts, setFocusedParts] = (0, _react.useState)({});
@@ -264,16 +367,36 @@ const DateTimePicker = props => {
264
367
  };
265
368
  })).catch(() => requestedYears.current.delete(year));
266
369
  }, [loadHolidays]);
370
+ // A month's grid also shows days of the months either side, and a Hijri
371
+ // month can run from December into January, so a month at either end of a
372
+ // year loads the year next to it too.
373
+ const loadHolidaysAround = (0, _react.useCallback)((year, month) => {
374
+ loadHolidaysFor(year);
375
+ if (month >= 11 && year < yearRange.last) loadHolidaysFor(year + 1);
376
+ if (month === 1 && year > yearRange.first) loadHolidaysFor(year - 1);
377
+ }, [loadHolidaysFor, yearRange.first, yearRange.last]);
267
378
  const holidays = (0, _react.useMemo)(() => [...(holidaysProp ?? []), ...Object.values(loadedHolidays).flat()], [holidaysProp, loadedHolidays]);
268
379
 
269
380
  // Limits are worked out when the picker opens (the screen's own validation
270
381
  // after Confirm stays the final check).
271
382
  const weekdaysKey = disabledWeekdays?.join(',');
383
+ // Limits built with `dependsOnNow` ("from now on") are rebuilt every minute
384
+ // while the picker is open.
385
+ const [minuteTick, setMinuteTick] = (0, _react.useState)(0);
272
386
  const constraints = (0, _react.useMemo)(() => {
273
387
  const nowDate = now?.() ?? new Date();
388
+ // yearRange bounds the limits too, so days outside it are greyed.
274
389
  const limits = {
275
- minDate,
276
- maxDate,
390
+ minDate: later(minDate, {
391
+ year: yearRange.first,
392
+ month: 1,
393
+ day: 1
394
+ }),
395
+ maxDate: earlier(maxDate, {
396
+ year: yearRange.last,
397
+ month: 12,
398
+ day: 31
399
+ }),
277
400
  disabledDates,
278
401
  enabledDates,
279
402
  timeBounds,
@@ -296,8 +419,8 @@ const DateTimePicker = props => {
296
419
  type,
297
420
  timeZone: zone,
298
421
  now: nowDate,
299
- minDate,
300
- maxDate,
422
+ minDate: limits.minDate,
423
+ maxDate: limits.maxDate,
301
424
  isDisabled: disabledDates,
302
425
  isEnabled: enabledDates,
303
426
  timeBounds,
@@ -305,8 +428,25 @@ const DateTimePicker = props => {
305
428
  holidays,
306
429
  disableHolidays
307
430
  });
308
- // eslint-disable-next-line react-hooks/exhaustive-deps -- `isOpen` and `today` refresh the limits on open and at midnight; weekdays are compared by content
309
- }, [isOpen, today, type, zone, now, holidays, minDate, maxDate, disabledDates, enabledDates, timeBounds, weekdaysKey, disableHolidays, getConstraints]);
431
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- `isOpen`, `today` and `minuteTick` refresh the limits on open, at midnight and each minute; weekdays are compared by content
432
+ }, [isOpen, today, minuteTick, type, zone, now, holidays, minDate, maxDate, disabledDates, enabledDates, timeBounds, weekdaysKey, disableHolidays, getConstraints, yearRange]);
433
+ const followsClock = isOpen && constraints.dependsOnNow;
434
+ (0, _react.useEffect)(() => {
435
+ if (!followsClock) return;
436
+ let timer;
437
+ const arm = () => {
438
+ const ms = 60_000 - (now?.() ?? new Date()).getTime() % 60_000;
439
+ timer = setTimeout(() => {
440
+ setMinuteTick(n => n + 1);
441
+ arm();
442
+ }, ms);
443
+ // Under Node (e.g. Jest) the timer must not keep the process alive.
444
+ timer.unref?.();
445
+ };
446
+ arm();
447
+ return () => clearTimeout(timer);
448
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- armed while open with a clock-bound limit
449
+ }, [followsClock]);
310
450
 
311
451
  // A typed field that doesn't parse blocks Confirm, per field: one end of a
312
452
  // range can't hide the other end's problem.
@@ -333,14 +473,30 @@ const DateTimePicker = props => {
333
473
  const [wheelSpinning, setWheelSpinning] = (0, _react.useState)(false);
334
474
  // From/To layout: the end that calendar taps fill. perDate: the day the time row edits.
335
475
  const [activeEnd, setActiveEnd] = (0, _react.useState)('from');
476
+ // From/To layout: a From or To field was tapped, so the next day tap edits that end only.
477
+ const [endPicked, setEndPicked] = (0, _react.useState)(false);
478
+ const activateEnd = (0, _react.useCallback)(end => {
479
+ setActiveEnd(end);
480
+ setEndPicked(true);
481
+ }, []);
336
482
  const [activeDay, setActiveDay] = (0, _react.useState)(null);
337
483
  const resetSelectionUi = (0, _react.useCallback)(() => {
484
+ // What was typed is gone with the selection, so nothing blocks Confirm.
485
+ setTypingBlocks({});
338
486
  setPendingTimes({});
339
487
  setActiveEnd('from');
488
+ setEndPicked(false);
340
489
  setActiveDay(null);
341
490
  }, []);
491
+ // A day in the month the calendar last showed, so a switch to the other
492
+ // calendar opens on the same days. Each open starts from the value again.
493
+ const shownAnchor = (0, _react.useRef)(null);
494
+ const rememberAnchor = (0, _react.useCallback)(day => {
495
+ shownAnchor.current = day;
496
+ }, []);
342
497
  // Opening or closing starts fresh: nothing edited, nothing blocked.
343
498
  (0, _react.useEffect)(() => {
499
+ shownAnchor.current = null;
344
500
  edited.current = false;
345
501
  setTypingBlocks({});
346
502
  setTimeCheck(0);
@@ -404,6 +560,59 @@ const DateTimePicker = props => {
404
560
  };
405
561
  const valueKey = JSON.stringify(value ?? '');
406
562
 
563
+ // A selection belongs to the calendar it was picked in (Gregorian or Hijri):
564
+ // it shows only there, and the field writes it in that calendar. A saved
565
+ // value remembers its calendar; one from outside counts as picked in the
566
+ // calendar the picker opens on.
567
+ // The saved value as a draft, for the on-screen field and for comparing
568
+ // values by what they hold.
569
+ const saved = (0, _react.useMemo)(() => (0, _draft.createDraft)(mode, value, draftOptions),
570
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- the value is compared by content (`valueKey`)
571
+ [valueKey, mode, draftOptions]);
572
+ /** A draft's days and times, so a value written another way ({to, from}) still matches. */
573
+ const contentOf = dr => JSON.stringify(valuesOf(dr));
574
+ const savedContent = contentOf(saved);
575
+ const savedSystemRef = (0, _react.useRef)(null);
576
+ const savedSystem = savedSystemRef.current?.content === savedContent ? savedSystemRef.current.system : outsideSystem;
577
+ const [draftSystem, setDraftSystem] = (0, _react.useState)(savedSystem);
578
+ // The draft is rebuilt on open and on a new value; so is its calendar. A new
579
+ // calendarSystem prop while the user is picking starts the selection over,
580
+ // since a selection is one calendar's.
581
+ const systemSeen = (0, _react.useRef)({
582
+ isOpen,
583
+ valueKey,
584
+ savedSystem
585
+ });
586
+ (0, _react.useEffect)(() => {
587
+ const seen = systemSeen.current;
588
+ systemSeen.current = {
589
+ isOpen,
590
+ valueKey,
591
+ savedSystem
592
+ };
593
+ setDraftSystem(savedSystem);
594
+ const systemOnly = seen.isOpen === isOpen && seen.valueKey === valueKey && seen.savedSystem !== savedSystem;
595
+ if (systemOnly && isOpen && edited.current) {
596
+ draft.clear();
597
+ resetSelectionUi();
598
+ }
599
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- the draft's actions are stable
600
+ }, [isOpen, valueKey, savedSystem]);
601
+ (0, _react.useEffect)(() => setDualTab(dualDefaultTab), [isOpen, dualDefaultTab]);
602
+ const selectionShown = draftSystem === shownSystem;
603
+ /** Saves a value: with the calendar it was picked in, when one can be Hijri. */
604
+ const emitChange = (0, _react.useCallback)((wire, picked) => {
605
+ savedSystemRef.current = {
606
+ content: contentOf((0, _draft.createDraft)(mode, wire, draftOptions)),
607
+ system: picked
608
+ };
609
+ if (hijriInPlay) onChange(wire, {
610
+ calendarSystem: picked
611
+ });else onChange(wire);
612
+ },
613
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- contentOf reads only `type` and the options listed
614
+ [hijriInPlay, onChange, mode, draftOptions]);
615
+
407
616
  /**
408
617
  * Whether a draft can be saved as it stands: complete, every day allowed,
409
618
  * every time allowed and on the minute step, and nothing being typed or
@@ -416,19 +625,19 @@ const DateTimePicker = props => {
416
625
 
417
626
  // Every save: Confirm, an 'instant' edit (onConfirm is added by `confirm`).
418
627
  const commit = (0, _react.useCallback)(wire => {
419
- onChange(wire);
628
+ emitChange(wire, draftSystem);
420
629
  onBlur?.();
421
- }, [onChange, onBlur]);
630
+ }, [emitChange, draftSystem, onBlur]);
422
631
  const confirm = (0, _react.useCallback)(() => {
423
632
  if (!canConfirm) return;
424
633
  const {
425
634
  validate: check,
426
635
  onError: report,
427
- value: saved
636
+ value: current
428
637
  } = latest.current;
429
638
  if (timeBlocked) {
430
639
  setTimeCheck(n => n + 1);
431
- report?.(timeIssue ?? 'TIME_NOT_ALLOWED', saved);
640
+ report?.(timeIssue ?? 'TIME_NOT_ALLOWED', current);
432
641
  return;
433
642
  }
434
643
  const wire = (0, _draft.draftToWire)(preview, draftOptions);
@@ -444,14 +653,14 @@ const DateTimePicker = props => {
444
653
  commit(wire);
445
654
  onConfirm?.(wire);
446
655
  edited.current = false;
447
- if (!isInline) close();
448
- }, [canConfirm, timeBlocked, timeIssue, commit, onConfirm, preview, draftOptions, isInline, close]);
656
+ if (!isInline) closePicker();
657
+ }, [canConfirm, timeBlocked, timeIssue, commit, onConfirm, preview, draftOptions, isInline, closePicker]);
449
658
  const clearValue = (0, _react.useCallback)(() => {
450
659
  draft.clear();
451
660
  resetSelectionUi();
452
661
  edited.current = false;
453
- onChange('');
454
- }, [draft, onChange, resetSelectionUi]);
662
+ emitChange('', draftSystem);
663
+ }, [draft, emitChange, draftSystem, resetSelectionUi]);
455
664
  const clearDraft = (0, _react.useCallback)(() => {
456
665
  edited.current = true;
457
666
  draft.clear();
@@ -460,9 +669,10 @@ const DateTimePicker = props => {
460
669
 
461
670
  // × in the field above the calendar. 'instant' saves every edit, so it
462
671
  // clears the saved value too (once; an empty value isn't saved again).
672
+ const hasSaved = valuesOf(saved).some(v => v !== null);
463
673
  const clearInSheet = (0, _react.useCallback)(() => {
464
- if (commitMode === 'instant' && valueKey !== '""') clearValue();else clearDraft();
465
- }, [commitMode, valueKey, clearValue, clearDraft]);
674
+ if (commitMode === 'instant' && hasSaved) clearValue();else clearDraft();
675
+ }, [commitMode, hasSaved, clearValue, clearDraft]);
466
676
 
467
677
  // Opening or closing starts without the last `validate` message.
468
678
  (0, _react.useEffect)(() => setValidation(null), [isOpen]);
@@ -473,15 +683,27 @@ const DateTimePicker = props => {
473
683
  // An edit equal to the saved value isn't saved again; one `validate`
474
684
  // rejected waits until the selection or the saved value changes.
475
685
  const lastRejected = (0, _react.useRef)(null);
686
+ // The last value saved: not saved again while the parent's `value` catches
687
+ // up (a slow store, a server round trip) or when it never does.
688
+ const lastEmitted = (0, _react.useRef)(null);
476
689
  (0, _react.useEffect)(() => {
477
690
  lastRejected.current = null;
478
- }, [valueKey]);
479
- (0, _react.useEffect)(() => {
691
+ lastEmitted.current = null;
692
+ }, [valueKey, isOpen]);
693
+ // The field in the sheet saves once typing there is done (focus leaves it),
694
+ // so 09:30 isn't saved as 09:00 and 09:03 on the way.
695
+ const sheetTyping = !!(focusedParts.value || focusedParts['value-from'] || focusedParts['value-to']);
696
+ /** Saves the draft in instant mode; `typingDone` once the sheet's field is left. */
697
+ const saveInstant = typingDone => {
480
698
  if (commitMode !== 'instant' || !isOpen || !edited.current) return;
481
- if (timeIssue || !canSave(draft.draft)) return;
699
+ if (!typingDone || timeIssue || !canSave(draft.draft)) return;
482
700
  const wire = draft.toWire();
483
701
  const key = JSON.stringify(wire);
484
- if (key === valueKey || key === lastRejected.current) return;
702
+ if (key === lastRejected.current || key === lastEmitted.current) return;
703
+ // The same dates picked in the same calendar aren't saved again; the same
704
+ // dates picked in the other calendar are.
705
+ const unchanged = key === valueKey || contentOf(draft.draft) === savedContent;
706
+ if (unchanged && draftSystem === savedSystem) return;
485
707
  const message = latest.current.validate?.(wire);
486
708
  if (message) {
487
709
  lastRejected.current = key;
@@ -492,9 +714,22 @@ const DateTimePicker = props => {
492
714
  latest.current.onError?.('VALIDATION', wire);
493
715
  return;
494
716
  }
717
+ lastEmitted.current = key;
495
718
  commit(wire);
496
- // eslint-disable-next-line react-hooks/exhaustive-deps -- when the draft or what blocks it changes, not when callbacks are re-created
497
- }, [commitMode, isOpen, draft.draft, timeIssue, typingBlocked, wheelSpinning, confirmDisabled, constraints]);
719
+ };
720
+ // Only typing waits for the field to be left; a tap is a finished edit.
721
+ const typedLast = (0, _react.useRef)(false);
722
+ (0, _react.useEffect)(() => saveInstant(!sheetTyping || !typedLast.current),
723
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- when the draft or what blocks it changes, not when callbacks are re-created
724
+ [commitMode, isOpen, sheetTyping, draft.draft, draftSystem, timeIssue, typingBlocked, wheelSpinning, confirmDisabled, constraints]);
725
+ // Closing while the sheet's field still has focus ends the typing: an
726
+ // instant picker saves what was typed before it closes.
727
+ const saveInstantRef = (0, _react.useRef)(saveInstant);
728
+ saveInstantRef.current = saveInstant;
729
+ const close = (0, _react.useCallback)(() => {
730
+ saveInstantRef.current(true);
731
+ closePicker();
732
+ }, [closePicker]);
498
733
 
499
734
  // A typed date with no time yet gets one the way a tapped day does: the fixed
500
735
  // newDayTime, else a time already typed in the time row, else now.
@@ -502,14 +737,24 @@ const DateTimePicker = props => {
502
737
  date: parsed.dateOnly,
503
738
  time: fixedTime ?? pending[key] ?? nowTime()
504
739
  } : null);
740
+
741
+ // Typed segments are Gregorian, so typing keeps the calendar a selection was
742
+ // picked in; into an empty draft, it takes the calendar on screen.
743
+ const adoptShownIfEmpty = () => {
744
+ if (valuesOf(d).every(v => v === null)) setDraftSystem(shownSystem);
745
+ };
505
746
  const onSheetTyped = parsed => {
506
747
  edited.current = true;
748
+ typedLast.current = true;
749
+ adoptShownIfEmpty();
507
750
  const typed = withFilledTime(parsed, 'single');
508
751
  setTypingBlock('single', !parsed.isEmpty && !typed);
509
752
  if (typed) draft.setValue(typed, 'single');else if (parsed.isEmpty) draft.clear();
510
753
  };
511
754
  const onRangeTyped = (end, parsed) => {
512
755
  edited.current = true;
756
+ typedLast.current = true;
757
+ adoptShownIfEmpty();
513
758
  const typed = withFilledTime(parsed, end);
514
759
  setTypingBlock(end, !parsed.isEmpty && !typed);
515
760
  if (typed || parsed.isEmpty) draft.setValue(typed, end);
@@ -530,28 +775,77 @@ const DateTimePicker = props => {
530
775
  minute: capped % 60
531
776
  };
532
777
  }, [now, zone, minuteStep]);
778
+
779
+ // A range end picked on the start's day starts an hour after the start (at
780
+ // most the day's latest allowed time, or its last step), so the range isn't
781
+ // out of order before the user has touched the time.
782
+ // A time typed for the end before its day is kept as typed.
783
+ const endTimeFor = (from, day, typed) => {
784
+ if (!fixedTime && typed) return typed;
785
+ const time = fixedTime ?? nowTime();
786
+ if (!from?.time || !(0, _calendarDate.isSameDay)(from.date, day)) return time;
787
+ const start = from.time.hour * 60 + from.time.minute;
788
+ if (time.hour * 60 + time.minute > start) return time;
789
+ // Within the day's allowed hours when it has them.
790
+ const max = constraints.timeBounds(day)?.max;
791
+ const last = max ? max.hour * 60 + max.minute : 24 * 60 - Math.max(1, minuteStep);
792
+ const end = Math.min(start + 60, last);
793
+ return {
794
+ hour: Math.floor(end / 60),
795
+ minute: end % 60
796
+ };
797
+ };
533
798
  const onSelectDay = (0, _react.useCallback)(day => {
534
799
  edited.current = true;
535
- if (d.mode === 'range') {
800
+ typedLast.current = false;
801
+ // A pick in the other calendar starts over: the selection is one calendar's.
802
+ const fresh = draftSystem !== shownSystem && valuesOf(d).some(v => v !== null);
803
+ setDraftSystem(shownSystem);
804
+ const cur = fresh ? (0, _draft.clearDraft)(d) : d;
805
+ const end0 = fresh ? 'from' : activeEnd;
806
+ const dayInEdit = fresh ? null : activeDay;
807
+ const times = fresh ? {} : pending;
808
+ if (fresh) {
809
+ draft.clear();
810
+ resetSelectionUi();
811
+ }
812
+ if (cur.mode === 'range') {
536
813
  if (rangeLayout === 'fromTo') {
814
+ setEndPicked(false);
815
+ // A full range: the tap starts a new one (or moves the nearest end).
816
+ if (!endPicked && cur.from.value && cur.to.value) {
817
+ const moveNearest = range?.reselect === 'moveNearestEnd';
818
+ const nearest = Math.abs((0, _calendarDate.daysBetween)(cur.from.value.date, day)) < Math.abs((0, _calendarDate.daysBetween)(cur.to.value.date, day)) ? 'from' : 'to';
819
+ const end = moveNearest ? nearest : 'from';
820
+ setTypingBlock('from', false);
821
+ setTypingBlock('to', false);
822
+ draft.selectDay(day, fixedTime ?? times[end] ?? nowTime());
823
+ setActiveEnd(moveNearest ? nearest : 'to');
824
+ return;
825
+ }
826
+ // Choosing the end after a start tap: a day before the start moves the start.
827
+ const end1 = end0 === 'to' && !endPicked && cur.from.value && (0, _calendarDate.compareCalendarDates)(day, cur.from.value.date) < 0 ? 'from' : end0;
537
828
  // The tapped day replaces whatever was typed in this end only.
538
- setTypingBlock(activeEnd, false);
539
- draft.setRangeEnd(day, activeEnd, fixedTime ?? pending[activeEnd] ?? nowTime());
540
- if (activeEnd === 'from') setActiveEnd('to');
829
+ setTypingBlock(end1, false);
830
+ draft.setRangeEnd(day, end1, end1 === 'to' ? endTimeFor(cur.from.value, day, times.to) : fixedTime ?? times.from ?? nowTime());
831
+ // The start tapped again where a range can't be one day deselects
832
+ // it, so the next tap picks the start again.
833
+ const deselects = end1 === 'to' && !(0, _draft.sameDayRangeOk)(draftOptions) && (0, _calendarDate.isSameDay)(cur.from.value?.date, day);
834
+ if (end0 === 'from') setActiveEnd('to');else if (deselects) setActiveEnd('from');
541
835
  return;
542
836
  }
543
837
  // The single field: the first tap is the start, the next one the end.
544
- const startsOver = !d.from.value || !!d.to.value && range?.reselect !== 'moveNearestEnd';
838
+ const startsOver = !cur.from.value || !!cur.to.value && range?.reselect !== 'moveNearestEnd';
545
839
  const end = startsOver ? 'from' : 'to';
546
840
  setTypingBlock('single', false);
547
- draft.selectDay(day, fixedTime ?? pending[end] ?? nowTime());
841
+ draft.selectDay(day, end === 'to' && !cur.to.value ? endTimeFor(cur.from.value, day, times.to) : fixedTime ?? times[end] ?? nowTime());
548
842
  return;
549
843
  }
550
- if (d.mode === 'multiple') {
844
+ if (cur.mode === 'multiple') {
551
845
  const perDate = type === 'datetime' && multipleTimeMode === 'perDate';
552
- const picked = d.slots.some(slot => (0, _calendarDate.isSameDay)(slot.value?.date, day));
846
+ const picked = cur.slots.some(slot => (0, _calendarDate.isSameDay)(slot.value?.date, day));
553
847
  // perDate: a tap on a picked day first makes it the one the time row edits.
554
- if (perDate && picked && !(0, _calendarDate.isSameDay)(activeDay, day)) {
848
+ if (perDate && picked && !(0, _calendarDate.isSameDay)(dayInEdit, day)) {
555
849
  setActiveDay(day);
556
850
  return;
557
851
  }
@@ -560,18 +854,28 @@ const DateTimePicker = props => {
560
854
  return;
561
855
  }
562
856
  setTypingBlock('single', false);
563
- draft.selectDay(day, fixedTime ?? pending.single ?? nowTime());
564
- }, [d, draft, nowTime, rangeLayout, activeEnd, activeDay, fixedTime, pending, range?.reselect, type, multipleTimeMode, setTypingBlock]);
857
+ draft.selectDay(day, fixedTime ?? times.single ?? nowTime());
858
+ },
859
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- valuesOf reads only `d` and props listed here
860
+ [d, draft, nowTime, rangeLayout, activeEnd, activeDay, fixedTime, pending, range?.reselect, type, multipleTimeMode, setTypingBlock, draftSystem, shownSystem, resetSelectionUi, endPicked, draftOptions, minuteStep, constraints]);
861
+
862
+ // The calendar gets a tap handler that never changes, so its memoized day
863
+ // cells don't all redraw on every tap; it calls the current one.
864
+ const selectDayRef = (0, _react.useRef)(onSelectDay);
865
+ selectDayRef.current = onSelectDay;
866
+ const onSelectDayStable = (0, _react.useCallback)(day => selectDayRef.current(day), []);
565
867
 
566
868
  // Greying that depends on what's picked: range length, From/To order, the multiple cap.
567
869
  const calendarConstraints = (0, _react.useMemo)(() => {
568
870
  if (d.mode === 'range') {
569
- const choosingEnd = rangeLayout === 'fromTo' ? activeEnd === 'to' : !!d.from.value && !d.to.value;
871
+ // A full From/To range greys nothing: the next tap starts a new one.
872
+ const choosingEnd = rangeLayout === 'fromTo' ? activeEnd === 'to' && (endPicked || !d.to.value) : !!d.from.value && !d.to.value;
570
873
  return (0, _selectionRules.withSelectionRules)(constraints, {
571
874
  rangeStart: choosingEnd ? d.from.value?.date : null,
572
875
  minDays: range?.minDays,
573
876
  maxDays: range?.maxDays,
574
- blockBeforeStart: rangeLayout === 'fromTo'
877
+ // Only an end chosen from the To field can't go before the start.
878
+ blockBeforeStart: rangeLayout === 'fromTo' && endPicked
575
879
  });
576
880
  }
577
881
  if (d.mode === 'multiple') {
@@ -582,7 +886,7 @@ const DateTimePicker = props => {
582
886
  });
583
887
  }
584
888
  return constraints;
585
- }, [constraints, d, rangeLayout, activeEnd, range?.minDays, range?.maxDays, multiple?.maxSelections]);
889
+ }, [constraints, d, rangeLayout, activeEnd, endPicked, range?.minDays, range?.maxDays, multiple?.maxSelections]);
586
890
  const selection = draft.draft.mode === 'single' ? {
587
891
  kind: 'single',
588
892
  day: draft.draft.slot.value?.date ?? null
@@ -609,13 +913,13 @@ const DateTimePicker = props => {
609
913
  }
610
914
  }, [isOpen, constraints, today]);
611
915
  const handleVisibleMonth = (0, _react.useCallback)((year, month) => {
612
- loadHolidaysFor(year);
916
+ loadHolidaysAround(year, month);
613
917
  onVisibleMonthChange?.(year, month);
614
- }, [loadHolidaysFor, onVisibleMonthChange]);
918
+ }, [loadHolidaysAround, onVisibleMonthChange]);
615
919
  (0, _react.useEffect)(() => {
616
920
  if (!isOpen) return;
617
- const anchor = selection.kind === 'single' ? selection.day : null;
618
- loadHolidaysFor((anchor ?? today).year);
921
+ const anchor = (selection.kind === 'single' ? selection.day : null) ?? today;
922
+ loadHolidaysAround(anchor.year, anchor.month);
619
923
  // eslint-disable-next-line react-hooks/exhaustive-deps -- once per open
620
924
  }, [isOpen]);
621
925
 
@@ -666,17 +970,24 @@ const DateTimePicker = props => {
666
970
  return;
667
971
  }
668
972
  setTriggerError('');
669
- onChange(wire);
973
+ // Typing keeps the calendar the saved value was picked in.
974
+ emitChange(wire, savedSystem);
670
975
  onBlur?.();
671
976
  };
672
977
 
978
+ /** A value's date in the calendar it was picked in: Hijri text, or none for the dateFormat. */
979
+ const dateTextFor = picked => picked === 'hijri' ? v => (0, _calendarSystem.hijriDateText)(v.date, hijriLocale) ?? (0, _fieldText.formatDateText)(v, dateFormat) : undefined;
980
+ const savedDateText = dateTextFor(savedSystem);
981
+ const draftDateText = dateTextFor(draftSystem);
982
+ const savedStrings = stringsFor(savedSystem);
983
+ const draftStrings = stringsFor(draftSystem);
984
+ // Error messages inside the picker follow the tab on screen; the on-screen
985
+ // field's keep `strings`.
986
+ const shownStrings = stringsFor(shownSystem);
987
+
673
988
  // What the on-screen field shows: the saved value, never the draft.
674
- const savedKey = valueKey;
675
- const saved = (0, _react.useMemo)(() => (0, _draft.createDraft)(mode, value, draftOptions),
676
- // eslint-disable-next-line react-hooks/exhaustive-deps -- the value is compared by content (`savedKey`)
677
- [savedKey, mode, draftOptions]);
678
989
  const savedSingle = saved.mode === 'single' ? saved.slot.value : null;
679
- const savedText = saved.mode === 'range' ? (0, _fieldText.formatRangeText)(saved.from.value, saved.to.value, type, dateFormat, timeFormat, strings.rangeSeparator) : saved.mode === 'multiple' ? (0, _fieldText.formatMultipleText)(saved.slots.map(slot => slot.value), type, dateFormat, timeFormat) : precision !== 'day' ? periodText(savedSingle) : undefined;
990
+ const savedText = saved.mode === 'range' ? (0, _fieldText.formatRangeText)(saved.from.value, saved.to.value, type, dateFormat, timeFormat, strings.rangeSeparator, savedDateText, savedStrings) : saved.mode === 'multiple' ? (0, _fieldText.formatMultipleText)(saved.slots.map(slot => slot.value), type, dateFormat, timeFormat, savedDateText, savedStrings) : precision !== 'day' ? periodText(savedSingle) : undefined;
680
991
  const periodPlaceholder = precision === 'year' ? strings.placeholderYear : precision === 'month' ? `${strings.placeholderMonth} ${strings.placeholderYear}` : undefined;
681
992
 
682
993
  // The time a custom renderTimeRow edits, and how it sets it (the same
@@ -702,7 +1013,7 @@ const DateTimePicker = props => {
702
1013
  type,
703
1014
  mode,
704
1015
  value,
705
- displayText: savedText ?? (0, _fieldText.formatValueText)(savedSingle, type, dateFormat, timeFormat),
1016
+ displayText: digitsFor(savedSystem)(savedText ?? (0, _fieldText.formatValueText)(savedSingle, type, dateFormat, timeFormat, savedDateText, savedStrings)),
706
1017
  disabled,
707
1018
  readOnly,
708
1019
  isOpen,
@@ -723,11 +1034,11 @@ const DateTimePicker = props => {
723
1034
  };
724
1035
  const sheetValue = draft.draft.mode === 'single' ? draft.draft.slot.value : null;
725
1036
  // A time outside the limits is explained under the time row, not here.
726
- const sheetValueError = sheetValue && dayOff(sheetValue.date) ? strings.errorNotAllowed : '';
1037
+ const sheetValueError = sheetValue && dayOff(sheetValue.date) ? shownStrings.errorNotAllowed : '';
727
1038
  let rangeError = '';
728
1039
  if (d.mode === 'range' && d.from.value && d.to.value) {
729
1040
  const length = (0, _calendarDate.daysBetween)(d.from.value.date, d.to.value.date) + 1;
730
- if (constraints.dayStatus(d.from.value.date).disabled || constraints.dayStatus(d.to.value.date).disabled) rangeError = strings.errorNotAllowed;else if (previewIssue === 'RANGE_ORDER') rangeError = strings.errorRangeOrder;else if (previewIssue === 'RANGE_LENGTH') rangeError = range?.minDays !== undefined && length < range.minDays ? strings.errorRangeTooShort(range.minDays) : strings.errorRangeTooLong(range?.maxDays ?? length);
1041
+ if (constraints.dayStatus(d.from.value.date).disabled || constraints.dayStatus(d.to.value.date).disabled) rangeError = shownStrings.errorNotAllowed;else if (previewIssue === 'RANGE_ORDER') rangeError = shownStrings.errorRangeOrder;else if (previewIssue === 'RANGE_LENGTH') rangeError = range?.minDays !== undefined && length < range.minDays ? shownStrings.errorRangeTooShort(range.minDays) : shownStrings.errorRangeTooLong(range?.maxDays ?? length);
731
1042
  }
732
1043
  const fieldCommon = {
733
1044
  type,
@@ -743,8 +1054,11 @@ const DateTimePicker = props => {
743
1054
  };
744
1055
  const trigger = !showField || isInline ? null : renderField ? renderField(state) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_ValueField.default, {
745
1056
  ...fieldCommon,
1057
+ strings: savedStrings,
1058
+ errorStrings: strings,
746
1059
  value: savedSingle,
747
1060
  displayText: savedText,
1061
+ dateText: savedDateText,
748
1062
  allowTyping: mode === 'single' && precision === 'day' && allowFieldTyping,
749
1063
  onTypingDone: onTriggerTyped,
750
1064
  onTyped: () => setTriggerError(''),
@@ -774,8 +1088,11 @@ const DateTimePicker = props => {
774
1088
  testID: testID ? `${testID}-value` : undefined
775
1089
  }) : mode === 'single' ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_ValueField.default, {
776
1090
  ...fieldCommon,
1091
+ strings: draftStrings,
1092
+ errorStrings: shownStrings,
777
1093
  value: sheetValue,
778
1094
  displayText: precision !== 'day' ? periodText(sheetValue) : undefined,
1095
+ dateText: draftDateText,
779
1096
  placeholder: sheetOptions?.fieldPlaceholder ?? periodPlaceholder,
780
1097
  allowTyping: allowTyping && precision === 'day',
781
1098
  onTyped: onSheetTyped,
@@ -788,13 +1105,16 @@ const DateTimePicker = props => {
788
1105
  testID: testID ? `${testID}-value` : undefined
789
1106
  }) : d.mode === 'range' ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_RangeFields.default, {
790
1107
  ...fieldCommon,
1108
+ strings: draftStrings,
1109
+ errorStrings: shownStrings,
791
1110
  layout: rangeLayout,
1111
+ dateText: draftDateText,
792
1112
  showIcon: sheetOptions?.fieldIcon,
793
1113
  from: d.from.value,
794
1114
  to: d.to.value,
795
1115
  placeholder: sheetOptions?.fieldPlaceholder,
796
1116
  activeEnd: activeEnd,
797
- onActivate: setActiveEnd,
1117
+ onActivate: activateEnd,
798
1118
  allowTyping: allowTyping,
799
1119
  onTyped: onRangeTyped,
800
1120
  onFocusChange: (end, f) => reportFocus(`value-${end}`, f),
@@ -805,8 +1125,9 @@ const DateTimePicker = props => {
805
1125
  testID: testID
806
1126
  }) : d.mode === 'multiple' ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_ValueField.default, {
807
1127
  ...fieldCommon,
1128
+ strings: draftStrings,
808
1129
  value: null,
809
- displayText: (0, _fieldText.formatMultipleText)(draftValues, type, dateFormat, timeFormat),
1130
+ displayText: (0, _fieldText.formatMultipleText)(draftValues, type, dateFormat, timeFormat, draftDateText, draftStrings),
810
1131
  placeholder: sheetOptions?.fieldPlaceholder,
811
1132
  allowClear: allowClear,
812
1133
  onClear: clearInSheet,
@@ -815,37 +1136,102 @@ const DateTimePicker = props => {
815
1136
  active: true,
816
1137
  testID: testID ? `${testID}-value` : undefined
817
1138
  }) : null;
818
- const calendar = folded ? null : /*#__PURE__*/(0, _jsxRuntime.jsx)(_Calendar.default, {
819
- constraints: calendarConstraints,
820
- today: today,
821
- initialVisibleDate: initialVisibleDate,
822
- selection: selection,
823
- onSelectDay: onSelectDay,
824
- firstDayOfWeek: firstDayOfWeek,
825
- showOutsideDays: showOutsideDays,
826
- showHolidays: showHolidays,
827
- yearRange: yearRange,
828
- locale: loc
829
- // Month and year picks are Gregorian whatever the calendar system.
830
- ,
831
- calendarSystem: precision === 'day' ? (0, _calendarSystem.resolveCalendarSystem)(calendarSystem) : 'gregory',
832
- initialView: initialView,
833
- precision: precision,
834
- enableMonthSwipe: enableMonthSwipe,
835
- showToday: showToday,
836
- onVisibleMonthChange: handleVisibleMonth,
837
- renderDay: renderDay,
838
- renderWeekday: renderWeekday,
839
- renderMonthChip: renderMonthChip,
840
- renderYearCell: renderYearCell,
841
- renderMonthCell: renderMonthCell,
842
- renderEmptyState: renderEmptyState,
843
- icons: icons,
844
- iconProps: iconProps,
1139
+ const systemLabels = {
1140
+ gregory: strings.calendarGregorian ?? _defaultStrings.DEFAULT_STRINGS.calendarGregorian,
1141
+ hijri: strings.calendarHijri ?? _defaultStrings.DEFAULT_STRINGS.calendarHijri,
1142
+ dual: strings.calendarDual ?? _defaultStrings.DEFAULT_STRINGS.calendarDual
1143
+ };
1144
+ const systemA11yLabel = strings.a11yCalendarSystem ?? _defaultStrings.DEFAULT_STRINGS.a11yCalendarSystem;
1145
+ const chooseSystem = next => {
1146
+ if (next === system) return;
1147
+ setChosenSystem(next);
1148
+ if (next === 'dual') setDualTab(dualDefaultTab);
1149
+ echo.current = next;
1150
+ onCalendarSystemChange?.(next);
1151
+ };
1152
+ const calendarSwitchNode = !switchSystems ? null : renderCalendarSwitch ? renderCalendarSwitch({
1153
+ systems: switchSystems,
1154
+ selected: system,
1155
+ onSelect: chooseSystem,
1156
+ tokens,
1157
+ strings
1158
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_CalendarSwitch.default, {
1159
+ variant: "switch",
1160
+ options: switchSystems.map(v => {
1161
+ return {
1162
+ value: v,
1163
+ label: systemLabels[v]
1164
+ };
1165
+ }),
1166
+ selected: system,
1167
+ onSelect: chooseSystem,
1168
+ accessibilityLabel: systemA11yLabel,
845
1169
  tokens: tokens,
846
1170
  styles: styles,
847
- strings: strings,
848
- testID: testID
1171
+ testID: testID ? `${testID}-calendar-switch` : undefined
1172
+ });
1173
+ const dualTabs = system !== 'dual' ? null : /*#__PURE__*/(0, _jsxRuntime.jsx)(_CalendarSwitch.default, {
1174
+ variant: "tabs",
1175
+ options: [{
1176
+ value: 'gregory',
1177
+ label: systemLabels.gregory
1178
+ }, {
1179
+ value: 'hijri',
1180
+ label: systemLabels.hijri
1181
+ }],
1182
+ selected: dualTab,
1183
+ onSelect: setDualTab,
1184
+ accessibilityLabel: systemA11yLabel,
1185
+ tokens: tokens,
1186
+ styles: styles,
1187
+ testID: testID ? `${testID}-dual-tabs` : undefined
1188
+ });
1189
+ // The Hijri tab lays out its calendar and time rows right to left; the
1190
+ // wrapper always renders, so a tab change doesn't remount the time boxes.
1191
+ const hijriShown = shownSystem === 'hijri';
1192
+ const mirrored = node => node == null ? null : /*#__PURE__*/(0, _jsxRuntime.jsx)(_direction.RtlContext.Provider, {
1193
+ value: hijriShown || null,
1194
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
1195
+ style: hijriShown ? RTL : undefined,
1196
+ children: node
1197
+ })
1198
+ });
1199
+ // Another calendar opens on the days the last one showed, else on the
1200
+ // selection (shown or not), else where the picker would open.
1201
+ const calendarAnchor = shownAnchor.current ?? (selectionShown ? null : (0, _selection.firstSelectedDay)(selection)) ?? initialVisibleDate;
1202
+ const calendar = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
1203
+ style: folded ? FOLDED : undefined,
1204
+ children: [calendarSwitchNode, dualTabs, mirrored(/*#__PURE__*/(0, _jsxRuntime.jsx)(_Calendar.default, {
1205
+ constraints: selectionShown ? calendarConstraints : constraints,
1206
+ today: today,
1207
+ initialVisibleDate: calendarAnchor,
1208
+ selection: selectionShown ? selection : emptySelection(selection),
1209
+ onSelectDay: onSelectDayStable,
1210
+ firstDayOfWeek: firstDayOfWeek,
1211
+ showOutsideDays: showOutsideDays,
1212
+ showHolidays: showHolidays,
1213
+ yearRange: yearRange,
1214
+ locale: shownSystem === 'hijri' ? hijriLocale : loc,
1215
+ calendarSystem: shownSystem,
1216
+ initialView: initialView,
1217
+ precision: precision,
1218
+ enableMonthSwipe: enableMonthSwipe,
1219
+ showToday: showToday,
1220
+ onVisibleMonthChange: handleVisibleMonth,
1221
+ onAnchorChange: rememberAnchor,
1222
+ renderDay: renderDay,
1223
+ renderWeekday: renderWeekday,
1224
+ renderMonthChip: renderMonthChip,
1225
+ renderYearCell: renderYearCell,
1226
+ renderMonthCell: renderMonthCell,
1227
+ renderEmptyState: renderEmptyState,
1228
+ icons: icons,
1229
+ iconProps: iconProps,
1230
+ tokens: tokens,
1231
+ styles: styles,
1232
+ strings: stringsFor(shownSystem),
1233
+ testID: testID
1234
+ }, shownSystem))]
849
1235
  });
850
1236
  const timeRow = type !== 'datetime' ? null : renderTimeRow ? renderTimeRow(state) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_TimeRows.default, {
851
1237
  draft: d,
@@ -872,14 +1258,26 @@ const DateTimePicker = props => {
872
1258
  onPendingChange: onRowPending,
873
1259
  tokens: tokens,
874
1260
  styles: styles,
875
- strings: strings,
1261
+ strings: stringsFor(shownSystem),
876
1262
  testID: testID
877
1263
  });
878
1264
 
879
1265
  // Shown while the selection is still the one it was given for.
880
1266
  const validationMessage = validation && (validation.key === JSON.stringify(draft.toWire()) || validation.key === JSON.stringify((0, _draft.draftToWire)(preview, draftOptions))) ? validation.message : null;
1267
+
1268
+ // The field writes the date in the digits of the calendar it was picked in;
1269
+ // the calendar and the time rows follow the tab that shows.
881
1270
  const sheetContent = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
882
- children: [sheetField, calendar, timeRow, validationMessage ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_FieldMessages.default, {
1271
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_numerals2.NumeralsContext.Provider, {
1272
+ value: digitsFor(draftSystem),
1273
+ children: sheetField
1274
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_numerals2.NumeralsContext.Provider, {
1275
+ value: digitsFor(shownSystem),
1276
+ children: calendar
1277
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_numerals2.NumeralsContext.Provider, {
1278
+ value: digitsFor(shownSystem),
1279
+ children: mirrored(timeRow)
1280
+ }), validationMessage ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_FieldMessages.default, {
883
1281
  error: validationMessage,
884
1282
  tokens: tokens,
885
1283
  styles: {
@@ -889,7 +1287,8 @@ const DateTimePicker = props => {
889
1287
  testID: testID ? `${testID}-validation` : undefined
890
1288
  }) : null]
891
1289
  });
892
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
1290
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_numerals2.NumeralsContext.Provider, {
1291
+ value: digitsFor(savedSystem),
893
1292
  children: [trigger, /*#__PURE__*/(0, _jsxRuntime.jsx)(_PickerContainer.default, {
894
1293
  presentation: presentation,
895
1294
  isOpen: isOpen,