@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.
- package/README.md +65 -33
- package/docs/custom-fonts.md +36 -0
- package/docs/troubleshooting.md +45 -44
- package/expo-plugin/hostDependencyWarnings.d.ts +5 -5
- package/expo-plugin/hostDependencyWarnings.js +7 -7
- package/expo-plugin/hostDependencyWarnings.js.map +1 -1
- package/lib/commonjs/anchors/AnchorRegistry.js +5 -0
- package/lib/commonjs/anchors/AnchorRegistry.js.map +1 -1
- package/lib/commonjs/anchors/ScrollContainerRegistry.js +8 -0
- package/lib/commonjs/anchors/ScrollContainerRegistry.js.map +1 -1
- package/lib/commonjs/anchors/fiber/FiberScanRootStore.js +8 -0
- package/lib/commonjs/anchors/fiber/FiberScanRootStore.js.map +1 -1
- package/lib/commonjs/anchors/fiber/detectAppFontFamily.js +341 -0
- package/lib/commonjs/anchors/fiber/detectAppFontFamily.js.map +1 -0
- package/lib/commonjs/anchors/fiber/presentedModal.js +215 -0
- package/lib/commonjs/anchors/fiber/presentedModal.js.map +1 -0
- package/lib/commonjs/anchors/fiber/touchTargetFiber.js +1 -0
- package/lib/commonjs/anchors/fiber/touchTargetFiber.js.map +1 -1
- package/lib/commonjs/anchors/fiber/visibleRect.js +12 -3
- package/lib/commonjs/anchors/fiber/visibleRect.js.map +1 -1
- package/lib/commonjs/anchors/fiber/visibleScreens.js +6 -0
- package/lib/commonjs/anchors/fiber/visibleScreens.js.map +1 -1
- package/lib/commonjs/anchors/useUserflowAnchor.js.map +1 -1
- package/lib/commonjs/anchors/useUserflowScrollContainer.js.map +1 -1
- package/lib/commonjs/authoring/ElementPickerOverlay.js +197 -138
- package/lib/commonjs/authoring/ElementPickerOverlay.js.map +1 -1
- package/lib/commonjs/authoring/hitTest.js +67 -10
- package/lib/commonjs/authoring/hitTest.js.map +1 -1
- package/lib/commonjs/authoring/hostAtPoint.js +45 -21
- package/lib/commonjs/authoring/hostAtPoint.js.map +1 -1
- package/lib/commonjs/content/BannerStepButton.js +2 -1
- package/lib/commonjs/content/BannerStepButton.js.map +1 -1
- package/lib/commonjs/content/RichContentRenderer.js +27 -9
- package/lib/commonjs/content/RichContentRenderer.js.map +1 -1
- package/lib/commonjs/content/StepButton.js +2 -1
- package/lib/commonjs/content/StepButton.js.map +1 -1
- package/lib/commonjs/content/resolveContentFontFamily.js +96 -0
- package/lib/commonjs/content/resolveContentFontFamily.js.map +1 -0
- package/lib/commonjs/deepLinking.js.map +1 -1
- package/lib/commonjs/deviceContext.js +39 -19
- package/lib/commonjs/deviceContext.js.map +1 -1
- package/lib/commonjs/index.js +13 -5
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/installCheck.js +3 -3
- package/lib/commonjs/installCheck.js.map +1 -1
- package/lib/commonjs/lifecycle.js +2 -0
- package/lib/commonjs/lifecycle.js.map +1 -1
- package/lib/commonjs/pairing/PairingController.js.map +1 -1
- package/lib/commonjs/runtime/BannerHost.js +3 -3
- package/lib/commonjs/runtime/BannerHost.js.map +1 -1
- package/lib/commonjs/runtime/UserflowOverlay.js +17 -13
- package/lib/commonjs/runtime/UserflowOverlay.js.map +1 -1
- package/lib/commonjs/runtime/WindowOverlayHost.js +83 -0
- package/lib/commonjs/runtime/WindowOverlayHost.js.map +1 -0
- package/lib/commonjs/runtime/pushBannerLayoutContext.js +11 -8
- package/lib/commonjs/runtime/pushBannerLayoutContext.js.map +1 -1
- package/lib/commonjs/runtime/userflowCore.js +9 -2
- package/lib/commonjs/runtime/userflowCore.js.map +1 -1
- package/lib/commonjs/surfaces/BannerSurface.js +2 -6
- package/lib/commonjs/surfaces/BannerSurface.js.map +1 -1
- package/lib/commonjs/surfaces/ProgressBar.js +2 -1
- package/lib/commonjs/surfaces/ProgressBar.js.map +1 -1
- package/lib/commonjs/surfaces/TooltipSurface.js +114 -51
- package/lib/commonjs/surfaces/TooltipSurface.js.map +1 -1
- package/lib/commonjs/surfaces/bannerWebView/BannerWebViewBar.js +6 -4
- package/lib/commonjs/surfaces/bannerWebView/BannerWebViewBar.js.map +1 -1
- package/lib/commonjs/surfaces/bannerWebView/bannerNeedsWebView.js +3 -33
- package/lib/commonjs/surfaces/bannerWebView/bannerNeedsWebView.js.map +1 -1
- package/lib/commonjs/surfaces/bannerWebView/bannerThemeStyles.js +2 -1
- package/lib/commonjs/surfaces/bannerWebView/bannerThemeStyles.js.map +1 -1
- package/lib/commonjs/surfaces/bannerWebView/bannerWebViewHeight.js +33 -0
- package/lib/commonjs/surfaces/bannerWebView/bannerWebViewHeight.js.map +1 -0
- package/lib/commonjs/surfaces/bannerWebView/buildCustomBannerHtml.js +45 -12
- package/lib/commonjs/surfaces/bannerWebView/buildCustomBannerHtml.js.map +1 -1
- package/lib/commonjs/surfaces/tooltip/TooltipHighlight.js +6 -6
- package/lib/commonjs/surfaces/tooltip/TooltipHighlight.js.map +1 -1
- package/lib/commonjs/surfaces/tooltip/targetOrigin.js +74 -0
- package/lib/commonjs/surfaces/tooltip/targetOrigin.js.map +1 -0
- package/lib/commonjs/version.js +1 -1
- package/lib/module/anchors/AnchorRegistry.js +5 -0
- package/lib/module/anchors/AnchorRegistry.js.map +1 -1
- package/lib/module/anchors/ScrollContainerRegistry.js +8 -0
- package/lib/module/anchors/ScrollContainerRegistry.js.map +1 -1
- package/lib/module/anchors/fiber/FiberScanRootStore.js +8 -0
- package/lib/module/anchors/fiber/FiberScanRootStore.js.map +1 -1
- package/lib/module/anchors/fiber/detectAppFontFamily.js +330 -0
- package/lib/module/anchors/fiber/detectAppFontFamily.js.map +1 -0
- package/lib/module/anchors/fiber/presentedModal.js +206 -0
- package/lib/module/anchors/fiber/presentedModal.js.map +1 -0
- package/lib/module/anchors/fiber/touchTargetFiber.js +1 -0
- package/lib/module/anchors/fiber/touchTargetFiber.js.map +1 -1
- package/lib/module/anchors/fiber/visibleRect.js +12 -3
- package/lib/module/anchors/fiber/visibleRect.js.map +1 -1
- package/lib/module/anchors/fiber/visibleScreens.js +5 -0
- package/lib/module/anchors/fiber/visibleScreens.js.map +1 -1
- package/lib/module/anchors/useUserflowAnchor.js.map +1 -1
- package/lib/module/anchors/useUserflowScrollContainer.js.map +1 -1
- package/lib/module/authoring/ElementPickerOverlay.js +199 -140
- package/lib/module/authoring/ElementPickerOverlay.js.map +1 -1
- package/lib/module/authoring/hitTest.js +67 -11
- package/lib/module/authoring/hitTest.js.map +1 -1
- package/lib/module/authoring/hostAtPoint.js +45 -21
- package/lib/module/authoring/hostAtPoint.js.map +1 -1
- package/lib/module/content/BannerStepButton.js +2 -1
- package/lib/module/content/BannerStepButton.js.map +1 -1
- package/lib/module/content/RichContentRenderer.js +27 -9
- package/lib/module/content/RichContentRenderer.js.map +1 -1
- package/lib/module/content/StepButton.js +2 -1
- package/lib/module/content/StepButton.js.map +1 -1
- package/lib/module/content/resolveContentFontFamily.js +89 -0
- package/lib/module/content/resolveContentFontFamily.js.map +1 -0
- package/lib/module/deepLinking.js.map +1 -1
- package/lib/module/deviceContext.js +38 -17
- package/lib/module/deviceContext.js.map +1 -1
- package/lib/module/index.js +13 -5
- package/lib/module/index.js.map +1 -1
- package/lib/module/installCheck.js +3 -3
- package/lib/module/installCheck.js.map +1 -1
- package/lib/module/lifecycle.js +2 -0
- package/lib/module/lifecycle.js.map +1 -1
- package/lib/module/pairing/PairingController.js.map +1 -1
- package/lib/module/runtime/BannerHost.js +3 -3
- package/lib/module/runtime/BannerHost.js.map +1 -1
- package/lib/module/runtime/UserflowOverlay.js +18 -14
- package/lib/module/runtime/UserflowOverlay.js.map +1 -1
- package/lib/module/runtime/WindowOverlayHost.js +76 -0
- package/lib/module/runtime/WindowOverlayHost.js.map +1 -0
- package/lib/module/runtime/pushBannerLayoutContext.js +11 -8
- package/lib/module/runtime/pushBannerLayoutContext.js.map +1 -1
- package/lib/module/runtime/userflowCore.js +9 -2
- package/lib/module/runtime/userflowCore.js.map +1 -1
- package/lib/module/surfaces/BannerSurface.js +2 -6
- package/lib/module/surfaces/BannerSurface.js.map +1 -1
- package/lib/module/surfaces/ProgressBar.js +2 -1
- package/lib/module/surfaces/ProgressBar.js.map +1 -1
- package/lib/module/surfaces/TooltipSurface.js +114 -51
- package/lib/module/surfaces/TooltipSurface.js.map +1 -1
- package/lib/module/surfaces/bannerWebView/BannerWebViewBar.js +6 -4
- package/lib/module/surfaces/bannerWebView/BannerWebViewBar.js.map +1 -1
- package/lib/module/surfaces/bannerWebView/bannerNeedsWebView.js +3 -31
- package/lib/module/surfaces/bannerWebView/bannerNeedsWebView.js.map +1 -1
- package/lib/module/surfaces/bannerWebView/bannerThemeStyles.js +2 -1
- package/lib/module/surfaces/bannerWebView/bannerThemeStyles.js.map +1 -1
- package/lib/module/surfaces/bannerWebView/bannerWebViewHeight.js +29 -0
- package/lib/module/surfaces/bannerWebView/bannerWebViewHeight.js.map +1 -0
- package/lib/module/surfaces/bannerWebView/buildCustomBannerHtml.js +45 -12
- package/lib/module/surfaces/bannerWebView/buildCustomBannerHtml.js.map +1 -1
- package/lib/module/surfaces/tooltip/TooltipHighlight.js +6 -6
- package/lib/module/surfaces/tooltip/TooltipHighlight.js.map +1 -1
- package/lib/module/surfaces/tooltip/targetOrigin.js +67 -0
- package/lib/module/surfaces/tooltip/targetOrigin.js.map +1 -0
- package/lib/module/version.js +1 -1
- package/lib/typescript/commonjs/src/anchors/AnchorRegistry.d.ts +7 -0
- package/lib/typescript/commonjs/src/anchors/AnchorRegistry.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/anchors/ScrollContainerRegistry.d.ts +11 -2
- package/lib/typescript/commonjs/src/anchors/ScrollContainerRegistry.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/anchors/fiber/FiberScanRootStore.d.ts +5 -0
- package/lib/typescript/commonjs/src/anchors/fiber/FiberScanRootStore.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/anchors/fiber/detectAppFontFamily.d.ts +30 -0
- package/lib/typescript/commonjs/src/anchors/fiber/detectAppFontFamily.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/anchors/fiber/presentedModal.d.ts +45 -0
- package/lib/typescript/commonjs/src/anchors/fiber/presentedModal.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/anchors/fiber/visibleRect.d.ts +5 -2
- package/lib/typescript/commonjs/src/anchors/fiber/visibleRect.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/anchors/fiber/visibleScreens.d.ts +2 -0
- package/lib/typescript/commonjs/src/anchors/fiber/visibleScreens.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/anchors/useUserflowAnchor.d.ts +2 -2
- package/lib/typescript/commonjs/src/anchors/useUserflowAnchor.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/anchors/useUserflowScrollContainer.d.ts +3 -2
- package/lib/typescript/commonjs/src/anchors/useUserflowScrollContainer.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/authoring/ElementPickerOverlay.d.ts +4 -0
- package/lib/typescript/commonjs/src/authoring/ElementPickerOverlay.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/authoring/hitTest.d.ts +25 -2
- package/lib/typescript/commonjs/src/authoring/hitTest.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/authoring/hostAtPoint.d.ts +6 -1
- package/lib/typescript/commonjs/src/authoring/hostAtPoint.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/content/BannerStepButton.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/content/RichContentRenderer.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/content/StepButton.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/content/resolveContentFontFamily.d.ts +35 -0
- package/lib/typescript/commonjs/src/content/resolveContentFontFamily.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/deepLinking.d.ts +1 -1
- package/lib/typescript/commonjs/src/deepLinking.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/deviceContext.d.ts +14 -5
- package/lib/typescript/commonjs/src/deviceContext.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/index.d.ts +11 -5
- package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/installCheck.d.ts +2 -2
- package/lib/typescript/commonjs/src/installCheck.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/lifecycle.d.ts +1 -0
- package/lib/typescript/commonjs/src/lifecycle.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/pairing/PairingController.d.ts +1 -1
- package/lib/typescript/commonjs/src/pairing/PairingController.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/runtime/UserflowOverlay.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/runtime/WindowOverlayHost.d.ts +34 -0
- package/lib/typescript/commonjs/src/runtime/WindowOverlayHost.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/runtime/pushBannerLayoutContext.d.ts +5 -0
- package/lib/typescript/commonjs/src/runtime/pushBannerLayoutContext.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/runtime/userflowCore.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/surfaces/BannerSurface.d.ts +1 -4
- package/lib/typescript/commonjs/src/surfaces/BannerSurface.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/surfaces/ProgressBar.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/surfaces/TooltipSurface.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/surfaces/bannerWebView/BannerWebViewBar.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/surfaces/bannerWebView/bannerNeedsWebView.d.ts +3 -12
- package/lib/typescript/commonjs/src/surfaces/bannerWebView/bannerNeedsWebView.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/surfaces/bannerWebView/bannerThemeStyles.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/surfaces/bannerWebView/bannerWebViewHeight.d.ts +13 -0
- package/lib/typescript/commonjs/src/surfaces/bannerWebView/bannerWebViewHeight.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/surfaces/bannerWebView/buildCustomBannerHtml.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/surfaces/tooltip/targetOrigin.d.ts +26 -0
- package/lib/typescript/commonjs/src/surfaces/tooltip/targetOrigin.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/version.d.ts +1 -1
- package/lib/typescript/module/src/anchors/AnchorRegistry.d.ts +7 -0
- package/lib/typescript/module/src/anchors/AnchorRegistry.d.ts.map +1 -1
- package/lib/typescript/module/src/anchors/ScrollContainerRegistry.d.ts +11 -2
- package/lib/typescript/module/src/anchors/ScrollContainerRegistry.d.ts.map +1 -1
- package/lib/typescript/module/src/anchors/fiber/FiberScanRootStore.d.ts +5 -0
- package/lib/typescript/module/src/anchors/fiber/FiberScanRootStore.d.ts.map +1 -1
- package/lib/typescript/module/src/anchors/fiber/detectAppFontFamily.d.ts +30 -0
- package/lib/typescript/module/src/anchors/fiber/detectAppFontFamily.d.ts.map +1 -0
- package/lib/typescript/module/src/anchors/fiber/presentedModal.d.ts +45 -0
- package/lib/typescript/module/src/anchors/fiber/presentedModal.d.ts.map +1 -0
- package/lib/typescript/module/src/anchors/fiber/visibleRect.d.ts +5 -2
- package/lib/typescript/module/src/anchors/fiber/visibleRect.d.ts.map +1 -1
- package/lib/typescript/module/src/anchors/fiber/visibleScreens.d.ts +2 -0
- package/lib/typescript/module/src/anchors/fiber/visibleScreens.d.ts.map +1 -1
- package/lib/typescript/module/src/anchors/useUserflowAnchor.d.ts +2 -2
- package/lib/typescript/module/src/anchors/useUserflowAnchor.d.ts.map +1 -1
- package/lib/typescript/module/src/anchors/useUserflowScrollContainer.d.ts +3 -2
- package/lib/typescript/module/src/anchors/useUserflowScrollContainer.d.ts.map +1 -1
- package/lib/typescript/module/src/authoring/ElementPickerOverlay.d.ts +4 -0
- package/lib/typescript/module/src/authoring/ElementPickerOverlay.d.ts.map +1 -1
- package/lib/typescript/module/src/authoring/hitTest.d.ts +25 -2
- package/lib/typescript/module/src/authoring/hitTest.d.ts.map +1 -1
- package/lib/typescript/module/src/authoring/hostAtPoint.d.ts +6 -1
- package/lib/typescript/module/src/authoring/hostAtPoint.d.ts.map +1 -1
- package/lib/typescript/module/src/content/BannerStepButton.d.ts.map +1 -1
- package/lib/typescript/module/src/content/RichContentRenderer.d.ts.map +1 -1
- package/lib/typescript/module/src/content/StepButton.d.ts.map +1 -1
- package/lib/typescript/module/src/content/resolveContentFontFamily.d.ts +35 -0
- package/lib/typescript/module/src/content/resolveContentFontFamily.d.ts.map +1 -0
- package/lib/typescript/module/src/deepLinking.d.ts +1 -1
- package/lib/typescript/module/src/deepLinking.d.ts.map +1 -1
- package/lib/typescript/module/src/deviceContext.d.ts +14 -5
- package/lib/typescript/module/src/deviceContext.d.ts.map +1 -1
- package/lib/typescript/module/src/index.d.ts +11 -5
- package/lib/typescript/module/src/index.d.ts.map +1 -1
- package/lib/typescript/module/src/installCheck.d.ts +2 -2
- package/lib/typescript/module/src/installCheck.d.ts.map +1 -1
- package/lib/typescript/module/src/lifecycle.d.ts +1 -0
- package/lib/typescript/module/src/lifecycle.d.ts.map +1 -1
- package/lib/typescript/module/src/pairing/PairingController.d.ts +1 -1
- package/lib/typescript/module/src/pairing/PairingController.d.ts.map +1 -1
- package/lib/typescript/module/src/runtime/UserflowOverlay.d.ts.map +1 -1
- package/lib/typescript/module/src/runtime/WindowOverlayHost.d.ts +34 -0
- package/lib/typescript/module/src/runtime/WindowOverlayHost.d.ts.map +1 -0
- package/lib/typescript/module/src/runtime/pushBannerLayoutContext.d.ts +5 -0
- package/lib/typescript/module/src/runtime/pushBannerLayoutContext.d.ts.map +1 -1
- package/lib/typescript/module/src/runtime/userflowCore.d.ts.map +1 -1
- package/lib/typescript/module/src/surfaces/BannerSurface.d.ts +1 -4
- package/lib/typescript/module/src/surfaces/BannerSurface.d.ts.map +1 -1
- package/lib/typescript/module/src/surfaces/ProgressBar.d.ts.map +1 -1
- package/lib/typescript/module/src/surfaces/TooltipSurface.d.ts.map +1 -1
- package/lib/typescript/module/src/surfaces/bannerWebView/BannerWebViewBar.d.ts.map +1 -1
- package/lib/typescript/module/src/surfaces/bannerWebView/bannerNeedsWebView.d.ts +3 -12
- package/lib/typescript/module/src/surfaces/bannerWebView/bannerNeedsWebView.d.ts.map +1 -1
- package/lib/typescript/module/src/surfaces/bannerWebView/bannerThemeStyles.d.ts.map +1 -1
- package/lib/typescript/module/src/surfaces/bannerWebView/bannerWebViewHeight.d.ts +13 -0
- package/lib/typescript/module/src/surfaces/bannerWebView/bannerWebViewHeight.d.ts.map +1 -0
- package/lib/typescript/module/src/surfaces/bannerWebView/buildCustomBannerHtml.d.ts.map +1 -1
- package/lib/typescript/module/src/surfaces/tooltip/targetOrigin.d.ts +26 -0
- package/lib/typescript/module/src/surfaces/tooltip/targetOrigin.d.ts.map +1 -0
- package/lib/typescript/module/src/version.d.ts +1 -1
- package/package.json +5 -4
- package/src/anchors/AnchorRegistry.ts +8 -0
- package/src/anchors/ScrollContainerRegistry.ts +15 -3
- package/src/anchors/fiber/FiberScanRootStore.ts +8 -0
- package/src/anchors/fiber/detectAppFontFamily.ts +400 -0
- package/src/anchors/fiber/presentedModal.ts +203 -0
- package/src/anchors/fiber/touchTargetFiber.ts +2 -1
- package/src/anchors/fiber/visibleRect.ts +12 -3
- package/src/anchors/fiber/visibleScreens.ts +5 -0
- package/src/anchors/useUserflowAnchor.ts +4 -5
- package/src/anchors/useUserflowScrollContainer.ts +5 -4
- package/src/authoring/ElementPickerOverlay.tsx +242 -166
- package/src/authoring/hitTest.ts +88 -13
- package/src/authoring/hostAtPoint.ts +67 -21
- package/src/content/BannerStepButton.tsx +2 -1
- package/src/content/RichContentRenderer.tsx +16 -9
- package/src/content/StepButton.tsx +2 -1
- package/src/content/resolveContentFontFamily.ts +119 -0
- package/src/deepLinking.ts +2 -1
- package/src/deviceContext.ts +50 -14
- package/src/index.ts +13 -5
- package/src/installCheck.ts +3 -3
- package/src/lifecycle.ts +2 -1
- package/src/pairing/PairingController.ts +2 -1
- package/src/runtime/BannerHost.tsx +3 -3
- package/src/runtime/UserflowOverlay.tsx +29 -21
- package/src/runtime/WindowOverlayHost.tsx +95 -0
- package/src/runtime/pushBannerLayoutContext.tsx +14 -9
- package/src/runtime/userflowCore.ts +8 -2
- package/src/surfaces/BannerSurface.tsx +2 -6
- package/src/surfaces/ProgressBar.tsx +2 -1
- package/src/surfaces/TooltipSurface.tsx +118 -47
- package/src/surfaces/bannerWebView/BannerWebViewBar.tsx +6 -4
- package/src/surfaces/bannerWebView/bannerNeedsWebView.ts +4 -36
- package/src/surfaces/bannerWebView/bannerThemeStyles.ts +2 -1
- package/src/surfaces/bannerWebView/bannerWebViewHeight.ts +32 -0
- package/src/surfaces/bannerWebView/buildCustomBannerHtml.ts +48 -12
- package/src/surfaces/tooltip/TooltipHighlight.tsx +3 -5
- package/src/surfaces/tooltip/targetOrigin.ts +74 -0
- package/src/version.ts +1 -1
- package/vendor/core/dist/engine/UserflowCore.d.ts +7 -0
- package/vendor/core/dist/engine/UserflowCore.d.ts.map +1 -1
- package/vendor/core/dist/engine/UserflowCore.js +3 -2
- package/vendor/core/dist/engine/UserflowCore.js.map +1 -1
- package/vendor/core/dist/transport/phoenix.d.ts +12 -2
- package/vendor/core/dist/transport/phoenix.d.ts.map +1 -1
- package/vendor/core/dist/transport/phoenix.js +7 -6
- package/vendor/core/dist/transport/phoenix.js.map +1 -1
- package/vendor/core/dist/version.d.ts +1 -1
- package/vendor/core/dist/version.js +1 -1
- package/vendor/core/package.json +1 -1
- package/vendor/protocol/dist/flows.d.ts +2 -0
- package/vendor/protocol/dist/flows.d.ts.map +1 -1
- package/vendor/protocol/package.json +1 -1
package/src/deviceContext.ts
CHANGED
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Resolve mobile platform metadata for Userflow
|
|
2
|
+
* Resolve mobile platform metadata and the running SDK version for Userflow
|
|
3
|
+
* user attributes.
|
|
3
4
|
*
|
|
4
5
|
* Cached once during {@link Userflow.init} and merged into identify attributes
|
|
5
6
|
* (same lifecycle as {@link hostAppVersion.ts}).
|
|
6
7
|
*/
|
|
7
8
|
|
|
9
|
+
import { SDK_VERSION } from './version';
|
|
10
|
+
|
|
8
11
|
export type SdkPlatform = 'react_native';
|
|
9
12
|
export type DeviceOs = 'ios' | 'android';
|
|
10
13
|
export type DeviceType = 'phone' | 'tablet';
|
|
11
14
|
|
|
12
15
|
export interface DeviceContext {
|
|
13
16
|
sdk: SdkPlatform;
|
|
17
|
+
/**
|
|
18
|
+
* Published `@userflow-tech/react-native` version, e.g. `0.4.6`. Always set by
|
|
19
|
+
* the SDK; optional so context objects built by host code (mocks) stay valid.
|
|
20
|
+
*/
|
|
21
|
+
sdkVersion?: string;
|
|
14
22
|
deviceOs?: DeviceOs;
|
|
15
23
|
deviceType?: DeviceType;
|
|
16
24
|
}
|
|
@@ -19,6 +27,7 @@ export interface DeviceContext {
|
|
|
19
27
|
export const ANDROID_TABLET_SMALLEST_WIDTH_DP = 600;
|
|
20
28
|
|
|
21
29
|
export const SDK_USER_ATTRIBUTE = 'sdk';
|
|
30
|
+
export const SDK_VERSION_USER_ATTRIBUTE = 'sdk_version';
|
|
22
31
|
export const DEVICE_OS_USER_ATTRIBUTE = 'device_os';
|
|
23
32
|
export const DEVICE_TYPE_USER_ATTRIBUTE = 'device_type';
|
|
24
33
|
|
|
@@ -70,6 +79,7 @@ export function resolveDeviceContextFromSources(sources: {
|
|
|
70
79
|
const deviceType = resolveDeviceTypeFromSources(sources);
|
|
71
80
|
return {
|
|
72
81
|
sdk: 'react_native',
|
|
82
|
+
sdkVersion: SDK_VERSION,
|
|
73
83
|
...(deviceOs ? { deviceOs } : {}),
|
|
74
84
|
...(deviceType ? { deviceType } : {}),
|
|
75
85
|
};
|
|
@@ -103,6 +113,7 @@ export function resolveDeviceContext(): DeviceContext {
|
|
|
103
113
|
|
|
104
114
|
/** `undefined` until the first {@link cacheDeviceContextAtInit}; then resolved. */
|
|
105
115
|
let cachedDeviceContext: DeviceContext | undefined;
|
|
116
|
+
let didWarnSdkVersionOverride = false;
|
|
106
117
|
|
|
107
118
|
/**
|
|
108
119
|
* Resolve and cache device metadata during {@link Userflow.init}.
|
|
@@ -118,33 +129,57 @@ export function getCachedDeviceContext(): DeviceContext | null {
|
|
|
118
129
|
return cachedDeviceContext ?? null;
|
|
119
130
|
}
|
|
120
131
|
|
|
121
|
-
/**
|
|
122
|
-
|
|
123
|
-
const cached = getCachedDeviceContext();
|
|
124
|
-
if (!cached) return {};
|
|
132
|
+
/** Device fields for UpsertUser that identify attributes may override. */
|
|
133
|
+
function overridableDeviceAttributes(context: DeviceContext): Record<string, string> {
|
|
125
134
|
return {
|
|
126
|
-
[SDK_USER_ATTRIBUTE]:
|
|
127
|
-
...(
|
|
128
|
-
...(
|
|
135
|
+
[SDK_USER_ATTRIBUTE]: context.sdk,
|
|
136
|
+
...(context.deviceOs ? { [DEVICE_OS_USER_ATTRIBUTE]: context.deviceOs } : {}),
|
|
137
|
+
...(context.deviceType ? { [DEVICE_TYPE_USER_ATTRIBUTE]: context.deviceType } : {}),
|
|
129
138
|
};
|
|
130
139
|
}
|
|
131
140
|
|
|
132
141
|
/** Optional user-attribute keys added by {@link mergeDeviceContextUserAttributes}. */
|
|
133
142
|
export type DeviceContextUserAttributeMap = Partial<{
|
|
134
143
|
[SDK_USER_ATTRIBUTE]: SdkPlatform;
|
|
144
|
+
[SDK_VERSION_USER_ATTRIBUTE]: string;
|
|
135
145
|
[DEVICE_OS_USER_ATTRIBUTE]: DeviceOs;
|
|
136
146
|
[DEVICE_TYPE_USER_ATTRIBUTE]: DeviceType;
|
|
137
147
|
}>;
|
|
138
148
|
|
|
139
|
-
/**
|
|
149
|
+
/** One development warning when identify attributes try to set `sdk_version`. */
|
|
150
|
+
function warnIfSdkVersionOverridden(attributes: Record<string, unknown> | undefined): void {
|
|
151
|
+
if (!__DEV__ || didWarnSdkVersionOverride) return;
|
|
152
|
+
const passed = attributes?.[SDK_VERSION_USER_ATTRIBUTE];
|
|
153
|
+
// `{ set: value }` is the long form of a bare literal.
|
|
154
|
+
const value =
|
|
155
|
+
typeof passed === 'object' && passed !== null && 'set' in passed
|
|
156
|
+
? (passed as { set: unknown }).set
|
|
157
|
+
: passed;
|
|
158
|
+
if (value === undefined || value === SDK_VERSION) return;
|
|
159
|
+
didWarnSdkVersionOverride = true;
|
|
160
|
+
// eslint-disable-next-line no-console -- intentional development diagnostic
|
|
161
|
+
console.warn(
|
|
162
|
+
`[Userflow] "${SDK_VERSION_USER_ATTRIBUTE}" is set by the SDK (${SDK_VERSION}); the value passed to identify / identifyAnonymous was ignored.`,
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Merges cached device attrs into identify attributes. Caller values win on key
|
|
168
|
+
* conflicts, except `sdk_version`, which always reports the running SDK.
|
|
169
|
+
*/
|
|
140
170
|
export function mergeDeviceContextUserAttributes<T extends Record<string, unknown>>(
|
|
141
171
|
attributes?: T,
|
|
142
172
|
): (T & DeviceContextUserAttributeMap) | undefined {
|
|
143
|
-
const
|
|
144
|
-
if (
|
|
173
|
+
const cached = getCachedDeviceContext();
|
|
174
|
+
if (!cached) {
|
|
145
175
|
return attributes as (T & DeviceContextUserAttributeMap) | undefined;
|
|
146
176
|
}
|
|
147
|
-
|
|
177
|
+
warnIfSdkVersionOverridden(attributes);
|
|
178
|
+
return {
|
|
179
|
+
...overridableDeviceAttributes(cached),
|
|
180
|
+
...(attributes ?? {}),
|
|
181
|
+
[SDK_VERSION_USER_ATTRIBUTE]: SDK_VERSION,
|
|
182
|
+
} as T & DeviceContextUserAttributeMap;
|
|
148
183
|
}
|
|
149
184
|
|
|
150
185
|
export function formatDeviceContextLog(resolved: DeviceContext | null): string {
|
|
@@ -153,7 +188,7 @@ export function formatDeviceContextLog(resolved: DeviceContext | null): string {
|
|
|
153
188
|
}
|
|
154
189
|
const os = resolved.deviceOs ?? 'unknown';
|
|
155
190
|
const type = resolved.deviceType ?? 'unknown';
|
|
156
|
-
return `[Userflow] device context sdk=${resolved.sdk} device_os=${os} device_type=${type}`;
|
|
191
|
+
return `[Userflow] device context sdk=${resolved.sdk} sdk_version=${resolved.sdkVersion ?? 'unknown'} device_os=${os} device_type=${type}`;
|
|
157
192
|
}
|
|
158
193
|
|
|
159
194
|
/** Log cached user-attribute values. Requires {@link cacheDeviceContextAtInit}. */
|
|
@@ -162,7 +197,8 @@ export function logDeviceContext(): void {
|
|
|
162
197
|
console.log(formatDeviceContextLog(getCachedDeviceContext()));
|
|
163
198
|
}
|
|
164
199
|
|
|
165
|
-
/** @internal Resets init cache between tests. */
|
|
200
|
+
/** @internal Resets init cache and the one-time override warning between tests. */
|
|
166
201
|
export function resetCachedDeviceContextForTests(): void {
|
|
167
202
|
cachedDeviceContext = undefined;
|
|
203
|
+
didWarnSdkVersionOverride = false;
|
|
168
204
|
}
|
package/src/index.ts
CHANGED
|
@@ -22,6 +22,7 @@ import type {
|
|
|
22
22
|
|
|
23
23
|
import './anchors/autoAnchor';
|
|
24
24
|
import { anchorChangeTicker } from './anchors/anchorChangeTicker';
|
|
25
|
+
import { resetDetectedAppFont } from './anchors/fiber/detectAppFontFamily';
|
|
25
26
|
import { notifyAnchorScreenChange } from './anchors/resolveAnchorHost';
|
|
26
27
|
import {
|
|
27
28
|
setCustomScrollIntoView as setCustomScrollIntoViewConfig,
|
|
@@ -367,7 +368,10 @@ export const Userflow = {
|
|
|
367
368
|
setOnNavigate(handler: FlowNavigateHandler | null | undefined): void {
|
|
368
369
|
setHostOnNavigate(handler);
|
|
369
370
|
},
|
|
370
|
-
/**
|
|
371
|
+
/**
|
|
372
|
+
* Identify the current user and upsert their attributes. The SDK adds `sdk_version`
|
|
373
|
+
* itself; a value passed for it here is ignored.
|
|
374
|
+
*/
|
|
371
375
|
async identify(
|
|
372
376
|
userId: string,
|
|
373
377
|
attributes?: UserflowAttributes,
|
|
@@ -390,7 +394,10 @@ export const Userflow = {
|
|
|
390
394
|
await core.identify(userId, mergeSystemUserAttributes(attributes), options);
|
|
391
395
|
await afterIdentify();
|
|
392
396
|
},
|
|
393
|
-
/**
|
|
397
|
+
/**
|
|
398
|
+
* Identify an anonymous user with a stable auto-generated id stored on device. Like
|
|
399
|
+
* {@link identify}, the SDK sets `sdk_version` itself.
|
|
400
|
+
*/
|
|
394
401
|
async identifyAnonymous(
|
|
395
402
|
attributes?: UserflowAttributes,
|
|
396
403
|
options?: UserflowIdentifyOptions,
|
|
@@ -477,8 +484,8 @@ export const Userflow = {
|
|
|
477
484
|
return getCachedHostAppVersion();
|
|
478
485
|
},
|
|
479
486
|
/**
|
|
480
|
-
* Platform metadata cached during {@link init} (`sdk`, `
|
|
481
|
-
* or `null` before init.
|
|
487
|
+
* Platform metadata cached during {@link init} (`sdk`, `sdkVersion`, `deviceOs`,
|
|
488
|
+
* `deviceType`), or `null` before init.
|
|
482
489
|
*/
|
|
483
490
|
getDeviceContext(): DeviceContext | null {
|
|
484
491
|
return getCachedDeviceContext();
|
|
@@ -493,6 +500,7 @@ export const Userflow = {
|
|
|
493
500
|
},
|
|
494
501
|
/** Clears the current user identity and disconnects from Userflow. */
|
|
495
502
|
async reset(): Promise<void> {
|
|
503
|
+
resetDetectedAppFont();
|
|
496
504
|
resetClientConditionEngine();
|
|
497
505
|
resetFlowSessionEngine();
|
|
498
506
|
resetBannerSessionEngine();
|
|
@@ -574,7 +582,7 @@ export const Userflow = {
|
|
|
574
582
|
logHostAppVersionToConsole();
|
|
575
583
|
},
|
|
576
584
|
/**
|
|
577
|
-
* Log cached user-attribute values (`sdk`, `device_os`, `device_type`).
|
|
585
|
+
* Log cached user-attribute values (`sdk`, `sdk_version`, `device_os`, `device_type`).
|
|
578
586
|
* Requires {@link init}; before init, logs that init is required.
|
|
579
587
|
*/
|
|
580
588
|
logDeviceContext(): void {
|
package/src/installCheck.ts
CHANGED
|
@@ -10,7 +10,7 @@ export const INSTALL_ASYNC_STORAGE_LINE =
|
|
|
10
10
|
'- @react-native-async-storage/async-storage is not linked. Anonymous users and Builder pairing will not persist. Add it to the app package.json (npx expo install @react-native-async-storage/async-storage), run pod install on iOS, and rebuild.';
|
|
11
11
|
|
|
12
12
|
export const INSTALL_VIEW_SHOT_LINE =
|
|
13
|
-
'- react-native-view-shot is not linked, so Builder element selection gets no screenshot. Install it and rebuild. On Expo SDK 56
|
|
13
|
+
'- react-native-view-shot is not linked, so Builder element selection gets no screenshot. Install it and rebuild. On Expo SDK 56 to 58, run npx expo install react-native-view-shot unpinned, with no expo.install.exclude entry for it. Otherwise install react-native-view-shot@^5.0.0; on Expo SDK 55 and older, an unpinned npx expo install resolves 4.0.3.';
|
|
14
14
|
|
|
15
15
|
export const INSTALL_WEBVIEW_LINE =
|
|
16
16
|
'- react-native-webview is not linked. Evaluate JavaScript and WebView banners will not run. Install it (npx expo install react-native-webview) and rebuild.';
|
|
@@ -36,7 +36,7 @@ export const INSTALL_SAFE_AREA_WARNING =
|
|
|
36
36
|
export function formatViewShotVersionWarning(version: string): string {
|
|
37
37
|
return (
|
|
38
38
|
`[Userflow] react-native-view-shot@${version} is older than 5.0.0, so Builder element selection may not get a screenshot. ` +
|
|
39
|
-
'On Expo SDK 56
|
|
39
|
+
'On Expo SDK 56 to 58, run npx expo install react-native-view-shot unpinned, with no expo.install.exclude entry for it, and rebuild. ' +
|
|
40
40
|
'Otherwise install react-native-view-shot@^5.0.0 in the same command as the SDK and rebuild; on Expo SDK 55 and older, also add "react-native-view-shot" to expo.install.exclude. ' +
|
|
41
41
|
'Do not retry the install with --force or --legacy-peer-deps; that leaves this version in place.\n' +
|
|
42
42
|
INSTALL_CHECK_FOOTER
|
|
@@ -89,7 +89,7 @@ function readViewShotVersion(): string | null {
|
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
/** Dev warning when view-shot 4.x is installed. Null on 5.x or when it is absent. */
|
|
92
|
+
/** Dev warning when view-shot 4.x is installed. Null on 5.x and later, or when it is absent. */
|
|
93
93
|
export function viewShotVersionWarning(): string | null {
|
|
94
94
|
const version = readViewShotVersion();
|
|
95
95
|
if (!version) return null;
|
package/src/lifecycle.ts
CHANGED
|
@@ -94,7 +94,8 @@ export class LifecycleController {
|
|
|
94
94
|
private readonly scheduler: LifecycleScheduler;
|
|
95
95
|
private readonly now: () => number;
|
|
96
96
|
private readonly suspendGraceMs: number;
|
|
97
|
-
|
|
97
|
+
/** Wider than AppStateStatus: React Native 0.88 types currentState as `string | null | undefined`. */
|
|
98
|
+
private readonly getCurrentAppState: () => string | null | undefined;
|
|
98
99
|
private readonly subscribeAppState: (handler: (status: AppStateStatus) => void) => () => void;
|
|
99
100
|
|
|
100
101
|
private unsubscribeAppState: (() => void) | null = null;
|
|
@@ -59,7 +59,8 @@ export interface PairingControllerOptions {
|
|
|
59
59
|
*/
|
|
60
60
|
cancelPendingDraftEnd?: () => void;
|
|
61
61
|
LinkingModule?: {
|
|
62
|
-
|
|
62
|
+
// React Native 0.88 adds undefined to the result.
|
|
63
|
+
getInitialURL(): Promise<string | null | undefined>;
|
|
63
64
|
addEventListener(type: 'url', handler: (event: { url: string }) => void): { remove(): void };
|
|
64
65
|
};
|
|
65
66
|
AppStateModule?: {
|
|
@@ -49,15 +49,15 @@ export function BannerHost({
|
|
|
49
49
|
if (edgeFilter && edge !== edgeFilter) return null;
|
|
50
50
|
|
|
51
51
|
const floats = banner.overlay !== false;
|
|
52
|
-
const usesWebView = bannerNeedsWebView(banner
|
|
53
|
-
// Custom
|
|
52
|
+
const usesWebView = bannerNeedsWebView(banner);
|
|
53
|
+
// Custom banner WebViews paint in the overlay host (same as userflow.js). A second
|
|
54
54
|
// WKWebView in the flow slot often fails to load after the first banner dismisses.
|
|
55
55
|
const hostAsOverlay = floats || usesWebView;
|
|
56
56
|
if ((placement === 'overlay') !== hostAsOverlay) return null;
|
|
57
57
|
|
|
58
58
|
const pushLayoutEdge = placement === 'flow' && !hostAsOverlay ? edge : null;
|
|
59
59
|
// Builder overlay:true floats below the status bar. Push-layout WebViews in the overlay
|
|
60
|
-
// host still paint safe-area chrome (overlay:false + custom
|
|
60
|
+
// host still paint safe-area chrome (overlay:false + custom banner).
|
|
61
61
|
const overlaySafeEdge = hostAsOverlay && !floats ? edge : null;
|
|
62
62
|
|
|
63
63
|
const surface = (
|
|
@@ -12,6 +12,7 @@ import { stepTrapsHostAccessibility } from '../surfaces/hostAccessibilityTrap';
|
|
|
12
12
|
|
|
13
13
|
import { BannerHost } from './BannerHost';
|
|
14
14
|
import { FlowRenderer } from './FlowRenderer';
|
|
15
|
+
import { WindowOverlayHost } from './WindowOverlayHost';
|
|
15
16
|
import { useFlowSessionState } from './useFlowSessionState';
|
|
16
17
|
import { getUserflowCore } from './userflowCore';
|
|
17
18
|
|
|
@@ -86,30 +87,37 @@ export function UserflowOverlay({
|
|
|
86
87
|
* destroy a running script. `suppressed` hides it for the pick.
|
|
87
88
|
*/}
|
|
88
89
|
<EvalJsHost suppressed={pickerActive} />
|
|
89
|
-
<PreviewModeBanner
|
|
90
|
-
onConfirmingChange={setPreviewConfirming}
|
|
91
|
-
onExit={onExitPreview}
|
|
92
|
-
held={previewHeld}
|
|
93
|
-
onRestart={onRestartPreview}
|
|
94
|
-
state={pairingState}
|
|
95
|
-
suppressed={pickerActive}
|
|
96
|
-
/>
|
|
97
90
|
{/*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
91
|
+
* One host for all three, so they keep this paint order above native
|
|
92
|
+
* modal screens. The host app's trap does not reach a natively presented
|
|
93
|
+
* modal, so the host traps VoiceOver itself.
|
|
101
94
|
*/}
|
|
102
|
-
{
|
|
103
|
-
<
|
|
104
|
-
|
|
105
|
-
|
|
95
|
+
<WindowOverlayHost accessibilityModal={trapHostAccessibility}>
|
|
96
|
+
<PreviewModeBanner
|
|
97
|
+
onConfirmingChange={setPreviewConfirming}
|
|
98
|
+
onExit={onExitPreview}
|
|
99
|
+
held={previewHeld}
|
|
100
|
+
onRestart={onRestartPreview}
|
|
101
|
+
state={pairingState}
|
|
102
|
+
suppressed={pickerActive}
|
|
106
103
|
/>
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
104
|
+
{/*
|
|
105
|
+
* Unmount flow chrome for the whole pick. The session stays alive;
|
|
106
|
+
* captureScreen would otherwise include the modal or tooltip.
|
|
107
|
+
* Remounting reads the same session back.
|
|
108
|
+
*/}
|
|
109
|
+
{pickerActive ? null : (
|
|
110
|
+
<FlowRenderer
|
|
111
|
+
engine={engine}
|
|
112
|
+
previewRestartGeneration={pairingState.previewRestartGeneration}
|
|
113
|
+
/>
|
|
114
|
+
)}
|
|
115
|
+
{/*
|
|
116
|
+
* After flow chrome so BODY_FIRST / BODY_LAST overlay banners stay visible
|
|
117
|
+
* while a tour step (modal, tooltip, condition wait) is still active.
|
|
118
|
+
*/}
|
|
119
|
+
<BannerHost engine={bannerEngine} hidden={pickerActive} />
|
|
120
|
+
</WindowOverlayHost>
|
|
113
121
|
<ElementPickerOverlay />
|
|
114
122
|
</>
|
|
115
123
|
);
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Platform } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import { isNativeModuleLinked } from '../nativeModules';
|
|
5
|
+
|
|
6
|
+
interface FullWindowOverlayProps {
|
|
7
|
+
children?: React.ReactNode;
|
|
8
|
+
/** react-native-screens 4.x. Defaults to true, which traps VoiceOver inside the overlay. */
|
|
9
|
+
unstable_accessibilityContainerViewIsModal?: boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
type FullWindowOverlayComponent = React.ComponentType<FullWindowOverlayProps>;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Native module in every react-native-screens 3.x and 4.x build. Rendering
|
|
16
|
+
* `FullWindowOverlay` without the native half would mount an unregistered
|
|
17
|
+
* component, so the package is not required until this is linked.
|
|
18
|
+
*/
|
|
19
|
+
const SCREENS_NATIVE_MODULE = 'RNSModule';
|
|
20
|
+
|
|
21
|
+
let cached: FullWindowOverlayComponent | null | undefined;
|
|
22
|
+
|
|
23
|
+
/** react-native-screens' `FullWindowOverlay`, or null when it cannot host chrome here. */
|
|
24
|
+
function getFullWindowOverlay(): FullWindowOverlayComponent | null {
|
|
25
|
+
if (cached !== undefined) return cached;
|
|
26
|
+
cached = null;
|
|
27
|
+
|
|
28
|
+
// FullWindowOverlay is iOS-only; elsewhere it renders a plain View.
|
|
29
|
+
if (Platform.OS !== 'ios' || typeof require !== 'function') return cached;
|
|
30
|
+
if (!isNativeModuleLinked(SCREENS_NATIVE_MODULE)) return cached;
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
// Not a peer: apps that present native modals already have it, through
|
|
34
|
+
// Expo Router or React Navigation's native stack.
|
|
35
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires -- optional package probe
|
|
36
|
+
const mod = require('react-native-screens') as {
|
|
37
|
+
FullWindowOverlay?: FullWindowOverlayComponent;
|
|
38
|
+
};
|
|
39
|
+
cached = mod?.FullWindowOverlay ?? null;
|
|
40
|
+
} catch {
|
|
41
|
+
cached = null;
|
|
42
|
+
}
|
|
43
|
+
return cached;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface WindowOverlayHostProps {
|
|
47
|
+
children: React.ReactNode;
|
|
48
|
+
/**
|
|
49
|
+
* Hide everything outside the host from VoiceOver, natively presented
|
|
50
|
+
* modals included. Defaults to false.
|
|
51
|
+
*/
|
|
52
|
+
accessibilityModal?: boolean;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** True when {@link WindowOverlayHost} draws above natively presented modals. */
|
|
56
|
+
export function hasWindowOverlayHost(): boolean {
|
|
57
|
+
return getFullWindowOverlay() != null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Hosts SDK chrome above everything else in the app window.
|
|
62
|
+
*
|
|
63
|
+
* On iOS, react-native-screens presents `modal`, `transparentModal`,
|
|
64
|
+
* `formSheet` and `fullScreenModal` screens, and React Native presents
|
|
65
|
+
* `<Modal>`, as view controllers above the React Native root view, so chrome
|
|
66
|
+
* rendered in `UserflowProvider`'s overlay is drawn beneath them and never
|
|
67
|
+
* receives touches there. `FullWindowOverlay` moves its children into a
|
|
68
|
+
* container on the window itself. Measured on iOS 17.4 and 26.5 with
|
|
69
|
+
* react-native-screens 4.16, that container stays above sheets whether they are
|
|
70
|
+
* presented before or after it mounts.
|
|
71
|
+
*
|
|
72
|
+
* Each host is its own container, stacked by when it was attached rather than
|
|
73
|
+
* by React order, so chrome that has to keep a paint order shares one host.
|
|
74
|
+
*
|
|
75
|
+
* Touches inside the host arrive in window coordinates, as they do in the root
|
|
76
|
+
* view. Children render in place when the overlay is unavailable: on Android,
|
|
77
|
+
* and in apps without react-native-screens.
|
|
78
|
+
*/
|
|
79
|
+
export function WindowOverlayHost({
|
|
80
|
+
children,
|
|
81
|
+
accessibilityModal = false,
|
|
82
|
+
}: WindowOverlayHostProps): React.ReactElement {
|
|
83
|
+
const FullWindowOverlay = getFullWindowOverlay();
|
|
84
|
+
if (!FullWindowOverlay) return <>{children}</>;
|
|
85
|
+
return (
|
|
86
|
+
<FullWindowOverlay unstable_accessibilityContainerViewIsModal={accessibilityModal}>
|
|
87
|
+
{children}
|
|
88
|
+
</FullWindowOverlay>
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** @internal Clears the cached `FullWindowOverlay` lookup between tests. */
|
|
93
|
+
export function resetWindowOverlayHostForTests(): void {
|
|
94
|
+
cached = undefined;
|
|
95
|
+
}
|
|
@@ -92,6 +92,11 @@ export function usePushBannerLayoutRegistration(
|
|
|
92
92
|
* Clears the host top/bottom safe-area override only after push-layout chrome
|
|
93
93
|
* has laid out, so a session without visible chrome cannot leave a white strip.
|
|
94
94
|
*
|
|
95
|
+
* Remembers which edge laid out instead of resetting a flag in an effect: on
|
|
96
|
+
* Fabric the chrome's first onLayout can run before the mount's passive effects
|
|
97
|
+
* flush, and a reset there would discard it until the banner happened to
|
|
98
|
+
* re-layout, leaving already-mounted host screens on the old inset.
|
|
99
|
+
*
|
|
95
100
|
* @internal
|
|
96
101
|
*/
|
|
97
102
|
export function usePushBannerHostInsetRegistration(
|
|
@@ -99,23 +104,23 @@ export function usePushBannerHostInsetRegistration(
|
|
|
99
104
|
sessionId: string,
|
|
100
105
|
enabled: boolean,
|
|
101
106
|
): (event: LayoutChangeEvent) => void {
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
React.useEffect(() => {
|
|
105
|
-
setLaidOut(false);
|
|
106
|
-
}, [edge, enabled]);
|
|
107
|
+
const activeEdge = enabled && edge ? edge : null;
|
|
108
|
+
const [laidOutEdge, setLaidOutEdge] = React.useState<PushBannerLayoutEdge | null>(null);
|
|
107
109
|
|
|
108
|
-
usePushBannerLayoutRegistration(
|
|
110
|
+
usePushBannerLayoutRegistration(
|
|
111
|
+
activeEdge && laidOutEdge === activeEdge ? activeEdge : null,
|
|
112
|
+
sessionId,
|
|
113
|
+
);
|
|
109
114
|
|
|
110
115
|
return React.useCallback(
|
|
111
116
|
(event: LayoutChangeEvent) => {
|
|
112
|
-
if (!
|
|
117
|
+
if (!activeEdge) {
|
|
113
118
|
return;
|
|
114
119
|
}
|
|
115
120
|
if (event.nativeEvent.layout.height > 0) {
|
|
116
|
-
|
|
121
|
+
setLaidOutEdge(activeEdge);
|
|
117
122
|
}
|
|
118
123
|
},
|
|
119
|
-
[
|
|
124
|
+
[activeEdge],
|
|
120
125
|
);
|
|
121
126
|
}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { UserflowCore } from '@userflow-tech/core';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
import { SDK_VERSION } from '../version';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Shared {@link UserflowCore} singleton for the RN package facade + provider.
|
|
7
|
+
* Joins report the published SDK version (not the internal core version) as
|
|
8
|
+
* `userflowClientBuild`.
|
|
9
|
+
*/
|
|
10
|
+
const core = new UserflowCore({ clientBuild: `react-native-${SDK_VERSION}` });
|
|
5
11
|
|
|
6
12
|
export function getUserflowCore(): UserflowCore {
|
|
7
13
|
return core;
|
|
@@ -25,10 +25,7 @@ export interface BannerSurfaceProps {
|
|
|
25
25
|
|
|
26
26
|
let warnedMissingWebView = false;
|
|
27
27
|
|
|
28
|
-
/**
|
|
29
|
-
* Native banner bar, or a WebView when a button runs Evaluate JavaScript or the
|
|
30
|
-
* theme has published custom CSS (same CDN stylesheet as userflow.js iframes).
|
|
31
|
-
*/
|
|
28
|
+
/** Native banner bar, or a WebView when `customBannerEnabled` is set on the banner. */
|
|
32
29
|
export function BannerSurface({
|
|
33
30
|
session,
|
|
34
31
|
pushLayoutEdge = null,
|
|
@@ -37,8 +34,7 @@ export function BannerSurface({
|
|
|
37
34
|
onDismiss,
|
|
38
35
|
}: BannerSurfaceProps): React.ReactElement | null {
|
|
39
36
|
const banner = session.version.banner;
|
|
40
|
-
const
|
|
41
|
-
const needsWebView = banner != null && bannerNeedsWebView(banner, theme);
|
|
37
|
+
const needsWebView = banner != null && bannerNeedsWebView(banner);
|
|
42
38
|
const webView = needsWebView ? getEvalJsWebView() : null;
|
|
43
39
|
|
|
44
40
|
React.useEffect(() => {
|
|
@@ -2,6 +2,7 @@ import type { ThemeFragment } from '@userflow-tech/protocol';
|
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { StyleSheet, Text, View } from 'react-native';
|
|
4
4
|
|
|
5
|
+
import { resolveContentFontFamily } from '../content/resolveContentFontFamily';
|
|
5
6
|
import { foregroundAlpha } from '../content/themeColor';
|
|
6
7
|
|
|
7
8
|
export type ProgressBarPlacement = 'TOP' | 'BOTTOM';
|
|
@@ -72,7 +73,7 @@ export function ProgressBar({
|
|
|
72
73
|
styles.numberedLabel,
|
|
73
74
|
{
|
|
74
75
|
color: foregroundAlpha(theme.fontColor, 0.55),
|
|
75
|
-
fontFamily: theme
|
|
76
|
+
fontFamily: resolveContentFontFamily(theme),
|
|
76
77
|
fontSize: Math.max(12, Math.round(theme.fontSize * 0.875)),
|
|
77
78
|
},
|
|
78
79
|
]}
|