@rocapine/react-native-onboarding-ui 1.12.0 → 1.14.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 (90) hide show
  1. package/dist/UI/Pages/ComposableScreen/Renderer.js.map +1 -1
  2. package/dist/UI/Pages/ComposableScreen/elements/BaseBoxProps.d.ts +67 -0
  3. package/dist/UI/Pages/ComposableScreen/elements/BaseBoxProps.d.ts.map +1 -1
  4. package/dist/UI/Pages/ComposableScreen/elements/BaseBoxProps.js +15 -1
  5. package/dist/UI/Pages/ComposableScreen/elements/BaseBoxProps.js.map +1 -1
  6. package/dist/UI/Pages/ComposableScreen/elements/ButtonElement.d.ts +27 -0
  7. package/dist/UI/Pages/ComposableScreen/elements/ButtonElement.d.ts.map +1 -1
  8. package/dist/UI/Pages/ComposableScreen/elements/ButtonElement.js +40 -14
  9. package/dist/UI/Pages/ComposableScreen/elements/ButtonElement.js.map +1 -1
  10. package/dist/UI/Pages/ComposableScreen/elements/CarouselElement.d.ts +27 -0
  11. package/dist/UI/Pages/ComposableScreen/elements/CarouselElement.d.ts.map +1 -1
  12. package/dist/UI/Pages/ComposableScreen/elements/CarouselElement.js +3 -2
  13. package/dist/UI/Pages/ComposableScreen/elements/CarouselElement.js.map +1 -1
  14. package/dist/UI/Pages/ComposableScreen/elements/CheckboxGroupElement.d.ts +27 -0
  15. package/dist/UI/Pages/ComposableScreen/elements/CheckboxGroupElement.d.ts.map +1 -1
  16. package/dist/UI/Pages/ComposableScreen/elements/CheckboxGroupElement.js +3 -1
  17. package/dist/UI/Pages/ComposableScreen/elements/CheckboxGroupElement.js.map +1 -1
  18. package/dist/UI/Pages/ComposableScreen/elements/DatePickerElement.d.ts +27 -0
  19. package/dist/UI/Pages/ComposableScreen/elements/DatePickerElement.d.ts.map +1 -1
  20. package/dist/UI/Pages/ComposableScreen/elements/DatePickerElement.js +4 -2
  21. package/dist/UI/Pages/ComposableScreen/elements/DatePickerElement.js.map +1 -1
  22. package/dist/UI/Pages/ComposableScreen/elements/GradientBox.d.ts +11 -0
  23. package/dist/UI/Pages/ComposableScreen/elements/GradientBox.d.ts.map +1 -0
  24. package/dist/UI/Pages/ComposableScreen/elements/GradientBox.js +33 -0
  25. package/dist/UI/Pages/ComposableScreen/elements/GradientBox.js.map +1 -0
  26. package/dist/UI/Pages/ComposableScreen/elements/IconElement.d.ts +27 -0
  27. package/dist/UI/Pages/ComposableScreen/elements/IconElement.d.ts.map +1 -1
  28. package/dist/UI/Pages/ComposableScreen/elements/IconElement.js +3 -3
  29. package/dist/UI/Pages/ComposableScreen/elements/IconElement.js.map +1 -1
  30. package/dist/UI/Pages/ComposableScreen/elements/ImageElement.d.ts +27 -0
  31. package/dist/UI/Pages/ComposableScreen/elements/ImageElement.d.ts.map +1 -1
  32. package/dist/UI/Pages/ComposableScreen/elements/ImageElement.js +51 -23
  33. package/dist/UI/Pages/ComposableScreen/elements/ImageElement.js.map +1 -1
  34. package/dist/UI/Pages/ComposableScreen/elements/InputElement.d.ts +27 -0
  35. package/dist/UI/Pages/ComposableScreen/elements/InputElement.d.ts.map +1 -1
  36. package/dist/UI/Pages/ComposableScreen/elements/LottieElement.d.ts +27 -0
  37. package/dist/UI/Pages/ComposableScreen/elements/LottieElement.d.ts.map +1 -1
  38. package/dist/UI/Pages/ComposableScreen/elements/LottieElement.js +4 -3
  39. package/dist/UI/Pages/ComposableScreen/elements/LottieElement.js.map +1 -1
  40. package/dist/UI/Pages/ComposableScreen/elements/RadioGroupElement.d.ts +27 -0
  41. package/dist/UI/Pages/ComposableScreen/elements/RadioGroupElement.d.ts.map +1 -1
  42. package/dist/UI/Pages/ComposableScreen/elements/RadioGroupElement.js +3 -1
  43. package/dist/UI/Pages/ComposableScreen/elements/RadioGroupElement.js.map +1 -1
  44. package/dist/UI/Pages/ComposableScreen/elements/RiveElement.d.ts +27 -0
  45. package/dist/UI/Pages/ComposableScreen/elements/RiveElement.d.ts.map +1 -1
  46. package/dist/UI/Pages/ComposableScreen/elements/StackElement.d.ts +28 -1
  47. package/dist/UI/Pages/ComposableScreen/elements/StackElement.d.ts.map +1 -1
  48. package/dist/UI/Pages/ComposableScreen/elements/StackElement.js +3 -3
  49. package/dist/UI/Pages/ComposableScreen/elements/StackElement.js.map +1 -1
  50. package/dist/UI/Pages/ComposableScreen/elements/TextElement.d.ts +28 -1
  51. package/dist/UI/Pages/ComposableScreen/elements/TextElement.d.ts.map +1 -1
  52. package/dist/UI/Pages/ComposableScreen/elements/TextElement.js +48 -21
  53. package/dist/UI/Pages/ComposableScreen/elements/TextElement.js.map +1 -1
  54. package/dist/UI/Pages/ComposableScreen/elements/VideoElement.d.ts +33 -0
  55. package/dist/UI/Pages/ComposableScreen/elements/VideoElement.d.ts.map +1 -1
  56. package/dist/UI/Pages/ComposableScreen/elements/VideoElement.js +7 -5
  57. package/dist/UI/Pages/ComposableScreen/elements/VideoElement.js.map +1 -1
  58. package/dist/UI/Pages/ComposableScreen/elements/ZStackElement.d.ts +77 -0
  59. package/dist/UI/Pages/ComposableScreen/elements/ZStackElement.d.ts.map +1 -0
  60. package/dist/UI/Pages/ComposableScreen/elements/ZStackElement.js +39 -0
  61. package/dist/UI/Pages/ComposableScreen/elements/ZStackElement.js.map +1 -0
  62. package/dist/UI/Pages/ComposableScreen/elements/renderElement.d.ts +1 -1
  63. package/dist/UI/Pages/ComposableScreen/elements/renderElement.d.ts.map +1 -1
  64. package/dist/UI/Pages/ComposableScreen/elements/renderElement.js +4 -0
  65. package/dist/UI/Pages/ComposableScreen/elements/renderElement.js.map +1 -1
  66. package/dist/UI/Pages/ComposableScreen/elements/shared.d.ts +1 -1
  67. package/dist/UI/Pages/ComposableScreen/elements/shared.d.ts.map +1 -1
  68. package/dist/UI/Pages/ComposableScreen/types.d.ts +9 -1
  69. package/dist/UI/Pages/ComposableScreen/types.d.ts.map +1 -1
  70. package/dist/UI/Pages/ComposableScreen/types.js +9 -1
  71. package/dist/UI/Pages/ComposableScreen/types.js.map +1 -1
  72. package/package.json +6 -2
  73. package/src/UI/Pages/ComposableScreen/Renderer.tsx +1 -1
  74. package/src/UI/Pages/ComposableScreen/elements/BaseBoxProps.ts +42 -0
  75. package/src/UI/Pages/ComposableScreen/elements/ButtonElement.tsx +56 -12
  76. package/src/UI/Pages/ComposableScreen/elements/CarouselElement.tsx +5 -4
  77. package/src/UI/Pages/ComposableScreen/elements/CheckboxGroupElement.tsx +5 -3
  78. package/src/UI/Pages/ComposableScreen/elements/DatePickerElement.tsx +6 -4
  79. package/src/UI/Pages/ComposableScreen/elements/GradientBox.tsx +56 -0
  80. package/src/UI/Pages/ComposableScreen/elements/IconElement.tsx +5 -4
  81. package/src/UI/Pages/ComposableScreen/elements/ImageElement.tsx +64 -24
  82. package/src/UI/Pages/ComposableScreen/elements/LottieElement.tsx +10 -6
  83. package/src/UI/Pages/ComposableScreen/elements/RadioGroupElement.tsx +5 -3
  84. package/src/UI/Pages/ComposableScreen/elements/StackElement.tsx +6 -5
  85. package/src/UI/Pages/ComposableScreen/elements/TextElement.tsx +57 -21
  86. package/src/UI/Pages/ComposableScreen/elements/VideoElement.tsx +13 -6
  87. package/src/UI/Pages/ComposableScreen/elements/ZStackElement.tsx +60 -0
  88. package/src/UI/Pages/ComposableScreen/elements/renderElement.tsx +6 -1
  89. package/src/UI/Pages/ComposableScreen/elements/shared.ts +1 -1
  90. package/src/UI/Pages/ComposableScreen/types.ts +17 -1
