flowboard-react 0.6.1 → 0.6.3

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 (97) hide show
  1. package/README.md +168 -52
  2. package/app.plugin.js +341 -0
  3. package/bin/setup.js +427 -0
  4. package/lib/module/Flowboard.js +1 -2
  5. package/lib/module/Flowboard.js.map +1 -1
  6. package/lib/module/FlowboardProvider.js +1 -1
  7. package/lib/module/FlowboardProvider.js.map +1 -1
  8. package/lib/module/components/FlowboardFlow.js +31 -9
  9. package/lib/module/components/FlowboardFlow.js.map +1 -1
  10. package/lib/module/components/FlowboardRenderer.js +419 -85
  11. package/lib/module/components/FlowboardRenderer.js.map +1 -1
  12. package/lib/module/core/clientContext.js +10 -29
  13. package/lib/module/core/clientContext.js.map +1 -1
  14. package/lib/module/core/fontAwesome.js +2 -9
  15. package/lib/module/core/fontAwesome.js.map +1 -1
  16. package/lib/module/core/onboardingRepository.js +13 -13
  17. package/lib/module/core/onboardingRepository.js.map +1 -1
  18. package/lib/module/native/asyncStorage.js +55 -0
  19. package/lib/module/native/asyncStorage.js.map +1 -0
  20. package/lib/module/native/deviceInfo.js +46 -0
  21. package/lib/module/native/deviceInfo.js.map +1 -0
  22. package/lib/module/native/inAppReview.js +17 -0
  23. package/lib/module/native/inAppReview.js.map +1 -0
  24. package/lib/module/native/linearGradient.js +29 -0
  25. package/lib/module/native/linearGradient.js.map +1 -0
  26. package/lib/module/native/lottie.js +20 -0
  27. package/lib/module/native/lottie.js.map +1 -0
  28. package/lib/module/native/maskedView.js +26 -0
  29. package/lib/module/native/maskedView.js.map +1 -0
  30. package/lib/module/native/pagerView.js +79 -0
  31. package/lib/module/native/pagerView.js.map +1 -0
  32. package/lib/module/native/permissions.js +30 -0
  33. package/lib/module/native/permissions.js.map +1 -0
  34. package/lib/module/native/runtime.js +81 -0
  35. package/lib/module/native/runtime.js.map +1 -0
  36. package/lib/module/native/safeAreaContext.js +43 -0
  37. package/lib/module/native/safeAreaContext.js.map +1 -0
  38. package/lib/module/native/svg.js +83 -0
  39. package/lib/module/native/svg.js.map +1 -0
  40. package/lib/module/native/vectorIcons.js +41 -0
  41. package/lib/module/native/vectorIcons.js.map +1 -0
  42. package/lib/module/utils/flowboardUtils.js +4 -1
  43. package/lib/module/utils/flowboardUtils.js.map +1 -1
  44. package/lib/typescript/src/Flowboard.d.ts.map +1 -1
  45. package/lib/typescript/src/components/FlowboardFlow.d.ts.map +1 -1
  46. package/lib/typescript/src/components/FlowboardRenderer.d.ts +33 -0
  47. package/lib/typescript/src/components/FlowboardRenderer.d.ts.map +1 -1
  48. package/lib/typescript/src/core/clientContext.d.ts.map +1 -1
  49. package/lib/typescript/src/core/fontAwesome.d.ts +1 -1
  50. package/lib/typescript/src/core/fontAwesome.d.ts.map +1 -1
  51. package/lib/typescript/src/core/onboardingRepository.d.ts.map +1 -1
  52. package/lib/typescript/src/native/asyncStorage.d.ts +16 -0
  53. package/lib/typescript/src/native/asyncStorage.d.ts.map +1 -0
  54. package/lib/typescript/src/native/deviceInfo.d.ts +11 -0
  55. package/lib/typescript/src/native/deviceInfo.d.ts.map +1 -0
  56. package/lib/typescript/src/native/inAppReview.d.ts +4 -0
  57. package/lib/typescript/src/native/inAppReview.d.ts.map +1 -0
  58. package/lib/typescript/src/native/linearGradient.d.ts +3 -0
  59. package/lib/typescript/src/native/linearGradient.d.ts.map +1 -0
  60. package/lib/typescript/src/native/lottie.d.ts +3 -0
  61. package/lib/typescript/src/native/lottie.d.ts.map +1 -0
  62. package/lib/typescript/src/native/maskedView.d.ts +3 -0
  63. package/lib/typescript/src/native/maskedView.d.ts.map +1 -0
  64. package/lib/typescript/src/native/pagerView.d.ts +14 -0
  65. package/lib/typescript/src/native/pagerView.d.ts.map +1 -0
  66. package/lib/typescript/src/native/permissions.d.ts +9 -0
  67. package/lib/typescript/src/native/permissions.d.ts.map +1 -0
  68. package/lib/typescript/src/native/runtime.d.ts +13 -0
  69. package/lib/typescript/src/native/runtime.d.ts.map +1 -0
  70. package/lib/typescript/src/native/safeAreaContext.d.ts +15 -0
  71. package/lib/typescript/src/native/safeAreaContext.d.ts.map +1 -0
  72. package/lib/typescript/src/native/svg.d.ts +8 -0
  73. package/lib/typescript/src/native/svg.d.ts.map +1 -0
  74. package/lib/typescript/src/native/vectorIcons.d.ts +4 -0
  75. package/lib/typescript/src/native/vectorIcons.d.ts.map +1 -0
  76. package/lib/typescript/src/utils/flowboardUtils.d.ts.map +1 -1
  77. package/package.json +24 -19
  78. package/src/Flowboard.ts +1 -2
  79. package/src/FlowboardProvider.tsx +1 -1
  80. package/src/components/FlowboardFlow.tsx +47 -9
  81. package/src/components/FlowboardRenderer.tsx +689 -113
  82. package/src/core/clientContext.ts +10 -32
  83. package/src/core/fontAwesome.ts +2 -9
  84. package/src/core/onboardingRepository.ts +18 -13
  85. package/src/native/asyncStorage.ts +99 -0
  86. package/src/native/deviceInfo.ts +88 -0
  87. package/src/native/inAppReview.ts +34 -0
  88. package/src/native/linearGradient.tsx +24 -0
  89. package/src/native/lottie.tsx +17 -0
  90. package/src/native/maskedView.tsx +19 -0
  91. package/src/native/pagerView.tsx +95 -0
  92. package/src/native/permissions.ts +59 -0
  93. package/src/native/runtime.ts +110 -0
  94. package/src/native/safeAreaContext.tsx +44 -0
  95. package/src/native/svg.tsx +82 -0
  96. package/src/native/vectorIcons.tsx +50 -0
  97. package/src/utils/flowboardUtils.ts +9 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"svg.d.ts","sourceRoot":"","sources":["../../../../src/native/svg.tsx"],"names":[],"mappings":"AAaA,eAAO,MAAM,YAAY,SAGxB,CAAC;AAMF,MAAM,CAAC,OAAO,UAAU,GAAG,CAAC,KAAK,EAAE,GAAG,2CAcrC;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,GAAG,2CAOhC;AAED,wBAAgB,CAAC,CAAC,KAAK,EAAE,GAAG,2CAO3B;AAED,wBAAgB,IAAI,CAAC,KAAK,EAAE,GAAG,2CAO9B;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,GAAG,2CAOjC;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,GAAG,2CAOjC"}
