@jobber/components-native 0.84.4-match-mobi-55ef4ec.7 → 0.84.4-match-mobi-540af48.10

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/dist/package.json +26 -15
  2. package/dist/src/ActionItem/ActionItemGroup.js +1 -1
  3. package/dist/src/AutoLink/components/Link/Link.js +1 -1
  4. package/dist/src/Banner/Banner.js +2 -0
  5. package/dist/src/Banner/components/BannerIcon/BannerIcon.style.js +3 -0
  6. package/dist/src/BottomSheet/BottomSheet.js +58 -32
  7. package/dist/src/BottomSheet/BottomSheet.style.js +8 -9
  8. package/dist/src/BottomSheet/hooks/useBottomSheetBackHandler.js +26 -0
  9. package/dist/src/Button/components/InternalButtonLoading/InternalButtonLoading.js +0 -1
  10. package/dist/src/ButtonGroup/ButtonGroup.js +1 -1
  11. package/dist/src/Chip/Chip.js +12 -1
  12. package/dist/src/Chip/Chip.style.js +1 -1
  13. package/dist/src/Content/ContentHorizontal.style.js +15 -0
  14. package/dist/src/Content/ContentSpaceAround.style.js +15 -0
  15. package/dist/src/Content/ContentVertical.style.js +15 -0
  16. package/dist/src/ContentOverlay/ContentOverlay.js +5 -7
  17. package/dist/src/ContentOverlay/UNSAFE_WrappedModalize.js +23 -0
  18. package/dist/src/ErrorMessageWrapper/context/ErrorMessageProvider.js +1 -1
  19. package/dist/src/Form/Form.js +5 -2
  20. package/dist/src/Form/components/FormCache/FormCache.js +1 -0
  21. package/dist/src/Form/components/FormMessageBanner/FormMessageBanner.js +1 -1
  22. package/dist/src/Form/context/AtlantisFormContext.js +1 -0
  23. package/dist/src/Form/hooks/useInternalForm.js +6 -3
  24. package/dist/src/FormatFile/components/MediaView/MediaView.js +22 -5
  25. package/dist/src/FormatFile/utils/createUseCreateThumbnail.js +1 -1
  26. package/dist/src/InputCurrency/InputCurrency.js +42 -30
  27. package/dist/src/InputDate/InputDate.js +2 -2
  28. package/dist/src/InputEmail/InputEmail.js +12 -4
  29. package/dist/src/InputFieldWrapper/InputFieldWrapper.js +14 -12
  30. package/dist/src/InputFieldWrapper/InputFieldWrapper.style.js +1 -1
  31. package/dist/src/InputFieldWrapper/components/Prefix/Prefix.js +5 -2
  32. package/dist/src/InputFieldWrapper/components/Suffix/Suffix.js +5 -2
  33. package/dist/src/InputNumber/InputNumber.js +10 -4
  34. package/dist/src/InputPressable/InputPressable.js +20 -8
  35. package/dist/src/InputPressable/InputPressable.style.js +3 -0
  36. package/dist/src/InputSearch/InputSearch.js +1 -1
  37. package/dist/src/InputText/InputText.js +24 -13
  38. package/dist/src/InputText/InputText.style.js +4 -0
  39. package/dist/src/InputTime/InputTime.js +2 -2
  40. package/dist/src/Menu/Menu.js +2 -2
  41. package/dist/src/ProgressBar/ProgressBar.js +10 -6
  42. package/dist/src/ProgressBar/ProgressBarInner.js +3 -12
  43. package/dist/src/ProgressBar/ProgressBarStepped.js +7 -2
  44. package/dist/src/Select/Select.style.js +1 -0
  45. package/dist/src/Select/components/SelectPressable/SelectPressable.js +1 -1
  46. package/dist/src/StatusLabel/StatusLabel.style.js +2 -2
  47. package/dist/src/Switch/components/BaseSwitch/BaseSwitch.js +7 -1
  48. package/dist/src/Typography/Typography.js +16 -5
  49. package/dist/src/hooks/useAtlantisI18n/locales/en.json +1 -0
  50. package/dist/src/hooks/useAtlantisI18n/locales/es.json +1 -0
  51. package/dist/src/hooks/useFormController.js +6 -15
  52. package/dist/tsconfig.build.json +7 -0
  53. package/dist/tsconfig.build.tsbuildinfo +1 -0
  54. package/dist/tsconfig.json +4 -6
  55. package/dist/types/src/ActionItem/ActionItem.d.ts +2 -1
  56. package/dist/types/src/ActionItem/ActionItemGroup.d.ts +2 -1
  57. package/dist/types/src/ActionItem/components/ActionItemContainer.d.ts +2 -1
  58. package/dist/types/src/ActionLabel/ActionLabel.d.ts +4 -3
  59. package/dist/types/src/ActivityIndicator/ActivityIndicator.d.ts +2 -1
  60. package/dist/types/src/AutoLink/AutoLink.d.ts +2 -1
  61. package/dist/types/src/AutoLink/components/ComposeTextWithLinks/ComposeTextWithLinks.d.ts +2 -1
  62. package/dist/types/src/AutoLink/components/Link/Link.d.ts +2 -1
  63. package/dist/types/src/Banner/Banner.d.ts +2 -1
  64. package/dist/types/src/Banner/components/BannerIcon/BannerIcon.d.ts +2 -1
  65. package/dist/types/src/Banner/components/BannerIcon/BannerIcon.style.d.ts +3 -0
  66. package/dist/types/src/Banner/types.d.ts +1 -1
  67. package/dist/types/src/BottomSheet/BottomSheet.d.ts +7 -3
  68. package/dist/types/src/BottomSheet/BottomSheet.style.d.ts +7 -14
  69. package/dist/types/src/BottomSheet/components/BottomSheetOption/BottomSheetOption.d.ts +2 -1
  70. package/dist/types/src/BottomSheet/hooks/useBottomSheetBackHandler.d.ts +8 -0
  71. package/dist/types/src/Button/Button.d.ts +2 -1
  72. package/dist/types/src/Button/components/InternalButtonLoading/InternalButtonLoading.d.ts +1 -1
  73. package/dist/types/src/ButtonGroup/ButtonGroup.d.ts +2 -1
  74. package/dist/types/src/ButtonGroup/ButtonGroupAction.d.ts +4 -3
  75. package/dist/types/src/ButtonGroup/components/SecondaryActionSheet/SecondaryActionSheet.d.ts +3 -2
  76. package/dist/types/src/Card/Card.d.ts +2 -1
  77. package/dist/types/src/Card/components/InternalCardHeader.d.ts +2 -1
  78. package/dist/types/src/Checkbox/Checkbox.d.ts +2 -1
  79. package/dist/types/src/Checkbox/CheckboxGroup.d.ts +2 -1
  80. package/dist/types/src/Chip/Chip.d.ts +2 -1
  81. package/dist/types/src/Content/Content.d.ts +3 -2
  82. package/dist/types/src/Content/ContentHorizontal.style.d.ts +15 -0
  83. package/dist/types/src/Content/ContentSpaceAround.style.d.ts +15 -0
  84. package/dist/types/src/Content/ContentVertical.style.d.ts +15 -0
  85. package/dist/types/src/ContentOverlay/ContentOverlay.d.ts +1 -1
  86. package/dist/types/src/ContentOverlay/UNSAFE_WrappedModalize.d.ts +3 -0
  87. package/dist/types/src/Disclosure/Disclosure.d.ts +1 -1
  88. package/dist/types/src/Divider/Divider.d.ts +2 -1
  89. package/dist/types/src/EmptyState/EmptyState.d.ts +2 -1
  90. package/dist/types/src/ErrorMessageWrapper/ErrorMessageWrapper.d.ts +2 -1
  91. package/dist/types/src/ErrorMessageWrapper/context/ErrorMessageProvider.d.ts +2 -1
  92. package/dist/types/src/ErrorMessageWrapper/context/types.d.ts +1 -1
  93. package/dist/types/src/Flex/Flex.d.ts +2 -1
  94. package/dist/types/src/Form/Form.d.ts +2 -1
  95. package/dist/types/src/Form/components/FormActionBar/FormActionBar.d.ts +3 -2
  96. package/dist/types/src/Form/components/FormBody/FormBody.d.ts +3 -2
  97. package/dist/types/src/Form/components/FormCache/FormCache.d.ts +4 -3
  98. package/dist/types/src/Form/components/FormErrorBanner/FormErrorBanner.d.ts +2 -1
  99. package/dist/types/src/Form/components/FormMask/FormMask.d.ts +2 -1
  100. package/dist/types/src/Form/components/FormMessage/FormMessage.d.ts +2 -1
  101. package/dist/types/src/Form/components/FormMessage/components/InternalFormMessage/InternalFormMessage.d.ts +2 -1
  102. package/dist/types/src/Form/components/FormMessageBanner/FormMessageBanner.d.ts +2 -1
  103. package/dist/types/src/Form/components/FormSaveButton/FormSaveButton.d.ts +2 -1
  104. package/dist/types/src/Form/context/AtlantisFormContext.d.ts +2 -1
  105. package/dist/types/src/Form/context/types.d.ts +5 -4
  106. package/dist/types/src/Form/hooks/useFormViewRefs.d.ts +2 -2
  107. package/dist/types/src/Form/hooks/useInternalForm.d.ts +7 -7
  108. package/dist/types/src/Form/types.d.ts +13 -7
  109. package/dist/types/src/FormField/FormField.d.ts +1 -1
  110. package/dist/types/src/FormatFile/FormatFile.d.ts +2 -1
  111. package/dist/types/src/FormatFile/components/ErrorIcon/ErrorIcon.d.ts +2 -1
  112. package/dist/types/src/FormatFile/components/FileView/FileView.d.ts +2 -1
  113. package/dist/types/src/FormatFile/components/FormatFileBottomSheet/FormatFileBottomSheet.d.ts +3 -2
  114. package/dist/types/src/FormatFile/components/MediaView/MediaView.d.ts +2 -1
  115. package/dist/types/src/FormatFile/components/ProgressBar/ProgressBar.d.ts +2 -1
  116. package/dist/types/src/Heading/Heading.d.ts +4 -3
  117. package/dist/types/src/Icon/Icon.d.ts +2 -1
  118. package/dist/types/src/IconButton/IconButton.d.ts +1 -1
  119. package/dist/types/src/InputCurrency/InputCurrency.d.ts +2 -1
  120. package/dist/types/src/InputDate/InputDate.d.ts +4 -2
  121. package/dist/types/src/InputFieldWrapper/InputFieldWrapper.d.ts +9 -2
  122. package/dist/types/src/InputFieldWrapper/InputFieldWrapper.style.d.ts +1 -1
  123. package/dist/types/src/InputFieldWrapper/components/ClearAction/ClearAction.d.ts +2 -1
  124. package/dist/types/src/InputFieldWrapper/components/Prefix/Prefix.d.ts +4 -4
  125. package/dist/types/src/InputFieldWrapper/components/Suffix/Suffix.d.ts +4 -4
  126. package/dist/types/src/InputPressable/InputPressable.d.ts +9 -1
  127. package/dist/types/src/InputPressable/InputPressable.style.d.ts +3 -0
  128. package/dist/types/src/InputSearch/InputSearch.d.ts +1 -1
  129. package/dist/types/src/InputSearch/components/FilterButton.d.ts +2 -1
  130. package/dist/types/src/InputText/InputText.d.ts +11 -3
  131. package/dist/types/src/InputText/InputText.style.d.ts +4 -0
  132. package/dist/types/src/InputText/context/InputAccessoriesProvider.d.ts +2 -1
  133. package/dist/types/src/InputTime/InputTime.d.ts +4 -2
  134. package/dist/types/src/Menu/Menu.d.ts +2 -1
  135. package/dist/types/src/Menu/components/MenuOption/MenuOption.d.ts +2 -1
  136. package/dist/types/src/Menu/components/Overlay/Overlay.d.ts +2 -1
  137. package/dist/types/src/Menu/types.d.ts +6 -1
  138. package/dist/types/src/ProgressBar/ProgressBar.d.ts +2 -1
  139. package/dist/types/src/ProgressBar/ProgressBarInner.d.ts +5 -1
  140. package/dist/types/src/ProgressBar/ProgressBarStepped.d.ts +3 -1
  141. package/dist/types/src/ProgressBar/types.d.ts +20 -0
  142. package/dist/types/src/Select/Select.d.ts +3 -2
  143. package/dist/types/src/Select/components/SelectDefaultPicker/SelectDefaultPicker.d.ts +2 -1
  144. package/dist/types/src/Select/components/SelectDefaultPicker/SelectDefaultPicker.ios.d.ts +2 -1
  145. package/dist/types/src/Select/components/SelectInternalPicker/SelectInternalPicker.d.ts +2 -1
  146. package/dist/types/src/Select/components/SelectPressable/SelectPressable.d.ts +2 -1
  147. package/dist/types/src/StatusLabel/StatusLabel.d.ts +2 -1
  148. package/dist/types/src/StatusLabel/StatusLabel.style.d.ts +1 -1
  149. package/dist/types/src/Switch/Switch.d.ts +2 -1
  150. package/dist/types/src/Switch/components/BaseSwitch/BaseSwitch.d.ts +2 -1
  151. package/dist/types/src/Text/Text.d.ts +4 -3
  152. package/dist/types/src/TextList/TextList.d.ts +2 -1
  153. package/dist/types/src/ThumbnailList/ThumbnailList.d.ts +2 -1
  154. package/dist/types/src/Toast/Toast.d.ts +2 -1
  155. package/dist/types/src/Typography/Typography.d.ts +3 -3
  156. package/dist/types/src/Typography/TypographyGestureDetector.d.ts +2 -1
  157. package/dist/types/src/utils/test/MockSafeAreaProvider.d.ts +1 -1
  158. package/package.json +26 -15
  159. package/src/ActionItem/ActionItem.tsx +1 -1
  160. package/src/ActionItem/ActionItemGroup.tsx +1 -3
  161. package/src/ActionItem/components/ActionItemContainer.tsx +1 -1
  162. package/src/ActionLabel/ActionLabel.test.tsx +12 -0
  163. package/src/ActionLabel/ActionLabel.tsx +3 -3
  164. package/src/ActionLabel/__snapshots__/ActionLabel.test.tsx.snap +66 -0
  165. package/src/ActivityIndicator/ActivityIndicator.tsx +1 -3
  166. package/src/AtlantisContext/AtlantisContext.test.tsx +1 -1
  167. package/src/AtlantisThemeContext/AtlantisThemeContext.test.tsx +5 -5
  168. package/src/AutoLink/AutoLink.test.tsx +2 -4
  169. package/src/AutoLink/AutoLink.tsx +1 -1
  170. package/src/AutoLink/components/ComposeTextWithLinks/ComposeTextWithLinks.tsx +1 -1
  171. package/src/AutoLink/components/Link/Link.tsx +1 -5
  172. package/src/Banner/Banner.test.tsx +12 -0
  173. package/src/Banner/Banner.tsx +4 -2
  174. package/src/Banner/components/BannerIcon/BannerIcon.style.ts +3 -0
  175. package/src/Banner/components/BannerIcon/BannerIcon.tsx +1 -1
  176. package/src/Banner/types.ts +1 -1
  177. package/src/BottomSheet/BottomSheet.stories.tsx +128 -0
  178. package/src/BottomSheet/BottomSheet.style.ts +7 -14
  179. package/src/BottomSheet/BottomSheet.test.tsx +34 -39
  180. package/src/BottomSheet/BottomSheet.tsx +112 -92
  181. package/src/BottomSheet/components/BottomSheetOption/BottomSheetOption.tsx +1 -1
  182. package/src/BottomSheet/hooks/useBottomSheetBackHandler.test.ts +90 -0
  183. package/src/BottomSheet/hooks/useBottomSheetBackHandler.ts +41 -0
  184. package/src/Button/Button.tsx +1 -1
  185. package/src/Button/components/InternalButtonLoading/InternalButtonLoading.tsx +1 -2
  186. package/src/ButtonGroup/ButtonGroup.test.tsx +13 -11
  187. package/src/ButtonGroup/ButtonGroup.tsx +2 -2
  188. package/src/ButtonGroup/ButtonGroupAction.tsx +4 -4
  189. package/src/ButtonGroup/components/SecondaryActionSheet/SecondaryActionSheet.tsx +2 -2
  190. package/src/Card/Card.tsx +1 -1
  191. package/src/Card/components/InternalCardHeader.tsx +1 -1
  192. package/src/Checkbox/Checkbox.test.tsx +118 -1
  193. package/src/Checkbox/Checkbox.tsx +2 -2
  194. package/src/Checkbox/CheckboxGroup.test.tsx +3 -7
  195. package/src/Checkbox/CheckboxGroup.tsx +2 -2
  196. package/src/Chip/Chip.style.ts +1 -1
  197. package/src/Chip/Chip.tsx +20 -2
  198. package/src/Content/Content.tsx +7 -2
  199. package/src/Content/ContentHorizontal.style.ts +20 -0
  200. package/src/Content/ContentSpaceAround.style.ts +20 -0
  201. package/src/Content/ContentVertical.style.ts +20 -0
  202. package/src/ContentOverlay/ContentOverlay.test.tsx +34 -27
  203. package/src/ContentOverlay/ContentOverlay.tsx +7 -7
  204. package/src/ContentOverlay/UNSAFE_WrappedModalize.tsx +41 -0
  205. package/src/ContentOverlay/hooks/useKeyboardVisibility.test.ts +7 -7
  206. package/src/ContentOverlay/hooks/useViewLayoutHeight.test.ts +1 -1
  207. package/src/Disclosure/Disclosure.tsx +1 -1
  208. package/src/Divider/Divider.tsx +1 -1
  209. package/src/EmptyState/EmptyState.test.tsx +29 -42
  210. package/src/EmptyState/EmptyState.tsx +1 -1
  211. package/src/ErrorMessageWrapper/ErrorMessageWrapper.tsx +1 -1
  212. package/src/ErrorMessageWrapper/context/ErrorMessageProvider.tsx +3 -5
  213. package/src/ErrorMessageWrapper/context/types.ts +1 -1
  214. package/src/Flex/Flex.tsx +2 -2
  215. package/src/Form/Form.test.tsx +145 -2
  216. package/src/Form/Form.tsx +8 -1
  217. package/src/Form/components/FormActionBar/FormActionBar.tsx +3 -3
  218. package/src/Form/components/FormBody/FormBody.tsx +3 -3
  219. package/src/Form/components/FormCache/FormCache.tsx +5 -4
  220. package/src/Form/components/FormErrorBanner/FormErrorBanner.tsx +1 -1
  221. package/src/Form/components/FormMask/FormMask.tsx +1 -1
  222. package/src/Form/components/FormMessage/FormMessage.test.tsx +40 -27
  223. package/src/Form/components/FormMessage/FormMessage.tsx +1 -1
  224. package/src/Form/components/FormMessage/components/InternalFormMessage/InternalFormMessage.tsx +1 -1
  225. package/src/Form/components/FormMessageBanner/FormMessageBanner.tsx +1 -3
  226. package/src/Form/components/FormSaveButton/FormSaveButton.test.tsx +2 -2
  227. package/src/Form/components/FormSaveButton/FormSaveButton.tsx +1 -1
  228. package/src/Form/context/AtlantisFormContext.test.tsx +1 -1
  229. package/src/Form/context/AtlantisFormContext.tsx +1 -0
  230. package/src/Form/context/types.ts +5 -4
  231. package/src/Form/hooks/useFormViewRefs.ts +4 -5
  232. package/src/Form/hooks/useInternalForm.ts +14 -6
  233. package/src/Form/hooks/useScrollToError/useScrollToError.test.tsx +2 -1
  234. package/src/Form/types.ts +14 -8
  235. package/src/FormField/FormField.tsx +1 -1
  236. package/src/FormatFile/FormatFile.test.tsx +21 -21
  237. package/src/FormatFile/FormatFile.tsx +3 -3
  238. package/src/FormatFile/components/ErrorIcon/ErrorIcon.tsx +1 -1
  239. package/src/FormatFile/components/FileView/FileView.tsx +1 -1
  240. package/src/FormatFile/components/FormatFileBottomSheet/FormatFileBottomSheet.test.tsx +14 -14
  241. package/src/FormatFile/components/FormatFileBottomSheet/FormatFileBottomSheet.tsx +2 -2
  242. package/src/FormatFile/components/MediaView/MediaView.test.tsx +283 -0
  243. package/src/FormatFile/components/MediaView/MediaView.tsx +28 -7
  244. package/src/FormatFile/components/ProgressBar/ProgressBar.tsx +1 -1
  245. package/src/FormatFile/utils/createUseCreateThumbnail.ts +1 -1
  246. package/src/Glimmer/Glimmer.test.tsx +2 -2
  247. package/src/Heading/Heading.test.tsx +13 -0
  248. package/src/Heading/Heading.tsx +3 -3
  249. package/src/Heading/__snapshots__/Heading.test.tsx.snap +65 -0
  250. package/src/Icon/Icon.tsx +1 -1
  251. package/src/Icon/__snapshots__/Icon.test.tsx.snap +7 -0
  252. package/src/IconButton/IconButton.tsx +1 -1
  253. package/src/InputCurrency/InputCurrency.tsx +72 -58
  254. package/src/InputDate/InputDate.tsx +7 -3
  255. package/src/InputEmail/InputEmail.tsx +15 -8
  256. package/src/InputFieldWrapper/InputFieldWrapper.style.ts +1 -1
  257. package/src/InputFieldWrapper/InputFieldWrapper.test.tsx +48 -1
  258. package/src/InputFieldWrapper/InputFieldWrapper.tsx +39 -29
  259. package/src/InputFieldWrapper/components/ClearAction/ClearAction.tsx +1 -1
  260. package/src/InputFieldWrapper/components/Prefix/Prefix.test.tsx +8 -16
  261. package/src/InputFieldWrapper/components/Prefix/Prefix.tsx +8 -6
  262. package/src/InputFieldWrapper/components/Suffix/Suffix.test.tsx +2 -4
  263. package/src/InputFieldWrapper/components/Suffix/Suffix.tsx +8 -6
  264. package/src/InputNumber/InputNumber.tsx +11 -7
  265. package/src/InputPassword/InputPassword.tsx +1 -1
  266. package/src/InputPressable/InputPressable.style.ts +4 -0
  267. package/src/InputPressable/InputPressable.test.tsx +75 -1
  268. package/src/InputPressable/InputPressable.tsx +34 -8
  269. package/src/InputSearch/InputSearch.tsx +2 -1
  270. package/src/InputSearch/components/FilterButton.tsx +1 -1
  271. package/src/InputText/InputText.style.ts +5 -0
  272. package/src/InputText/InputText.test.tsx +190 -1
  273. package/src/InputText/InputText.tsx +37 -20
  274. package/src/InputText/context/InputAccessoriesProvider.tsx +1 -1
  275. package/src/InputTime/InputTime.tsx +7 -3
  276. package/src/Menu/Menu.tsx +3 -3
  277. package/src/Menu/components/MenuOption/MenuOption.tsx +1 -1
  278. package/src/Menu/components/Overlay/Overlay.tsx +1 -1
  279. package/src/Menu/types.ts +7 -1
  280. package/src/ProgressBar/ProgressBar.test.tsx +109 -0
  281. package/src/ProgressBar/ProgressBar.tsx +18 -2
  282. package/src/ProgressBar/ProgressBarInner.tsx +8 -11
  283. package/src/ProgressBar/ProgressBarStepped.tsx +12 -1
  284. package/src/ProgressBar/__snapshots__/ProgressBar.test.tsx.snap +14 -0
  285. package/src/ProgressBar/types.ts +22 -0
  286. package/src/Select/Select.style.ts +1 -0
  287. package/src/Select/Select.tsx +2 -2
  288. package/src/Select/components/SelectDefaultPicker/SelectDefaultPicker.ios.tsx +1 -1
  289. package/src/Select/components/SelectDefaultPicker/SelectDefaultPicker.tsx +1 -1
  290. package/src/Select/components/SelectInternalPicker/SelectInternalPicker.tsx +1 -1
  291. package/src/Select/components/SelectPressable/SelectPressable.tsx +1 -4
  292. package/src/StatusLabel/StatusLabel.style.ts +2 -2
  293. package/src/StatusLabel/StatusLabel.tsx +1 -1
  294. package/src/StatusLabel/__snapshots__/StatusLabel.test.tsx.snap +14 -14
  295. package/src/Switch/Switch.tsx +1 -1
  296. package/src/Switch/components/BaseSwitch/BaseSwitch.tsx +8 -2
  297. package/src/Text/Text.test.tsx +10 -0
  298. package/src/Text/Text.tsx +3 -3
  299. package/src/Text/__snapshots__/Text.test.tsx.snap +66 -0
  300. package/src/TextList/TextList.tsx +1 -1
  301. package/src/ThumbnailList/ThumbnailList.test.tsx +5 -5
  302. package/src/ThumbnailList/ThumbnailList.tsx +1 -1
  303. package/src/ThumbnailList/__snapshots__/ThumbnailList.test.tsx.snap +199 -1
  304. package/src/Toast/Toast.tsx +2 -2
  305. package/src/Typography/Typography.test.tsx +61 -0
  306. package/src/Typography/Typography.tsx +25 -9
  307. package/src/Typography/TypographyGestureDetector.tsx +1 -3
  308. package/src/Typography/__snapshots__/Typography.test.tsx.snap +222 -0
  309. package/src/hooks/useAtlantisI18n/locales/en.json +1 -0
  310. package/src/hooks/useAtlantisI18n/locales/es.json +1 -0
  311. package/src/hooks/useFormController.ts +7 -14
  312. package/src/utils/test/MockSafeAreaProvider.tsx +1 -1
  313. package/dist/tsconfig.tsbuildinfo +0 -1
