@utilitywarehouse/hearth-react-native 0.3.0 → 0.4.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 (313) hide show
  1. package/.storybook/preview.tsx +3 -0
  2. package/.turbo/turbo-build.log +1 -1
  3. package/.turbo/turbo-lint.log +3 -1
  4. package/CHANGELOG.md +22 -0
  5. package/build/components/Alert/AlertCloseButton.js +25 -3
  6. package/build/components/Alert/AlertIcon.js +17 -1
  7. package/build/components/Alert/AlertIconButton.js +27 -1
  8. package/build/components/Alert/AlertLink.js +47 -1
  9. package/build/components/Alert/AlertText.d.ts +1 -1
  10. package/build/components/Alert/AlertText.js +26 -2
  11. package/build/components/Alert/AlertTitle.d.ts +1 -1
  12. package/build/components/Alert/AlertTitle.js +26 -2
  13. package/build/components/Badge/BadgeIcon.js +72 -0
  14. package/build/components/Badge/BadgeText.js +72 -0
  15. package/build/components/Button/ButtonRoot.js +1 -0
  16. package/build/components/Checkbox/Checkbox.d.ts +2 -2
  17. package/build/components/Checkbox/Checkbox.js +11 -10
  18. package/build/components/Checkbox/Checkbox.props.d.ts +3 -1
  19. package/build/components/Checkbox/CheckboxIcon.js +1 -1
  20. package/build/components/Checkbox/CheckboxImage.d.ts +6 -0
  21. package/build/components/Checkbox/CheckboxImage.js +5 -0
  22. package/build/components/Checkbox/CheckboxTileRoot.js +1 -1
  23. package/build/components/Checkbox/index.d.ts +3 -2
  24. package/build/components/Checkbox/index.js +2 -1
  25. package/build/components/CurrencyInput/CurrencyInput.js +1 -1
  26. package/build/components/DatePicker/DatePicker.context.d.ts +19 -0
  27. package/build/components/DatePicker/DatePicker.context.js +3 -0
  28. package/build/components/DatePicker/DatePicker.d.ts +19 -0
  29. package/build/components/DatePicker/DatePicker.js +479 -0
  30. package/build/components/DatePicker/DatePicker.props.d.ts +125 -0
  31. package/build/components/DatePicker/DatePicker.props.js +1 -0
  32. package/build/components/DatePicker/DatePickerCalendar.d.ts +2 -0
  33. package/build/components/DatePicker/DatePickerCalendar.js +28 -0
  34. package/build/components/DatePicker/DatePickerDay.d.ts +11 -0
  35. package/build/components/DatePicker/DatePickerDay.js +242 -0
  36. package/build/components/DatePicker/DatePickerDays.d.ts +2 -0
  37. package/build/components/DatePicker/DatePickerDays.js +157 -0
  38. package/build/components/DatePicker/DatePickerFooter.d.ts +2 -0
  39. package/build/components/DatePicker/DatePickerFooter.js +23 -0
  40. package/build/components/DatePicker/DatePickerHeader/DatePickerHeader.props.d.ts +8 -0
  41. package/build/components/DatePicker/DatePickerHeader/DatePickerHeader.props.js +1 -0
  42. package/build/components/DatePicker/DatePickerHeader/DatePickerMonthButton.d.ts +2 -0
  43. package/build/components/DatePicker/DatePickerHeader/DatePickerMonthButton.js +14 -0
  44. package/build/components/DatePicker/DatePickerHeader/DatePickerNextButton.d.ts +2 -0
  45. package/build/components/DatePicker/DatePickerHeader/DatePickerNextButton.js +32 -0
  46. package/build/components/DatePicker/DatePickerHeader/DatePickerPrevButton.d.ts +2 -0
  47. package/build/components/DatePicker/DatePickerHeader/DatePickerPrevButton.js +32 -0
  48. package/build/components/DatePicker/DatePickerHeader/DatePickerSelectors.d.ts +6 -0
  49. package/build/components/DatePicker/DatePickerHeader/DatePickerSelectors.js +64 -0
  50. package/build/components/DatePicker/DatePickerHeader/DatePickerTimeButton.d.ts +1 -0
  51. package/build/components/DatePicker/DatePickerHeader/DatePickerTimeButton.js +22 -0
  52. package/build/components/DatePicker/DatePickerHeader/DatePickerYearButton.d.ts +2 -0
  53. package/build/components/DatePicker/DatePickerHeader/DatePickerYearButton.js +25 -0
  54. package/build/components/DatePicker/DatePickerHeader/index.d.ts +3 -0
  55. package/build/components/DatePicker/DatePickerHeader/index.js +30 -0
  56. package/build/components/DatePicker/DatePickerMonths.d.ts +2 -0
  57. package/build/components/DatePicker/DatePickerMonths.js +69 -0
  58. package/build/components/DatePicker/DatePickerWeekdays.d.ts +8 -0
  59. package/build/components/DatePicker/DatePickerWeekdays.js +26 -0
  60. package/build/components/DatePicker/DatePickerYears.d.ts +2 -0
  61. package/build/components/DatePicker/DatePickerYears.js +83 -0
  62. package/build/components/DatePicker/TimePicker.d.ts +3 -0
  63. package/build/components/DatePicker/TimePicker.js +84 -0
  64. package/build/components/DatePicker/enums.d.ts +12 -0
  65. package/build/components/DatePicker/enums.js +12 -0
  66. package/build/components/DatePicker/index.d.ts +4 -0
  67. package/build/components/DatePicker/index.js +3 -0
  68. package/build/components/DatePicker/polyfill.d.ts +0 -0
  69. package/build/components/DatePicker/polyfill.js +22 -0
  70. package/build/components/DatePicker/time-picker/animated-math.d.ts +4 -0
  71. package/build/components/DatePicker/time-picker/animated-math.js +19 -0
  72. package/build/components/DatePicker/time-picker/period-native.d.ts +6 -0
  73. package/build/components/DatePicker/time-picker/period-native.js +17 -0
  74. package/build/components/DatePicker/time-picker/period-picker.d.ts +6 -0
  75. package/build/components/DatePicker/time-picker/period-picker.js +10 -0
  76. package/build/components/DatePicker/time-picker/period-web.d.ts +6 -0
  77. package/build/components/DatePicker/time-picker/period-web.js +21 -0
  78. package/build/components/DatePicker/time-picker/wheel-native.d.ts +8 -0
  79. package/build/components/DatePicker/time-picker/wheel-native.js +19 -0
  80. package/build/components/DatePicker/time-picker/wheel-picker/index.d.ts +2 -0
  81. package/build/components/DatePicker/time-picker/wheel-picker/index.js +2 -0
  82. package/build/components/DatePicker/time-picker/wheel-picker/wheel-picker-item.d.ts +16 -0
  83. package/build/components/DatePicker/time-picker/wheel-picker/wheel-picker-item.js +97 -0
  84. package/build/components/DatePicker/time-picker/wheel-picker/wheel-picker.d.ts +21 -0
  85. package/build/components/DatePicker/time-picker/wheel-picker/wheel-picker.js +88 -0
  86. package/build/components/DatePicker/time-picker/wheel-picker/wheel-picker.style.d.ts +23 -0
  87. package/build/components/DatePicker/time-picker/wheel-picker/wheel-picker.style.js +21 -0
  88. package/build/components/DatePicker/time-picker/wheel-web.d.ts +8 -0
  89. package/build/components/DatePicker/time-picker/wheel-web.js +148 -0
  90. package/build/components/DatePicker/time-picker/wheel.d.ts +8 -0
  91. package/build/components/DatePicker/time-picker/wheel.js +10 -0
  92. package/build/components/DatePicker/utils.d.ts +212 -0
  93. package/build/components/DatePicker/utils.js +391 -0
  94. package/build/components/DatePickerInput/DatePickerInput.d.ts +6 -0
  95. package/build/components/DatePickerInput/DatePickerInput.js +126 -0
  96. package/build/components/DatePickerInput/DatePickerInput.props.d.ts +47 -0
  97. package/build/components/DatePickerInput/DatePickerInput.props.js +1 -0
  98. package/build/components/DatePickerInput/DatePickerInputDoneButton.d.ts +8 -0
  99. package/build/components/DatePickerInput/DatePickerInputDoneButton.js +19 -0
  100. package/build/components/DatePickerInput/DatePickerInputDoneButton.web.d.ts +5 -0
  101. package/build/components/DatePickerInput/DatePickerInputDoneButton.web.js +5 -0
  102. package/build/components/DatePickerInput/index.d.ts +2 -0
  103. package/build/components/DatePickerInput/index.js +1 -0
  104. package/build/components/Input/InputField.d.ts +1 -1
  105. package/build/components/Input/InputField.js +1 -1
  106. package/build/components/Input/InputSlot.d.ts +1 -1
  107. package/build/components/Input/InputSlot.js +3 -3
  108. package/build/components/Link/Link.d.ts +1 -1
  109. package/build/components/Link/Link.js +4 -4
  110. package/build/components/Link/Link.props.d.ts +3 -0
  111. package/build/components/Radio/Radio.d.ts +2 -2
  112. package/build/components/Radio/Radio.js +9 -8
  113. package/build/components/Radio/Radio.props.d.ts +3 -1
  114. package/build/components/Radio/RadioImage.d.ts +6 -0
  115. package/build/components/Radio/RadioImage.js +5 -0
  116. package/build/components/Radio/RadioTileRoot.js +1 -1
  117. package/build/components/Radio/index.d.ts +3 -2
  118. package/build/components/Radio/index.js +2 -1
  119. package/build/components/Select/SelectOption.js +1 -7
  120. package/build/components/UnstyledIconButton/UnstyledIconButton.d.ts +1 -1
  121. package/build/components/UnstyledIconButton/UnstyledIconButton.js +5 -5
  122. package/build/components/UnstyledIconButton/UnstyledIconButton.props.d.ts +2 -1
  123. package/build/components/UnstyledIconButton/UnstyledIconButtonRoot.js +1 -1
  124. package/build/components/index.d.ts +2 -0
  125. package/build/components/index.js +2 -0
  126. package/build/core/themes.d.ts +12 -12
  127. package/build/hooks/index.d.ts +4 -3
  128. package/build/hooks/index.js +4 -3
  129. package/build/hooks/usePrevious.d.ts +1 -0
  130. package/build/hooks/usePrevious.js +8 -0
  131. package/build/hooks/useTheme.d.ts +2 -1
  132. package/build/hooks/useTheme.js +2 -2
  133. package/build/tokens/color.d.ts +12 -12
  134. package/build/tokens/color.js +6 -6
  135. package/build/tokens/components/dark/alert.d.ts +13 -0
  136. package/build/tokens/components/dark/alert.js +13 -0
  137. package/build/tokens/components/dark/checkbox.d.ts +3 -0
  138. package/build/tokens/components/dark/checkbox.js +3 -0
  139. package/build/tokens/components/dark/date-picker.d.ts +1 -0
  140. package/build/tokens/components/dark/date-picker.js +1 -0
  141. package/build/tokens/components/dark/icon-button.d.ts +7 -0
  142. package/build/tokens/components/dark/icon-button.js +7 -0
  143. package/build/tokens/components/dark/illustrations.d.ts +7 -0
  144. package/build/tokens/components/dark/illustrations.js +6 -0
  145. package/build/tokens/components/dark/index.d.ts +2 -0
  146. package/build/tokens/components/dark/index.js +2 -0
  147. package/build/tokens/components/dark/link.d.ts +5 -0
  148. package/build/tokens/components/dark/link.js +5 -0
  149. package/build/tokens/components/dark/progress-bar.d.ts +41 -0
  150. package/build/tokens/components/dark/progress-bar.js +40 -0
  151. package/build/tokens/components/dark/segmented-control.d.ts +2 -2
  152. package/build/tokens/components/dark/segmented-control.js +2 -2
  153. package/build/tokens/components/dark/table.d.ts +3 -0
  154. package/build/tokens/components/dark/table.js +3 -0
  155. package/build/tokens/components/light/alert.d.ts +13 -0
  156. package/build/tokens/components/light/alert.js +13 -0
  157. package/build/tokens/components/light/checkbox.d.ts +3 -0
  158. package/build/tokens/components/light/checkbox.js +3 -0
  159. package/build/tokens/components/light/date-picker.d.ts +1 -0
  160. package/build/tokens/components/light/date-picker.js +1 -0
  161. package/build/tokens/components/light/icon-button.d.ts +7 -0
  162. package/build/tokens/components/light/icon-button.js +7 -0
  163. package/build/tokens/components/light/illustrations.d.ts +7 -0
  164. package/build/tokens/components/light/illustrations.js +6 -0
  165. package/build/tokens/components/light/index.d.ts +2 -0
  166. package/build/tokens/components/light/index.js +2 -0
  167. package/build/tokens/components/light/link.d.ts +5 -0
  168. package/build/tokens/components/light/link.js +5 -0
  169. package/build/tokens/components/light/progress-bar.d.ts +41 -0
  170. package/build/tokens/components/light/progress-bar.js +40 -0
  171. package/build/tokens/components/light/segmented-control.d.ts +2 -2
  172. package/build/tokens/components/light/segmented-control.js +2 -2
  173. package/build/tokens/components/light/table.d.ts +3 -0
  174. package/build/tokens/components/light/table.js +3 -0
  175. package/build/tokens/index.d.ts +1 -0
  176. package/build/tokens/index.js +1 -0
  177. package/build/tokens/motion.d.ts +23 -0
  178. package/build/tokens/motion.js +22 -0
  179. package/build/tokens/primitive.d.ts +19 -0
  180. package/build/tokens/primitive.js +19 -0
  181. package/build/tokens/semantic-dark.d.ts +5 -5
  182. package/build/tokens/semantic-dark.js +5 -5
  183. package/build/tokens/semantic-light.d.ts +1 -1
  184. package/build/tokens/semantic-light.js +1 -1
  185. package/build/utils/index.d.ts +1 -0
  186. package/build/utils/index.js +1 -0
  187. package/build/utils/isEqual.d.ts +2 -0
  188. package/build/utils/isEqual.js +29 -0
  189. package/chromatic.config.json +6 -0
  190. package/docs/assets/bank-logo.png +0 -0
  191. package/docs/assets/bank-logo1.png +0 -0
  192. package/docs/components/AllComponents.web.tsx +43 -1
  193. package/docs/components/ViewWrap.tsx +32 -0
  194. package/docs/components/index.ts +7 -7
  195. package/docs/getting-started.mdx +6 -6
  196. package/docs/introduction.mdx +3 -3
  197. package/package.json +16 -12
  198. package/src/components/Alert/AlertCloseButton.tsx +33 -5
  199. package/src/components/Alert/AlertIcon.tsx +17 -1
  200. package/src/components/Alert/AlertIconButton.tsx +37 -4
  201. package/src/components/Alert/AlertLink.tsx +52 -1
  202. package/src/components/Alert/AlertText.tsx +28 -3
  203. package/src/components/Alert/AlertTitle.tsx +28 -3
  204. package/src/components/Badge/BadgeIcon.tsx +72 -0
  205. package/src/components/Badge/BadgeText.tsx +72 -0
  206. package/src/components/Button/ButtonRoot.tsx +1 -0
  207. package/src/components/Checkbox/Checkbox.docs.mdx +45 -7
  208. package/src/components/Checkbox/Checkbox.props.ts +3 -1
  209. package/src/components/Checkbox/Checkbox.stories.tsx +37 -1
  210. package/src/components/Checkbox/Checkbox.tsx +12 -9
  211. package/src/components/Checkbox/CheckboxIcon.tsx +1 -1
  212. package/src/components/Checkbox/CheckboxImage.tsx +9 -0
  213. package/src/components/Checkbox/CheckboxTileRoot.tsx +1 -1
  214. package/src/components/Checkbox/index.ts +3 -2
  215. package/src/components/CurrencyInput/CurrencyInput.tsx +2 -1
  216. package/src/components/DatePicker/DatePicker.context.ts +23 -0
  217. package/src/components/DatePicker/DatePicker.docs.mdx +239 -0
  218. package/src/components/DatePicker/DatePicker.props.ts +139 -0
  219. package/src/components/DatePicker/DatePicker.stories.tsx +98 -0
  220. package/src/components/DatePicker/DatePicker.tsx +669 -0
  221. package/src/components/DatePicker/DatePickerCalendar.tsx +41 -0
  222. package/src/components/DatePicker/DatePickerDay.tsx +302 -0
  223. package/src/components/DatePicker/DatePickerDays.tsx +241 -0
  224. package/src/components/DatePicker/DatePickerFooter.tsx +35 -0
  225. package/src/components/DatePicker/DatePickerHeader/DatePickerHeader.props.ts +10 -0
  226. package/src/components/DatePicker/DatePickerHeader/DatePickerMonthButton.tsx +29 -0
  227. package/src/components/DatePicker/DatePickerHeader/DatePickerNextButton.tsx +46 -0
  228. package/src/components/DatePicker/DatePickerHeader/DatePickerPrevButton.tsx +46 -0
  229. package/src/components/DatePicker/DatePickerHeader/DatePickerSelectors.tsx +96 -0
  230. package/src/components/DatePicker/DatePickerHeader/DatePickerTimeButton.tsx +48 -0
  231. package/src/components/DatePicker/DatePickerHeader/DatePickerYearButton.tsx +50 -0
  232. package/src/components/DatePicker/DatePickerHeader/index.tsx +64 -0
  233. package/src/components/DatePicker/DatePickerMonths.tsx +101 -0
  234. package/src/components/DatePicker/DatePickerWeekdays.tsx +49 -0
  235. package/src/components/DatePicker/DatePickerYears.tsx +119 -0
  236. package/src/components/DatePicker/TimePicker.tsx +141 -0
  237. package/src/components/DatePicker/enums.ts +14 -0
  238. package/src/components/DatePicker/index.ts +13 -0
  239. package/src/components/DatePicker/polyfill.ts +21 -0
  240. package/src/components/DatePicker/time-picker/animated-math.ts +33 -0
  241. package/src/components/DatePicker/time-picker/period-native.tsx +34 -0
  242. package/src/components/DatePicker/time-picker/period-picker.tsx +16 -0
  243. package/src/components/DatePicker/time-picker/period-web.tsx +36 -0
  244. package/src/components/DatePicker/time-picker/wheel-native.tsx +37 -0
  245. package/src/components/DatePicker/time-picker/wheel-picker/index.ts +3 -0
  246. package/src/components/DatePicker/time-picker/wheel-picker/wheel-picker-item.tsx +132 -0
  247. package/src/components/DatePicker/time-picker/wheel-picker/wheel-picker.style.ts +22 -0
  248. package/src/components/DatePicker/time-picker/wheel-picker/wheel-picker.tsx +200 -0
  249. package/src/components/DatePicker/time-picker/wheel-web.tsx +181 -0
  250. package/src/components/DatePicker/time-picker/wheel.tsx +18 -0
  251. package/src/components/DatePicker/utils.ts +549 -0
  252. package/src/components/DatePickerInput/DatePickerInput.docs.mdx +237 -0
  253. package/src/components/DatePickerInput/DatePickerInput.props.ts +50 -0
  254. package/src/components/DatePickerInput/DatePickerInput.stories.tsx +178 -0
  255. package/src/components/DatePickerInput/DatePickerInput.tsx +265 -0
  256. package/src/components/DatePickerInput/DatePickerInputDoneButton.tsx +42 -0
  257. package/src/components/DatePickerInput/DatePickerInputDoneButton.web.tsx +7 -0
  258. package/src/components/DatePickerInput/index.ts +2 -0
  259. package/src/components/Icon/Icon.stories.tsx +4 -3
  260. package/src/components/IconContainer/IconContainer.docs.mdx +4 -4
  261. package/src/components/Input/InputField.tsx +0 -2
  262. package/src/components/Input/InputSlot.tsx +14 -3
  263. package/src/components/Link/Link.props.ts +3 -0
  264. package/src/components/Link/Link.tsx +12 -6
  265. package/src/components/List/List.docs.mdx +24 -23
  266. package/src/components/Modal/Modal.stories.tsx +2 -30
  267. package/src/components/Radio/Radio.docs.mdx +96 -124
  268. package/src/components/Radio/Radio.props.ts +3 -1
  269. package/src/components/Radio/Radio.stories.tsx +47 -0
  270. package/src/components/Radio/Radio.tsx +10 -7
  271. package/src/components/Radio/RadioImage.tsx +9 -0
  272. package/src/components/Radio/RadioTileRoot.tsx +1 -1
  273. package/src/components/Radio/index.ts +3 -2
  274. package/src/components/Select/Select.docs.mdx +6 -6
  275. package/src/components/Select/Select.stories.tsx +7 -7
  276. package/src/components/Select/SelectOption.tsx +4 -10
  277. package/src/components/UnstyledIconButton/UnstyledIconButton.props.ts +2 -1
  278. package/src/components/UnstyledIconButton/UnstyledIconButton.tsx +23 -5
  279. package/src/components/UnstyledIconButton/UnstyledIconButtonRoot.tsx +7 -3
  280. package/src/components/index.ts +2 -0
  281. package/src/hooks/index.ts +4 -3
  282. package/src/hooks/usePrevious.ts +9 -0
  283. package/src/hooks/useTheme.ts +4 -3
  284. package/src/tokens/color.ts +6 -6
  285. package/src/tokens/components/dark/alert.ts +13 -0
  286. package/src/tokens/components/dark/checkbox.ts +3 -0
  287. package/src/tokens/components/dark/date-picker.ts +1 -0
  288. package/src/tokens/components/dark/icon-button.ts +7 -0
  289. package/src/tokens/components/dark/illustrations.ts +7 -0
  290. package/src/tokens/components/dark/index.ts +2 -0
  291. package/src/tokens/components/dark/link.ts +5 -0
  292. package/src/tokens/components/dark/progress-bar.ts +41 -0
  293. package/src/tokens/components/dark/segmented-control.ts +2 -2
  294. package/src/tokens/components/dark/table.ts +3 -0
  295. package/src/tokens/components/light/alert.ts +13 -0
  296. package/src/tokens/components/light/checkbox.ts +3 -0
  297. package/src/tokens/components/light/date-picker.ts +1 -0
  298. package/src/tokens/components/light/icon-button.ts +7 -0
  299. package/src/tokens/components/light/illustrations.ts +7 -0
  300. package/src/tokens/components/light/index.ts +2 -0
  301. package/src/tokens/components/light/link.ts +5 -0
  302. package/src/tokens/components/light/progress-bar.ts +41 -0
  303. package/src/tokens/components/light/segmented-control.ts +2 -2
  304. package/src/tokens/components/light/table.ts +3 -0
  305. package/src/tokens/index.ts +1 -0
  306. package/src/tokens/motion.ts +23 -0
  307. package/src/tokens/primitive.ts +19 -0
  308. package/src/tokens/semantic-dark.ts +5 -5
  309. package/src/tokens/semantic-light.ts +1 -1
  310. package/src/utils/index.ts +1 -0
  311. package/src/utils/isEqual.ts +30 -0
  312. package/docs/assets/react-native-pig.png +0 -0
  313. package/docs/components/AdvancedRadioExample.tsx +0 -126