@@ -0,0 +1,4 @@
1
+ export declare const vectorIconsNativeAvailable: boolean;
2
+ export declare function getFontAwesomeGlyphMap(): Record<string, number> | null;
3
+ export declare function FontAwesome6(props: any): import("react/jsx-runtime").JSX.Element;
4
+ //# sourceMappingURL=vectorIcons.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vectorIcons.d.ts","sourceRoot":"","sources":["../../../../src/native/vectorIcons.tsx"],"names":[],"mappings":"AASA,eAAO,MAAM,0BAA0B,SAGtC,CAAC;AAcF,wBAAgB,sBAAsB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAetE;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,GAAG,2CAMtC"}
@@ -1 +1 @@
1
- {"version":3,"file":"flowboardUtils.d.ts","sourceRoot":"","sources":["../../../../src/utils/flowboardUtils.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,MAAM,GAAG;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,MAK1B,CAAC;AAIF,wBAAgB,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,MAAM,CAiD/D;AAgBD,wBAAgB,cAAc,CAC5B,KAAK,EAAE,GAAG,EACV,UAAU,UAAQ,GACjB,MAAM,GAAG,SAAS,CAepB;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,GAAG,GAAG,MAAM,CAuB9C;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;CACrB,CAOA;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG;IACnD,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB,CAOA;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,OAAa,GAAG,MAAM,CAiBrE;AAED,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC5B,MAAM,CAMR;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC5B,GAAG,CAkDL;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,GAAG,EACV,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC5B,MAAM,GAAG,IAAI,CAqBf;AAED,wBAAgB,eAAe,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,GAAG,CA4C5D;AAED,wBAAgB,mBAAmB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,GAAG,CAWvD;AAED,wBAAgB,cAAc,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,GAAG,CAYlD;AAED,wBAAgB,kBAAkB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,GAAG,CAgBtD;AAED,wBAAgB,mBAAmB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,GAAG,CAYvD;AAED,wBAAgB,eAAe,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,GAAG,CAkBnD;AAED,wBAAgB,cAAc,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG;IAC9C,cAAc,EAAE,GAAG,CAAC;IACpB,UAAU,EAAE,GAAG,CAAC;CACjB,CAsBA"}
1
+ {"version":3,"file":"flowboardUtils.d.ts","sourceRoot":"","sources":["../../../../src/utils/flowboardUtils.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,MAAM,GAAG;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,MAK1B,CAAC;AAIF,wBAAgB,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,MAAM,CAiD/D;AAgBD,wBAAgB,cAAc,CAC5B,KAAK,EAAE,GAAG,EACV,UAAU,UAAQ,GACjB,MAAM,GAAG,SAAS,CAuBpB;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,GAAG,GAAG,MAAM,CAuB9C;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;CACrB,CAOA;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG;IACnD,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB,CAOA;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,OAAa,GAAG,MAAM,CAiBrE;AAED,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC5B,MAAM,CAMR;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC5B,GAAG,CAkDL;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,GAAG,EACV,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC5B,MAAM,GAAG,IAAI,CAqBf;AAED,wBAAgB,eAAe,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,GAAG,CA4C5D;AAED,wBAAgB,mBAAmB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,GAAG,CAWvD;AAED,wBAAgB,cAAc,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,GAAG,CAYlD;AAED,wBAAgB,kBAAkB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,GAAG,CAgBtD;AAED,wBAAgB,mBAAmB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,GAAG,CAYvD;AAED,wBAAgB,eAAe,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,GAAG,CAkBnD;AAED,wBAAgB,cAAc,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG;IAC9C,cAAc,EAAE,GAAG,CAAC;IACpB,UAAU,EAAE,GAAG,CAAC;CACjB,CAsBA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flowboard-react",
3
- "version": "0.6.1",
3
+ "version": "0.6.3",
4
4
  "description": "Onboard your users with one click",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
@@ -10,14 +10,17 @@
10
10
  "types": "./lib/typescript/src/index.d.ts",
11
11
  "default": "./lib/module/index.js"
12
12
  },
13
+ "./app.plugin.js": "./app.plugin.js",
13
14
  "./package.json": "./package.json"
14
15
  },
15
16
  "files": [
16
17
  "src",
17
18
  "lib",
19
+ "bin",
18
20
  "android",
19
21
  "ios",
20
22
  "cpp",
23
+ "app.plugin.js",
21
24
  "*.podspec",
22
25
  "react-native.config.js",
23
26
  "!ios/build",
@@ -32,8 +35,13 @@
32
35
  "!**/.*"
33
36
  ],
34
37
  "dependencies": {
35
- "expr-eval": "^2.0.2",
36
- "uuid": "^11.1.0"
38
+ "expr-eval": ">= 2.0.2 < 3",
39
+ "react-native-get-random-values": "1.11.0",
40
+ "react-native-mask-input": "1.2.3",
41
+ "uuid": ">= 8.3.2 < 12"
42
+ },
43
+ "bin": {
44
+ "flowboard-setup": "./bin/setup.js"
37
45
  },
38
46
  "scripts": {
39
47
  "example": "yarn workspace flowboard-react-example",
@@ -91,22 +99,19 @@
91
99
  "typescript": "^5.9.2"
92
100
  },
93
101
  "peerDependencies": {
94
- "@react-native-async-storage/async-storage": "^1.24.0",
95
- "@react-native-masked-view/masked-view": "^0.3.2",
96
- "lottie-react-native": "^7.1.0",
97
- "react": "*",
98
- "react-native": "*",
99
- "react-native-device-info": "^13.2.0",
100
- "react-native-gesture-handler": "^2.30.0",
101
- "react-native-get-random-values": "^1.11.0",
102
- "react-native-in-app-review": "^4.3.0",
103
- "react-native-linear-gradient": "^2.8.3",
104
- "react-native-mask-input": "^1.2.3",
105
- "react-native-pager-view": "^6.2.4",
106
- "react-native-permissions": "^4.1.5",
107
- "react-native-safe-area-context": "^5.0.0",
108
- "react-native-svg": "^15.10.1",
109
- "react-native-vector-icons": "^10.2.0"
102
+ "@react-native-async-storage/async-storage": ">= 1.24.0",
103
+ "@react-native-masked-view/masked-view": ">= 0.3.2",
104
+ "lottie-react-native": ">= 7.1.0",
105
+ "react": ">= 18.2.0",
106
+ "react-native": ">= 0.71.0",
107
+ "react-native-device-info": ">= 13.2.0",
108
+ "react-native-in-app-review": ">= 4.3.0",
109
+ "react-native-linear-gradient": ">= 2.8.3",
110
+ "react-native-pager-view": ">= 6.2.4",
111
+ "react-native-permissions": ">= 4.1.5",
112
+ "react-native-safe-area-context": ">= 5.0.0",
113
+ "react-native-svg": ">= 15.10.1",
114
+ "react-native-vector-icons": ">= 10.2.0"
110
115
  },
111
116
  "workspaces": [
112
117
  "example"
package/src/Flowboard.ts CHANGED
@@ -142,8 +142,7 @@ export class Flowboard {
142
142
  });
143
143
  } catch (error) {
144
144
  Flowboard.log(`Failed to load onboarding by id: ${String(error)}`);
145
- Alert.alert('Failed to load onboarding', String(error));
146
- return;
145
+ throw error;
147
146
  }