@@ -1,10 +1,11 @@
1
1
  import React from "react";
2
2
  import { z } from "zod";
3
- import { View, Text, StyleSheet } from "react-native";
3
+ import { Text, StyleSheet } from "react-native";
4
4
  import { BaseBoxProps, BaseBoxPropsSchema } from "./BaseBoxProps";
5
5
  import { UIElement } from "../types";
6
6
  import { RenderContext, dim } from "./shared";
7
7
  import { getTextStyle } from "../../../Theme/helpers";
8
+ import { GradientBox } from "./GradientBox";
8
9
 
9
10
  export type LottieElementProps = BaseBoxProps & {
10
11
  source: string;
@@ -54,7 +55,7 @@ export const LottieElementComponent = ({ element, ctx }: Props): React.ReactElem
54
55
  minHeight: element.props.minHeight,
55
56
  maxHeight: element.props.maxHeight,
56
57
  opacity: element.props.opacity,
57
- backgroundColor: element.props.backgroundColor,
58
+ backgroundColor: element.props.backgroundGradient ? undefined : element.props.backgroundColor,
58
59
  margin: element.props.margin,
59
60
  marginHorizontal: element.props.marginHorizontal,
60
61
  marginVertical: element.props.marginVertical,
@@ -69,16 +70,19 @@ export const LottieElementComponent = ({ element, ctx }: Props): React.ReactElem
69
70
 
70
71
  if (!LottieView) {
71
72
  return (
72
- <View style={[wrapperStyle, styles.mediaFallback, { backgroundColor: theme.colors.neutral.lowest }]}>
73
+ <GradientBox
74
+ gradient={element.props.backgroundGradient}
75
+ style={[wrapperStyle, styles.mediaFallback, { backgroundColor: theme.colors.neutral.lowest }] as any}
76
+ >
73
77
  <Text style={[styles.mediaFallbackText, getTextStyle(theme, "caption"), { color: theme.colors.text.tertiary }]}>
74
78
  Install lottie-react-native to render Lottie animations.
75
79
  </Text>
76
- </View>
80
+ </GradientBox>
77
81
  );
78
82
  }
79
83
 
80
84
  return (
81
- <View style={wrapperStyle}>
85
+ <GradientBox gradient={element.props.backgroundGradient} style={wrapperStyle as any}>
82
86
  <LottieView
83
87
  source={{ uri: element.props.source }}
84
88
  autoPlay={element.props.autoPlay ?? true}
@@ -86,7 +90,7 @@ export const LottieElementComponent = ({ element, ctx }: Props): React.ReactElem
86
90
  speed={element.props.speed}
87
91
  style={styles.fill}
88
92
  />
89
- </View>
93
+ </GradientBox>
90
94
  );
91
95
  };
