@umituz/react-native-onboarding 2.6.7 → 2.6.9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-onboarding",
3
- "version": "2.6.7",
3
+ "version": "2.6.9",
4
4
  "description": "Advanced onboarding flow for React Native apps with personalization questions, theme-aware colors, animations, and customizable slides. SOLID, DRY, KISS principles applied.",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -0,0 +1,173 @@
1
+ /**
2
+ * Onboarding Screen Content Component
3
+ * Single Responsibility: Render onboarding screen content (header, slide, footer)
4
+ */
5
+
6
+ import React from "react";
7
+ import { View, StyleSheet, StatusBar } from "react-native";
8
+ import { LinearGradient } from "expo-linear-gradient";
9
+ import { useTheme } from "@umituz/react-native-design-system-theme";
10
+ import type { OnboardingSlide } from "../../domain/entities/OnboardingSlide";
11
+ import { OnboardingHeader } from "./OnboardingHeader";
12
+ import { OnboardingSlide as OnboardingSlideComponent } from "./OnboardingSlide";
13
+ import { QuestionSlide } from "./QuestionSlide";
14
+ import { OnboardingFooter } from "./OnboardingFooter";
15
+
16
+ export interface OnboardingScreenContentProps {
17
+ containerStyle?: any;
18
+ useGradient: boolean;
19
+ currentSlide: OnboardingSlide | undefined;
20
+ isFirstSlide: boolean;
21
+ isLastSlide: boolean;
22
+ currentIndex: number;
23
+ totalSlides: number;
24
+ currentAnswer: any;
25
+ isAnswerValid: boolean;
26
+ showBackButton: boolean;
27
+ showSkipButton: boolean;
28
+ showProgressBar: boolean;
29
+ showDots: boolean;
30
+ showProgressText: boolean;
31
+ skipButtonText?: string;
32
+ nextButtonText?: string;
33
+ getStartedButtonText?: string;
34
+ onBack: () => void;
35
+ onSkip: () => void;
36
+ onNext: () => void;
37
+ onAnswerChange: (value: any) => void;
38
+ renderHeader?: (props: {
39
+ isFirstSlide: boolean;
40
+ onBack: () => void;
41
+ onSkip: () => void;
42
+ }) => React.ReactNode;
43
+ renderFooter?: (props: {
44
+ currentIndex: number;
45
+ totalSlides: number;
46
+ isLastSlide: boolean;
47
+ onNext: () => void;
48
+ onUpgrade?: () => void;
49
+ showPaywallOnComplete?: boolean;
50
+ }) => React.ReactNode;
51
+ renderSlide?: (slide: OnboardingSlide) => React.ReactNode;
52
+ onUpgrade?: () => void;
53
+ showPaywallOnComplete?: boolean;
54
+ SliderComponent?: React.ComponentType<{
55
+ style?: any;
56
+ minimumValue: number;
57
+ maximumValue: number;
58
+ value: number;
59
+ onValueChange: (value: number) => void;
60
+ minimumTrackTintColor?: string;
61
+ maximumTrackTintColor?: string;
62
+ thumbTintColor?: string;
63
+ step?: number;
64
+ }>;
65
+ }
66
+
67
+ export const OnboardingScreenContent: React.FC<OnboardingScreenContentProps> = ({
68
+ containerStyle,
69
+ useGradient,
70
+ currentSlide,
71
+ isFirstSlide,
72
+ isLastSlide,
73
+ currentIndex,
74
+ totalSlides,
75
+ currentAnswer,
76
+ isAnswerValid,
77
+ showBackButton,
78
+ showSkipButton,
79
+ showProgressBar,
80
+ showDots,
81
+ showProgressText,
82
+ skipButtonText,
83
+ nextButtonText,
84
+ getStartedButtonText,
85
+ onBack,
86
+ onSkip,
87
+ onNext,
88
+ onAnswerChange,
89
+ renderHeader,
90
+ renderFooter,
91
+ renderSlide,
92
+ onUpgrade,
93
+ showPaywallOnComplete,
94
+ SliderComponent,
95
+ }) => {
96
+ const { themeMode } = useTheme();
97
+
98
+ return (
99
+ <View style={[styles.container, containerStyle]}>
100
+ <StatusBar barStyle={themeMode === "dark" ? "light-content" : "dark-content"} />
101
+ {useGradient && currentSlide && (
102
+ <LinearGradient
103
+ colors={currentSlide.gradient as [string, string, ...string[]]}
104
+ start={{ x: 0, y: 0 }}
105
+ end={{ x: 1, y: 1 }}
106
+ style={StyleSheet.absoluteFill}
107
+ />
108
+ )}
109
+ {renderHeader ? (
110
+ renderHeader({
111
+ isFirstSlide,
112
+ onBack,
113
+ onSkip,
114
+ })
115
+ ) : (
116
+ <OnboardingHeader
117
+ isFirstSlide={isFirstSlide}
118
+ onBack={onBack}
119
+ onSkip={onSkip}
120
+ showBackButton={showBackButton}
121
+ showSkipButton={showSkipButton}
122
+ skipButtonText={skipButtonText}
123
+ useGradient={useGradient}
124
+ />
125
+ )}
126
+ {currentSlide &&
127
+ (renderSlide ? (
128
+ renderSlide(currentSlide)
129
+ ) : currentSlide.type === "question" && currentSlide.question ? (
130
+ <QuestionSlide
131
+ slide={currentSlide}
132
+ value={currentAnswer}
133
+ onChange={onAnswerChange}
134
+ useGradient={useGradient}
135
+ SliderComponent={SliderComponent}
136
+ />
137
+ ) : (
138
+ <OnboardingSlideComponent slide={currentSlide} useGradient={useGradient} />
139
+ ))}
140
+ {renderFooter ? (
141
+ renderFooter({
142
+ currentIndex,
143
+ totalSlides,
144
+ isLastSlide,
145
+ onNext,
146
+ onUpgrade,
147
+ showPaywallOnComplete,
148
+ })
149
+ ) : (
150
+ <OnboardingFooter
151
+ currentIndex={currentIndex}
152
+ totalSlides={totalSlides}
153
+ isLastSlide={isLastSlide}
154
+ onNext={onNext}
155
+ showProgressBar={showProgressBar}
156
+ showDots={showDots}
157
+ showProgressText={showProgressText}
158
+ nextButtonText={nextButtonText}
159
+ getStartedButtonText={getStartedButtonText}
160
+ disabled={!isAnswerValid}
161
+ useGradient={useGradient}
162
+ />
163
+ )}
164
+ </View>
165
+ );
166
+ };
167
+
168
+ const styles = StyleSheet.create({
169
+ container: {
170
+ flex: 1,
171
+ },
172
+ });
173
+
@@ -15,12 +15,24 @@ export interface QuestionRendererProps {
15
15
  question: OnboardingQuestion;
16
16
  value: any;
17
17
  onChange: (value: any) => void;
18
+ SliderComponent?: React.ComponentType<{
19
+ style?: any;
20
+ minimumValue: number;
21
+ maximumValue: number;
22
+ value: number;
23
+ onValueChange: (value: number) => void;
24
+ minimumTrackTintColor?: string;
25
+ maximumTrackTintColor?: string;
26
+ thumbTintColor?: string;
27
+ step?: number;
28
+ }>;
18
29
  }