148
147
 
149
148
  await Flowboard.launchResolvedOnboarding(data, options);
@@ -1,8 +1,8 @@
1
1
  import React, { useEffect, useState } from 'react';
2
2
  import { Modal, StyleSheet, View } from 'react-native';
3
- import { SafeAreaProvider } from 'react-native-safe-area-context';
4
3
  import { Flowboard, type LaunchPayload } from './Flowboard';
5
4
  import FlowboardFlow from './components/FlowboardFlow';
5
+ import { SafeAreaProvider } from './native/safeAreaContext';
6
6
 
7
7
  const styles = StyleSheet.create({
8
8
  modalContainer: {
@@ -1,19 +1,22 @@
1
1
  import { useEffect, useMemo, useRef, useState } from 'react';
2
2
  import { Alert, Keyboard, Platform, StyleSheet, View } from 'react-native';
3
- import PagerView from 'react-native-pager-view';
4
3
  import { Linking } from 'react-native';
5
- import InAppReview from 'react-native-in-app-review';
6
- import { SafeAreaProvider } from 'react-native-safe-area-context';
7
4
  import {
8
5
  openSettings,
9
6
  PERMISSIONS,
10
7
  request,
11
8
  requestNotifications,
12
9
  RESULTS,
13
- } from 'react-native-permissions';
10
+ } from '../native/permissions';
14
11
  import { AssetPreloader } from '../core/assetPreloader';
15
12
  import { AnalyticsManager, OnboardingOutcome } from '../core/analyticsManager';
16
13
  import { OnboardingRepository } from '../core/onboardingRepository';
14
+ import {
15
+ requestInAppReview,
16
+ isInAppReviewAvailable,
17
+ } from '../native/inAppReview';
18
+ import PagerView, { type PagerViewHandle } from '../native/pagerView';
19
+ import { SafeAreaProvider } from '../native/safeAreaContext';
17
20
  import FlowboardRenderer from './FlowboardRenderer';
18
21
  import {
19
22
  SliderRegistry,
@@ -27,9 +30,10 @@ import type {
27
30
  OnboardingEndCallback,
28
31
  OnStepChangeCallback,
29
32
  } from '../types/flowboard';
33
+ import { parseColor } from '../utils/flowboardUtils';
30
34
 
31
35
  const styles = StyleSheet.create({
32
- container: { flex: 1, backgroundColor: '#ffffff' },
36
+ container: { flex: 1 },
33
37
  fullFlex: { flex: 1 },
34
38
  });
35
39
 
@@ -61,7 +65,7 @@ export default function FlowboardFlow(props: FlowboardFlowProps) {
61
65
  const repository = useMemo(() => new OnboardingRepository(), []);
62
66
  const assetPreloader = useMemo(() => new AssetPreloader(), []);
63
67
  const sliderRegistry = useMemo(() => new SliderRegistry(), []);
64
- const pagerRef = useRef<PagerView>(null);
68
+ const pagerRef = useRef<PagerViewHandle | null>(null);
65
69
  const [currentIndex, setCurrentIndex] = useState(() =>
66
70
  resolveInitialPage(initialStep, screens.length)
67
71
  );
@@ -77,6 +81,9 @@ export default function FlowboardFlow(props: FlowboardFlowProps) {
77
81
  const didSyncPagerRef = useRef(false);
78
82
  const completedRef = useRef(false);
79
83
  const flowStartTimeRef = useRef(Date.now());
84
+ const currentScreenData =
85
+ (screens[currentIndex] as Record<string, any> | undefined) ?? null;
86
+ const flowBackgroundColor = resolveScreenBackgroundColor(currentScreenData);
80
87
 
81
88
  useEffect(() => {
82
89
  AnalyticsManager.instance.startSession({ flowData: data });
@@ -323,8 +330,8 @@ export default function FlowboardFlow(props: FlowboardFlowProps) {
323
330
 
324
331
  const handleRateAppAction = async (index: number, totalScreens: number) => {
325
332
  try {
326
- if (InAppReview.isAvailable()) {
327
- InAppReview.RequestInAppReview();
333
+ if (isInAppReviewAvailable()) {
334
+ await requestInAppReview();
328
335
  }
329
336
  } catch {
330
337
  // ignore
@@ -406,7 +413,14 @@ export default function FlowboardFlow(props: FlowboardFlowProps) {
406
413
 
407
414
  return (
408
415
  <SafeAreaProvider>
409
- <View style={styles.container}>
416
+ <View
417
+ style={[
418
+ styles.container,
419
+ flowBackgroundColor
420
+ ? { backgroundColor: flowBackgroundColor }
421
+ : undefined,
422
+ ]}
423
+ >
410
424
  <PagerView
411
425
  ref={pagerRef}
412
426
  style={styles.fullFlex}
@@ -461,6 +475,30 @@ function resolveInitialPage(desired: number, total: number): number {
461
475
  return desired;
462
476
  }
463
477
 
478
+ function resolveScreenBackgroundColor(
479
+ screenData: Record<string, any> | null
480
+ ): string | undefined {
481
+ if (!screenData) return undefined;
482
+
483
+ const bgData = screenData.background;
484
+ if (bgData && typeof bgData === 'object') {
485
+ const type = String(bgData.type ?? '').toLowerCase();
486
+ if (type === 'color' && bgData.color !== undefined) {
487
+ return parseColor(bgData.color);
488
+ }
489
+ if (type === 'gradient' && Array.isArray(bgData.colors)) {
490
+ const first = bgData.colors[0];
491
+ if (first !== undefined) return parseColor(first);
492
+ }
493
+ }
494
+
495
+ if (screenData.backgroundColor !== undefined) {
496
+ return parseColor(screenData.backgroundColor);
497
+ }
498
+
499
+ return undefined;
500
+ }
501
+
464
502
  function validateScreen(
465
503
  screenData: Record<string, any>,
466
504
  formData: Record<string, any>