@rocapine/react-native-onboarding-ui 1.0.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 (275) hide show
  1. package/dist/UI/Components/CircularProgress.d.ts +8 -0
  2. package/dist/UI/Components/CircularProgress.d.ts.map +1 -0
  3. package/dist/UI/Components/CircularProgress.js +104 -0
  4. package/dist/UI/Components/CircularProgress.js.map +1 -0
  5. package/dist/UI/Components/ProgressBar.d.ts +12 -0
  6. package/dist/UI/Components/ProgressBar.d.ts.map +1 -0
  7. package/dist/UI/Components/ProgressBar.js +121 -0
  8. package/dist/UI/Components/ProgressBar.js.map +1 -0
  9. package/dist/UI/Components/StaggeredTextList.d.ts +11 -0
  10. package/dist/UI/Components/StaggeredTextList.d.ts.map +1 -0
  11. package/dist/UI/Components/StaggeredTextList.js +111 -0
  12. package/dist/UI/Components/StaggeredTextList.js.map +1 -0
  13. package/dist/UI/Components/index.d.ts +4 -0
  14. package/dist/UI/Components/index.d.ts.map +1 -0
  15. package/dist/UI/Components/index.js +20 -0
  16. package/dist/UI/Components/index.js.map +1 -0
  17. package/dist/UI/ErrorBoundary/ErrorBoundary.d.ts +19 -0
  18. package/dist/UI/ErrorBoundary/ErrorBoundary.d.ts.map +1 -0
  19. package/dist/UI/ErrorBoundary/ErrorBoundary.js +123 -0
  20. package/dist/UI/ErrorBoundary/ErrorBoundary.js.map +1 -0
  21. package/dist/UI/ErrorBoundary/index.d.ts +3 -0
  22. package/dist/UI/ErrorBoundary/index.d.ts.map +1 -0
  23. package/dist/UI/ErrorBoundary/index.js +8 -0
  24. package/dist/UI/ErrorBoundary/index.js.map +1 -0
  25. package/dist/UI/ErrorBoundary/withErrorBoundary.d.ts +6 -0
  26. package/dist/UI/ErrorBoundary/withErrorBoundary.d.ts.map +1 -0
  27. package/dist/UI/ErrorBoundary/withErrorBoundary.js +13 -0
  28. package/dist/UI/ErrorBoundary/withErrorBoundary.js.map +1 -0
  29. package/dist/UI/OnboardingPage.d.ts +16 -0
  30. package/dist/UI/OnboardingPage.d.ts.map +1 -0
  31. package/dist/UI/OnboardingPage.js +38 -0
  32. package/dist/UI/OnboardingPage.js.map +1 -0
  33. package/dist/UI/Pages/Carousel/Renderer.d.ts +13 -0
  34. package/dist/UI/Pages/Carousel/Renderer.d.ts.map +1 -0
  35. package/dist/UI/Pages/Carousel/Renderer.js +121 -0
  36. package/dist/UI/Pages/Carousel/Renderer.js.map +1 -0
  37. package/dist/UI/Pages/Carousel/index.d.ts +3 -0
  38. package/dist/UI/Pages/Carousel/index.d.ts.map +1 -0
  39. package/dist/UI/Pages/Carousel/index.js +19 -0
  40. package/dist/UI/Pages/Carousel/index.js.map +1 -0
  41. package/dist/UI/Pages/Carousel/types.d.ts +32 -0
  42. package/dist/UI/Pages/Carousel/types.d.ts.map +1 -0
  43. package/dist/UI/Pages/Carousel/types.js +24 -0
  44. package/dist/UI/Pages/Carousel/types.js.map +1 -0
  45. package/dist/UI/Pages/Commitment/Renderer.d.ts +13 -0
  46. package/dist/UI/Pages/Commitment/Renderer.d.ts.map +1 -0
  47. package/dist/UI/Pages/Commitment/Renderer.js +173 -0
  48. package/dist/UI/Pages/Commitment/Renderer.js.map +1 -0
  49. package/dist/UI/Pages/Commitment/index.d.ts +3 -0
  50. package/dist/UI/Pages/Commitment/index.d.ts.map +1 -0
  51. package/dist/UI/Pages/Commitment/index.js +19 -0
  52. package/dist/UI/Pages/Commitment/index.js.map +1 -0
  53. package/dist/UI/Pages/Commitment/types.d.ts +41 -0
  54. package/dist/UI/Pages/Commitment/types.d.ts.map +1 -0
  55. package/dist/UI/Pages/Commitment/types.js +27 -0
  56. package/dist/UI/Pages/Commitment/types.js.map +1 -0
  57. package/dist/UI/Pages/Loader/Renderer.d.ts +10 -0
  58. package/dist/UI/Pages/Loader/Renderer.d.ts.map +1 -0
  59. package/dist/UI/Pages/Loader/Renderer.js +215 -0
  60. package/dist/UI/Pages/Loader/Renderer.js.map +1 -0
  61. package/dist/UI/Pages/Loader/index.d.ts +3 -0
  62. package/dist/UI/Pages/Loader/index.d.ts.map +1 -0
  63. package/dist/UI/Pages/Loader/index.js +19 -0
  64. package/dist/UI/Pages/Loader/index.js.map +1 -0
  65. package/dist/UI/Pages/Loader/types.d.ts +57 -0
  66. package/dist/UI/Pages/Loader/types.d.ts.map +1 -0
  67. package/dist/UI/Pages/Loader/types.js +30 -0
  68. package/dist/UI/Pages/Loader/types.js.map +1 -0
  69. package/dist/UI/Pages/MediaContent/Renderer.d.ts +13 -0
  70. package/dist/UI/Pages/MediaContent/Renderer.d.ts.map +1 -0
  71. package/dist/UI/Pages/MediaContent/Renderer.js +76 -0
  72. package/dist/UI/Pages/MediaContent/Renderer.js.map +1 -0
  73. package/dist/UI/Pages/MediaContent/index.d.ts +3 -0
  74. package/dist/UI/Pages/MediaContent/index.d.ts.map +1 -0
  75. package/dist/UI/Pages/MediaContent/index.js +19 -0
  76. package/dist/UI/Pages/MediaContent/index.js.map +1 -0
  77. package/dist/UI/Pages/MediaContent/types.d.ts +44 -0
  78. package/dist/UI/Pages/MediaContent/types.d.ts.map +1 -0
  79. package/dist/UI/Pages/MediaContent/types.js +22 -0
  80. package/dist/UI/Pages/MediaContent/types.js.map +1 -0
  81. package/dist/UI/Pages/Picker/Renderer.d.ts +13 -0
  82. package/dist/UI/Pages/Picker/Renderer.d.ts.map +1 -0
  83. package/dist/UI/Pages/Picker/Renderer.js +268 -0
  84. package/dist/UI/Pages/Picker/Renderer.js.map +1 -0
  85. package/dist/UI/Pages/Picker/index.d.ts +3 -0
  86. package/dist/UI/Pages/Picker/index.d.ts.map +1 -0
  87. package/dist/UI/Pages/Picker/index.js +19 -0
  88. package/dist/UI/Pages/Picker/index.js.map +1 -0
  89. package/dist/UI/Pages/Picker/types.d.ts +49 -0
  90. package/dist/UI/Pages/Picker/types.d.ts.map +1 -0
  91. package/dist/UI/Pages/Picker/types.js +30 -0
  92. package/dist/UI/Pages/Picker/types.js.map +1 -0
  93. package/dist/UI/Pages/Question/Renderer.d.ts +18 -0
  94. package/dist/UI/Pages/Question/Renderer.d.ts.map +1 -0
  95. package/dist/UI/Pages/Question/Renderer.js +128 -0
  96. package/dist/UI/Pages/Question/Renderer.js.map +1 -0
  97. package/dist/UI/Pages/Question/components.d.ts +57 -0
  98. package/dist/UI/Pages/Question/components.d.ts.map +1 -0
  99. package/dist/UI/Pages/Question/components.js +57 -0
  100. package/dist/UI/Pages/Question/components.js.map +1 -0
  101. package/dist/UI/Pages/Question/index.d.ts +4 -0
  102. package/dist/UI/Pages/Question/index.d.ts.map +1 -0
  103. package/dist/UI/Pages/Question/index.js +20 -0
  104. package/dist/UI/Pages/Question/index.js.map +1 -0
  105. package/dist/UI/Pages/Question/types.d.ts +47 -0
  106. package/dist/UI/Pages/Question/types.d.ts.map +1 -0
  107. package/dist/UI/Pages/Question/types.js +28 -0
  108. package/dist/UI/Pages/Question/types.js.map +1 -0
  109. package/dist/UI/Pages/Ratings/Renderer.d.ts +13 -0
  110. package/dist/UI/Pages/Ratings/Renderer.d.ts.map +1 -0
  111. package/dist/UI/Pages/Ratings/Renderer.js +201 -0
  112. package/dist/UI/Pages/Ratings/Renderer.js.map +1 -0
  113. package/dist/UI/Pages/Ratings/index.d.ts +3 -0
  114. package/dist/UI/Pages/Ratings/index.d.ts.map +1 -0
  115. package/dist/UI/Pages/Ratings/index.js +19 -0
  116. package/dist/UI/Pages/Ratings/index.js.map +1 -0
  117. package/dist/UI/Pages/Ratings/types.d.ts +32 -0
  118. package/dist/UI/Pages/Ratings/types.d.ts.map +1 -0
  119. package/dist/UI/Pages/Ratings/types.js +25 -0
  120. package/dist/UI/Pages/Ratings/types.js.map +1 -0
  121. package/dist/UI/Pages/index.d.ts +9 -0
  122. package/dist/UI/Pages/index.d.ts.map +1 -0
  123. package/dist/UI/Pages/index.js +26 -0
  124. package/dist/UI/Pages/index.js.map +1 -0
  125. package/dist/UI/Pages/types.d.ts +19 -0
  126. package/dist/UI/Pages/types.d.ts.map +1 -0
  127. package/dist/UI/Pages/types.js +25 -0
  128. package/dist/UI/Pages/types.js.map +1 -0
  129. package/dist/UI/Provider/OnboardingProgressProvider.d.ts +18 -0
  130. package/dist/UI/Provider/OnboardingProgressProvider.d.ts.map +1 -0
  131. package/dist/UI/Provider/OnboardingProgressProvider.js +23 -0
  132. package/dist/UI/Provider/OnboardingProgressProvider.js.map +1 -0
  133. package/dist/UI/Provider/index.d.ts +2 -0
  134. package/dist/UI/Provider/index.d.ts.map +1 -0
  135. package/dist/UI/Provider/index.js +7 -0
  136. package/dist/UI/Provider/index.js.map +1 -0
  137. package/dist/UI/Templates/OnboardingTemplate.d.ts +15 -0
  138. package/dist/UI/Templates/OnboardingTemplate.d.ts.map +1 -0
  139. package/dist/UI/Templates/OnboardingTemplate.js +48 -0
  140. package/dist/UI/Templates/OnboardingTemplate.js.map +1 -0
  141. package/dist/UI/Templates/index.d.ts +2 -0
  142. package/dist/UI/Templates/index.d.ts.map +1 -0
  143. package/dist/UI/Templates/index.js +6 -0
  144. package/dist/UI/Templates/index.js.map +1 -0
  145. package/dist/UI/Theme/ThemeProvider.d.ts +27 -0
  146. package/dist/UI/Theme/ThemeProvider.d.ts.map +1 -0
  147. package/dist/UI/Theme/ThemeProvider.js +49 -0
  148. package/dist/UI/Theme/ThemeProvider.js.map +1 -0
  149. package/dist/UI/Theme/defaultTheme.d.ts +7 -0
  150. package/dist/UI/Theme/defaultTheme.d.ts.map +1 -0
  151. package/dist/UI/Theme/defaultTheme.js +14 -0
  152. package/dist/UI/Theme/defaultTheme.js.map +1 -0
  153. package/dist/UI/Theme/helpers.d.ts +12 -0
  154. package/dist/UI/Theme/helpers.d.ts.map +1 -0
  155. package/dist/UI/Theme/helpers.js +21 -0
  156. package/dist/UI/Theme/helpers.js.map +1 -0
  157. package/dist/UI/Theme/index.d.ts +8 -0
  158. package/dist/UI/Theme/index.d.ts.map +1 -0
  159. package/dist/UI/Theme/index.js +24 -0
  160. package/dist/UI/Theme/index.js.map +1 -0
  161. package/dist/UI/Theme/token.d.ts +107 -0
  162. package/dist/UI/Theme/token.d.ts.map +1 -0
  163. package/dist/UI/Theme/token.js +108 -0
  164. package/dist/UI/Theme/token.js.map +1 -0
  165. package/dist/UI/Theme/tokens/darkTokens.d.ts +24 -0
  166. package/dist/UI/Theme/tokens/darkTokens.d.ts.map +1 -0
  167. package/dist/UI/Theme/tokens/darkTokens.js +27 -0
  168. package/dist/UI/Theme/tokens/darkTokens.js.map +1 -0
  169. package/dist/UI/Theme/tokens/index.d.ts +4 -0
  170. package/dist/UI/Theme/tokens/index.d.ts.map +1 -0
  171. package/dist/UI/Theme/tokens/index.js +20 -0
  172. package/dist/UI/Theme/tokens/index.js.map +1 -0
  173. package/dist/UI/Theme/tokens/lightTokens.d.ts +24 -0
  174. package/dist/UI/Theme/tokens/lightTokens.d.ts.map +1 -0
  175. package/dist/UI/Theme/tokens/lightTokens.js +27 -0
  176. package/dist/UI/Theme/tokens/lightTokens.js.map +1 -0
  177. package/dist/UI/Theme/tokens/typography.d.ts +65 -0
  178. package/dist/UI/Theme/tokens/typography.d.ts.map +1 -0
  179. package/dist/UI/Theme/tokens/typography.js +68 -0
  180. package/dist/UI/Theme/tokens/typography.js.map +1 -0
  181. package/dist/UI/Theme/types.d.ts +65 -0
  182. package/dist/UI/Theme/types.d.ts.map +1 -0
  183. package/dist/UI/Theme/types.js +3 -0
  184. package/dist/UI/Theme/types.js.map +1 -0
  185. package/dist/UI/Theme/useTheme.d.ts +7 -0
  186. package/dist/UI/Theme/useTheme.d.ts.map +1 -0
  187. package/dist/UI/Theme/useTheme.js +23 -0
  188. package/dist/UI/Theme/useTheme.js.map +1 -0
  189. package/dist/UI/Theme/utils.d.ts +12 -0
  190. package/dist/UI/Theme/utils.d.ts.map +1 -0
  191. package/dist/UI/Theme/utils.js +55 -0
  192. package/dist/UI/Theme/utils.js.map +1 -0
  193. package/dist/UI/index.d.ts +8 -0
  194. package/dist/UI/index.d.ts.map +1 -0
  195. package/dist/UI/index.js +24 -0
  196. package/dist/UI/index.js.map +1 -0
  197. package/dist/UI/types.d.ts +23 -0
  198. package/dist/UI/types.d.ts.map +1 -0
  199. package/dist/UI/types.js +3 -0
  200. package/dist/UI/types.js.map +1 -0
  201. package/dist/assets/laurel-left.png +0 -0
  202. package/dist/assets/laurel-right.png +0 -0
  203. package/dist/assets/star-filled.png +0 -0
  204. package/dist/index.d.ts +9 -0
  205. package/dist/index.d.ts.map +1 -0
  206. package/dist/index.js +33 -0
  207. package/dist/index.js.map +1 -0
  208. package/dist/provider/CustomComponentsContext.d.ts +57 -0
  209. package/dist/provider/CustomComponentsContext.d.ts.map +1 -0
  210. package/dist/provider/CustomComponentsContext.js +19 -0
  211. package/dist/provider/CustomComponentsContext.js.map +1 -0
  212. package/dist/provider/OnboardingUIProvider.d.ts +44 -0
  213. package/dist/provider/OnboardingUIProvider.d.ts.map +1 -0
  214. package/dist/provider/OnboardingUIProvider.js +33 -0
  215. package/dist/provider/OnboardingUIProvider.js.map +1 -0
  216. package/dist/provider/OnboardingUIProvider.old.d.ts +60 -0
  217. package/dist/provider/OnboardingUIProvider.old.d.ts.map +1 -0
  218. package/dist/provider/OnboardingUIProvider.old.js +53 -0
  219. package/dist/provider/OnboardingUIProvider.old.js.map +1 -0
  220. package/package.json +77 -0
  221. package/src/UI/Components/CircularProgress.tsx +146 -0
  222. package/src/UI/Components/ProgressBar.tsx +143 -0
  223. package/src/UI/Components/StaggeredTextList.tsx +152 -0
  224. package/src/UI/Components/index.ts +3 -0
  225. package/src/UI/ErrorBoundary/ErrorBoundary.tsx +181 -0
  226. package/src/UI/ErrorBoundary/README.md +71 -0
  227. package/src/UI/ErrorBoundary/index.ts +2 -0
  228. package/src/UI/ErrorBoundary/withErrorBoundary.tsx +19 -0
  229. package/src/UI/OnboardingPage.tsx +53 -0
  230. package/src/UI/Pages/Carousel/Renderer.tsx +210 -0
  231. package/src/UI/Pages/Carousel/index.ts +2 -0
  232. package/src/UI/Pages/Carousel/types.ts +26 -0
  233. package/src/UI/Pages/Commitment/Renderer.tsx +312 -0
  234. package/src/UI/Pages/Commitment/index.ts +2 -0
  235. package/src/UI/Pages/Commitment/types.ts +28 -0
  236. package/src/UI/Pages/Loader/Renderer.tsx +417 -0
  237. package/src/UI/Pages/Loader/index.ts +2 -0
  238. package/src/UI/Pages/Loader/types.ts +32 -0
  239. package/src/UI/Pages/MediaContent/Renderer.tsx +130 -0
  240. package/src/UI/Pages/MediaContent/index.ts +2 -0
  241. package/src/UI/Pages/MediaContent/types.ts +26 -0
  242. package/src/UI/Pages/Picker/Renderer.tsx +618 -0
  243. package/src/UI/Pages/Picker/index.ts +2 -0
  244. package/src/UI/Pages/Picker/types.ts +34 -0
  245. package/src/UI/Pages/Question/Renderer.tsx +208 -0
  246. package/src/UI/Pages/Question/components.tsx +130 -0
  247. package/src/UI/Pages/Question/index.ts +3 -0
  248. package/src/UI/Pages/Question/types.ts +29 -0
  249. package/src/UI/Pages/Ratings/Renderer.tsx +282 -0
  250. package/src/UI/Pages/Ratings/index.ts +2 -0
  251. package/src/UI/Pages/Ratings/types.ts +22 -0
  252. package/src/UI/Pages/index.ts +10 -0
  253. package/src/UI/Pages/types.ts +25 -0
  254. package/src/UI/Provider/OnboardingProgressProvider.tsx +40 -0
  255. package/src/UI/Provider/index.ts +1 -0
  256. package/src/UI/Templates/OnboardingTemplate.tsx +86 -0
  257. package/src/UI/Templates/index.ts +1 -0
  258. package/src/UI/Theme/ThemeProvider.tsx +100 -0
  259. package/src/UI/Theme/defaultTheme.ts +12 -0
  260. package/src/UI/Theme/helpers.ts +24 -0
  261. package/src/UI/Theme/index.ts +7 -0
  262. package/src/UI/Theme/token.ts +106 -0
  263. package/src/UI/Theme/tokens/darkTokens.ts +25 -0
  264. package/src/UI/Theme/tokens/index.ts +3 -0
  265. package/src/UI/Theme/tokens/lightTokens.ts +25 -0
  266. package/src/UI/Theme/tokens/typography.ts +66 -0
  267. package/src/UI/Theme/types.ts +72 -0
  268. package/src/UI/Theme/useTheme.ts +22 -0
  269. package/src/UI/Theme/utils.ts +67 -0
  270. package/src/UI/index.ts +7 -0
  271. package/src/UI/types.ts +41 -0
  272. package/src/assets/laurel-left.png +0 -0
  273. package/src/assets/laurel-right.png +0 -0
  274. package/src/assets/star-filled.png +0 -0
  275. package/src/index.ts +28 -0
