@userflow-tech/react-native 0.6.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 +41 -33
- package/docs/troubleshooting.md +38 -38
- 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/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/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/RichContentRenderer.js +19 -7
- package/lib/commonjs/content/RichContentRenderer.js.map +1 -1
- 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 +11 -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/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/userflowCore.js +9 -2
- package/lib/commonjs/runtime/userflowCore.js.map +1 -1
- package/lib/commonjs/surfaces/TooltipSurface.js +109 -51
- package/lib/commonjs/surfaces/TooltipSurface.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/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/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/RichContentRenderer.js +19 -7
- package/lib/module/content/RichContentRenderer.js.map +1 -1
- 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 +11 -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/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/userflowCore.js +9 -2
- package/lib/module/runtime/userflowCore.js.map +1 -1
- package/lib/module/surfaces/TooltipSurface.js +109 -51
- package/lib/module/surfaces/TooltipSurface.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/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/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/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/userflowCore.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/surfaces/TooltipSurface.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/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/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/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/userflowCore.d.ts.map +1 -1
- package/lib/typescript/module/src/surfaces/TooltipSurface.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/presentedModal.ts +203 -0
- package/src/anchors/fiber/touchTargetFiber.ts +2 -1
- package/src/anchors/fiber/visibleRect.ts +12 -3
- 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/RichContentRenderer.tsx +11 -9
- package/src/deepLinking.ts +2 -1
- package/src/deviceContext.ts +50 -14
- package/src/index.ts +11 -5
- package/src/installCheck.ts +3 -3
- package/src/lifecycle.ts +2 -1
- package/src/pairing/PairingController.ts +2 -1
- package/src/runtime/UserflowOverlay.tsx +29 -21
- package/src/runtime/WindowOverlayHost.tsx +95 -0
- package/src/runtime/userflowCore.ts +8 -2
- package/src/surfaces/TooltipSurface.tsx +103 -45
- 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/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PairingController.d.ts","sourceRoot":"","sources":["../../../../../src/pairing/PairingController.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,aAAa,EACb,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,YAAY,EAClB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAY,KAAK,cAAc,EAAqB,MAAM,cAAc,CAAC;AAOhF,OAAO,EASL,KAAK,aAAa,EACnB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAA2B,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEjF,MAAM,MAAM,yBAAyB,GAAG,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;AAY5E,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,YAAY,CAAC;IACnB,+EAA+E;IAC/E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B,mDAAmD;IACnD,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC/B;;;OAGG;IACH,6BAA6B,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,kEAAkE;IAClE,eAAe,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC;;;OAGG;IACH,qBAAqB,CAAC,EAAE,MAAM,IAAI,CAAC;IACnC,aAAa,CAAC,EAAE;
|
|
1
|
+
{"version":3,"file":"PairingController.d.ts","sourceRoot":"","sources":["../../../../../src/pairing/PairingController.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UserflowOverlay.d.ts","sourceRoot":"","sources":["../../../../../src/runtime/UserflowOverlay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAClF,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"UserflowOverlay.d.ts","sourceRoot":"","sources":["../../../../../src/runtime/UserflowOverlay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAClF,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAiB/B,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,YAAY,EAAE,mBAAmB,CAAC;IAClC,6EAA6E;IAC7E,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACvC;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,EAC9B,MAAM,EACN,YAAY,EACZ,YAAY,GACb,EAAE,oBAAoB,GAAG,KAAK,CAAC,YAAY,CAyF3C"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export interface WindowOverlayHostProps {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
/**
|
|
5
|
+
* Hide everything outside the host from VoiceOver, natively presented
|
|
6
|
+
* modals included. Defaults to false.
|
|
7
|
+
*/
|
|
8
|
+
accessibilityModal?: boolean;
|
|
9
|
+
}
|
|
10
|
+
/** True when {@link WindowOverlayHost} draws above natively presented modals. */
|
|
11
|
+
export declare function hasWindowOverlayHost(): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Hosts SDK chrome above everything else in the app window.
|
|
14
|
+
*
|
|
15
|
+
* On iOS, react-native-screens presents `modal`, `transparentModal`,
|
|
16
|
+
* `formSheet` and `fullScreenModal` screens, and React Native presents
|
|
17
|
+
* `<Modal>`, as view controllers above the React Native root view, so chrome
|
|
18
|
+
* rendered in `UserflowProvider`'s overlay is drawn beneath them and never
|
|
19
|
+
* receives touches there. `FullWindowOverlay` moves its children into a
|
|
20
|
+
* container on the window itself. Measured on iOS 17.4 and 26.5 with
|
|
21
|
+
* react-native-screens 4.16, that container stays above sheets whether they are
|
|
22
|
+
* presented before or after it mounts.
|
|
23
|
+
*
|
|
24
|
+
* Each host is its own container, stacked by when it was attached rather than
|
|
25
|
+
* by React order, so chrome that has to keep a paint order shares one host.
|
|
26
|
+
*
|
|
27
|
+
* Touches inside the host arrive in window coordinates, as they do in the root
|
|
28
|
+
* view. Children render in place when the overlay is unavailable: on Android,
|
|
29
|
+
* and in apps without react-native-screens.
|
|
30
|
+
*/
|
|
31
|
+
export declare function WindowOverlayHost({ children, accessibilityModal, }: WindowOverlayHostProps): React.ReactElement;
|
|
32
|
+
/** @internal Clears the cached `FullWindowOverlay` lookup between tests. */
|
|
33
|
+
export declare function resetWindowOverlayHostForTests(): void;
|
|
34
|
+
//# sourceMappingURL=WindowOverlayHost.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WindowOverlayHost.d.ts","sourceRoot":"","sources":["../../../../../src/runtime/WindowOverlayHost.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AA6C/B,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,iFAAiF;AACjF,wBAAgB,oBAAoB,IAAI,OAAO,CAE9C;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,QAAQ,EACR,kBAA0B,GAC3B,EAAE,sBAAsB,GAAG,KAAK,CAAC,YAAY,CAQ7C;AAED,4EAA4E;AAC5E,wBAAgB,8BAA8B,IAAI,IAAI,CAErD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"userflowCore.d.ts","sourceRoot":"","sources":["../../../../../src/runtime/userflowCore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"userflowCore.d.ts","sourceRoot":"","sources":["../../../../../src/runtime/userflowCore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAWnD,wBAAgB,eAAe,IAAI,YAAY,CAE9C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TooltipSurface.d.ts","sourceRoot":"","sources":["../../../../../src/surfaces/TooltipSurface.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAGL,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EACnB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"TooltipSurface.d.ts","sourceRoot":"","sources":["../../../../../src/surfaces/TooltipSurface.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAGL,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EACnB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAiC/B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AA+CxD,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,OAAO,EAAE,mBAAmB,CAAC;IAC7B,WAAW,EAAE,gBAAgB,CAAC;IAC9B,KAAK,EAAE,aAAa,CAAC;IACrB,eAAe,EAAE,eAAe,CAAC;IACjC;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAID;;;GAGG;AACH,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAuCzC;;;GAGG;AACH,wBAAgB,cAAc,CAAC,EAC7B,MAAM,EACN,OAAO,EACP,WAAW,EACX,KAAK,EACL,eAAe,EACf,UAAc,GACf,EAAE,mBAAmB,GAAG,KAAK,CAAC,YAAY,GAAG,IAAI,CA08BjD"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { AnyFiber } from '../../anchors/fiber/fiberInternals';
|
|
2
|
+
import { type Point } from '../../anchors/fiber/presentedModal';
|
|
3
|
+
import type { Rect } from './inferTooltipPlacement';
|
|
4
|
+
/**
|
|
5
|
+
* How long "nothing is presented" is trusted on the same screen. The lookup
|
|
6
|
+
* walks the whole fiber tree (1.4ms for 2,200 fibers in a debug build), and
|
|
7
|
+
* an anchored tooltip resolves four times a second. Expo Router and native
|
|
8
|
+
* stack modals change the screen, which skips this wait; a React Native
|
|
9
|
+
* `<Modal>` over the target is noticed within it.
|
|
10
|
+
*/
|
|
11
|
+
export declare const NO_MODAL_TRUST_MS = 1000;
|
|
12
|
+
/**
|
|
13
|
+
* Where a tooltip target's measured rects sit in the window. `done` gets the
|
|
14
|
+
* window position of `(0, 0)` in the target's measure space, or null when the
|
|
15
|
+
* tooltip cannot point at it: a natively presented modal covers the target,
|
|
16
|
+
* or the target is inside a modal that cannot be placed (see
|
|
17
|
+
* `presentedModal.ts`). Also null when the target has no fiber to place.
|
|
18
|
+
*
|
|
19
|
+
* Without the window host, flow chrome is drawn in the root view under any
|
|
20
|
+
* native modal, as before, and `done` runs synchronously with zero.
|
|
21
|
+
*/
|
|
22
|
+
export declare function locateTargetOrigin(fiber: AnyFiber | null, done: (origin: Point | null) => void): void;
|
|
23
|
+
export declare function offsetRect(rect: Rect, origin: Point): Rect;
|
|
24
|
+
/** @internal Forgets the cached "nothing is presented" between tests. */
|
|
25
|
+
export declare function resetTargetOriginForTests(): void;
|
|
26
|
+
//# sourceMappingURL=targetOrigin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"targetOrigin.d.ts","sourceRoot":"","sources":["../../../../../../src/surfaces/tooltip/targetOrigin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAC;AACnE,OAAO,EAGL,KAAK,KAAK,EACX,MAAM,oCAAoC,CAAC;AAI5C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAIpD;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,OAAO,CAAC;AAItC;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,QAAQ,GAAG,IAAI,EACtB,IAAI,EAAE,CAAC,MAAM,EAAE,KAAK,GAAG,IAAI,KAAK,IAAI,GACnC,IAAI,CAyBN;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,GAAG,IAAI,CAG1D;AAED,yEAAyE;AACzE,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@userflow-tech/react-native",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Userflow SDK for React Native — onboarding flows, tooltips, and modals.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"main": "./lib/commonjs/index.js",
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
"build": "node ../../scripts/write-version.mjs SDK_VERSION && bob build",
|
|
80
80
|
"test": "jest",
|
|
81
81
|
"lint": "eslint src",
|
|
82
|
-
"typecheck": "tsc --noEmit",
|
|
82
|
+
"typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.typetests.json",
|
|
83
83
|
"pretest": "node ../../scripts/write-version.mjs SDK_VERSION",
|
|
84
84
|
"prepack": "node ../../scripts/prepare-sdk-pack.mjs",
|
|
85
85
|
"postpack": "node ../../scripts/restore-sdk-pack.mjs",
|
|
@@ -94,8 +94,8 @@
|
|
|
94
94
|
"react-native": ">=0.76.0",
|
|
95
95
|
"react-native-device-info": ">=11.0.0 <16.0.0",
|
|
96
96
|
"react-native-safe-area-context": ">=4.0.0 <6.0.0",
|
|
97
|
-
"react-native-view-shot": "^5.0.0",
|
|
98
|
-
"react-native-webview": ">=13.8.0 <
|
|
97
|
+
"react-native-view-shot": "^5.0.0 || ^6.0.0",
|
|
98
|
+
"react-native-webview": ">=13.8.0 <15.0.0"
|
|
99
99
|
},
|
|
100
100
|
"peerDependenciesMeta": {
|
|
101
101
|
"@react-native-community/netinfo": {
|
|
@@ -133,6 +133,7 @@
|
|
|
133
133
|
"@userflow-tech/eslint-config": "workspace:*",
|
|
134
134
|
"@userflow-tech/tsconfig": "workspace:*",
|
|
135
135
|
"babel-jest": "^29.7.0",
|
|
136
|
+
"expo-constants": "~57.0.19",
|
|
136
137
|
"expo-router": "^5.1.0",
|
|
137
138
|
"jest": "^29.7.0",
|
|
138
139
|
"react": "19.1.0",
|
|
@@ -15,6 +15,14 @@ export interface AnchorHost {
|
|
|
15
15
|
node?: object | null;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* The view instance an anchor ref receives. Structural rather than `View`,
|
|
20
|
+
* which React Native 0.88 types as a function component, not an instance.
|
|
21
|
+
*/
|
|
22
|
+
export interface MeasurableNode {
|
|
23
|
+
measureInWindow: AnchorHost['measureInWindow'];
|
|
24
|
+
}
|
|
25
|
+
|
|
18
26
|
type Listener = () => void;
|
|
19
27
|
|
|
20
28
|
/**
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import type { NativeScrollEvent, NativeSyntheticEvent
|
|
1
|
+
import type { NativeScrollEvent, NativeSyntheticEvent } from 'react-native';
|
|
2
2
|
|
|
3
3
|
import type { Rect } from '../surfaces/tooltip/inferTooltipPlacement';
|
|
4
4
|
|
|
5
|
+
import type { MeasurableNode } from './AnchorRegistry';
|
|
6
|
+
|
|
5
7
|
/** Padding applied when scrolling a target into the visible region of a container. */
|
|
6
8
|
const INTO_VIEW_PADDING = 24;
|
|
7
9
|
|
|
@@ -13,6 +15,16 @@ export interface ScrollContainerHost {
|
|
|
13
15
|
scrollTo: (options: { x?: number; y?: number; animated?: boolean }) => void;
|
|
14
16
|
}
|
|
15
17
|
|
|
18
|
+
/**
|
|
19
|
+
* The ScrollView instance a scroll container ref receives. Structural rather
|
|
20
|
+
* than `ScrollView`, which React Native 0.88 types as a function component.
|
|
21
|
+
* Older React Native types leave measureInWindow off the ScrollView instance,
|
|
22
|
+
* so it is not required here.
|
|
23
|
+
*/
|
|
24
|
+
export interface ScrollContainerNode {
|
|
25
|
+
scrollTo: ScrollContainerHost['scrollTo'];
|
|
26
|
+
}
|
|
27
|
+
|
|
16
28
|
type Listener = () => void;
|
|
17
29
|
|
|
18
30
|
/**
|
|
@@ -90,10 +102,10 @@ export const scrollContainerRegistry = new ScrollContainerRegistry();
|
|
|
90
102
|
|
|
91
103
|
/** Build a host from a live ScrollView + tracked content offset. */
|
|
92
104
|
export function createScrollContainerHost(
|
|
93
|
-
node:
|
|
105
|
+
node: ScrollContainerNode,
|
|
94
106
|
getContentOffset: () => { x: number; y: number },
|
|
95
107
|
): ScrollContainerHost {
|
|
96
|
-
const measurable = node as
|
|
108
|
+
const measurable = node as ScrollContainerNode & MeasurableNode;
|
|
97
109
|
return {
|
|
98
110
|
measureInWindow: (callback) => {
|
|
99
111
|
measurable.measureInWindow(callback);
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a natively presented modal sits in the window.
|
|
3
|
+
*
|
|
4
|
+
* Fabric measures and hit-tests content inside a react-native-screens modal
|
|
5
|
+
* screen (`RNSModalScreen`) or a React Native `<Modal>` relative to the modal,
|
|
6
|
+
* not the window: both shadow nodes are `RootNodeKind`, and the native side
|
|
7
|
+
* reports only their size. That is the window for full-screen presentations,
|
|
8
|
+
* but a page sheet or form sheet starts below the top of the window, so window
|
|
9
|
+
* points and measured rects disagree by the sheet's origin.
|
|
10
|
+
*
|
|
11
|
+
* The SDK has no native code to ask UIKit where the sheet is, so the origin is
|
|
12
|
+
* derived from sizes: a sheet as wide as the window is anchored to its bottom.
|
|
13
|
+
* Measured on iOS 17.4 and 26.5 and an iPadOS 26.5 portrait iPad: page sheets
|
|
14
|
+
* at 852 − 783 = 69, 874 − 812 = 62 and 1210 − 1104 = 106, a `fitToContents`
|
|
15
|
+
* form sheet at 852 − 424 = 428.
|
|
16
|
+
*
|
|
17
|
+
* A narrower sheet (an iPad form sheet) cannot be placed from sizes. One
|
|
18
|
+
* measured 580×376 on a 834×1210 window sat at y = 549, neither centered (417)
|
|
19
|
+
* nor bottom-anchored (834): its detent is anchored inside a taller container
|
|
20
|
+
* the shadow tree never sees. It gets no origin, so picks on it fail closed.
|
|
21
|
+
*
|
|
22
|
+
* Only a sheet at its full-height detent is reliably on the bottom edge. A
|
|
23
|
+
* shorter one is not, in two cases, and also gets no origin:
|
|
24
|
+
* - From iOS 26 it floats. On iOS 26.5 the `fitToContents` trade ticket
|
|
25
|
+
* measured 402×424 on a 402×874 window, but UIKit drew it about 8pt in from
|
|
26
|
+
* the sides and bottom at about 0.96 scale, so a bottom-anchored origin was
|
|
27
|
+
* up to 8pt off. Page sheets there stay edge to edge (origin 62, exact).
|
|
28
|
+
* - While the keyboard is up, a sheet that fits above the keyboard may have
|
|
29
|
+
* been lifted to clear it. One that is taller than the space above the
|
|
30
|
+
* keyboard was not: on iOS 26.5 a page sheet stayed at 62 with a 335pt
|
|
31
|
+
* keyboard, and on iOS 17.4 the trade ticket grew from 424 to 715 under a
|
|
32
|
+
* 291pt keyboard and stayed on the bottom edge (852 − 715 = 137, exact).
|
|
33
|
+
*
|
|
34
|
+
* Paper measures with UIKit, in window coordinates, so its origin is zero.
|
|
35
|
+
* Outside iOS the modal is measured where it sits, as before this lookup.
|
|
36
|
+
*/
|
|
37
|
+
import { Dimensions, Keyboard, Platform } from 'react-native';
|
|
38
|
+
|
|
39
|
+
import type { AnyFiber } from './fiberInternals';
|
|
40
|
+
import { measureHostFiber } from './measureHostFiber';
|
|
41
|
+
import { fiberIsUnder, topmostVisibleModalHost } from './visibleRect';
|
|
42
|
+
|
|
43
|
+
export interface Point {
|
|
44
|
+
x: number;
|
|
45
|
+
y: number;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface Size {
|
|
49
|
+
width: number;
|
|
50
|
+
height: number;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface PresentedModal {
|
|
54
|
+
/** `RNSModalScreen`, or React Native's `ModalHostView`. */
|
|
55
|
+
host: AnyFiber;
|
|
56
|
+
/**
|
|
57
|
+
* Window position of `(0, 0)` in the space the modal's content is measured
|
|
58
|
+
* and hit-tested in. Null when the modal cannot be placed.
|
|
59
|
+
*/
|
|
60
|
+
origin: Point | null;
|
|
61
|
+
/** The modal's size, when it was measured (iOS Fabric only). */
|
|
62
|
+
size: Size | null;
|
|
63
|
+
/** True on iOS Fabric, where that space is the modal's own rather than the window's. */
|
|
64
|
+
modalSpace: boolean;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const ZERO: Point = { x: 0, y: 0 };
|
|
68
|
+
|
|
69
|
+
const MEASURE_TIMEOUT_MS = 400;
|
|
70
|
+
|
|
71
|
+
/** Layout sizes are fractional and may miss the window size by a hair. */
|
|
72
|
+
const SIZE_SLACK = 1;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* A sheet whose top is within this fraction of the window height is at its
|
|
76
|
+
* full-height detent. Measured: 69/852 (iOS 17.4), 62/874 (iOS 26.5) and
|
|
77
|
+
* 106/1210 (iPadOS 26.5). Medium and `fitToContents` detents start far lower.
|
|
78
|
+
*/
|
|
79
|
+
const FULL_HEIGHT_SHEET_MAX_TOP = 0.15;
|
|
80
|
+
|
|
81
|
+
/** First iOS release that floats sheets shorter than full height. */
|
|
82
|
+
const FLOATING_SHEETS_IOS = 26;
|
|
83
|
+
|
|
84
|
+
function isFabric(): boolean {
|
|
85
|
+
const manager = (globalThis as { nativeFabricUIManager?: unknown }).nativeFabricUIManager;
|
|
86
|
+
return manager != null && typeof manager === 'object';
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function readWindowSize(): Size | null {
|
|
90
|
+
try {
|
|
91
|
+
const { width, height } = Dimensions.get('window');
|
|
92
|
+
if (width > 0 && height > 0) return { width, height };
|
|
93
|
+
} catch {
|
|
94
|
+
// Tests and odd hosts.
|
|
95
|
+
}
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function floatsShortSheets(): boolean {
|
|
100
|
+
const major = parseInt(String(Platform.Version), 10);
|
|
101
|
+
return Number.isFinite(major) && major >= FLOATING_SHEETS_IOS;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** Window y of the keyboard's top edge, or null when it is down. Unknown counts as up at the bottom. */
|
|
105
|
+
function keyboardTop(windowSize: Size): number | null {
|
|
106
|
+
try {
|
|
107
|
+
if (typeof Keyboard?.isVisible !== 'function' || !Keyboard.isVisible()) return null;
|
|
108
|
+
const metrics = typeof Keyboard.metrics === 'function' ? Keyboard.metrics() : undefined;
|
|
109
|
+
return metrics && metrics.height > 0 ? metrics.screenY : windowSize.height;
|
|
110
|
+
} catch {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function measureSize(fiber: AnyFiber): Promise<Size | null> {
|
|
116
|
+
return new Promise((resolve) => {
|
|
117
|
+
let settled = false;
|
|
118
|
+
const timer = setTimeout(() => {
|
|
119
|
+
if (settled) return;
|
|
120
|
+
settled = true;
|
|
121
|
+
resolve(null);
|
|
122
|
+
}, MEASURE_TIMEOUT_MS);
|
|
123
|
+
try {
|
|
124
|
+
measureHostFiber(fiber, (_x, _y, width, height) => {
|
|
125
|
+
if (settled) return;
|
|
126
|
+
settled = true;
|
|
127
|
+
clearTimeout(timer);
|
|
128
|
+
resolve(width > 0 && height > 0 ? { width, height } : null);
|
|
129
|
+
});
|
|
130
|
+
} catch {
|
|
131
|
+
if (settled) return;
|
|
132
|
+
settled = true;
|
|
133
|
+
clearTimeout(timer);
|
|
134
|
+
resolve(null);
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Window origin of a presented modal of `size`, bottom-anchored. Null when it
|
|
141
|
+
* is narrower than the window (see above) or does not fit in it, as
|
|
142
|
+
* mid-rotation.
|
|
143
|
+
*/
|
|
144
|
+
export function modalOriginInWindow(size: Size, windowSize: Size): Point | null {
|
|
145
|
+
if (size.width <= 0 || size.height <= 0) return null;
|
|
146
|
+
if (size.width > windowSize.width + SIZE_SLACK || size.height > windowSize.height + SIZE_SLACK) {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
if (size.width < windowSize.width - SIZE_SLACK) return null;
|
|
150
|
+
return { x: 0, y: Math.max(0, windowSize.height - size.height) };
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/** {@link modalOriginInWindow}, or null when a short sheet may be off the bottom edge (see above). */
|
|
154
|
+
function placeModal(size: Size, windowSize: Size): Point | null {
|
|
155
|
+
const origin = modalOriginInWindow(size, windowSize);
|
|
156
|
+
if (!origin || origin.y <= windowSize.height * FULL_HEIGHT_SHEET_MAX_TOP) return origin;
|
|
157
|
+
if (floatsShortSheets()) return null;
|
|
158
|
+
const keyboard = keyboardTop(windowSize);
|
|
159
|
+
if (keyboard != null && size.height <= keyboard) return null;
|
|
160
|
+
return origin;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* The modal drawn on top of the app and where its content space sits in the
|
|
165
|
+
* window, or null when nothing is presented. Look it up per tap: a
|
|
166
|
+
* `fitToContents` sheet resizes as its content changes.
|
|
167
|
+
*/
|
|
168
|
+
export async function locatePresentedModal(root: AnyFiber | null): Promise<PresentedModal | null> {
|
|
169
|
+
const host = topmostVisibleModalHost(root);
|
|
170
|
+
if (!host) return null;
|
|
171
|
+
if (Platform.OS !== 'ios' || !isFabric()) {
|
|
172
|
+
return { host, origin: ZERO, size: null, modalSpace: false };
|
|
173
|
+
}
|
|
174
|
+
const size = await measureSize(host);
|
|
175
|
+
const windowSize = readWindowSize();
|
|
176
|
+
const origin = size && windowSize ? placeModal(size, windowSize) : null;
|
|
177
|
+
return { host, origin, size, modalSpace: true };
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/** True when window point `(x, y)` is outside a placed modal, on the screen it covers. */
|
|
181
|
+
export function isOutsideModal(x: number, y: number, modal: PresentedModal): boolean {
|
|
182
|
+
const { origin, size } = modal;
|
|
183
|
+
if (!origin || !size) return false;
|
|
184
|
+
return x < origin.x || y < origin.y || x > origin.x + size.width || y > origin.y + size.height;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Window position of `(0, 0)` in the space `fiber` is measured in, given what
|
|
189
|
+
* {@link locatePresentedModal} returned. Null when `modal` covers `fiber`, or
|
|
190
|
+
* `fiber` is inside a modal that cannot be placed.
|
|
191
|
+
*/
|
|
192
|
+
export function measureOriginOf(fiber: AnyFiber, modal: PresentedModal | null): Point | null {
|
|
193
|
+
if (!modal) return ZERO;
|
|
194
|
+
if (!fiberIsUnder(fiber, modal.host)) return null;
|
|
195
|
+
return modal.origin;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/** `rect`, measured in `modal`'s content space, in window coordinates. */
|
|
199
|
+
export function rectInWindow<T extends Point>(rect: T, modal: PresentedModal): T {
|
|
200
|
+
const origin = modal.origin ?? ZERO;
|
|
201
|
+
if (origin.x === 0 && origin.y === 0) return rect;
|
|
202
|
+
return { ...rect, x: rect.x + origin.x, y: rect.y + origin.y };
|
|
203
|
+
}
|
|
@@ -73,9 +73,10 @@ function nativeTagForTouch(
|
|
|
73
73
|
event: GestureResponderEvent,
|
|
74
74
|
identifier: number | string | undefined,
|
|
75
75
|
): number | undefined {
|
|
76
|
+
// Readonly: React Native 0.88 types changedTouches as a readonly array.
|
|
76
77
|
const native = event.nativeEvent as {
|
|
77
78
|
target?: unknown;
|
|
78
|
-
changedTouches?:
|
|
79
|
+
changedTouches?: ReadonlyArray<{ identifier?: number | string; target?: unknown }>;
|
|
79
80
|
};
|
|
80
81
|
if (identifier != null && native.changedTouches) {
|
|
81
82
|
const touch = native.changedTouches.find((entry) => entry.identifier === identifier);
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
} from './fiberInternals';
|
|
18
18
|
import { findScrollAncestors } from './findScrollAncestors';
|
|
19
19
|
import { measureHostFiber } from './measureHostFiber';
|
|
20
|
+
import { isFiberOnVisibleScreen } from './visibleScreens';
|
|
20
21
|
|
|
21
22
|
export interface VisibleRect {
|
|
22
23
|
x: number;
|
|
@@ -30,6 +31,9 @@ const MEASURE_TIMEOUT_MS = 400;
|
|
|
30
31
|
/** Paper and Fabric names for React Native's `<Modal>`. */
|
|
31
32
|
const MODAL_HOST_TYPES = new Set(['RCTModalHostView', 'ModalHostView']);
|
|
32
33
|
|
|
34
|
+
/** react-native-screens' iOS host for `modal`, `transparentModal`, `formSheet` and other presented screens. */
|
|
35
|
+
const SCREENS_MODAL_TYPE = 'RNSModalScreen';
|
|
36
|
+
|
|
33
37
|
type MeasureCallback = (x: number, y: number, width: number, height: number) => void;
|
|
34
38
|
|
|
35
39
|
function measureFiberRect(fiber: AnyFiber): Promise<VisibleRect | null> {
|
|
@@ -99,10 +103,12 @@ export async function clipToScrollViewports(
|
|
|
99
103
|
|
|
100
104
|
function isModalHost(fiber: AnyFiber): boolean {
|
|
101
105
|
const type = getHostTypeName(fiber);
|
|
102
|
-
return type !== undefined && MODAL_HOST_TYPES.has(type);
|
|
106
|
+
return type !== undefined && (MODAL_HOST_TYPES.has(type) || type === SCREENS_MODAL_TYPE);
|
|
103
107
|
}
|
|
104
108
|
|
|
105
109
|
function isModalVisible(fiber: AnyFiber): boolean {
|
|
110
|
+
// A presented screen stays mounted under the next one; only the top of its stack is visible.
|
|
111
|
+
if (getHostTypeName(fiber) === SCREENS_MODAL_TYPE) return isFiberOnVisibleScreen(fiber);
|
|
106
112
|
const props = getMemoizedProps(fiber);
|
|
107
113
|
if (!props) return true;
|
|
108
114
|
if (props.visible === false) return false;
|
|
@@ -110,8 +116,11 @@ function isModalVisible(fiber: AnyFiber): boolean {
|
|
|
110
116
|
}
|
|
111
117
|
|
|
112
118
|
/**
|
|
113
|
-
* The visible modal host drawn on top, or null
|
|
114
|
-
*
|
|
119
|
+
* The visible modal host drawn on top, or null: a React Native `<Modal>` or a
|
|
120
|
+
* screen react-native-screens presents natively. Later fibers win: React Native
|
|
121
|
+
* mounts a newer `<Modal>` after the previous one, a native stack's newest
|
|
122
|
+
* screen is its last child, and a modal presented from inside another one sits
|
|
123
|
+
* deeper in the tree.
|
|
115
124
|
*/
|
|
116
125
|
export function topmostVisibleModalHost(root: AnyFiber | null, maxNodes = 8_000): AnyFiber | null {
|
|
117
126
|
if (!root) return null;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import type { View } from 'react-native';
|
|
3
2
|
|
|
4
|
-
import { anchorRegistry, type AnchorHost } from './AnchorRegistry';
|
|
3
|
+
import { anchorRegistry, type AnchorHost, type MeasurableNode } from './AnchorRegistry';
|
|
5
4
|
|
|
6
5
|
/**
|
|
7
6
|
* Register a view as a manual Userflow tooltip / embed target.
|
|
@@ -29,7 +28,7 @@ import { anchorRegistry, type AnchorHost } from './AnchorRegistry';
|
|
|
29
28
|
*
|
|
30
29
|
* Phase 3 resolves targets via `step.selector.css` (leading `#` stripped).
|
|
31
30
|
*/
|
|
32
|
-
export function useUserflowAnchor(id: string): React.RefCallback<
|
|
31
|
+
export function useUserflowAnchor(id: string): React.RefCallback<MeasurableNode> {
|
|
33
32
|
const hostRef = React.useRef<AnchorHost | null>(null);
|
|
34
33
|
const idRef = React.useRef(id);
|
|
35
34
|
|
|
@@ -55,7 +54,7 @@ export function useUserflowAnchor(id: string): React.RefCallback<View> {
|
|
|
55
54
|
};
|
|
56
55
|
}, []);
|
|
57
56
|
|
|
58
|
-
return React.useCallback((node:
|
|
57
|
+
return React.useCallback((node: MeasurableNode | null) => {
|
|
59
58
|
const previous = hostRef.current;
|
|
60
59
|
const currentId = idRef.current;
|
|
61
60
|
if (previous) {
|
|
@@ -73,7 +72,7 @@ export function useUserflowAnchor(id: string): React.RefCallback<View> {
|
|
|
73
72
|
},
|
|
74
73
|
node,
|
|
75
74
|
scrollIntoView: () => {
|
|
76
|
-
const scrollable = node as
|
|
75
|
+
const scrollable = node as MeasurableNode & {
|
|
77
76
|
scrollIntoView?: (options?: { block?: string; inline?: string }) => void;
|
|
78
77
|
};
|
|
79
78
|
if (typeof scrollable.scrollIntoView === 'function') {
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import type { NativeScrollEvent, NativeSyntheticEvent
|
|
2
|
+
import type { NativeScrollEvent, NativeSyntheticEvent } from 'react-native';
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
5
|
createScrollContainerHost,
|
|
6
6
|
scrollContainerRegistry,
|
|
7
7
|
type ScrollContainerHost,
|
|
8
|
+
type ScrollContainerNode,
|
|
8
9
|
} from './ScrollContainerRegistry';
|
|
9
10
|
|
|
10
11
|
export interface UserflowScrollContainerProps {
|
|
11
12
|
/** Attach to the host ScrollView (or merge with an existing ref). */
|
|
12
|
-
ref: React.RefCallback<
|
|
13
|
+
ref: React.RefCallback<ScrollContainerNode>;
|
|
13
14
|
/** Forward to ScrollView so content offsets stay in sync for scroll-into-view. */
|
|
14
15
|
onScroll: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
|
|
15
16
|
/** Required for frequent offset updates while scrolling. */
|
|
@@ -42,7 +43,7 @@ export function useUserflowScrollContainer(
|
|
|
42
43
|
onScrollProp?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void,
|
|
43
44
|
): UserflowScrollContainerProps {
|
|
44
45
|
const hostRef = React.useRef<ScrollContainerHost | null>(null);
|
|
45
|
-
const nodeRef = React.useRef<
|
|
46
|
+
const nodeRef = React.useRef<ScrollContainerNode | null>(null);
|
|
46
47
|
const offsetRef = React.useRef({ x: 0, y: 0 });
|
|
47
48
|
|
|
48
49
|
React.useEffect(() => {
|
|
@@ -55,7 +56,7 @@ export function useUserflowScrollContainer(
|
|
|
55
56
|
};
|
|
56
57
|
}, []);
|
|
57
58
|
|
|
58
|
-
const ref = React.useCallback((node:
|
|
59
|
+
const ref = React.useCallback((node: ScrollContainerNode | null) => {
|
|
59
60
|
const previous = hostRef.current;
|
|
60
61
|
if (previous) {
|
|
61
62
|
scrollContainerRegistry.unregister(previous);
|