@momo-kits/native-kits 0.161.1-beta.15-debug → 0.161.2-beta.1

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 (139) hide show
  1. package/ios/Application/ApplicationEnvironment.swift +2 -6
  2. package/ios/Input/Input.swift +50 -21
  3. package/ios/Input/InputPhoneNumber.swift +17 -17
  4. package/ios/StatusBarTap/StatusBarTap.h +13 -0
  5. package/ios/StatusBarTap/StatusBarTap.m +75 -0
  6. package/ios/Typography/Text.swift +19 -14
  7. package/ios/Typography/Typography.swift +22 -1
  8. package/ios/native-kits.podspec +2 -1
  9. package/package.json +1 -1
  10. package/build.gradle.kts +0 -11
  11. package/compose/build.gradle.kts +0 -180
  12. package/compose/build.gradle.kts.backup +0 -180
  13. package/compose/compose.podspec +0 -47
  14. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/Platform.android.kt +0 -116
  15. package/compose/src/commonMain/composeResources/font/momosignature.otf +0 -0
  16. package/compose/src/commonMain/composeResources/font/momotrustdisplay.otf +0 -0
  17. package/compose/src/commonMain/composeResources/font/sfprotext_black.otf +0 -0
  18. package/compose/src/commonMain/composeResources/font/sfprotext_black.ttf +0 -0
  19. package/compose/src/commonMain/composeResources/font/sfprotext_bold.ttf +0 -0
  20. package/compose/src/commonMain/composeResources/font/sfprotext_heavy.ttf +0 -0
  21. package/compose/src/commonMain/composeResources/font/sfprotext_light.ttf +0 -0
  22. package/compose/src/commonMain/composeResources/font/sfprotext_medium.ttf +0 -0
  23. package/compose/src/commonMain/composeResources/font/sfprotext_regular.ttf +0 -0
  24. package/compose/src/commonMain/composeResources/font/sfprotext_semibold.ttf +0 -0
  25. package/compose/src/commonMain/composeResources/font/sfprotext_thin.otf +0 -0
  26. package/compose/src/commonMain/composeResources/font/sfprotext_thin.ttf +0 -0
  27. package/compose/src/commonMain/composeResources/font/sfprotext_ultralight.otf +0 -0
  28. package/compose/src/commonMain/composeResources/font/sfprotext_ultralight.ttf +0 -0
  29. package/compose/src/commonMain/kotlin/vn/momo/kits/application/AnimationSearchInput.kt +0 -57
  30. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Context.kt +0 -115
  31. package/compose/src/commonMain/kotlin/vn/momo/kits/application/FloatingButton.kt +0 -201
  32. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Header.kt +0 -222
  33. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderAnimated.kt +0 -48
  34. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderBackground.kt +0 -86
  35. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderDefault.kt +0 -76
  36. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderExtended.kt +0 -76
  37. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderRight.kt +0 -305
  38. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderTitle.kt +0 -33
  39. package/compose/src/commonMain/kotlin/vn/momo/kits/application/LiteScreen.kt +0 -720
  40. package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +0 -121
  41. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +0 -402
  42. package/compose/src/commonMain/kotlin/vn/momo/kits/application/useHeaderSearchAnimation.kt +0 -69
  43. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Avatar.kt +0 -157
  44. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Badge.kt +0 -85
  45. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeDot.kt +0 -32
  46. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeRibbon.kt +0 -340
  47. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BaselineView.kt +0 -194
  48. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +0 -357
  49. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Carousel.kt +0 -123
  50. package/compose/src/commonMain/kotlin/vn/momo/kits/components/CheckBox.kt +0 -94
  51. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Chip.kt +0 -136
  52. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Collapse.kt +0 -224
  53. package/compose/src/commonMain/kotlin/vn/momo/kits/components/CupertinoOverscroll.kt +0 -543
  54. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Divider.kt +0 -23
  55. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Icon.kt +0 -76
  56. package/compose/src/commonMain/kotlin/vn/momo/kits/components/IconButton.kt +0 -148
  57. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Image.kt +0 -188
  58. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Information.kt +0 -116
  59. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +0 -448
  60. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputDropDown.kt +0 -172
  61. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputMoney.kt +0 -255
  62. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputOTP.kt +0 -231
  63. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputPhoneNumber.kt +0 -233
  64. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +0 -254
  65. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +0 -241
  66. package/compose/src/commonMain/kotlin/vn/momo/kits/components/LazyColumnWithBouncing.kt +0 -364
  67. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Loader.kt +0 -108
  68. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationDot.kt +0 -56
  69. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationNumber.kt +0 -41
  70. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationScroll.kt +0 -92
  71. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationWhiteDot.kt +0 -40
  72. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +0 -352
  73. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupPromotion.kt +0 -103
  74. package/compose/src/commonMain/kotlin/vn/momo/kits/components/ProgressInfo.kt +0 -338
  75. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Radio.kt +0 -70
  76. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Rating.kt +0 -87
  77. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Skeleton.kt +0 -96
  78. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Slider.kt +0 -348
  79. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Stepper.kt +0 -256
  80. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Steps.kt +0 -494
  81. package/compose/src/commonMain/kotlin/vn/momo/kits/components/SuggestAction.kt +0 -131
  82. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Swipe.kt +0 -215
  83. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Switch.kt +0 -96
  84. package/compose/src/commonMain/kotlin/vn/momo/kits/components/TabView.kt +0 -531
  85. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tag.kt +0 -92
  86. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +0 -130
  87. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Title.kt +0 -214
  88. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tooltip.kt +0 -590
  89. package/compose/src/commonMain/kotlin/vn/momo/kits/components/TrustBanner.kt +0 -177
  90. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Uploader.kt +0 -192
  91. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePicker.kt +0 -205
  92. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerTypes.kt +0 -29
  93. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerUtils.kt +0 -239
  94. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/WheelPicker.kt +0 -191
  95. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Colors.kt +0 -306
  96. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Radius.kt +0 -12
  97. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Spacing.kt +0 -16
  98. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Theme.kt +0 -188
  99. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +0 -270
  100. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Card.kt +0 -2
  101. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Item.kt +0 -35
  102. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Section.kt +0 -2
  103. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/AutomationId.kt +0 -57
  104. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Clickable.kt +0 -68
  105. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Conditional.kt +0 -11
  106. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/DeprecatedModifier.kt +0 -14
  107. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Shadow.kt +0 -50
  108. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Size.kt +0 -51
  109. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/BottomSheet.kt +0 -253
  110. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ModalScreen.kt +0 -133
  111. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigation.kt +0 -99
  112. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +0 -168
  113. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigator.kt +0 -333
  114. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +0 -552
  115. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTab.kt +0 -161
  116. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +0 -243
  117. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/CurvedContainer.kt +0 -86
  118. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/FloatingButton.kt +0 -187
  119. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +0 -279
  120. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderBackground.kt +0 -80
  121. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderRight.kt +0 -306
  122. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderTitle.kt +0 -32
  123. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderUser.kt +0 -370
  124. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SnackBar.kt +0 -131
  125. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/tracking/ScreenTracker.kt +0 -167
  126. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +0 -45
  127. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Icons.kt +0 -1329
  128. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Resources.kt +0 -62
  129. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Tracking.kt +0 -15
  130. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Utils.kt +0 -105
  131. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +0 -176
  132. package/gradle/libs.versions.toml +0 -58
  133. package/gradle/wrapper/gradle-wrapper.jar +0 -0
  134. package/gradle/wrapper/gradle-wrapper.properties +0 -8
  135. package/gradle.properties +0 -26
  136. package/gradlew +0 -252
  137. package/gradlew.bat +0 -94
  138. package/local.properties +0 -8
  139. package/settings.gradle.kts +0 -52
