@rocapine/react-native-onboarding-ui 1.1.1 → 1.1.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.
package/package.json
CHANGED
|
@@ -14,15 +14,13 @@ type ContentProps = {
|
|
|
14
14
|
const MediaContentRendererBase = ({ step, onContinue, theme = defaultTheme }: ContentProps) => {
|
|
15
15
|
// Validate the schema
|
|
16
16
|
const validatedData = MediaContentStepTypeSchema.parse(step);
|
|
17
|
-
const { mediaSource, title, description } = validatedData.payload;
|
|
17
|
+
const { mediaSource, title, description, layoutStyle = "default" } = validatedData.payload;
|
|
18
18
|
|
|
19
19
|
const renderMedia = () => {
|
|
20
20
|
if (mediaSource.type === "image") {
|
|
21
|
-
// Check if it's a local path or URL
|
|
22
21
|
if ("localPathId" in mediaSource) {
|
|
23
|
-
// TODO: Map localPathId to actual local image path
|
|
24
22
|
return (
|
|
25
|
-
<View style={[styles.mediaPlaceholder, { backgroundColor: theme.colors.neutral.lowest }]}>
|
|
23
|
+
<View style={[styles.mediaContainer, styles.mediaPlaceholder, { backgroundColor: theme.colors.neutral.lowest }]}>
|
|
26
24
|
<Text style={[getTextStyle(theme, "body"), styles.placeholderText, { color: theme.colors.text.disable }]}>
|
|
27
25
|
Image: {mediaSource.localPathId}
|
|
28
26
|
</Text>
|
|
@@ -30,36 +28,92 @@ const MediaContentRendererBase = ({ step, onContinue, theme = defaultTheme }: Co
|
|
|
30
28
|
);
|
|
31
29
|
} else if ("url" in mediaSource) {
|
|
32
30
|
return (
|
|
33
|
-
<
|
|
34
|
-
source={{ uri: mediaSource.url }}
|
|
35
|
-
|
|
36
|
-
resizeMode="cover"
|
|
37
|
-
/>
|
|
31
|
+
<View style={styles.mediaContainer}>
|
|
32
|
+
<Image source={{ uri: mediaSource.url }} style={styles.mediaImage} resizeMode="cover" />
|
|
33
|
+
</View>
|
|
38
34
|
);
|
|
39
35
|
}
|
|
40
36
|
} else if (mediaSource.type === "lottie") {
|
|
41
|
-
// TODO: Implement Lottie animation support
|
|
42
37
|
return (
|
|
43
|
-
<View style={[styles.mediaPlaceholder, { backgroundColor: theme.colors.neutral.lowest }]}>
|
|
38
|
+
<View style={[styles.mediaContainer, styles.mediaPlaceholder, { backgroundColor: theme.colors.neutral.lowest }]}>
|
|
44
39
|
<Text style={[getTextStyle(theme, "body"), styles.placeholderText, { color: theme.colors.text.disable }]}>Lottie Animation</Text>
|
|
45
40
|
</View>
|
|
46
41
|
);
|
|
47
42
|
} else if (mediaSource.type === "rive") {
|
|
48
|
-
// Rive animation placeholder
|
|
49
43
|
return (
|
|
50
|
-
<View style={[styles.mediaPlaceholder, { backgroundColor: theme.colors.neutral.lowest }]}>
|
|
44
|
+
<View style={[styles.mediaContainer, styles.mediaPlaceholder, { backgroundColor: theme.colors.neutral.lowest }]}>
|
|
51
45
|
<Text style={[getTextStyle(theme, "body"), styles.placeholderText, { color: theme.colors.text.disable }]}>Rive Animation</Text>
|
|
52
46
|
</View>
|
|
53
47
|
);
|
|
54
48
|
}
|
|
55
49
|
|
|
56
50
|
return (
|
|
57
|
-
<View style={[styles.mediaPlaceholder, { backgroundColor: theme.colors.neutral.lowest }]}>
|
|
51
|
+
<View style={[styles.mediaContainer, styles.mediaPlaceholder, { backgroundColor: theme.colors.neutral.lowest }]}>
|
|
58
52
|
<Text style={[getTextStyle(theme, "body"), styles.placeholderText, { color: theme.colors.text.disable }]}>Media</Text>
|
|
59
53
|
</View>
|
|
60
54
|
);
|
|
61
55
|
};
|
|
62
56
|
|
|
57
|
+
const renderTextBlock = () => (
|
|
58
|
+
<>
|
|
59
|
+
<Text style={[getTextStyle(theme, "heading1"), styles.title, { color: theme.colors.text.primary }]}>{title}</Text>
|
|
60
|
+
{description && <Text style={[getTextStyle(theme, "heading3"), styles.subtitle, { color: theme.colors.text.secondary }]}>{description}</Text>}
|
|
61
|
+
</>
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
const renderContent = () => {
|
|
65
|
+
switch (layoutStyle) {
|
|
66
|
+
case "media_bottom":
|
|
67
|
+
return (
|
|
68
|
+
<ScrollView
|
|
69
|
+
contentContainerStyle={[styles.scrollContent, { paddingTop: 0 }]}
|
|
70
|
+
showsVerticalScrollIndicator={false}
|
|
71
|
+
alwaysBounceVertical={false}
|
|
72
|
+
>
|
|
73
|
+
<View style={[styles.container, styles.containerSpaceBetween]}>
|
|
74
|
+
<View style={styles.textBlock}>{renderTextBlock()}</View>
|
|
75
|
+
<View style={styles.flexSpacer} />
|
|
76
|
+
{renderMedia()}
|
|
77
|
+
</View>
|
|
78
|
+
</ScrollView>
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
case "media_top":
|
|
82
|
+
return (
|
|
83
|
+
<ScrollView
|
|
84
|
+
contentContainerStyle={styles.scrollContent}
|
|
85
|
+
showsVerticalScrollIndicator={false}
|
|
86
|
+
alwaysBounceVertical={false}
|
|
87
|
+
>
|
|
88
|
+
<View style={styles.container}>
|
|
89
|
+
{renderMedia()}
|
|
90
|
+
{renderTextBlock()}
|
|
91
|
+
</View>
|
|
92
|
+
</ScrollView>
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
case "default":
|
|
96
|
+
default:
|
|
97
|
+
return (
|
|
98
|
+
<ScrollView
|
|
99
|
+
contentContainerStyle={styles.scrollContent}
|
|
100
|
+
showsVerticalScrollIndicator={false}
|
|
101
|
+
alwaysBounceVertical={false}
|
|
102
|
+
>
|
|
103
|
+
<View style={[styles.container, styles.containerCenter]}>
|
|
104
|
+
<Text style={[getTextStyle(theme, "heading1"), styles.title, { color: theme.colors.text.primary }]}>{title}</Text>
|
|
105
|
+
{renderMedia()}
|
|
106
|
+
{description && (
|
|
107
|
+
<Text style={[getTextStyle(theme, "heading3"), styles.subtitle, { color: theme.colors.text.secondary }]}>
|
|
108
|
+
{description}
|
|
109
|
+
</Text>
|
|
110
|
+
)}
|
|
111
|
+
</View>
|
|
112
|
+
</ScrollView>
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
|
|
63
117
|
return (
|
|
64
118
|
<OnboardingTemplate
|
|
65
119
|
step={step}
|
|
@@ -67,22 +121,7 @@ const MediaContentRendererBase = ({ step, onContinue, theme = defaultTheme }: Co
|
|
|
67
121
|
theme={theme}
|
|
68
122
|
button={{ text: validatedData.continueButtonLabel }}
|
|
69
123
|
>
|
|
70
|
-
|
|
71
|
-
contentContainerStyle={styles.scrollContent}
|
|
72
|
-
showsVerticalScrollIndicator={false}
|
|
73
|
-
alwaysBounceVertical={false}
|
|
74
|
-
>
|
|
75
|
-
<View style={styles.container}>
|
|
76
|
-
{/* Title */}
|
|
77
|
-
<Text style={[getTextStyle(theme, "heading1"), styles.title, { color: theme.colors.text.primary }]}>{title}</Text>
|
|
78
|
-
|
|
79
|
-
{/* Media Content */}
|
|
80
|
-
<View style={styles.mediaContainer}>{renderMedia()}</View>
|
|
81
|
-
|
|
82
|
-
{/* Description/Subtitle */}
|
|
83
|
-
{description && <Text style={[getTextStyle(theme, "heading3"), styles.subtitle, { color: theme.colors.text.secondary }]}>{description}</Text>}
|
|
84
|
-
</View>
|
|
85
|
-
</ScrollView>
|
|
124
|
+
{renderContent()}
|
|
86
125
|
</OnboardingTemplate>
|
|
87
126
|
);
|
|
88
127
|
};
|
|
@@ -99,13 +138,28 @@ const styles = StyleSheet.create({
|
|
|
99
138
|
gap: 24,
|
|
100
139
|
alignItems: "center",
|
|
101
140
|
},
|
|
141
|
+
containerCenter: {
|
|
142
|
+
justifyContent: "center",
|
|
143
|
+
},
|
|
144
|
+
containerSpaceBetween: {
|
|
145
|
+
justifyContent: "flex-start",
|
|
146
|
+
paddingTop: 32,
|
|
147
|
+
},
|
|
148
|
+
flexSpacer: {
|
|
149
|
+
flex: 0.4,
|
|
150
|
+
},
|
|
151
|
+
textBlock: {
|
|
152
|
+
gap: 8,
|
|
153
|
+
alignItems: "center",
|
|
154
|
+
width: "100%",
|
|
155
|
+
},
|
|
102
156
|
title: {
|
|
103
157
|
textAlign: "center",
|
|
104
158
|
letterSpacing: -0.76,
|
|
105
159
|
},
|
|
106
160
|
mediaContainer: {
|
|
107
161
|
width: "100%",
|
|
108
|
-
|
|
162
|
+
aspectRatio: 1,
|
|
109
163
|
borderRadius: 32,
|
|
110
164
|
overflow: "hidden",
|
|
111
165
|
},
|
|
@@ -5,11 +5,16 @@ import {
|
|
|
5
5
|
SocialProofSchema,
|
|
6
6
|
} from "../types";
|
|
7
7
|
|
|
8
|
+
export const MediaContentLayoutStyleSchema = z
|
|
9
|
+
.enum(["default", "media_top", "media_bottom"])
|
|
10
|
+
.default("default");
|
|
11
|
+
|
|
8
12
|
export const MediaContentStepPayloadSchema = z.object({
|
|
9
13
|
mediaSource: MediaSourceSchema,
|
|
10
14
|
title: z.string(),
|
|
11
15
|
description: z.string().nullish(),
|
|
12
16
|
socialProof: SocialProofSchema.nullish(),
|
|
17
|
+
layoutStyle: MediaContentLayoutStyleSchema.optional(),
|
|
13
18
|
});
|
|
14
19
|
|
|
15
20
|
export const MediaContentStepTypeSchema = z.object({
|