@@ -1,4 +1,4 @@
1
- import React from "react";
1
+ import React, { type ReactElement } from "react";
2
2
  import { act, fireEvent, render, waitFor } from "@testing-library/react-native";
3
3
  import { Alert, Keyboard } from "react-native";
4
4
  import { Host } from "react-native-portalize";
@@ -94,7 +94,7 @@ interface FormTestProps {
94
94
  onSubmit: () => void,
95
95
  label: string | undefined,
96
96
  isSubmitting: boolean,
97
- ) => JSX.Element;
97
+ ) => ReactElement;
98
98
  readonly initialLoading?: boolean;
99
99
  readonly initialValues?: FormFields;
100
100
  readonly bannerMessages?: FormBannerMessage[];
@@ -104,6 +104,7 @@ interface FormTestProps {
104
104
  readonly onBeforeSubmit?: jest.Mock;
105
105
  readonly renderFooter?: React.ReactNode;
106
106
  readonly saveButtonOffset?: number;
107
+ readonly UNSAFE_allowDiscardLocalCacheWhenOffline?: boolean;
107
108
  }
108
109
 
109
110
  function FormTest(props: FormTestProps) {
@@ -125,6 +126,7 @@ function MockForm({
125
126
  localCacheId,
126
127
  renderFooter,
127
128
  saveButtonOffset,
129
+ UNSAFE_allowDiscardLocalCacheWhenOffline = false,
128
130
  }: FormTestProps) {
129
131
  const formErrors: FormBannerErrors = {};
130
132
 
@@ -154,6 +156,9 @@ function MockForm({
154
156
  onBeforeSubmit={onBeforeSubmit}
155
157
  renderFooter={renderFooter}
156
158
  saveButtonOffset={saveButtonOffset}
159
+ UNSAFE_allowDiscardLocalCacheWhenOffline={
160
+ UNSAFE_allowDiscardLocalCacheWhenOffline
161
+ }
157
162
  >
158
163
  <InputText
159
164
  name={testInputTextName}
@@ -561,4 +566,142 @@ describe("Form", () => {
561
566
  expect(queryByTestId("ATL-FormSafeArea")).toBeNull();
562
567
  });
563
568
  });
569
+
570
+ describe("Leaving the form", () => {
571
+ let mockUseConfirmBeforeBack: jest.Mock;
572
+ let mockRemoveLocalCache: jest.Mock;
573
+ const atlantisContextSpy = jest.spyOn(
574
+ atlantisContext,
575
+ "useAtlantisContext",
576
+ );
577
+
578
+ beforeEach(() => {
579
+ mockUseConfirmBeforeBack = jest
580
+ .fn()
581
+ .mockReturnValue({ current: jest.fn() });
582
+ mockRemoveLocalCache = jest.fn();
583
+
584
+ jest
585
+ .spyOn(
586
+ require("../Form/context/AtlantisFormContext"),
587
+ "useAtlantisFormContext",
588
+ )
589
+ .mockReturnValue({
590
+ useConfirmBeforeBack: mockUseConfirmBeforeBack,
591
+ useInternalFormLocalCache: () => ({
592
+ setLocalCache: jest.fn(),
593
+ removeLocalCache: mockRemoveLocalCache,
594
+ }),
595
+ edgeToEdgeEnabled: false,
596
+ });
597
+ });
598
+
599
+ afterEach(() => {
600
+ jest.restoreAllMocks();
601
+ });
602
+
603
+ describe("when UNSAFE_allowDiscardLocalCacheWhenOffline is false", () => {
604
+ it("should NOT pass onAcceptEvent when offline", () => {
605
+ atlantisContextSpy.mockReturnValue({
606
+ ...atlantisContextDefaultValues,
607
+ isOnline: false,
608
+ });
609
+
610
+ render(
611
+ <FormTest
612
+ onSubmit={onSubmitMock}
613
+ UNSAFE_allowDiscardLocalCacheWhenOffline={false}
614
+ localCacheKey="testCacheKey"
615
+ />,
616
+ );
617
+
618
+ expect(mockUseConfirmBeforeBack).toHaveBeenCalled();
619
+ const callArgs = mockUseConfirmBeforeBack.mock.calls[0][0];
620
+ expect(callArgs.onAcceptEvent).toBeUndefined();
621
+ expect(callArgs.showLostProgressMessage).toBe(false);
622
+ });
623
+
624
+ it("should pass onAcceptEvent when online", () => {
625
+ atlantisContextSpy.mockReturnValue({
626
+ ...atlantisContextDefaultValues,
627
+ isOnline: true,
628
+ });
629
+
630
+ render(
631
+ <FormTest
632
+ onSubmit={onSubmitMock}
633
+ UNSAFE_allowDiscardLocalCacheWhenOffline={false}
634
+ localCacheKey="testCacheKey"
635
+ />,
636
+ );
637
+
638
+ expect(mockUseConfirmBeforeBack).toHaveBeenCalled();
639
+ const callArgs = mockUseConfirmBeforeBack.mock.calls[0][0];
640
+ expect(callArgs.onAcceptEvent).toBe(mockRemoveLocalCache);
641
+ expect(callArgs.showLostProgressMessage).toBe(true);
642
+ });
643
+ });
644
+
645
+ describe("when UNSAFE_allowDiscardLocalCacheWhenOffline is true", () => {
646
+ it("should pass onAcceptEvent when offline", () => {
647
+ atlantisContextSpy.mockReturnValue({
648
+ ...atlantisContextDefaultValues,
649
+ isOnline: false,
650
+ });
651
+
652
+ render(
653
+ <FormTest
654
+ onSubmit={onSubmitMock}
655
+ UNSAFE_allowDiscardLocalCacheWhenOffline={true}
656
+ localCacheKey="testCacheKey"
657
+ />,
658
+ );
659
+
660
+ expect(mockUseConfirmBeforeBack).toHaveBeenCalled();
661
+ const callArgs = mockUseConfirmBeforeBack.mock.calls[0][0];
662
+ expect(callArgs.onAcceptEvent).toBe(mockRemoveLocalCache);
663
+ expect(callArgs.showLostProgressMessage).toBe(true);
664
+ });
665
+
666
+ it("should pass onAcceptEvent when online", () => {
667
+ atlantisContextSpy.mockReturnValue({
668
+ ...atlantisContextDefaultValues,
669
+ isOnline: true,
670
+ });
671
+
672
+ render(
673
+ <FormTest
674
+ onSubmit={onSubmitMock}
675
+ UNSAFE_allowDiscardLocalCacheWhenOffline={true}
676
+ localCacheKey="testCacheKey"
677
+ />,
678
+ );
679
+
680
+ expect(mockUseConfirmBeforeBack).toHaveBeenCalled();
681
+ const callArgs = mockUseConfirmBeforeBack.mock.calls[0][0];
682
+ expect(callArgs.onAcceptEvent).toBe(mockRemoveLocalCache);
683
+ expect(callArgs.showLostProgressMessage).toBe(true);
684
+ });
685
+ });
686
+
687
+ describe("without localCacheKey", () => {
688
+ it("should always show lost progress message when no cache key is provided", () => {
689
+ atlantisContextSpy.mockReturnValue({
690
+ ...atlantisContextDefaultValues,
691
+ isOnline: false,
692
+ });
693
+
694
+ render(
695
+ <FormTest
696
+ onSubmit={onSubmitMock}
697
+ UNSAFE_allowDiscardLocalCacheWhenOffline={false}
698
+ />,
699
+ );
700
+
701
+ expect(mockUseConfirmBeforeBack).toHaveBeenCalled();
702
+ const callArgs = mockUseConfirmBeforeBack.mock.calls[0][0];
703
+ expect(callArgs.showLostProgressMessage).toBe(true);
704
+ });
705
+ });
706
+ });
564
707
  });
