@momo-kits/native-kits 0.118.1-beta.3 → 0.120.0-beta.20

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.
@@ -96,7 +96,8 @@ val AppLanguage = staticCompositionLocalOf<String?> {
96
96
  data class KitConfig(
97
97
  val trustBanner: TrustBannerData? = null,
98
98
  val headerBar: String? = null,
99
- val headerGradient: String? = null
99
+ val headerGradient: String? = null,
100
+ val isWhiteList: Boolean = false
100
101
  )
101
102
 
102
103
  @Composable
@@ -36,7 +36,6 @@ import androidx.compose.ui.text.input.KeyboardType
36
36
  import androidx.compose.ui.unit.dp
37
37
  import androidx.compose.ui.zIndex
38
38
  import vn.momo.kits.const.AppTheme
39
- import vn.momo.kits.const.Colors
40
39
  import vn.momo.kits.const.Radius
41
40
  import vn.momo.kits.const.Spacing
42
41
  import vn.momo.kits.const.Typography
@@ -1,5 +1,7 @@
1
1
  package vn.momo.kits.components
2
2
 
3
+ import androidx.compose.foundation.border
4
+ import androidx.compose.foundation.layout.Box
3
5
  import androidx.compose.runtime.Composable
4
6
  import androidx.compose.ui.Modifier
5
7
  import androidx.compose.ui.graphics.Color
@@ -8,8 +10,10 @@ import androidx.compose.ui.text.TextStyle
8
10
  import androidx.compose.ui.text.style.TextAlign
9
11
  import androidx.compose.ui.text.style.TextDecoration
10
12
  import androidx.compose.ui.text.style.TextOverflow
13
+ import androidx.compose.ui.unit.dp
11
14
  import androidx.compose.ui.unit.sp
12
15
  import vn.momo.kits.const.AppTheme
16
+ import vn.momo.kits.const.Colors
13
17
  import vn.momo.kits.const.Typography
14
18
  import vn.momo.kits.const.getFontFamily
15
19
  import vn.momo.kits.const.scaleSize
@@ -45,4 +49,5 @@ fun Text(
45
49
  onTextLayout = onTextLayout,
46
50
  overflow = overflow
47
51
  )
52
+
48
53
  }
@@ -12,32 +12,39 @@ import org.jetbrains.compose.resources.Font
12
12
  import org.jetbrains.compose.resources.FontResource
13
13
  import org.jetbrains.compose.resources.InternalResourceApi
14
14
  import org.jetbrains.compose.resources.ResourceItem
15
+ import vn.momo.kits.application.AppConfig
16
+ import vn.momo.kits.application.KitConfig
15
17
  import vn.momo.kits.platform.getScreenDimensions
18
+ import kotlin.math.max
16
19
  import kotlin.math.min
17
20
 
18
21
  const val DEFAULT_SCREEN_SIZE = 375f
19
- const val MAX_FONT_SCALE = 1.2f
22
+ const val MAX_FONT_SCALE = 1.5f
20
23
  const val MAX_DEVICE_SCALE = 5
21
24
 
22
25
  @Composable