@@ -17,7 +17,7 @@ public class MiniAppContext {
17
17
  public var toolkitConfig: [String: Any] = [:]
18
18
  public var providerId: String = "momo"
19
19
  public var permissions: [[String: Any]] = []
20
-
20
+
21
21
  public init(appId: String, appCode: String, appName: Any? = nil, appIcon: String, description: Any? = nil, support: [String: Any] = [:], toolkitConfig: [String: Any] = [:], providerId: String = "momo", permissions: [[String: Any]] = []) {
22
22
  self.appId = appId
23
23
  self.appCode = appCode
@@ -37,15 +37,11 @@ public class KitConfig {
37
37
  public var headerGradient: String? = nil
38
38
  }
39
39
 
40
- public var IsShowBaseLineDebug = false
41
-
42
- public var UseFontScaleSystem = true
43
-
44
40
  public class ApplicationEnvironment: ObservableObject {
45
41
  let applicationContext: MiniAppContext?
46
42
  let composeApi: KitComposeApi?
47
43
  let config: KitConfig?
48
-
44
+
49
45
  public init(applicationContext: MiniAppContext? = nil, composeApi: KitComposeApi? = nil, config: KitConfig? = nil) {
50
46
  self.applicationContext = applicationContext
51
47
  self.composeApi = composeApi
@@ -4,7 +4,7 @@ import Combine
4
4
 
5
5
  public struct Input: View {
6
6
  @Binding public var text: String
7
-
7
+
8
8
  public var placeholder: String
9
9
  public var floatingValue: String
10
10
  public var floatingIcon: String
@@ -22,6 +22,7 @@ public struct Input: View {
22
22
  public var leadingIconColor: Color
23
23
  public var loading: Bool
24
24
  public var required: Bool
25
+ public var maxLength: Int?
25
26
  public var fontWeight: InputFontWeight
26
27
  public var keyboardType: UIKeyboardType
27
28
  public var autofocus: Bool
@@ -29,10 +30,10 @@ public struct Input: View {
29
30
  public var onFocus: (() -> Void)?
30
31
  public var onBlur: (() -> Void)?
31
32
  public var onRightIconPressed: (() -> Void)?
32
-
33
+
33
34
  @State private var isFocused: Bool = false
34
35
  @State private var isPasswordHidden: Bool = true
35
-
36
+
36
37
  public init(
37
38
  text: Binding<String>,
38
39
  placeholder: String = "",
@@ -52,6 +53,7 @@ public struct Input: View {
52
53
  leadingIconColor: Color = Colors.black12,
53
54
  loading: Bool = false,
54
55
  required: Bool = false,
56
+ maxLength: Int? = nil,
55
57
  fontWeight: InputFontWeight = .regular,
56
58
  keyboardType: UIKeyboardType = .default,
57
59
  autofocus: Bool = false,
@@ -78,6 +80,7 @@ public struct Input: View {
78
80
  self.leadingIconColor = leadingIconColor
79
81
  self.loading = loading
80
82
  self.required = required
83
+ self.maxLength = maxLength
81
84
  self.fontWeight = fontWeight
82
85
  self.keyboardType = keyboardType
83
86
  self.autofocus = autofocus
@@ -93,7 +96,7 @@ public struct Input: View {
93
96
  get: { self.text },
94
97
  set: { newValue in
95
98
  self.text = newValue
96
- self.onChangeText?(newValue)
99
+ self.onChangeText?(limitText(newValue))
97
100
  }
98
101
  )
99
102
 
@@ -115,7 +118,7 @@ public struct Input: View {
115
118
  .offset(x: Spacing.S, y: -8)
116
119
  .zIndex(10)
117
120
  }
118
-
121
+
119
122
  // Input container
120
123
  HStack(alignment: .center, spacing: 0) {
121
124
  // Leading icon
@@ -123,7 +126,7 @@ public struct Input: View {
123
126
  Icon(source: leadingIcon, size: size == .small ? 24 : 32, color: leadingIconColor)
124
127
  .padding(.trailing, Spacing.M)
125
128
  }
126
-
129
+
127
130
  // Text input field
128
131
  ZStack(alignment: .leading) {
129
132
  if text.isEmpty {
@@ -133,7 +136,7 @@ public struct Input: View {
133
136
  color: getPlaceholderColor()
134
137
  )
135
138
  }
136
-
139
+
137
140
  if secureTextEntry && isPasswordHidden {
138
141
  SecureInputField(
139
142
  text: $text,
@@ -142,6 +145,7 @@ public struct Input: View {
142
145
  fontWeight: fontWeight == .bold ? .bold : .regular,
143
146
  textColor: UIColor(getTextColor()),
144
147
  isDisabled: disabled || readOnly,
148
+ maxLength: maxLength,
145
149
  onFocusChange: { focused in
146
150
  handleFocusChange(focused)
147
151
  },
@@ -156,9 +160,15 @@ public struct Input: View {
156
160
  .foregroundColor(getTextColor())
157
161
  .disabled(disabled || readOnly)
158
162
  .applyPrimaryCursorColor()
163
+ .onChange(of: text) { newValue in
164
+ let limited = limitText(newValue)
165
+ if limited != newValue {
166
+ text = limited
167
+ }
168
+ }
159
169
  }
160
170
  }
161
-
171
+
162
172
  // Clear button (only show when focused and has text)
163
173
  if isFocused && !text.isEmpty {
164
174
  SwiftUI.Button(action: {
@@ -169,14 +179,14 @@ public struct Input: View {
169
179
  .padding(.leading, Spacing.S).accessibility(identifier: "ic_clear")
170
180
  }
171
181
  }
172
-
182
+
173
183
  // Loading indicator
174
184
  if loading {
175
185
  ActivityIndicator(isAnimating: .constant(true), style: .medium)
176
186
  .frame(width: 16, height: 16)
177
187
  .padding(.leading, Spacing.S)
178
188
  }
179
-
189
+
180
190
  // Right icon (password toggle or custom icon)
181
191
  if secureTextEntry {
182
192
  if !text.isEmpty {
@@ -197,7 +207,7 @@ public struct Input: View {
197
207
  }
198
208
  }
199
209
  .padding(.horizontal, Spacing.M)
200
- .frame(height: scaleSize(size == .small ? 48 : 56))
210
+ .frame(height: scaleSize(size == .small ? 48 : 56, 1.1))
201
211
  .background(
202
212
  RoundedRectangle(cornerRadius: Radius.S)
203
213
  .fill(Colors.black01)
@@ -207,7 +217,7 @@ public struct Input: View {
207
217
  .stroke(borderColor(), lineWidth: 1)
208
218
  )
209
219
  }
210
-
220
+
211
221
  // Error or hint
212
222
  ErrorView(
213
223
  errorMessage: error,
@@ -223,9 +233,9 @@ public struct Input: View {
223
233
  }
224
234
  }
225
235
  }
226
-
236
+
227
237
  // MARK: - Helpers
228
-
238
+
229
239
  private func handleFocusChange(_ focused: Bool) {
230
240
  isFocused = focused
231
241
  if focused {
@@ -234,12 +244,19 @@ public struct Input: View {
234
244
  onBlur?()
235
245
  }
236
246
  }
237
-
247
+
238
248
  private func togglePasswordVisibility() {
239
249
  isPasswordHidden.toggle()
240
250
  onRightIconPressed?()
241
251
  }
242
252
 
253
+ private func limitText(_ value: String) -> String {
254
+ guard let maxLength = maxLength else {
255
+ return value
256
+ }
257
+ return String(value.prefix(maxLength))
258
+ }
259
+
243
260
  private func borderColor() -> Color {
244
261
  if disabled {
245
262
  return Colors.black04 // border.disable
@@ -252,19 +269,19 @@ public struct Input: View {
252
269
  }
253
270
  return Colors.black04 // border.default
254
271
  }
255
-
272
+
256
273
  private func getTextColor() -> Color {
257
274
  return disabled ? Colors.black09 : Colors.black17
258
275
  }
259
-
276
+
260
277
  private func getPlaceholderColor() -> Color {
261
278
  return disabled ? Colors.black09 : Colors.black12
262
279
  }
263
-
280
+
264
281
  private func getFloatingColor() -> Color {
265
282
  return disabled ? Colors.black09 : Colors.black12
266
283
  }
267
-
284
+
268
285
  private func getFloatingIconColor() -> Color {
269
286
  return disabled ? Colors.black09 : floatingIconColor
270
287
  }
@@ -279,6 +296,7 @@ private struct SecureInputField: UIViewRepresentable {
279
296
  var fontWeight: UIFont.Weight
280
297
  var textColor: UIColor
281
298
  var isDisabled: Bool
299
+ var maxLength: Int?
282
300
  var onFocusChange: (Bool) -> Void
283
301
  var onChangeText: ((String) -> Void)?
284
302
 
@@ -307,6 +325,7 @@ private struct SecureInputField: UIViewRepresentable {
307
325
  }
308
326
 
309
327
  func updateUIView(_ textField: UITextField, context: Context) {
328
+ context.coordinator.parent = self
310
329
  if textField.text != text {
311
330
  textField.text = text
312
331
  }
@@ -342,7 +361,7 @@ private struct SecureInputField: UIViewRepresentable {
342
361
  }
343
362
 
344
363
  func textFieldDidEndEditing(_ textField: UITextField) {
345
- parent.text = textField.text ?? ""
364
+ parent.text = limitText(textField.text ?? "")
346
365
  parent.onFocusChange(false)
347
366
  }
348
367
 
@@ -357,7 +376,10 @@ private struct SecureInputField: UIViewRepresentable {
357
376
 
358
377
  @objc func textFieldDidChange(_ textField: UITextField) {
359
378
  if isResettingText { return }
360
- let newText = textField.text ?? ""
379
+ let newText = limitText(textField.text ?? "")
380
+ if textField.text != newText {
381
+ textField.text = newText
382
+ }
361
383
  parent.text = newText
362
384
  parent.onChangeText?(newText)
363
385
  }
@@ -366,6 +388,13 @@ private struct SecureInputField: UIViewRepresentable {
366
388
  textField.resignFirstResponder()
367
389
  return true
368
390
  }
391
+
392
+ private func limitText(_ value: String) -> String {
393
+ guard let maxLength = parent.maxLength else {
394
+ return value
395
+ }
396
+ return String(value.prefix(maxLength))
397
+ }
369
398
  }
370
399
  }
371
400
 
@@ -8,7 +8,7 @@
8
8
  import SwiftUI
9
9
  public struct InputPhoneNumber: View {
10
10
  @Binding public var text: String
11
-
11
+
12
12
  public var placeholder: String
13
13
  public var size: InputSize
14
14
  public var hintText: String
@@ -22,9 +22,9 @@ public struct InputPhoneNumber: View {
22
22
  public var onBlur: (() -> Void)?
23
23
  public var onRightIconPressed: (() -> Void)?
24
24
  public var accessibilityLabel: String?
25
-
25
+
26
26
  @State private var isFocused: Bool = false
27
-
27
+
28
28
  public init(
29
29
  text: Binding<String>,
30
30
  placeholder: String = "0123456789",
@@ -57,7 +57,7 @@ public struct InputPhoneNumber: View {
57
57
  self.onRightIconPressed = onRightIconPressed
58
58
  self.accessibilityLabel = accessibilityLabel
59
59
  }
60
-
60
+
61
61
  // MARK: - Body
62
62
  public var body: some View {
63
63
  let textBinding = Binding<String>(
@@ -67,28 +67,28 @@ public struct InputPhoneNumber: View {
67
67
  self.onChangeText?(newValue)
68
68
  }
69
69
  )
70
-
70
+
71
71
  VStack(alignment: .leading, spacing: 4) {
72
72
  HStack(spacing: 0) {
73
73
  // 🇻🇳 Flag
74
74
  ImageView("https://static.momocdn.net/app/img/icon/ic-qrcode-package/ic_vn_flag.png")
75
75
  .frame(width: 24, height: 24)
76
76
  .padding(.trailing, Spacing.XS)
77
-
77
+
78
78
  MomoText("+84", typography: size == .small ? .headerSSemibold : .headerMBold)
79
79
  .foregroundColor(Colors.black17)
80
-
80
+
81
81
  Rectangle()
82
82
  .fill(Colors.black04)
83
83
  .frame(width: 1, height: size == .small ? 24 : 32)
84
84
  .padding(.horizontal, Spacing.M)
85
-
85
+
86
86
  // Text input
87
87
  ZStack(alignment: .leading) {
88
88
  if text.isEmpty {
89
89
  MomoText(placeholder, typography: size == .small ? .headerSSemibold : .headerMBold, color: Colors.black12)
90
90
  }
91
-
91
+
92
92
  TextField("", text: textBinding, onEditingChanged: { focused in
93
93
  handleFocusChange(focused)
94
94
  })
@@ -100,7 +100,7 @@ public struct InputPhoneNumber: View {
100
100
  .accessibility(identifier: accessibilityLabel ?? "")
101
101
  .accessibilityValue(textBinding.wrappedValue.isEmpty ? placeholder : textBinding.wrappedValue)
102
102
  }
103
-
103
+
104
104
  // Clear button
105
105
  if isFocused && !text.isEmpty {
106
106
  SwiftUI.Button(action: {
@@ -111,13 +111,13 @@ public struct InputPhoneNumber: View {
111
111
  .padding(.leading, Spacing.S).accessibility(identifier: "ic_clear")
112
112
  }
113
113
  }
114
-
114
+
115
115
  // Loading indicator
116
116
  if loading {
117
117
  ActivityIndicator(isAnimating: .constant(true), style: .medium)
118
118
  .frame(width: 16, height: 16)
119
119
  }
120
-
120
+
121
121
  // ✅ Right icon
122
122
  if !rightIcon.isEmpty {
123
123
  SwiftUI.Button(action: { onRightIconPressed?() }) {
@@ -127,7 +127,7 @@ public struct InputPhoneNumber: View {
127
127
  }
128
128
  }
129
129
  .padding(.horizontal, Spacing.M)
130
- .frame(height: scaleSize(size == .small ? 48 : 56))
130
+ .frame(height: scaleSize(size == .small ? 48 : 56, 1.1))
131
131
  .background(
132
132
  RoundedRectangle(cornerRadius: Radius.S)
133
133
  .fill(Colors.black01)
@@ -136,7 +136,7 @@ public struct InputPhoneNumber: View {
136
136
  RoundedRectangle(cornerRadius: Radius.S)
137
137
  .stroke(borderColor(), lineWidth: isFocused ? 1.5 : 1)
138
138
  )
139
-
139
+
140
140
  // Error or hint
141
141
  ErrorView(
142
142
  errorMessage: error,
@@ -145,9 +145,9 @@ public struct InputPhoneNumber: View {
145
145
  )
146
146
  }
147
147
  }
148
-
148
+
149
149
  // MARK: - Helpers
150
-
150
+
151
151
  private func handleFocusChange(_ focused: Bool) {
152
152
  isFocused = focused
153
153
  if focused {
@@ -156,7 +156,7 @@ public struct InputPhoneNumber: View {
156
156
  onBlur?()
157
157
  }
158
158
  }
159
-
159
+
160
160
  private func borderColor() -> Color {
161
161
  if !error.isEmpty { return Colors.red03 }
162
162
  if isFocused { return Colors.primary }
@@ -0,0 +1,13 @@
1
+ #import <Foundation/Foundation.h>
2
+
3
+ NS_ASSUME_NONNULL_BEGIN
4
+
5
+ /// Posts `MoMoStatusBarTap.notificationName` on every status-bar tap.
6
+ /// The swizzle installs automatically at framework load (`+load`) — calling
7
+ /// `install` is a no-op kept for explicit/manual triggering.
8
+ @interface MoMoStatusBarTap : NSObject
9
+ @property (class, nonatomic, readonly) NSNotificationName notificationName;
10
+ + (void)install;
11
+ @end
12
+
13
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,75 @@
1
+ #import <UIKit/UIKit.h>
2
+ #import <objc/message.h>
3
+ #import <objc/runtime.h>
4
+ #import "StatusBarTap.h"
5
+
6
+ // Performs the actual swizzle once per process. Safe to call multiple times.
7
+ static void mm_installStatusBarTapSwizzleOnce(void) {
8
+ static dispatch_once_t onceToken;
9
+ dispatch_once(&onceToken, ^{
10
+ Class cls = [UIStatusBarManager class];
11
+ SEL originalSelector = NSSelectorFromString(@"handleTapAction:");
12
+ SEL swizzledSelector = NSSelectorFromString(@"mm_handleTapAction:");
13
+
14
+ Method originalMethod = class_getInstanceMethod(cls, originalSelector);
15
+ Method swizzledMethod = class_getInstanceMethod(cls, swizzledSelector);
16
+ if (!originalMethod || !swizzledMethod) return;
17
+
18
+ // Verify the original method matches the (id) -> void shape we expect.
19
+ // Encoding may include byte offsets (e.g. "v32@0:8@16") so we filter
20
+ // digits out before comparing.
21
+ const char *encPtr = method_getTypeEncoding(originalMethod);
22
+ if (encPtr) {
23
+ NSMutableString *enc = [NSMutableString string];
24
+ for (const char *p = encPtr; *p; p++) {
25
+ if (!(*p >= '0' && *p <= '9')) [enc appendFormat:@"%c", *p];
26
+ }
27
+ if (![enc isEqualToString:@"v@:@"]) return;
28
+ }
29
+
30
+ BOOL didAdd = class_addMethod(cls,
31
+ originalSelector,
32
+ method_getImplementation(swizzledMethod),
33
+ method_getTypeEncoding(swizzledMethod));
34
+ if (didAdd) {
35
+ class_replaceMethod(cls,
36
+ swizzledSelector,
37
+ method_getImplementation(originalMethod),
38
+ method_getTypeEncoding(originalMethod));
39
+ } else {
40
+ method_exchangeImplementations(originalMethod, swizzledMethod);
41
+ }
42
+ });
43
+ }
44
+
45
+ @implementation MoMoStatusBarTap
46
+ + (NSNotificationName)notificationName { return @"statusBarSelected"; }
47
+ + (void)install { mm_installStatusBarTapSwizzleOnce(); }
48
+ @end
49
+
50
+ // MARK: - Swizzle target on UIStatusBarManager
51
+ // `mm_handleTapAction:` is the replacement IMP. After the add/exchange,
52
+ // this selector points at the original UIKit IMP — calling it inside
53
+ // the body invokes UIKit's real handler so UIScrollView.scrollsToTop
54
+ // and any other side effects continue to work.
55
+
56
+ @interface UIStatusBarManager (MoMoStatusBarTap)
57
+ @end
58
+
59
+ @implementation UIStatusBarManager (MoMoStatusBarTap)
60
+
61
+ // Auto-install at framework load. Commented out so the swizzle stays
62
+ // opt-in via `[MoMoStatusBarTap install]`. Uncomment to revert to
63
+ // auto-installation before main().
64
+ //
65
+ // + (void)load {
66
+ // mm_installStatusBarTapSwizzleOnce();
67
+ // }
68
+
69
+ - (void)mm_handleTapAction:(id)action {
70
+ [self mm_handleTapAction:action];
71
+ [[NSNotificationCenter defaultCenter] postNotificationName:MoMoStatusBarTap.notificationName
72
+ object:nil];
73
+ }
74
+
75
+ @end
@@ -1,25 +1,30 @@
1
1
  import SwiftUI
2
2
 
3
- private let DEFAULT_SCREEN_SIZE: CGFloat = 375
4
- private let MAX_FONT_SCALE: CGFloat = 1.2
3
+ public func scaleSize(_ size: CGFloat, _ scaleRate: CGFloat? = nil) -> CGFloat {
4
+ let defaultScreenSize: CGFloat = 375
5
+ let maxFontScale: CGFloat = scaleRate ?? 1.5
6
+ let maxDeviceScale: CGFloat = 5
5
7
 
6
- public func scaleSize(_ size: CGFloat) -> CGFloat {
7
- if UseFontScaleSystem {
8
- let deviceWidth = UIScreen.main.bounds.width
9
- let deviceScale = deviceWidth / DEFAULT_SCREEN_SIZE
8
+ let deviceWidth = UIScreen.main.bounds.width
9
+ let deviceScale = deviceWidth / defaultScreenSize
10
10
 
11
- let defaultFont = UIFont.systemFont(ofSize: UIFont.labelFontSize)
12
- let scaledFont = UIFontMetrics.default.scaledFont(for: defaultFont)
13
- let fontScale = scaledFont.pointSize / defaultFont.pointSize
11
+ let defaultFont = UIFont.systemFont(ofSize: UIFont.labelFontSize)
12
+ let scaledFont = UIFontMetrics.default.scaledFont(for: defaultFont)
13
+ let fontScale = scaledFont.pointSize / defaultFont.pointSize
14
14
 
15
- let maxSize = size * MAX_FONT_SCALE
16
- let fontSizeScaleDevice = deviceScale > 1 ? deviceScale * size : size
17
- let fontSizeScaleOS = fontScale > 1 ? fontScale * size : size
15
+ var fontSizeDeviceScale = size
16
+ var fontSizeOSScale = size
18
17
 
19
- return min(max(fontSizeScaleDevice, fontSizeScaleOS), maxSize)
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)
20
25
  }
21
26
 
22
- return size
27
+ return max(fontSizeDeviceScale, fontSizeOSScale)
23
28
  }
24
29
 
25
30
  public enum TypographyStyle {
@@ -2,7 +2,28 @@ import SwiftUI
2
2
 
3
3
  public extension Font {
4
4
  static func appFont(size: CGFloat) -> Font {
5
- return Font.system(size: scaleSize(size))
5
+ let defaultScreenSize: CGFloat = 375
6
+ let maxFontScale: CGFloat = 1.5
7
+ let maxDeviceScale: CGFloat = 5
8
+
9
+ let deviceWidth = UIScreen.main.bounds.width
10
+ let deviceScale = deviceWidth / defaultScreenSize
11
+
12
+ let defaultFont = UIFont.systemFont(ofSize: UIFont.labelFontSize)
13
+ let scaledFont = UIFontMetrics.default.scaledFont(for: defaultFont)
14
+ let fontScale = scaledFont.pointSize / defaultFont.pointSize
15
+
16
+ var fontSize = size
17
+
18
+ if deviceScale > 1 {
19
+ fontSize = min(fontSize * deviceScale, fontSize + maxDeviceScale)
20
+ }
21
+
22
+ if fontScale > 1 {
23
+ fontSize = min(fontSize * fontScale, fontSize * maxFontScale)
24
+ }
25
+
26
+ return Font.system(size: fontSize)
6
27
  }
7
28
 
8
29
  // New supported typography styles
@@ -10,7 +10,8 @@ Pod::Spec.new do |s|
10
10
  s.ios.deployment_target = '15.0'
11
11
  s.swift_version = '5.0'
12
12
 
13
- s.source_files = "**/*.swift"
13
+ s.source_files = "**/*.{swift,m,h}"
14
+ s.public_header_files = "StatusBarTap/*.h"
14
15
  s.framework = 'SwiftUI', 'Combine'
15
16
  s.dependency 'SDWebImageSwiftUI'
16
17
  s.dependency 'lottie-ios'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/native-kits",
3
- "version": "0.161.1-beta.15-debug",
3
+ "version": "0.161.2-beta.1",
4
4
  "private": false,
5
5
  "dependencies": {},
6
6
  "devDependencies": {},
package/build.gradle.kts DELETED
@@ -1,11 +0,0 @@
1
- plugins {
2
- // this is necessary to avoid the plugins to be loaded multiple times
3
- // in each subproject's classloader
4
- alias(libs.plugins.android.application) apply false
5
- alias(libs.plugins.android.library) apply false
6
- alias(libs.plugins.compose) apply false
7
- alias(libs.plugins.kotlin.compose.compiler) apply false
8
- alias(libs.plugins.jetbrains.kotlin.multiplatform) apply false
9
- alias(libs.plugins.jetbrains.kotlin.serialization) apply false
10
- alias(libs.plugins.vanniktech.mavenPublish) apply false
11
- }