@userflow-tech/react-native 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/README.md +82 -54
  2. package/docs/troubleshooting.md +29 -23
  3. package/expo-plugin/hostDependencyWarnings.d.ts +5 -2
  4. package/expo-plugin/hostDependencyWarnings.d.ts.map +1 -1
  5. package/expo-plugin/hostDependencyWarnings.js +12 -2
  6. package/expo-plugin/hostDependencyWarnings.js.map +1 -1
  7. package/lib/commonjs/authoring/capturePickerScreenshot.js +9 -1
  8. package/lib/commonjs/authoring/capturePickerScreenshot.js.map +1 -1
  9. package/lib/commonjs/evalJs/getWebView.js +5 -13
  10. package/lib/commonjs/evalJs/getWebView.js.map +1 -1
  11. package/lib/commonjs/hostAppVersion.js +6 -1
  12. package/lib/commonjs/hostAppVersion.js.map +1 -1
  13. package/lib/commonjs/installCheck.js +61 -29
  14. package/lib/commonjs/installCheck.js.map +1 -1
  15. package/lib/commonjs/nativeModules.js +44 -0
  16. package/lib/commonjs/nativeModules.js.map +1 -0
  17. package/lib/commonjs/network.js +20 -7
  18. package/lib/commonjs/network.js.map +1 -1
  19. package/lib/commonjs/pairing/tokenStorage.js +17 -4
  20. package/lib/commonjs/pairing/tokenStorage.js.map +1 -1
  21. package/lib/commonjs/surfaces/BannerSurface.js +3 -1
  22. package/lib/commonjs/surfaces/BannerSurface.js.map +1 -1
  23. package/lib/commonjs/surfaces/safeArea.js +6 -0
  24. package/lib/commonjs/surfaces/safeArea.js.map +1 -1
  25. package/lib/commonjs/version.js +1 -1
  26. package/lib/module/authoring/capturePickerScreenshot.js +9 -1
  27. package/lib/module/authoring/capturePickerScreenshot.js.map +1 -1
  28. package/lib/module/evalJs/getWebView.js +5 -13
  29. package/lib/module/evalJs/getWebView.js.map +1 -1
  30. package/lib/module/hostAppVersion.js +6 -1
  31. package/lib/module/hostAppVersion.js.map +1 -1
  32. package/lib/module/installCheck.js +56 -26
  33. package/lib/module/installCheck.js.map +1 -1
  34. package/lib/module/nativeModules.js +40 -0
  35. package/lib/module/nativeModules.js.map +1 -0
  36. package/lib/module/network.js +20 -7
  37. package/lib/module/network.js.map +1 -1
  38. package/lib/module/pairing/tokenStorage.js +17 -4
  39. package/lib/module/pairing/tokenStorage.js.map +1 -1
  40. package/lib/module/surfaces/BannerSurface.js +3 -1
  41. package/lib/module/surfaces/BannerSurface.js.map +1 -1
  42. package/lib/module/surfaces/safeArea.js +5 -0
  43. package/lib/module/surfaces/safeArea.js.map +1 -1
  44. package/lib/module/version.js +1 -1
  45. package/lib/typescript/commonjs/src/authoring/capturePickerScreenshot.d.ts.map +1 -1
  46. package/lib/typescript/commonjs/src/evalJs/getWebView.d.ts +2 -1
  47. package/lib/typescript/commonjs/src/evalJs/getWebView.d.ts.map +1 -1
  48. package/lib/typescript/commonjs/src/hostAppVersion.d.ts +1 -1
  49. package/lib/typescript/commonjs/src/hostAppVersion.d.ts.map +1 -1
  50. package/lib/typescript/commonjs/src/installCheck.d.ts +18 -3
  51. package/lib/typescript/commonjs/src/installCheck.d.ts.map +1 -1
  52. package/lib/typescript/commonjs/src/nativeModules.d.ts +13 -0
  53. package/lib/typescript/commonjs/src/nativeModules.d.ts.map +1 -0
  54. package/lib/typescript/commonjs/src/network.d.ts.map +1 -1
  55. package/lib/typescript/commonjs/src/pairing/tokenStorage.d.ts.map +1 -1
  56. package/lib/typescript/commonjs/src/surfaces/BannerSurface.d.ts.map +1 -1
  57. package/lib/typescript/commonjs/src/surfaces/safeArea.d.ts +2 -0
  58. package/lib/typescript/commonjs/src/surfaces/safeArea.d.ts.map +1 -1
  59. package/lib/typescript/commonjs/src/version.d.ts +1 -1
  60. package/lib/typescript/module/src/authoring/capturePickerScreenshot.d.ts.map +1 -1
  61. package/lib/typescript/module/src/evalJs/getWebView.d.ts +2 -1
  62. package/lib/typescript/module/src/evalJs/getWebView.d.ts.map +1 -1
  63. package/lib/typescript/module/src/hostAppVersion.d.ts +1 -1
  64. package/lib/typescript/module/src/hostAppVersion.d.ts.map +1 -1
  65. package/lib/typescript/module/src/installCheck.d.ts +18 -3
  66. package/lib/typescript/module/src/installCheck.d.ts.map +1 -1
  67. package/lib/typescript/module/src/nativeModules.d.ts +13 -0
  68. package/lib/typescript/module/src/nativeModules.d.ts.map +1 -0
  69. package/lib/typescript/module/src/network.d.ts.map +1 -1
  70. package/lib/typescript/module/src/pairing/tokenStorage.d.ts.map +1 -1
  71. package/lib/typescript/module/src/surfaces/BannerSurface.d.ts.map +1 -1
  72. package/lib/typescript/module/src/surfaces/safeArea.d.ts +2 -0
  73. package/lib/typescript/module/src/surfaces/safeArea.d.ts.map +1 -1
  74. package/lib/typescript/module/src/version.d.ts +1 -1
  75. package/package.json +13 -8
  76. package/src/authoring/capturePickerScreenshot.ts +10 -1
  77. package/src/evalJs/getWebView.ts +6 -13
  78. package/src/hostAppVersion.ts +7 -1
  79. package/src/installCheck.ts +67 -33
  80. package/src/nativeModules.ts +48 -0
  81. package/src/network.ts +27 -11
  82. package/src/pairing/tokenStorage.ts +23 -7
  83. package/src/surfaces/BannerSurface.tsx +7 -5
  84. package/src/surfaces/safeArea.ts +5 -0
  85. package/src/version.ts +1 -1
  86. package/vendor/core/package.json +1 -1
  87. package/vendor/protocol/package.json +1 -1
  88. package/docs/webview-custom-banner-poc.md +0 -64
