@userflow-tech/react-native 0.4.5 → 0.6.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 +31 -2
- package/docs/anchoring.md +6 -1
- package/docs/custom-fonts.md +36 -0
- package/docs/troubleshooting.md +33 -6
- package/lib/commonjs/anchors/AutoAnchorRegistry.js +144 -34
- package/lib/commonjs/anchors/AutoAnchorRegistry.js.map +1 -1
- package/lib/commonjs/anchors/animationFrame.js +29 -1
- package/lib/commonjs/anchors/animationFrame.js.map +1 -1
- package/lib/commonjs/anchors/appActive.js +61 -0
- package/lib/commonjs/anchors/appActive.js.map +1 -0
- package/lib/commonjs/anchors/elementConditionEvaluator.js +25 -8
- package/lib/commonjs/anchors/elementConditionEvaluator.js.map +1 -1
- package/lib/commonjs/anchors/elementTapMonitor.js +67 -12
- package/lib/commonjs/anchors/elementTapMonitor.js.map +1 -1
- package/lib/commonjs/anchors/elementTargetMatch.js +33 -7
- package/lib/commonjs/anchors/elementTargetMatch.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/fiberInternals.js +66 -0
- package/lib/commonjs/anchors/fiber/fiberInternals.js.map +1 -1
- package/lib/commonjs/anchors/fiber/indexHostFibers.js +4 -3
- package/lib/commonjs/anchors/fiber/indexHostFibers.js.map +1 -1
- package/lib/commonjs/anchors/fiber/resolveFiberPath.js +30 -15
- package/lib/commonjs/anchors/fiber/resolveFiberPath.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/fiberAnchorCache.js +20 -0
- package/lib/commonjs/anchors/fiberAnchorCache.js.map +1 -1
- package/lib/commonjs/anchors/gestureHandlerHandoff.js +304 -0
- package/lib/commonjs/anchors/gestureHandlerHandoff.js.map +1 -0
- package/lib/commonjs/anchors/resolveAnchorHost.js +6 -0
- package/lib/commonjs/anchors/resolveAnchorHost.js.map +1 -1
- package/lib/commonjs/anchors/resolveAutoAnchorHost.js +11 -6
- package/lib/commonjs/anchors/resolveAutoAnchorHost.js.map +1 -1
- package/lib/commonjs/anchors/resolveElementTargets.js +63 -8
- package/lib/commonjs/anchors/resolveElementTargets.js.map +1 -1
- package/lib/commonjs/anchors/semanticMatcher.js +43 -21
- package/lib/commonjs/anchors/semanticMatcher.js.map +1 -1
- package/lib/commonjs/anchors/tapSlop.js +16 -0
- package/lib/commonjs/anchors/tapSlop.js.map +1 -0
- package/lib/commonjs/anchors/targetPressMonitor.js +66 -12
- package/lib/commonjs/anchors/targetPressMonitor.js.map +1 -1
- package/lib/commonjs/authoring/fingerprintFromInstance.js +5 -9
- package/lib/commonjs/authoring/fingerprintFromInstance.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 +20 -14
- 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/openSafeUrl.js +3 -1
- package/lib/commonjs/content/openSafeUrl.js.map +1 -1
- package/lib/commonjs/content/resolveContentFontFamily.js +96 -0
- package/lib/commonjs/content/resolveContentFontFamily.js.map +1 -0
- package/lib/commonjs/expo-router/useUserflowExpoRouter.js +6 -0
- package/lib/commonjs/expo-router/useUserflowExpoRouter.js.map +1 -1
- package/lib/commonjs/index.js +21 -5
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/navigation/navigateUrlUtils.js +105 -0
- package/lib/commonjs/navigation/navigateUrlUtils.js.map +1 -0
- package/lib/commonjs/navigation/openExternalNavigateUrl.js +14 -0
- package/lib/commonjs/navigation/openExternalNavigateUrl.js.map +1 -0
- package/lib/commonjs/navigation/openFlowNavigateUrl.js +47 -41
- package/lib/commonjs/navigation/openFlowNavigateUrl.js.map +1 -1
- package/lib/commonjs/pairing/PairingController.js +3 -1
- package/lib/commonjs/pairing/PairingController.js.map +1 -1
- package/lib/commonjs/runtime/BannerHost.js +38 -29
- package/lib/commonjs/runtime/BannerHost.js.map +1 -1
- package/lib/commonjs/runtime/TargetPressBridge.js +55 -7
- package/lib/commonjs/runtime/TargetPressBridge.js.map +1 -1
- package/lib/commonjs/runtime/UserflowOverlay.js +5 -11
- package/lib/commonjs/runtime/UserflowOverlay.js.map +1 -1
- package/lib/commonjs/runtime/UserflowProvider.js +66 -40
- package/lib/commonjs/runtime/UserflowProvider.js.map +1 -1
- package/lib/commonjs/runtime/bannerEngine.js +8 -2
- package/lib/commonjs/runtime/bannerEngine.js.map +1 -1
- package/lib/commonjs/runtime/bannerFlowSpacer.js +71 -0
- package/lib/commonjs/runtime/bannerFlowSpacer.js.map +1 -0
- package/lib/commonjs/runtime/flowEngine.js +11 -0
- package/lib/commonjs/runtime/flowEngine.js.map +1 -1
- package/lib/commonjs/runtime/previewStart.js +39 -0
- package/lib/commonjs/runtime/previewStart.js.map +1 -0
- package/lib/commonjs/runtime/pushBannerLayoutContext.js +101 -0
- package/lib/commonjs/runtime/pushBannerLayoutContext.js.map +1 -0
- package/lib/commonjs/screenTracker.js +12 -0
- package/lib/commonjs/screenTracker.js.map +1 -1
- package/lib/commonjs/surfaces/BannerBar.js +79 -61
- package/lib/commonjs/surfaces/BannerBar.js.map +1 -1
- package/lib/commonjs/surfaces/BannerSurface.js +28 -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 +48 -41
- package/lib/commonjs/surfaces/TooltipSurface.js.map +1 -1
- package/lib/commonjs/surfaces/bannerBarLayout.js +77 -10
- package/lib/commonjs/surfaces/bannerBarLayout.js.map +1 -1
- package/lib/commonjs/surfaces/bannerWebView/BannerWebViewBar.js +114 -63
- 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 +104 -23
- package/lib/commonjs/surfaces/bannerWebView/buildCustomBannerHtml.js.map +1 -1
- package/lib/commonjs/surfaces/hostAccessibilityTrap.js +28 -0
- package/lib/commonjs/surfaces/hostAccessibilityTrap.js.map +1 -0
- package/lib/commonjs/surfaces/resolveBannerTheme.js +6 -3
- package/lib/commonjs/surfaces/resolveBannerTheme.js.map +1 -1
- package/lib/commonjs/surfaces/tooltip/TooltipBubble.js +3 -2
- package/lib/commonjs/surfaces/tooltip/TooltipBubble.js.map +1 -1
- package/lib/commonjs/surfaces/tooltip/targetSearchSchedule.js +134 -0
- package/lib/commonjs/surfaces/tooltip/targetSearchSchedule.js.map +1 -0
- package/lib/commonjs/version.js +1 -1
- package/lib/module/anchors/AutoAnchorRegistry.js +145 -35
- package/lib/module/anchors/AutoAnchorRegistry.js.map +1 -1
- package/lib/module/anchors/animationFrame.js +29 -2
- package/lib/module/anchors/animationFrame.js.map +1 -1
- package/lib/module/anchors/appActive.js +57 -0
- package/lib/module/anchors/appActive.js.map +1 -0
- package/lib/module/anchors/elementConditionEvaluator.js +26 -9
- package/lib/module/anchors/elementConditionEvaluator.js.map +1 -1
- package/lib/module/anchors/elementTapMonitor.js +67 -12
- package/lib/module/anchors/elementTapMonitor.js.map +1 -1
- package/lib/module/anchors/elementTargetMatch.js +32 -7
- package/lib/module/anchors/elementTargetMatch.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/fiberInternals.js +65 -0
- package/lib/module/anchors/fiber/fiberInternals.js.map +1 -1
- package/lib/module/anchors/fiber/indexHostFibers.js +4 -3
- package/lib/module/anchors/fiber/indexHostFibers.js.map +1 -1
- package/lib/module/anchors/fiber/resolveFiberPath.js +30 -15
- package/lib/module/anchors/fiber/resolveFiberPath.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/fiberAnchorCache.js +19 -0
- package/lib/module/anchors/fiberAnchorCache.js.map +1 -1
- package/lib/module/anchors/gestureHandlerHandoff.js +298 -0
- package/lib/module/anchors/gestureHandlerHandoff.js.map +1 -0
- package/lib/module/anchors/resolveAnchorHost.js +1 -0
- package/lib/module/anchors/resolveAnchorHost.js.map +1 -1
- package/lib/module/anchors/resolveAutoAnchorHost.js +11 -6
- package/lib/module/anchors/resolveAutoAnchorHost.js.map +1 -1
- package/lib/module/anchors/resolveElementTargets.js +63 -8
- package/lib/module/anchors/resolveElementTargets.js.map +1 -1
- package/lib/module/anchors/semanticMatcher.js +43 -21
- package/lib/module/anchors/semanticMatcher.js.map +1 -1
- package/lib/module/anchors/tapSlop.js +11 -0
- package/lib/module/anchors/tapSlop.js.map +1 -0
- package/lib/module/anchors/targetPressMonitor.js +53 -8
- package/lib/module/anchors/targetPressMonitor.js.map +1 -1
- package/lib/module/authoring/fingerprintFromInstance.js +6 -10
- package/lib/module/authoring/fingerprintFromInstance.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 +20 -14
- 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/openSafeUrl.js +3 -1
- package/lib/module/content/openSafeUrl.js.map +1 -1
- package/lib/module/content/resolveContentFontFamily.js +89 -0
- package/lib/module/content/resolveContentFontFamily.js.map +1 -0
- package/lib/module/expo-router/useUserflowExpoRouter.js +7 -1
- package/lib/module/expo-router/useUserflowExpoRouter.js.map +1 -1
- package/lib/module/index.js +24 -7
- package/lib/module/index.js.map +1 -1
- package/lib/module/navigation/navigateUrlUtils.js +94 -0
- package/lib/module/navigation/navigateUrlUtils.js.map +1 -0
- package/lib/module/navigation/openExternalNavigateUrl.js +11 -0
- package/lib/module/navigation/openExternalNavigateUrl.js.map +1 -0
- package/lib/module/navigation/openFlowNavigateUrl.js +22 -36
- package/lib/module/navigation/openFlowNavigateUrl.js.map +1 -1
- package/lib/module/pairing/PairingController.js +3 -1
- package/lib/module/pairing/PairingController.js.map +1 -1
- package/lib/module/runtime/BannerHost.js +38 -29
- package/lib/module/runtime/BannerHost.js.map +1 -1
- package/lib/module/runtime/TargetPressBridge.js +56 -8
- package/lib/module/runtime/TargetPressBridge.js.map +1 -1
- package/lib/module/runtime/UserflowOverlay.js +5 -11
- package/lib/module/runtime/UserflowOverlay.js.map +1 -1
- package/lib/module/runtime/UserflowProvider.js +66 -40
- package/lib/module/runtime/UserflowProvider.js.map +1 -1
- package/lib/module/runtime/bannerEngine.js +7 -2
- package/lib/module/runtime/bannerEngine.js.map +1 -1
- package/lib/module/runtime/bannerFlowSpacer.js +65 -0
- package/lib/module/runtime/bannerFlowSpacer.js.map +1 -0
- package/lib/module/runtime/flowEngine.js +11 -0
- package/lib/module/runtime/flowEngine.js.map +1 -1
- package/lib/module/runtime/previewStart.js +35 -0
- package/lib/module/runtime/previewStart.js.map +1 -0
- package/lib/module/runtime/pushBannerLayoutContext.js +94 -0
- package/lib/module/runtime/pushBannerLayoutContext.js.map +1 -0
- package/lib/module/screenTracker.js +11 -0
- package/lib/module/screenTracker.js.map +1 -1
- package/lib/module/surfaces/BannerBar.js +80 -62
- package/lib/module/surfaces/BannerBar.js.map +1 -1
- package/lib/module/surfaces/BannerSurface.js +28 -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 +49 -42
- package/lib/module/surfaces/TooltipSurface.js.map +1 -1
- package/lib/module/surfaces/bannerBarLayout.js +72 -11
- package/lib/module/surfaces/bannerBarLayout.js.map +1 -1
- package/lib/module/surfaces/bannerWebView/BannerWebViewBar.js +115 -64
- 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 +104 -23
- package/lib/module/surfaces/bannerWebView/buildCustomBannerHtml.js.map +1 -1
- package/lib/module/surfaces/hostAccessibilityTrap.js +24 -0
- package/lib/module/surfaces/hostAccessibilityTrap.js.map +1 -0
- package/lib/module/surfaces/resolveBannerTheme.js +6 -3
- package/lib/module/surfaces/resolveBannerTheme.js.map +1 -1
- package/lib/module/surfaces/tooltip/TooltipBubble.js +3 -2
- package/lib/module/surfaces/tooltip/TooltipBubble.js.map +1 -1
- package/lib/module/surfaces/tooltip/targetSearchSchedule.js +128 -0
- package/lib/module/surfaces/tooltip/targetSearchSchedule.js.map +1 -0
- package/lib/module/version.js +1 -1
- package/lib/typescript/commonjs/src/anchors/AutoAnchorRegistry.d.ts +36 -2
- package/lib/typescript/commonjs/src/anchors/AutoAnchorRegistry.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/anchors/animationFrame.d.ts +0 -4
- package/lib/typescript/commonjs/src/anchors/animationFrame.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/anchors/appActive.d.ts +8 -0
- package/lib/typescript/commonjs/src/anchors/appActive.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/anchors/elementTapMonitor.d.ts +17 -0
- package/lib/typescript/commonjs/src/anchors/elementTapMonitor.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/anchors/elementTargetMatch.d.ts +7 -0
- package/lib/typescript/commonjs/src/anchors/elementTargetMatch.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/fiberInternals.d.ts +7 -0
- package/lib/typescript/commonjs/src/anchors/fiber/fiberInternals.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/anchors/fiber/indexHostFibers.d.ts +3 -2
- package/lib/typescript/commonjs/src/anchors/fiber/indexHostFibers.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/anchors/fiber/resolveFiberPath.d.ts +3 -0
- package/lib/typescript/commonjs/src/anchors/fiber/resolveFiberPath.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/fiberAnchorCache.d.ts +5 -0
- package/lib/typescript/commonjs/src/anchors/fiberAnchorCache.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/anchors/gestureHandlerHandoff.d.ts +70 -0
- package/lib/typescript/commonjs/src/anchors/gestureHandlerHandoff.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/anchors/resolveAnchorHost.d.ts +1 -0
- package/lib/typescript/commonjs/src/anchors/resolveAnchorHost.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/anchors/resolveAutoAnchorHost.d.ts +11 -4
- package/lib/typescript/commonjs/src/anchors/resolveAutoAnchorHost.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/anchors/resolveElementTargets.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/anchors/semanticMatcher.d.ts +2 -0
- package/lib/typescript/commonjs/src/anchors/semanticMatcher.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/anchors/tapSlop.d.ts +9 -0
- package/lib/typescript/commonjs/src/anchors/tapSlop.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/anchors/targetPressMonitor.d.ts +13 -8
- package/lib/typescript/commonjs/src/anchors/targetPressMonitor.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/authoring/fingerprintFromInstance.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/openSafeUrl.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/expo-router/useUserflowExpoRouter.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/index.d.ts +6 -5
- package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/navigation/navigateUrlUtils.d.ts +15 -0
- package/lib/typescript/commonjs/src/navigation/navigateUrlUtils.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/navigation/openExternalNavigateUrl.d.ts +3 -0
- package/lib/typescript/commonjs/src/navigation/openExternalNavigateUrl.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/navigation/openFlowNavigateUrl.d.ts +2 -5
- package/lib/typescript/commonjs/src/navigation/openFlowNavigateUrl.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/pairing/PairingController.d.ts +6 -0
- package/lib/typescript/commonjs/src/pairing/PairingController.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/runtime/BannerHost.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/runtime/TargetPressBridge.d.ts +3 -0
- package/lib/typescript/commonjs/src/runtime/TargetPressBridge.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/runtime/UserflowOverlay.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/runtime/UserflowProvider.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/runtime/bannerEngine.d.ts +5 -1
- package/lib/typescript/commonjs/src/runtime/bannerEngine.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/runtime/bannerFlowSpacer.d.ts +15 -0
- package/lib/typescript/commonjs/src/runtime/bannerFlowSpacer.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/runtime/flowEngine.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/runtime/previewStart.d.ts +13 -0
- package/lib/typescript/commonjs/src/runtime/previewStart.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/runtime/pushBannerLayoutContext.d.ts +22 -0
- package/lib/typescript/commonjs/src/runtime/pushBannerLayoutContext.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/screenTracker.d.ts +6 -0
- package/lib/typescript/commonjs/src/screenTracker.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/surfaces/BannerBar.d.ts +3 -1
- package/lib/typescript/commonjs/src/surfaces/BannerBar.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/surfaces/BannerSurface.d.ts +6 -5
- 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 +1 -1
- package/lib/typescript/commonjs/src/surfaces/TooltipSurface.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/surfaces/bannerBarLayout.d.ts +17 -0
- package/lib/typescript/commonjs/src/surfaces/bannerBarLayout.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/surfaces/bannerWebView/BannerWebViewBar.d.ts +3 -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/hostAccessibilityTrap.d.ts +14 -0
- package/lib/typescript/commonjs/src/surfaces/hostAccessibilityTrap.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/surfaces/resolveBannerTheme.d.ts +4 -1
- package/lib/typescript/commonjs/src/surfaces/resolveBannerTheme.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/surfaces/tooltip/TooltipBubble.d.ts +7 -1
- package/lib/typescript/commonjs/src/surfaces/tooltip/TooltipBubble.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/surfaces/tooltip/targetSearchSchedule.d.ts +60 -0
- package/lib/typescript/commonjs/src/surfaces/tooltip/targetSearchSchedule.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/version.d.ts +1 -1
- package/lib/typescript/module/src/anchors/AutoAnchorRegistry.d.ts +36 -2
- package/lib/typescript/module/src/anchors/AutoAnchorRegistry.d.ts.map +1 -1
- package/lib/typescript/module/src/anchors/animationFrame.d.ts +0 -4
- package/lib/typescript/module/src/anchors/animationFrame.d.ts.map +1 -1
- package/lib/typescript/module/src/anchors/appActive.d.ts +8 -0
- package/lib/typescript/module/src/anchors/appActive.d.ts.map +1 -0
- package/lib/typescript/module/src/anchors/elementTapMonitor.d.ts +17 -0
- package/lib/typescript/module/src/anchors/elementTapMonitor.d.ts.map +1 -1
- package/lib/typescript/module/src/anchors/elementTargetMatch.d.ts +7 -0
- package/lib/typescript/module/src/anchors/elementTargetMatch.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/fiberInternals.d.ts +7 -0
- package/lib/typescript/module/src/anchors/fiber/fiberInternals.d.ts.map +1 -1
- package/lib/typescript/module/src/anchors/fiber/indexHostFibers.d.ts +3 -2
- package/lib/typescript/module/src/anchors/fiber/indexHostFibers.d.ts.map +1 -1
- package/lib/typescript/module/src/anchors/fiber/resolveFiberPath.d.ts +3 -0
- package/lib/typescript/module/src/anchors/fiber/resolveFiberPath.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/fiberAnchorCache.d.ts +5 -0
- package/lib/typescript/module/src/anchors/fiberAnchorCache.d.ts.map +1 -1
- package/lib/typescript/module/src/anchors/gestureHandlerHandoff.d.ts +70 -0
- package/lib/typescript/module/src/anchors/gestureHandlerHandoff.d.ts.map +1 -0
- package/lib/typescript/module/src/anchors/resolveAnchorHost.d.ts +1 -0
- package/lib/typescript/module/src/anchors/resolveAnchorHost.d.ts.map +1 -1
- package/lib/typescript/module/src/anchors/resolveAutoAnchorHost.d.ts +11 -4
- package/lib/typescript/module/src/anchors/resolveAutoAnchorHost.d.ts.map +1 -1
- package/lib/typescript/module/src/anchors/resolveElementTargets.d.ts.map +1 -1
- package/lib/typescript/module/src/anchors/semanticMatcher.d.ts +2 -0
- package/lib/typescript/module/src/anchors/semanticMatcher.d.ts.map +1 -1
- package/lib/typescript/module/src/anchors/tapSlop.d.ts +9 -0
- package/lib/typescript/module/src/anchors/tapSlop.d.ts.map +1 -0
- package/lib/typescript/module/src/anchors/targetPressMonitor.d.ts +13 -8
- package/lib/typescript/module/src/anchors/targetPressMonitor.d.ts.map +1 -1
- package/lib/typescript/module/src/authoring/fingerprintFromInstance.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/openSafeUrl.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/expo-router/useUserflowExpoRouter.d.ts.map +1 -1
- package/lib/typescript/module/src/index.d.ts +6 -5
- package/lib/typescript/module/src/index.d.ts.map +1 -1
- package/lib/typescript/module/src/navigation/navigateUrlUtils.d.ts +15 -0
- package/lib/typescript/module/src/navigation/navigateUrlUtils.d.ts.map +1 -0
- package/lib/typescript/module/src/navigation/openExternalNavigateUrl.d.ts +3 -0
- package/lib/typescript/module/src/navigation/openExternalNavigateUrl.d.ts.map +1 -0
- package/lib/typescript/module/src/navigation/openFlowNavigateUrl.d.ts +2 -5
- package/lib/typescript/module/src/navigation/openFlowNavigateUrl.d.ts.map +1 -1
- package/lib/typescript/module/src/pairing/PairingController.d.ts +6 -0
- package/lib/typescript/module/src/pairing/PairingController.d.ts.map +1 -1
- package/lib/typescript/module/src/runtime/BannerHost.d.ts.map +1 -1
- package/lib/typescript/module/src/runtime/TargetPressBridge.d.ts +3 -0
- package/lib/typescript/module/src/runtime/TargetPressBridge.d.ts.map +1 -1
- package/lib/typescript/module/src/runtime/UserflowOverlay.d.ts.map +1 -1
- package/lib/typescript/module/src/runtime/UserflowProvider.d.ts.map +1 -1
- package/lib/typescript/module/src/runtime/bannerEngine.d.ts +5 -1
- package/lib/typescript/module/src/runtime/bannerEngine.d.ts.map +1 -1
- package/lib/typescript/module/src/runtime/bannerFlowSpacer.d.ts +15 -0
- package/lib/typescript/module/src/runtime/bannerFlowSpacer.d.ts.map +1 -0
- package/lib/typescript/module/src/runtime/flowEngine.d.ts.map +1 -1
- package/lib/typescript/module/src/runtime/previewStart.d.ts +13 -0
- package/lib/typescript/module/src/runtime/previewStart.d.ts.map +1 -0
- package/lib/typescript/module/src/runtime/pushBannerLayoutContext.d.ts +22 -0
- package/lib/typescript/module/src/runtime/pushBannerLayoutContext.d.ts.map +1 -0
- package/lib/typescript/module/src/screenTracker.d.ts +6 -0
- package/lib/typescript/module/src/screenTracker.d.ts.map +1 -1
- package/lib/typescript/module/src/surfaces/BannerBar.d.ts +3 -1
- package/lib/typescript/module/src/surfaces/BannerBar.d.ts.map +1 -1
- package/lib/typescript/module/src/surfaces/BannerSurface.d.ts +6 -5
- 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 +1 -1
- package/lib/typescript/module/src/surfaces/TooltipSurface.d.ts.map +1 -1
- package/lib/typescript/module/src/surfaces/bannerBarLayout.d.ts +17 -0
- package/lib/typescript/module/src/surfaces/bannerBarLayout.d.ts.map +1 -1
- package/lib/typescript/module/src/surfaces/bannerWebView/BannerWebViewBar.d.ts +3 -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/hostAccessibilityTrap.d.ts +14 -0
- package/lib/typescript/module/src/surfaces/hostAccessibilityTrap.d.ts.map +1 -0
- package/lib/typescript/module/src/surfaces/resolveBannerTheme.d.ts +4 -1
- package/lib/typescript/module/src/surfaces/resolveBannerTheme.d.ts.map +1 -1
- package/lib/typescript/module/src/surfaces/tooltip/TooltipBubble.d.ts +7 -1
- package/lib/typescript/module/src/surfaces/tooltip/TooltipBubble.d.ts.map +1 -1
- package/lib/typescript/module/src/surfaces/tooltip/targetSearchSchedule.d.ts +60 -0
- package/lib/typescript/module/src/surfaces/tooltip/targetSearchSchedule.d.ts.map +1 -0
- package/lib/typescript/module/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/anchors/AutoAnchorRegistry.ts +166 -35
- package/src/anchors/animationFrame.ts +31 -1
- package/src/anchors/appActive.ts +63 -0
- package/src/anchors/elementConditionEvaluator.ts +29 -12
- package/src/anchors/elementTapMonitor.ts +68 -10
- package/src/anchors/elementTargetMatch.ts +34 -7
- package/src/anchors/fiber/FiberScanRootStore.ts +8 -0
- package/src/anchors/fiber/detectAppFontFamily.ts +400 -0
- package/src/anchors/fiber/fiberInternals.ts +68 -0
- package/src/anchors/fiber/indexHostFibers.ts +8 -3
- package/src/anchors/fiber/resolveFiberPath.ts +25 -16
- package/src/anchors/fiber/visibleScreens.ts +5 -0
- package/src/anchors/fiberAnchorCache.ts +19 -0
- package/src/anchors/gestureHandlerHandoff.ts +356 -0
- package/src/anchors/resolveAnchorHost.ts +2 -0
- package/src/anchors/resolveAutoAnchorHost.ts +18 -8
- package/src/anchors/resolveElementTargets.ts +64 -7
- package/src/anchors/semanticMatcher.ts +48 -27
- package/src/anchors/tapSlop.ts +18 -0
- package/src/anchors/targetPressMonitor.ts +56 -19
- package/src/authoring/fingerprintFromInstance.ts +4 -5
- package/src/content/BannerStepButton.tsx +2 -1
- package/src/content/RichContentRenderer.tsx +19 -13
- package/src/content/StepButton.tsx +2 -1
- package/src/content/openSafeUrl.ts +3 -1
- package/src/content/resolveContentFontFamily.ts +119 -0
- package/src/expo-router/useUserflowExpoRouter.ts +10 -1
- package/src/index.ts +22 -9
- package/src/navigation/navigateUrlUtils.ts +100 -0
- package/src/navigation/openExternalNavigateUrl.ts +9 -0
- package/src/navigation/openFlowNavigateUrl.ts +36 -36
- package/src/pairing/PairingController.ts +9 -1
- package/src/runtime/BannerHost.tsx +41 -23
- package/src/runtime/TargetPressBridge.tsx +66 -9
- package/src/runtime/UserflowOverlay.tsx +7 -9
- package/src/runtime/UserflowProvider.tsx +56 -32
- package/src/runtime/bannerEngine.ts +10 -2
- package/src/runtime/bannerFlowSpacer.tsx +70 -0
- package/src/runtime/flowEngine.ts +11 -0
- package/src/runtime/previewStart.ts +49 -0
- package/src/runtime/pushBannerLayoutContext.tsx +126 -0
- package/src/screenTracker.ts +11 -0
- package/src/surfaces/BannerBar.tsx +93 -55
- package/src/surfaces/BannerSurface.tsx +61 -9
- package/src/surfaces/ProgressBar.tsx +2 -1
- package/src/surfaces/TooltipSurface.tsx +78 -53
- package/src/surfaces/bannerBarLayout.ts +80 -7
- package/src/surfaces/bannerWebView/BannerWebViewBar.tsx +151 -57
- 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 +111 -23
- package/src/surfaces/hostAccessibilityTrap.ts +25 -0
- package/src/surfaces/resolveBannerTheme.ts +14 -3
- package/src/surfaces/tooltip/TooltipBubble.tsx +8 -1
- package/src/surfaces/tooltip/targetSearchSchedule.ts +140 -0
- package/src/version.ts +1 -1
- package/vendor/core/dist/engine/BannerSessionEngine.d.ts +29 -2
- package/vendor/core/dist/engine/BannerSessionEngine.d.ts.map +1 -1
- package/vendor/core/dist/engine/BannerSessionEngine.js +87 -6
- package/vendor/core/dist/engine/BannerSessionEngine.js.map +1 -1
- package/vendor/core/dist/engine/ClientConditionEngine.d.ts.map +1 -1
- package/vendor/core/dist/engine/ClientConditionEngine.js +30 -7
- package/vendor/core/dist/engine/ClientConditionEngine.js.map +1 -1
- package/vendor/core/dist/engine/PairingEngine.d.ts +6 -1
- package/vendor/core/dist/engine/PairingEngine.d.ts.map +1 -1
- package/vendor/core/dist/engine/PairingEngine.js +23 -3
- package/vendor/core/dist/engine/PairingEngine.js.map +1 -1
- package/vendor/core/dist/engine/handleActions.d.ts.map +1 -1
- package/vendor/core/dist/engine/handleActions.js +67 -2
- package/vendor/core/dist/engine/handleActions.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
|
@@ -23,11 +23,14 @@ import { getEvalJsWebView, type EvalJsWebViewHandle } from '../../evalJs/getWebV
|
|
|
23
23
|
import { injectEvalPendingIntoWebView } from '../../evalJs/injectEvalPending';
|
|
24
24
|
import type { EvalJsContext } from '../../evalJs/types';
|
|
25
25
|
import { useEvalJsWebViewInjection } from '../../evalJs/useEvalJsWebViewInjection';
|
|
26
|
+
import { usePushBannerHostInsetRegistration } from '../../runtime/pushBannerLayoutContext';
|
|
27
|
+
import { setBannerFlowSpacerHeight } from '../../runtime/bannerFlowSpacer';
|
|
28
|
+
import { warnBannerOnce } from '../../runtime/bannerPlacement';
|
|
26
29
|
import { getUserflowCore } from '../../runtime/userflowCore';
|
|
27
30
|
import { getCurrentScreenLocation, subscribeScreenLocation } from '../../screenTracker';
|
|
28
31
|
import {
|
|
29
32
|
bannerFrameStyle,
|
|
30
|
-
|
|
33
|
+
bannerPushLayoutChrome,
|
|
31
34
|
resolveBannerBarBorderRadius,
|
|
32
35
|
} from '../bannerBarLayout';
|
|
33
36
|
import { bannerOverlayShadowStyle } from '../bannerBarTokens';
|
|
@@ -39,6 +42,8 @@ import { buildCustomBannerBodyHtml } from './buildCustomBannerHtml';
|
|
|
39
42
|
|
|
40
43
|
export interface BannerWebViewBarProps {
|
|
41
44
|
session: BannerSessionFragment;
|
|
45
|
+
pushLayoutEdge?: 'top' | 'bottom' | null;
|
|
46
|
+
overlaySafeEdge?: 'top' | 'bottom' | null;
|
|
42
47
|
onActions: (actions: FlowActionFragment[]) => void | Promise<void>;
|
|
43
48
|
onDismiss: (endReason: EndFlowReasonInput) => void;
|
|
44
49
|
}
|
|
@@ -68,14 +73,27 @@ function useEvalJsScreen(): { name?: string; path?: string } {
|
|
|
68
73
|
|
|
69
74
|
export function BannerWebViewBar({
|
|
70
75
|
session,
|
|
76
|
+
pushLayoutEdge = null,
|
|
77
|
+
overlaySafeEdge = null,
|
|
71
78
|
onActions,
|
|
72
79
|
onDismiss,
|
|
73
80
|
}: BannerWebViewBarProps): React.ReactElement | null {
|
|
74
81
|
const banner = session.version.banner;
|
|
82
|
+
const overlay = banner?.overlay !== false;
|
|
83
|
+
const hostInsetEdge = banner && !overlay && pushLayoutEdge ? pushLayoutEdge : null;
|
|
84
|
+
const pushLayoutRegistrationEdge =
|
|
85
|
+
hostInsetEdge ?? (!overlay && overlaySafeEdge ? overlaySafeEdge : null);
|
|
86
|
+
const safeAreaEdge = hostInsetEdge ?? overlaySafeEdge ?? null;
|
|
87
|
+
const onPushChromeLayout = usePushBannerHostInsetRegistration(
|
|
88
|
+
pushLayoutRegistrationEdge,
|
|
89
|
+
session.id,
|
|
90
|
+
pushLayoutRegistrationEdge != null,
|
|
91
|
+
);
|
|
75
92
|
const WebView = getEvalJsWebView();
|
|
76
93
|
const webRef = React.useRef<EvalJsWebViewHandle>(null);
|
|
77
94
|
const [pageReady, setPageReady] = React.useState(false);
|
|
78
95
|
const [contentHeight, setContentHeight] = React.useState(56);
|
|
96
|
+
const [webLayoutHeight, setWebLayoutHeight] = React.useState<number | null>(null);
|
|
79
97
|
const colorScheme = useColorScheme();
|
|
80
98
|
const viewport = useWindowDimensions();
|
|
81
99
|
const insets = useUserflowSafeAreaInsets();
|
|
@@ -104,18 +122,18 @@ export function BannerWebViewBar({
|
|
|
104
122
|
const serverEndpoint = getUserflowCore().getServerEndpoint() ?? DEFAULT_SERVER_ENDPOINT;
|
|
105
123
|
|
|
106
124
|
const skipAutoRunEval = shouldSkipBannerAutoRunEval(session.id);
|
|
107
|
-
const initialContext = React.useRef(context);
|
|
108
125
|
const html = React.useMemo(() => {
|
|
109
126
|
const body = buildCustomBannerBodyHtml(session, lookupAttribute, serverEndpoint, {
|
|
110
127
|
skipAutoRunEval,
|
|
111
128
|
});
|
|
112
|
-
return buildBootstrapHtml(
|
|
113
|
-
}, [lookupAttribute, serverEndpoint, session, skipAutoRunEval]);
|
|
129
|
+
return buildBootstrapHtml(context, body);
|
|
130
|
+
}, [context, lookupAttribute, serverEndpoint, session, skipAutoRunEval]);
|
|
114
131
|
|
|
115
|
-
const
|
|
132
|
+
const fadeIn = banner?.animate === true && hostInsetEdge == null;
|
|
133
|
+
const opacity = React.useRef(new Animated.Value(fadeIn ? 0 : 1)).current;
|
|
116
134
|
|
|
117
135
|
React.useEffect(() => {
|
|
118
|
-
if (!
|
|
136
|
+
if (!fadeIn) {
|
|
119
137
|
opacity.setValue(1);
|
|
120
138
|
return;
|
|
121
139
|
}
|
|
@@ -129,13 +147,39 @@ export function BannerWebViewBar({
|
|
|
129
147
|
return () => {
|
|
130
148
|
animation.stop();
|
|
131
149
|
};
|
|
132
|
-
}, [
|
|
150
|
+
}, [fadeIn, opacity, session.id]);
|
|
133
151
|
|
|
134
152
|
React.useEffect(() => {
|
|
135
153
|
setPageReady(false);
|
|
136
154
|
setContentHeight(56);
|
|
155
|
+
setWebLayoutHeight(null);
|
|
137
156
|
}, [session.id, html]);
|
|
138
157
|
|
|
158
|
+
const reserveFlowSpace = !overlay && overlaySafeEdge != null;
|
|
159
|
+
React.useEffect(() => {
|
|
160
|
+
if (!reserveFlowSpace || !overlaySafeEdge) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
return () => {
|
|
164
|
+
setBannerFlowSpacerHeight(overlaySafeEdge, 0);
|
|
165
|
+
};
|
|
166
|
+
}, [overlaySafeEdge, reserveFlowSpace, session.id]);
|
|
167
|
+
|
|
168
|
+
React.useEffect(() => {
|
|
169
|
+
if (pushLayoutRegistrationEdge == null) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
const timer = setTimeout(() => {
|
|
173
|
+
if (webLayoutHeight == null) {
|
|
174
|
+
warnBannerOnce(
|
|
175
|
+
`push-webview-layout:${session.id}`,
|
|
176
|
+
'Userflow: push-layout WebView banner did not report a layout height; check custom CSS / WebView logs',
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
}, 4000);
|
|
180
|
+
return () => clearTimeout(timer);
|
|
181
|
+
}, [pushLayoutRegistrationEdge, session.id, webLayoutHeight]);
|
|
182
|
+
|
|
139
183
|
React.useEffect(() => {
|
|
140
184
|
if (!pageReady || skipAutoRunEval || !banner) {
|
|
141
185
|
return;
|
|
@@ -177,17 +221,23 @@ export function BannerWebViewBar({
|
|
|
177
221
|
const maxHeight = Math.floor(viewport.height * 0.92);
|
|
178
222
|
const next = Math.min(Math.ceil(height), maxHeight);
|
|
179
223
|
setContentHeight((prev) => (Math.abs(next - prev) <= 1 ? prev : next));
|
|
224
|
+
setWebLayoutHeight(next);
|
|
180
225
|
}
|
|
181
226
|
return;
|
|
182
227
|
}
|
|
183
228
|
if (record.__userflow === 1 && record.type === 'bannerButton') {
|
|
184
229
|
const buttonId = record.buttonId;
|
|
185
230
|
if (typeof buttonId === 'string' && banner) {
|
|
186
|
-
const button =
|
|
231
|
+
const button =
|
|
232
|
+
banner.buttons.find((entry) => entry.id === buttonId) ??
|
|
233
|
+
banner.buttons.find((entry) => entry.cvid === buttonId);
|
|
187
234
|
if (button) {
|
|
188
235
|
void Promise.resolve(onActions(button.actions)).then(() => {
|
|
189
236
|
injectEvalPendingIntoWebView(webRef.current);
|
|
190
237
|
});
|
|
238
|
+
} else if (__DEV__) {
|
|
239
|
+
// eslint-disable-next-line no-console -- intentional development diagnostic
|
|
240
|
+
console.warn('[Userflow] banner button not found for id', buttonId);
|
|
191
241
|
}
|
|
192
242
|
}
|
|
193
243
|
return;
|
|
@@ -241,72 +291,116 @@ export function BannerWebViewBar({
|
|
|
241
291
|
return;
|
|
242
292
|
}
|
|
243
293
|
},
|
|
244
|
-
[
|
|
294
|
+
[
|
|
295
|
+
banner,
|
|
296
|
+
insets.bottom,
|
|
297
|
+
insets.top,
|
|
298
|
+
onActions,
|
|
299
|
+
onDismiss,
|
|
300
|
+
overlaySafeEdge,
|
|
301
|
+
reserveFlowSpace,
|
|
302
|
+
viewport.height,
|
|
303
|
+
],
|
|
245
304
|
);
|
|
246
305
|
|
|
247
306
|
if (!banner || !WebView) {
|
|
248
307
|
return null;
|
|
249
308
|
}
|
|
250
309
|
|
|
251
|
-
const overlay = banner.overlay !== false;
|
|
252
310
|
const frameStyle = bannerFrameStyle(banner);
|
|
253
|
-
const innerStyle = bannerInnerStyle(banner);
|
|
254
311
|
const overlayEdge = banner.embedMode === BannerEmbedMode.BODY_LAST ? 'bottom' : 'top';
|
|
255
312
|
const barRadius = resolveBannerBarBorderRadius(banner);
|
|
313
|
+
// Custom CSS paints the card, often with its own radius. The theme color
|
|
314
|
+
// (brand blue when banner tokens are unset) would otherwise fill the
|
|
315
|
+
// status-bar pad and the corners outside that radius.
|
|
316
|
+
const shellBackground = 'transparent';
|
|
256
317
|
const webStyle: ViewStyle = {
|
|
257
318
|
width: '100%',
|
|
258
319
|
height: contentHeight,
|
|
259
|
-
backgroundColor:
|
|
320
|
+
backgroundColor: shellBackground,
|
|
260
321
|
};
|
|
261
322
|
const debugging = typeof __DEV__ !== 'undefined' && __DEV__ ? true : undefined;
|
|
323
|
+
const insetChrome = safeAreaEdge
|
|
324
|
+
? bannerPushLayoutChrome(safeAreaEdge, insets, shellBackground)
|
|
325
|
+
: null;
|
|
326
|
+
const insetChromeOutsideFade = insetChrome != null && fadeIn;
|
|
327
|
+
|
|
328
|
+
const webViewBar = (
|
|
329
|
+
<View
|
|
330
|
+
testID="userflow-banner-webview"
|
|
331
|
+
pointerEvents="auto"
|
|
332
|
+
style={[{ borderRadius: barRadius ?? 0, overflow: 'hidden' as const }]}
|
|
333
|
+
>
|
|
334
|
+
<WebView
|
|
335
|
+
key={session.id}
|
|
336
|
+
ref={webRef}
|
|
337
|
+
source={{ html, baseUrl: EVAL_JS_BASE_URL }}
|
|
338
|
+
style={webStyle}
|
|
339
|
+
javaScriptEnabled
|
|
340
|
+
domStorageEnabled
|
|
341
|
+
scrollEnabled={false}
|
|
342
|
+
bounces={false}
|
|
343
|
+
showsHorizontalScrollIndicator={false}
|
|
344
|
+
showsVerticalScrollIndicator={false}
|
|
345
|
+
originWhitelist={['*']}
|
|
346
|
+
setSupportMultipleWindows={false}
|
|
347
|
+
androidLayerType="hardware"
|
|
348
|
+
{...(debugging !== undefined ? { webviewDebuggingEnabled: debugging } : {})}
|
|
349
|
+
onMessage={onMessage}
|
|
350
|
+
onLoadEnd={() => {
|
|
351
|
+
setPageReady(true);
|
|
352
|
+
webRef.current?.injectJavaScript(
|
|
353
|
+
'window.__userflowBannerLayout&&window.__userflowBannerLayout();true;',
|
|
354
|
+
);
|
|
355
|
+
}}
|
|
356
|
+
onShouldStartLoadWithRequest={(request) => {
|
|
357
|
+
if (isBootstrapUrl(request.url)) {
|
|
358
|
+
return true;
|
|
359
|
+
}
|
|
360
|
+
openExternal(request.url);
|
|
361
|
+
return false;
|
|
362
|
+
}}
|
|
363
|
+
onOpenWindow={(event) => {
|
|
364
|
+
const url = event.nativeEvent.targetUrl;
|
|
365
|
+
if (url) {
|
|
366
|
+
openExternal(url);
|
|
367
|
+
}
|
|
368
|
+
}}
|
|
369
|
+
/>
|
|
370
|
+
</View>
|
|
371
|
+
);
|
|
372
|
+
|
|
373
|
+
const animatedBar = (
|
|
374
|
+
<Animated.View
|
|
375
|
+
style={[
|
|
376
|
+
{ opacity },
|
|
377
|
+
overlay ? bannerOverlayShadowStyle(overlayEdge) : null,
|
|
378
|
+
insetChromeOutsideFade ? null : insetChrome,
|
|
379
|
+
]}
|
|
380
|
+
>
|
|
381
|
+
{webViewBar}
|
|
382
|
+
</Animated.View>
|
|
383
|
+
);
|
|
262
384
|
|
|
263
385
|
return (
|
|
264
|
-
<View
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
ref={webRef}
|
|
275
|
-
source={{ html, baseUrl: EVAL_JS_BASE_URL }}
|
|
276
|
-
style={webStyle}
|
|
277
|
-
javaScriptEnabled
|
|
278
|
-
domStorageEnabled
|
|
279
|
-
scrollEnabled={false}
|
|
280
|
-
bounces={false}
|
|
281
|
-
showsHorizontalScrollIndicator={false}
|
|
282
|
-
showsVerticalScrollIndicator={false}
|
|
283
|
-
originWhitelist={['*']}
|
|
284
|
-
setSupportMultipleWindows={false}
|
|
285
|
-
androidLayerType="hardware"
|
|
286
|
-
{...(debugging !== undefined ? { webviewDebuggingEnabled: debugging } : {})}
|
|
287
|
-
onMessage={onMessage}
|
|
288
|
-
onLoadEnd={() => {
|
|
289
|
-
setPageReady(true);
|
|
290
|
-
webRef.current?.injectJavaScript(
|
|
291
|
-
'window.__userflowBannerLayout&&window.__userflowBannerLayout();true;',
|
|
292
|
-
);
|
|
293
|
-
}}
|
|
294
|
-
onShouldStartLoadWithRequest={(request) => {
|
|
295
|
-
if (isBootstrapUrl(request.url)) {
|
|
296
|
-
return true;
|
|
386
|
+
<View
|
|
387
|
+
testID="userflow-banner-frame"
|
|
388
|
+
style={frameStyle}
|
|
389
|
+
onLayout={
|
|
390
|
+
reserveFlowSpace && overlaySafeEdge
|
|
391
|
+
? (event) => {
|
|
392
|
+
onPushChromeLayout(event);
|
|
393
|
+
const h = event.nativeEvent.layout.height;
|
|
394
|
+
if (h > 0) {
|
|
395
|
+
setBannerFlowSpacerHeight(overlaySafeEdge, h);
|
|
297
396
|
}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
}
|
|
306
|
-
}}
|
|
307
|
-
/>
|
|
308
|
-
</View>
|
|
309
|
-
</Animated.View>
|
|
397
|
+
}
|
|
398
|
+
: pushLayoutRegistrationEdge
|
|
399
|
+
? onPushChromeLayout
|
|
400
|
+
: undefined
|
|
401
|
+
}
|
|
402
|
+
>
|
|
403
|
+
{insetChromeOutsideFade ? <View style={insetChrome}>{animatedBar}</View> : animatedBar}
|
|
310
404
|
</View>
|
|
311
405
|
);
|
|
312
406
|
}
|
|
@@ -1,38 +1,6 @@
|
|
|
1
|
-
import type { BannerFragment
|
|
2
|
-
import { FlowActionType } from '@userflow-tech/protocol';
|
|
1
|
+
import type { BannerFragment } from '@userflow-tech/protocol';
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
/** POC / local testing when the builder flag is not on the wire yet. */
|
|
9
|
-
export function setDebugForceWebViewBanner(enabled: boolean): void {
|
|
10
|
-
debugForceWebViewBanner = enabled;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/** @internal */
|
|
14
|
-
export function resetDebugForceWebViewBannerForTests(): void {
|
|
15
|
-
debugForceWebViewBanner = false;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function bannerHasEvalJsAction(banner: BannerFragment): boolean {
|
|
19
|
-
return banner.buttons.some((button) =>
|
|
20
|
-
button.actions.some((action) => action.type === FlowActionType.EVAL_JS),
|
|
21
|
-
);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Use the WebView banner renderer when any button runs Evaluate JavaScript
|
|
26
|
-
* (needs the shared eval page), when the theme has published custom CSS
|
|
27
|
-
* (`.userflow-custom-container-*` / `.userflow-custom-button-*` via CDN),
|
|
28
|
-
* or when {@link setDebugForceWebViewBanner} is true.
|
|
29
|
-
*/
|
|
30
|
-
export function bannerNeedsWebView(banner: BannerFragment, theme?: ThemeFragment | null): boolean {
|
|
31
|
-
if (debugForceWebViewBanner) {
|
|
32
|
-
return true;
|
|
33
|
-
}
|
|
34
|
-
if (theme != null && themeHasPublishedCustomCss(theme)) {
|
|
35
|
-
return true;
|
|
36
|
-
}
|
|
37
|
-
return bannerHasEvalJsAction(banner);
|
|
3
|
+
/** Use the WebView banner renderer when the builder enabled custom banners. */
|
|
4
|
+
export function bannerNeedsWebView(banner: BannerFragment): boolean {
|
|
5
|
+
return banner.customBannerEnabled === true;
|
|
38
6
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ThemeFragment } from '@userflow-tech/protocol';
|
|
2
2
|
|
|
3
|
+
import { contentFontFamilyCss } from '../../content/resolveContentFontFamily';
|
|
3
4
|
import { resolveBannerBackgroundColor, resolveBannerForegroundColor } from '../resolveBannerTheme';
|
|
4
5
|
|
|
5
6
|
function readString(theme: ThemeFragment, key: string, fallback: string): string {
|
|
@@ -68,7 +69,7 @@ export function bannerThemeInlineStyles(theme: ThemeFragment): Record<string, st
|
|
|
68
69
|
'bannerActiveForegroundColor',
|
|
69
70
|
bannerFg,
|
|
70
71
|
),
|
|
71
|
-
'--userflow-font-family':
|
|
72
|
+
'--userflow-font-family': contentFontFamilyCss(theme),
|
|
72
73
|
'--userflow-font-size': `${fontSize}px`,
|
|
73
74
|
'--userflow-line-height': `${lineHeight}px`,
|
|
74
75
|
'--userflow-button-height': readCssLength(theme, 'buttonHeight', 32),
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Height the native WebView should use for a custom banner.
|
|
3
|
+
*
|
|
4
|
+
* Custom CSS often sizes the card with `min-height` and takes the copy and
|
|
5
|
+
* buttons out of flow (`position: absolute`). The WebView is created shorter
|
|
6
|
+
* than that card, so a root that only looks as tall as the viewport because of
|
|
7
|
+
* `min-height` must not be replaced with the close button's box.
|
|
8
|
+
*
|
|
9
|
+
* When the root really is stretching to fill a taller viewport (`height: 100%`),
|
|
10
|
+
* fall back to in-flow content, and never below `min-height`.
|
|
11
|
+
*/
|
|
12
|
+
export function resolveBannerWebViewHeight(
|
|
13
|
+
rectHeight: number,
|
|
14
|
+
scrollHeight: number,
|
|
15
|
+
viewportHeight: number,
|
|
16
|
+
minHeight: number,
|
|
17
|
+
contentHeight: number,
|
|
18
|
+
): number {
|
|
19
|
+
const rect = rectHeight > 0 ? rectHeight : 0;
|
|
20
|
+
const scroll = scrollHeight > 0 ? scrollHeight : 0;
|
|
21
|
+
let height = Math.ceil(Math.max(rect, scroll));
|
|
22
|
+
const floor = minHeight > 0 ? Math.ceil(minHeight) : 0;
|
|
23
|
+
if (viewportHeight > 0 && height >= viewportHeight - 2 && height > floor + 1) {
|
|
24
|
+
if (contentHeight > 0 && contentHeight < height) {
|
|
25
|
+
height = Math.ceil(contentHeight > floor ? contentHeight : floor);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (floor > height) {
|
|
29
|
+
height = floor;
|
|
30
|
+
}
|
|
31
|
+
return height;
|
|
32
|
+
}
|
|
@@ -2,11 +2,17 @@ import { interpolateVariables } from '@userflow-tech/core';
|
|
|
2
2
|
import type { BannerFragment, BannerSessionFragment } from '@userflow-tech/protocol';
|
|
3
3
|
import { BannerContentLayout } from '@userflow-tech/protocol';
|
|
4
4
|
|
|
5
|
+
import {
|
|
6
|
+
bannerContentFontLockCss,
|
|
7
|
+
contentFontFaceCss,
|
|
8
|
+
} from '../../content/resolveContentFontFamily';
|
|
5
9
|
import { buildBootstrapHtml, wrapCode } from '../../evalJs/bootstrap';
|
|
6
10
|
import type { EvalJsContext } from '../../evalJs/types';
|
|
7
11
|
|
|
8
12
|
import { collectBannerAutoRunEvalCodes } from './bannerAutoRunEvalJs';
|
|
9
13
|
import { bannerThemeStyleAttribute } from './bannerThemeStyles';
|
|
14
|
+
import { resolveBannerInnerMaxWidth } from '../bannerBarLayout';
|
|
15
|
+
|
|
10
16
|
import { BANNER_WEB_FRAME_CSS } from './bannerWebFrameCss';
|
|
11
17
|
import { buttonClassName } from './buttonClassName';
|
|
12
18
|
import { resolveCustomStylesheetUrl } from './resolveCdnHost';
|
|
@@ -25,26 +31,45 @@ function contentLayoutClass(layout: BannerContentLayout): string {
|
|
|
25
31
|
}
|
|
26
32
|
|
|
27
33
|
function layoutMeasureScript(): string {
|
|
34
|
+
// Inlined on purpose. Hermes' Function#toString is not the source text, so
|
|
35
|
+
// interpolating resolveBannerWebViewHeight.toString() ships a dead function.
|
|
36
|
+
// Keep this body in sync with resolveBannerWebViewHeight.
|
|
28
37
|
return `
|
|
29
38
|
(function(){
|
|
39
|
+
function resolveBannerWebViewHeight(rectHeight,scrollHeight,viewportHeight,minHeight,contentHeight){
|
|
40
|
+
var rect=rectHeight>0?rectHeight:0;
|
|
41
|
+
var scroll=scrollHeight>0?scrollHeight:0;
|
|
42
|
+
var height=Math.ceil(Math.max(rect,scroll));
|
|
43
|
+
var floor=minHeight>0?Math.ceil(minHeight):0;
|
|
44
|
+
if(viewportHeight>0&&height>=viewportHeight-2&&height>floor+1){
|
|
45
|
+
if(contentHeight>0&&contentHeight<height){
|
|
46
|
+
height=Math.ceil(contentHeight>floor?contentHeight:floor);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if(floor>height) height=floor;
|
|
50
|
+
return height;
|
|
51
|
+
}
|
|
30
52
|
function postLayout(){
|
|
31
53
|
var root=document.querySelector('.userflowjs-banner-root');
|
|
32
54
|
if(!root||!window.ReactNativeWebView||!window.ReactNativeWebView.postMessage)return;
|
|
33
55
|
var rectH=root.getBoundingClientRect().height;
|
|
34
56
|
var scrollH=root.scrollHeight;
|
|
35
|
-
var
|
|
57
|
+
var minH=parseFloat(window.getComputedStyle(root).minHeight);
|
|
58
|
+
if(!(minH>0)) minH=0;
|
|
36
59
|
var vh=window.innerHeight||0;
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
60
|
+
var inFlow=0;
|
|
61
|
+
var all=0;
|
|
62
|
+
for(var i=0;i<root.childNodes.length;i++){
|
|
63
|
+
var node=root.childNodes[i];
|
|
64
|
+
if(!node||node.nodeType!==1) continue;
|
|
65
|
+
var box=node.scrollHeight||node.offsetHeight||0;
|
|
66
|
+
all+=box;
|
|
67
|
+
var cs=window.getComputedStyle(node);
|
|
68
|
+
if(cs.display==='none'||cs.position==='absolute'||cs.position==='fixed') continue;
|
|
69
|
+
inFlow+=box;
|
|
47
70
|
}
|
|
71
|
+
var content=inFlow>0?inFlow:all;
|
|
72
|
+
var h=resolveBannerWebViewHeight(rectH,scrollH,vh,minH,content);
|
|
48
73
|
window.ReactNativeWebView.postMessage(JSON.stringify({__userflow:1,type:'bannerLayout',height:h}));
|
|
49
74
|
}
|
|
50
75
|
window.__userflowBannerLayout=postLayout;
|
|
@@ -52,36 +77,87 @@ function layoutMeasureScript(): string {
|
|
|
52
77
|
var root=document.querySelector('.userflowjs-banner-root');
|
|
53
78
|
if(root){new ResizeObserver(postLayout).observe(root);}
|
|
54
79
|
}
|
|
80
|
+
var links=document.querySelectorAll('link[rel="stylesheet"]');
|
|
81
|
+
for(var s=0;s<links.length;s++){
|
|
82
|
+
links[s].addEventListener('load',postLayout);
|
|
83
|
+
links[s].addEventListener('error',postLayout);
|
|
84
|
+
}
|
|
55
85
|
window.addEventListener('load',postLayout);
|
|
86
|
+
// Custom CSS is often still applying on the first pass. A short WebView
|
|
87
|
+
// then clamps used height, so min-height never changes the box and
|
|
88
|
+
// ResizeObserver does not fire. Measure again after the stylesheet can apply.
|
|
56
89
|
setTimeout(postLayout,0);
|
|
90
|
+
setTimeout(postLayout,60);
|
|
91
|
+
setTimeout(postLayout,250);
|
|
57
92
|
})();
|
|
58
93
|
`;
|
|
59
94
|
}
|
|
60
95
|
|
|
61
|
-
function bannerInteractionScript(): string {
|
|
96
|
+
function bannerInteractionScript(buttonsJson: string): string {
|
|
62
97
|
return `
|
|
63
98
|
(function(){
|
|
99
|
+
var __userflowBannerButtons=${buttonsJson};
|
|
64
100
|
function post(msg){
|
|
65
101
|
if(window.ReactNativeWebView&&window.ReactNativeWebView.postMessage){
|
|
66
102
|
window.ReactNativeWebView.postMessage(JSON.stringify(Object.assign({__userflow:1},msg)));
|
|
67
103
|
}
|
|
68
104
|
}
|
|
69
|
-
|
|
105
|
+
function resolveButtonId(el){
|
|
106
|
+
if(!el||!el.closest)return null;
|
|
107
|
+
var tagged=el.closest('[data-userflow-banner-button]');
|
|
108
|
+
if(tagged){
|
|
109
|
+
return tagged.getAttribute('data-userflow-banner-button');
|
|
110
|
+
}
|
|
111
|
+
function hasClass(el,token){
|
|
112
|
+
if(!token)return false;
|
|
113
|
+
var cls=el.className||'';
|
|
114
|
+
var parts=cls.split(/\\s+/);
|
|
115
|
+
for(var p=0;p<parts.length;p++){
|
|
116
|
+
if(parts[p]===token)return true;
|
|
117
|
+
}
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
function appearanceClass(appearance){
|
|
121
|
+
if(!appearance)return '';
|
|
122
|
+
var value=appearance;
|
|
123
|
+
var known=value==='primary'||value==='PRIMARY'||value==='default'||value==='DEFAULT'||value==='banner-primary'||value==='banner-secondary';
|
|
124
|
+
return known?'userflowjs-bubble-button--'+value.toLowerCase():value;
|
|
125
|
+
}
|
|
126
|
+
var bubble=el.closest('.userflowjs-bubble-button,button.userflowjs-bubble-button');
|
|
127
|
+
if(bubble){
|
|
128
|
+
var id=bubble.getAttribute('data-userflow-banner-button');
|
|
129
|
+
if(id)return id;
|
|
130
|
+
for(var i=0;i<__userflowBannerButtons.length;i++){
|
|
131
|
+
var meta=__userflowBannerButtons[i];
|
|
132
|
+
if(meta.appearance&&hasClass(bubble,appearanceClass(meta.appearance)))return meta.id;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
var custom=el.closest('[class*="userflow-custom-button"]');
|
|
136
|
+
if(custom){
|
|
137
|
+
for(var j=0;j<__userflowBannerButtons.length;j++){
|
|
138
|
+
var entry=__userflowBannerButtons[j];
|
|
139
|
+
if(entry.appearance&&hasClass(custom,appearanceClass(entry.appearance)))return entry.id;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
function onActivate(ev){
|
|
70
145
|
var t=ev.target;
|
|
71
146
|
if(!t||!t.closest)return;
|
|
72
|
-
var btn=t.closest('[data-userflow-banner-button]');
|
|
73
|
-
if(btn){
|
|
74
|
-
ev.preventDefault();
|
|
75
|
-
post({type:'bannerButton',buttonId:btn.getAttribute('data-userflow-banner-button')});
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
147
|
var close=t.closest('[data-userflow-banner-dismiss]');
|
|
79
148
|
if(close){
|
|
80
149
|
ev.preventDefault();
|
|
81
150
|
window.__userflowBannerEvalDismissed=true;
|
|
82
151
|
post({type:'bannerDismiss'});
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
var buttonId=resolveButtonId(t);
|
|
155
|
+
if(buttonId){
|
|
156
|
+
ev.preventDefault();
|
|
157
|
+
post({type:'bannerButton',buttonId:buttonId});
|
|
83
158
|
}
|
|
84
|
-
}
|
|
159
|
+
}
|
|
160
|
+
document.addEventListener('click',onActivate,true);
|
|
85
161
|
})();
|
|
86
162
|
`;
|
|
87
163
|
}
|
|
@@ -128,9 +204,12 @@ export function buildCustomBannerBodyHtml(
|
|
|
128
204
|
const theme = session.version.theme;
|
|
129
205
|
const layoutClass = contentLayoutClass(banner.contentLayout);
|
|
130
206
|
const themeStyle = bannerThemeStyleAttribute(theme);
|
|
207
|
+
const fontFaceCss = contentFontFaceCss(theme);
|
|
208
|
+
const fontLockCss = bannerContentFontLockCss(theme);
|
|
131
209
|
const customCssUrl = resolveCustomStylesheetUrl(serverEndpoint, theme);
|
|
210
|
+
const innerMaxWidth = resolveBannerInnerMaxWidth(banner);
|
|
132
211
|
const maxInner =
|
|
133
|
-
|
|
212
|
+
innerMaxWidth != null && innerMaxWidth > 0 ? ` style="max-width:${innerMaxWidth}px"` : '';
|
|
134
213
|
const contentHtml = richContentDocToHtml(banner.content, lookupAttribute);
|
|
135
214
|
const buttonsHtml = banner.buttons
|
|
136
215
|
.map((button) => {
|
|
@@ -143,13 +222,22 @@ export function buildCustomBannerBodyHtml(
|
|
|
143
222
|
? '<div class="userflowjs-banner-start-spacer"></div>'
|
|
144
223
|
: '<button type="button" class="userflowjs-banner-close userflowjs-button-reset" data-userflow-banner-dismiss="1" aria-label="Dismiss">×</button>';
|
|
145
224
|
|
|
225
|
+
const buttonMetaJson = JSON.stringify(
|
|
226
|
+
banner.buttons.map((button) => ({
|
|
227
|
+
id: button.id,
|
|
228
|
+
cvid: button.cvid,
|
|
229
|
+
appearance: button.appearance ?? '',
|
|
230
|
+
})),
|
|
231
|
+
).replace(/</g, '\\u003c');
|
|
232
|
+
|
|
146
233
|
const customLink = customCssUrl
|
|
147
234
|
? `<link rel="stylesheet" href="${escapeAttr(customCssUrl)}" />`
|
|
148
235
|
: '';
|
|
149
236
|
|
|
150
237
|
return `
|
|
151
|
-
<style>${BANNER_WEB_FRAME_CSS}</style>
|
|
238
|
+
<style>${fontFaceCss}${BANNER_WEB_FRAME_CSS}</style>
|
|
152
239
|
${customLink}
|
|
240
|
+
<style>${fontLockCss}</style>
|
|
153
241
|
<div class="userflowjs-banner-root userflowjs-theme-root ${layoutClass}" style="${themeStyle}">
|
|
154
242
|
<div class="userflowjs-banner-start-spacer"></div>
|
|
155
243
|
<div class="userflowjs-banner-inner"${maxInner}>
|
|
@@ -158,7 +246,7 @@ ${customLink}
|
|
|
158
246
|
</div>
|
|
159
247
|
${closeHtml}
|
|
160
248
|
</div>
|
|
161
|
-
<script>${layoutMeasureScript()}${bannerInteractionScript()}${options?.skipAutoRunEval ? '' : bannerAutoRunEvalScript(banner, lookupAttribute)}</script>
|
|
249
|
+
<script>${layoutMeasureScript()}${bannerInteractionScript(buttonMetaJson)}${options?.skipAutoRunEval ? '' : bannerAutoRunEvalScript(banner, lookupAttribute)}</script>
|
|
162
250
|
`;
|
|
163
251
|
}
|
|
164
252
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { FlowStepFragment } from '@userflow-tech/protocol';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Whether a step hides host app content from the accessibility tree.
|
|
5
|
+
*
|
|
6
|
+
* Modals always do. A tooltip does only when `tooltipTargetBlocked` seals its
|
|
7
|
+
* target too — otherwise the target is the control the step asks the user to
|
|
8
|
+
* press, so a screen reader has to be able to reach it.
|
|
9
|
+
*
|
|
10
|
+
* `UserflowOverlay` traps the host with this, and tooltip cards gate
|
|
11
|
+
* `accessibilityViewIsModal` on it: on iOS that flag alone drops the host app,
|
|
12
|
+
* target included, out of VoiceOver's reach.
|
|
13
|
+
*/
|
|
14
|
+
export function stepTrapsHostAccessibility(
|
|
15
|
+
step: Pick<FlowStepFragment, 'appearance' | 'tooltipTargetBlocked'>,
|
|
16
|
+
): boolean {
|
|
17
|
+
const appearance = String(step.appearance).toUpperCase();
|
|
18
|
+
if (appearance === 'HIDDEN') {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
if (appearance !== 'TOOLTIP') {
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
return step.tooltipTargetBlocked;
|
|
25
|
+
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { ThemeFragment } from '@userflow-tech/protocol';
|
|
2
2
|
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* Last-resort banner chrome when neither banner nor brand tokens are set on the
|
|
5
|
+
* wire (web `applyThemeDefaults` falls back to brand first).
|
|
6
|
+
*/
|
|
4
7
|
export const DEFAULT_BANNER_BACKGROUND_COLOR = '#0A1A24';
|
|
5
8
|
export const DEFAULT_BANNER_FOREGROUND_COLOR = '#FFFFFF';
|
|
6
9
|
|
|
@@ -10,9 +13,17 @@ function readThemeColor(theme: ThemeFragment, key: string): string | undefined {
|
|
|
10
13
|
}
|
|
11
14
|
|
|
12
15
|
export function resolveBannerBackgroundColor(theme: ThemeFragment): string {
|
|
13
|
-
return
|
|
16
|
+
return (
|
|
17
|
+
readThemeColor(theme, 'bannerBackgroundColor') ??
|
|
18
|
+
readThemeColor(theme, 'brandBackgroundColor') ??
|
|
19
|
+
DEFAULT_BANNER_BACKGROUND_COLOR
|
|
20
|
+
);
|
|
14
21
|
}
|
|
15
22
|
|
|
16
23
|
export function resolveBannerForegroundColor(theme: ThemeFragment): string {
|
|
17
|
-
return
|
|
24
|
+
return (
|
|
25
|
+
readThemeColor(theme, 'bannerForegroundColor') ??
|
|
26
|
+
readThemeColor(theme, 'brandForegroundColor') ??
|
|
27
|
+
DEFAULT_BANNER_FOREGROUND_COLOR
|
|
28
|
+
);
|
|
18
29
|
}
|