@userflow-tech/react-native 0.5.0 → 0.7.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 (328) hide show
  1. package/README.md +65 -33
  2. package/docs/custom-fonts.md +36 -0
  3. package/docs/troubleshooting.md +45 -44
  4. package/expo-plugin/hostDependencyWarnings.d.ts +5 -5
  5. package/expo-plugin/hostDependencyWarnings.js +7 -7
  6. package/expo-plugin/hostDependencyWarnings.js.map +1 -1
  7. package/lib/commonjs/anchors/AnchorRegistry.js +5 -0
  8. package/lib/commonjs/anchors/AnchorRegistry.js.map +1 -1
  9. package/lib/commonjs/anchors/ScrollContainerRegistry.js +8 -0
  10. package/lib/commonjs/anchors/ScrollContainerRegistry.js.map +1 -1
  11. package/lib/commonjs/anchors/fiber/FiberScanRootStore.js +8 -0
  12. package/lib/commonjs/anchors/fiber/FiberScanRootStore.js.map +1 -1
  13. package/lib/commonjs/anchors/fiber/detectAppFontFamily.js +341 -0
  14. package/lib/commonjs/anchors/fiber/detectAppFontFamily.js.map +1 -0
  15. package/lib/commonjs/anchors/fiber/presentedModal.js +215 -0
  16. package/lib/commonjs/anchors/fiber/presentedModal.js.map +1 -0
  17. package/lib/commonjs/anchors/fiber/touchTargetFiber.js +1 -0
  18. package/lib/commonjs/anchors/fiber/touchTargetFiber.js.map +1 -1
  19. package/lib/commonjs/anchors/fiber/visibleRect.js +12 -3
  20. package/lib/commonjs/anchors/fiber/visibleRect.js.map +1 -1
  21. package/lib/commonjs/anchors/fiber/visibleScreens.js +6 -0
  22. package/lib/commonjs/anchors/fiber/visibleScreens.js.map +1 -1
  23. package/lib/commonjs/anchors/useUserflowAnchor.js.map +1 -1
  24. package/lib/commonjs/anchors/useUserflowScrollContainer.js.map +1 -1
  25. package/lib/commonjs/authoring/ElementPickerOverlay.js +197 -138
  26. package/lib/commonjs/authoring/ElementPickerOverlay.js.map +1 -1
  27. package/lib/commonjs/authoring/hitTest.js +67 -10
  28. package/lib/commonjs/authoring/hitTest.js.map +1 -1
  29. package/lib/commonjs/authoring/hostAtPoint.js +45 -21
  30. package/lib/commonjs/authoring/hostAtPoint.js.map +1 -1
  31. package/lib/commonjs/content/BannerStepButton.js +2 -1
  32. package/lib/commonjs/content/BannerStepButton.js.map +1 -1
  33. package/lib/commonjs/content/RichContentRenderer.js +27 -9
  34. package/lib/commonjs/content/RichContentRenderer.js.map +1 -1
  35. package/lib/commonjs/content/StepButton.js +2 -1
  36. package/lib/commonjs/content/StepButton.js.map +1 -1
  37. package/lib/commonjs/content/resolveContentFontFamily.js +96 -0
  38. package/lib/commonjs/content/resolveContentFontFamily.js.map +1 -0
  39. package/lib/commonjs/deepLinking.js.map +1 -1
  40. package/lib/commonjs/deviceContext.js +39 -19
  41. package/lib/commonjs/deviceContext.js.map +1 -1
  42. package/lib/commonjs/index.js +13 -5
  43. package/lib/commonjs/index.js.map +1 -1
  44. package/lib/commonjs/installCheck.js +3 -3
  45. package/lib/commonjs/installCheck.js.map +1 -1
  46. package/lib/commonjs/lifecycle.js +2 -0
  47. package/lib/commonjs/lifecycle.js.map +1 -1
  48. package/lib/commonjs/pairing/PairingController.js.map +1 -1
  49. package/lib/commonjs/runtime/BannerHost.js +3 -3
  50. package/lib/commonjs/runtime/BannerHost.js.map +1 -1
  51. package/lib/commonjs/runtime/UserflowOverlay.js +17 -13
  52. package/lib/commonjs/runtime/UserflowOverlay.js.map +1 -1
  53. package/lib/commonjs/runtime/WindowOverlayHost.js +83 -0
  54. package/lib/commonjs/runtime/WindowOverlayHost.js.map +1 -0
  55. package/lib/commonjs/runtime/pushBannerLayoutContext.js +11 -8
  56. package/lib/commonjs/runtime/pushBannerLayoutContext.js.map +1 -1
  57. package/lib/commonjs/runtime/userflowCore.js +9 -2
  58. package/lib/commonjs/runtime/userflowCore.js.map +1 -1
  59. package/lib/commonjs/surfaces/BannerSurface.js +2 -6
  60. package/lib/commonjs/surfaces/BannerSurface.js.map +1 -1
  61. package/lib/commonjs/surfaces/ProgressBar.js +2 -1
  62. package/lib/commonjs/surfaces/ProgressBar.js.map +1 -1
  63. package/lib/commonjs/surfaces/TooltipSurface.js +114 -51
  64. package/lib/commonjs/surfaces/TooltipSurface.js.map +1 -1
  65. package/lib/commonjs/surfaces/bannerWebView/BannerWebViewBar.js +6 -4
  66. package/lib/commonjs/surfaces/bannerWebView/BannerWebViewBar.js.map +1 -1
  67. package/lib/commonjs/surfaces/bannerWebView/bannerNeedsWebView.js +3 -33
  68. package/lib/commonjs/surfaces/bannerWebView/bannerNeedsWebView.js.map +1 -1
  69. package/lib/commonjs/surfaces/bannerWebView/bannerThemeStyles.js +2 -1
  70. package/lib/commonjs/surfaces/bannerWebView/bannerThemeStyles.js.map +1 -1
  71. package/lib/commonjs/surfaces/bannerWebView/bannerWebViewHeight.js +33 -0
  72. package/lib/commonjs/surfaces/bannerWebView/bannerWebViewHeight.js.map +1 -0
  73. package/lib/commonjs/surfaces/bannerWebView/buildCustomBannerHtml.js +45 -12
  74. package/lib/commonjs/surfaces/bannerWebView/buildCustomBannerHtml.js.map +1 -1
  75. package/lib/commonjs/surfaces/tooltip/TooltipHighlight.js +6 -6
  76. package/lib/commonjs/surfaces/tooltip/TooltipHighlight.js.map +1 -1
  77. package/lib/commonjs/surfaces/tooltip/targetOrigin.js +74 -0
  78. package/lib/commonjs/surfaces/tooltip/targetOrigin.js.map +1 -0
  79. package/lib/commonjs/version.js +1 -1
  80. package/lib/module/anchors/AnchorRegistry.js +5 -0
  81. package/lib/module/anchors/AnchorRegistry.js.map +1 -1
  82. package/lib/module/anchors/ScrollContainerRegistry.js +8 -0
  83. package/lib/module/anchors/ScrollContainerRegistry.js.map +1 -1
  84. package/lib/module/anchors/fiber/FiberScanRootStore.js +8 -0
  85. package/lib/module/anchors/fiber/FiberScanRootStore.js.map +1 -1
  86. package/lib/module/anchors/fiber/detectAppFontFamily.js +330 -0
  87. package/lib/module/anchors/fiber/detectAppFontFamily.js.map +1 -0
  88. package/lib/module/anchors/fiber/presentedModal.js +206 -0
  89. package/lib/module/anchors/fiber/presentedModal.js.map +1 -0
  90. package/lib/module/anchors/fiber/touchTargetFiber.js +1 -0
  91. package/lib/module/anchors/fiber/touchTargetFiber.js.map +1 -1
  92. package/lib/module/anchors/fiber/visibleRect.js +12 -3
  93. package/lib/module/anchors/fiber/visibleRect.js.map +1 -1
  94. package/lib/module/anchors/fiber/visibleScreens.js +5 -0
  95. package/lib/module/anchors/fiber/visibleScreens.js.map +1 -1
  96. package/lib/module/anchors/useUserflowAnchor.js.map +1 -1
  97. package/lib/module/anchors/useUserflowScrollContainer.js.map +1 -1
  98. package/lib/module/authoring/ElementPickerOverlay.js +199 -140
  99. package/lib/module/authoring/ElementPickerOverlay.js.map +1 -1
  100. package/lib/module/authoring/hitTest.js +67 -11
  101. package/lib/module/authoring/hitTest.js.map +1 -1
  102. package/lib/module/authoring/hostAtPoint.js +45 -21
  103. package/lib/module/authoring/hostAtPoint.js.map +1 -1
  104. package/lib/module/content/BannerStepButton.js +2 -1
  105. package/lib/module/content/BannerStepButton.js.map +1 -1
  106. package/lib/module/content/RichContentRenderer.js +27 -9
  107. package/lib/module/content/RichContentRenderer.js.map +1 -1
  108. package/lib/module/content/StepButton.js +2 -1
  109. package/lib/module/content/StepButton.js.map +1 -1
  110. package/lib/module/content/resolveContentFontFamily.js +89 -0
  111. package/lib/module/content/resolveContentFontFamily.js.map +1 -0
  112. package/lib/module/deepLinking.js.map +1 -1
  113. package/lib/module/deviceContext.js +38 -17
  114. package/lib/module/deviceContext.js.map +1 -1
  115. package/lib/module/index.js +13 -5
  116. package/lib/module/index.js.map +1 -1
  117. package/lib/module/installCheck.js +3 -3
  118. package/lib/module/installCheck.js.map +1 -1
  119. package/lib/module/lifecycle.js +2 -0
  120. package/lib/module/lifecycle.js.map +1 -1
  121. package/lib/module/pairing/PairingController.js.map +1 -1
  122. package/lib/module/runtime/BannerHost.js +3 -3
  123. package/lib/module/runtime/BannerHost.js.map +1 -1
  124. package/lib/module/runtime/UserflowOverlay.js +18 -14
  125. package/lib/module/runtime/UserflowOverlay.js.map +1 -1
  126. package/lib/module/runtime/WindowOverlayHost.js +76 -0
  127. package/lib/module/runtime/WindowOverlayHost.js.map +1 -0
  128. package/lib/module/runtime/pushBannerLayoutContext.js +11 -8
  129. package/lib/module/runtime/pushBannerLayoutContext.js.map +1 -1
  130. package/lib/module/runtime/userflowCore.js +9 -2
  131. package/lib/module/runtime/userflowCore.js.map +1 -1
  132. package/lib/module/surfaces/BannerSurface.js +2 -6
  133. package/lib/module/surfaces/BannerSurface.js.map +1 -1
  134. package/lib/module/surfaces/ProgressBar.js +2 -1
  135. package/lib/module/surfaces/ProgressBar.js.map +1 -1
  136. package/lib/module/surfaces/TooltipSurface.js +114 -51
  137. package/lib/module/surfaces/TooltipSurface.js.map +1 -1
  138. package/lib/module/surfaces/bannerWebView/BannerWebViewBar.js +6 -4
  139. package/lib/module/surfaces/bannerWebView/BannerWebViewBar.js.map +1 -1
  140. package/lib/module/surfaces/bannerWebView/bannerNeedsWebView.js +3 -31
  141. package/lib/module/surfaces/bannerWebView/bannerNeedsWebView.js.map +1 -1
  142. package/lib/module/surfaces/bannerWebView/bannerThemeStyles.js +2 -1
  143. package/lib/module/surfaces/bannerWebView/bannerThemeStyles.js.map +1 -1
  144. package/lib/module/surfaces/bannerWebView/bannerWebViewHeight.js +29 -0
  145. package/lib/module/surfaces/bannerWebView/bannerWebViewHeight.js.map +1 -0
  146. package/lib/module/surfaces/bannerWebView/buildCustomBannerHtml.js +45 -12
  147. package/lib/module/surfaces/bannerWebView/buildCustomBannerHtml.js.map +1 -1
  148. package/lib/module/surfaces/tooltip/TooltipHighlight.js +6 -6
  149. package/lib/module/surfaces/tooltip/TooltipHighlight.js.map +1 -1
  150. package/lib/module/surfaces/tooltip/targetOrigin.js +67 -0
  151. package/lib/module/surfaces/tooltip/targetOrigin.js.map +1 -0
  152. package/lib/module/version.js +1 -1
  153. package/lib/typescript/commonjs/src/anchors/AnchorRegistry.d.ts +7 -0
  154. package/lib/typescript/commonjs/src/anchors/AnchorRegistry.d.ts.map +1 -1
  155. package/lib/typescript/commonjs/src/anchors/ScrollContainerRegistry.d.ts +11 -2
  156. package/lib/typescript/commonjs/src/anchors/ScrollContainerRegistry.d.ts.map +1 -1
  157. package/lib/typescript/commonjs/src/anchors/fiber/FiberScanRootStore.d.ts +5 -0
  158. package/lib/typescript/commonjs/src/anchors/fiber/FiberScanRootStore.d.ts.map +1 -1
  159. package/lib/typescript/commonjs/src/anchors/fiber/detectAppFontFamily.d.ts +30 -0
  160. package/lib/typescript/commonjs/src/anchors/fiber/detectAppFontFamily.d.ts.map +1 -0
  161. package/lib/typescript/commonjs/src/anchors/fiber/presentedModal.d.ts +45 -0
  162. package/lib/typescript/commonjs/src/anchors/fiber/presentedModal.d.ts.map +1 -0
  163. package/lib/typescript/commonjs/src/anchors/fiber/visibleRect.d.ts +5 -2
  164. package/lib/typescript/commonjs/src/anchors/fiber/visibleRect.d.ts.map +1 -1
  165. package/lib/typescript/commonjs/src/anchors/fiber/visibleScreens.d.ts +2 -0
  166. package/lib/typescript/commonjs/src/anchors/fiber/visibleScreens.d.ts.map +1 -1
  167. package/lib/typescript/commonjs/src/anchors/useUserflowAnchor.d.ts +2 -2
  168. package/lib/typescript/commonjs/src/anchors/useUserflowAnchor.d.ts.map +1 -1
  169. package/lib/typescript/commonjs/src/anchors/useUserflowScrollContainer.d.ts +3 -2
  170. package/lib/typescript/commonjs/src/anchors/useUserflowScrollContainer.d.ts.map +1 -1
  171. package/lib/typescript/commonjs/src/authoring/ElementPickerOverlay.d.ts +4 -0
  172. package/lib/typescript/commonjs/src/authoring/ElementPickerOverlay.d.ts.map +1 -1
  173. package/lib/typescript/commonjs/src/authoring/hitTest.d.ts +25 -2
  174. package/lib/typescript/commonjs/src/authoring/hitTest.d.ts.map +1 -1
  175. package/lib/typescript/commonjs/src/authoring/hostAtPoint.d.ts +6 -1
  176. package/lib/typescript/commonjs/src/authoring/hostAtPoint.d.ts.map +1 -1
  177. package/lib/typescript/commonjs/src/content/BannerStepButton.d.ts.map +1 -1
  178. package/lib/typescript/commonjs/src/content/RichContentRenderer.d.ts.map +1 -1
  179. package/lib/typescript/commonjs/src/content/StepButton.d.ts.map +1 -1
  180. package/lib/typescript/commonjs/src/content/resolveContentFontFamily.d.ts +35 -0
  181. package/lib/typescript/commonjs/src/content/resolveContentFontFamily.d.ts.map +1 -0
  182. package/lib/typescript/commonjs/src/deepLinking.d.ts +1 -1
  183. package/lib/typescript/commonjs/src/deepLinking.d.ts.map +1 -1
  184. package/lib/typescript/commonjs/src/deviceContext.d.ts +14 -5
  185. package/lib/typescript/commonjs/src/deviceContext.d.ts.map +1 -1
  186. package/lib/typescript/commonjs/src/index.d.ts +11 -5
  187. package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
  188. package/lib/typescript/commonjs/src/installCheck.d.ts +2 -2
  189. package/lib/typescript/commonjs/src/installCheck.d.ts.map +1 -1
  190. package/lib/typescript/commonjs/src/lifecycle.d.ts +1 -0
  191. package/lib/typescript/commonjs/src/lifecycle.d.ts.map +1 -1
  192. package/lib/typescript/commonjs/src/pairing/PairingController.d.ts +1 -1
  193. package/lib/typescript/commonjs/src/pairing/PairingController.d.ts.map +1 -1
  194. package/lib/typescript/commonjs/src/runtime/UserflowOverlay.d.ts.map +1 -1
  195. package/lib/typescript/commonjs/src/runtime/WindowOverlayHost.d.ts +34 -0
  196. package/lib/typescript/commonjs/src/runtime/WindowOverlayHost.d.ts.map +1 -0
  197. package/lib/typescript/commonjs/src/runtime/pushBannerLayoutContext.d.ts +5 -0
  198. package/lib/typescript/commonjs/src/runtime/pushBannerLayoutContext.d.ts.map +1 -1
  199. package/lib/typescript/commonjs/src/runtime/userflowCore.d.ts.map +1 -1
  200. package/lib/typescript/commonjs/src/surfaces/BannerSurface.d.ts +1 -4
  201. package/lib/typescript/commonjs/src/surfaces/BannerSurface.d.ts.map +1 -1
  202. package/lib/typescript/commonjs/src/surfaces/ProgressBar.d.ts.map +1 -1
  203. package/lib/typescript/commonjs/src/surfaces/TooltipSurface.d.ts.map +1 -1
  204. package/lib/typescript/commonjs/src/surfaces/bannerWebView/BannerWebViewBar.d.ts.map +1 -1
  205. package/lib/typescript/commonjs/src/surfaces/bannerWebView/bannerNeedsWebView.d.ts +3 -12
  206. package/lib/typescript/commonjs/src/surfaces/bannerWebView/bannerNeedsWebView.d.ts.map +1 -1
  207. package/lib/typescript/commonjs/src/surfaces/bannerWebView/bannerThemeStyles.d.ts.map +1 -1
  208. package/lib/typescript/commonjs/src/surfaces/bannerWebView/bannerWebViewHeight.d.ts +13 -0
  209. package/lib/typescript/commonjs/src/surfaces/bannerWebView/bannerWebViewHeight.d.ts.map +1 -0
  210. package/lib/typescript/commonjs/src/surfaces/bannerWebView/buildCustomBannerHtml.d.ts.map +1 -1
  211. package/lib/typescript/commonjs/src/surfaces/tooltip/targetOrigin.d.ts +26 -0
  212. package/lib/typescript/commonjs/src/surfaces/tooltip/targetOrigin.d.ts.map +1 -0
  213. package/lib/typescript/commonjs/src/version.d.ts +1 -1
  214. package/lib/typescript/module/src/anchors/AnchorRegistry.d.ts +7 -0
  215. package/lib/typescript/module/src/anchors/AnchorRegistry.d.ts.map +1 -1
  216. package/lib/typescript/module/src/anchors/ScrollContainerRegistry.d.ts +11 -2
  217. package/lib/typescript/module/src/anchors/ScrollContainerRegistry.d.ts.map +1 -1
  218. package/lib/typescript/module/src/anchors/fiber/FiberScanRootStore.d.ts +5 -0
  219. package/lib/typescript/module/src/anchors/fiber/FiberScanRootStore.d.ts.map +1 -1
  220. package/lib/typescript/module/src/anchors/fiber/detectAppFontFamily.d.ts +30 -0
  221. package/lib/typescript/module/src/anchors/fiber/detectAppFontFamily.d.ts.map +1 -0
  222. package/lib/typescript/module/src/anchors/fiber/presentedModal.d.ts +45 -0
  223. package/lib/typescript/module/src/anchors/fiber/presentedModal.d.ts.map +1 -0
  224. package/lib/typescript/module/src/anchors/fiber/visibleRect.d.ts +5 -2
  225. package/lib/typescript/module/src/anchors/fiber/visibleRect.d.ts.map +1 -1
  226. package/lib/typescript/module/src/anchors/fiber/visibleScreens.d.ts +2 -0
  227. package/lib/typescript/module/src/anchors/fiber/visibleScreens.d.ts.map +1 -1
  228. package/lib/typescript/module/src/anchors/useUserflowAnchor.d.ts +2 -2
  229. package/lib/typescript/module/src/anchors/useUserflowAnchor.d.ts.map +1 -1
  230. package/lib/typescript/module/src/anchors/useUserflowScrollContainer.d.ts +3 -2
  231. package/lib/typescript/module/src/anchors/useUserflowScrollContainer.d.ts.map +1 -1
  232. package/lib/typescript/module/src/authoring/ElementPickerOverlay.d.ts +4 -0
  233. package/lib/typescript/module/src/authoring/ElementPickerOverlay.d.ts.map +1 -1
  234. package/lib/typescript/module/src/authoring/hitTest.d.ts +25 -2
  235. package/lib/typescript/module/src/authoring/hitTest.d.ts.map +1 -1
  236. package/lib/typescript/module/src/authoring/hostAtPoint.d.ts +6 -1
  237. package/lib/typescript/module/src/authoring/hostAtPoint.d.ts.map +1 -1
  238. package/lib/typescript/module/src/content/BannerStepButton.d.ts.map +1 -1
  239. package/lib/typescript/module/src/content/RichContentRenderer.d.ts.map +1 -1
  240. package/lib/typescript/module/src/content/StepButton.d.ts.map +1 -1
  241. package/lib/typescript/module/src/content/resolveContentFontFamily.d.ts +35 -0
  242. package/lib/typescript/module/src/content/resolveContentFontFamily.d.ts.map +1 -0
  243. package/lib/typescript/module/src/deepLinking.d.ts +1 -1
  244. package/lib/typescript/module/src/deepLinking.d.ts.map +1 -1
  245. package/lib/typescript/module/src/deviceContext.d.ts +14 -5
  246. package/lib/typescript/module/src/deviceContext.d.ts.map +1 -1
  247. package/lib/typescript/module/src/index.d.ts +11 -5
  248. package/lib/typescript/module/src/index.d.ts.map +1 -1
  249. package/lib/typescript/module/src/installCheck.d.ts +2 -2
  250. package/lib/typescript/module/src/installCheck.d.ts.map +1 -1
  251. package/lib/typescript/module/src/lifecycle.d.ts +1 -0
  252. package/lib/typescript/module/src/lifecycle.d.ts.map +1 -1
  253. package/lib/typescript/module/src/pairing/PairingController.d.ts +1 -1
  254. package/lib/typescript/module/src/pairing/PairingController.d.ts.map +1 -1
  255. package/lib/typescript/module/src/runtime/UserflowOverlay.d.ts.map +1 -1
  256. package/lib/typescript/module/src/runtime/WindowOverlayHost.d.ts +34 -0
  257. package/lib/typescript/module/src/runtime/WindowOverlayHost.d.ts.map +1 -0
  258. package/lib/typescript/module/src/runtime/pushBannerLayoutContext.d.ts +5 -0
  259. package/lib/typescript/module/src/runtime/pushBannerLayoutContext.d.ts.map +1 -1
  260. package/lib/typescript/module/src/runtime/userflowCore.d.ts.map +1 -1
  261. package/lib/typescript/module/src/surfaces/BannerSurface.d.ts +1 -4
  262. package/lib/typescript/module/src/surfaces/BannerSurface.d.ts.map +1 -1
  263. package/lib/typescript/module/src/surfaces/ProgressBar.d.ts.map +1 -1
  264. package/lib/typescript/module/src/surfaces/TooltipSurface.d.ts.map +1 -1
  265. package/lib/typescript/module/src/surfaces/bannerWebView/BannerWebViewBar.d.ts.map +1 -1
  266. package/lib/typescript/module/src/surfaces/bannerWebView/bannerNeedsWebView.d.ts +3 -12
  267. package/lib/typescript/module/src/surfaces/bannerWebView/bannerNeedsWebView.d.ts.map +1 -1
  268. package/lib/typescript/module/src/surfaces/bannerWebView/bannerThemeStyles.d.ts.map +1 -1
  269. package/lib/typescript/module/src/surfaces/bannerWebView/bannerWebViewHeight.d.ts +13 -0
  270. package/lib/typescript/module/src/surfaces/bannerWebView/bannerWebViewHeight.d.ts.map +1 -0
  271. package/lib/typescript/module/src/surfaces/bannerWebView/buildCustomBannerHtml.d.ts.map +1 -1
  272. package/lib/typescript/module/src/surfaces/tooltip/targetOrigin.d.ts +26 -0
  273. package/lib/typescript/module/src/surfaces/tooltip/targetOrigin.d.ts.map +1 -0
  274. package/lib/typescript/module/src/version.d.ts +1 -1
  275. package/package.json +5 -4
  276. package/src/anchors/AnchorRegistry.ts +8 -0
  277. package/src/anchors/ScrollContainerRegistry.ts +15 -3
  278. package/src/anchors/fiber/FiberScanRootStore.ts +8 -0
  279. package/src/anchors/fiber/detectAppFontFamily.ts +400 -0
  280. package/src/anchors/fiber/presentedModal.ts +203 -0
  281. package/src/anchors/fiber/touchTargetFiber.ts +2 -1
  282. package/src/anchors/fiber/visibleRect.ts +12 -3
  283. package/src/anchors/fiber/visibleScreens.ts +5 -0
  284. package/src/anchors/useUserflowAnchor.ts +4 -5
  285. package/src/anchors/useUserflowScrollContainer.ts +5 -4
  286. package/src/authoring/ElementPickerOverlay.tsx +242 -166
  287. package/src/authoring/hitTest.ts +88 -13
  288. package/src/authoring/hostAtPoint.ts +67 -21
  289. package/src/content/BannerStepButton.tsx +2 -1
  290. package/src/content/RichContentRenderer.tsx +16 -9
  291. package/src/content/StepButton.tsx +2 -1
  292. package/src/content/resolveContentFontFamily.ts +119 -0
  293. package/src/deepLinking.ts +2 -1
  294. package/src/deviceContext.ts +50 -14
  295. package/src/index.ts +13 -5
  296. package/src/installCheck.ts +3 -3
  297. package/src/lifecycle.ts +2 -1
  298. package/src/pairing/PairingController.ts +2 -1
  299. package/src/runtime/BannerHost.tsx +3 -3
  300. package/src/runtime/UserflowOverlay.tsx +29 -21
  301. package/src/runtime/WindowOverlayHost.tsx +95 -0
  302. package/src/runtime/pushBannerLayoutContext.tsx +14 -9
  303. package/src/runtime/userflowCore.ts +8 -2
  304. package/src/surfaces/BannerSurface.tsx +2 -6
  305. package/src/surfaces/ProgressBar.tsx +2 -1
  306. package/src/surfaces/TooltipSurface.tsx +118 -47
  307. package/src/surfaces/bannerWebView/BannerWebViewBar.tsx +6 -4
  308. package/src/surfaces/bannerWebView/bannerNeedsWebView.ts +4 -36
  309. package/src/surfaces/bannerWebView/bannerThemeStyles.ts +2 -1
  310. package/src/surfaces/bannerWebView/bannerWebViewHeight.ts +32 -0
  311. package/src/surfaces/bannerWebView/buildCustomBannerHtml.ts +48 -12
  312. package/src/surfaces/tooltip/TooltipHighlight.tsx +3 -5
  313. package/src/surfaces/tooltip/targetOrigin.ts +74 -0
  314. package/src/version.ts +1 -1
  315. package/vendor/core/dist/engine/UserflowCore.d.ts +7 -0
  316. package/vendor/core/dist/engine/UserflowCore.d.ts.map +1 -1
  317. package/vendor/core/dist/engine/UserflowCore.js +3 -2
  318. package/vendor/core/dist/engine/UserflowCore.js.map +1 -1
  319. package/vendor/core/dist/transport/phoenix.d.ts +12 -2
  320. package/vendor/core/dist/transport/phoenix.d.ts.map +1 -1
  321. package/vendor/core/dist/transport/phoenix.js +7 -6
  322. package/vendor/core/dist/transport/phoenix.js.map +1 -1
  323. package/vendor/core/dist/version.d.ts +1 -1
  324. package/vendor/core/dist/version.js +1 -1
  325. package/vendor/core/package.json +1 -1
  326. package/vendor/protocol/dist/flows.d.ts +2 -0
  327. package/vendor/protocol/dist/flows.d.ts.map +1 -1
  328. package/vendor/protocol/package.json +1 -1