@@ -61,11 +61,13 @@ export function BannerSurface({
61
61
  if (!webView) {
62
62
  if (!warnedMissingWebView) {
63
63
  warnedMissingWebView = true;
64
- console.warn(
65
- 'Userflow: WebView banner requires react-native-webview in the native binary. ' +
66
- 'Add it to your app (e.g. npx expo install react-native-webview), run pod install under ios/, ' +
67
- 'then rebuild with expo run:ios (not Expo Go). Falling back to the native banner bar.',
68
- );
64
+ if (__DEV__) {
65
+ console.warn(
66
+ 'Userflow: WebView banner requires react-native-webview in the native binary. ' +
67
+ 'Add it to your app (e.g. npx expo install react-native-webview), run pod install under ios/, ' +
68
+ 'then rebuild with expo run:ios (not Expo Go). Falling back to the native banner bar.',
69
+ );
70
+ }
69
71
  }
70
72
  return <BannerBar session={session} onActions={onActions} onDismiss={onDismiss} />;
71
73
  }
@@ -48,6 +48,11 @@ function loadSafeAreaModule(): SafeAreaModule | null {
48
48
  return cachedModule;
49
49
  }
50
50
 
51
+ /** True when the optional peer's JavaScript package can be loaded. */
52
+ export function isSafeAreaContextInstalled(): boolean {
53
+ return loadSafeAreaModule() != null;
54
+ }
55
+
51
56
  function copyInsets(insets: Partial<EdgeInsets> | null | undefined): EdgeInsets | null {
52
57
  if (!insets) return null;
53
58
  const top = insets.top;
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  /** Generated by scripts/write-version.mjs — do not edit. */
2
- export const SDK_VERSION = '0.3.1';
2
+ export const SDK_VERSION = '0.4.0';
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@userflow-tech/core",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "description": "Userflow React Native SDK core — platform-agnostic engine and protocol client.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "type": "module",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@userflow-tech/protocol",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "description": "Userflow React Native SDK protocol — wire contracts and shared types.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "type": "module",
@@ -1,64 +0,0 @@
1
- # WebView banner POC (React Native)
2
-
3
- Proof of concept for React Native banners that use **Evaluate JavaScript** on buttons—the same `window.userflow` bridge and (when the WebView path is used) web banner DOM + theme **custom.css** as userflow.js on web.
4
-
5
- ## Enabling
6
-
7
- 1. **Custom CSS (theme):** Publish custom CSS in the builder (**Edit custom CSS**). When the theme has a `cssVersion`, banners use the WebView renderer and load `custom.css` from the CDN (same URL as userflow.js iframes). Use `.userflow-custom-container-<name>` on container blocks and `.userflow-custom-button-<name>` as button appearance in the builder.
8
- 2. **Evaluate JavaScript:** Use a button whose **only** action is **Evaluate JavaScript** if the script should auto-run when the WebView loads (once per banner session). Mixed-action buttons run eval on click only.
9
- 3. `react-native-webview` ships as an SDK dependency; after install or upgrade, **rebuild** the native app (`pod install` on iOS). If Metro still cannot load it, add `react-native-webview` explicitly in the host app and rebuild again.
10
-
11
- For local SDK development without custom CSS or Evaluate JavaScript, use `setDebugForceWebViewBanner` from `bannerNeedsWebView.ts` (not exported on the public `Userflow` API).
12
-
13
- Web embeds are unchanged (native userflow.js banner).
14
-
15
- ## Architecture
16
-
17
- - **Native shell:** `BannerHost` / `EmbedBannerPlaceholder` unchanged (overlay vs flow, safe area, margins, max width).
18
- - **Single WebView:** `BannerWebViewBar` renders the web DOM (`userflowjs-banner-*`, `userflowjs-bubble-button-*`) plus inlined frame CSS and a link to `https://cdn.{host}/themes/{themeId}/stylesheets/{cssVersion}/custom.css` when the theme has `cssVersion`.
19
- - **Actions:** Button clicks post to RN → `BannerSessionEngine.handleActions` → `EVAL_JS` uses the **same** WebView via `evalJsController` (overlay `EvalJsHost` is suppressed while the banner owns the page).
20
- - **Dismiss from JS:** `userflow.endFlow()` and `userflow.close()` end the **banner session** (same as the native X), not only the tour flow engine.
21
-
22
- ## Manual test checklist (iOS + Android)
23
-
24
- - [ ] Standard banner (no Evaluate JavaScript): native `BannerBar`, unchanged layout.
25
- - [ ] WebView banner: theme custom CSS applies to buttons/content (use builder theme + custom classes on buttons).
26
- - [ ] Top (`BODY_FIRST`) and bottom (`BODY_LAST`) placement; overlay on/off.
27
- - [ ] Button **Evaluate JavaScript** runs (`userflow.track`, `userflow.updateUser`, etc.).
28
- - [ ] **Auto-run on show:** Evaluate JavaScript on an **eval-only** banner button (no other actions on that button) runs when the WebView loads. TinyTime fixture: `apps/tinytime/eval-js-samples/etoro-crypto-deposit-banner-rn.js`.
29
- - [ ] Dismiss (X) ends banner with user-closed reason.
30
- - [ ] Small phone, large phone, and tablet aspect ratios—watch for clipped or extra-tall bar (height comes from WebView content measurement).
31
- - [ ] Rotation: bar height updates after orientation change.
32
-
33
- ## Findings
34
-
35
- ### Feasibility
36
-
37
- - **Works in principle:** WebView can load CDN `custom.css` and reuse web class names; eval JS reuses the existing `wrapCode` / `window.userflow` bridge.
38
- - **Gaps vs web:** Rich content HTML export is a **subset** (paragraphs, headings, lists, quotes, code, links, attributes)—no images/video/button groups inside content. Button hidden/disabled conditions are not evaluated in the WebView. Fonts rely on theme `fontFamily` / custom CSS, not full web font loading.
39
-
40
- ### Layout and screen-size risks
41
-
42
- - Height is driven by content measurement on `.userflowjs-banner-root` and `ResizeObserver` when available; there can be a one-frame jump before measure completes.
43
- - `overlay: false` push layout depends on measured WebView height—verify on long copy and multiple buttons wrapping.
44
- - Safe area is applied on the **native** host, not inside the WebView document (unlike some full-screen eval JS samples).
45
-
46
- ### Single WebView / eval routing
47
-
48
- - While a WebView banner is mounted, `evalJsController.bannerOwnsWebView` prevents a second overlay WebView.
49
- - **Conflict:** A flow **Evaluate JavaScript** step running at the same time as a WebView banner would share the banner WebView—not supported in this POC.
50
-
51
- ### Security / performance
52
-
53
- - Custom CSS is fetched from the CDN at runtime (network required on first paint).
54
- - One WebView per banner session with eval JS; memory cost is acceptable for typical use but not ideal for many simultaneous surfaces.
55
-
56
- ### Follow-ups before production
57
-
58
- - Builder copy review; document unsupported banner capabilities (sticky scroll, element embed modes, condition-driven buttons).
59
- - Align with UMD-166 (banner component) and UMD-168 (banner eval extension).
60
- - Optional: ship compiled `bubble-frame` CSS from CDN instead of bundled subset.
61
-
62
- ## Customer sample fixtures
63
-
64
- When validating against a specific customer banner, paste their theme **custom.css** and button **Evaluate JavaScript** into the builder test flow and attach the same snippets to the Jira ticket for regression reference.