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
@@ -1,4 +1,4 @@
1
- import type { SegmentError } from '../../core/segments';
1
+ import { to12Hour, type SegmentError } from '../../core/segments';
2
2
  import type { DateTimeValue, PickerType, TimeFormat } from '../../core/types';
3
3
  import { DEFAULT_STRINGS, type PickerStrings } from '../theme/defaultStrings';
4
4
 
@@ -14,29 +14,62 @@ export const formatDateText = (
14
14
  .replace('MM', pad2(value.date.month))
15
15
  .replace('dd', pad2(value.date.day));
16
16
 
17
+ /** The AM / PM labels and the date-time separator, from `strings`. */
18
+ export type PeriodLabels = Pick<
19
+ PickerStrings,
20
+ 'am' | 'pm' | 'dateTimeSeparator'
21
+ >;
22
+
17
23
  /** '03:45 PM' (12-hour) or '15:45' (24-hour). Always shows AM/PM in 12-hour mode. */
18
24
  export const formatTimeText = (
19
25
  value: DateTimeValue,
20
- timeFormat: TimeFormat
26
+ timeFormat: TimeFormat,
27
+ periods: PeriodLabels = DEFAULT_STRINGS
21
28
  ): string => {
22
29
  if (!value.time) return '';
23
30
  const { hour, minute } = value.time;
24
31
  if (timeFormat === '24h') return `${pad2(hour)}:${pad2(minute)}`;
25
- const hour12 = hour % 12 === 0 ? 12 : hour % 12;
26
- return `${pad2(hour12)}:${pad2(minute)} ${hour < 12 ? 'AM' : 'PM'}`;
32
+ const { hour12, period } = to12Hour(hour);
33
+ return `${pad2(hour12)}:${pad2(minute)} ${period === 'AM' ? periods.am : periods.pm}`;
27
34
  };
28
35
 
36
+ /** Writes a value's date some other way, e.g. as a Hijri date. */
37
+ export type DateTextFormatter = (value: DateTimeValue) => string;
38
+
39
+ /** A value's date and time as two texts; the time is '' for a date or a value without one. */
40
+ export const formatValueParts = (
41
+ value: DateTimeValue,
42
+ type: PickerType,
43
+ dateFormat: string,
44
+ timeFormat: TimeFormat,
45
+ dateText?: DateTextFormatter,
46
+ periods: PeriodLabels = DEFAULT_STRINGS
47
+ ): { date: string; time: string } => ({
48
+ date: dateText ? dateText(value) : formatDateText(value, dateFormat),
49
+ time:
50
+ type === 'datetime' && value.time
51
+ ? formatTimeText(value, timeFormat, periods)
52
+ : '',
53
+ });
54
+
29
55
  export const formatValueText = (
30
56
  value: DateTimeValue | null,
31
57
  type: PickerType,
32
58
  dateFormat: string,
33
- timeFormat: TimeFormat
59
+ timeFormat: TimeFormat,
60
+ dateText?: DateTextFormatter,
61
+ periods: PeriodLabels = DEFAULT_STRINGS
34
62
  ): string => {
35
63
  if (!value) return '';
36
- const date = formatDateText(value, dateFormat);
37
- return type === 'datetime' && value.time
38
- ? `${date} ${formatTimeText(value, timeFormat)}`
39
- : date;
64
+ const { date, time } = formatValueParts(
65
+ value,
66
+ type,
67
+ dateFormat,
68
+ timeFormat,
69
+ dateText,
70
+ periods
71
+ );
72
+ return time ? `${date}${periods.dateTimeSeparator ?? ' '}${time}` : date;
40
73
  };
41
74
 
42
75
  /** '21-10-2026 – 25-10-2026'; just the start (with the dash) while the end is open. */
@@ -46,11 +79,27 @@ export const formatRangeText = (
46
79
  type: PickerType,
47
80
  dateFormat: string,
48
81
  timeFormat: TimeFormat,
49
- separator: string = ' – '
82
+ separator: string = ' – ',
83
+ dateText?: DateTextFormatter,
84
+ periods: PeriodLabels = DEFAULT_STRINGS
50
85
  ): string => {
51
86
  if (!from && !to) return '';
52
- const a = formatValueText(from, type, dateFormat, timeFormat);
53
- const b = formatValueText(to, type, dateFormat, timeFormat);
87
+ const a = formatValueText(
88
+ from,
89
+ type,
90
+ dateFormat,
91
+ timeFormat,
92
+ dateText,
93
+ periods
94
+ );
95
+ const b = formatValueText(
96
+ to,
97
+ type,
98
+ dateFormat,
99
+ timeFormat,
100
+ dateText,
101
+ periods
102
+ );
54
103
  return `${a}${separator}${b}`.trim();
55
104
  };
56
105
 
@@ -59,11 +108,15 @@ export const formatMultipleText = (
59
108
  values: (DateTimeValue | null)[],
60
109
  type: PickerType,
61
110
  dateFormat: string,
62
- timeFormat: TimeFormat
111
+ timeFormat: TimeFormat,
112
+ dateText?: DateTextFormatter,
113
+ periods: PeriodLabels = DEFAULT_STRINGS
63
114
  ): string =>
64
115
  values
65
116
  .filter((v): v is DateTimeValue => !!v)
66
- .map((v) => formatValueText(v, type, dateFormat, timeFormat))
117
+ .map((v) =>
118
+ formatValueText(v, type, dateFormat, timeFormat, dateText, periods)
119
+ )
67
120
  .join(', ');
68
121
 
69
122
  /** 'DD-MM-YYYY' or 'DD-MM-YYYY hh:mm AM', from the placeholder strings. */
@@ -84,7 +137,7 @@ export const placeholderText = (
84
137
  timeFormat === '24h'
85
138
  ? `${strings.placeholderHour24}:${strings.placeholderMinute}`
86
139
  : `${strings.placeholderHour}:${strings.placeholderMinute} ${strings.am}`;
87
- return `${date} ${time}`;
140
+ return `${date}${strings.dateTimeSeparator ?? ' '}${time}`;
88
141
  };
89
142
 
90
143
  const TIME_KEYS = ['hour', 'minute', 'period'];
@@ -0,0 +1,33 @@
1
+ import { createContext, useContext, type Context } from 'react';
2
+
3
+ type Insets = { bottom: number } | null;
4
+
5
+ declare const require: (name: string) => unknown;
6
+
7
+ /**
8
+ * react-native-safe-area-context's insets, when the app has that package (an
9
+ * optional peer: most Expo apps do). The require sits in a try so a missing
10
+ * package is fine: Metro allows optional dependencies there.
11
+ */
12
+ const readContext = (): Context<Insets> | null => {
13
+ try {
14
+ const lib = require('react-native-safe-area-context') as {
15
+ SafeAreaInsetsContext?: Context<Insets>;
16
+ };
17
+ return lib.SafeAreaInsetsContext ?? null;
18
+ } catch {
19
+ return null;
20
+ }
21
+ };
22
+
23
+ const NO_INSETS = createContext<Insets>(null);
24
+ const InsetsContext = readContext() ?? NO_INSETS;
25
+
26
+ /**
27
+ * The bottom safe-area inset (the home indicator, or Android's navigation bar
28
+ * in an edge-to-edge app), from the app's SafeAreaProvider; 0 without one.
29
+ * Read through the context rather than `useSafeAreaInsets`, which throws when
30
+ * there's no provider.
31
+ */
32
+ export const useBottomInset = (): number =>
33
+ useContext(InsetsContext)?.bottom ?? 0;
@@ -1,31 +1,59 @@
1
1
  import { useEffect, useState } from 'react';
2
- import { Keyboard, Platform } from 'react-native';
2
+ import { Keyboard, Platform, type KeyboardEvent } from 'react-native';
3
3
 
4
- /**
5
- * True while the keyboard is up and the picker is open. The picker folds the
6
- * calendar away then, so the box being typed in (and Confirm) stay visible on
7
- * small phones; inline, it folds only while one of its own boxes has focus,
8
- * since another field on the screen can raise the keyboard too.
9
- */
10
- export const useKeyboardFold = (active: boolean): boolean => {
11
- const [keyboardUp, setKeyboardUp] = useState(false);
4
+ interface KeyboardState {
5
+ up: boolean;
6
+ /** The keyboard's height while it's up, 0 when down (or not reported). */
7
+ height: number;
8
+ }
9
+
10
+ const DOWN: KeyboardState = { up: false, height: 0 };
11
+
12
+ /** The keyboard as it is now: it can already be up when the picker mounts or opens. */
13
+ const current = (): KeyboardState =>
14
+ Keyboard.isVisible()
15
+ ? { up: true, height: Keyboard.metrics()?.height ?? 0 }
16
+ : DOWN;
17
+
18
+ /** Whether the keyboard is up, and how tall it is, while `active`. */
19
+ export const useKeyboard = (active: boolean): KeyboardState => {
20
+ const [keyboard, setKeyboard] = useState(() => (active ? current() : DOWN));
12
21
 
13
22
  useEffect(() => {
14
23
  if (!active) {
15
- setKeyboardUp(false);
24
+ setKeyboard(DOWN);
16
25
  return undefined;
17
26
  }
27
+ setKeyboard(current());
18
28
  const showEvent =
19
29
  Platform.OS === 'ios' ? 'keyboardWillShow' : 'keyboardDidShow';
20
30
  const hideEvent =
21
31
  Platform.OS === 'ios' ? 'keyboardWillHide' : 'keyboardDidHide';
22
- const show = Keyboard.addListener(showEvent, () => setKeyboardUp(true));
23
- const hide = Keyboard.addListener(hideEvent, () => setKeyboardUp(false));
32
+ const show = Keyboard.addListener(showEvent, (e?: KeyboardEvent) =>
33
+ setKeyboard({ up: true, height: e?.endCoordinates?.height ?? 0 })
34
+ );
35
+ const hide = Keyboard.addListener(hideEvent, () => setKeyboard(DOWN));
36
+ // iOS: a sheet opened on keyboardWillHide mounts before the keyboard is
37
+ // gone, so it reads it as up; keyboardDidHide puts that right.
38
+ const hidden =
39
+ hideEvent === 'keyboardDidHide'
40
+ ? null
41
+ : Keyboard.addListener('keyboardDidHide', () => setKeyboard(DOWN));
24
42
  return () => {
25
43
  show.remove();
26
44
  hide.remove();
45
+ hidden?.remove();
27
46
  };
28
47
  }, [active]);
29
48
 
30
- return keyboardUp;
49
+ return keyboard;
31
50
  };
51
+
52
+ /**
53
+ * True while the keyboard is up and the picker is open. With
54
+ * `hideCalendarOnKeyboard` the picker folds the calendar away then, so the box being typed in (and Confirm) stay visible on
55
+ * small phones; inline, it folds only while one of its own boxes has focus,
56
+ * since another field on the screen can raise the keyboard too.
57
+ */
58
+ export const useKeyboardFold = (active: boolean): boolean =>
59
+ useKeyboard(active).up;
@@ -19,7 +19,8 @@ interface Options {
19
19
  * Opens and closes the picker.
20
20
  * - calls `onBeforeOpen` first;
21
21
  * - if a text input has focus, closes the keyboard and waits for it on iOS and
22
- * Android (so the sheet doesn't jump as the keyboard leaves), with a 450 ms fallback;
22
+ * Android (so the sheet doesn't jump as the keyboard leaves), with a 450 ms
23
+ * fallback; a controlled `visible` turned on waits the same way;
23
24
  * - disabled and read-only pickers never open.
24
25
  */
25
26
  export const useOpenPicker = ({
@@ -32,7 +33,16 @@ export const useOpenPicker = ({
32
33
  }: Options): { isOpen: boolean; open: () => void; close: () => void } => {
33
34
  const [openState, setOpenState] = useState(false);
34
35
  const isControlled = visible !== undefined;
35
- const isOpen = isControlled ? !!visible : openState;
36
+ // Controlled: `visible` turned on while a text input has focus waits for
37
+ // the keyboard. Decided while rendering, so the sheet never shows a frame
38
+ // early.
39
+ const [keyboardWait, setKeyboardWait] = useState(false);
40
+ const [seenVisible, setSeenVisible] = useState(visible);
41
+ if (isControlled && visible !== seenVisible) {
42
+ setSeenVisible(visible);
43
+ setKeyboardWait(!!visible && !!TextInput.State.currentlyFocusedInput?.());
44
+ }
45
+ const isOpen = isControlled ? !!visible && !keyboardWait : openState;
36
46
  const pending = useRef<{ cancel: () => void } | null>(null);
37
47
 
38
48
  const cancelPending = () => {
@@ -41,29 +51,17 @@ export const useOpenPicker = ({
41
51
  };
42
52
  useEffect(() => cancelPending, []);
43
53
 
44
- const reallyOpen = useCallback(() => {
45
- pending.current = null;
46
- if (!isControlled) setOpenState(true);
47
- onOpen?.();
48
- }, [isControlled, onOpen]);
49
-
50
- const open = useCallback(() => {
51
- if (disabled || readOnly || isOpen || pending.current) return;
52
- onBeforeOpen?.();
53
- const focused = TextInput.State.currentlyFocusedInput?.();
54
- if (!focused) {
55
- reallyOpen();
56
- return;
57
- }
54
+ /** Closes the keyboard and calls `then` once it's gone (or after the fallback). */
55
+ const afterKeyboard = (then: () => void) => {
58
56
  const event =
59
57
  Platform.OS === 'ios' ? 'keyboardWillHide' : 'keyboardDidHide';
60
58
  const sub = Keyboard.addListener(event, () => {
61
59
  cancelPending();
62
- reallyOpen();
60
+ then();
63
61
  });
64
62
  const timer = setTimeout(() => {
65
63
  cancelPending();
66
- reallyOpen();
64
+ then();
67
65
  }, KEYBOARD_WAIT_FALLBACK_MS);
68
66
  pending.current = {
69
67
  cancel: () => {
@@ -72,6 +70,31 @@ export const useOpenPicker = ({
72
70
  },
73
71
  };
74
72
  Keyboard.dismiss();
73
+ };
74
+
75
+ useEffect(() => {
76
+ if (!keyboardWait) return undefined;
77
+ afterKeyboard(() => setKeyboardWait(false));
78
+ return cancelPending;
79
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- while waiting
80
+ }, [keyboardWait]);
81
+
82
+ const reallyOpen = useCallback(() => {
83
+ pending.current = null;
84
+ if (!isControlled) setOpenState(true);
85
+ onOpen?.();
86
+ }, [isControlled, onOpen]);
87
+
88
+ const open = useCallback(() => {
89
+ if (disabled || readOnly || isOpen || pending.current) return;
90
+ onBeforeOpen?.();
91
+ const focused = TextInput.State.currentlyFocusedInput?.();
92
+ if (!focused) {
93
+ reallyOpen();
94
+ return;
95
+ }
96
+ afterKeyboard(reallyOpen);
97
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- afterKeyboard only uses refs and stable APIs
75
98
  }, [disabled, readOnly, isOpen, onBeforeOpen, reallyOpen]);
76
99
 
77
100
  const close = useCallback(() => {
@@ -17,12 +17,13 @@ const valueKey = (v: DateTimeValue | null): string =>
17
17
  /**
18
18
  * State for the typed field. Re-syncs from `value` when it changes from outside
19
19
  * (a calendar tap, a clear) while no segment is focused, and reports every
20
- * parse result to `onParsed`.
20
+ * parse result to `onParsed`, saying whether it came from such a value
21
+ * (`fromOutside`) rather than from typing.
21
22
  */
22
23
  export const useTypedSegments = (
23
24
  value: DateTimeValue | null,
24
25
  options: SegmentEditorOptions,
25
- onParsed?: (parsed: ParsedSegments) => void
26
+ onParsed?: (parsed: ParsedSegments, fromOutside: boolean) => void
26
27
  ): {
27
28
  state: SegmentEditorState;
28
29
  dispatch: (action: SegmentEditorAction) => void;
@@ -51,9 +52,12 @@ export const useTypedSegments = (
51
52
  // Fast typing (a hardware keyboard, autofill) sends the next character
52
53
  // before React re-renders, so inputs compare against this, not `state`.
53
54
  const latest = useRef(state);
55
+ // Whether the last action was a value set from outside, not typing.
56
+ const lastWasReset = useRef(false);
54
57
  const dispatch = useCallback(
55
58
  (action: SegmentEditorAction) => {
56
59
  latest.current = reducer(latest.current, action);
60
+ lastWasReset.current = action.type === 'reset';
57
61
  reactDispatch(action);
58
62
  },
59
63
  [reducer]
@@ -93,7 +97,7 @@ export const useTypedSegments = (
93
97
  // What's typed is newer than anything that was waiting to be shown.
94
98
  resetOnLeave.current = false;
95
99
  }
96
- onParsedRef.current?.(state.parsed);
100
+ onParsedRef.current?.(state.parsed, lastWasReset.current);
97
101
  }, [state.parsed]);
98
102
 
99
103
  return { state, dispatch, getState };
@@ -18,6 +18,8 @@ export interface PickerStrings {
18
18
  /** Between the two ends of a range in the field text. */
19
19
  rangeSeparator: string;
20
20
  pm: string;
21
+ /** Between the date and the time in the field text and its placeholder. */
22
+ dateTimeSeparator?: string;
21
23
  /** Placeholders of the typed date segments and time boxes, and of the empty field. */
22
24
  placeholderDay: string;
23
25
  placeholderMonth: string;
@@ -39,8 +41,15 @@ export interface PickerStrings {
39
41
  errorRangeTooShort: (days: number) => string;
40
42
  errorRangeTooLong: (days: number) => string;
41
43
  nothingSelectable: string;
44
+ /** The calendar switch and the dual tabs. */
45
+ calendarGregorian?: string;
46
+ calendarHijri?: string;
47
+ calendarDual?: string;
48
+ a11yCalendarSystem?: string;
42
49
  a11yClear: string;
43
50
  a11yOpen: string;
51
+ /** The built-in sheet's backdrop, which closes it. */
52
+ a11yClose?: string;
44
53
  a11yDay: string;
45
54
  a11yMonth: string;
46
55
  a11yYear: string;
@@ -57,7 +66,7 @@ export interface PickerStrings {
57
66
  a11yRangeEnd: string;
58
67
  }
59
68
 
60
- export const DEFAULT_STRINGS: PickerStrings = {
69
+ export const DEFAULT_STRINGS: Required<PickerStrings> = {
61
70
  titleDate: 'Select date',
62
71
  confirm: 'Confirm',
63
72
  reset: 'Reset',
@@ -72,6 +81,7 @@ export const DEFAULT_STRINGS: PickerStrings = {
72
81
  am: 'AM',
73
82
  rangeSeparator: ' – ',
74
83
  pm: 'PM',
84
+ dateTimeSeparator: ' ',
75
85
  placeholderDay: 'DD',
76
86
  placeholderMonth: 'MM',
77
87
  placeholderYear: 'YYYY',
@@ -87,12 +97,17 @@ export const DEFAULT_STRINGS: PickerStrings = {
87
97
  errorNotAllowed: "This date isn't available",
88
98
  errorTimeNotAllowed: "This time isn't available",
89
99
  errorMinuteStep: (step) => `Choose a minute in steps of ${step}`,
90
- errorRangeOrder: 'The end must be after the start',
100
+ errorRangeOrder: 'The end date must be greater than the start date',
91
101
  errorRangeTooShort: (n) => `Choose a range of at least ${n} days`,
92
102
  errorRangeTooLong: (n) => `Choose a range of at most ${n} days`,
93
103
  nothingSelectable: 'No dates are available',
104
+ calendarGregorian: 'Gregorian',
105
+ calendarHijri: 'Hijri',
106
+ calendarDual: 'Dual',
107
+ a11yCalendarSystem: 'Calendar',
94
108
  a11yClear: 'Clear date',
95
109
  a11yOpen: 'Open date picker',
110
+ a11yClose: 'Close',
96
111
  a11yDay: 'Day',
97
112
  a11yMonth: 'Month',
98
113
  a11yYear: 'Year',
@@ -109,9 +124,19 @@ export const DEFAULT_STRINGS: PickerStrings = {
109
124
  a11yRangeEnd: 'end of range',
110
125
  };
111
126
 
127
+ /** The keys that have a value: one left `undefined` (or `null`) keeps what's under it. */
128
+ export const compactStrings = (
129
+ overrides?: Partial<PickerStrings>
130
+ ): Partial<PickerStrings> =>
131
+ overrides
132
+ ? (Object.fromEntries(
133
+ Object.entries(overrides).filter(([, v]) => v != null)
134
+ ) as Partial<PickerStrings>)
135
+ : {};
136
+
112
137
  /** The English defaults with the caller's overrides on top. */
113
138
  export const resolveStrings = (
114
139
  overrides?: Partial<PickerStrings>
115
- ): PickerStrings => {
116
- return { ...DEFAULT_STRINGS, ...overrides };
140
+ ): Required<PickerStrings> => {
141
+ return { ...DEFAULT_STRINGS, ...compactStrings(overrides) };
117
142
  };
@@ -0,0 +1,12 @@
1
+ import { createContext, useContext } from 'react';
2
+ import { I18nManager } from 'react-native';
3
+
4
+ /**
5
+ * Whether a part of the picker is laid out right to left. The picker sets it
6
+ * for the calendar and the time rows while the Hijri tab shows; elsewhere the
7
+ * app's direction (`I18nManager.isRTL`) decides.
8
+ */
9
+ export const RtlContext = createContext<boolean | null>(null);
10
+
11
+ export const useIsRTL = (): boolean =>
12
+ useContext(RtlContext) ?? I18nManager.isRTL;
@@ -0,0 +1,11 @@
1
+ import { createContext, useContext } from 'react';
2
+ import { latinDigits } from '../../core/numerals';
3
+
4
+ /**
5
+ * The digits every number in the picker is drawn with, set once by the picker
6
+ * from its `numerals` and `locale` props. Values and typed input stay 0–9.
7
+ */
8
+ export const NumeralsContext =
9
+ createContext<(text: string) => string>(latinDigits);
10
+
11
+ export const useNumerals = () => useContext(NumeralsContext);
@@ -25,6 +25,11 @@ export const STYLE_KEYS = [
25
25
  'fieldText',
26
26
  /** The value's text while the field is disabled (the placeholder keeps its own colour). */
27
27
  'fieldTextDisabled',
28
+ /**
29
+ * Sets the date of a single date-time value apart from its time, e.g.
30
+ * `{ minWidth: '50%' }` starts the time at the middle of the field.
31
+ */
32
+ 'fieldDateText',
28
33
  'fieldPlaceholder',
29
34
  'fieldSegment',
30
35
  'fieldSegmentFocused',
@@ -52,6 +57,18 @@ export const STYLE_KEYS = [
52
57
  'monthChipText',
53
58
  'monthChipSelected',
54
59
  'monthChipDisabled',
60
+ // calendar switch (calendarSwitch prop)
61
+ 'calendarSwitch',
62
+ 'calendarSwitchSegment',
63
+ 'calendarSwitchSegmentSelected',
64
+ 'calendarSwitchText',
65
+ 'calendarSwitchTextSelected',
66
+ /** The Gregorian / Hijri tabs of a dual calendar. */
67
+ 'dualTabs',
68
+ 'dualTab',
69
+ 'dualTabSelected',
70
+ 'dualTabText',
71
+ 'dualTabTextSelected',
55
72
  // weekdays
56
73
  'weekdayRow',
57
74
  'weekdayText',
@@ -73,7 +90,7 @@ export const STYLE_KEYS = [
73
90
  'disabledText',
74
91
  'holiday',
75
92
  'holidayText',
76
- /** The small Hijri day under the Gregorian one ('dual'). */
93
+ /** A second line under the day number. Not drawn by the picker any more; kept so styles that set it still compile. */
77
94
  'daySubLabel',
78
95
  // grids
79
96
  'yearGrid',
@@ -9,6 +9,8 @@ export interface ThemeTokens {
9
9
  /** Headings in the sheet: the year title and the time label. */
10
10
  heading: string;
11
11
  mutedText: string;
12
+ /** Days of the months before and after, which can still be picked. */
13
+ outsideText?: string;
12
14
  placeholder: string;
13
15
  border: string;
14
16
  /** Typed time boxes. */
@@ -46,12 +48,13 @@ export interface ThemeTokens {
46
48
  touchTarget: number;
47
49
  }
48
50
 
49
- export const DEFAULT_TOKENS: ThemeTokens = {
51
+ export const DEFAULT_TOKENS: Required<ThemeTokens> = {
50
52
  accent: '#2563EB',
51
53
  onAccent: '#FFFFFF',
52
54
  text: '#111827',
53
55
  heading: '#111827',
54
56
  mutedText: '#6B7280',
57
+ outsideText: '#6B7280',
55
58
  placeholder: '#9CA3AF',
56
59
  border: '#D1D5DB',
57
60
  inputBorder: '#D1D5DB',
@@ -109,6 +112,7 @@ export const buildTokens = (overrides?: Partial<ThemeTokens>): ThemeTokens => {
109
112
  return {
110
113
  ...DEFAULT_TOKENS,
111
114
  ...(overrides?.accent ? { borderFocused: overrides.accent } : null),
115
+ ...(overrides?.mutedText ? { outsideText: overrides.mutedText } : null),
112
116
  ...overrides,
113
117
  };
114
118
  };
@@ -1,4 +1,10 @@
1
- import React, { useCallback, useEffect, useRef, useState } from 'react';
1
+ import React, {
2
+ useCallback,
3
+ useEffect,
4
+ useMemo,
5
+ useRef,
6
+ useState,
7
+ } from 'react';
2
8
  import { Text, View } from 'react-native';
3
9
  import type { TextInputRef } from '../nativeTypes';
4
10
  import type { TimeBounds } from '../../core/constraints';
@@ -244,6 +250,20 @@ const TimeRow: React.FC<TimeRowProps> = ({
244
250
  const setRef = useCallback((key: TimeKey, r: TextInputRef | null) => {
245
251
  refs.current[key] = r;
246
252
  }, []);
253
+ // 'Start time, Hour' and 'End time, Hour' read differently, as the typed
254
+ // date field's segments do.
255
+ const boxStrings = useMemo(
256
+ () =>
257
+ label
258
+ ? {
259
+ ...strings,
260
+ a11yHour: `${label}, ${strings.a11yHour}`,
261
+ a11yMinute: `${label}, ${strings.a11yMinute}`,
262
+ a11yPeriod: `${label}, ${strings.a11yPeriod}`,
263
+ }
264
+ : strings,
265
+ [label, strings]
266
+ );
247
267
 
248
268
  return (
249
269
  <View style={s.wrapper} testID={testID}>
@@ -263,7 +283,7 @@ const TimeRow: React.FC<TimeRowProps> = ({
263
283
  disabled={disabled}
264
284
  tokens={tokens}
265
285
  styles={styles}
266
- strings={strings}
286
+ strings={boxStrings}
267
287
  testID={testID ? `${testID}-wheel` : undefined}
268
288
  />
269
289
  ) : (
@@ -282,7 +302,7 @@ const TimeRow: React.FC<TimeRowProps> = ({
282
302
  disabled={disabled}
283
303
  tokens={tokens}
284
304
  styles={styles}
285
- strings={strings}
305
+ strings={boxStrings}
286
306
  testID={testID}
287
307
  />
288
308
  )}
@@ -12,6 +12,7 @@ import type { TimeFormat } from '../../core/types';
12
12
  import type { PickerStrings } from '../theme/defaultStrings';
13
13
  import type { PickerStyles } from '../theme/styleKeys';
14
14
  import { MAX_FONT_SCALE } from '../theme/a11y';
15
+ import { useNumerals } from '../theme/numerals';
15
16
  import type { ThemeTokens } from '../theme/tokens';
16
17
  import { buildTimeStyles } from './timeStyles';
17
18
 
@@ -59,6 +60,7 @@ const TypedTime: React.FC<Props> = ({
59
60
  strings,
60
61
  testID,
61
62
  }) => {
63
+ const digits = useNumerals();
62
64
  const s = buildTimeStyles(tokens);
63
65
 
64
66
  const box = (key: TimeKey) => (
@@ -78,7 +80,7 @@ const TypedTime: React.FC<Props> = ({
78
80
  accessibilityLabel={
79
81
  key === 'hour' ? strings.a11yHour : strings.a11yMinute
80
82
  }
81
- value={values[key] ?? ''}
83
+ value={digits(values[key] ?? '')}
82
84
  placeholder={
83
85
  key === 'minute'
84
86
  ? strings.placeholderMinute