related-ui-components 2.0.2 → 2.0.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,286 +1,266 @@
1
1
  // src/components/SelaDealCard/SelaDealCard.tsx
2
2
  import React from "react";
3
3
  import {
4
- ImageSourcePropType,
5
- StyleProp,
6
- ViewStyle,
7
- View,
8
- Text,
9
- TextStyle,
10
- DimensionValue,
11
- StyleSheet,
4
+ ImageSourcePropType,
5
+ StyleProp,
6
+ ViewStyle,
7
+ View,
8
+ Text,
9
+ TextStyle,
10
+ DimensionValue,
11
+ StyleSheet,
12
12
  } from "react-native";
13
13
  import Card from "../Card"; // Adjust path to your Card component
14
14
  import { useTheme } from "../../../theme/ThemeContext"; // Adjust path
15
+ import { ThemeType } from "../../../theme";
16
+ import { LockOverlay } from "../../LockOverlay";
15
17
 
16
18
  interface SelaDealCardProps {
17
- variant: "horizontal" | "vertical";
18
- backgroundImage: ImageSourcePropType;
19
- label?: string;
20
- labelStyle?: StyleProp<TextStyle>;
21
- labelContainerStyle?: StyleProp<ViewStyle>;
22
- providerName?: string;
23
- providerNameStyle?: StyleProp<TextStyle>;
24
- description?: string;
25
- descriptionStyle?: StyleProp<TextStyle>;
26
- price?: string;
27
- priceStyle?: StyleProp<TextStyle>;
28
- priceContainerStyle?: StyleProp<ViewStyle>;
29
- onPress?: () => void;
30
- style?: StyleProp<ViewStyle>; // Overall card style
31
- width?: DimensionValue;
32
- height?: DimensionValue;
33
- isRTL?: boolean;
34
- borderRadius?: number;
35
- contentColor?: string; // For text like providerName, description on the image
36
- labelBackgroundColor?: string;
37
- labelTextColor?: string;
38
- priceBackgroundColor?: string;
39
- priceTextColor?: string;
19
+ variant: "horizontal" | "vertical";
20
+ backgroundImage: ImageSourcePropType;
21
+ label?: string;
22
+ labelStyle?: StyleProp<TextStyle>;
23
+ labelContainerStyle?: StyleProp<ViewStyle>;
24
+ providerName?: string;
25
+ providerNameStyle?: StyleProp<TextStyle>;
26
+ description?: string;
27
+ descriptionStyle?: StyleProp<TextStyle>;
28
+ price?: string;
29
+ priceStyle?: StyleProp<TextStyle>;
30
+ priceContainerStyle?: StyleProp<ViewStyle>;
31
+ onPress?: () => void;
32
+ style?: StyleProp<ViewStyle>; // Overall card style
33
+ width?: DimensionValue;
34
+ height?: DimensionValue;
35
+ isRTL?: boolean;
36
+ borderRadius?: number;
37
+ contentColor?: string; // For text like providerName, description on the image
38
+ labelBackgroundColor?: string;
39
+ labelTextColor?: string;
40
+ priceBackgroundColor?: string;
41
+ priceTextColor?: string;
42
+ darkOverlayEnabled?: boolean; // New prop
43
+ darkOverlayColor?: string; // New prop for custom overlay color
44
+ lockOverlay?: boolean
40
45
  }
41
46
 