19
30
 
20
31
  export const QuestionRenderer: React.FC<QuestionRendererProps> = ({
21
32
  question,
22
33
  value,
23
34
  onChange,
35
+ SliderComponent,
24
36
  }) => {
25
37
  switch (question.type) {
26
38
  case "single_choice":
@@ -48,11 +60,15 @@ export const QuestionRenderer: React.FC<QuestionRendererProps> = ({
48
60
  />
49
61
  );
50
62
  case "slider":
63
+ if (!SliderComponent) {
64
+ return null;
65
+ }
51
66
  return (
52
67
  <SliderQuestion
53
68
  question={question}
54
69
  value={value}
55
70
  onChange={onChange}
71
+ SliderComponent={SliderComponent}
56
72
  />
57
73
  );
58
74
  case "rating":
@@ -67,4 +83,3 @@ export const QuestionRenderer: React.FC<QuestionRendererProps> = ({
67
83
  return null;
68
84
  }
69
85
  };
70
-
@@ -15,6 +15,17 @@ export interface QuestionSlideProps {
15
15
  value: any;
16
16
  onChange: (value: any) => void;
17
17
  useGradient?: boolean;
18
+ SliderComponent?: React.ComponentType<{
19
+ style?: any;
20
+ minimumValue: number;
21
+ maximumValue: number;
22
+ value: number;
23
+ onValueChange: (value: number) => void;
24
+ minimumTrackTintColor?: string;
25
+ maximumTrackTintColor?: string;
26
+ thumbTintColor?: string;
27
+ step?: number;
28
+ }>;
18
29
  }
19
30
 
20
31
  export const QuestionSlide: React.FC<QuestionSlideProps> = ({
@@ -22,6 +33,7 @@ export const QuestionSlide: React.FC<QuestionSlideProps> = ({
22
33
  value,
23
34
  onChange,
24
35
  useGradient = false,
36
+ SliderComponent,
25
37
  }) => {
26
38
  const tokens = useAppDesignTokens();
27
39
  const styles = useMemo(() => getStyles(tokens, useGradient), [tokens, useGradient]);
@@ -36,7 +48,12 @@ export const QuestionSlide: React.FC<QuestionSlideProps> = ({
36
48
  <QuestionSlideHeader slide={slide} useGradient={useGradient} />
37
49
 
38
50
  <View style={styles.questionContainer}>
39
- <QuestionRenderer question={question} value={value} onChange={onChange} />
51
+ <QuestionRenderer
52
+ question={question}
53
+ value={value}
54
+ onChange={onChange}
55
+ SliderComponent={SliderComponent}
56
+ />
40
57
  </View>
41
58
 
42
59
  {question.validation?.required && !value && (
@@ -4,22 +4,24 @@
4
4
  */
5
5
 
6
6
  import React, { useMemo } from "react";
7
- import { View, Text, TouchableOpacity, StyleSheet } from "react-native";
7
+ import { View, Text, StyleSheet } from "react-native";
8
8
  import type { OnboardingQuestion } from "../../../domain/entities/OnboardingQuestion";
9
9
 
10
- // Lazy import slider to handle peer dependency gracefully
11
- let SliderComponent: any = null;
12
- try {
13
- // eslint-disable-next-line @typescript-eslint/no-require-imports
14
- SliderComponent = require("@react-native-community/slider").default;
15
- } catch {
16
- // Slider not available - will show fallback
17
- }
18
-
19
10
  export interface SliderQuestionProps {
20
11
  question: OnboardingQuestion;
21
12
  value: number | undefined;
22
13
  onChange: (value: number) => void;
14
+ SliderComponent: React.ComponentType<{
15
+ style?: any;
16
+ minimumValue: number;
17
+ maximumValue: number;
18
+ value: number;
19
+ onValueChange: (value: number) => void;
20
+ minimumTrackTintColor?: string;
21
+ maximumTrackTintColor?: string;
22
+ thumbTintColor?: string;
23
+ step?: number;
24
+ }>;
23
25
  }
24
26
 
25
27
  const getSliderConfig = (question: OnboardingQuestion) => {
@@ -29,87 +31,35 @@ const getSliderConfig = (question: OnboardingQuestion) => {
29
31
  return { min, max };
30
32
  };
31
33
 
32
- const SliderFallback: React.FC<{
33
- min: number;
34
- max: number;
35
- value: number;
36
- onChange: (value: number) => void;
37
- }> = ({ min, max, value, onChange }) => {
38
- const handleIncrement = () => {
39
- if (value < max) {
40
- onChange(value + 1);
41
- }
42
- };
43
-
44
- const handleDecrement = () => {
45
- if (value > min) {
46
- onChange(value - 1);
47
- }
48
- };
49
-
50
- return (
51
- <View style={styles.fallbackContainer}>
52
- <View style={styles.fallbackControls}>
53
- <TouchableOpacity
54
- style={styles.fallbackButton}
55
- onPress={handleDecrement}
56
- activeOpacity={0.7}
57
- >
58
- <Text style={styles.fallbackButtonText}>−</Text>
59
- </TouchableOpacity>
60
- <Text style={styles.fallbackValue}>{value}</Text>
61
- <TouchableOpacity
62
- style={styles.fallbackButton}
63
- onPress={handleIncrement}
64
- activeOpacity={0.7}
65
- >
66
- <Text style={styles.fallbackButtonText}>+</Text>
67
- </TouchableOpacity>
68
- </View>
69
- <View style={styles.fallbackLabels}>
70
- <Text style={styles.label}>{min}</Text>
71
- <Text style={styles.label}>{max}</Text>
72
- </View>
73
- </View>
74
- );
75
- };
76
-
77
34
  export const SliderQuestion: React.FC<SliderQuestionProps> = ({
78
35
  question,
79
36
  value,
80
37
  onChange,
38
+ SliderComponent,
81
39
  }) => {
82
40
  const { min, max } = useMemo(() => getSliderConfig(question), [question]);
83
41
  const currentValue = value ?? min;
84
42
 
85
- const sliderProps = {
86
- style: styles.slider,
87
- minimumValue: min,
88
- maximumValue: max,
89
- value: currentValue,
90
- onValueChange: onChange,
91
- minimumTrackTintColor: "#FFFFFF",
92
- maximumTrackTintColor: "rgba(255, 255, 255, 0.3)",
93
- thumbTintColor: "#FFFFFF",
94
- step: 1,
95
- };
96
-
97
43
  return (
98
44
  <View style={styles.container}>
99
45
  <View style={styles.valueContainer}>
100
46
  <Text style={styles.valueText}>{currentValue}</Text>
101
47
  </View>
102
- {SliderComponent ? (
103
- <>
104
- <SliderComponent {...sliderProps} />
105
- <View style={styles.labels}>
106
- <Text style={styles.label}>{min}</Text>
107
- <Text style={styles.label}>{max}</Text>
108
- </View>
109
- </>
110
- ) : (
111
- <SliderFallback min={min} max={max} value={currentValue} onChange={onChange} />
112
- )}
48
+ <SliderComponent
49
+ style={styles.slider}
50
+ minimumValue={min}
51
+ maximumValue={max}
52
+ value={currentValue}
53
+ onValueChange={onChange}
54
+ minimumTrackTintColor="#FFFFFF"
55
+ maximumTrackTintColor="rgba(255, 255, 255, 0.3)"
56
+ thumbTintColor="#FFFFFF"
57
+ step={1}
58
+ />
59
+ <View style={styles.labels}>
60
+ <Text style={styles.label}>{min}</Text>
61
+ <Text style={styles.label}>{max}</Text>
62
+ </View>
113
63
  </View>
114
64
  );
115
65
  };
@@ -142,39 +92,4 @@ const styles = StyleSheet.create({
142
92
  color: "rgba(255, 255, 255, 0.7)",
143
93
  fontWeight: "500",
144
94
  },
145
- fallbackContainer: {
146
- width: "100%",
147
- },
148
- fallbackControls: {
149
- flexDirection: "row",
150
- alignItems: "center",
151
- justifyContent: "center",
152
- gap: 24,
153
- },
154
- fallbackButton: {
155
- width: 60,
156
- height: 60,
157
- backgroundColor: "rgba(255, 255, 255, 0.2)",
158
- borderRadius: 30,
159
- alignItems: "center",
160
- justifyContent: "center",
161
- },
162
- fallbackButtonText: {
163
- fontSize: 48,
164
- fontWeight: "bold",
165
- color: "#FFFFFF",
166
- lineHeight: 60,
167
- },
168
- fallbackValue: {
169
- fontSize: 36,
170
- fontWeight: "bold",
171
- color: "#FFFFFF",
172
- minWidth: 80,
173
- textAlign: "center",
174
- },
175
- fallbackLabels: {
176
- flexDirection: "row",
177
- justifyContent: "space-between",
178
- marginTop: 16,
179
- },
180
95
  });
@@ -3,15 +3,14 @@
3
3
  *
4
4
  * Main onboarding screen component with theme-aware colors
5
5
  * Generic and reusable across hundreds of apps
6
- *
6
+ *
7
7
  * This component only handles UI coordination - no business logic
8
8
  */
9
9
 
10
10
  import React, { useMemo } from "react";
11
- import { View, StyleSheet, StatusBar } from "react-native";
12
- import { LinearGradient } from "expo-linear-gradient";
11
+ import { StyleSheet } from "react-native";
13
12
  import { useSafeAreaInsets } from "react-native-safe-area-context";
14
- import { useAppDesignTokens, useTheme } from "@umituz/react-native-design-system-theme";
13
+ import { useAppDesignTokens } from "@umituz/react-native-design-system-theme";
15
14
  import type { OnboardingOptions } from "../../domain/entities/OnboardingOptions";
16
15
  import { useOnboardingNavigation } from "../../infrastructure/hooks/useOnboardingNavigation";
17
16
  import { useOnboardingAnswers } from "../../infrastructure/hooks/useOnboardingAnswers";
@@ -19,10 +18,7 @@ import { useOnboardingStore } from "../../infrastructure/storage/OnboardingStore
19
18
  import { OnboardingSlideService } from "../../infrastructure/services/OnboardingSlideService";
20
19
  import { OnboardingValidationService } from "../../infrastructure/services/OnboardingValidationService";
21
20
  import { shouldUseGradient } from "../../infrastructure/utils/gradientUtils";
22
- import { OnboardingHeader } from "../components/OnboardingHeader";
23
- import { OnboardingSlide as OnboardingSlideComponent } from "../components/OnboardingSlide";
24
- import { QuestionSlide } from "../components/QuestionSlide";
25
- import { OnboardingFooter } from "../components/OnboardingFooter";
21
+ import { OnboardingScreenContent } from "../components/OnboardingScreenContent";
26
22
 
27
23
  export interface OnboardingScreenProps extends OnboardingOptions {
28
24
  /**
@@ -62,13 +58,25 @@ export interface OnboardingScreenProps extends OnboardingOptions {
62
58
  * When true, shows premium paywall before completing onboarding
63
59
  */
64
60
  showPaywallOnComplete?: boolean;
61
+
62
+ /**
63
+ * Slider component for slider questions
64
+ * Required if using slider question type
65
+ * Import from @react-native-community/slider
66
+ */
67
+ SliderComponent?: React.ComponentType<{
68
+ style?: any;
69
+ minimumValue: number;
70
+ maximumValue: number;
71
+ value: number;
72
+ onValueChange: (value: number) => void;
73
+ minimumTrackTintColor?: string;
74
+ maximumTrackTintColor?: string;
75
+ thumbTintColor?: string;
76
+ step?: number;
77
+ }>;
65
78
  }
66
79
 
67
- /**
68
- * Onboarding Screen Component
69
- *
70
- * Displays onboarding flow with theme-aware colors, animations, and navigation
71
- */
72
80
  export const OnboardingScreen: React.FC<OnboardingScreenProps> = ({
73
81
  slides,
74
82
  onComplete,
@@ -89,15 +97,14 @@ export const OnboardingScreen: React.FC<OnboardingScreenProps> = ({
89
97
  onUpgrade,
90
98
  showPaywallOnComplete = false,
91
99
  useGradient: globalUseGradient = false,
100
+ SliderComponent,
92
101
  }) => {
93
102
  const insets = useSafeAreaInsets();
94
103
  const tokens = useAppDesignTokens();
95
- const { themeMode } = useTheme();
96
104
  const onboardingStore = useOnboardingStore();
97
105
 
98
106
  // Filter slides using service
99
107
  const filteredSlides = useMemo(() => {
100
- // Safety check: if slides is undefined or empty, return empty array
101
108
  if (!slides || !Array.isArray(slides) || slides.length === 0) {
102
109
  return [];
103
110
  }
@@ -147,7 +154,6 @@ export const OnboardingScreen: React.FC<OnboardingScreenProps> = ({
147
154
  // Handle next slide
148
155
  const handleNext = async () => {
149
156
  await saveCurrentAnswer(currentSlide);
150
-
151
157
  if (isLastSlide) {
152
158
  await completeOnboarding();
153
159
  } else {
@@ -189,92 +195,52 @@ export const OnboardingScreen: React.FC<OnboardingScreenProps> = ({
189
195
  );
190
196
  }, [currentSlide, currentAnswer]);
191
197
 
192
- const styles = useMemo(
193
- () => getStyles(insets, tokens, useGradient),
194
- [insets, tokens, useGradient],
198
+ const containerStyle = useMemo(
199
+ () => [
200
+ styles.container,
201
+ {
202
+ paddingTop: insets.top,
203
+ backgroundColor: useGradient ? "transparent" : tokens.colors.backgroundPrimary,
204
+ },
205
+ ],
206
+ [insets.top, useGradient, tokens.colors.backgroundPrimary],
195
207
  );
196
208
 
197
209
  return (
198
- <View style={styles.container}>
199
- <StatusBar barStyle={themeMode === "dark" ? "light-content" : "dark-content"} />
200
- {useGradient && currentSlide && (
201
- <LinearGradient
202
- colors={currentSlide.gradient as [string, string, ...string[]]}
203
- start={{ x: 0, y: 0 }}
204
- end={{ x: 1, y: 1 }}
205
- style={StyleSheet.absoluteFill}
206
- />
207
- )}
208
- {renderHeader ? (
209
- renderHeader({
210
- isFirstSlide,
211
- onBack: handlePrevious,
212
- onSkip: handleSkip,
213
- })
214
- ) : (
215
- <OnboardingHeader
216
- isFirstSlide={isFirstSlide}
217
- onBack={handlePrevious}
218
- onSkip={handleSkip}
219
- showBackButton={showBackButton}
220
- showSkipButton={showSkipButton}
221
- skipButtonText={skipButtonText}
222
- useGradient={useGradient}
223
- />
224
- )}
225
- {currentSlide && (
226
- renderSlide ? (
227
- renderSlide(currentSlide)
228
- ) : currentSlide.type === "question" && currentSlide.question ? (
229
- <QuestionSlide
230
- slide={currentSlide}
231
- value={currentAnswer}
232
- onChange={setCurrentAnswer}
233
- useGradient={useGradient}
234
- />
235
- ) : (
236
- <OnboardingSlideComponent slide={currentSlide} useGradient={useGradient} />
237
- )
238
- )}
239
- {renderFooter ? (
240
- renderFooter({
241
- currentIndex,
242
- totalSlides: filteredSlides.length,
243
- isLastSlide,
244
- onNext: handleNext,
245
- onUpgrade,
246
- showPaywallOnComplete,
247
- })
248
- ) : (
249
- <OnboardingFooter
250
- currentIndex={currentIndex}
251
- totalSlides={filteredSlides.length}
252
- isLastSlide={isLastSlide}
253
- onNext={handleNext}
254
- showProgressBar={showProgressBar}
255
- showDots={showDots}
256
- showProgressText={showProgressText}
257
- nextButtonText={nextButtonText}
258
- getStartedButtonText={getStartedButtonText}
259
- disabled={!isAnswerValid}
260
- useGradient={useGradient}
261
- />
262
- )}
263
- </View>
210
+ <OnboardingScreenContent
211
+ containerStyle={containerStyle}
212
+ useGradient={useGradient}
213
+ currentSlide={currentSlide}
214
+ isFirstSlide={isFirstSlide}
215
+ isLastSlide={isLastSlide}
216
+ currentIndex={currentIndex}
217
+ totalSlides={filteredSlides.length}
218
+ currentAnswer={currentAnswer}
219
+ isAnswerValid={isAnswerValid}
220
+ showBackButton={showBackButton}
221
+ showSkipButton={showSkipButton}
222
+ showProgressBar={showProgressBar}
223
+ showDots={showDots}
224
+ showProgressText={showProgressText}
225
+ skipButtonText={skipButtonText}
226
+ nextButtonText={nextButtonText}
227
+ getStartedButtonText={getStartedButtonText}
228
+ onBack={handlePrevious}
229
+ onSkip={handleSkip}
230
+ onNext={handleNext}
231
+ onAnswerChange={setCurrentAnswer}
232
+ renderHeader={renderHeader}
233
+ renderFooter={renderFooter}
234
+ renderSlide={renderSlide}
235
+ onUpgrade={onUpgrade}
236
+ showPaywallOnComplete={showPaywallOnComplete}
237
+ SliderComponent={SliderComponent}
238
+ />
264
239
  );
265
240
  };
266
241
 
267
- const getStyles = (
268
- insets: { top: number },
269
- tokens: ReturnType<typeof useAppDesignTokens>,
270
- useGradient: boolean,
271
- ) =>
272
- StyleSheet.create({
273
- container: {
274
- flex: 1,
275
- paddingTop: insets.top,
276
- // Use transparent background when gradient is used, otherwise use theme background
277
- backgroundColor: useGradient ? 'transparent' : tokens.colors.backgroundPrimary,
278
- },
279
- });
280
-
242
+ const styles = StyleSheet.create({
243
+ container: {
244
+ flex: 1,
245
+ },
246
+ });