@umituz/react-native-settings 4.23.129 → 4.23.131

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-settings",
3
- "version": "4.23.129",
3
+ "version": "4.23.131",
4
4
  "description": "Complete settings hub for React Native apps - consolidated package with settings, localization, about, legal, appearance, feedback, FAQs, rating, and gamification",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -5,7 +5,7 @@
5
5
 
6
6
  import React from "react";
7
7
  import { View, StyleSheet, type ViewStyle, type TextStyle } from "react-native";
8
- import { useAppDesignTokens, AtomicText, withAlpha } from "@umituz/react-native-design-system";
8
+ import { useAppDesignTokens, AtomicText, withAlpha, useResponsive } from "@umituz/react-native-design-system";
9
9
 
10
10
  export interface AchievementCardProps {
11
11
  title: string;
@@ -41,24 +41,44 @@ export const AchievementCard: React.FC<AchievementCardProps> = ({
41
41
  subtextColor,
42
42
  }) => {
43
43
  const tokens = useAppDesignTokens();
44
-
44
+ const { getFontSize, getIconSize } = useResponsive();
45
+
45
46
  const finalUnlockedColor = unlockedColor || tokens.colors.success;
46
47
  const finalLockedColor = lockedColor || tokens.colors.textDisabled;
47
48
  const finalBackgroundColor = backgroundColor || tokens.colors.surface;
48
49
  const finalTextColor = textColor || tokens.colors.textPrimary;
49
50
  const finalSubtextColor = subtextColor || tokens.colors.textSecondary;
50
-
51
+
51
52
  const accentColor = isUnlocked ? finalUnlockedColor : finalLockedColor;
53
+ const titleFontSize = getFontSize(16);
54
+ const descriptionFontSize = getFontSize(13);
55
+ const checkmarkFontSize = getFontSize(14);
56
+ const iconSize = getIconSize(48);
57
+ const checkmarkSize = getIconSize(24);
52
58
 
53
59
  return (
54
60
  <View
55
61
  style={[
56
62
  styles.container,
57
- { backgroundColor: finalBackgroundColor, borderColor: withAlpha(accentColor, 0.4) },
63
+ {
64
+ backgroundColor: finalBackgroundColor,
65
+ borderColor: withAlpha(accentColor, 0.4),
66
+ padding: tokens.spacing.md,
67
+ borderRadius: tokens.borders.radius.md,
68
+ gap: tokens.spacing.md,
69
+ },
58
70
  containerStyle,
59
71
  ]}
60
72
  >
61
- <View style={[styles.iconContainer, { backgroundColor: withAlpha(accentColor, 0.2) }]}>
73
+ <View style={[
74
+ styles.iconContainer,
75
+ {
76
+ backgroundColor: withAlpha(accentColor, 0.2),
77
+ width: iconSize,
78
+ height: iconSize,
79
+ borderRadius: iconSize / 2,
80
+ }
81
+ ]}>
62
82
  {icon}
63
83
  </View>
64
84
 
@@ -66,22 +86,45 @@ export const AchievementCard: React.FC<AchievementCardProps> = ({
66
86
  <AtomicText
67
87
  style={[
68
88
  styles.title,
69
- { color: isUnlocked ? finalTextColor : finalSubtextColor },
89
+ {
90
+ color: isUnlocked ? finalTextColor : finalSubtextColor,
91
+ fontSize: titleFontSize,
92
+ },
70
93
  titleStyle,
71
94
  ]}
72
95
  >
73
96
  {title}
74
97
  </AtomicText>
75
- <AtomicText style={[styles.description, { color: finalSubtextColor }, descriptionStyle]}>
98
+ <AtomicText style={[
99
+ styles.description,
100
+ {
101
+ color: finalSubtextColor,
102
+ fontSize: descriptionFontSize,
103
+ marginTop: tokens.spacing.xs,
104
+ },
105
+ descriptionStyle
106
+ ]}>
76
107
  {description}
77
108
  </AtomicText>
78
109
 
79
110
  {!isUnlocked && (
80
- <View style={[styles.progressBar, { backgroundColor: withAlpha(finalLockedColor, 0.4) }, progressBarStyle]}>
111
+ <View style={[
112
+ styles.progressBar,
113
+ {
114
+ backgroundColor: withAlpha(finalLockedColor, 0.4),
115
+ marginTop: tokens.spacing.sm,
116
+ borderRadius: tokens.borders.radius.xs,
117
+ },
118
+ progressBarStyle
119
+ ]}>
81
120
  <View
82
121
  style={[
83
122
  styles.progressFill,
84
- { width: `${progress}%`, backgroundColor: accentColor },
123
+ {
124
+ width: `${progress}%`,
125
+ backgroundColor: accentColor,
126
+ borderRadius: tokens.borders.radius.xs,
127
+ },
85
128
  ]}
86
129
  />
87
130
  </View>
@@ -89,8 +132,24 @@ export const AchievementCard: React.FC<AchievementCardProps> = ({
89
132
  </View>
90
133
 
91
134
  {isUnlocked && (
92
- <View style={[styles.checkmark, { backgroundColor: finalUnlockedColor }]}>
93
- <AtomicText style={[styles.checkmarkText, { color: tokens.colors.onPrimary }]}>✓</AtomicText>
135
+ <View style={[
136
+ styles.checkmark,
137
+ {
138
+ backgroundColor: finalUnlockedColor,
139
+ width: checkmarkSize,
140
+ height: checkmarkSize,
141
+ borderRadius: checkmarkSize / 2,
142
+ }
143
+ ]}>
144
+ <AtomicText style={[
145
+ styles.checkmarkText,
146
+ {
147
+ color: tokens.colors.onPrimary,
148
+ fontSize: checkmarkFontSize,
149
+ }
150
+ ]}>
151
+
152
+ </AtomicText>
94
153
  </View>
95
154
  )}
96
155
  </View>
@@ -101,15 +160,9 @@ const styles = StyleSheet.create({
101
160
  container: {
102
161
  flexDirection: "row",
103
162
  alignItems: "center",
104
- padding: 12,
105
- borderRadius: 12,
106
163
  borderWidth: 1,
107
- gap: 12,
108
164
  },
109
165
  iconContainer: {
110
- width: 48,
111
- height: 48,
112
- borderRadius: 24,
113
166
  justifyContent: "center",
114
167
  alignItems: "center",
115
168
  },
@@ -117,32 +170,21 @@ const styles = StyleSheet.create({
117
170
  flex: 1,
118
171
  },
119
172
  title: {
120
- fontSize: 16,
121
173
  fontWeight: "600",
122
174
  },
123
- description: {
124
- fontSize: 13,
125
- marginTop: 2,
126
- },
175
+ description: {},
127
176
  progressBar: {
128
177
  height: 4,
129
- borderRadius: 2,
130
- marginTop: 8,
131
178
  overflow: "hidden",
132
179
  },
133
180
  progressFill: {
134
181
  height: "100%",
135
- borderRadius: 2,
136
182
  },
137
183
  checkmark: {
138
- width: 24,
139
- height: 24,
140
- borderRadius: 12,
141
184
  justifyContent: "center",
142
185
  alignItems: "center",
143
186
  },
144
187
  checkmarkText: {
145
- fontSize: 14,
146
188
  fontWeight: "bold",
147
189
  },
148
190
  });
@@ -54,7 +54,6 @@ export const GamificationScreenWithConfig: React.FC<GamificationConfigProps> = (
54
54
  streakProps: {
55
55
  current: streak.current,
56
56
  longest: streak.longest,
57
- currentLabel: config.translations.currentStreak,
58
57
  bestLabel: config.translations.bestStreak,
59
58
  daysLabel: config.translations.days,
60
59
  },
@@ -62,12 +61,12 @@ export const GamificationScreenWithConfig: React.FC<GamificationConfigProps> = (
62
61
  {
63
62
  label: config.translations.pointsLabel,
64
63
  value: points,
65
- icon: "star",
64
+ icon: "",
66
65
  },
67
66
  {
68
67
  label: config.translations.totalCompletedLabel,
69
68
  value: totalTasksCompleted,
70
- icon: "checkmark-circle",
69
+ icon: "",
71
70
  },
72
71
  ],
73
72
  achievements: achievementItems,
@@ -5,7 +5,7 @@
5
5
 
6
6
  import React from "react";
7
7
  import { View, StyleSheet, type ViewStyle, type TextStyle } from "react-native";
8
- import { useAppDesignTokens, AtomicText, withAlpha } from "@umituz/react-native-design-system";
8
+ import { useAppDesignTokens, AtomicText, withAlpha, useResponsive } from "@umituz/react-native-design-system";
9
9
 
10
10
  export interface LevelProgressProps {
11
11
  level: number;
@@ -49,39 +49,99 @@ export const LevelProgress: React.FC<LevelProgressProps> = ({
49
49
  subtextColor,
50
50
  }) => {
51
51
  const tokens = useAppDesignTokens();
52
-
52
+ const { getFontSize, getIconSize } = useResponsive();
53
+
53
54
  const finalPrimaryColor = primaryColor || tokens.colors.primary;
54
55
  const finalSecondaryColor = secondaryColor || tokens.colors.surfaceSecondary;
55
56
  const finalBackgroundColor = backgroundColor || tokens.colors.surface;
56
57
  const finalTextColor = textColor || tokens.colors.textPrimary;
57
58
  const finalSubtextColor = subtextColor || tokens.colors.textSecondary;
58
59
 
60
+ const titleFontSize = getFontSize(18);
61
+ const subtitleFontSize = getFontSize(14);
62
+ const badgeSize = getIconSize(52);
63
+ const badgeFontSize = getFontSize(20);
64
+ const progressBarHeight = getFontSize(10);
65
+
59
66
  return (
60
- <View style={[styles.container, { backgroundColor: finalBackgroundColor }, containerStyle]}>
61
- <View style={styles.header}>
67
+ <View style={[
68
+ styles.container,
69
+ {
70
+ backgroundColor: finalBackgroundColor,
71
+ borderRadius: tokens.borders.radius.lg,
72
+ padding: tokens.spacing.lg,
73
+ },
74
+ containerStyle
75
+ ]}>
76
+ <View style={[styles.header, { marginBottom: tokens.spacing.md }]}>
62
77
  <View style={styles.titleSection}>
63
- <AtomicText style={[styles.levelTitle, { color: finalTextColor }, titleStyle]}>
78
+ <AtomicText style={[
79
+ styles.levelTitle,
80
+ {
81
+ color: finalTextColor,
82
+ fontSize: titleFontSize,
83
+ },
84
+ titleStyle
85
+ ]}>
64
86
  {levelTitle}
65
87
  </AtomicText>
66
88
  {showPoints && (
67
- <AtomicText style={[styles.subtitle, { color: finalSubtextColor }, subtitleStyle]}>
89
+ <AtomicText style={[
90
+ styles.subtitle,
91
+ {
92
+ color: finalSubtextColor,
93
+ fontSize: subtitleFontSize,
94
+ marginTop: tokens.spacing.xs,
95
+ },
96
+ subtitleStyle
97
+ ]}>
68
98
  {points} / {points + pointsToNext}
69
99
  </AtomicText>
70
100
  )}
71
101
  </View>
72
102
 
73
- <View style={[styles.badge, { backgroundColor: withAlpha(finalPrimaryColor, 0.2), borderColor: withAlpha(finalPrimaryColor, 0.4) }, badgeStyle]}>
74
- <AtomicText style={[styles.badgeText, { color: finalPrimaryColor }, badgeTextStyle]}>
103
+ <View style={[
104
+ styles.badge,
105
+ {
106
+ backgroundColor: withAlpha(finalPrimaryColor, 0.2),
107
+ borderColor: withAlpha(finalPrimaryColor, 0.4),
108
+ width: badgeSize,
109
+ height: badgeSize,
110
+ borderRadius: badgeSize / 2,
111
+ borderWidth: 2,
112
+ },
113
+ badgeStyle
114
+ ]}>
115
+ <AtomicText style={[
116
+ styles.badgeText,
117
+ {
118
+ color: finalPrimaryColor,
119
+ fontSize: badgeFontSize,
120
+ },
121
+ badgeTextStyle
122
+ ]}>
75
123
  {level}
76
124
  </AtomicText>
77
125
  </View>
78
126
  </View>
79
127
 
80
- <View style={[styles.progressBar, { backgroundColor: finalSecondaryColor }, progressBarStyle]}>
128
+ <View style={[
129
+ styles.progressBar,
130
+ {
131
+ backgroundColor: finalSecondaryColor,
132
+ height: progressBarHeight,
133
+ borderRadius: tokens.borders.radius.sm,
134
+ },
135
+ progressBarStyle
136
+ ]}>
81
137
  <View
82
138
  style={[
83
139
  styles.progressFill,
84
- { width: `${Math.min(100, progress)}%`, backgroundColor: finalPrimaryColor },
140
+ {
141
+ width: `${Math.min(100, progress)}%`,
142
+ backgroundColor: finalPrimaryColor,
143
+ borderRadius: tokens.borders.radius.sm,
144
+ },
85
145
  progressFillStyle,
86
146
  ]}
87
147
  />
@@ -91,46 +151,30 @@ export const LevelProgress: React.FC<LevelProgressProps> = ({
91
151
  };
92
152
 
93
153
  const styles = StyleSheet.create({
94
- container: {
95
- borderRadius: 16,
96
- padding: 16,
97
- },
154
+ container: {},
98
155
  header: {
99
156
  flexDirection: "row",
100
157
  justifyContent: "space-between",
101
158
  alignItems: "center",
102
- marginBottom: 12,
103
159
  },
104
160
  titleSection: {
105
161
  flex: 1,
106
162
  },
107
163
  levelTitle: {
108
- fontSize: 18,
109
164
  fontWeight: "700",
110
165
  },
111
- subtitle: {
112
- fontSize: 14,
113
- marginTop: 2,
114
- },
166
+ subtitle: {},
115
167
  badge: {
116
- width: 48,
117
- height: 48,
118
- borderRadius: 24,
119
168
  justifyContent: "center",
120
169
  alignItems: "center",
121
- borderWidth: 2,
122
170
  },
123
171
  badgeText: {
124
- fontSize: 18,
125
172
  fontWeight: "bold",
126
173
  },
127
174
  progressBar: {
128
- height: 8,
129
- borderRadius: 4,
130
175
  overflow: "hidden",
131
176
  },
132
177
  progressFill: {
133
178
  height: "100%",
134
- borderRadius: 4,
135
179
  },
136
180
  });
@@ -5,7 +5,7 @@
5
5
 
6
6
  import React from "react";
7
7
  import { View, StyleSheet, type ViewStyle, type TextStyle } from "react-native";
8
- import { useAppDesignTokens, AtomicText, withAlpha } from "@umituz/react-native-design-system";
8
+ import { useAppDesignTokens, AtomicText, withAlpha, useResponsive } from "@umituz/react-native-design-system";
9
9
 
10
10
  export interface PointsBadgeProps {
11
11
  points: number;
@@ -27,20 +27,28 @@ export const PointsBadge: React.FC<PointsBadgeProps> = ({
27
27
  borderColor,
28
28
  }) => {
29
29
  const tokens = useAppDesignTokens();
30
+ const { getFontSize } = useResponsive();
30
31
  const finalTextColor = textColor || tokens.colors.primary;
31
32
  const finalBackgroundColor = backgroundColor || withAlpha(finalTextColor, 0.1);
32
33
  const finalBorderColor = borderColor || withAlpha(finalTextColor, 0.2);
34
+ const fontSize = getFontSize(16);
33
35
 
34
36
  return (
35
37
  <View
36
38
  style={[
37
39
  styles.container,
38
- { backgroundColor: finalBackgroundColor, borderColor: finalBorderColor },
40
+ {
41
+ backgroundColor: finalBackgroundColor,
42
+ borderColor: finalBorderColor,
43
+ paddingHorizontal: tokens.spacing.md,
44
+ paddingVertical: tokens.spacing.xs,
45
+ borderRadius: tokens.borders.radius.full,
46
+ },
39
47
  containerStyle,
40
48
  ]}
41
49
  >
42
50
  {icon}
43
- <AtomicText style={[styles.text, { color: finalTextColor }, textStyle]}>
51
+ <AtomicText style={[styles.text, { color: finalTextColor, fontSize }, textStyle]}>
44
52
  {points}
45
53
  </AtomicText>
46
54
  </View>
@@ -52,13 +60,9 @@ const styles = StyleSheet.create({
52
60
  flexDirection: "row",
53
61
  alignItems: "center",
54
62
  gap: 6,
55
- paddingHorizontal: 12,
56
- paddingVertical: 6,
57
- borderRadius: 20,
58
63
  borderWidth: 1,
59
64
  },
60
65
  text: {
61
- fontSize: 16,
62
66
  fontWeight: "bold",
63
67
  },
64
68
  });
@@ -1,16 +1,16 @@
1
1
  /**
2
- * StatsCard Component
3
- * Displays a stat with icon - all text via props
2
+ * StatsCard Component - Modern Design
3
+ * Clean card-based stat display with emoji icons
4
4
  */
5
5
 
6
6
  import React from "react";
7
7
  import { View, StyleSheet, type ViewStyle, type TextStyle } from "react-native";
8
- import { useAppDesignTokens, AtomicText, AtomicIcon, withAlpha } from "@umituz/react-native-design-system";
8
+ import { useAppDesignTokens, AtomicText, useResponsive } from "@umituz/react-native-design-system";
9
9
 
10
10
  export interface StatsCardProps {
11
11
  value: number;
12
12
  label: string;
13
- icon: React.ReactNode | string;
13
+ icon?: React.ReactNode | string;
14
14
  suffix?: string;
15
15
  containerStyle?: ViewStyle;
16
16
  valueStyle?: TextStyle;
@@ -31,35 +31,86 @@ export const StatsCard: React.FC<StatsCardProps> = ({
31
31
  labelStyle,
32
32
  accentColor,
33
33
  backgroundColor,
34
- textColor,
34
+ textColor: _textColor,
35
35
  subtextColor,
36
36
  }) => {
37
37
  const tokens = useAppDesignTokens();
38
-
38
+ const { getFontSize } = useResponsive();
39
+
39
40
  const finalAccentColor = accentColor || tokens.colors.primary;
40
41
  const finalBackgroundColor = backgroundColor || tokens.colors.surface;
41
- const finalTextColor = textColor || tokens.colors.textPrimary;
42
42
  const finalSubtextColor = subtextColor || tokens.colors.textSecondary;
43
43
 
44
- const renderedIcon = typeof icon === 'string' ? (
45
- <AtomicIcon name={icon} size="sm" customColor={finalAccentColor} />
46
- ) : icon;
44
+ const valueFontSize = getFontSize(48);
45
+ const suffixFontSize = getFontSize(16);
46
+ const labelFontSize = getFontSize(12);
47
+ const emojiSize = getFontSize(32);
47
48
 
48
49
  return (
49
- <View style={[styles.container, { backgroundColor: finalBackgroundColor }, containerStyle]}>
50
- <View style={[styles.iconContainer, { backgroundColor: withAlpha(finalAccentColor, 0.15) }]}>
51
- {renderedIcon}
52
- </View>
50
+ <View style={[
51
+ styles.container,
52
+ {
53
+ backgroundColor: finalBackgroundColor,
54
+ borderRadius: tokens.borders.radius.xl,
55
+ padding: tokens.spacing.xl,
56
+ shadowColor: "#000",
57
+ shadowOffset: { width: 0, height: 2 },
58
+ shadowOpacity: 0.1,
59
+ shadowRadius: 8,
60
+ elevation: 3,
61
+ },
62
+ containerStyle
63
+ ]}>
64
+ {/* Emoji Icon at Top */}
65
+ {icon && (
66
+ <AtomicText style={[
67
+ styles.emoji,
68
+ {
69
+ fontSize: emojiSize,
70
+ marginBottom: tokens.spacing.sm,
71
+ }
72
+ ]}>
73
+ {icon}
74
+ </AtomicText>
75
+ )}
76
+
77
+ {/* Large Value in Center */}
53
78
  <View style={styles.valueRow}>
54
- <AtomicText style={[styles.value, { color: finalTextColor }, valueStyle]}>
79
+ <AtomicText style={[
80
+ styles.value,
81
+ {
82
+ color: finalAccentColor,
83
+ fontSize: valueFontSize,
84
+ lineHeight: valueFontSize + 8,
85
+ },
86
+ valueStyle
87
+ ]}>
55
88
  {value}
56
89
  </AtomicText>
57
90
  {suffix && (
58
- <AtomicText style={[styles.suffix, { color: finalSubtextColor }]}>{suffix}</AtomicText>
91
+ <AtomicText style={[
92
+ styles.suffix,
93
+ {
94
+ color: finalSubtextColor,
95
+ fontSize: suffixFontSize,
96
+ }
97
+ ]}>
98
+ {suffix}
99
+ </AtomicText>
59
100
  )}
60
101
  </View>
61
- <AtomicText style={[styles.label, { color: finalSubtextColor }, labelStyle]}>
62
- {label}
102
+
103
+ {/* Small Label Below */}
104
+ <AtomicText style={[
105
+ styles.label,
106
+ {
107
+ color: finalSubtextColor,
108
+ fontSize: labelFontSize,
109
+ marginTop: tokens.spacing.xs,
110
+ },
111
+ labelStyle
112
+ ]}>
113
+ {label.toUpperCase()}
63
114
  </AtomicText>
64
115
  </View>
65
116
  );
@@ -69,16 +120,10 @@ const styles = StyleSheet.create({
69
120
  container: {
70
121
  flex: 1,
71
122
  minWidth: "45%",
72
- borderRadius: 12,
73
- padding: 12,
74
- },
75
- iconContainer: {
76
- width: 36,
77
- height: 36,
78
- borderRadius: 18,
79
123
  alignItems: "center",
80
- justifyContent: "center",
81
- marginBottom: 8,
124
+ },
125
+ emoji: {
126
+ textAlign: "center",
82
127
  },
83
128
  valueRow: {
84
129
  flexDirection: "row",
@@ -86,14 +131,16 @@ const styles = StyleSheet.create({
86
131
  gap: 4,
87
132
  },
88
133
  value: {
89
- fontSize: 24,
90
- fontWeight: "bold",
134
+ fontWeight: "800",
135
+ letterSpacing: -1,
136
+ textAlign: "center",
91
137
  },
92
138
  suffix: {
93
- fontSize: 12,
139
+ fontWeight: "600",
94
140
  },
95
141
  label: {
96
- fontSize: 12,
97
- marginTop: 2,
142
+ fontWeight: "600",
143
+ letterSpacing: 0.5,
144
+ textAlign: "center",
98
145
  },
99
146
  });
@@ -1,16 +1,15 @@
1
1
  /**
2
- * StreakDisplay Component
3
- * Displays streak information - all text via props
2
+ * StreakDisplay Component - Modern Design
3
+ * Clean card-based design with emoji icons
4
4
  */
5
5
 
6
6
  import React from "react";
7
7
  import { View, StyleSheet, type ViewStyle, type TextStyle } from "react-native";
8
- import { useAppDesignTokens, AtomicText, AtomicIcon, withAlpha } from "@umituz/react-native-design-system";
8
+ import { useAppDesignTokens, AtomicText, withAlpha, useResponsive } from "@umituz/react-native-design-system";
9
9
 
10
10
  export interface StreakDisplayProps {
11
11
  current: number;
12
12
  longest: number;
13
- currentLabel: string;
14
13
  bestLabel: string;
15
14
  daysLabel: string;
16
15
  icon?: React.ReactNode | string;
@@ -26,51 +25,101 @@ export interface StreakDisplayProps {
26
25
  export const StreakDisplay: React.FC<StreakDisplayProps> = ({
27
26
  current,
28
27
  longest,
29
- currentLabel,
30
28
  bestLabel,
31
29
  daysLabel,
32
- icon,
33
30
  containerStyle,
34
31
  numberStyle,
35
32
  labelStyle,
36
33
  primaryColor,
37
34
  backgroundColor,
38
- textColor,
35
+ textColor: _textColor,
39
36
  subtextColor,
40
37
  }) => {
41
38
  const tokens = useAppDesignTokens();
42
-
39
+ const { getFontSize } = useResponsive();
40
+
43
41
  const finalPrimaryColor = primaryColor || tokens.colors.primary;
44
42
  const finalBackgroundColor = backgroundColor || tokens.colors.surface;
45
- const finalTextColor = textColor || tokens.colors.textPrimary;
46
43
  const finalSubtextColor = subtextColor || tokens.colors.textSecondary;
47
44
 
48
- const renderedIcon = typeof icon === 'string' ? (
49
- <AtomicIcon name={icon} size="md" customColor={finalPrimaryColor} />
50
- ) : icon || <AtomicIcon name="flame" size="md" customColor={finalPrimaryColor} />;
45
+ const streakNumberSize = getFontSize(48);
46
+ const streakLabelSize = getFontSize(13);
47
+ const bestNumberSize = getFontSize(20);
48
+ const bestLabelSize = getFontSize(11);
51
49
 
52
50
  return (
53
- <View style={[styles.container, { backgroundColor: finalBackgroundColor }, containerStyle]}>
54
- <View style={styles.mainStreak}>
55
- <View style={styles.iconContainer}>{renderedIcon}</View>
56
- <View style={styles.streakInfo}>
57
- <AtomicText style={[styles.number, { color: finalPrimaryColor }, numberStyle]}>
58
- {current}
59
- </AtomicText>
60
- <AtomicText style={[styles.label, { color: finalSubtextColor }, labelStyle]}>
61
- {daysLabel}
62
- </AtomicText>
51
+ <View style={[
52
+ styles.container,
53
+ {
54
+ backgroundColor: finalBackgroundColor,
55
+ borderRadius: tokens.borders.radius.xl,
56
+ padding: tokens.spacing.xl,
57
+ shadowColor: "#000",
58
+ shadowOffset: { width: 0, height: 2 },
59
+ shadowOpacity: 0.1,
60
+ shadowRadius: 8,
61
+ elevation: 3,
62
+ },
63
+ containerStyle
64
+ ]}>
65
+ {/* Main Streak Section */}
66
+ <View style={styles.mainSection}>
67
+ <AtomicText style={styles.emoji}>🔥</AtomicText>
68
+ <View style={styles.streakNumbers}>
69
+ <View style={styles.currentStreak}>
70
+ <AtomicText style={[
71
+ styles.streakNumber,
72
+ {
73
+ color: finalPrimaryColor,
74
+ fontSize: streakNumberSize,
75
+ lineHeight: streakNumberSize + 8,
76
+ },
77
+ numberStyle
78
+ ]}>
79
+ {current}
80
+ </AtomicText>
81
+ <AtomicText style={[
82
+ styles.streakLabel,
83
+ {
84
+ color: finalSubtextColor,
85
+ fontSize: streakLabelSize,
86
+ marginTop: tokens.spacing.xs,
87
+ },
88
+ labelStyle
89
+ ]}>
90
+ {daysLabel.toUpperCase()}
91
+ </AtomicText>
92
+ </View>
63
93
  </View>
64
- <AtomicText style={[styles.currentLabel, { color: finalTextColor }]}>
65
- {currentLabel}
66
- </AtomicText>
67
94
  </View>
68
95
 
69
- <View style={[styles.bestStreak, { backgroundColor: withAlpha(finalPrimaryColor, 0.2) }]}>
70
- <AtomicText style={[styles.bestLabel, { color: finalSubtextColor }]}>
71
- {bestLabel}
96
+ {/* Best Streak Badge */}
97
+ <View style={[
98
+ styles.bestBadge,
99
+ {
100
+ backgroundColor: withAlpha(finalPrimaryColor, 0.12),
101
+ borderRadius: tokens.borders.radius.lg,
102
+ paddingHorizontal: tokens.spacing.md,
103
+ paddingVertical: tokens.spacing.md,
104
+ }
105
+ ]}>
106
+ <AtomicText style={[
107
+ styles.bestLabel,
108
+ {
109
+ color: finalSubtextColor,
110
+ fontSize: bestLabelSize,
111
+ }
112
+ ]}>
113
+ {bestLabel.toUpperCase()}
72
114
  </AtomicText>
73
- <AtomicText style={[styles.bestNumber, { color: finalPrimaryColor }]}>
115
+ <AtomicText style={[
116
+ styles.bestNumber,
117
+ {
118
+ color: finalPrimaryColor,
119
+ fontSize: bestNumberSize,
120
+ marginTop: tokens.spacing.xs / 2,
121
+ }
122
+ ]}>
74
123
  {longest}
75
124
  </AtomicText>
76
125
  </View>
@@ -80,50 +129,42 @@ export const StreakDisplay: React.FC<StreakDisplayProps> = ({
80
129
 
81
130
  const styles = StyleSheet.create({
82
131
  container: {
83
- borderRadius: 16,
84
- padding: 16,
85
132
  flexDirection: "row",
86
133
  alignItems: "center",
87
134
  justifyContent: "space-between",
88
135
  },
89
- mainStreak: {
136
+ mainSection: {
90
137
  flexDirection: "row",
91
138
  alignItems: "center",
92
- gap: 12,
139
+ gap: 16,
140
+ flex: 1,
93
141
  },
94
- iconContainer: {
95
- width: 40,
96
- height: 40,
97
- justifyContent: "center",
98
- alignItems: "center",
142
+ emoji: {
143
+ fontSize: 40,
99
144
  },
100
- streakInfo: {
101
- alignItems: "center",
145
+ streakNumbers: {
146
+ flex: 1,
102
147
  },
103
- number: {
104
- fontSize: 32,
105
- fontWeight: "bold",
148
+ currentStreak: {
149
+ alignItems: "flex-start",
106
150
  },
107
- label: {
108
- fontSize: 12,
109
- textTransform: "uppercase",
151
+ streakNumber: {
152
+ fontWeight: "800",
153
+ letterSpacing: -1,
110
154
  },
111
- currentLabel: {
112
- fontSize: 14,
113
- fontWeight: "500",
155
+ streakLabel: {
156
+ fontWeight: "600",
157
+ letterSpacing: 0.5,
114
158
  },
115
- bestStreak: {
116
- paddingHorizontal: 12,
117
- paddingVertical: 8,
118
- borderRadius: 12,
159
+ bestBadge: {
119
160
  alignItems: "center",
161
+ minWidth: 70,
120
162
  },
121
163
  bestLabel: {
122
- fontSize: 11,
123
- textTransform: "uppercase",
164
+ fontWeight: "700",
165
+ letterSpacing: 0.5,
124
166
  },
125
167
  bestNumber: {
126
- fontSize: 18,
127
- fontWeight: "bold",
168
+ fontWeight: "800",
128
169
  },
129
170
  });