42
47
  const SelaDealCard: React.FC<SelaDealCardProps> = ({
43
- variant,
44
- backgroundImage,
45
- label,
46
- labelStyle,
47
- labelContainerStyle,
48
- providerName,
49
- providerNameStyle,
50
- description,
51
- descriptionStyle,
52
- price,
53
- priceStyle,
54
- priceContainerStyle,
55
- onPress,
56
- style,
57
- width = "100%",
58
- height = variant === "horizontal" ? 180 : 280, // Different default heights
59
- isRTL: propIsRTL,
60
- borderRadius = 12, // Default based on images
61
- contentColor,
62
- labelBackgroundColor,
63
- labelTextColor,
64
- priceBackgroundColor,
65
- priceTextColor,
48
+ variant,
49
+ backgroundImage,
50
+ label,
51
+ labelStyle,
52
+ labelContainerStyle,
53
+ providerName,
54
+ providerNameStyle,
55
+ description,
56
+ descriptionStyle,
57
+ price,
58
+ priceStyle,
59
+ priceContainerStyle,
60
+ onPress,
61
+ style,
62
+ width = "100%",
63
+ height = variant === "horizontal" ? 180 : 280, // Different default heights
64
+ isRTL: propIsRTL,
65
+ borderRadius = 12, // Default based on images
66
+ darkOverlayEnabled = true,
67
+ darkOverlayColor = "rgba(0, 0, 0, 0.3)",
68
+ lockOverlay = false
66
69
  }) => {
67
- const { theme, isRTL: themeIsRTL } = useTheme();
68
- const isRTL = propIsRTL !== undefined ? propIsRTL : themeIsRTL;
70
+ const { theme, isRTL: themeIsRTL } = useTheme();
71
+ const isRTL = propIsRTL !== undefined ? propIsRTL : themeIsRTL;
69
72
 
70
- // Default color for text directly on the image (e.g., provider name, description)
71
- // Provider name in images is often yellow, description white.
72
- // Consumers can override with providerNameStyle/descriptionStyle.
73
- const mainImageTextColor = contentColor || "#FFFFFF"; // Default to white
73
+ const styles = getStyles(theme, isRTL);
74
74
 
75
- // --- Label Styles ---
76
- // Image 1 (Horizontal "Offer"): White background, dark text.
77
- // Image 2 (Vertical "Booking"): Appears to be a light text on image, no distinct bg.
78
- // For consistency, let's assume label has a background.
79
- const actualLabelBgColor = labelBackgroundColor || theme.surface;
80
- const actualLabelTxtColor = labelTextColor || theme.onSurface;
75
+ const finalLabelContainerStyle: StyleProp<ViewStyle> = [
76
+ styles.labelContainerBase,
77
+ labelContainerStyle,
78
+ ];
79
+ const finalLabelStyle: StyleProp<TextStyle> = [
80
+ styles.labelTextBase,
81
+ labelStyle,
82
+ ];
81
83
 
82
- const finalLabelContainerStyle: StyleProp<ViewStyle> = [
83
- styles.labelContainerBase,
84
- { backgroundColor: actualLabelBgColor },
85
- labelContainerStyle,
86
- ];
87
- const finalLabelStyle: StyleProp<TextStyle> = [
88
- styles.labelTextBase,
89
- { color: actualLabelTxtColor },
90
- labelStyle,
91
- ];
84
+ const finalPriceContainerStyle: StyleProp<ViewStyle> = [
85
+ styles.priceContainerBase,
86
+ variant === "horizontal"
87
+ ? styles.priceContainerHorizontal
88
+ : styles.priceContainerVertical,
89
+ priceContainerStyle,
90
+ ];
91
+ const finalPriceStyle: StyleProp<TextStyle> = [
92
+ styles.priceTextBase,
93
+ priceStyle,
94
+ ];
92
95
 
93
- // --- Price Container Styles ---
94
- // Horizontal (Image 1): Bright cyan/teal background, dark text.
95
- const defaultHorizontalPriceBg = priceBackgroundColor || "#17D4C6";
96
- const defaultHorizontalPriceText = priceTextColor || "#000000";
97
- // Vertical (Image 2): Semi-transparent dark background, white text.
98
- const defaultVerticalPriceBg =
99
- priceBackgroundColor || "rgba(0, 0, 0, 0.5)";
100
- const defaultVerticalPriceText = priceTextColor || "#FFFFFF";
96
+ const providerTextStyle: StyleProp<TextStyle> = [
97
+ styles.providerNameBase,
98
+ { color: theme.onSurface, textAlign: isRTL ? "right" : "left" },
99
+ providerNameStyle,
100
+ ];
101
101
 
102
- const actualPriceBgColor =
103
- variant === "horizontal"
104
- ? defaultHorizontalPriceBg
105
- : defaultVerticalPriceBg;
106
- const actualPriceTxtColor =
107
- variant === "horizontal"
108
- ? defaultHorizontalPriceText
109
- : defaultVerticalPriceText;
110
-
111
- const finalPriceContainerStyle: StyleProp<ViewStyle> = [
112
- styles.priceContainerBase,
113
- { backgroundColor: actualPriceBgColor },
114
- variant === "horizontal"
115
- ? styles.priceContainerHorizontal
116
- : styles.priceContainerVertical,
117
- priceContainerStyle,
118
- ];
119
- const finalPriceStyle: StyleProp<TextStyle> = [
120
- styles.priceTextBase,
121
- { color: actualPriceTxtColor },
122
- priceStyle,
123
- ];
102
+ const descriptionTextStyle: StyleProp<TextStyle> = [
103
+ styles.descriptionBase,
104
+ { color: theme.onSurface, textAlign: isRTL ? "right" : "left" },
105
+ descriptionStyle,
106
+ ];
124
107
 
125
- // --- Text Styles for Content on Image ---
126
- const providerTextStyle: StyleProp<TextStyle> = [
127
- styles.providerNameBase,
128
- // In images, provider name is often yellow. This can be set via providerNameStyle.
129
- { color: mainImageTextColor, textAlign: isRTL ? "right" : "left" },
130
- providerNameStyle,
131
- ];
108
+ return (
109
+ <Card
110
+ onPress={onPress}
111
+ style={[styles.cardBase, { borderRadius, width, height }, style]}
112
+ backgroundImage={{
113
+ source: backgroundImage,
114
+ resizeMode: "cover",
115
+ }}
116
+ >
117
+ {darkOverlayEnabled && (
118
+ <View
119
+ style={[
120
+ StyleSheet.absoluteFill,
121
+ { backgroundColor: darkOverlayColor },
122
+ { borderRadius: borderRadius }
123
+ ]}
124
+ />
125
+ )}
132
126
 
133
- const descriptionTextStyle: StyleProp<TextStyle> = [
134
- styles.descriptionBase,
135
- { color: mainImageTextColor, textAlign: isRTL ? "right" : "left" },
136
- descriptionStyle,
137
- ];
127
+ <LockOverlay
128
+ visible={lockOverlay}
129
+ contentPosition={variant == "horizontal" ?
130
+ isRTL ? "top-left" : "top-right" :
131
+ isRTL ? "top-right" : "top-left"
132
+ }
133
+ iconSize={24}
134
+ text={""}
135
+ overlayOpacity={0.4}
136
+ />
138
137
 
139
- return (
140
- <Card
141
- onPress={onPress}
142
- style={[styles.cardBase, { borderRadius, width, height }, style]}
143
- backgroundImage={{
144
- source: backgroundImage,
145
- resizeMode: "cover",
146
- }}
147
- >
148
- <View style={styles.overlayContainer}>
149
- {/* Top Section (for Label) */}
150
- <View
151
- style={[
152
- styles.topSection,
153
- // Horizontal: LTR=left, RTL=right
154
- // Vertical: LTR=right, RTL=left
155
- {
156
- alignItems:
157
- variant === "horizontal"
158
- ? isRTL
159
- ? "flex-end"
160
- : "flex-start"
161
- : isRTL
162
- ? "flex-start"
163
- : "flex-end",
164
- },
165
- ]}
166
- >
167
- {label && (
168
- <View style={finalLabelContainerStyle}>
169
- <Text style={finalLabelStyle}>{label}</Text>
170
- </View>
171
- )}
172
- </View>
138
+ <View style={styles.overlayContainer}>
139
+ <View
140
+ style={[
141
+ styles.topSection,
142
+ {
143
+ alignItems:
144
+ variant === "horizontal"
145
+ ? isRTL
146
+ ? "flex-end"
147
+ : "flex-start"
148
+ : isRTL
149
+ ? "flex-start"
150
+ : "flex-end",
151
+ },
152
+ ]}
153
+ >
154
+ {label && (
155
+ <View style={finalLabelContainerStyle}>
156
+ <Text style={finalLabelStyle}>{label}</Text>
157
+ </View>
158
+ )}
159
+ </View>
173
160
 
174
- {/* Bottom Section (Provider, Description, Price) */}
175
- {variant === "horizontal" ? (
176
- <View style={styles.bottomContentHorizontal}>
177
- <View style={styles.textBlockHorizontal}>
178
- {providerName && (
179
- <Text style={providerTextStyle}>{providerName}</Text>
180
- )}
181
- {description && (
182
- <Text style={descriptionTextStyle}>{description}</Text>
183
- )}
161
+ {variant === "horizontal" ? (
162
+ <View style={styles.bottomContentHorizontal}>
163
+ <View style={styles.textBlockHorizontal}>
164
+ {providerName && (
165
+ <Text style={providerTextStyle}>{providerName}</Text>
166
+ )}
167
+ {description && (
168
+ <Text style={descriptionTextStyle}>{description}</Text>
169
+ )}
170
+ </View>
171
+ {price && (
172
+ <View style={finalPriceContainerStyle}>
173
+ <Text style={finalPriceStyle}>{price}</Text>
174
+ </View>
175
+ )}
176
+ </View>
177
+ ) : (
178
+ <View style={styles.bottomContentVertical}>
179
+ <View style={styles.textBlockVertical}>
180
+ {providerName && (
181
+ <Text style={providerTextStyle}>{providerName}</Text>
182
+ )}
183
+ {description && (
184
+ <Text style={descriptionTextStyle}>{description}</Text>
185
+ )}
186
+ </View>
187
+ {price && (
188
+ <View style={finalPriceContainerStyle}>
189
+ <Text style={finalPriceStyle}>{price}</Text>
190
+ </View>
191
+ )}
192
+ </View>
193
+ )}
184
194
  </View>
185
- {price && (
186
- <View style={finalPriceContainerStyle}>
187
- <Text style={finalPriceStyle}>{price}</Text>
188
- </View>
189
- )}
190
- </View>
191
- ) : (
192
- // Vertical Variant
193
- <View style={styles.bottomContentVertical}>
194
- <View style={styles.textBlockVertical}>
195
- {providerName && (
196
- <Text style={providerTextStyle}>{providerName}</Text>
197
- )}
198
- {description && (
199
- <Text style={descriptionTextStyle}>{description}</Text>
200
- )}
201
- </View>
202
- {price && (
203
- <View style={finalPriceContainerStyle}>
204
- <Text style={finalPriceStyle}>{price}</Text>
205
- </View>
206
- )}
207
- </View>
208
- )}
209
- </View>
210
- </Card>
211
- );
195
+ </Card>
196
+ );
212
197
  };
