@utilitywarehouse/hearth-react-native 0.3.1 → 0.4.1

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 (274) hide show
  1. package/.storybook/preview.tsx +3 -0
  2. package/.turbo/turbo-build.log +1 -1
  3. package/.turbo/turbo-lint.log +1 -1
  4. package/CHANGELOG.md +16 -0
  5. package/build/components/CurrencyInput/CurrencyInput.js +1 -1
  6. package/build/components/DatePicker/DatePicker.context.d.ts +19 -0
  7. package/build/components/DatePicker/DatePicker.context.js +3 -0
  8. package/build/components/DatePicker/DatePicker.d.ts +19 -0
  9. package/build/components/DatePicker/DatePicker.js +479 -0
  10. package/build/components/DatePicker/DatePicker.props.d.ts +125 -0
  11. package/build/components/DatePicker/DatePicker.props.js +1 -0
  12. package/build/components/DatePicker/DatePickerCalendar.d.ts +2 -0
  13. package/build/components/DatePicker/DatePickerCalendar.js +28 -0
  14. package/build/components/DatePicker/DatePickerDay.d.ts +11 -0
  15. package/build/components/DatePicker/DatePickerDay.js +242 -0
  16. package/build/components/DatePicker/DatePickerDays.d.ts +2 -0
  17. package/build/components/DatePicker/DatePickerDays.js +157 -0
  18. package/build/components/DatePicker/DatePickerFooter.d.ts +2 -0
  19. package/build/components/DatePicker/DatePickerFooter.js +23 -0
  20. package/build/components/DatePicker/DatePickerHeader/DatePickerHeader.props.d.ts +8 -0
  21. package/build/components/DatePicker/DatePickerHeader/DatePickerHeader.props.js +1 -0
  22. package/build/components/DatePicker/DatePickerHeader/DatePickerMonthButton.d.ts +2 -0
  23. package/build/components/DatePicker/DatePickerHeader/DatePickerMonthButton.js +14 -0
  24. package/build/components/DatePicker/DatePickerHeader/DatePickerNextButton.d.ts +2 -0
  25. package/build/components/DatePicker/DatePickerHeader/DatePickerNextButton.js +32 -0
  26. package/build/components/DatePicker/DatePickerHeader/DatePickerPrevButton.d.ts +2 -0
  27. package/build/components/DatePicker/DatePickerHeader/DatePickerPrevButton.js +32 -0
  28. package/build/components/DatePicker/DatePickerHeader/DatePickerSelectors.d.ts +6 -0
  29. package/build/components/DatePicker/DatePickerHeader/DatePickerSelectors.js +64 -0
  30. package/build/components/DatePicker/DatePickerHeader/DatePickerTimeButton.d.ts +1 -0
  31. package/build/components/DatePicker/DatePickerHeader/DatePickerTimeButton.js +22 -0
  32. package/build/components/DatePicker/DatePickerHeader/DatePickerYearButton.d.ts +2 -0
  33. package/build/components/DatePicker/DatePickerHeader/DatePickerYearButton.js +25 -0
  34. package/build/components/DatePicker/DatePickerHeader/index.d.ts +3 -0
  35. package/build/components/DatePicker/DatePickerHeader/index.js +30 -0
  36. package/build/components/DatePicker/DatePickerMonths.d.ts +2 -0
  37. package/build/components/DatePicker/DatePickerMonths.js +69 -0
  38. package/build/components/DatePicker/DatePickerWeekdays.d.ts +8 -0
  39. package/build/components/DatePicker/DatePickerWeekdays.js +26 -0
  40. package/build/components/DatePicker/DatePickerYears.d.ts +2 -0
  41. package/build/components/DatePicker/DatePickerYears.js +83 -0
  42. package/build/components/DatePicker/TimePicker.d.ts +3 -0
  43. package/build/components/DatePicker/TimePicker.js +84 -0
  44. package/build/components/DatePicker/enums.d.ts +12 -0
  45. package/build/components/DatePicker/enums.js +12 -0
  46. package/build/components/DatePicker/index.d.ts +4 -0
  47. package/build/components/DatePicker/index.js +3 -0
  48. package/build/components/DatePicker/polyfill.d.ts +0 -0
  49. package/build/components/DatePicker/polyfill.js +22 -0
  50. package/build/components/DatePicker/time-picker/animated-math.d.ts +4 -0
  51. package/build/components/DatePicker/time-picker/animated-math.js +19 -0
  52. package/build/components/DatePicker/time-picker/period-native.d.ts +6 -0
  53. package/build/components/DatePicker/time-picker/period-native.js +17 -0
  54. package/build/components/DatePicker/time-picker/period-picker.d.ts +6 -0
  55. package/build/components/DatePicker/time-picker/period-picker.js +10 -0
  56. package/build/components/DatePicker/time-picker/period-web.d.ts +6 -0
  57. package/build/components/DatePicker/time-picker/period-web.js +21 -0
  58. package/build/components/DatePicker/time-picker/wheel-native.d.ts +8 -0
  59. package/build/components/DatePicker/time-picker/wheel-native.js +19 -0
  60. package/build/components/DatePicker/time-picker/wheel-picker/index.d.ts +2 -0
  61. package/build/components/DatePicker/time-picker/wheel-picker/index.js +2 -0
  62. package/build/components/DatePicker/time-picker/wheel-picker/wheel-picker-item.d.ts +16 -0
  63. package/build/components/DatePicker/time-picker/wheel-picker/wheel-picker-item.js +97 -0
  64. package/build/components/DatePicker/time-picker/wheel-picker/wheel-picker.d.ts +21 -0
  65. package/build/components/DatePicker/time-picker/wheel-picker/wheel-picker.js +88 -0
  66. package/build/components/DatePicker/time-picker/wheel-picker/wheel-picker.style.d.ts +23 -0
  67. package/build/components/DatePicker/time-picker/wheel-picker/wheel-picker.style.js +21 -0
  68. package/build/components/DatePicker/time-picker/wheel-web.d.ts +8 -0
  69. package/build/components/DatePicker/time-picker/wheel-web.js +148 -0
  70. package/build/components/DatePicker/time-picker/wheel.d.ts +8 -0
  71. package/build/components/DatePicker/time-picker/wheel.js +10 -0
  72. package/build/components/DatePicker/utils.d.ts +212 -0
  73. package/build/components/DatePicker/utils.js +391 -0
  74. package/build/components/DatePickerInput/DatePickerInput.d.ts +6 -0
  75. package/build/components/DatePickerInput/DatePickerInput.js +126 -0
  76. package/build/components/DatePickerInput/DatePickerInput.props.d.ts +47 -0
  77. package/build/components/DatePickerInput/DatePickerInput.props.js +1 -0
  78. package/build/components/DatePickerInput/DatePickerInputDoneButton.d.ts +8 -0
  79. package/build/components/DatePickerInput/DatePickerInputDoneButton.js +19 -0
  80. package/build/components/DatePickerInput/DatePickerInputDoneButton.web.d.ts +5 -0
  81. package/build/components/DatePickerInput/DatePickerInputDoneButton.web.js +5 -0
  82. package/build/components/DatePickerInput/index.d.ts +2 -0
  83. package/build/components/DatePickerInput/index.js +1 -0
  84. package/build/components/Input/InputField.d.ts +1 -1
  85. package/build/components/Input/InputField.js +1 -1
  86. package/build/components/Input/InputSlot.d.ts +1 -1
  87. package/build/components/Input/InputSlot.js +3 -3
  88. package/build/components/UnstyledIconButton/UnstyledIconButton.js +2 -2
  89. package/build/components/UnstyledIconButton/UnstyledIconButtonRoot.js +1 -1
  90. package/build/components/index.d.ts +2 -0
  91. package/build/components/index.js +2 -0
  92. package/build/core/themes.d.ts +482 -0
  93. package/build/core/themes.js +31 -0
  94. package/build/hooks/index.d.ts +4 -3
  95. package/build/hooks/index.js +4 -3
  96. package/build/hooks/usePrevious.d.ts +1 -0
  97. package/build/hooks/usePrevious.js +8 -0
  98. package/build/hooks/useTheme.d.ts +2 -1
  99. package/build/hooks/useTheme.js +2 -2
  100. package/build/legacyTokens/common/brand.d.ts +16 -0
  101. package/build/legacyTokens/common/brand.js +17 -0
  102. package/build/legacyTokens/common/index.d.ts +8 -0
  103. package/build/legacyTokens/common/index.js +9 -0
  104. package/build/legacyTokens/common/service.d.ts +20 -0
  105. package/build/legacyTokens/common/service.js +21 -0
  106. package/build/legacyTokens/dark/apple.d.ts +28 -0
  107. package/build/legacyTokens/dark/apple.js +29 -0
  108. package/build/legacyTokens/dark/cyan.d.ts +48 -0
  109. package/build/legacyTokens/dark/cyan.js +49 -0
  110. package/build/legacyTokens/dark/gold.d.ts +44 -0
  111. package/build/legacyTokens/dark/gold.js +45 -0
  112. package/build/legacyTokens/dark/grape.d.ts +28 -0
  113. package/build/legacyTokens/dark/grape.js +29 -0
  114. package/build/legacyTokens/dark/green.d.ts +40 -0
  115. package/build/legacyTokens/dark/green.js +41 -0
  116. package/build/legacyTokens/dark/grey.d.ts +60 -0
  117. package/build/legacyTokens/dark/grey.js +61 -0
  118. package/build/legacyTokens/dark/index.d.ts +40 -0
  119. package/build/legacyTokens/dark/index.js +41 -0
  120. package/build/legacyTokens/dark/pink.d.ts +28 -0
  121. package/build/legacyTokens/dark/pink.js +29 -0
  122. package/build/legacyTokens/dark/purple.d.ts +48 -0
  123. package/build/legacyTokens/dark/purple.js +49 -0
  124. package/build/legacyTokens/dark/red.d.ts +40 -0
  125. package/build/legacyTokens/dark/red.js +41 -0
  126. package/build/legacyTokens/dark/rose.d.ts +28 -0
  127. package/build/legacyTokens/dark/rose.js +29 -0
  128. package/build/legacyTokens/index.d.ts +12 -0
  129. package/build/legacyTokens/index.js +13 -0
  130. package/build/legacyTokens/light/apple.d.ts +28 -0
  131. package/build/legacyTokens/light/apple.js +29 -0
  132. package/build/legacyTokens/light/cyan.d.ts +48 -0
  133. package/build/legacyTokens/light/cyan.js +49 -0
  134. package/build/legacyTokens/light/gold.d.ts +44 -0
  135. package/build/legacyTokens/light/gold.js +45 -0
  136. package/build/legacyTokens/light/grape.d.ts +28 -0
  137. package/build/legacyTokens/light/grape.js +29 -0
  138. package/build/legacyTokens/light/green.d.ts +40 -0
  139. package/build/legacyTokens/light/green.js +41 -0
  140. package/build/legacyTokens/light/grey.d.ts +60 -0
  141. package/build/legacyTokens/light/grey.js +61 -0
  142. package/build/legacyTokens/light/index.d.ts +40 -0
  143. package/build/legacyTokens/light/index.js +41 -0
  144. package/build/legacyTokens/light/pink.d.ts +28 -0
  145. package/build/legacyTokens/light/pink.js +29 -0
  146. package/build/legacyTokens/light/purple.d.ts +48 -0
  147. package/build/legacyTokens/light/purple.js +49 -0
  148. package/build/legacyTokens/light/red.d.ts +40 -0
  149. package/build/legacyTokens/light/red.js +41 -0
  150. package/build/legacyTokens/light/rose.d.ts +32 -0
  151. package/build/legacyTokens/light/rose.js +33 -0
  152. package/build/tokens/components/dark/date-picker.d.ts +1 -0
  153. package/build/tokens/components/dark/date-picker.js +1 -0
  154. package/build/tokens/components/dark/illustrations.d.ts +7 -0
  155. package/build/tokens/components/dark/illustrations.js +6 -0
  156. package/build/tokens/components/dark/index.d.ts +1 -0
  157. package/build/tokens/components/dark/index.js +1 -0
  158. package/build/tokens/components/dark/segmented-control.d.ts +2 -2
  159. package/build/tokens/components/dark/segmented-control.js +2 -2
  160. package/build/tokens/components/dark/table.d.ts +3 -0
  161. package/build/tokens/components/dark/table.js +3 -0
  162. package/build/tokens/components/light/date-picker.d.ts +1 -0
  163. package/build/tokens/components/light/date-picker.js +1 -0
  164. package/build/tokens/components/light/illustrations.d.ts +7 -0
  165. package/build/tokens/components/light/illustrations.js +6 -0
  166. package/build/tokens/components/light/index.d.ts +1 -0
  167. package/build/tokens/components/light/index.js +1 -0
  168. package/build/tokens/components/light/segmented-control.d.ts +2 -2
  169. package/build/tokens/components/light/segmented-control.js +2 -2
  170. package/build/tokens/components/light/table.d.ts +3 -0
  171. package/build/tokens/components/light/table.js +3 -0
  172. package/build/utils/index.d.ts +1 -0
  173. package/build/utils/index.js +1 -0
  174. package/build/utils/isEqual.d.ts +2 -0
  175. package/build/utils/isEqual.js +29 -0
  176. package/chromatic.config.json +6 -0
  177. package/docs/components/AllComponents.web.tsx +43 -1
  178. package/docs/components/ViewWrap.tsx +32 -0
  179. package/docs/components/index.ts +1 -0
  180. package/docs/getting-started.mdx +6 -6
  181. package/package.json +11 -8
  182. package/src/components/CurrencyInput/CurrencyInput.tsx +2 -1
  183. package/src/components/DatePicker/DatePicker.context.ts +23 -0
  184. package/src/components/DatePicker/DatePicker.docs.mdx +239 -0
  185. package/src/components/DatePicker/DatePicker.props.ts +139 -0
  186. package/src/components/DatePicker/DatePicker.stories.tsx +98 -0
  187. package/src/components/DatePicker/DatePicker.tsx +669 -0
  188. package/src/components/DatePicker/DatePickerCalendar.tsx +41 -0
  189. package/src/components/DatePicker/DatePickerDay.tsx +302 -0
  190. package/src/components/DatePicker/DatePickerDays.tsx +241 -0
  191. package/src/components/DatePicker/DatePickerFooter.tsx +35 -0
  192. package/src/components/DatePicker/DatePickerHeader/DatePickerHeader.props.ts +10 -0
  193. package/src/components/DatePicker/DatePickerHeader/DatePickerMonthButton.tsx +29 -0
  194. package/src/components/DatePicker/DatePickerHeader/DatePickerNextButton.tsx +46 -0
  195. package/src/components/DatePicker/DatePickerHeader/DatePickerPrevButton.tsx +46 -0
  196. package/src/components/DatePicker/DatePickerHeader/DatePickerSelectors.tsx +96 -0
  197. package/src/components/DatePicker/DatePickerHeader/DatePickerTimeButton.tsx +48 -0
  198. package/src/components/DatePicker/DatePickerHeader/DatePickerYearButton.tsx +50 -0
  199. package/src/components/DatePicker/DatePickerHeader/index.tsx +64 -0
  200. package/src/components/DatePicker/DatePickerMonths.tsx +101 -0
  201. package/src/components/DatePicker/DatePickerWeekdays.tsx +49 -0
  202. package/src/components/DatePicker/DatePickerYears.tsx +119 -0
  203. package/src/components/DatePicker/TimePicker.tsx +141 -0
  204. package/src/components/DatePicker/enums.ts +14 -0
  205. package/src/components/DatePicker/index.ts +13 -0
  206. package/src/components/DatePicker/polyfill.ts +21 -0
  207. package/src/components/DatePicker/time-picker/animated-math.ts +33 -0
  208. package/src/components/DatePicker/time-picker/period-native.tsx +34 -0
  209. package/src/components/DatePicker/time-picker/period-picker.tsx +16 -0
  210. package/src/components/DatePicker/time-picker/period-web.tsx +36 -0
  211. package/src/components/DatePicker/time-picker/wheel-native.tsx +37 -0
  212. package/src/components/DatePicker/time-picker/wheel-picker/index.ts +3 -0
  213. package/src/components/DatePicker/time-picker/wheel-picker/wheel-picker-item.tsx +132 -0
  214. package/src/components/DatePicker/time-picker/wheel-picker/wheel-picker.style.ts +22 -0
  215. package/src/components/DatePicker/time-picker/wheel-picker/wheel-picker.tsx +200 -0
  216. package/src/components/DatePicker/time-picker/wheel-web.tsx +181 -0
  217. package/src/components/DatePicker/time-picker/wheel.tsx +18 -0
  218. package/src/components/DatePicker/utils.ts +549 -0
  219. package/src/components/DatePickerInput/DatePickerInput.docs.mdx +237 -0
  220. package/src/components/DatePickerInput/DatePickerInput.props.ts +50 -0
  221. package/src/components/DatePickerInput/DatePickerInput.stories.tsx +178 -0
  222. package/src/components/DatePickerInput/DatePickerInput.tsx +265 -0
  223. package/src/components/DatePickerInput/DatePickerInputDoneButton.tsx +42 -0
  224. package/src/components/DatePickerInput/DatePickerInputDoneButton.web.tsx +7 -0
  225. package/src/components/DatePickerInput/index.ts +2 -0
  226. package/src/components/Icon/Icon.stories.tsx +4 -3
  227. package/src/components/Input/InputField.tsx +0 -2
  228. package/src/components/Input/InputSlot.tsx +14 -3
  229. package/src/components/Modal/Modal.stories.tsx +2 -30
  230. package/src/components/UnstyledIconButton/UnstyledIconButton.tsx +14 -2
  231. package/src/components/UnstyledIconButton/UnstyledIconButtonRoot.tsx +7 -3
  232. package/src/components/index.ts +2 -0
  233. package/src/core/themes.ts +31 -0
  234. package/src/hooks/index.ts +4 -3
  235. package/src/hooks/usePrevious.ts +9 -0
  236. package/src/hooks/useTheme.ts +4 -3
  237. package/src/legacyTokens/common/brand.ts +18 -0
  238. package/src/legacyTokens/common/index.ts +10 -0
  239. package/src/legacyTokens/common/service.ts +22 -0
  240. package/src/legacyTokens/dark/apple.ts +30 -0
  241. package/src/legacyTokens/dark/cyan.ts +50 -0
  242. package/src/legacyTokens/dark/gold.ts +46 -0
  243. package/src/legacyTokens/dark/grape.ts +30 -0
  244. package/src/legacyTokens/dark/green.ts +42 -0
  245. package/src/legacyTokens/dark/grey.ts +62 -0
  246. package/src/legacyTokens/dark/index.ts +42 -0
  247. package/src/legacyTokens/dark/pink.ts +30 -0
  248. package/src/legacyTokens/dark/purple.ts +50 -0
  249. package/src/legacyTokens/dark/red.ts +42 -0
  250. package/src/legacyTokens/dark/rose.ts +30 -0
  251. package/src/legacyTokens/index.ts +14 -0
  252. package/src/legacyTokens/light/apple.ts +30 -0
  253. package/src/legacyTokens/light/cyan.ts +50 -0
  254. package/src/legacyTokens/light/gold.ts +46 -0
  255. package/src/legacyTokens/light/grape.ts +30 -0
  256. package/src/legacyTokens/light/green.ts +42 -0
  257. package/src/legacyTokens/light/grey.ts +62 -0
  258. package/src/legacyTokens/light/index.ts +42 -0
  259. package/src/legacyTokens/light/pink.ts +30 -0
  260. package/src/legacyTokens/light/purple.ts +50 -0
  261. package/src/legacyTokens/light/red.ts +42 -0
  262. package/src/legacyTokens/light/rose.ts +34 -0
  263. package/src/tokens/components/dark/date-picker.ts +1 -0
  264. package/src/tokens/components/dark/illustrations.ts +7 -0
  265. package/src/tokens/components/dark/index.ts +1 -0
  266. package/src/tokens/components/dark/segmented-control.ts +2 -2
  267. package/src/tokens/components/dark/table.ts +3 -0
  268. package/src/tokens/components/light/date-picker.ts +1 -0
  269. package/src/tokens/components/light/illustrations.ts +7 -0
  270. package/src/tokens/components/light/index.ts +1 -0
  271. package/src/tokens/components/light/segmented-control.ts +2 -2
  272. package/src/tokens/components/light/table.ts +3 -0
  273. package/src/utils/index.ts +1 -0
  274. package/src/utils/isEqual.ts +30 -0