23
- fun scaleSize(size: Float): Float {
26
+ fun scaleSize(size: Float, config: KitConfig? = AppConfig.current): Float {
27
+ val isWhiteList = config?.isWhiteList ?: false
24
28
  val deviceWidth = getScreenDimensions().width
25
29
  val deviceScale = deviceWidth / DEFAULT_SCREEN_SIZE
26
30
 
27
31
  val density = LocalDensity.current
28
32
  val fontScale = density.fontScale
29
33
 
30
- var fontSize = size / fontScale //To ignore OS scale
34
+ val defaultFontSize = size / fontScale //To ignore OS scale
35
+ var fontSizeScaleDevice = defaultFontSize
36
+ var fontSizeScaleOS = defaultFontSize
31
37
 
32
38
  if (deviceScale > 1) {
33
- fontSize = min(deviceScale * fontSize, fontSize + MAX_DEVICE_SCALE)
39
+ fontSizeScaleDevice =
40
+ min(deviceScale * fontSizeScaleDevice, fontSizeScaleDevice + MAX_DEVICE_SCALE)
34
41
  }
35
42
 
36
43
  if (fontScale > 1) {
37
- fontSize = min(fontScale * fontSize, fontSize * MAX_FONT_SCALE)
44
+ fontSizeScaleOS = min(fontScale * fontSizeScaleOS, fontSizeScaleOS * MAX_FONT_SCALE)
38
45
  }
39
46
 
40
- return fontSize
47
+ return if (isWhiteList) max(fontSizeScaleDevice, fontSizeScaleOS) else fontSizeScaleDevice
41
48
  }
42
49
 
43
50
  @OptIn(InternalResourceApi::class)
@@ -214,8 +214,8 @@ public struct Header: View {
214
214
  }
215
215
  } else {
216
216
  Text(title)
217
- .font(Font.system(size: 17).weight(.bold))
218
- .lineSpacing(22)
217
+ .font(Font.system(size: scaleSize(17)).weight(.bold))
218
+ .lineSpacing(scaleSize(22))
219
219
  .foregroundColor(tintColor)
220
220
  .frame(maxWidth: titlePosition == .center ? UIScreen.main.bounds.width - 252 : nil)
221
221
  .frame(maxWidth: titlePosition == .center ? .infinity : UIScreen.main.bounds.width - 172, alignment: titlePosition == .center ? .center : .leading)
@@ -62,11 +62,11 @@ public struct Button: View {
62
62
  func renderTitle(title: String, type: ButtonType, size: ButtonSize) -> Text {
63
63
  switch size {
64
64
  case .large:
65
- return Text(title).font(.system(size: 16, weight: Font.Weight.bold))
65
+ return Text(title).font(.system(size: scaleSize(16), weight: Font.Weight.bold))
66
66
  case .medium:
67
- return Text(title).font(.system(size: 14, weight: Font.Weight.bold))
67
+ return Text(title).font(.system(size: scaleSize(14), weight: Font.Weight.bold))
68
68
  case .small:
69
- return Text(title).font(.system(size: 12, weight: Font.Weight.bold))
69
+ return Text(title).font(.system(size: scaleSize(12), weight: Font.Weight.bold))
70
70
  }
71
71
  }
72
72
  }
@@ -53,8 +53,7 @@ public struct Checkbox: View{
53
53
 
54
54
  // Title
55
55
  if !title.isEmpty {
56
- Text(title)
57
- .font(.description1)
56
+ MomoText(title, typography: .bodyDefaultRegular)
58
57
  }
59
58
  }
60
59
  }