213
198
 
214
- const styles = StyleSheet.create({
215
- cardBase: {
216
- overflow: "hidden", // Ensures content respects borderRadius
217
- position: "relative",
218
- },
219
- overlayContainer: {
220
- flex: 1,
221
- padding: 16, // General padding for content from edges
222
- justifyContent: "space-between", // Pushes top and bottom sections apart
223
- // Optional: Add a LinearGradient here for a scrim if text readability is an issue
224
- },
225
- topSection: {
226
- // This view ensures the label is positioned correctly (start/end)
227
- // It will be at the top due to justifyContent: 'space-between' on overlayContainer
228
- },
229
- labelContainerBase: {
230
- paddingVertical: 6,
231
- paddingHorizontal: 12,
232
- borderRadius: 16, // Pill shape
233
- // alignSelf is determined by parent's alignItems in topSection
234
- },
235
- labelTextBase: {
236
- fontWeight: "600",
237
- fontSize: 13,
238
- },
239
- providerNameBase: {
240
- // Example: Yellow text in images "Altanfeethi", "Riva Jeddah Yacht Club"
241
- fontSize: 20,
242
- fontWeight: "bold",
243
- marginBottom: 2, // Space between provider name and description
244
- },
245
- descriptionBase: {
246
- // Example: White text in images "1 Year Membership", "2 hours Boat Trip"
247
- fontSize: 14,
248
- },
249
- priceContainerBase: {
250
- paddingVertical: 8,
251
- paddingHorizontal: 16,
252
- borderRadius: 10, // Rounded corners for the price box
253
- },
254
- priceTextBase: {
255
- fontWeight: "bold",
256
- fontSize: 16,
257
- },
258
- // --- Horizontal Variant Layout ---
259
- bottomContentHorizontal: {
260
- flexDirection: "row",
261
- justifyContent: "space-between",
262
- alignItems: "flex-end", // Aligns text block and price box to their bottom
263
- },
264
- textBlockHorizontal: {
265
- flex: 1, // Allows text to take available space, pushing price to the side
266
- marginRight: 10, // Space between text content and price box
267
- },
268
- priceContainerHorizontal: {
269
- // Specific styling for horizontal price box if needed (e.g., fixed width)
270
- // Default is to wrap content.
271
- },
272
- // --- Vertical Variant Layout ---
273
- bottomContentVertical: {
274
- flexDirection: "column", // Stacks text block and price box vertically
275
- },
276
- textBlockVertical: {
277
- marginBottom: 12, // Space between text content and price box
278
- // Text inside will align start/end based on isRTL and individual text styles
279
- },
280
- priceContainerVertical: {
281
- alignSelf: "stretch", // Makes the price box take the full width
282
- alignItems: "center", // Centers the price text within the wide box
283
- },
199
+ const getStyles = (theme: ThemeType, isRTL: boolean) => StyleSheet.create({
200
+ cardBase: {
201
+ overflow: "hidden",
202
+ position: "relative",
203
+ },
204
+ overlayContainer: {
205
+ flex: 1,
206
+ padding: 16,
207
+ justifyContent: "space-between",
208
+ },
209
+ topSection: {
210
+ },
211
+ labelContainerBase: {
212
+ paddingVertical: 6,
213
+ paddingHorizontal: 12,
214
+ borderRadius: 8,
215
+ backgroundColor: theme.background
216
+ },
217
+ labelTextBase: {
218
+ fontWeight: "600",
219
+ fontSize: 13,
220
+ color: theme.onBackground
221
+ },
222
+ providerNameBase: {
223
+ fontSize: 20,
224
+ fontWeight: "bold",
225
+ marginBottom: 2,
226
+ color: theme.secondary
227
+ },
228
+ descriptionBase: {
229
+ fontSize: 14,
230
+ color: theme.helper
231
+ },
232
+ priceContainerBase: {
233
+ paddingVertical: 8,
234
+ paddingHorizontal: 16,
235
+ borderRadius: 10,
236
+ backgroundColor: theme.primary
237
+ },
238
+ priceTextBase: {
239
+ fontWeight: "bold",
240
+ fontSize: 16,
241
+ color: theme.onPrimary
242
+ },
243
+ bottomContentHorizontal: {
244
+ flexDirection: isRTL ? "row-reverse" : "row",
245
+ justifyContent: "space-between",
246
+ alignItems: "flex-end",
247
+ },
248
+ textBlockHorizontal: {
249
+ flex: 1,
250
+ marginRight: 10,
251
+ },
252
+ priceContainerHorizontal: {
253
+ },
254
+ bottomContentVertical: {
255
+ flexDirection: "column",
256
+ },
257
+ textBlockVertical: {
258
+ marginBottom: 12,
259
+ },
260
+ priceContainerVertical: {
261
+ alignSelf: "stretch",
262
+ alignItems: "center",
263
+ },
284
264
  });
285
265
 
286
266
  export default SelaDealCard;