related-ui-components 1.6.1 → 1.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.
@@ -1 +1 @@
1
- {"version":3,"file":"ScratchCard.d.ts","sourceRoot":"","sources":["../../../../../src/components/ScratchCard/ScratchCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAKN,MAAM,OAAO,CAAC;AAiBf,OAAO,EACL,SAAS,EAET,SAAS,EAET,kBAAkB,EAEnB,MAAM,cAAc,CAAC;AAQtB,KAAK,gBAAgB,GAAG;IACtB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAC3B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;CAC1B,CAAC;AAEF,QAAA,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CA8K3C,CAAC;AAyBF,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"ScratchCard.d.ts","sourceRoot":"","sources":["../../../../../src/components/ScratchCard/ScratchCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAKN,MAAM,OAAO,CAAC;AAiBf,OAAO,EACL,SAAS,EAET,SAAS,EAET,kBAAkB,EAEnB,MAAM,cAAc,CAAC;AAYtB,KAAK,gBAAgB,GAAG;IACtB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAC3B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;CAC1B,CAAC;AAEF,QAAA,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAwL3C,CAAC;AAyBF,eAAe,WAAW,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "related-ui-components",
3
3
  "main": "./src/index.ts",
4
- "version": "1.6.1",
4
+ "version": "1.6.3",
5
5
  "scripts": {
6
6
  "start": "expo start",
7
7
  "reset-project": "node ./scripts/reset-project.js",
package/src/app.tsx CHANGED
@@ -7,6 +7,7 @@ import {
7
7
  ScrollView,
8
8
  FlatList,
9
9
  Alert,
10
+ Modal, // Import Modal
10
11
  } from "react-native";
11
12
  import { Ionicons } from "@expo/vector-icons";
12
13
  import { RelatedProvider, useTheme } from "./theme";
@@ -15,212 +16,91 @@ import {
15
16
  Filters,
16
17
  Popup,
17
18
  RedemptionOption,
18
- ScratchCard,
19
+ ScratchCard, // Your component
19
20
  ScratchCardContent,
20
21
  UnlockRewards,
21
22
  } from "./components";
22
23
  import { SafeAreaView } from "react-native-safe-area-context";
23
- import SelectAmount from "./components/SelectAmount/SelectAmount";
24
- import Slider from "@react-native-community/slider";
25
- import SummaryBar from "./components/TravelBooking/SummaryBar";
26
- import NumericStepper from "./components/NumericStepper/NumericStepper";
27
- import FlightSummaryBar from "./components/TravelBooking/FlightSummary";
28
- import HotelSummaryBar from "./components/TravelBooking/HotelSummary";
29
- import TabSelector from "./components/TravelBooking/TabSelector";
30
- import FlightForm from "./components/TravelBooking/FlightForm";
31
- import DateRangePicker from "./components/DateRangePicker/DateRangePicker";
32
- import HotelForm from "./components/TravelBooking/HotelForm";
33
- import CarRentalForm from "./components/TravelBooking/CarRentalForm";
34
- import TravelBooking from "./components/TravelBooking/TravelBooking";
35
- import { GestureHandlerRootView } from "react-native-gesture-handler";
36
- // import BRANDS from "./constants/BRANDS";
24
+ // ... other imports
25
+ import { GestureHandlerRootView } from "react-native-gesture-handler"; // Ensure import
37
26
 
38
27
  export default function App() {
39
28
  const { theme } = useTheme();
40
- const [filtersVisible, setFiltersVisible] = useState(false);
41
- const [mode, setMode] = useState<"flight" | "hotel">("flight");
29
+ // ... other state and constants
42
30
 
43
- // Define some sort options for the filter
44
- const sortOptions = [
45
- { id: 1, name: "Price: Low to High", value: "price_asc" },
46
- { id: 2, name: "Price: High to Low", value: "price_desc" },
47
- { id: 3, name: "Newest", value: "newest" },
48
- ];
49
-
50
- const iconSize = 24;
51
- const iconColor = theme.onSurface;
52
-
53
- const redemptionOption = [
54
- {
55
- icon: (
56
- <Ionicons name="bag-handle-outline" size={iconSize} color={iconColor} />
57
- ),
58
- key: "redemptionOptions.onlineShopping", // Use translation key
59
- orientation: "horizontal",
60
- width: 150,
61
- },
62
- {
63
- icon: (
64
- <Ionicons name="ticket-outline" size={iconSize} color={iconColor} />
65
- ),
66
- key: "redemptionOptions.eVouchers", // Use translation key
67
- width: 105,
68
- },
69
- {
70
- icon: <Ionicons name="cash-outline" size={iconSize} color={iconColor} />,
71
- key: "redemptionOptions.cashback", // Use translation key
72
- width: 105,
73
- },
74
- {
75
- icon: <Ionicons name="heart-outline" size={iconSize} color={iconColor} />,
76
- key: "redemptionOptions.donate", // Use translation key
77
- width: 87,
78
- },
79
- {
80
- icon: (
81
- <Ionicons name="airplane-outline" size={iconSize} color={iconColor} />
82
- ),
83
- key: "redemptionOptions.travel", // Use translation key
84
- width: 87,
85
- },
86
- {
87
- icon: (
88
- <Ionicons
89
- name="swap-horizontal-outline"
90
- size={iconSize}
91
- color={iconColor}
92
- />
93
- ),
94
- key: "redemptionOptions.pointsExchange", // Use translation key
95
- width: 87,
96
- },
97
- {
98
- icon: <Ionicons name="send-outline" size={iconSize} color={iconColor} />,
99
- key: "redemptionOptions.transferPoints", // Use translation key
100
- width: 87,
101
- },
102
- ];
103
-
104
- const redemptionOptions = redemptionOption.map((item) => ({
105
- ...item,
106
- text: "Online shopping",
107
- }));
108
- const debounceTimerRef = useRef<NodeJS.Timeout | null>(null);
109
-
110
- const rewardsData = [
111
- {
112
- icon: <Ionicons name="water-outline" size={24} color={theme.helper} />,
113
- activeIcon: <Ionicons name="water" size={24} color={theme.primary} />,
114
- title: "Aqua Guardian",
115
- description:
116
- "Maintain water usage below the community average for a month.",
117
- isActive: false,
118
- status: "0/1",
119
- statusBackgroundColor: theme.disabled,
120
- statusTextColor: theme.text,
121
- },
122
- {
123
- icon: <Ionicons name="build-outline" size={24} color={theme.helper} />,
124
- activeIcon: <Ionicons name="build" size={24} color={theme.secondary} />,
125
- title: "Leak Detective",
126
- description: "Successfully report and fix a water leak on your property.",
127
- isActive: true,
128
- status: "1/1",
129
- statusBackgroundColor: theme.primary,
130
- statusTextColor: theme.secondary,
131
- },
132
- {
133
- icon: <Ionicons name="leaf-outline" size={24} color={theme.helper} />,
134
- activeIcon: <Ionicons name="leaf" size={24} color={theme.primary} />,
135
- title: "Eco-Warrior",
136
- description:
137
- "Implement a rainwater harvesting system or greywater recycling.",
138
- isActive: false,
139
- status: "0/1",
140
- statusBackgroundColor: theme.disabled,
141
- statusTextColor: theme.text,
142
- },
143
- {
144
- icon: <Ionicons name="leaf-outline" size={24} color={theme.helper} />,
145
- activeIcon: <Ionicons name="leaf" size={24} color={theme.primary} />,
146
- title: "Eco-Warrior",
147
- description:
148
- "Implement a rainwater harvesting system or greywater recycling.",
149
- isActive: false,
150
- status: "0/1",
151
- statusBackgroundColor: theme.disabled,
152
- statusTextColor: theme.text,
153
- },
154
- {
155
- icon: <Ionicons name="leaf-outline" size={24} color={theme.helper} />,
156
- activeIcon: <Ionicons name="leaf" size={24} color={theme.primary} />,
157
- title: "Eco-Warrior",
158
- description:
159
- "Implement a rainwater harvesting system or greywater recycling.",
160
- isActive: false,
161
- status: "0/1",
162
- statusBackgroundColor: theme.disabled,
163
- statusTextColor: theme.text,
164
- },
165
- {
166
- icon: <Ionicons name="leaf-outline" size={24} color={theme.helper} />,
167
- activeIcon: <Ionicons name="leaf" size={24} color={theme.primary} />,
168
- title: "Eco-Warrior",
169
- description:
170
- "Implement a rainwater harvesting system or greywater recycling.",
171
- isActive: false,
172
- status: "0/1",
173
- statusBackgroundColor: theme.disabled,
174
- statusTextColor: theme.text,
175
- },
176
- {
177
- icon: <Ionicons name="leaf-outline" size={24} color={theme.helper} />,
178
- activeIcon: <Ionicons name="leaf" size={24} color={theme.primary} />,
179
- title: "Eco-Warrior",
180
- description:
181
- "Implement a rainwater harvesting system or greywater recycling.",
182
- isActive: false,
183
- status: "0/1",
184
- statusBackgroundColor: theme.disabled,
185
- statusTextColor: theme.text,
186
- },
187
- ];
31
+ // State to control modal visibility
32
+ const [isScratchModalVisible, setScratchModalVisible] = useState(false); // Example state
188
33
 
189
34
  return (
190
- <GestureHandlerRootView>
35
+ // Root view for the main app
36
+ <GestureHandlerRootView style={{ flex: 1 }}>
191
37
  <RelatedProvider>
192
38
  <SafeAreaView
193
- style={{ padding: 10, flex: 1, backgroundColor: theme.background }}
39
+ style={{ flex: 1, padding: 10, backgroundColor: theme.background }}
194
40
  >
195
- <ScratchCard
196
- backgroundColor="#8A2BE2"
197
- text="Scratch to reveal your prize!"
198
- textFontColor="#FFFFFF"
199
- textFontSize={18}
200
- width={300}
201
- height={150}
202
- // onScratched={() => alert("Congratulations! You won a prize!")}
203
- >
204
- <ScratchCardContent style={{ backgroundColor: "#FFD700" }}>
205
- <Text style={{ fontSize: 24, fontWeight: "bold", color: "#000" }}>
206
- 50% OFF COUPON
207
- </Text>
208
- <Text style={{ marginTop: 8, color: "#333" }}>
209
- Use code: SCRATCH50
210
- </Text>
211
- </ScratchCardContent>
212
- </ScratchCard>
213
- {/* <UnlockRewards
214
- title="Your Rewards"
215
- description="Complete tasks to unlock special benefits"
216
- rewards={rewardsData}
217
- // onClose={handleClose}
218
- showCloseIcon={true}
219
- closeIconVariant="nested"
220
- topBackgroundHeight={200}
221
- customCloseIcon={<Ionicons name="close-circle" size={28} color={theme.primary} />}
222
- /> */}
223
- {/* <Popup title="TEST" content="TEST" visible onClose={()=>{}} backgroundImage={require("@/assets/images/namshi-banner.png")} containerStyle={{height: 300}}></Popup> */}
41
+ {/* Example Button to open the modal */}
42
+ <TouchableOpacity
43
+ onPress={() => setScratchModalVisible(true)}
44
+ style={styles.testButton}
45
+ >
46
+ <Text style={styles.buttonText}>Show Scratch Card Modal</Text>
47
+ </TouchableOpacity>
48
+
49
+ {/* --- The Modal --- */}
50
+ <Modal
51
+ visible={isScratchModalVisible}
52
+ onRequestClose={() => setScratchModalVisible(false)} // Allow closing
53
+ transparent={true} // Example: make it transparent
54
+ animationType="slide" // Example animation
55
+ >
56
+ {/* Root view specifically for the modal's content */}
57
+ <GestureHandlerRootView style={styles.modalRootView}>
58
+ {/* Optional: Add a background overlay */}
59
+ <View style={styles.modalOverlay}>
60
+ {/* Center the card or position as needed */}
61
+ <View style={styles.modalContentContainer}>
62
+ <ScratchCard
63
+ backgroundColor="#8A2BE2"
64
+ text="Scratch to reveal your prize!"
65
+ textFontColor="#FFFFFF"
66
+ textFontSize={18}
67
+ width={300}
68
+ height={150}
69
+ onScratched={() => {
70
+ Alert.alert("Congratulations!", "You won a prize!");
71
+ // Optionally close modal after scratching
72
+ // setTimeout(() => setScratchModalVisible(false), 500);
73
+ }}
74
+ >
75
+ <ScratchCardContent style={{ backgroundColor: "#FFD700" }}>
76
+ <Text
77
+ style={{
78
+ fontSize: 24,
79
+ fontWeight: "bold",
80
+ color: "#000",
81
+ }}
82
+ >
83
+ 50% OFF COUPON
84
+ </Text>
85
+ <Text style={{ marginTop: 8, color: "#333" }}>
86
+ Use code: SCRATCH50
87
+ </Text>
88
+ </ScratchCardContent>
89
+ </ScratchCard>
90
+
91
+ {/* Button to close the modal */}
92
+ <TouchableOpacity
93
+ onPress={() => setScratchModalVisible(false)}
94
+ style={styles.closeButton}
95
+ >
96
+ <Text style={styles.buttonText}>Close</Text>
97
+ </TouchableOpacity>
98
+ </View>
99
+ </View>
100
+ </GestureHandlerRootView>
101
+ </Modal>
102
+
103
+ {/* Other app content can go here */}
224
104
  </SafeAreaView>
225
105
  </RelatedProvider>
226
106
  </GestureHandlerRootView>
@@ -228,17 +108,14 @@ export default function App() {
228
108
  }
229
109
 
230
110
  const styles = StyleSheet.create({
231
- container: {
232
- flex: 1,
233
- backgroundColor: "black",
234
- padding: 10,
235
- },
111
+ // ... your existing styles
236
112
  testButton: {
237
113
  backgroundColor: "#4a90e2",
238
114
  paddingVertical: 12,
239
115
  paddingHorizontal: 30,
240
116
  borderRadius: 8,
241
117
  marginBottom: 20,
118
+ alignSelf: "center",
242
119
  },
243
120
  buttonText: {
244
121
  color: "#FFFFFF",
@@ -246,4 +123,28 @@ const styles = StyleSheet.create({
246
123
  fontWeight: "bold",
247
124
  textAlign: "center",
248
125
  },
126
+ // Styles for the Modal
127
+ modalRootView: {
128
+ flex: 1, // Important for the root view to take up space
129
+ },
130
+ modalOverlay: {
131
+ flex: 1,
132
+ backgroundColor: "rgba(0, 0, 0, 0.5)", // Semi-transparent background
133
+ justifyContent: "center", // Center content vertically
134
+ alignItems: "center", // Center content horizontally
135
+ },
136
+ modalContentContainer: {
137
+ // Optional: Add padding or background to the content area if needed
138
+ // backgroundColor: 'white',
139
+ // padding: 20,
140
+ // borderRadius: 10,
141
+ alignItems: "center", // Center items like the close button
142
+ },
143
+ closeButton: {
144
+ marginTop: 20,
145
+ backgroundColor: "#d9534f",
146
+ paddingVertical: 10,
147
+ paddingHorizontal: 25,
148
+ borderRadius: 8,
149
+ },
249
150
  });
@@ -30,7 +30,11 @@ import {
30
30
  } from "react-native";
31
31
  // Import runOnJS and useSharedValue
32
32
  import { runOnJS, useSharedValue } from "react-native-reanimated";
33
- import { Gesture, GestureDetector } from "react-native-gesture-handler";
33
+ import {
34
+ Gesture,
35
+ GestureDetector,
36
+ GestureHandlerRootView,
37
+ } from "react-native-gesture-handler";
34
38
 
35
39
  // Ignore specific warning if it appears, related to path mutation - use cautiously
36
40
  // LogBox.ignoreLogs(['Skia: SkPath.Make()']);
@@ -48,7 +52,7 @@ type ScratchCardProps = {
48
52
  textFont?: ImageRequireSource;
49
53
  textFontSize?: number;
50
54
  textFontColor?: string;
51
- onScratched?: () => void;
55
+ onScratched?: () => void;
52
56
  };
53
57
 
54
58
  const ScratchCard: React.FC<ScratchCardProps> = ({
@@ -56,7 +60,7 @@ const ScratchCard: React.FC<ScratchCardProps> = ({
56
60
  children,
57
61
  image,
58
62
  brushStrokeWidth = 50,
59
- revealThreshold = 0.8,
63
+ revealThreshold = 0.8,
60
64
  width = 300,
61
65
  height = 300,
62
66
  backgroundColor = "#CCCCCC",
@@ -78,29 +82,32 @@ const ScratchCard: React.FC<ScratchCardProps> = ({
78
82
  const path = useSharedValue<SkPath>(Skia.Path.Make());
79
83
 
80
84
  useEffect(() => {
81
- path.value = Skia.Path.Make();
82
- isThresholdReached.value = false
83
- setScratched(false);
85
+ path.value = Skia.Path.Make();
86
+ isThresholdReached.value = false;
87
+ setScratched(false);
84
88
  }, [areaWidth, areaHeight]);
85
89
 
86
- const handleLayout = useCallback((event: any) => {
87
- const { width: newWidth, height: newHeight } = event.nativeEvent.layout;
88
- if (newWidth > 0 && newHeight > 0) {
89
- if (newWidth !== areaWidth || newHeight !== areaHeight) {
90
- setSize([newWidth, newHeight]);
91
- }
92
- if (!isLayoutReady) {
93
- setLayoutReady(true);
90
+ const handleLayout = useCallback(
91
+ (event: any) => {
92
+ const { width: newWidth, height: newHeight } = event.nativeEvent.layout;
93
+ if (newWidth > 0 && newHeight > 0) {
94
+ if (newWidth !== areaWidth || newHeight !== areaHeight) {
95
+ setSize([newWidth, newHeight]);
96
+ }
97
+ if (!isLayoutReady) {
98
+ setLayoutReady(true);
99
+ }
100
+ } else {
101
+ setLayoutReady(false);
94
102
  }
95
- } else {
96
- setLayoutReady(false);
97
- }
98
- }, [areaWidth, areaHeight, isLayoutReady]);
103
+ },
104
+ [areaWidth, areaHeight, isLayoutReady]
105
+ );
99
106
 
100
107
  const revealCardOnJS = useCallback(() => {
101
108
  setScratched(true);
102
- onScratched?.();
103
- }, [onScratched]);
109
+ onScratched?.();
110
+ }, [onScratched]);
104
111
 
105
112
  const pan = Gesture.Pan()
106
113
  .averageTouches(true)
@@ -144,14 +151,19 @@ const ScratchCard: React.FC<ScratchCardProps> = ({
144
151
  } catch (error) {
145
152
  console.error("ScratchCard: Error in onChange (UI Thread):", error);
146
153
  }
147
- })
154
+ });
148
155
 
149
156
  const textMetrics = React.useMemo(() => {
150
157
  if (loadedFont && text && areaWidth > 0 && areaHeight > 0) {
151
158
  const metrics = loadedFont.measureText(text);
152
159
  const textX = areaWidth / 2 - metrics.width / 2;
153
160
  const textY = areaHeight / 2 + metrics.height / 3;
154
- return { x: textX, y: textY, width: metrics.width, height: metrics.height };
161
+ return {
162
+ x: textX,
163
+ y: textY,
164
+ width: metrics.width,
165
+ height: metrics.height,
166
+ };
155
167
  }
156
168
  return null;
157
169
  }, [loadedFont, text, areaWidth, areaHeight]);
@@ -159,71 +171,73 @@ const ScratchCard: React.FC<ScratchCardProps> = ({
159
171
  const canRenderCanvas = isLayoutReady && areaWidth > 0 && areaHeight > 0;
160
172
 
161
173
  return (
162
- <View
163
- onLayout={handleLayout}
164
- style={[styles.container, style, { width, height }]}
165
- >
166
- <View style={styles.content}>{children}</View>
167
-
168
- {!isScratched && canRenderCanvas && (
169
- <GestureDetector gesture={pan}>
170
- <Canvas style={styles.canvas}>
171
- <Mask
172
- mode="luminance"
173
- mask={
174
- <Group>
175
- <Rect
176
- x={0}
177
- y={0}
178
- width={areaWidth}
179
- height={areaHeight}
180
- color="white"
181
- />
182
- <Path
183
- path={path}
184
- color="black"
185
- style="stroke"
186
- strokeJoin="round"
187
- strokeCap="round"
188
- strokeWidth={brushStrokeWidth}
189
- />
190
- </Group>
191
- }
192
- >
193
- {loadedImg ? (
194
- <Image
195
- image={loadedImg}
196
- fit="cover"
197
- x={0}
198
- y={0}
199
- width={areaWidth}
200
- height={areaHeight}
201
- />
202
- ) : (
203
- <Group>
204
- <Rect
174
+ <GestureHandlerRootView>
175
+ <View
176
+ onLayout={handleLayout}
177
+ style={[styles.container, style, { width, height }]}
178
+ >
179
+ <View style={styles.content}>{children}</View>
180
+
181
+ {!isScratched && canRenderCanvas && (
182
+ <GestureDetector gesture={pan}>
183
+ <Canvas style={styles.canvas}>
184
+ <Mask
185
+ mode="luminance"
186
+ mask={
187
+ <Group>
188
+ <Rect
189
+ x={0}
190
+ y={0}
191
+ width={areaWidth}
192
+ height={areaHeight}
193
+ color="white"
194
+ />
195
+ <Path
196
+ path={path}
197
+ color="black"
198
+ style="stroke"
199
+ strokeJoin="round"
200
+ strokeCap="round"
201
+ strokeWidth={brushStrokeWidth}
202
+ />
203
+ </Group>
204
+ }
205
+ >
206
+ {loadedImg ? (
207
+ <Image
208
+ image={loadedImg}
209
+ fit="cover"
205
210
  x={0}
206
211
  y={0}
207
212
  width={areaWidth}
208
213
  height={areaHeight}
209
- color={backgroundColor}
210
214
  />
211
- {loadedFont && textMetrics && text ? (
212
- <Text
213
- x={textMetrics.x}
214
- y={textMetrics.y}
215
- text={text}
216
- color={textFontColor}
217
- font={loadedFont}
215
+ ) : (
216
+ <Group>
217
+ <Rect
218
+ x={0}
219
+ y={0}
220
+ width={areaWidth}
221
+ height={areaHeight}
222
+ color={backgroundColor}
218
223
  />
219
- ) : null}
220
- </Group>
221
- )}
222
- </Mask>
223
- </Canvas>
224
- </GestureDetector>
225
- )}
226
- </View>
224
+ {loadedFont && textMetrics && text ? (
225
+ <Text
226
+ x={textMetrics.x}
227
+ y={textMetrics.y}
228
+ text={text}
229
+ color={textFontColor}
230
+ font={loadedFont}
231
+ />
232
+ ) : null}
233
+ </Group>
234
+ )}
235
+ </Mask>
236
+ </Canvas>
237
+ </GestureDetector>
238
+ )}
239
+ </View>
240
+ </GestureHandlerRootView>
227
241
  );
228
242
  };
229
243
 
@@ -238,7 +252,7 @@ const styles = StyleSheet.create({
238
252
  left: 0,
239
253
  width: "100%",
240
254
  height: "100%",
241
- zIndex: 1,
255
+ zIndex: 1,
242
256
  },
243
257
  canvas: {
244
258
  position: "absolute",