@@ -5,6 +5,7 @@ import SwiftUI
5
5
  fileprivate struct FloatingComponent: View {
6
6
  var floatingValue: String
7
7
  var floatingIcon: AnyView?
8
+ var disabled: Bool = false
8
9
 
9
10
  public init (_ floatingValue: String = "", floatingIcon: AnyView? = nil){
10
11
  self.floatingValue = floatingValue
@@ -13,12 +14,9 @@ fileprivate struct FloatingComponent: View {
13
14
 
14
15
  public var body: some View {
15
16
  return HStack {
16
- Text(floatingValue)
17
- .font(.paragraph)
18
- .foregroundColor(Colors.black09)
19
- .font(.system(size: 12))
20
- .padding(.leading, 8)
21
- .padding(.trailing, 8)
17
+ MomoText(floatingValue, typography: .labelSMedium, color: self.disabled ? Colors.black12 : Colors.black08)
18
+ .padding(.leading, Spacing.XS)
19
+ .padding(.trailing, Spacing.XS)
22
20
  floatingIcon
23
21
  }
24
22
  .background(Colors.black01)
@@ -113,84 +111,83 @@ public struct Input: View {
113
111
  }
114
112
 
115
113
  public var body: some View {
116
- VStack(alignment: .leading, spacing: 4) {
117
- ZStack(alignment: .topLeading) {
118
- HStack(alignment: .center) {
119
- if let leadingIcon = leadingIcon {
120
- Icon(source: leadingIcon, size: 16, color: leadingIconColor)
121
- }
122
-
123
- if !isSecure {
124
- TextField("", text: $value, onEditingChanged: { isChange in
125
- self.focused = isChange
126
- })
127
- .disabled(disabled)
128
- .font(fontWeight == .bold ? .headline : .body)
129
- } else {
130
- DotTextField(value: $value)
131
- .disabled(disabled)
132
- }
133
-
134
- if loading {
135
- ActivityIndicator(isAnimating: .constant(true), style: .medium)
136
- .frame(width: 20, height: 20)
137
- } else if !value.isEmpty {
138
- SwiftButton(action: onCancel){
139
- Image(systemName: "x.circle.fill")
140
- .foregroundColor(Colors.text)
141
- .frame(width: 16, height: 16)
142
- .padding(.leading, -4)
143
- .padding(.trailing, 8)
144
- }
145
- }
146
-
147
- rightIcon
114
+ VStack(alignment: .leading, spacing: 4) {
115
+ ZStack(alignment: .topLeading) {
116
+ HStack(alignment: .center) {
117
+ if let leadingIcon = leadingIcon {
118
+ Icon(source: leadingIcon, size: 16, color: leadingIconColor)
148
119
  }
149
- .padding(.horizontal, 12)
150
- .frame(height: size == .small ? 40 : 48)
151
- .background(disabled ? Colors.black01 : Color.white)
152
- .overlay(RoundedRectangle(cornerRadius: 8).stroke(focused ? Colors.pink03 : Colors.border, lineWidth: 1))
153
120
 
154
- if value.isEmpty {
155
- Text(placeholder + (required ? " *" : ""))
156
- .foregroundColor(Colors.black09)
157
- .padding(.horizontal, leadingIcon == nil ? 12 : 32)
158
- .padding(.top, 12)
159
- .allowsHitTesting(false)
121
+ if !isSecure {
122
+ TextField("", text: $value ,onEditingChanged: { isChange in
123
+ self.focused = isChange
124
+ })
125
+ .disabled(disabled)
126
+ .frame(maxHeight: .infinity)
127
+ .multilineTextAlignment(.leading)
128
+ .font(.system(size: scaleSize(14)))
129
+ } else {
130
+ DotTextField(value: $value)
131
+ .disabled(disabled)
160
132
  }
161
133
 
162
- if !floatingValue.isEmpty {
163
- FloatingComponent(floatingValue, floatingIcon: floatingIconURL.map { url in
164
- AnyView(
165
- Icon(source: url, size: 16, color: floatingIconColor)
166
- )
167
- })
168
-
134
+ if loading {
135
+ ActivityIndicator(isAnimating: .constant(true), style: .medium)
136
+ .frame(width: 20, height: 20)
137
+ } else if !value.isEmpty {
138
+ SwiftButton(action: onCancel){
139
+ Image(systemName: "x.circle.fill")
140
+ .foregroundColor(Colors.text)
141
+ .frame(width: 16, height: 16)
142
+ .padding(.leading, -4)
143
+ .padding(.trailing, 8)
144
+ }
169
145
  }
146
+
147
+ rightIcon
170
148
  }
149
+ .padding(.horizontal, 12)
150
+ .frame(height: size == .small ? scaleSize(40) : scaleSize(48))
151
+ .background(disabled ? Colors.black01 : Color.white)
152
+ .overlay(RoundedRectangle(cornerRadius: 8).stroke(focused ? Colors.pink03 : Colors.border, lineWidth: 1))
171
153
 
172
- if !errorMessage.isEmpty {
173
- Text(errorMessage)
174
- .foregroundColor(.red)
175
- .font(.caption)
176
- } else if let hint = hintText {
177
- Text(hint)
154
+ if value.isEmpty {
155
+ Text(placeholder + (required ? " *" : ""))
156
+ .font(.system(size: scaleSize(14)))
178
157
  .foregroundColor(Colors.black09)
179
- .font(.caption)
158
+ .padding(.horizontal, leadingIcon == nil ? 12 : 32)
159
+ .padding(.top, 12)
160
+ .allowsHitTesting(false)
180
161
  }
162
+
163
+ if !floatingValue.isEmpty {
164
+ FloatingComponent(floatingValue, floatingIcon: floatingIconURL.map { url in
165
+ AnyView(
166
+ Icon(source: url, size: 16, color: floatingIconColor)
167
+ )
168
+ })
169
+
170
+ }
171
+ }
172
+
173
+ if !errorMessage.isEmpty {
174
+ MomoText(errorMessage, typography: .descriptionDefaultRegular, color: Colors.red03)
175
+ } else if hintText != nil {
176
+ MomoText(errorMessage, typography: .descriptionDefaultRegular, color: Colors.black12)
181
177
  }
182
178
  }
179
+ }
183
180
  }
184
181
 
185
182
 
186
183
  struct ActivityIndicator: UIViewRepresentable {
187
184
  @Binding var isAnimating: Bool
188
185
  let style: UIActivityIndicatorView.Style
189
-
186
+
190
187
  func makeUIView(context: UIViewRepresentableContext<ActivityIndicator>) -> UIActivityIndicatorView {
191
188
  return UIActivityIndicatorView(style: style)
192
189
  }
193
-
190
+
194
191
  func updateUIView(_ uiView: UIActivityIndicatorView, context: UIViewRepresentableContext<ActivityIndicator>) {
195
192
  isAnimating ? uiView.startAnimating() : uiView.stopAnimating()
196
193
  }
@@ -0,0 +1,140 @@
1
+ import SwiftUI
2
+
3
+ public func scaleSize(_ size: CGFloat) -> CGFloat {
4
+ let defaultScreenSize: CGFloat = 375
5
+ let maxFontScale: CGFloat = 1.5
6
+ let maxDeviceScale: CGFloat = 5
7
+
8
+ let deviceWidth = UIScreen.main.bounds.width
9
+ let deviceScale = deviceWidth / defaultScreenSize
10
+
11
+ let defaultFont = UIFont.systemFont(ofSize: UIFont.labelFontSize)
12
+ let scaledFont = UIFontMetrics.default.scaledFont(for: defaultFont)
13
+ let fontScale = scaledFont.pointSize / defaultFont.pointSize
14
+
15
+ var fontSizeDeviceScale = size
16
+ var fontSizeOSScale = size
17
+
18
+
19
+ if deviceScale > 1 {
20
+ fontSizeDeviceScale = min(fontSizeDeviceScale * deviceScale, fontSizeDeviceScale + maxDeviceScale)
21
+ }
22
+
23
+ if fontScale > 1 {
24
+ fontSizeOSScale = min(fontSizeOSScale * fontScale, fontSizeOSScale * maxFontScale)
25
+ }
26
+
27
+ return max(fontSizeDeviceScale, fontSizeOSScale)
28
+ }
29
+
30
+ public enum TypographyStyle {
31
+ case headlineDefaultBold
32
+ case headerMBold
33
+ case headerDefaultBold
34
+ case headerSSemibold
35
+ case headerXsSemibold
36
+ case bodyDefaultRegular
37
+ case bodyDefaultRegularStrikethrough
38
+ case descriptionDefaultRegular
39
+ case descriptionDefaultRegularStrikethrough
40
+ case descriptionXsRegular
41
+ case descriptionXsRegularStrikethrough
42
+ case labelDefaultMedium
43
+ case labelSMedium
44
+ case labelXsMedium
45
+ case actionDefaultBold
46
+ case actionSBold
47
+ case actionXsBold
48
+ case actionXxsBold
49
+ }
50
+
51
+ public extension TypographyStyle {
52
+ var fontSize: CGFloat {
53
+ switch self {
54
+ case .headlineDefaultBold: return 24
55
+ case .headerMBold: return 18
56
+ case .headerDefaultBold: return 16
57
+ case .headerSSemibold: return 14
58
+ case .headerXsSemibold: return 12
59
+ case .bodyDefaultRegular, .bodyDefaultRegularStrikethrough: return 14
60
+ case .descriptionDefaultRegular, .descriptionDefaultRegularStrikethrough: return 12
61
+ case .descriptionXsRegular, .descriptionXsRegularStrikethrough: return 10
62
+ case .labelDefaultMedium: return 14
63
+ case .labelSMedium: return 12
64
+ case .labelXsMedium: return 10
65
+ case .actionDefaultBold: return 16
66
+ case .actionSBold: return 14
67
+ case .actionXsBold: return 12
68
+ case .actionXxsBold: return 10
69
+ }
70
+ }
71
+ var lineHeight: CGFloat {
72
+ switch self {
73
+ case .headlineDefaultBold: return 34
74
+ case .headerMBold: return 26
75
+ case .headerDefaultBold: return 22
76
+ case .headerSSemibold: return 20
77
+ case .headerXsSemibold: return 18
78
+ case .bodyDefaultRegular, .bodyDefaultRegularStrikethrough: return 20
79
+ case .descriptionDefaultRegular, .descriptionDefaultRegularStrikethrough: return 18
80
+ case .descriptionXsRegular, .descriptionXsRegularStrikethrough: return 14
81
+ case .labelDefaultMedium: return 20
82
+ case .labelSMedium: return 18
83
+ case .labelXsMedium: return 14
84
+ case .actionDefaultBold: return 22
85
+ case .actionSBold: return 20
86
+ case .actionXsBold: return 18
87
+ case .actionXxsBold: return 14
88
+ }
89
+ }
90
+ var fontWeight: Font.Weight {
91
+ switch self {
92
+ case .headlineDefaultBold, .headerMBold, .headerDefaultBold,
93
+ .actionDefaultBold, .actionSBold, .actionXsBold, .actionXxsBold:
94
+ return .bold
95
+ case .headerSSemibold, .headerXsSemibold:
96
+ return .semibold
97
+ case .bodyDefaultRegular, .bodyDefaultRegularStrikethrough,
98
+ .descriptionDefaultRegular, .descriptionDefaultRegularStrikethrough,
99
+ .descriptionXsRegular, .descriptionXsRegularStrikethrough:
100
+ return .regular
101
+ case .labelDefaultMedium, .labelSMedium, .labelXsMedium:
102
+ return .medium
103
+ }
104
+ }
105
+ var isStrikethrough: Bool {
106
+ switch self {
107
+ case .bodyDefaultRegularStrikethrough,
108
+ .descriptionDefaultRegularStrikethrough,
109
+ .descriptionXsRegularStrikethrough:
110
+ return true
111
+ default:
112
+ return false
113
+ }
114
+ }
115
+ }
116
+
117
+ public struct MomoText: View {
118
+ private let content: String
119
+ private let typography: TypographyStyle
120
+ private let color: Color
121
+
122
+ public init(
123
+ _ content: String,
124
+ typography: TypographyStyle = .bodyDefaultRegular,
125
+ color: Color = Colors.text
126
+ ) {
127
+ self.content = content
128
+ self.typography = typography
129
+ self.color = color
130
+ }
131
+
132
+ public var body: some View {
133
+ let text = SwiftUI.Text(content)
134
+ .font(.system(size: scaleSize(typography.fontSize), weight: typography.fontWeight))
135
+ .foregroundColor(color)
136
+ .lineSpacing(scaleSize(typography.lineHeight) - scaleSize(typography.fontSize))
137
+
138
+ return text
139
+ }
140
+ }
package/local.properties CHANGED
@@ -4,5 +4,5 @@
4
4
  # Location of the SDK. This is only used by Gradle.
5
5
  # For customization when using a Version Control System, please read the
6
6
  # header note.
7
- #Wed Aug 21 14:20:12 ICT 2024
8
- sdk.dir=/Users/huynhdung/Library/Android/sdk
7
+ #Tue Apr 08 11:13:31 ICT 2025
8
+ sdk.dir=/Users/sonnguyen/Library/Android/sdk
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/native-kits",
3
- "version": "0.118.1-beta.3",
3
+ "version": "0.120.0-beta.20",
4
4
  "private": false,
5
5
  "dependencies": {},
6
6
  "devDependencies": {},