92
96
 
@@ -4,6 +4,7 @@ import { View, Text, TouchableOpacity } from "react-native";
4
4
  import { BaseBoxProps, BaseBoxPropsSchema } from "./BaseBoxProps";
5
5
  import { UIElement } from "../types";
6
6
  import { RenderContext, dim } from "./shared";
7
+ import { GradientBox } from "./GradientBox";
7
8
 
8
9
  export type RadioGroupElementProps = BaseBoxProps & {
9
10
  variableName?: string;
@@ -85,8 +86,8 @@ export const RadioGroupComponent = ({ element, ctx }: Props): React.ReactElement
85
86
  const isHorizontal = element.props.direction === "horizontal";
86
87
 
87
88
  return (
88
- <View
89
- accessibilityRole="radiogroup"
89
+ <GradientBox
90
+ gradient={element.props.backgroundGradient}
90
91
  style={{
91
92
  flexDirection: isHorizontal ? "row" : "column",
92
93
  flexWrap: isHorizontal ? "wrap" : undefined,
@@ -103,6 +104,7 @@ export const RadioGroupComponent = ({ element, ctx }: Props): React.ReactElement
103
104
  borderWidth: element.props.borderWidth,
104
105
  borderRadius: element.props.borderRadius,
105
106
  borderColor: element.props.borderColor,
107
+ backgroundColor: element.props.backgroundGradient ? undefined : element.props.backgroundColor,
106
108
  opacity: element.props.opacity,
107
109
  }}
108
110
  >
@@ -177,6 +179,6 @@ export const RadioGroupComponent = ({ element, ctx }: Props): React.ReactElement
177
179
  </TouchableOpacity>
178
180
  );
179
181
  })}