@@ -0,0 +1,25 @@
1
+ import { z } from "zod";
2
+
3
+ export const CustomPayloadSchema = z.record(z.string(), z.any()).nullish();
4
+
5
+ export const MediaSourceSchema = z.union([
6
+ z.object({
7
+ type: z.literal("image").or(z.literal("lottie")).or(z.literal("rive")),
8
+ localPathId: z.string(),
9
+ }),
10
+ z.object({
11
+ type: z.literal("image").or(z.literal("lottie")).or(z.literal("rive")),
12
+ url: z.string(),
13
+ }),
14
+ ]);
15
+
16
+ export const SocialProofSchema = z.object({
17
+ numberOfStar: z.number(),
18
+ content: z.string(),
19
+ authorName: z.string(),
20
+ });
21
+
22
+ export const InfoBoxSchema = z.object({
23
+ title: z.string(),
24
+ content: z.string(),
25
+ });
@@ -0,0 +1,40 @@
1
+ import { createContext, useState } from "react";
2
+ import { SafeAreaProvider } from "react-native-safe-area-context";
3
+ import { ThemeProvider } from "../Theme/ThemeProvider";
4
+ import { ColorScheme } from "../Theme/types";
5
+
6
+ export const OnboardingProgressProvider = ({
7
+ children,
8
+ initialColorScheme = "light",
9
+ }: {
10
+ children: React.ReactNode;
11
+ initialColorScheme?: ColorScheme;
12
+ }) => {
13
+ const [activeStep, setActiveStep] = useState({
14
+ number: 0,
15
+ displayProgressHeader: false,
16
+ });
17
+ const [totalSteps, setTotalSteps] = useState(0);
18
+
19
+ return (
20
+ <SafeAreaProvider>
21
+ <ThemeProvider initialColorScheme={initialColorScheme}>
22
+ <OnboardingProgressContext.Provider
23
+ value={{ activeStep, setActiveStep, totalSteps, setTotalSteps }}
24
+ >
25
+ {children}
26
+ </OnboardingProgressContext.Provider>
27
+ </ThemeProvider>
28
+ </SafeAreaProvider>
29
+ );
30
+ };
31
+
32
+ export const OnboardingProgressContext = createContext({
33
+ activeStep: { number: 0, displayProgressHeader: false },
34
+ setActiveStep: (step: {
35
+ number: number;
36
+ displayProgressHeader: boolean;
37
+ }) => {},
38
+ totalSteps: 0,
39
+ setTotalSteps: (steps: number) => {},
40
+ });
@@ -0,0 +1 @@
1
+ export { ThemeProvider, useTheme } from "../Theme";
@@ -0,0 +1,86 @@
1
+ import { StyleSheet, Text, TouchableOpacity, View } from "react-native";
2
+ import { OnboardingStepType } from "../types";
3
+ import { useSafeAreaInsets } from "react-native-safe-area-context";
4
+ import { getTextStyle } from "../Theme/helpers";
5
+ import { Theme } from "../Theme/types";
6
+ import { defaultTheme } from "../Theme/defaultTheme";
7
+
8
+ type OnboardingTemplateProps = {
9
+ children: React.ReactNode;
10
+ onContinue: () => void;
11
+ button?: {
12
+ text: string;
13
+ disabled?: boolean;
14
+ };
15
+ step: OnboardingStepType;
16
+ theme?: Theme;
17
+ };
18
+
19
+ export const OnboardingTemplate = ({
20
+ children,
21
+ onContinue,
22
+ step,
23
+ button,
24
+ theme = defaultTheme,
25
+ }: OnboardingTemplateProps) => {
26
+ const { top, bottom } = useSafeAreaInsets();
27
+
28
+ return (
29
+ <View
30
+ style={[
31
+ styles.container,
32
+ {
33
+ backgroundColor: theme.colors.neutral.lowest,
34
+ paddingTop: step.displayProgressHeader ? top + 40 : top,
35
+ paddingBottom: bottom
36
+ },
37
+ ]}
38
+ >
39
+ {children}
40
+ {button && (
41
+ <View style={styles.bottomSection}>
42
+ <TouchableOpacity
43
+ style={[
44
+ styles.ctaButton,
45
+ { backgroundColor: theme.colors.primary },
46
+ button.disabled && { backgroundColor: theme.colors.disable },
47
+ ]}
48
+ onPress={onContinue}
49
+ activeOpacity={0.8}
50
+ disabled={button.disabled}
51
+ >
52
+ <Text
53
+ style={[
54
+ getTextStyle(theme, "button"),
55
+ styles.ctaButtonText,
56
+ { color: theme.colors.text.opposite },
57
+ button.disabled && { color: theme.colors.text.disable },
58
+ ]}
59
+ >
60
+ {button.text}
61
+ </Text>
62
+ </TouchableOpacity>
63
+ </View>
64
+ )}
65
+ </View>
66
+ );
67
+ };
68
+
69
+ const styles = StyleSheet.create({
70
+ container: {
71
+ flex: 1,
72
+ },
73
+ bottomSection: {
74
+ paddingHorizontal: 32,
75
+ gap: 24,
76
+ alignItems: "center",
77
+ },
78
+ ctaButton: {
79
+ borderRadius: 90,
80
+ paddingVertical: 18,
81
+ paddingHorizontal: 24,
82
+ minWidth: 234,
83
+ alignItems: "center",
84
+ },
85
+ ctaButtonText: {},
86
+ });
@@ -0,0 +1 @@
1
+ export { OnboardingTemplate } from "./OnboardingTemplate";
@@ -0,0 +1,100 @@
1
+ import React, { createContext, useState, ReactNode, useMemo } from "react";
2
+ import { lightTokens, darkTokens, typography } from "./tokens";
3
+ import { Theme, ColorScheme, DeepPartial } from "./types";
4
+ import { mergeThemeTokens, deepMerge } from "./utils";
5
+
6
+ type ThemeContextType = {
7
+ theme: Theme;
8
+ colorScheme: ColorScheme;
9
+ toggleTheme: () => void;
10
+ };
11
+
12
+ export const ThemeContext = createContext<ThemeContextType | undefined>(
13
+ undefined
14
+ );
15
+
16
+ type ThemeProviderProps = {
17
+ children: ReactNode;
18
+ initialColorScheme?: ColorScheme;
19
+ /**
20
+ * Custom theme to override both light and dark mode tokens.
21
+ */
22
+ customTheme?: DeepPartial<Theme>;
23
+ /**
24
+ * Custom theme tokens for light mode only.
25
+ */
26
+ customLightTheme?: DeepPartial<Theme>;
27
+ /**
28
+ * Custom theme tokens for dark mode only.
29
+ */
30
+ customDarkTheme?: DeepPartial<Theme>;
31
+ };
32
+
33
+ export const ThemeProvider = ({
34
+ children,
35
+ initialColorScheme = "light",
36
+ customTheme,
37
+ customLightTheme,
38
+ customDarkTheme,
39
+ }: ThemeProviderProps) => {
40
+ const [colorScheme, setColorScheme] =
41
+ useState<ColorScheme>(initialColorScheme);
42
+
43
+ // Merge custom themes with defaults (memoized for performance)
44
+ const mergedLightTheme = useMemo(() => {
45
+ let baseLight = mergeThemeTokens(
46
+ lightTokens.colors,
47
+ typography,
48
+ customLightTheme
49
+ );
50
+
51
+ // Apply global customTheme on top if provided
52
+ if (customTheme) {
53
+ baseLight = {
54
+ colors: customTheme.colors
55
+ ? deepMerge(baseLight.colors, customTheme.colors)
56
+ : baseLight.colors,
57
+ typography: customTheme.typography
58
+ ? deepMerge(baseLight.typography, customTheme.typography)
59
+ : baseLight.typography,
60
+ };
61
+ }
62
+
63
+ return baseLight;
64
+ }, [customTheme, customLightTheme]);
65
+
66
+ const mergedDarkTheme = useMemo(() => {
67
+ let baseDark = mergeThemeTokens(
68
+ darkTokens.colors,
69
+ typography,
70
+ customDarkTheme
71
+ );
72
+
73
+ // Apply global customTheme on top if provided
74
+ if (customTheme) {
75
+ baseDark = {
76
+ colors: customTheme.colors
77
+ ? deepMerge(baseDark.colors, customTheme.colors)
78
+ : baseDark.colors,
79
+ typography: customTheme.typography
80
+ ? deepMerge(baseDark.typography, customTheme.typography)
81
+ : baseDark.typography,
82
+ };
83
+ }
84
+
85
+ return baseDark;
86
+ }, [customTheme, customDarkTheme]);
87
+
88
+ const theme: Theme =
89
+ colorScheme === "light" ? mergedLightTheme : mergedDarkTheme;
90
+
91
+ const toggleTheme = () => {
92
+ setColorScheme((prev) => (prev === "light" ? "dark" : "light"));
93
+ };
94
+
95
+ return (
96
+ <ThemeContext.Provider value={{ theme, colorScheme, toggleTheme }}>
97
+ {children}
98
+ </ThemeContext.Provider>
99
+ );
100
+ };
@@ -0,0 +1,12 @@
1
+ import { Theme } from "./types";
2
+ import { lightTokens } from "./tokens/lightTokens";
3
+ import { typography } from "./tokens/typography";
4
+
5
+ /**
6
+ * Default theme that combines light color tokens and typography.
7
+ * This is used as a fallback when no theme is provided to components.
8
+ */
9
+ export const defaultTheme: Theme = {
10
+ colors: lightTokens.colors,
11
+ typography: typography,
12
+ };
@@ -0,0 +1,24 @@
1
+ import { Theme, TextStyles } from "./types";
2
+ import { TextStyle } from "react-native";
3
+
4
+ /**
5
+ * Get a semantic text style from the theme with resolved font family.
6
+ *
7
+ * @example
8
+ * <Text style={[getTextStyle(theme, "heading1"), { color: theme.colors.text.primary }]}>
9
+ * Title
10
+ * </Text>
11
+ */
12
+ export function getTextStyle(
13
+ theme: Theme,
14
+ styleName: keyof TextStyles
15
+ ): TextStyle {
16
+ const style = theme.typography.textStyles[styleName];
17
+
18
+ return {
19
+ fontFamily: style.fontFamily,
20
+ fontSize: style.fontSize,
21
+ fontWeight: style.fontWeight,
22
+ lineHeight: style.fontSize * style.lineHeight,
23
+ };
24
+ }
@@ -0,0 +1,7 @@
1
+ export * from "./ThemeProvider";
2
+ export * from "./useTheme";
3
+ export * from "./types";
4
+ export * from "./tokens";
5
+ export * from "./utils";
6
+ export * from "./helpers";
7
+ export * from "./defaultTheme";
@@ -0,0 +1,106 @@
1
+ const lightMode = {
2
+ color: {
3
+ disable: "#6d6d6d",
4
+ primary: "#264653",
5
+ secondary: "#3d3d3d",
6
+ tertiary1: "#f4a261",
7
+ tertiary2: "#e76f51",
8
+ tertiary3: "#e9c46a",
9
+ colorsNeutralHigh: "#4f4f4f",
10
+ colorsNeutralHigher: "#3d3d3d",
11
+ colorsNeutralHighest: "#262626",
12
+ colorsNeutralLow: "#b0b0b0",
13
+ colorsNeutralLower: "#e7e7e7",
14
+ colorsNeutralLowest: "#f6f6f6",
15
+ colorsNeutralMedium: "#6d6d6d",
16
+ colorsSurfaceHigh: "#6d6d6d",
17
+ colorsSurfaceHigher: "#4f4f4f",
18
+ colorsSurfaceHighest: "#3d3d3d",
19
+ colorsSurfaceLow: "#e7e7e7",
20
+ colorsSurfaceLower: "#f6f6f6",
21
+ colorsSurfaceLowest: "#ffffff",
22
+ colorsSurfaceMedium: "#b0b0b0",
23
+ colorsSurfaceOpposite: "#262626",
24
+ colorsTextDisable: "#b0b0b0",
25
+ colorsTextOpposite: "#ffffff",
26
+ colorsTextPrimary: "#262626",
27
+ colorsTextSecondary: "#3d3d3d",
28
+ colorsTextTerciary: "#6d6d6d",
29
+ },
30
+ };
31
+ const darkMode = {
32
+ color: {
33
+ disable: "#6d6d6d",
34
+ primary: "#c8ff2f",
35
+ secondary: "#000000",
36
+ tertiary1: "#f4a261",
37
+ tertiary2: "#e76f51",
38
+ tertiary3: "#e9c46a",
39
+ colorsNeutralHigh: "#6d6d6d",
40
+ colorsNeutralHigher: "#b0b0b0",
41
+ colorsNeutralHighest: "#f6f6f6",
42
+ colorsNeutralLow: "#4f4f4f",
43
+ colorsNeutralLower: "#3d3d3d",
44
+ colorsNeutralLowest: "#262626",
45
+ colorsNeutralMedium: "#6d6d6d",
46
+ colorsSurfaceHigh: "#575757",
47
+ colorsSurfaceHigher: "#888888",
48
+ colorsSurfaceHighest: "#e7e7e7",
49
+ colorsSurfaceLow: "#3d3d3d",
50
+ colorsSurfaceLower: "#262626",
51
+ colorsSurfaceLowest: "#000000",
52
+ colorsSurfaceMedium: "#454545",
53
+ colorsSurfaceOpposite: "#ffffff",
54
+ colorsTextDisable: "#6d6d6d",
55
+ colorsTextOpposite: "#262626",
56
+ colorsTextPrimary: "#ffffff",
57
+ colorsTextSecondary: "#d1d1d1",
58
+ colorsTextTerciary: "#b0b0b0",
59
+ },
60
+ };
61
+ const brand1 = {
62
+ number: {
63
+ fontSizeXs: "12px",
64
+ fontSizeSm: "14px",
65
+ fontSizeMd: "16px",
66
+ fontSizeLg: "20px",
67
+ fontSizeXl: "24px",
68
+ fontSize2xl: "32px",
69
+ fontSize3xl: "40px",
70
+ fontSize4xl: "72px",
71
+ },
72
+ string: {
73
+ fontFamilyTagline: "Inter",
74
+ fontFamilyText: "Inter",
75
+ fontFamilyTitle: "Inter",
76
+ fontWeightBold: "bold",
77
+ fontWeightExtraBold: "extrabold",
78
+ fontWeightItalic: "italic",
79
+ fontWeightMedium: "medium",
80
+ fontWeightRegular: "regular",
81
+ fontWeightSemiBold: "semibold",
82
+ },
83
+ };
84
+ const brand2 = {
85
+ number: {
86
+ fontSizeXs: "12px",
87
+ fontSizeSm: "14px",
88
+ fontSizeMd: "16px",
89
+ fontSizeLg: "20px",
90
+ fontSizeXl: "24px",
91
+ fontSize2xl: "32px",
92
+ fontSize3xl: "40px",
93
+ fontSize4xl: "72px",
94
+ },
95
+ string: {
96
+ fontFamilyTagline: "Montserrat",
97
+ fontFamilyText: "ubuntu",
98
+ fontFamilyTitle: "ubuntu",
99
+ fontWeightBold: "bold",
100
+ fontWeightExtraBold: "extrabold",
101
+ fontWeightItalic: "italic",
102
+ fontWeightMedium: "medium",
103
+ fontWeightRegular: "regular",
104
+ fontWeightSemiBold: "semibold",
105
+ },
106
+ };
@@ -0,0 +1,25 @@
1
+ import { ColorTokens } from "../types";
2
+
3
+ export const darkTokens = {
4
+ colors: {
5
+ primary: "#c8ff2f",
6
+ disable: "#6d6d6d",
7
+ neutral: {
8
+ high: "#6d6d6d",
9
+ higher: "#b0b0b0",
10
+ highest: "#f6f6f6",
11
+ low: "#4f4f4f",
12
+ lower: "#3d3d3d",
13
+ lowest: "#262626",
14
+ lowestest: "#000000",
15
+ medium: "#6d6d6d",
16
+ },
17
+ text: {
18
+ disable: "#6d6d6d",
19
+ opposite: "#262626",
20
+ primary: "#ffffff",
21
+ secondary: "#d1d1d1",
22
+ tertiary: "#b0b0b0",
23
+ },
24
+ },
25
+ } satisfies { colors: ColorTokens };
@@ -0,0 +1,3 @@
1
+ export * from "./lightTokens";
2
+ export * from "./darkTokens";
3
+ export * from "./typography";
@@ -0,0 +1,25 @@
1
+ import { ColorTokens } from "../types";
2
+
3
+ export const lightTokens = {
4
+ colors: {
5
+ primary: "#264653",
6
+ disable: "#6d6d6d",
7
+ neutral: {
8
+ high: "#4f4f4f",
9
+ higher: "#3d3d3d",
10
+ highest: "#262626",
11
+ low: "#b0b0b0",
12
+ lower: "#e7e7e7",
13
+ lowest: "#f6f6f6",
14
+ lowestest: "#ffffff",
15
+ medium: "#6d6d6d",
16
+ },
17
+ text: {
18
+ disable: "#b0b0b0",
19
+ opposite: "#ffffff",
20
+ primary: "#262626",
21
+ secondary: "#3d3d3d",
22
+ tertiary: "#6d6d6d",
23
+ },
24
+ },
25
+ } satisfies { colors: ColorTokens };
@@ -0,0 +1,66 @@
1
+ import { TypographyTokens } from "../types";
2
+
3
+ export const typography = {
4
+ fontWeight: {
5
+ regular: "400" as const,
6
+ medium: "500" as const,
7
+ semibold: "600" as const,
8
+ bold: "700" as const,
9
+ extrabold: "800" as const,
10
+ },
11
+ lineHeight: {
12
+ tight: 1.25,
13
+ normal: 1.3,
14
+ relaxed: 1.4,
15
+ },
16
+ textStyles: {
17
+ heading1: {
18
+ fontSize: 32,
19
+ fontWeight: "600" as const,
20
+ lineHeight: 1.25,
21
+ fontFamily: "Inter",
22
+ },
23
+ heading2: {
24
+ fontSize: 24,
25
+ fontWeight: "600" as const,
26
+ lineHeight: 1.3,
27
+ fontFamily: "Inter",
28
+ },
29
+ heading3: {
30
+ fontSize: 18,
31
+ fontWeight: "500" as const,
32
+ lineHeight: 1.3,
33
+ fontFamily: "Inter",
34
+ },
35
+ body: {
36
+ fontSize: 16,
37
+ fontWeight: "400" as const,
38
+ lineHeight: 1.3,
39
+ fontFamily: "Inter",
40
+ },
41
+ bodyMedium: {
42
+ fontSize: 16,
43
+ fontWeight: "500" as const,
44
+ lineHeight: 1.3,
45
+ fontFamily: "Inter",
46
+ },
47
+ label: {
48
+ fontSize: 14,
49
+ fontWeight: "500" as const,
50
+ lineHeight: 1.3,
51
+ fontFamily: "Inter",
52
+ },
53
+ caption: {
54
+ fontSize: 12,
55
+ fontWeight: "400" as const,
56
+ lineHeight: 1.3,
57
+ fontFamily: "Inter",
58
+ },
59
+ button: {
60
+ fontSize: 16,
61
+ fontWeight: "500" as const,
62
+ lineHeight: 1.5,
63
+ fontFamily: "Inter",
64
+ },
65
+ },
66
+ } satisfies TypographyTokens;
@@ -0,0 +1,72 @@
1
+ export type ColorTokens = {
2
+ primary: string;
3
+ disable: string;
4
+ neutral: {
5
+ high: string;
6
+ higher: string;
7
+ highest: string;
8
+ low: string;
9
+ lower: string;
10
+ lowest: string;
11
+ lowestest: string;
12
+ medium: string;
13
+ };
14
+ text: {
15
+ disable: string;
16
+ opposite: string;
17
+ primary: string;
18
+ secondary: string;
19
+ tertiary: string;
20
+ };
21
+ };
22
+
23
+ export type TextStyle = {
24
+ fontSize: number;
25
+ fontWeight: "400" | "500" | "600" | "700" | "800";
26
+ lineHeight: number;
27
+ fontFamily: string;
28
+ };
29
+
30
+ export type TextStyles = {
31
+ heading1: TextStyle;
32
+ heading2: TextStyle;
33
+ heading3: TextStyle;
34
+ body: TextStyle;
35
+ bodyMedium: TextStyle;
36
+ label: TextStyle;
37
+ caption: TextStyle;
38
+ button: TextStyle;
39
+ };
40
+
41
+ export type TypographyTokens = {
42
+ fontWeight: {
43
+ regular: "400";
44
+ medium: "500";
45
+ semibold: "600";
46
+ bold: "700";
47
+ extrabold: "800";
48
+ };
49
+ lineHeight: {
50
+ tight: number;
51
+ normal: number;
52
+ relaxed: number;
53
+ };
54
+ textStyles: TextStyles;
55
+ };
56
+
57
+ export type Theme = {
58
+ colors: ColorTokens;
59
+ typography: TypographyTokens;
60
+ };
61
+
62
+ export type ColorScheme = "light" | "dark";
63
+
64
+ /**
65
+ * Deep partial utility type for nested objects.
66
+ * Makes all properties optional recursively.
67
+ */
68
+ export type DeepPartial<T> = T extends object
69
+ ? {
70
+ [P in keyof T]?: DeepPartial<T[P]>;
71
+ }
72
+ : T;
@@ -0,0 +1,22 @@
1
+ import { useContext } from "react";
2
+ import { ThemeContext } from "./ThemeProvider";
3
+ import { Theme } from "./types";
4
+ import { lightTokens, typography } from "./tokens";
5
+
6
+ export const useTheme = () => {
7
+ const context = useContext(ThemeContext);
8
+
9
+ if (context === undefined) {
10
+ const theme: Theme = {
11
+ colors: lightTokens.colors,
12
+ typography,
13
+ };
14
+ return {
15
+ theme: theme,
16
+ colorScheme: "light",
17
+ toggleTheme: () => {},
18
+ };
19
+ }
20
+
21
+ return context;
22
+ };
@@ -0,0 +1,67 @@
1
+ import { Theme, ColorTokens, TypographyTokens, DeepPartial } from "./types";
2
+
3
+ /**
4
+ * Deep merge utility for theme tokens.
5
+ * Recursively merges custom theme values into default theme.
6
+ */
7
+ export function deepMerge<T extends Record<string, any>>(
8
+ target: T,
9
+ source: DeepPartial<T> | undefined
10
+ ): T {
11
+ if (!source) return target;
12
+
13
+ const result = { ...target };
14
+
15
+ for (const key in source) {
16
+ const sourceValue = source[key];
17
+ const targetValue = result[key];
18
+
19
+ if (
20
+ sourceValue &&
21
+ typeof sourceValue === "object" &&
22
+ !Array.isArray(sourceValue) &&
23
+ targetValue &&
24
+ typeof targetValue === "object" &&
25
+ !Array.isArray(targetValue)
26
+ ) {
27
+ // Recursively merge nested objects
28
+ result[key] = deepMerge(targetValue, sourceValue);
29
+ } else if (sourceValue !== undefined) {
30
+ // Override primitive values
31
+ result[key] = sourceValue as any;
32
+ }
33
+ }
34
+
35
+ return result;
36
+ }
37
+
38
+ /**
39
+ * Merge custom theme tokens with default tokens.
40
+ * Supports partial Theme objects with nested property overrides.
41
+ */
42
+ export function mergeThemeTokens(
43
+ defaultColors: ColorTokens,
44
+ defaultTypography: TypographyTokens,
45
+ customTheme?: DeepPartial<Theme>
46
+ ): Theme {
47
+ if (!customTheme) {
48
+ return {
49
+ colors: defaultColors,
50
+ typography: defaultTypography,
51
+ };
52
+ }
53
+
54
+ // Check if customTheme has colors and/or typography
55
+ const hasColors = "colors" in customTheme && customTheme.colors !== undefined;
56
+ const hasTypography =
57
+ "typography" in customTheme && customTheme.typography !== undefined;
58
+
59
+ return {
60
+ colors: hasColors
61
+ ? deepMerge(defaultColors, customTheme.colors)
62
+ : defaultColors,
63
+ typography: hasTypography
64
+ ? deepMerge(defaultTypography, customTheme.typography)
65
+ : defaultTypography,
66
+ };
67
+ }