@@ -20,6 +20,7 @@ export default {
20
20
  item: {
21
21
  borderRadius: 8,
22
22
  minWidth: 32,
23
+ rangeBackground: '#f7f7f7',
23
24
  roundelBackgroundColorInverted: '#fcfbf2',
24
25
  roundelHeight: 6,
25
26
  roundelWidth: 6,
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Do not edit directly, this file was auto-generated.
3
+ */
4
+ declare const _default: {
5
+ readonly mode: "light";
6
+ };
7
+ export default _default;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Do not edit directly, this file was auto-generated.
3
+ */
4
+ export default {
5
+ mode: 'light',
6
+ };
@@ -21,6 +21,7 @@ export { default as expandableCard } from './expandable-card';
21
21
  export { default as formField } from './form-field';
22
22
  export { default as iconButton } from './icon-button';
23
23
  export { default as iconContainer } from './icon-container';
24
+ export { default as illustrations } from './illustrations';
24
25
  export { default as indicatorIconButton } from './indicator-icon-button';
25
26
  export { default as inlineLink } from './inline-link';
26
27
  export { default as input } from './input';
@@ -21,6 +21,7 @@ export { default as expandableCard } from './expandable-card';
21
21
  export { default as formField } from './form-field';
22
22
  export { default as iconButton } from './icon-button';
23
23
  export { default as iconContainer } from './icon-container';
24
+ export { default as illustrations } from './illustrations';
24
25
  export { default as indicatorIconButton } from './indicator-icon-button';
25
26
  export { default as inlineLink } from './inline-link';
26
27
  export { default as input } from './input';
@@ -2,10 +2,10 @@
2
2
  * Do not edit directly, this file was auto-generated.
3
3
  */
4
4
  declare const _default: {
5
- readonly borderRadius: 6;
5
+ readonly borderRadius: 9999;
6
6
  readonly gap: 6;
7
7
  readonly group: {
8
- readonly borderRadius: 8;
8
+ readonly borderRadius: 9999;
9
9
  readonly borderWidth: 1;
10
10
  readonly gap: 4;
11
11
  readonly height: 48;
@@ -2,10 +2,10 @@
2
2
  * Do not edit directly, this file was auto-generated.
3
3
  */
4
4
  export default {
5
- borderRadius: 6,
5
+ borderRadius: 9999,
6
6
  gap: 6,
7
7
  group: {
8
- borderRadius: 8,
8
+ borderRadius: 9999,
9
9
  borderWidth: 1,
10
10
  gap: 4,
11
11
  height: 48,
@@ -13,6 +13,9 @@ declare const _default: {
13
13
  readonly headerCell: {
14
14
  readonly borderWidth: 2;
15
15
  readonly gap: 8;
16
+ readonly neutral: {
17
+ readonly backgroundColor: "#f1efe4";
18
+ };
16
19
  readonly paddingHorizontal: 12;
17
20
  readonly paddingVertical: 16;
18
21
  };
@@ -13,6 +13,9 @@ export default {
13
13
  headerCell: {
14
14
  borderWidth: 2,
15
15
  gap: 8,
16
+ neutral: {
17
+ backgroundColor: '#f1efe4',
18
+ },
16
19
  paddingHorizontal: 12,
17
20
  paddingVertical: 16,
18
21
  },
@@ -3,4 +3,5 @@ export { default as formatThousands } from './formatThousands';
3
3
  export { default as getFlattenedColorValue } from './getFlattenedColorValue';
4
4
  export { default as getStyleValue } from './getStyleValue';
5
5
  export { default as hexWithOpacity } from './hexWithOpacity';
6
+ export { default as isEqual } from './isEqual';
6
7
  export * from './styleUtils';
@@ -3,4 +3,5 @@ export { default as formatThousands } from './formatThousands';
3
3
  export { default as getFlattenedColorValue } from './getFlattenedColorValue';
4
4
  export { default as getStyleValue } from './getStyleValue';
5
5
  export { default as hexWithOpacity } from './hexWithOpacity';
6
+ export { default as isEqual } from './isEqual';
6
7
  export * from './styleUtils';
@@ -0,0 +1,2 @@
1
+ declare const isEqual: (a: any, b: any) => boolean;
2
+ export default isEqual;
@@ -0,0 +1,29 @@
1
+ const isEqual = (a, b) => {
2
+ if (a === b)
3
+ return true;
4
+ if (typeof a !== typeof b)
5
+ return false;
6
+ if (typeof a !== 'object' || a === null || b === null)
7
+ return false;
8
+ if (Array.isArray(a) !== Array.isArray(b))
9
+ return false;
10
+ if (Array.isArray(a)) {
11
+ if (a.length !== b.length)
12
+ return false;
13
+ for (let i = 0; i < a.length; i++) {
14
+ if (!isEqual(a[i], b[i]))
15
+ return false;
16
+ }
17
+ return true;
18
+ }
19
+ const keysA = Object.keys(a);
20
+ const keysB = Object.keys(b);
21
+ if (keysA.length !== keysB.length)
22
+ return false;
23
+ for (const key of keysA) {
24
+ if (!keysB.includes(key) || !isEqual(a[key], b[key]))
25
+ return false;
26
+ }
27
+ return true;
28
+ };
29
+ export default isEqual;
@@ -0,0 +1,6 @@
1
+ {
2
+ "onlyChanged": true,
3
+ "projectId": "Project:68e3ad5c6e80b57678cad6c6",
4
+ "storybookBaseDir": "packages/react-native",
5
+ "zip": true
6
+ }
@@ -1,4 +1,4 @@
1
- import React, { useCallback, useEffect, useRef } from 'react';
1
+ import React, { useCallback, useEffect, useRef, useState } from 'react';
2
2
 
3
3
  import { BottomSheetModalMethods } from '@gorhom/bottom-sheet/lib/typescript/types';
4
4
  import {
@@ -18,6 +18,7 @@ import {
18
18
  Badge,
19
19
  BodyText,
20
20
  BottomSheet,
21
+ BottomSheetModal,
21
22
  BottomSheetModalProvider,
22
23
  BottomSheetView,
23
24
  Box,
@@ -26,6 +27,9 @@ import {
26
27
  Center,
27
28
  Checkbox,
28
29
  CurrencyInput,
30
+ DatePicker,
31
+ DatePickerInput,
32
+ DateType,
29
33
  DescriptionList,
30
34
  DescriptionListItem,
31
35
  DetailText,
@@ -110,6 +114,11 @@ const AllComponents: React.FC = () => {
110
114
  const handleModalOpenPress = useCallback(() => {
111
115
  modalRef.current?.present();
112
116
  }, []);
117
+ const [selected, setSelected] = useState<DateType>();
118
+ const datePickerRef = useRef<BottomSheetModal>(null);
119
+ const handleDatePickerOpenPress = useCallback(() => {
120
+ datePickerRef.current?.present();
121
+ }, []);
113
122
  useEffect(() => {
114
123
  if (bottomSheetRef.current) {
115
124
  setTimeout(() => {
@@ -124,8 +133,16 @@ const AllComponents: React.FC = () => {
124
133
  }, 400);
125
134
  }
126
135
  }, [modalRef]);
136
+ useEffect(() => {
137
+ if (datePickerRef.current) {
138
+ setTimeout(() => {
139
+ datePickerRef.current?.present();
140
+ }, 500);
141
+ }
142
+ }, [datePickerRef]);
127
143
  const [switchEnabled, setSwitchEnabled] = React.useState(false);
128
144
  const toggleSwitch = () => setSwitchEnabled(!switchEnabled);
145
+
129
146
  const [colorMode] = useColorMode();
130
147
  const isDark = colorMode === 'dark';
131
148
  return (
@@ -225,6 +242,30 @@ const AllComponents: React.FC = () => {
225
242
  <CurrencyInput />
226
243
  </Center>
227
244
  </ComponentWrapper>
245
+ <ComponentWrapper name="Date Picker" link="/?path=/docs/components-date-picker--docs">
246
+ <Center flex={1}>
247
+ <Button onPress={handleDatePickerOpenPress}>Open Date Picker</Button>
248
+ <BottomSheetModalProvider>
249
+ <DatePicker
250
+ ref={datePickerRef}
251
+ mode="single"
252
+ date={selected}
253
+ onChange={({ date }) => setSelected(date)}
254
+ onCancel={() => setSelected(undefined)}
255
+ />
256
+ </BottomSheetModalProvider>
257
+ </Center>
258
+ </ComponentWrapper>
259
+ <ComponentWrapper
260
+ name="Date Picker Input"
261
+ link="/?path=/docs/forms-date-picker-input--docs"
262
+ >
263
+ <Center flex={1} padding="200">
264
+ <BottomSheetModalProvider>
265
+ <DatePickerInput placeholder="DD/MM/YYYY" />
266
+ </BottomSheetModalProvider>
267
+ </Center>
268
+ </ComponentWrapper>
228
269
  <ComponentWrapper
229
270
  name="Description List"
230
271
  link="/?path=/docs/components-description-list--docs"
@@ -241,6 +282,7 @@ const AllComponents: React.FC = () => {
241
282
  <DetailText>This is some Detail Text</DetailText>
242
283
  </Center>
243
284
  </ComponentWrapper>
285
+
244
286
  <ComponentWrapper name="Divider" link="/?path=/docs/components-divider--docs">
245
287
  <Center flex={1} p="300">
246
288
  <BodyText>This text is divided</BodyText>
@@ -0,0 +1,32 @@
1
+ import { Dimensions, Platform, View, ViewProps } from 'react-native';
2
+ import { UnistylesRuntime } from '../../src/core';
3
+
4
+ const ViewWrap = ({ children }: { children: ViewProps['children'] }) => (
5
+ <View
6
+ style={{
7
+ width: Platform.OS === 'web' ? '100%' : Dimensions.get('window').width,
8
+ height:
9
+ Platform.OS === 'web'
10
+ ? '100%'
11
+ : Dimensions.get('window').height -
12
+ UnistylesRuntime.insets.top -
13
+ UnistylesRuntime.insets.bottom -
14
+ 33,
15
+
16
+ position: 'absolute',
17
+ top: 0,
18
+ left: 0,
19
+ right: 0,
20
+ bottom: 0,
21
+ flex: 1,
22
+ marginVertical: Platform.OS === 'web' ? 0 : -8,
23
+ justifyContent: 'center',
24
+ alignItems: 'center',
25
+ padding: 16,
26
+ }}
27
+ >
28
+ {children}
29
+ </View>
30
+ );
31
+
32
+ export default ViewWrap;
@@ -8,3 +8,4 @@ export { default as SwitchList } from './SwitchList';
8
8
  export { default as UsageWrap } from './UsageWrap';
9
9
  export { default as VariantTitle } from './VariantTitle';
10
10
  export { default as ViewFigmaButton } from './ViewFigmaButton';
11
+ export { default as ViewWrap } from './ViewWrap';
@@ -9,12 +9,12 @@ import { BackToTopButton, NextPrevPage } from './components';
9
9
  You can just start using the components from the `@utilitywarehouse/hearth-react-native` package.
10
10
 
11
11
  ```tsx
12
- import { Box, Alert, Text } from '@utilitywarehouse/hearth-react-native';
12
+ import { Box, Alert, BodyText } from '@utilitywarehouse/hearth-react-native';
13
13
 
14
14
  const App: React.FC = () => (
15
- <Box>
15
+ <Box p="200">
16
16
  <Alert variant="info" text="Welcome to Hearth React Native!" />
17
- <Text>Start building your app with Hearth React Native components.</Text>
17
+ <BodyText>Start building your app with Hearth React Native components.</BodyText>
18
18
  </Box>
19
19
  );
20
20
  ```
@@ -25,15 +25,15 @@ By default the light colour mode is enabled. If you want to enable dark mode, yo
25
25
  use the `useColorMode` hook to toggle between light and dark modes.
26
26
 
27
27
  ```tsx
28
- import { useColorMode, Box, Alert, Text, Button } from '@utilitywarehouse/hearth-react-native';
28
+ import { useColorMode, Box, Alert, BodyText, Button } from '@utilitywarehouse/hearth-react-native';
29
29
 
30
30
  const App: React.FC = () => {
31
31
  const [colorMode, setColorMode] = useColorMode();
32
32
 
33
33
  return (
34
- <Box>
34
+ <Box p="200">
35
35
  <Alert variant="info" text="Welcome to Hearth React Native!" />
36
- <Text>Start building your app with Hearth React Native components.</Text>
36
+ <BodyText>Start building your app with Hearth React Native components.</BodyText>
37
37
  <Button onPress={() => setColorMode(colorMode === 'light' ? 'dark' : 'light')}>
38
38
  Toggle Color Mode
39
39
  </Button>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@utilitywarehouse/hearth-react-native",
3
- "version": "0.3.1",
3
+ "version": "0.4.1",
4
4
  "description": "Utility Warehouse React Native UI library",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -8,7 +8,6 @@
8
8
  "type": "module",
9
9
  "sideEffects": false,
10
10
  "dependencies": {
11
- "@expo/html-elements": "latest",
12
11
  "@gluestack-ui/accordion": "1.0.7",
13
12
  "@gluestack-ui/alert": "0.1.15",
14
13
  "@gluestack-ui/button": "1.0.7",
@@ -20,7 +19,8 @@
20
19
  "@gluestack-ui/radio": "0.1.33",
21
20
  "@gluestack-ui/spinner": "0.1.14",
22
21
  "@gluestack-ui/switch": "0.1.22",
23
- "@gluestack-ui/textarea": "0.1.23"
22
+ "@gluestack-ui/textarea": "0.1.23",
23
+ "dayjs": "^1.11.13"
24
24
  },
25
25
  "devDependencies": {
26
26
  "@babel/plugin-proposal-export-namespace-from": "^7.18.9",
@@ -35,6 +35,7 @@
35
35
  "@types/react": "^19.1.10",
36
36
  "@vitest/browser": "^3.2.4",
37
37
  "@vitest/coverage-v8": "^3.2.4",
38
+ "chromatic": "^13.3.0",
38
39
  "eslint-plugin-storybook": "9.1.6",
39
40
  "playwright": "^1.53.1",
40
41
  "prismjs": "^1.30.0",
@@ -53,13 +54,13 @@
53
54
  "vite": "^7.1.3",
54
55
  "vitest": "^3.2.4",
55
56
  "@utilitywarehouse/hearth-fonts": "^0.0.3",
56
- "@utilitywarehouse/hearth-react-native-icons": "^0.4.0",
57
- "@utilitywarehouse/hearth-react-icons": "^0.4.0",
58
- "@utilitywarehouse/hearth-tokens": "^0.1.0"
57
+ "@utilitywarehouse/hearth-react-icons": "^0.5.0",
58
+ "@utilitywarehouse/hearth-react-native-icons": "^0.5.0",
59
+ "@utilitywarehouse/hearth-tokens": "^0.1.1"
59
60
  },
60
61
  "peerDependencies": {
61
62
  "@gorhom/bottom-sheet": "^5.0.0",
62
- "@utilitywarehouse/hearth-react-native-icons": "~0.4.0",
63
+ "@utilitywarehouse/hearth-react-native-icons": "0.4.0",
63
64
  "react": ">=17 || ^18.0.0 || ^19.0.0",
64
65
  "react-native": ">=0.77",
65
66
  "react-native-gesture-handler": "^2.22.0",
@@ -80,6 +81,8 @@
80
81
  "figma:publish": "figma connect publish",
81
82
  "test": "echo \"Error: no test specified\" && exit 1",
82
83
  "dev": "storybook dev -p 6006",
83
- "build:storybook": "storybook build"
84
+ "build:storybook": "storybook build",
85
+ "build-storybook": "storybook build",
86
+ "chromatic": "npx chromatic --project-token=chpt_cce0fb1ebd95d2a --build-script-name build:storybook"
84
87
  }
85
88
  }
@@ -47,13 +47,14 @@ const CurrencyInput = ({
47
47
  style={styles.wrap}
48
48
  >
49
49
  <InputSlot>
50
- <DetailText size="4xl" style={styles.text}>
50
+ <DetailText size="4xl" style={styles.text} accessible={false}>
51
51
  £
52
52
  </DetailText>
53
53
  </InputSlot>
54
54
  <InputField
55
55
  inputMode="decimal"
56
56
  inBottomSheet={inBottomSheet}
57
+ accessibilityHint='Enter the amount in pounds and pence, for example "10.99"'
57
58
  {...rest}
58
59
  placeholder={getPlaceholder}
59
60
  keyboardType="decimal-pad"
@@ -0,0 +1,23 @@
1
+ import { createContext, useContext } from 'react';
2
+ import type { DatePickerBaseProps, DateType } from './DatePicker.props';
3
+ import { CalendarViews } from './enums';
4
+
5
+ export interface DatePickerContextType extends DatePickerBaseProps {
6
+ showOutsideDays: boolean;
7
+ firstDayOfWeek: number;
8
+ calendarView: CalendarViews;
9
+ currentDate: DateType; // used for latest state of calendar based on Month and Year
10
+ currentYear: number;
11
+ numerals: 'latn';
12
+ setCalendarView: (value: CalendarViews) => void;
13
+ onSelectDate: (date: DateType) => void;
14
+ onSelectMonth: (month: number) => void;
15
+ onSelectYear: (year: number) => void;
16
+ onChangeMonth: (value: number) => void;
17
+ onChangeYear: (value: number) => void;
18
+ closeDatePicker: () => void;
19
+ }
20
+
21
+ export const DatePickerContext = createContext({} as DatePickerContextType);
22
+
23
+ export const useDatePickerContext = () => useContext(DatePickerContext);
@@ -0,0 +1,239 @@
1
+ import { Canvas, Controls, Meta } from '@storybook/addon-docs/blocks';
2
+ import { Button, Center } from '../../';
3
+ import { BackToTopButton, UsageWrap, ViewFigmaButton } from '../../../docs/components';
4
+ import * as Stories from './DatePicker.stories';
5
+
6
+ <ViewFigmaButton url="https://www.figma.com/design/6NKZXZhFSExXrcbBgc6zTR/Hearth-Components---Tokens?node-id=3725-357" />
7
+
8
+ <Meta title="Components / Date Picker" />
9
+
10
+ <BackToTopButton />
11
+
12
+ # Date Picker
13
+
14
+ The `DatePicker` component presents a calendar experience in a bottom sheet so people can choose one or more dates without leaving the current screen. It supports single-day, ranged, and multi-date selection while respecting locale, calendar, and availability rules.
15
+
16
+ - [Playground](#playground)
17
+ - [Usage](#usage)
18
+ - [Props](#props)
19
+ - [`DatePicker`](#datepicker)
20
+ - [Change handlers](#change-handlers)
21
+ - [Imperative API](#imperative-api)
22
+ - [Examples](#examples)
23
+ - [Range selection](#range-selection)
24
+ - [Multiple selection](#multiple-selection)
25
+ - [Integration notes](#integration-notes)
26
+ - [Accessibility](#accessibility)
27
+ - [Screen reader support](#screen-reader-support)
28
+ - [Keyboard navigation](#keyboard-navigation)
29
+ - [Best practices](#best-practices)
30
+
31
+ ## Playground
32
+
33
+ <Canvas of={Stories.Playground} />
34
+
35
+ <Controls of={Stories.Playground} />
36
+
37
+ ## Usage
38
+
39
+ Use the `DatePicker` with a ref so you can present and dismiss the bottom sheet when people tap a trigger like a button or form field. The picker respects the locale and calendar you provide and can be configured to limit which dates are selectable.
40
+
41
+ <UsageWrap>
42
+ <Center>
43
+ <Button onPress={() => {}}>Pick a date</Button>
44
+ </Center>
45
+ </UsageWrap>
46
+
47
+ ```tsx
48
+ import { useRef, useState } from 'react';
49
+ import {
50
+ BottomSheetModalProvider,
51
+ Button,
52
+ DatePicker,
53
+ type DateType,
54
+ } from '@utilitywarehouse/hearth-react-native';
55
+
56
+ const BookingDates = () => {
57
+ const pickerRef = useRef(null);
58
+ const [selected, setSelected] = useState<DateType>();
59
+
60
+ return (
61
+ <BottomSheetModalProvider>
62
+ <Button onPress={() => pickerRef.current?.present()}>Choose booking date</Button>
63
+
64
+ <DatePicker
65
+ ref={pickerRef}
66
+ mode="single"
67
+ date={selected}
68
+ onChange={({ date }) => setSelected(date)}
69
+ onCancel={() => setSelected(undefined)}
70
+ minDate={new Date()}
71
+ />
72
+ </BottomSheetModalProvider>
73
+ );
74
+ };
75
+ ```
76
+
77
+ ## Props
78
+
79
+ ### `DatePicker`
80
+
81
+ The `DatePicker` extends the `BottomSheetModal` component. The table below highlights the most frequently used props.
82
+
83
+ | Prop | Type | Default | Description |
84
+ | -------------------- | --------------------------------------------- | ------------------ | --------------------------------------------------------------------------------------------------------- |
85
+ | `mode` | `'single' \| 'range' \| 'multiple'` | `'single'` | Controls whether the picker returns one date, a start/end range, or multiple discrete dates. |
86
+ | `timeZone` | `string` | `-` | IANA time zone identifier applied when normalising and comparing dates. |
87
+ | `date` | `DateType` | `-` | Selected date in single mode. |
88
+ | `startDate` | `DateType` | `-` | Range start value in range mode. |
89
+ | `endDate` | `DateType` | `-` | Range end value in range mode. |
90
+ | `dates` | `DateType[]` | `-` | Selected dates in multiple mode. |
91
+ | `min` | `number` | `-` | Minimum length of a selected range (in days) when using range mode. |
92
+ | `max` | `number` | `-` | Maximum length of a selected range (in days) or the maximum number of selected dates in multiple mode. |
93
+ | `onChange` | `SingleChange \| RangeChange \| MultiChange` | `-` | Callback fired after a selection changes. |
94
+ | `minDate` | `DateType` | `-` | Earliest selectable date. Values before this are disabled. |
95
+ | `maxDate` | `DateType` | `-` | Latest selectable date. Values after this are disabled. |
96
+ | `enabledDates` | `DateType[] \| ((date: DateType) => boolean)` | `-` | List or predicate that marks which dates can be chosen. |
97
+ | `disabledDates` | `DateType[] \| ((date: DateType) => boolean)` | `-` | List or predicate that marks dates that cannot be chosen. |
98
+ | `firstDayOfWeek` | `number` | `1` | Index of the first weekday (0 = Sunday, 6 = Saturday). |
99
+ | `showOutsideDays` | `boolean` | `true` | Shows the trailing and leading days from adjacent months. |
100
+ | `initialView` | `'day' \| 'month' \| 'year'` | `'day'` | Determines the first calendar view when the sheet opens. |
101
+ | `containerHeight` | `number` | `CONTAINER_HEIGHT` | Height of the calendar container. |
102
+ | `weekdaysHeight` | `number` | `WEEKDAYS_HEIGHT` | Height of the weekday header row. |
103
+ | `navigationPosition` | `'around' \| 'right' \| 'left'` | `'right'` | Placement of the navigation controls. |
104
+ | `weekdaysFormat` | `'min' \| 'short' \| 'full'` | `'min'` | Formatting used for weekday labels. |
105
+ | `monthsFormat` | `'short' \| 'full'` | `'short'` | Formatting used for month names. |
106
+ | `monthCaptionFormat` | `'short' \| 'full'` | `'full'` | Formatting used for the heading above the calendar grid. |
107
+ | `multiRangeMode` | `boolean` | `-` | Enables an experimental range selection where users can keep choosing additional spans before confirming. |
108
+ | `hideHeader` | `boolean` | `-` | Hides the calendar header controls. |
109
+ | `hideFooter` | `boolean` | `-` | Hides the footer actions. |
110
+ | `hideWeekdays` | `boolean` | `-` | Removes the weekday labels row. |
111
+ | `disableMonthPicker` | `boolean` | `-` | Prevents switching to the month selection view. |
112
+ | `disableYearPicker` | `boolean` | `-` | Prevents switching to the year selection view. |
113
+ | `month` | `number` | `-` | Forces the calendar to display a specific month (0-11). |
114
+ | `year` | `number` | `-` | Forces the calendar to display a specific year. |
115
+ | `onMonthChange` | `(month: number) => void` | `() => {}` | Fired when the displayed month changes. |
116
+ | `onYearChange` | `(year: number) => void` | `() => {}` | Fired when the displayed year changes. |
117
+ | `onCancel` | `() => void` | `() => {}` | Fired when the cancel action is triggered from the footer. |
118
+ | `ref` | `Ref<BottomSheetModalMethods>` | `-` | Gives imperative access to the underlying bottom sheet for presenting or dismissing the picker. |
119
+
120
+ ### Change handlers
121
+
122
+ Each selection mode provides specialised payloads when `onChange` fires:
123
+
124
+ - **Single**: `{ date: DateType }`
125
+ - **Range**: `{ startDate: DateType; endDate: DateType }`
126
+ - **Multiple**: `{ dates: DateType[]; datePressed?: DateType; change: 'added' | 'removed' | 'updated' }`
127
+
128
+ ### Imperative API
129
+
130
+ Attach a ref that conforms to `BottomSheetModalMethods` so you can call `present()`, `close()`, or `dismiss()` as needed. This matches the API surface of `BottomSheetModal`.
131
+
132
+ ## Examples
133
+
134
+ ### Range selection
135
+
136
+ <Canvas of={Stories.Range} />
137
+
138
+ ```tsx
139
+ import { useRef, useState } from 'react';
140
+ import {
141
+ BottomSheetModalProvider,
142
+ Button,
143
+ DatePicker,
144
+ type DateType,
145
+ } from '@utilitywarehouse/hearth-react-native';
146
+
147
+ const Example = () => {
148
+ const pickerRef = useRef(null);
149
+ const [range, setRange] = useState<{ startDate?: DateType; endDate?: DateType }>({});
150
+
151
+ return (
152
+ <BottomSheetModalProvider>
153
+ <Button onPress={() => pickerRef.current?.present()}>Choose booking dates</Button>
154
+
155
+ <DatePicker
156
+ ref={pickerRef}
157
+ mode="range"
158
+ startDate={range.startDate}
159
+ endDate={range.endDate}
160
+ onChange={({ startDate, endDate }) => setRange({ startDate, endDate })}
161
+ onCancel={() => setRange({})}
162
+ minDate={new Date()}
163
+ min={2}
164
+ max={14}
165
+ />
166
+ </BottomSheetModalProvider>
167
+ );
168
+ };
169
+ ```
170
+
171
+ ### Multiple selection
172
+
173
+ <Canvas of={Stories.Multi} />
174
+
175
+ ```tsx
176
+ import { useRef, useState } from 'react';
177
+ import {
178
+ BottomSheetModalProvider,
179
+ Button,
180
+ DatePicker,
181
+ } from '@utilitywarehouse/hearth-react-native';
182
+
183
+ const Example = () => {
184
+ const pickerRef = useRef(null);
185
+ const [dates, setDates] = useState<DateType[]>([]);
186
+
187
+ return (
188
+ <BottomSheetModalProvider>
189
+ <Button onPress={() => pickerRef.current?.present()}>Choose booking dates</Button>
190
+
191
+ <DatePicker
192
+ ref={pickerRef}
193
+ mode="multiple"
194
+ dates={dates}
195
+ onChange={({ dates, datePressed, change }) => setDates(dates)}
196
+ onCancel={() => setDates([])}
197
+ minDate={new Date()}
198
+ min={2}
199
+ max={14}
200
+ />
201
+ </BottomSheetModalProvider>
202
+ );
203
+ };
204
+ ```
205
+
206
+ ## Integration notes
207
+
208
+ - Wrap your application (or the portion that renders the picker) with `BottomSheetModalProvider` so the sheet can mount correctly, especially when combining with other bottom-sheet components.
209
+ - Because the picker respects locale and time zone information, ensure you pass consistent values throughout your app when working with server-sourced dates.
210
+ - When pairing the picker with inputs like `FormField`, surface the chosen dates in the trigger control so people can review their selection after the sheet closes.
211
+
212
+ ## Accessibility
213
+
214
+ The `DatePicker` is designed to be fully accessible for VoiceOver (iOS) and TalkBack (Android) users:
215
+
216
+ ### Screen reader support
217
+
218
+ - **Automatic focus**: When the picker opens, screen readers automatically announce "Date picker opened" and focus on the calendar content.
219
+ - **Platform-optimized navigation**:
220
+ - On iOS, VoiceOver can freely navigate through all calendar elements.
221
+ - On Android, TalkBack announces "Date picker calendar" when opened, then allows navigation through child elements.
222
+ - **Descriptive labels**: Each interactive element has clear accessibility labels:
223
+ - Day buttons announce the full date: "Monday, October 8" (with "selected" appended for chosen dates).
224
+ - Month/year buttons announce the current month and year.
225
+ - Navigation buttons specify direction: "Next month", "Prev month", etc.
226
+ - View switcher announces: "Change to day view" or "Change to month view".
227
+
228
+ ### Keyboard navigation
229
+
230
+ - All interactive controls (days, months, years, navigation) expose `accessibilityRole="button"` for proper identification.
231
+ - Buttons respond to standard tap/activate gestures with screen readers.
232
+ - The footer cancel button is fully accessible and announced properly.
233
+
234
+ ### Best practices
235
+
236
+ - The picker works seamlessly within forms when triggered by accessible inputs like `DatePickerInput`.
237
+ - Disabled dates are marked as disabled in the accessibility tree, preventing selection attempts.
238
+ - The bottom sheet modal itself is marked as not accessible (`accessible={false}`) to prevent it from blocking navigation to child elements.
239
+ - All date announcements respect the English locale for consistency with the current implementation.