180
- </View>
182
+ </GradientBox>
181
183
  );
182
184
  };
@@ -1,9 +1,9 @@
1
1
  import React from "react";
2
2
  import { z } from "zod";
3
- import { View } from "react-native";
4
3
  import { BaseBoxProps, BaseBoxPropsSchema } from "./BaseBoxProps";
5
4
  import { UIElement } from "../types";
6
5
  import { RenderContext, dim } from "./shared";
6
+ import { GradientBox } from "./GradientBox";
7
7
 
8
8
  export type StackElementProps = BaseBoxProps & {
9
9
  gap?: number;
@@ -24,13 +24,14 @@ type StackUIElement = Extract<UIElement, { type: "YStack" | "XStack" }>;
24
24
  type Props = {
25
25
  element: StackUIElement;
26
26
  ctx: RenderContext;
27
- parentType?: "XStack" | "YStack";
27
+ parentType?: "XStack" | "YStack" | "ZStack";
28
28
  };
29
29
 
30
30
  export const StackElementComponent = ({ element, ctx, parentType }: Props): React.ReactElement => {
31
31
  const p = element.props;
32
32
  return (
33
- <View
33
+ <GradientBox
34
+ gradient={p.backgroundGradient}
34
35
  style={{
35
36
  flexDirection: element.type === "XStack" ? "row" : "column",
36
37
  gap: p.gap,
@@ -53,7 +54,7 @@ export const StackElementComponent = ({ element, ctx, parentType }: Props): Reac
53
54
  margin: p.margin,
54
55
  marginHorizontal: p.marginHorizontal,
55
56
  marginVertical: p.marginVertical,
56
- backgroundColor: p.backgroundColor,
57
+ backgroundColor: p.backgroundGradient ? undefined : p.backgroundColor,
57
58
  borderWidth: p.borderWidth,
58
59
  borderRadius: p.borderRadius,
59
60
  borderColor: p.borderColor,
@@ -62,6 +63,6 @@ export const StackElementComponent = ({ element, ctx, parentType }: Props): Reac
62
63
  }}
63
64
  >
64
65
  {ctx.renderChildren(element.children, element.type)}
65
- </View>
66
+ </GradientBox>
66
67
  );
67
68
  };
@@ -4,6 +4,7 @@ import { Text } from "react-native";
4
4
  import { BaseBoxProps, BaseBoxPropsSchema } from "./BaseBoxProps";
5
5
  import { UIElement } from "../types";
6
6
  import { RenderContext, interpolate, dim } from "./shared";
7
+ import { GradientBox } from "./GradientBox";
7
8
 
8
9
  export type TextElementProps = BaseBoxProps & {
9
10
  content: string;
@@ -34,7 +35,7 @@ type TextUIElement = Extract<UIElement, { type: "Text" }>;
34
35
  type Props = {
35
36
  element: TextUIElement;
36
37
  ctx: RenderContext;
37
- parentType?: "XStack" | "YStack";
38
+ parentType?: "XStack" | "YStack" | "ZStack";
38
39
  };
39
40
 
40
41
  export const TextElementComponent = ({ element, ctx, parentType }: Props): React.ReactElement => {
@@ -45,19 +46,19 @@ export const TextElementComponent = ({ element, ctx, parentType }: Props): React
45
46
  ? interpolate(p.content, variables)
46
47
  : p.content;
47
48
 
48
- return (
49
+ const textNode = (
49
50
  <Text
50
51
  style={{
51
52
  flex: p.flex,
52
53
  flexShrink: p.flexShrink ?? (parentType === "XStack" ? 1 : undefined),
53
- flexGrow: p.flexGrow,
54
- alignSelf: p.alignSelf,
55
- width: dim(p.width),
56
- height: dim(p.height),
57
- minWidth: p.minWidth,
58
- maxWidth: p.maxWidth,
59
- minHeight: p.minHeight,
60
- maxHeight: p.maxHeight,
54
+ flexGrow: p.backgroundGradient ? undefined : p.flexGrow,
55
+ alignSelf: p.backgroundGradient ? undefined : p.alignSelf,
56
+ width: p.backgroundGradient ? undefined : dim(p.width),
57
+ height: p.backgroundGradient ? undefined : dim(p.height),
58
+ minWidth: p.backgroundGradient ? undefined : p.minWidth,
59
+ maxWidth: p.backgroundGradient ? undefined : p.maxWidth,
60
+ minHeight: p.backgroundGradient ? undefined : p.minHeight,
61
+ maxHeight: p.backgroundGradient ? undefined : p.maxHeight,
61
62
  fontSize: p.fontSize,
62
63
  fontWeight: p.fontWeight as any,
63
64
  fontFamily: p.fontFamily,
@@ -65,20 +66,55 @@ export const TextElementComponent = ({ element, ctx, parentType }: Props): React
65
66
  textAlign: p.textAlign,
66
67
  letterSpacing: p.letterSpacing,
67
68
  lineHeight: p.lineHeight,
68
- backgroundColor: p.backgroundColor,
69
- padding: p.padding,
70
- paddingHorizontal: p.paddingHorizontal,
71
- paddingVertical: p.paddingVertical,
72
- margin: p.margin,
73
- marginHorizontal: p.marginHorizontal,
74
- marginVertical: p.marginVertical,
75
- borderWidth: p.borderWidth,
76
- borderRadius: p.borderRadius,
77
- borderColor: p.borderColor,
78
- opacity: p.opacity,
69
+ backgroundColor: p.backgroundGradient ? undefined : p.backgroundColor,
70
+ padding: p.backgroundGradient ? undefined : p.padding,
71
+ paddingHorizontal: p.backgroundGradient ? undefined : p.paddingHorizontal,
72
+ paddingVertical: p.backgroundGradient ? undefined : p.paddingVertical,
73
+ margin: p.backgroundGradient ? undefined : p.margin,
74
+ marginHorizontal: p.backgroundGradient ? undefined : p.marginHorizontal,
75
+ marginVertical: p.backgroundGradient ? undefined : p.marginVertical,
76
+ borderWidth: p.backgroundGradient ? undefined : p.borderWidth,
77
+ borderRadius: p.backgroundGradient ? undefined : p.borderRadius,
78
+ borderColor: p.backgroundGradient ? undefined : p.borderColor,
79
+ opacity: p.backgroundGradient ? undefined : p.opacity,
79
80
  }}
80
81
  >
81
82
  {content}
82
83
  </Text>
83
84
  );
85
+
86
+ if (p.backgroundGradient) {
87
+ return (
88
+ <GradientBox
89
+ gradient={p.backgroundGradient}
90
+ style={{
91
+ flex: p.flex,
92
+ flexShrink: p.flexShrink ?? (parentType === "XStack" ? 1 : undefined),
93
+ flexGrow: p.flexGrow,
94
+ alignSelf: p.alignSelf,
95
+ width: dim(p.width),
96
+ height: dim(p.height),
97
+ minWidth: p.minWidth,
98
+ maxWidth: p.maxWidth,
99
+ minHeight: p.minHeight,
100
+ maxHeight: p.maxHeight,
101
+ padding: p.padding,
102
+ paddingHorizontal: p.paddingHorizontal,
103
+ paddingVertical: p.paddingVertical,
104
+ margin: p.margin,
105
+ marginHorizontal: p.marginHorizontal,
106
+ marginVertical: p.marginVertical,
107
+ borderWidth: p.borderWidth,
108
+ borderRadius: p.borderRadius,
109
+ borderColor: p.borderColor,
110
+ opacity: p.opacity,
111
+ overflow: "hidden",
112
+ }}
113
+ >
114
+ {textNode}
115
+ </GradientBox>
116
+ );
117
+ }
118
+
119
+ return textNode;
84
120
  };
@@ -1,10 +1,11 @@
1
1
  import React, { useEffect } from "react";
2
2
  import { z } from "zod";
3
- import { View, Text, StyleSheet } from "react-native";
3
+ import { Text, StyleSheet } from "react-native";
4
4
  import { BaseBoxProps, BaseBoxPropsSchema } from "./BaseBoxProps";
5
5
  import { UIElement } from "../types";
6
6
  import { RenderContext, dim } from "./shared";
7
7
  import { getTextStyle } from "../../../Theme/helpers";
8
+ import { GradientBox } from "./GradientBox";
8
9
 
9
10
  export type VideoElementProps = BaseBoxProps & {
10
11
  url: string;
@@ -12,6 +13,7 @@ export type VideoElementProps = BaseBoxProps & {
12
13
  loop?: boolean;
13
14
  muted?: boolean;
14
15
  controls?: boolean;
16
+ contentFit?: "contain" | "cover" | "fill";
15
17
  };
16
18
 
17
19
  export const VideoElementPropsSchema = BaseBoxPropsSchema.extend({
@@ -20,6 +22,7 @@ export const VideoElementPropsSchema = BaseBoxPropsSchema.extend({
20
22
  loop: z.boolean().optional(),
21
23
  muted: z.boolean().optional(),
22
24
  controls: z.boolean().optional(),
25
+ contentFit: z.enum(["contain", "cover", "fill"]).optional(),
23
26
  });
24
27
 
25
28
  type VideoUIElement = Extract<UIElement, { type: "Video" }>;
@@ -50,6 +53,7 @@ try {
50
53
  style={style}
51
54
  allowsFullscreen={false}
52
55
  nativeControls={element.props.controls ?? false}
56
+ contentFit={element.props.contentFit ?? "contain"}
53
57
  />
54
58
  );
55
59
  };
@@ -76,7 +80,7 @@ export const VideoElementRenderer = ({ element, ctx }: Props): React.ReactElemen
76
80
  minHeight: element.props.minHeight,
77
81
  maxHeight: element.props.maxHeight,
78
82
  opacity: element.props.opacity,
79
- backgroundColor: element.props.backgroundColor,
83
+ backgroundColor: element.props.backgroundGradient ? undefined : element.props.backgroundColor,
80
84
  margin: element.props.margin,
81
85
  marginHorizontal: element.props.marginHorizontal,
82
86
  marginVertical: element.props.marginVertical,
@@ -91,18 +95,21 @@ export const VideoElementRenderer = ({ element, ctx }: Props): React.ReactElemen
91
95
 
92
96
  if (!VideoElementComponent) {
93
97
  return (
94
- <View style={[wrapperStyle, styles.mediaFallback, { backgroundColor: theme.colors.neutral.lowest }]}>
98
+ <GradientBox
99
+ gradient={element.props.backgroundGradient}
100
+ style={[wrapperStyle, styles.mediaFallback, { backgroundColor: theme.colors.neutral.lowest }] as any}
101
+ >
95
102
  <Text style={[styles.mediaFallbackText, getTextStyle(theme, "caption"), { color: theme.colors.text.tertiary }]}>
96
103
  Install expo-video to render videos.
97
104
  </Text>
98
- </View>
105
+ </GradientBox>
99
106
  );
100
107
  }
101
108
 
102
109
  return (
103
- <View style={wrapperStyle}>
110
+ <GradientBox gradient={element.props.backgroundGradient} style={wrapperStyle as any}>
104
111
  <VideoElementComponent element={element} style={styles.fill} />
105
- </View>
112
+ </GradientBox>
106
113
  );
107
114
  };
108
115
 
@@ -0,0 +1,60 @@
1
+ import React from "react";
2
+ import { View } from "react-native";
3
+ import { BaseBoxProps, BaseBoxPropsSchema } from "./BaseBoxProps";
4
+ import { UIElement } from "../types";
5
+ import { RenderContext, dim } from "./shared";
6
+ import { GradientBox } from "./GradientBox";
7
+
8
+ export type ZStackElementProps = BaseBoxProps;
9
+ export const ZStackElementPropsSchema = BaseBoxPropsSchema;
10
+
11
+ type ZStackUIElement = Extract<UIElement, { type: "ZStack" }>;
12
+
13
+ type Props = {
14
+ element: ZStackUIElement;
15
+ ctx: RenderContext;
16
+ };
17
+
18
+ export const ZStackElementComponent = ({ element, ctx }: Props): React.ReactElement => {
19
+ const p = element.props;
20
+ return (
21
+ <GradientBox
22
+ gradient={p.backgroundGradient}
23
+ style={{
24
+ position: "relative",
25
+ flex: p.flex,
26
+ flexShrink: p.flexShrink,
27
+ flexGrow: p.flexGrow,
28
+ alignSelf: p.alignSelf,
29
+ width: dim(p.width),
30
+ height: dim(p.height),
31
+ minWidth: p.minWidth,
32
+ maxWidth: p.maxWidth,
33
+ minHeight: p.minHeight,
34
+ maxHeight: p.maxHeight,
35
+ padding: p.padding,
36
+ paddingHorizontal: p.paddingHorizontal,
37
+ paddingVertical: p.paddingVertical,
38
+ margin: p.margin,
39
+ marginHorizontal: p.marginHorizontal,
40
+ marginVertical: p.marginVertical,
41
+ backgroundColor: p.backgroundGradient ? undefined : p.backgroundColor,
42
+ borderWidth: p.borderWidth,
43
+ borderRadius: p.borderRadius,
44
+ borderColor: p.borderColor,
45
+ overflow: p.overflow,
46
+ opacity: p.opacity,
47
+ }}
48
+ >
49
+ {element.children.map((child) => (
50
+ <View
51
+ key={child.id}
52
+ pointerEvents="box-none"
53
+ style={{ position: "absolute", top: 0, left: 0, right: 0, bottom: 0 }}
54
+ >
55
+ {ctx.renderChildren([child], "ZStack")}
56
+ </View>
57
+ ))}
58
+ </GradientBox>
59
+ );
60
+ };
@@ -14,11 +14,12 @@ import { CheckboxGroupComponent } from "./CheckboxGroupElement";
14
14
  import { ButtonElementComponent } from "./ButtonElement";
15
15
  import { DatePickerElementComponent } from "./DatePickerElement";
16
16
  import { CarouselElementComponent } from "./CarouselElement";
17
+ import { ZStackElementComponent } from "./ZStackElement";
17
18
 
18
19
  export const renderElement = (
19
20
  element: UIElement,
20
21
  ctx: RenderContext,
21
- parentType?: "XStack" | "YStack"
22
+ parentType?: "XStack" | "YStack" | "ZStack"
22
23
  ): React.ReactNode => {
23
24
  if (element.type === "YStack" || element.type === "XStack") {
24
25
  return <StackElementComponent key={element.id} element={element} ctx={ctx} parentType={parentType} />;
@@ -72,5 +73,9 @@ export const renderElement = (
72
73
  return <CarouselElementComponent key={element.id} element={element} ctx={ctx} />;
73
74
  }
74
75
 
76
+ if (element.type === "ZStack") {
77
+ return <ZStackElementComponent key={element.id} element={element} ctx={ctx} />;
78
+ }
79
+
75
80
  return null;
76
81
  };
@@ -8,7 +8,7 @@ export type RenderContext = {
8
8
  variables: Record<string, ComposableVariableEntry>;
9
9
  setVariable: (key: string, entry: ComposableVariableEntry) => void;
10
10
  onContinue: () => void;
11
- renderChildren: (elements: UIElement[], parentType: "XStack" | "YStack") => React.ReactNode;
11
+ renderChildren: (elements: UIElement[], parentType: "XStack" | "YStack" | "ZStack") => React.ReactNode;
12
12
  };
13
13
 
14
14
  export const interpolate = (template: string, variables: Record<string, ComposableVariableEntry>): string =>
@@ -13,6 +13,7 @@ import { type RadioGroupElementProps, RadioGroupElementPropsSchema } from "./ele
13
13
  import { type CheckboxGroupElementProps, CheckboxGroupElementPropsSchema } from "./elements/CheckboxGroupElement";
14
14
  import { type DatePickerElementProps, DatePickerElementPropsSchema } from "./elements/DatePickerElement";
15
15
  import { type CarouselElementProps, CarouselElementPropsSchema } from "./elements/CarouselElement";
16
+ import { type ZStackElementProps, ZStackElementPropsSchema } from "./elements/ZStackElement";
16
17
 
17
18
  export type { BaseBoxProps } from "./elements/BaseBoxProps";
18
19
  export { BaseBoxPropsSchema } from "./elements/BaseBoxProps";
@@ -29,6 +30,7 @@ export type { RadioGroupElementProps } from "./elements/RadioGroupElement";
29
30
  export type { CheckboxGroupElementProps } from "./elements/CheckboxGroupElement";
30
31
  export type { DatePickerElementProps } from "./elements/DatePickerElement";
31
32
  export type { CarouselElementProps } from "./elements/CarouselElement";
33
+ export type { ZStackElementProps } from "./elements/ZStackElement";
32
34
 
33
35
  // UIElement union — must live here (not in elements/) to avoid circular deps
34
36
  // because the Stack variant's children: UIElement[] references itself.
@@ -112,6 +114,13 @@ export type UIElement =
112
114
  type: "Carousel";
113
115
  props: CarouselElementProps;
114
116
  children: UIElement[];
117
+ }
118
+ | {
119
+ id: string;
120
+ name?: string;
121
+ type: "ZStack";
122
+ props: ZStackElementProps;
123
+ children: UIElement[];
115
124
  };
116
125
 
117
126
  export const UIElementSchema: z.ZodType<UIElement> = z.lazy(() =>
@@ -196,6 +205,13 @@ export const UIElementSchema: z.ZodType<UIElement> = z.lazy(() =>
196
205
  props: CarouselElementPropsSchema,
197
206
  children: z.array(UIElementSchema),
198
207
  }),
208
+ z.object({
209
+ id: z.string(),
210
+ name: z.string().optional(),
211
+ type: z.literal("ZStack"),
212
+ props: ZStackElementPropsSchema,
213
+ children: z.array(UIElementSchema),
214
+ }),
199
215
  ])
200
216
  );
201
217
 
@@ -211,7 +227,7 @@ export const ComposableScreenStepTypeSchema = z.object({
211
227
  payload: ComposableScreenStepPayloadSchema,
212
228
  customPayload: CustomPayloadSchema,
213
229
  continueButtonLabel: z.string().optional().default("Continue"),
214
- figmaUrl: z.string().nullable(),
230
+ figmaUrl: z.string().nullish(),
215
231
  });
216
232
 
217
233
  export type ComposableScreenStepType = z.infer<typeof ComposableScreenStepTypeSchema>;