package/src/Form/Form.tsx CHANGED
@@ -26,6 +26,7 @@ import { useScrollToError } from "./hooks/useScrollToError";
26
26
  import { FormSaveButton } from "./components/FormSaveButton";
27
27
  import { useSaveButtonPosition } from "./hooks/useSaveButtonPosition";
28
28
  import { FormCache } from "./components/FormCache/FormCache";
29
+ import { useAtlantisFormContext } from "./context/AtlantisFormContext";
29
30
  import { InputAccessoriesProvider } from "../InputText";
30
31
  import { tokens } from "../utils/design";
31
32
  import { ErrorMessageProvider } from "../ErrorMessageWrapper";
@@ -33,7 +34,7 @@ import { ErrorMessageProvider } from "../ErrorMessageWrapper";
33
34
  export function Form<T extends FieldValues, S>({
34
35
  initialLoading,
35
36
  ...rest
36
- }: FormProps<T, S>): JSX.Element {
37
+ }: FormProps<T, S>) {
37
38
  const child = initialLoading ? <FormMask /> : <InternalForm {...rest} />;
38
39
 
39
40
  return (
@@ -65,6 +66,7 @@ function InternalForm<T extends FieldValues, S>({
65
66
  saveButtonOffset,
66
67
  showStickySaveButton = false,
67
68
  renderFooter,
69
+ UNSAFE_allowDiscardLocalCacheWhenOffline,
68
70
  }: InternalFormProps<T, S>) {
69
71
  const { scrollViewRef, bottomViewRef, scrollToTop } = useFormViewRefs();
70
72
  const [saveButtonHeight, setSaveButtonHeight] = useState(0);
@@ -86,6 +88,7 @@ function InternalForm<T extends FieldValues, S>({
86
88
  scrollViewRef,
87
89
  saveButtonHeight,
88
90
  messageBannerHeight,
91
+ UNSAFE_allowDiscardLocalCacheWhenOffline,
89
92
  });
90
93
  const { windowHeight, headerHeight } = useScreenInformation();
91
94
  const [keyboardHeight, setKeyboardHeight] = useState(0);
@@ -134,6 +137,8 @@ function InternalForm<T extends FieldValues, S>({
134
137
 
135
138
  const styles = useStyles();
136
139
 
140
+ const { edgeToEdgeEnabled } = useAtlantisFormContext();
141
+
137
142
  return (
138
143
  <FormProvider {...formMethods}>
139
144
  <>
@@ -161,6 +166,7 @@ function InternalForm<T extends FieldValues, S>({
161
166
  <KeyboardAwareScrollView
162
167
  enableResetScrollToCoords={false}
163
168
  enableAutomaticScroll={true}
169
+ enableOnAndroid={edgeToEdgeEnabled}
164
170
  keyboardOpeningTime={
165
171
  Platform.OS === "ios" ? tokens["timing-slowest"] : 0
166
172
  }
@@ -168,6 +174,7 @@ function InternalForm<T extends FieldValues, S>({
168
174
  ref={scrollViewRef}
169
175
  {...keyboardProps}
170
176
  extraHeight={headerHeight}
177
+ extraScrollHeight={edgeToEdgeEnabled ? tokens["space-large"] : 0}
171
178
  contentContainerStyle={
172
179
  !keyboardHeight && styles.scrollContentContainer
173
180
  }
@@ -1,4 +1,4 @@
1
- import React from "react";
1
+ import React, { type ReactElement } from "react";
2
2
  import type { LayoutChangeEvent } from "react-native";
3
3
  import { StyleSheet } from "react-native";
4
4
  import Reanimated from "react-native-reanimated";
@@ -18,7 +18,7 @@ export interface FormActionBarProps {
18
18
  onSubmit: () => void,
19
19
  label: string | undefined,
20
20
  isSubmitting: boolean,
21
- ) => JSX.Element;
21
+ ) => ReactElement;
22
22
  readonly secondaryActions?: SecondaryActionProp[];
23
23
  readonly setSecondaryActionLoading?: (bool: boolean) => void;
24
24
  }
@@ -32,7 +32,7 @@ export function FormActionBar({
32
32
  setSaveButtonHeight,
33
33
  secondaryActions,
34
34
  setSecondaryActionLoading,
35
- }: FormActionBarProps): JSX.Element {
35
+ }: FormActionBarProps) {
36
36
  const styles = useStyles();
37
37
 
38
38
  const buttonStyle = StyleSheet.flatten([
@@ -1,4 +1,4 @@
1
- import React, { useMemo } from "react";
1
+ import React, { type ReactElement, useMemo } from "react";
2
2
  import { View } from "react-native";
3
3
  import { useStyles } from "./FormBody.style";
4
4
  import { useScreenInformation } from "../../hooks/useScreenInformation";
@@ -7,7 +7,7 @@ import { FormActionBar } from "../FormActionBar";
7
7
  import { tokens } from "../../../utils/design";
8
8
 
9
9
  interface FormBodyProps extends FormActionBarProps {
10
- readonly children: JSX.Element;
10
+ readonly children: ReactElement;
11
11
  readonly shouldRenderActionBar?: boolean;
12
12
  readonly saveButtonOffset?: number;
13
13
  }
@@ -24,7 +24,7 @@ export function FormBody({
24
24
  setSecondaryActionLoading,
25
25
  setSaveButtonHeight,
26
26
  saveButtonOffset,
27
- }: FormBodyProps): JSX.Element {
27
+ }: FormBodyProps) {
28
28
  const paddingBottom = useBottomPadding();
29
29
  const fullViewPadding = useMemo(() => ({ paddingBottom }), [paddingBottom]);
30
30
  const styles = useStyles();
@@ -1,5 +1,5 @@
1
1
  import React, { useEffect, useMemo } from "react";
2
- import type { FieldValues } from "react-hook-form";
2
+ import type { DeepPartial, FieldValues } from "react-hook-form";
3
3
  import { useFormContext, useWatch } from "react-hook-form";
4
4
  import omit from "lodash/omit";
5
5
 
@@ -7,18 +7,18 @@ interface FormCacheProps<T extends FieldValues> {
7
7
  readonly localCacheId?: string | string[];
8
8
  readonly localCacheKey?: string;
9
9
  readonly localCacheExclude?: string[];
10
- readonly setLocalCache: (data: T) => void;
10
+ readonly setLocalCache: (data: DeepPartial<T>) => void;
11
11
  }
12
12
 
13
13
  export function FormCache<T extends FieldValues>({
14
14
  localCacheExclude,
15
15
  localCacheKey,
16
16
  setLocalCache,
17
- }: FormCacheProps<T>): JSX.Element {
17
+ }: FormCacheProps<T>) {
18
18
  const { control, formState } = useFormContext<T>();
19
19
  const { isDirty } = formState;
20
20
 
21
- const formData = useWatch<T>({ control });
21
+ const formData = useWatch({ control });
22
22
  const shouldExclude = useMemo(() => {
23
23
  return Array.isArray(localCacheExclude) && localCacheExclude.length > 0;
24
24
  }, [localCacheExclude]);
@@ -46,5 +46,6 @@ export function FormCache<T extends FieldValues>({
46
46
  }
47
47
  }, [formData, isDirty, localCacheExclude, setLocalCache, shouldExclude]);
48
48
 
49
+ // eslint-disable-next-line react/jsx-no-useless-fragment
49
50
  return <></>;
50
51
  }
@@ -6,7 +6,7 @@ import { useAtlantisI18n } from "../../../hooks/useAtlantisI18n";
6
6
  export function FormErrorBanner({
7
7
  networkError,
8
8
  bannerError,
9
- }: FormBannerErrors): JSX.Element {
9
+ }: FormBannerErrors) {
10
10
  const { t } = useAtlantisI18n();
11
11
 
12
12
  if (networkError) {
@@ -4,7 +4,7 @@ import { useStyles } from "./FormMask.style";
4
4
  import { ActivityIndicator } from "../../../ActivityIndicator";
5
5
  import { useAtlantisI18n } from "../../../hooks/useAtlantisI18n";
6
6
 
7
- export function FormMask(): JSX.Element {
7
+ export function FormMask() {
8
8
  const { t } = useAtlantisI18n();
9
9
  const styles = useStyles();
10
10
 
@@ -1,30 +1,41 @@
1
1
  import React from "react";
2
- import { fireEvent, render } from "@testing-library/react-native";
2
+ import {
3
+ fireEvent,
4
+ render,
5
+ screen,
6
+ waitFor,
7
+ } from "@testing-library/react-native";
3
8
  import { FormMessage } from ".";
4
9
 
5
10
  describe("FormMessage", () => {
6
11
  it("should render null when there are no message to show", () => {
7
- const view = render(<FormMessage />);
8
- expect(view.toJSON()).toMatchInlineSnapshot(`null`);
12
+ render(<FormMessage />);
13
+ expect(screen.toJSON()).toMatchInlineSnapshot(`null`);
9
14
  });
10
15
 
11
- it("should show the message", () => {
12
- const { getByText } = render(<FormMessage />);
16
+ it("should show the message", async () => {
17
+ render(<FormMessage />);
13
18
 
14
19
  const description = "🔥";
15
20
  FormMessage.show({ description });
16
- expect(getByText(description)).toBeDefined();
21
+ await waitFor(() => {
22
+ expect(screen.getByText(description)).toBeDefined();
23
+ });
17
24
  });
18
25
 
19
- it("should close the message", () => {
20
- const { getByText, queryByText } = render(<FormMessage />);
26
+ it("should close the message", async () => {
27
+ render(<FormMessage />);
21
28
 
22
29
  const description = "🌚";
23
30
  FormMessage.show({ description });
24
- expect(getByText(description)).toBeDefined();
31
+ await waitFor(() => {
32
+ expect(screen.getByText(description)).toBeDefined();
33
+ });
25
34
 
26
35
  FormMessage.close();
27
- expect(queryByText(description)).toBeNull();
36
+ await waitFor(() => {
37
+ expect(screen.queryByText(description)).toBeNull();
38
+ });
28
39
  });
29
40
 
30
41
  describe("Opening another message through a message", () => {
@@ -40,33 +51,35 @@ describe("FormMessage", () => {
40
51
  },
41
52
  });
42
53
 
43
- it("should show the most recent message", () => {
44
- const { getByText, queryByText, getByLabelText } = render(
45
- <FormMessage />,
46
- );
54
+ it("should show the most recent message", async () => {
55
+ render(<FormMessage />);
47
56
 
48
57
  showMessage();
49
58
 
50
- expect(getByText(firstMessage)).toBeDefined();
51
- expect(queryByText(secondMessage)).toBeNull();
59
+ await waitFor(() => {
60
+ expect(screen.getByText(firstMessage)).toBeDefined();
61
+ });
62
+ expect(screen.queryByText(secondMessage)).toBeNull();
52
63
 
53
- fireEvent.press(getByLabelText("Click me"));
64
+ fireEvent.press(screen.getByLabelText("Click me"));
54
65
 
55
- expect(getByText(secondMessage)).toBeDefined();
56
- expect(queryByText(firstMessage)).toBeNull();
66
+ expect(screen.getByText(secondMessage)).toBeDefined();
67
+ expect(screen.queryByText(firstMessage)).toBeNull();
57
68
  });
58
69
 
59
- it("should close the most recent message", () => {
60
- const { getByText, queryByText, getByLabelText } = render(
61
- <FormMessage />,
62
- );
70
+ it("should close the most recent message", async () => {
71
+ render(<FormMessage />);
63
72
 
64
73
  showMessage();
65
- fireEvent.press(getByLabelText("Click me"));
74
+ await waitFor(() => {
75
+ expect(screen.getByText("Click me")).toBeDefined();
76
+ });
77
+ fireEvent.press(screen.getByLabelText("Click me"));
66
78
  FormMessage.close();
67
-
68
- expect(getByText(firstMessage)).toBeDefined();
69
- expect(queryByText(secondMessage)).toBeNull();
79
+ await waitFor(() => {
80
+ expect(screen.getByText(firstMessage)).toBeDefined();
81
+ });
82
+ expect(screen.queryByText(secondMessage)).toBeNull();
70
83
  });
71
84
  });
72
85
  });
@@ -17,7 +17,7 @@ let close: (() => void) | undefined;
17
17
  * message to the user. Use `FormMessage.close()` to close the most
18
18
  * recent message.
19
19
  */
20
- export const FormMessage = (): JSX.Element => {
20
+ export const FormMessage = () => {
21
21
  const [data, setData] = useState<FormMessageData[]>([]);
22
22
 
23
23
  open = useCallback(
@@ -15,7 +15,7 @@ interface FormMessageProps {
15
15
  export function InternalFormMessage({
16
16
  data,
17
17
  onRequestClose,
18
- }: FormMessageProps): JSX.Element {
18
+ }: FormMessageProps) {
19
19
  const { t } = useAtlantisI18n();
20
20
  const styles = useStyles();
21
21
  const emptyStateData: EmptyStateProps = useMemo(() => {
@@ -8,9 +8,7 @@ interface FormMessageBannerProps {
8
8
  readonly bannerMessages?: FormBannerMessage[];
9
9
  }
10
10
 
11
- export function FormMessageBanner({
12
- bannerMessages,
13
- }: FormMessageBannerProps): JSX.Element {
11
+ export function FormMessageBanner({ bannerMessages }: FormMessageBannerProps) {
14
12
  return (
15
13
  <>
16
14
  {bannerMessages?.map((message, index) => (
@@ -127,7 +127,7 @@ describe("when a secondaryActions is passed in", () => {
127
127
  const beforeSubmitMock = jest.fn().mockImplementation(() => {
128
128
  return Promise.resolve(true);
129
129
  });
130
- const { getByLabelText } = render(
130
+ const { findByLabelText, getByLabelText } = render(
131
131
  <ButtonGroupForTest
132
132
  primaryAction={pressHandler}
133
133
  loading={false}
@@ -145,7 +145,7 @@ describe("when a secondaryActions is passed in", () => {
145
145
  />,
146
146
  );
147
147
  fireEvent.press(getByLabelText("More"));
148
- expect(getByLabelText("hi")).toBeDefined();
148
+ expect(await findByLabelText("hi")).toBeDefined();
149
149
  fireEvent.press(getByLabelText("hi"));
150
150
  expect(beforeSubmitMock).toHaveBeenCalled();
151
151
  await waitFor(() => {
@@ -13,7 +13,7 @@ export function FormSaveButton({
13
13
  setSecondaryActionLoading,
14
14
  onOpenBottomSheet,
15
15
  onCloseBottomSheet,
16
- }: FormSaveButtonProps): JSX.Element {
16
+ }: FormSaveButtonProps) {
17
17
  const { t } = useAtlantisI18n();
18
18
  const formContext = useFormContext();
19
19
  const buttonActions = useButtonGroupAction(secondaryActions);
@@ -1,6 +1,6 @@
1
1
  import type { PropsWithChildren } from "react";
2
2
  import React from "react";
3
- import { renderHook } from "@testing-library/react-hooks";
3
+ import { renderHook } from "@testing-library/react-native";
4
4
  import type { AtlantisFormContextProps } from "./types";
5
5
  import {
6
6
  AtlantisFormContext,
@@ -11,6 +11,7 @@ export const atlantisFormContextDefaultValues = {
11
11
  setLocalCache: () => undefined,
12
12
  removeLocalCache: () => undefined,
13
13
  }),
14
+ edgeToEdgeEnabled: false,
14
15
  };
15
16
 
16
17
  export const AtlantisFormContext = createContext<AtlantisFormContextProps>(
@@ -1,5 +1,5 @@
1
- import type { MutableRefObject } from "react";
2
- import type { FieldValues, UseFormReturn } from "react-hook-form";
1
+ import type { RefObject } from "react";
2
+ import type { DeepPartial, FieldValues, UseFormReturn } from "react-hook-form";
3
3
 
4
4
  export interface UseConfirmBeforeBackProps {
5
5
  alwaysPreventBack: boolean;
@@ -21,13 +21,14 @@ interface LocalCacheOptions {
21
21
  export interface AtlantisFormContextProps {
22
22
  useConfirmBeforeBack: (
23
23
  props: UseConfirmBeforeBackProps,
24
- ) => MutableRefObject<() => void>;
24
+ ) => RefObject<() => void>;
25
25
  useInternalFormLocalCache: <TData extends FieldValues>(
26
26
  formMethods: UseFormReturn<TData>,
27
27
  cacheKey?: string,
28
28
  options?: LocalCacheOptions,
29
29
  ) => {
30
- setLocalCache: (data: TData) => void;
30
+ setLocalCache: (data: DeepPartial<TData>) => void;
31
31
  removeLocalCache: () => void;
32
32
  };
33
+ edgeToEdgeEnabled?: boolean;
33
34
  }
@@ -4,15 +4,14 @@ import type { View } from "react-native";
4
4
  import type { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view";
5
5
 
6
6
  interface UseFormViewRefsReturn {
7
- readonly scrollViewRef: RefObject<KeyboardAwareScrollView>;
8
- readonly bottomViewRef: RefObject<View>;
7
+ readonly scrollViewRef: RefObject<KeyboardAwareScrollView | null>;
8
+ readonly bottomViewRef: RefObject<View | null>;
9
9
  readonly scrollToTop: () => void;
10
10
  }
11
11
 
12
12
  export function useFormViewRefs(): UseFormViewRefsReturn {
13
- const scrollViewRef: RefObject<KeyboardAwareScrollView> =
14
- useRef<KeyboardAwareScrollView>(null);
15
- const bottomViewRef: RefObject<View> = useRef<View>(null);
13
+ const scrollViewRef = useRef<KeyboardAwareScrollView>(null);
14
+ const bottomViewRef = useRef<View>(null);
16
15
  const scrollToTop = useCallback(() => {
17
16
  scrollViewRef.current?.scrollToPosition(0, 0);
18
17
  }, [scrollViewRef]);
@@ -1,10 +1,11 @@
1
1
  import type {
2
+ DeepPartial,
2
3
  FieldValues,
3
4
  UseFormHandleSubmit,
4
5
  UseFormReturn,
5
6
  } from "react-hook-form";
6
7
  import { useForm } from "react-hook-form";
7
- import type { MutableRefObject, RefObject } from "react";
8
+ import type { RefObject } from "react";
8
9
  import type { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view";
9
10
  import { useAtlantisContext } from "../../AtlantisContext";
10
11
  import { useAtlantisFormContext } from "../context/AtlantisFormContext";
@@ -19,8 +20,9 @@ type UseInternalFormProps<T extends FieldValues, SubmitResponseType> = Pick<
19
20
  | "localCacheKey"
20
21
  | "localCacheExclude"
21
22
  | "localCacheId"
23
+ | "UNSAFE_allowDiscardLocalCacheWhenOffline"
22
24
  > & {
23
- scrollViewRef?: RefObject<KeyboardAwareScrollView>;
25
+ scrollViewRef?: RefObject<KeyboardAwareScrollView | null>;
24
26
  readonly saveButtonHeight: number;
25
27
  readonly messageBannerHeight: number;
26
28
  };
@@ -30,8 +32,8 @@ interface UseInternalForm<T extends FieldValues> {
30
32
  readonly handleSubmit: UseFormHandleSubmit<T>;
31
33
  readonly isSubmitting: boolean;
32
34
  readonly isDirty: boolean;
33
- readonly removeListenerRef: MutableRefObject<() => void>;
34
- readonly setLocalCache: (data: T) => void;
35
+ readonly removeListenerRef: RefObject<() => void>;
36
+ readonly setLocalCache: (data: DeepPartial<T>) => void;
35
37
  }
36
38
 
37
39
  export function useInternalForm<T extends FieldValues, SubmitResponseType>({
@@ -44,6 +46,7 @@ export function useInternalForm<T extends FieldValues, SubmitResponseType>({
44
46
  scrollViewRef,
45
47
  saveButtonHeight,
46
48
  messageBannerHeight,
49
+ UNSAFE_allowDiscardLocalCacheWhenOffline = false,
47
50
  }: UseInternalFormProps<T, SubmitResponseType>): UseInternalForm<T> {
48
51
  const { useConfirmBeforeBack, useInternalFormLocalCache } =
49
52
  useAtlantisFormContext();
@@ -81,11 +84,16 @@ export function useInternalForm<T extends FieldValues, SubmitResponseType>({
81
84
  };
82
85
  }
83
86
 
87
+ const shouldRemoveCacheOnBack = UNSAFE_allowDiscardLocalCacheWhenOffline
88
+ ? true
89
+ : isOnline;
90
+
84
91
  const removeListenerRef = useConfirmBeforeBack({
85
92
  alwaysPreventBack: isSubmitting,
86
93
  shouldShowAlert: isDirty,
87
- onAcceptEvent: isOnline ? removeLocalCache : undefined,
88
- showLostProgressMessage: isOnline || !clientSideSaveOn ? true : false,
94
+ onAcceptEvent: shouldRemoveCacheOnBack ? removeLocalCache : undefined,
95
+ showLostProgressMessage:
96
+ shouldRemoveCacheOnBack || !clientSideSaveOn ? true : false,
89
97
  });
90
98
 
91
99
  return {
@@ -1,4 +1,4 @@
1
- import { renderHook } from "@testing-library/react-hooks";
1
+ import { renderHook } from "@testing-library/react-native";
2
2
  import { useScrollToError } from "./useScrollToError";
3
3
 
4
4
  const mockFormState = {
@@ -25,6 +25,7 @@ jest.mock("../../../ErrorMessageWrapper", () => ({
25
25
  el: {
26
26
  measure: jest.fn((_, callback) => callback()),
27
27
  hasErrorMessage: true,
28
+ accessibilityFocus: jest.fn(),
28
29
  },
29
30
  },
30
31
  register: jest.fn(),