@@ -1,7 +1,6 @@
1
1
  import * as React from 'react';
2
- import type { View } from 'react-native';
3
2
 
4
- import { anchorRegistry, type AnchorHost } from './AnchorRegistry';
3
+ import { anchorRegistry, type AnchorHost, type MeasurableNode } from './AnchorRegistry';
5
4
 
6
5
  /**
7
6
  * Register a view as a manual Userflow tooltip / embed target.
@@ -29,7 +28,7 @@ import { anchorRegistry, type AnchorHost } from './AnchorRegistry';
29
28
  *
30
29
  * Phase 3 resolves targets via `step.selector.css` (leading `#` stripped).
31
30
  */
32
- export function useUserflowAnchor(id: string): React.RefCallback<View> {
31
+ export function useUserflowAnchor(id: string): React.RefCallback<MeasurableNode> {
33
32
  const hostRef = React.useRef<AnchorHost | null>(null);
34
33
  const idRef = React.useRef(id);
35
34
 
@@ -55,7 +54,7 @@ export function useUserflowAnchor(id: string): React.RefCallback<View> {
55
54
  };
56
55
  }, []);
57
56
 
58
- return React.useCallback((node: View | null) => {
57
+ return React.useCallback((node: MeasurableNode | null) => {
59
58
  const previous = hostRef.current;
60
59
  const currentId = idRef.current;
61
60
  if (previous) {
@@ -73,7 +72,7 @@ export function useUserflowAnchor(id: string): React.RefCallback<View> {
73
72
  },
74
73
  node,
75
74
  scrollIntoView: () => {
76
- const scrollable = node as View & {
75
+ const scrollable = node as MeasurableNode & {
77
76
  scrollIntoView?: (options?: { block?: string; inline?: string }) => void;
78
77
  };
79
78
  if (typeof scrollable.scrollIntoView === 'function') {
@@ -1,15 +1,16 @@
1
1
  import * as React from 'react';
2
- import type { NativeScrollEvent, NativeSyntheticEvent, ScrollView } from 'react-native';
2
+ import type { NativeScrollEvent, NativeSyntheticEvent } from 'react-native';
3
3
 
4
4
  import {
5
5
  createScrollContainerHost,
6
6
  scrollContainerRegistry,
7
7
  type ScrollContainerHost,
8
+ type ScrollContainerNode,
8
9
  } from './ScrollContainerRegistry';
9
10
 
10
11
  export interface UserflowScrollContainerProps {
11
12
  /** Attach to the host ScrollView (or merge with an existing ref). */
12
- ref: React.RefCallback<ScrollView>;
13
+ ref: React.RefCallback<ScrollContainerNode>;
13
14
  /** Forward to ScrollView so content offsets stay in sync for scroll-into-view. */
14
15
  onScroll: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
15
16
  /** Required for frequent offset updates while scrolling. */
@@ -42,7 +43,7 @@ export function useUserflowScrollContainer(
42
43
  onScrollProp?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void,
43
44
  ): UserflowScrollContainerProps {
44
45
  const hostRef = React.useRef<ScrollContainerHost | null>(null);
45
- const nodeRef = React.useRef<ScrollView | null>(null);
46
+ const nodeRef = React.useRef<ScrollContainerNode | null>(null);
46
47
  const offsetRef = React.useRef({ x: 0, y: 0 });
47
48
 
48
49
  React.useEffect(() => {
@@ -55,7 +56,7 @@ export function useUserflowScrollContainer(
55
56
  };
56
57
  }, []);
57
58
 
58
- const ref = React.useCallback((node: ScrollView | null) => {
59
+ const ref = React.useCallback((node: ScrollContainerNode | null) => {
59
60
  const previous = hostRef.current;
60
61
  if (previous) {
61
62
  scrollContainerRegistry.unregister(previous);
@@ -1,7 +1,15 @@
1
1
  import * as React from 'react';
2
- import { StyleSheet, View, type GestureResponderEvent, type ViewStyle } from 'react-native';
2
+ import {
3
+ Dimensions,
4
+ Keyboard,
5
+ StyleSheet,
6
+ View,
7
+ type GestureResponderEvent,
8
+ type ViewStyle,
9
+ } from 'react-native';
3
10
 
4
11
  import { pointInRect, TARGET_PRESS_TAP_SLOP } from '../anchors/targetPressMonitor';
12
+ import { WindowOverlayHost } from '../runtime/WindowOverlayHost';
5
13
  import { ABSOLUTE_FILL } from '../surfaces/absoluteFill';
6
14
  import {
7
15
  useReportAuthoringBottomHeight,
@@ -25,8 +33,10 @@ import {
25
33
  defaultCandidateIndex,
26
34
  hitTestAt,
27
35
  nextContainingIndex,
36
+ remeasureCandidates,
28
37
  type HitCandidate,
29
38
  type HitRect,
39
+ type ModalMiss,
30
40
  type PickTarget,
31
41
  } from './hitTest';
32
42
 
@@ -46,6 +56,10 @@ const WARNING_HELPER =
46
56
  'Element may have an unreliable ID. This element may be selected but could break later on.';
47
57
  const ERROR_LABEL = 'Can’t select this element';
48
58
  const ERROR_HELPER = 'Element ID not found — select a different element';
59
+ const UNPLACEABLE_SHEET_HELPER =
60
+ 'Can’t tell where this sheet is on screen — in Navigate screens, close the keyboard or expand the sheet';
61
+ const BEHIND_SHEET_HELPER =
62
+ 'This part of the screen is behind the sheet — select inside the sheet, or close it in Navigate screens';
49
63
  const ONBOARDING_COPY = 'Double tap anywhere to access the menu';
50
64
  const RETURN_NUDGE_TITLE = 'Return to the Userflow app';
51
65
  const RETURN_NUDGE_BODY =
@@ -71,6 +85,28 @@ function waitForCapturePaint(): Promise<void> {
71
85
  });
72
86
  }
73
87
 
88
+ interface TapHits {
89
+ hits: HitCandidate[];
90
+ /** Why a tap on a presented sheet found nothing, so the helper can say so. */
91
+ modalMiss: ModalMiss | null;
92
+ }
93
+
94
+ async function hitsAtTap(pageX: number, pageY: number): Promise<TapHits> {
95
+ let modalMiss: ModalMiss | null = null;
96
+ const hits = await hitTestAt(pageX, pageY, {
97
+ onModalMiss: (miss) => {
98
+ modalMiss = miss;
99
+ },
100
+ });
101
+ return { hits, modalMiss };
102
+ }
103
+
104
+ function modalMissHelper(miss: ModalMiss | null): string | null {
105
+ if (miss === 'unplaceable') return UNPLACEABLE_SHEET_HELPER;
106
+ if (miss === 'outside') return BEHIND_SHEET_HELPER;
107
+ return null;
108
+ }
109
+
74
110
  function ringStyle(rect: HitRect, inset: number): ViewStyle {
75
111
  return {
76
112
  position: 'absolute',
@@ -86,6 +122,10 @@ function ringStyle(rect: HitRect, inset: number): ViewStyle {
86
122
  * Overlay chrome for in-app element picking. Mounted by UserflowProvider;
87
123
  * renders nothing until {@link elementPickerController.beginSelection}.
88
124
  * Every pick shows the menu and onboarding tooltip.
125
+ *
126
+ * Drawn in {@link WindowOverlayHost} so native modal screens on iOS cannot
127
+ * cover it. It mounts only while there is something to show, so the window
128
+ * container exists only for the pick.
89
129
  */
90
130
  export function ElementPickerOverlay(): React.ReactElement | null {
91
131
  const [state, setState] = React.useState<ElementPickerState>(() =>
@@ -248,12 +288,12 @@ export function ElementPickerOverlay(): React.ReactElement | null {
248
288
  }
249
289
  }, [phase]);
250
290
 
251
- const applySelection = React.useCallback((hits: HitCandidate[]) => {
291
+ const applySelection = React.useCallback(({ hits, modalMiss }: TapHits) => {
252
292
  if (hits.length === 0) {
253
293
  setCandidates([]);
254
294
  setIndex(0);
255
295
  setSelection('error-no-element');
256
- setStatus(null);
296
+ setStatus(modalMissHelper(modalMiss));
257
297
  return;
258
298
  }
259
299
  const nextIndex = defaultCandidateIndex(hits);
@@ -264,11 +304,11 @@ export function ElementPickerOverlay(): React.ReactElement | null {
264
304
  }, []);
265
305
 
266
306
  const applyHits = React.useCallback(
267
- (hits: HitCandidate[]) => {
307
+ (tapHits: TapHits) => {
268
308
  if (modeRef.current !== 'select') return;
269
309
  lastTapRef.current = null;
270
310
  setChromeVisible(true);
271
- applySelection(hits);
311
+ applySelection(tapHits);
272
312
  },
273
313
  [applySelection],
274
314
  );
@@ -279,7 +319,7 @@ export function ElementPickerOverlay(): React.ReactElement | null {
279
319
  const gen = tapGenRef.current;
280
320
  setBusy(true);
281
321
  setStatus(null);
282
- const hitsPromise = hitTestAt(pageX, pageY);
322
+ const hitsPromise = hitsAtTap(pageX, pageY);
283
323
  const wait = new Promise<void>((resolve) => {
284
324
  applyResolveRef.current = resolve;
285
325
  applyTimerRef.current = setTimeout(() => {
@@ -290,9 +330,9 @@ export function ElementPickerOverlay(): React.ReactElement | null {
290
330
  });
291
331
  void (async () => {
292
332
  try {
293
- const [hits] = await Promise.all([hitsPromise, wait]);
333
+ const [tapHits] = await Promise.all([hitsPromise, wait]);
294
334
  if (tapGenRef.current !== gen) return;
295
- applyHits(hits);
335
+ applyHits(tapHits);
296
336
  } finally {
297
337
  if (tapGenRef.current === gen) setBusy(false);
298
338
  }
@@ -316,8 +356,7 @@ export function ElementPickerOverlay(): React.ReactElement | null {
316
356
  setBusy(true);
317
357
  setStatus(null);
318
358
  try {
319
- const hits = await hitTestAt(pageX, pageY);
320
- applySelection(hits);
359
+ applySelection(await hitsAtTap(pageX, pageY));
321
360
  } finally {
322
361
  setBusy(false);
323
362
  }
@@ -377,6 +416,41 @@ export function ElementPickerOverlay(): React.ReactElement | null {
377
416
  [hideOrShowChrome, onTap, scheduleSelection, selected, selection],
378
417
  );
379
418
 
419
+ // The keyboard opening or closing moves a sheet under the selection, and a
420
+ // rotation moves everything. Measure the selection again so the ring, re-tap
421
+ // cycling, the crop and the rect sent to the Builder follow it.
422
+ const candidatesRef = React.useRef(candidates);
423
+ candidatesRef.current = candidates;
424
+ const hasSelection = candidates.length > 0;
425
+ React.useEffect(() => {
426
+ if (!hasSelection) return;
427
+ let latest = 0;
428
+ const refresh = () => {
429
+ const run = (latest += 1);
430
+ const before = candidatesRef.current;
431
+ void remeasureCandidates(before).then((next) => {
432
+ if (run !== latest || candidatesRef.current !== before) return;
433
+ if (next) {
434
+ setCandidates(next);
435
+ return;
436
+ }
437
+ setCandidates([]);
438
+ setIndex(0);
439
+ setSelection('idle');
440
+ setStatus(null);
441
+ });
442
+ };
443
+ const subscriptions = [
444
+ Keyboard.addListener('keyboardDidShow', refresh),
445
+ Keyboard.addListener('keyboardDidHide', refresh),
446
+ Dimensions.addEventListener('change', refresh),
447
+ ];
448
+ return () => {
449
+ latest += 1;
450
+ for (const subscription of subscriptions) subscription.remove();
451
+ };
452
+ }, [hasSelection]);
453
+
380
454
  const deselect = React.useCallback(() => {
381
455
  setCandidates([]);
382
456
  setIndex(0);
@@ -459,172 +533,174 @@ export function ElementPickerOverlay(): React.ReactElement | null {
459
533
  const tooltipVisible = state.active && showOnboarding && chromeVisible && phase === 'selecting';
460
534
 
461
535
  return (
462
- <View pointerEvents="box-none" style={styles.root} testID="userflow-element-picker">
463
- {returnNudge && !state.active ? (
464
- <ChromeDialog
465
- body={RETURN_NUDGE_BODY}
466
- onClose={dismissReturnNudge}
467
- title={RETURN_NUDGE_TITLE}
468
- >
469
- <ChromeButton
470
- accessibilityLabel="Okay"
471
- flex
472
- label="Okay"
473
- onPress={dismissReturnNudge}
474
- testID="userflow-element-picker-return-okay"
475
- />
476
- </ChromeDialog>
477
- ) : null}
478
- {state.active && (phase === 'selecting' || phase === 'blocked') ? (
479
- <View pointerEvents="none" style={styles.dim} testID="userflow-element-picker-dim" />
480
- ) : null}
481
-
482
- {state.active && selected ? (
483
- <>
484
- {/*
485
- * Painter only. TooltipCutout's band pointerEvents follow the end-user
486
- * surface-interaction setting; the capture layer above absorbs every
487
- * touch first so that flag cannot leak into picking.
488
- */}
489
- <TooltipCutout
490
- backdropColor={chromeOverlay.color}
491
- backdropOpacity={chromeOverlay.opacity}
492
- targetBlocked={false}
493
- targetRect={{
494
- top: selected.rect.y,
495
- left: selected.rect.x,
496
- width: selected.rect.width,
497
- height: selected.rect.height,
498
- }}
499
- />
500
- <View
501
- pointerEvents="none"
502
- style={[
503
- ringStyle(selected.rect, 5),
504
- { borderWidth: 4, borderColor: chromeColors.focusRing },
505
- ]}
506
- testID="userflow-element-picker-focus-ring"
507
- />
536
+ <WindowOverlayHost>
537
+ <View pointerEvents="box-none" style={styles.root} testID="userflow-element-picker">
538
+ {returnNudge && !state.active ? (
539
+ <ChromeDialog
540
+ body={RETURN_NUDGE_BODY}
541
+ onClose={dismissReturnNudge}
542
+ title={RETURN_NUDGE_TITLE}
543
+ >
544
+ <ChromeButton
545
+ accessibilityLabel="Okay"
546
+ flex
547
+ label="Okay"
548
+ onPress={dismissReturnNudge}
549
+ testID="userflow-element-picker-return-okay"
550
+ />
551
+ </ChromeDialog>
552
+ ) : null}
553
+ {state.active && (phase === 'selecting' || phase === 'blocked') ? (
554
+ <View pointerEvents="none" style={styles.dim} testID="userflow-element-picker-dim" />
555
+ ) : null}
556
+
557
+ {state.active && selected ? (
558
+ <>
559
+ {/*
560
+ * Painter only. TooltipCutout's band pointerEvents follow the end-user
561
+ * surface-interaction setting; the capture layer above absorbs every
562
+ * touch first so that flag cannot leak into picking.
563
+ */}
564
+ <TooltipCutout
565
+ backdropColor={chromeOverlay.color}
566
+ backdropOpacity={chromeOverlay.opacity}
567
+ targetBlocked={false}
568
+ targetRect={{
569
+ top: selected.rect.y,
570
+ left: selected.rect.x,
571
+ width: selected.rect.width,
572
+ height: selected.rect.height,
573
+ }}
574
+ />
575
+ <View
576
+ pointerEvents="none"
577
+ style={[
578
+ ringStyle(selected.rect, 5),
579
+ { borderWidth: 4, borderColor: chromeColors.focusRing },
580
+ ]}
581
+ testID="userflow-element-picker-focus-ring"
582
+ />
583
+ <View
584
+ pointerEvents="none"
585
+ style={[
586
+ ringStyle(selected.rect, 1),
587
+ { borderWidth: 1, borderColor: chromeColors.white },
588
+ ]}
589
+ testID="userflow-element-picker-focus-ring-inner"
590
+ />
591
+ </>
592
+ ) : null}
593
+
594
+ {state.active && mode === 'select' ? (
508
595
  <View
509
- pointerEvents="none"
510
- style={[
511
- ringStyle(selected.rect, 1),
512
- { borderWidth: 1, borderColor: chromeColors.white },
513
- ]}
514
- testID="userflow-element-picker-focus-ring-inner"
596
+ testID="userflow-element-picker-capture"
597
+ style={styles.capture}
598
+ onStartShouldSetResponder={() => true}
599
+ onResponderGrant={onGrant}
600
+ onResponderRelease={onRelease}
515
601
  />
516
- </>
517
- ) : null}
518
-
519
- {state.active && mode === 'select' ? (
520
- <View
521
- testID="userflow-element-picker-capture"
522
- style={styles.capture}
523
- onStartShouldSetResponder={() => true}
524
- onResponderGrant={onGrant}
525
- onResponderRelease={onRelease}
526
- />
527
- ) : null}
528
-
529
- {showChromeBars ? (
530
- <ChromeBarTransition
531
- edge="top"
532
- pointerEvents="box-none"
533
- style={styles.top}
534
- visible={chromeBarsVisible}
535
- >
536
- <ChromeTopBar
537
- label={barLabel}
538
- onMeasureHeight={onMeasureHeight}
539
- tone={isError ? 'error' : 'default'}
540
- {...(toneIcon ? { icon: toneIcon } : {})}
541
- />
542
- </ChromeBarTransition>
543
- ) : null}
544
-
545
- {tooltipVisible ? (
546
- <View pointerEvents="none" style={[styles.tooltip, { top: barHeight }]}>
547
- <ChromeTooltip
548
- onDismiss={() => {
549
- setShowOnboarding(false);
550
- setChromeVisible(false);
551
- }}
602
+ ) : null}
603
+
604
+ {showChromeBars ? (
605
+ <ChromeBarTransition
606
+ edge="top"
607
+ pointerEvents="box-none"
608
+ style={styles.top}
609
+ visible={chromeBarsVisible}
552
610
  >
553
- {ONBOARDING_COPY}
554
- </ChromeTooltip>
555
- </View>
556
- ) : null}
557
-
558
- {showChromeBars ? (
559
- <ChromeBarTransition
560
- edge="bottom"
561
- pointerEvents="box-none"
562
- style={styles.bottom}
563
- visible={chromeBarsVisible}
564
- >
565
- <ChromeBottomSheet
566
- helperText={helperText}
567
- onMeasureHeight={onMeasureSheetHeight}
568
- tone={isError ? 'error' : 'default'}
569
- {...(helperIcon ? { helperIcon } : {})}
611
+ <ChromeTopBar
612
+ label={barLabel}
613
+ onMeasureHeight={onMeasureHeight}
614
+ tone={isError ? 'error' : 'default'}
615
+ {...(toneIcon ? { icon: toneIcon } : {})}
616
+ />
617
+ </ChromeBarTransition>
618
+ ) : null}
619
+
620
+ {tooltipVisible ? (
621
+ <View pointerEvents="none" style={[styles.tooltip, { top: barHeight }]}>
622
+ <ChromeTooltip
623
+ onDismiss={() => {
624
+ setShowOnboarding(false);
625
+ setChromeVisible(false);
626
+ }}
627
+ >
628
+ {ONBOARDING_COPY}
629
+ </ChromeTooltip>
630
+ </View>
631
+ ) : null}
632
+
633
+ {showChromeBars ? (
634
+ <ChromeBarTransition
635
+ edge="bottom"
636
+ pointerEvents="box-none"
637
+ style={styles.bottom}
638
+ visible={chromeBarsVisible}
570
639
  >
571
- {phase === 'selected' || phase === 'blocked' ? (
572
- <>
573
- <ChromeButton
574
- accessibilityLabel="Deselect"
575
- label="Deselect"
576
- onPress={deselect}
577
- testID="userflow-element-picker-deselect"
578
- variant="secondary"
579
- />
580
- <ChromeButton
581
- accessibilityLabel="Confirm element"
582
- disabled={busy || isError}
583
- label="Confirm element"
584
- onPress={() => {
585
- void confirm();
586
- }}
587
- testID="userflow-element-picker-confirm"
588
- />
589
- </>
590
- ) : (
591
- <>
592
- <ChromeButton
593
- accessibilityLabel="Cancel element selection"
594
- label="Cancel"
595
- onPress={() => elementPickerController.cancel()}
596
- testID="userflow-element-picker-cancel"
597
- variant="secondary"
598
- />
599
- {phase === 'selecting' ? (
640
+ <ChromeBottomSheet
641
+ helperText={helperText}
642
+ onMeasureHeight={onMeasureSheetHeight}
643
+ tone={isError ? 'error' : 'default'}
644
+ {...(helperIcon ? { helperIcon } : {})}
645
+ >
646
+ {phase === 'selected' || phase === 'blocked' ? (
647
+ <>
600
648
  <ChromeButton
601
- accessibilityLabel="Navigate screens"
602
- label="Navigate screens"
603
- onPress={() => {
604
- cancelPendingSelection();
605
- lastTapRef.current = null;
606
- setStatus(null);
607
- setMode('navigate');
608
- }}
609
- testID="userflow-element-picker-navigate"
649
+ accessibilityLabel="Deselect"
650
+ label="Deselect"
651
+ onPress={deselect}
652
+ testID="userflow-element-picker-deselect"
653
+ variant="secondary"
610
654
  />
611
- ) : (
612
655
  <ChromeButton
613
- accessibilityLabel="Select element here"
614
- label="Select element here"
656
+ accessibilityLabel="Confirm element"
657
+ disabled={busy || isError}
658
+ label="Confirm element"
615
659
  onPress={() => {
616
- setStatus(null);
617
- setMode('select');
660
+ void confirm();
618
661
  }}
619
- testID="userflow-element-picker-select-here"
662
+ testID="userflow-element-picker-confirm"
663
+ />
664
+ </>
665
+ ) : (
666
+ <>
667
+ <ChromeButton
668
+ accessibilityLabel="Cancel element selection"
669
+ label="Cancel"
670
+ onPress={() => elementPickerController.cancel()}
671
+ testID="userflow-element-picker-cancel"
672
+ variant="secondary"
620
673
  />
621
- )}
622
- </>
623
- )}
624
- </ChromeBottomSheet>
625
- </ChromeBarTransition>
626
- ) : null}
627
- </View>
674
+ {phase === 'selecting' ? (
675
+ <ChromeButton
676
+ accessibilityLabel="Navigate screens"
677
+ label="Navigate screens"
678
+ onPress={() => {
679
+ cancelPendingSelection();
680
+ lastTapRef.current = null;
681
+ setStatus(null);
682
+ setMode('navigate');
683
+ }}
684
+ testID="userflow-element-picker-navigate"
685
+ />
686
+ ) : (
687
+ <ChromeButton
688
+ accessibilityLabel="Select element here"
689
+ label="Select element here"
690
+ onPress={() => {
691
+ setStatus(null);
692
+ setMode('select');
693
+ }}
694
+ testID="userflow-element-picker-select-here"
695
+ />
696
+ )}
697
+ </>
698
+ )}
699
+ </ChromeBottomSheet>
700
+ </ChromeBarTransition>
701
+ ) : null}
702
+ </View>
703
+ </WindowOverlayHost>
628
704
  );
629
705
  }
630
706