@@ -0,0 +1,96 @@
1
+ import {
2
+ ChevronDownSmallIcon,
3
+ ChevronUpSmallIcon,
4
+ } from '@utilitywarehouse/hearth-react-native-icons';
5
+ import { memo } from 'react';
6
+ import { Pressable, View } from 'react-native';
7
+ import { StyleSheet } from 'react-native-unistyles';
8
+ import { Icon } from '../../Icon';
9
+ import { useDatePickerContext } from '../DatePicker.context';
10
+ import { NavigationPosition } from '../DatePicker.props';
11
+ import MonthButton from './DatePickerMonthButton';
12
+ import { TimeButton } from './DatePickerTimeButton';
13
+ import YearButton from './DatePickerYearButton';
14
+
15
+ type Props = {
16
+ position: NavigationPosition;
17
+ };
18
+
19
+ const Selectors = ({ position }: Props) => {
20
+ const { mode, calendarView, timePicker, setCalendarView } = useDatePickerContext();
21
+ styles.useVariants({ position });
22
+ const onPress = () => {
23
+ if (calendarView === 'month' || calendarView === 'year') {
24
+ setCalendarView('day');
25
+ }
26
+ if (calendarView === 'day' || calendarView === 'time') {
27
+ setCalendarView('month');
28
+ }
29
+ };
30
+ return (
31
+ <View style={[styles.container]}>
32
+ <View style={styles.monthYearWrap}>
33
+ <View style={styles.monthAndYear}>
34
+ {calendarView !== 'year' ? <MonthButton /> : null}
35
+ <YearButton />
36
+ </View>
37
+ <Pressable
38
+ onPress={onPress}
39
+ accessibilityRole="button"
40
+ accessibilityLabel={`Change to ${calendarView === 'month' || calendarView === 'year' ? 'day' : 'month'} view`}
41
+ >
42
+ <Icon
43
+ as={
44
+ calendarView === 'month' || calendarView === 'year'
45
+ ? ChevronUpSmallIcon
46
+ : ChevronDownSmallIcon
47
+ }
48
+ style={styles.icon}
49
+ />
50
+ </Pressable>
51
+ </View>
52
+ {timePicker && mode === 'single' && calendarView !== 'year' ? <TimeButton /> : null}
53
+ </View>
54
+ );
55
+ };
56
+
57
+ const styles = StyleSheet.create(theme => ({
58
+ container: {
59
+ flex: 1,
60
+ flexDirection: 'row',
61
+ alignItems: 'center',
62
+ variants: {
63
+ position: {
64
+ left: {
65
+ justifyContent: 'space-between',
66
+ flexDirection: 'row-reverse',
67
+ },
68
+ right: {
69
+ justifyContent: 'space-between',
70
+ flexDirection: 'row',
71
+ },
72
+ around: {
73
+ justifyContent: 'space-evenly',
74
+ },
75
+ },
76
+ },
77
+ },
78
+ icon: {
79
+ color: theme.color.icon.primary,
80
+ width: 20,
81
+ height: 20,
82
+ },
83
+ monthYearWrap: {
84
+ display: 'flex',
85
+ flexDirection: 'row',
86
+ alignItems: 'center',
87
+ gap: theme.components.datePicker.calendar.header.dateGap,
88
+ },
89
+ monthAndYear: {
90
+ gap: 5,
91
+ flexDirection: 'row',
92
+ alignItems: 'center',
93
+ },
94
+ }));
95
+
96
+ export default memo(Selectors);
@@ -0,0 +1,48 @@
1
+ import dayjs from 'dayjs';
2
+ import { useMemo } from 'react';
3
+ import { Pressable } from 'react-native';
4
+ import { BodyText } from '../../BodyText';
5
+ import { useDatePickerContext } from '../DatePicker.context';
6
+ import { formatNumber, getParsedDate } from '../utils';
7
+
8
+ export const TimeButton = () => {
9
+ const {
10
+ currentDate,
11
+ date,
12
+ calendarView,
13
+ setCalendarView,
14
+ numerals = 'latn',
15
+ use12Hours,
16
+ } = useDatePickerContext();
17
+
18
+ const { hour, hour12, minute, period } = useMemo(
19
+ () => getParsedDate(date || currentDate),
20
+ [date, currentDate]
21
+ );
22
+
23
+ const labelText = useMemo(() => {
24
+ const hourValue = use12Hours ? hour12 : hour;
25
+
26
+ const hourLabel =
27
+ hourValue < 10
28
+ ? `${formatNumber(0, numerals)}${formatNumber(hourValue, numerals)}`
29
+ : `${formatNumber(hourValue, numerals)}`;
30
+
31
+ const minuteLabel =
32
+ minute < 10
33
+ ? `${formatNumber(0, numerals)}${formatNumber(minute, numerals)}`
34
+ : `${formatNumber(minute, numerals)}`;
35
+
36
+ return `${hourLabel}:${minuteLabel} ${use12Hours ? period : ''}`.trim();
37
+ }, [numerals, hour, hour12, minute, use12Hours, period]);
38
+
39
+ return (
40
+ <Pressable
41
+ onPress={() => setCalendarView(calendarView === 'time' ? 'day' : 'time')}
42
+ accessibilityRole="button"
43
+ accessibilityLabel={dayjs(date || currentDate).format('HH:mm')}
44
+ >
45
+ <BodyText weight="semibold">{labelText}</BodyText>
46
+ </Pressable>
47
+ );
48
+ };
@@ -0,0 +1,50 @@
1
+ import dayjs from 'dayjs';
2
+ import { memo } from 'react';
3
+ import { Pressable } from 'react-native';
4
+ import { StyleSheet } from 'react-native-unistyles';
5
+ import { BodyText } from '../../BodyText';
6
+ import { useDatePickerContext } from '../DatePicker.context';
7
+ import { formatNumber, getDateYear, getYearRange } from '../utils';
8
+
9
+ const YearButton = () => {
10
+ const {
11
+ currentDate,
12
+ calendarView,
13
+ setCalendarView,
14
+ currentYear,
15
+ onChangeYear,
16
+ disableYearPicker,
17
+ numerals = 'latn',
18
+ } = useDatePickerContext();
19
+
20
+ const years = getYearRange(currentYear);
21
+ return (
22
+ <Pressable
23
+ disabled={disableYearPicker}
24
+ onPress={() => {
25
+ setCalendarView(calendarView === 'year' ? 'day' : 'year');
26
+ onChangeYear(getDateYear(currentDate));
27
+ }}
28
+ testID="btn-year"
29
+ accessibilityRole="button"
30
+ accessibilityLabel={dayjs(currentDate).format('YYYY')}
31
+ accessibilityHint={`${calendarView === 'year' ? 'Tap to switch to day view' : 'Tap to switch to year view'}`}
32
+ style={[styles.container]}
33
+ >
34
+ <BodyText weight="semibold">
35
+ {calendarView === 'year'
36
+ ? `${formatNumber(years[0] || 0, numerals)} - ${formatNumber(years[years.length - 1] || 0, numerals)}`
37
+ : formatNumber(parseInt(dayjs(currentDate).format('YYYY')), numerals)}
38
+ </BodyText>
39
+ </Pressable>
40
+ );
41
+ };
42
+
43
+ const styles = StyleSheet.create({
44
+ container: {
45
+ alignItems: 'center',
46
+ justifyContent: 'center',
47
+ },
48
+ });
49
+
50
+ export default memo(YearButton);
@@ -0,0 +1,64 @@
1
+ import { memo } from 'react';
2
+ import { View } from 'react-native';
3
+ import { StyleSheet } from 'react-native-unistyles';
4
+ import type { HeaderProps, NavigationProps } from './DatePickerHeader.props';
5
+ import NextButton from './DatePickerNextButton';
6
+ import PrevButton from './DatePickerPrevButton';
7
+ import Selectors from './DatePickerSelectors';
8
+
9
+ const NavigationButtons = ({}: NavigationProps) => (
10
+ <View style={styles.navigation}>
11
+ <PrevButton />
12
+ <NextButton />
13
+ </View>
14
+ );
15
+
16
+ const Header = ({ navigationPosition = 'around' }: HeaderProps) => (
17
+ <View style={[styles.headerContainer]}>
18
+ <View style={styles.container}>
19
+ {navigationPosition === 'left' ? (
20
+ <>
21
+ <NavigationButtons />
22
+ <Selectors position="left" />
23
+ </>
24
+ ) : navigationPosition === 'right' ? (
25
+ <>
26
+ <Selectors position="right" />
27
+ <NavigationButtons />
28
+ </>
29
+ ) : (
30
+ <>
31
+ <PrevButton />
32
+ <Selectors position="around" />
33
+ <NextButton />
34
+ </>
35
+ )}
36
+ </View>
37
+ </View>
38
+ );
39
+
40
+ const styles = StyleSheet.create(theme => ({
41
+ headerContainer: {
42
+ paddingVertical: 3,
43
+ },
44
+ container: {
45
+ flexDirection: 'row',
46
+ alignItems: 'center',
47
+ justifyContent: 'space-between',
48
+ },
49
+ navigation: {
50
+ flexDirection: 'row',
51
+ gap: theme.components.datePicker.header.controlGap,
52
+ },
53
+ }));
54
+
55
+ const customComparator = (prev: Readonly<HeaderProps>, next: Readonly<HeaderProps>) => {
56
+ const areEqual =
57
+ prev.PrevIcon === next.PrevIcon &&
58
+ prev.NextIcon === next.NextIcon &&
59
+ prev.navigationPosition === next.navigationPosition;
60
+
61
+ return areEqual;
62
+ };
63
+
64
+ export default memo(Header, customComparator);
@@ -0,0 +1,101 @@
1
+ import { Pressable, View } from 'react-native';
2
+ import { StyleSheet } from 'react-native-unistyles';
3
+ import { BodyText } from '../BodyText';
4
+ import { useDatePickerContext } from './DatePicker.context';
5
+ import { CONTAINER_HEIGHT } from './enums';
6
+ import { getMonthsArray, getParsedDate, isMonthDisabled } from './utils';
7
+
8
+ const Months = () => {
9
+ const {
10
+ currentDate,
11
+ onSelectMonth,
12
+ containerHeight = CONTAINER_HEIGHT,
13
+ monthsFormat = 'short',
14
+ minDate,
15
+ maxDate,
16
+ } = useDatePickerContext();
17
+
18
+ const { month } = getParsedDate(currentDate);
19
+
20
+ return (
21
+ <View style={styles.container} testID="month-selector">
22
+ <View style={styles.months}>
23
+ {getMonthsArray().map((item, index) => {
24
+ const isSelected = index === month;
25
+ const isDisabled = isMonthDisabled(index, currentDate, {
26
+ minDate,
27
+ maxDate,
28
+ });
29
+ styles.useVariants({ isSelected, isDisabled });
30
+
31
+ return (
32
+ <View key={index} style={styles.monthCell(containerHeight)}>
33
+ <Pressable
34
+ disabled={isDisabled}
35
+ onPress={() => onSelectMonth(index)}
36
+ accessibilityRole="button"
37
+ accessibilityLabel={item.name.full}
38
+ style={styles.item}
39
+ >
40
+ <BodyText key={index} style={styles.label}>
41
+ {item.name[monthsFormat]}
42
+ </BodyText>
43
+ </Pressable>
44
+ </View>
45
+ );
46
+ })}
47
+ </View>
48
+ </View>
49
+ );
50
+ };
51
+
52
+ const styles = StyleSheet.create(theme => ({
53
+ container: {
54
+ flex: 1,
55
+ alignItems: 'center',
56
+ },
57
+ months: {
58
+ flexDirection: 'row',
59
+ flexWrap: 'wrap',
60
+ },
61
+ month: {
62
+ flex: 1,
63
+ alignItems: 'center',
64
+ justifyContent: 'center',
65
+ },
66
+ monthCell: (containerHeight: number) => ({
67
+ width: `${99.9 / 3}%`,
68
+ height: containerHeight / 6,
69
+ padding: 2,
70
+ }),
71
+ label: {
72
+ variants: {
73
+ isSelected: {
74
+ true: {
75
+ color: theme.color.text.inverted,
76
+ },
77
+ },
78
+ },
79
+ },
80
+ item: {
81
+ flex: 1,
82
+ alignItems: 'center',
83
+ justifyContent: 'center',
84
+ padding: 8,
85
+ borderRadius: theme.borderRadius.md,
86
+ variants: {
87
+ isSelected: {
88
+ true: {
89
+ backgroundColor: theme.color.surface.brand.default,
90
+ },
91
+ },
92
+ isDisabled: {
93
+ true: {
94
+ opacity: theme.opacity.disabled,
95
+ },
96
+ },
97
+ },
98
+ },
99
+ }));
100
+
101
+ export default Months;
@@ -0,0 +1,49 @@
1
+ import { memo } from 'react';
2
+ import { View } from 'react-native';
3
+ import { StyleSheet } from 'react-native-unistyles';
4
+ import { BodyText } from '../BodyText';
5
+ import { WeekdayFormat } from './DatePicker.props';
6
+ import { WEEKDAYS_HEIGHT } from './enums';
7
+ import { getWeekdays } from './utils';
8
+
9
+ type WeekdaysProps = {
10
+ firstDayOfWeek: number;
11
+ weekdaysFormat?: WeekdayFormat;
12
+ weekdaysHeight?: number;
13
+ };
14
+
15
+ const Weekdays = ({
16
+ firstDayOfWeek,
17
+ weekdaysFormat = 'min',
18
+ weekdaysHeight = WEEKDAYS_HEIGHT,
19
+ }: WeekdaysProps) => {
20
+ return (
21
+ <View style={[styles.container(weekdaysHeight)]} testID="weekdays">
22
+ {getWeekdays(firstDayOfWeek)?.map((weekday, index) => (
23
+ <View key={index} style={[styles.weekday]}>
24
+ <BodyText style={styles.text} accessible={false}>
25
+ {weekday.name[weekdaysFormat]}
26
+ </BodyText>
27
+ </View>
28
+ ))}
29
+ </View>
30
+ );
31
+ };
32
+
33
+ const styles = StyleSheet.create(theme => ({
34
+ container: (weekdaysHeight: number) => ({
35
+ height: weekdaysHeight,
36
+ flexDirection: 'row',
37
+ alignItems: 'center',
38
+ }),
39
+ text: {
40
+ color: theme.color.text.secondary,
41
+ },
42
+ weekday: {
43
+ width: `${99.9 / 7}%`,
44
+ alignItems: 'center',
45
+ justifyContent: 'center',
46
+ },
47
+ }));
48
+
49
+ export default memo(Weekdays);
@@ -0,0 +1,119 @@
1
+ import { useCallback } from 'react';
2
+ import { Pressable, View } from 'react-native';
3
+ import { StyleSheet } from 'react-native-unistyles';
4
+ import { BodyText } from '../BodyText';
5
+ import { useDatePickerContext } from './DatePicker.context';
6
+ import { CONTAINER_HEIGHT } from './enums';
7
+ import { formatNumber, getDateYear, getYearRange, isYearDisabled } from './utils';
8
+
9
+ const Years = () => {
10
+ const {
11
+ mode,
12
+ numerals = 'latn',
13
+ currentDate,
14
+ currentYear,
15
+ date,
16
+ onSelectYear,
17
+ containerHeight = CONTAINER_HEIGHT,
18
+ minDate,
19
+ maxDate,
20
+ } = useDatePickerContext();
21
+
22
+ const selectedYear = getDateYear(date);
23
+
24
+ const generateCells = useCallback(() => {
25
+ const years = getYearRange(currentYear);
26
+ const activeYear = getDateYear(currentDate);
27
+ const column = years.map(year => {
28
+ const isSelected = year === selectedYear;
29
+ const isActivated = year === activeYear;
30
+
31
+ const isDisabled = isYearDisabled(year, { minDate, maxDate });
32
+
33
+ styles.useVariants({ isSelected, isDisabled, isActivated });
34
+
35
+ return (
36
+ <View key={year} style={styles.yearCell(containerHeight)}>
37
+ <Pressable
38
+ disabled={isDisabled}
39
+ onPress={() => onSelectYear(year)}
40
+ accessibilityRole="button"
41
+ accessibilityLabel={year.toString()}
42
+ style={styles.year}
43
+ >
44
+ <BodyText key={year} style={styles.label}>
45
+ {formatNumber(year, numerals)}
46
+ </BodyText>
47
+ </Pressable>
48
+ </View>
49
+ );
50
+ });
51
+ return column;
52
+ }, [
53
+ onSelectYear,
54
+ selectedYear,
55
+ currentYear,
56
+ currentDate,
57
+ styles,
58
+ mode,
59
+ minDate,
60
+ maxDate,
61
+ numerals,
62
+ ]);
63
+
64
+ return (
65
+ <View style={[styles.container, styles.years]} testID="year-selector">
66
+ <View style={styles.years}>{generateCells()}</View>
67
+ </View>
68
+ );
69
+ };
70
+
71
+ const styles = StyleSheet.create(theme => ({
72
+ container: {
73
+ flex: 1,
74
+ alignItems: 'center',
75
+ justifyContent: 'center',
76
+ },
77
+ years: {
78
+ flexDirection: 'row',
79
+ flexWrap: 'wrap',
80
+ },
81
+ year: {
82
+ flex: 1,
83
+ alignItems: 'center',
84
+ justifyContent: 'center',
85
+ padding: 8,
86
+ borderRadius: theme.borderRadius.md,
87
+ variants: {
88
+ isActivated: {
89
+ true: {
90
+ backgroundColor: theme.color.surface.brand.default,
91
+ },
92
+ },
93
+ isDisabled: {
94
+ true: {
95
+ opacity: theme.opacity.disabled,
96
+ },
97
+ },
98
+ isSelected: {
99
+ true: {},
100
+ },
101
+ },
102
+ },
103
+ yearCell: (containerHeight: number) => ({
104
+ width: `${99.9 / 3}%`,
105
+ height: containerHeight / 6,
106
+ padding: 2,
107
+ }),
108
+ label: {
109
+ variants: {
110
+ isActivated: {
111
+ true: {
112
+ color: theme.color.text.inverted,
113
+ },
114
+ },
115
+ },
116
+ },
117
+ }));
118
+
119
+ export default Years;
@@ -0,0 +1,141 @@
1
+ import dayjs from 'dayjs';
2
+ import { useCallback, useMemo } from 'react';
3
+ import { ScrollView, View } from 'react-native';
4
+ import { StyleSheet } from 'react-native-unistyles';
5
+ import { BodyText } from '../BodyText';
6
+ import { useDatePickerContext } from './DatePicker.context';
7
+ import { Numerals, PickerOption } from './DatePicker.props';
8
+ import { CONTAINER_HEIGHT } from './enums';
9
+ import PeriodPicker from './time-picker/period-picker';
10
+ import Wheel from './time-picker/wheel';
11
+ import { formatNumber, getParsedDate } from './utils';
12
+
13
+ export type Period = 'AM' | 'PM';
14
+
15
+ const createNumberList = (
16
+ num: number,
17
+ numerals: Numerals,
18
+ startFrom: number = 0
19
+ ): PickerOption[] => {
20
+ return Array.from({ length: num }, (_, i) => ({
21
+ value: i + startFrom,
22
+ text:
23
+ i + startFrom < 10
24
+ ? `${formatNumber(0, numerals)}${formatNumber(i + startFrom, numerals)}`
25
+ : `${formatNumber(i + startFrom, numerals)}`,
26
+ }));
27
+ };
28
+
29
+ const TimePicker = () => {
30
+ const {
31
+ currentDate,
32
+ date,
33
+ onSelectDate,
34
+ timeZone,
35
+ numerals = 'latn',
36
+ use12Hours,
37
+ } = useDatePickerContext();
38
+
39
+ const hours = useMemo(
40
+ () => createNumberList(use12Hours ? 12 : 24, numerals, use12Hours ? 1 : 0),
41
+ [numerals, use12Hours]
42
+ );
43
+
44
+ const minutes = useMemo(() => createNumberList(60, numerals), [numerals]);
45
+
46
+ const { hour, hour12, minute, period } = getParsedDate(date || currentDate);
47
+
48
+ const handleChangeHour = useCallback(
49
+ (value: number) => {
50
+ let hour24 = value;
51
+
52
+ if (use12Hours) {
53
+ if (period === 'AM' && value === 12) {
54
+ hour24 = 0;
55
+ } else if (period === 'PM' && value < 12) {
56
+ hour24 = value + 12;
57
+ } else {
58
+ hour24 = value;
59
+ }
60
+ }
61
+ const newDate = dayjs.tz(date, timeZone).hour(hour24).minute(minute);
62
+ onSelectDate(newDate);
63
+ },
64
+ [date, onSelectDate, timeZone, use12Hours, period, minute]
65
+ );
66
+
67
+ const handleChangeMinute = useCallback(
68
+ (value: number) => {
69
+ const newDate = dayjs.tz(date, timeZone).minute(value);
70
+ onSelectDate(newDate);
71
+ },
72
+ [date, onSelectDate, timeZone]
73
+ );
74
+
75
+ const handlePeriodChange = useCallback(
76
+ (newPeriod: Period) => {
77
+ let newHour = hour12;
78
+ if (newPeriod === 'PM' && hour12 < 12) {
79
+ newHour = hour12 + 12;
80
+ } else if (newPeriod === 'AM' && hour12 === 12) {
81
+ newHour = 0;
82
+ } else if (newPeriod === 'AM' && hour >= 12) {
83
+ newHour = hour12;
84
+ }
85
+
86
+ const newDate = dayjs.tz(date || currentDate, timeZone).hour(newHour);
87
+ onSelectDate(newDate);
88
+ },
89
+ [date, currentDate, onSelectDate, timeZone, hour, hour12]
90
+ );
91
+
92
+ return (
93
+ <ScrollView
94
+ horizontal={true}
95
+ scrollEnabled={false}
96
+ contentContainerStyle={styles.container}
97
+ testID="time-selector"
98
+ >
99
+ <View style={styles.timePickerContainer}>
100
+ <View style={styles.wheelContainer}>
101
+ <Wheel value={use12Hours ? hour12 : hour} items={hours} setValue={handleChangeHour} />
102
+ </View>
103
+ <BodyText style={styles.timeSeparator}>:</BodyText>
104
+ <View style={styles.wheelContainer}>
105
+ <Wheel value={minute} items={minutes} setValue={handleChangeMinute} />
106
+ </View>
107
+ </View>
108
+ {use12Hours && period ? (
109
+ <View style={styles.periodContainer}>
110
+ <PeriodPicker value={period} setValue={handlePeriodChange} />
111
+ </View>
112
+ ) : null}
113
+ </ScrollView>
114
+ );
115
+ };
116
+
117
+ const styles = StyleSheet.create({
118
+ container: {
119
+ flex: 1,
120
+ alignItems: 'center',
121
+ justifyContent: 'center',
122
+ },
123
+ wheelContainer: {
124
+ flex: 1,
125
+ },
126
+ timePickerContainer: {
127
+ alignItems: 'center',
128
+ justifyContent: 'center',
129
+ width: CONTAINER_HEIGHT / 2,
130
+ height: CONTAINER_HEIGHT / 2,
131
+ flexDirection: 'row',
132
+ },
133
+ timeSeparator: {
134
+ marginHorizontal: 5,
135
+ },
136
+ periodContainer: {
137
+ marginLeft: 10,
138
+ },
139
+ });
140
+
141
+ export default TimePicker;
@@ -0,0 +1,14 @@
1
+ export type CalendarViews = 'day' | 'month' | 'year' | 'time';
2
+
3
+ export enum CalendarActionKind {
4
+ SET_CALENDAR_VIEW = 'SET_CALENDAR_VIEW',
5
+ CHANGE_CURRENT_DATE = 'CHANGE_CURRENT_DATE',
6
+ CHANGE_CURRENT_YEAR = 'CHANGE_CURRENT_YEAR',
7
+ CHANGE_SELECTED_DATE = 'CHANGE_SELECTED_DATE',
8
+ CHANGE_SELECTED_RANGE = 'CHANGE_SELECTED_RANGE',
9
+ CHANGE_SELECTED_MULTIPLE = 'CHANGE_SELECTED_MULTIPLE',
10
+ RESET_STATE = 'RESET_STATE',
11
+ }
12
+
13
+ export const CONTAINER_HEIGHT = 300;
14
+ export const WEEKDAYS_HEIGHT = 25;
@@ -0,0 +1,13 @@
1
+ import 'dayjs/locale/en';
2
+ import './polyfill';
3
+
4
+ export type {
5
+ CalendarDay,
6
+ CalendarMode,
7
+ CalendarMonth,
8
+ CalendarWeek,
9
+ CalendarYear,
10
+ DateType,
11
+ } from './DatePicker.props';
12
+
13
+ export { default as DatePicker } from './DatePicker';