@momo-kits/native-kits 0.162.4-debug → 0.162.5-debug

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 (96) hide show
  1. package/compose/build.gradle.kts +11 -8
  2. package/compose/build.gradle.kts.backup +10 -7
  3. package/compose/compose.podspec +1 -1
  4. package/compose/src/commonMain/kotlin/vn/momo/kits/application/AnimationSearchInput.kt +2 -7
  5. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Context.kt +10 -3
  6. package/compose/src/commonMain/kotlin/vn/momo/kits/application/FloatingButton.kt +6 -24
  7. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Header.kt +4 -19
  8. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderAnimated.kt +1 -10
  9. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderBackground.kt +2 -2
  10. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderDefault.kt +1 -1
  11. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderExtended.kt +1 -1
  12. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderRight.kt +5 -16
  13. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderTitle.kt +1 -1
  14. package/compose/src/commonMain/kotlin/vn/momo/kits/application/LiteScreen.kt +6 -101
  15. package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +2 -14
  16. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +8 -33
  17. package/compose/src/commonMain/kotlin/vn/momo/kits/application/useHeaderSearchAnimation.kt +1 -1
  18. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Badge.kt +1 -6
  19. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeRibbon.kt +27 -29
  20. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BaselineView.kt +3 -26
  21. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +27 -30
  22. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Carousel.kt +3 -13
  23. package/compose/src/commonMain/kotlin/vn/momo/kits/components/CheckBox.kt +0 -5
  24. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Chip.kt +3 -11
  25. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Collapse.kt +3 -18
  26. package/compose/src/commonMain/kotlin/vn/momo/kits/components/CupertinoOverscroll.kt +11 -11
  27. package/compose/src/commonMain/kotlin/vn/momo/kits/components/IconButton.kt +3 -11
  28. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Information.kt +1 -5
  29. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +84 -59
  30. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputDropDown.kt +13 -71
  31. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputMoney.kt +10 -51
  32. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputOTP.kt +6 -1
  33. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputPhoneNumber.kt +4 -21
  34. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +1 -1
  35. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +15 -76
  36. package/compose/src/commonMain/kotlin/vn/momo/kits/components/LazyColumnWithBouncing.kt +5 -26
  37. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationDot.kt +1 -1
  38. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationScroll.kt +3 -11
  39. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +15 -36
  40. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupPromotion.kt +3 -9
  41. package/compose/src/commonMain/kotlin/vn/momo/kits/components/ProgressInfo.kt +0 -28
  42. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Radio.kt +2 -13
  43. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Skeleton.kt +4 -10
  44. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Slider.kt +3 -28
  45. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Stepper.kt +8 -47
  46. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Steps.kt +4 -25
  47. package/compose/src/commonMain/kotlin/vn/momo/kits/components/SuggestAction.kt +2 -11
  48. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Swipe.kt +1 -17
  49. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Switch.kt +1 -6
  50. package/compose/src/commonMain/kotlin/vn/momo/kits/components/TabView.kt +50 -111
  51. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tag.kt +1 -5
  52. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +7 -8
  53. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Title.kt +1 -12
  54. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tooltip.kt +4 -96
  55. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Uploader.kt +2 -12
  56. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePicker.kt +9 -21
  57. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerTypes.kt +2 -2
  58. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerUtils.kt +9 -14
  59. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/WheelPicker.kt +8 -11
  60. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Theme.kt +1 -1
  61. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +24 -40
  62. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Item.kt +1 -1
  63. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/AutomationId.kt +0 -5
  64. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Clickable.kt +0 -2
  65. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/DeprecatedModifier.kt +94 -4
  66. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Shadow.kt +0 -2
  67. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ModalScreen.kt +1 -5
  68. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigation.kt +5 -15
  69. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +48 -7
  70. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigator.kt +48 -33
  71. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +56 -55
  72. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTab.kt +3 -9
  73. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +12 -32
  74. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/CurvedContainer.kt +1 -1
  75. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/FloatingButton.kt +6 -24
  76. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +11 -7
  77. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderBackground.kt +2 -1
  78. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderRight.kt +6 -3
  79. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderTitle.kt +1 -1
  80. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderUser.kt +3 -13
  81. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SnackBar.kt +3 -2
  82. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/tracking/ScreenTracker.kt +1 -40
  83. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/ComposeLottieAnimation.kt +0 -2
  84. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +0 -8
  85. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Resources.kt +2 -17
  86. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Tracking.kt +1 -1
  87. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Utils.kt +3 -3
  88. package/compose/src/iosMain/kotlin/vn/momo/kits/navigation/ScrollToTop.ios.kt +2 -3
  89. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +0 -2
  90. package/gradle.properties +1 -1
  91. package/ios/Application/ApplicationEnvironment.swift +1 -0
  92. package/ios/Application/FontScaleStore.swift +59 -0
  93. package/ios/Typography/Text.swift +12 -7
  94. package/ios/Typography/Typography.swift +13 -8
  95. package/package.json +1 -1
  96. package/compose/src/commonMain/kotlin/vn/momo/kits/components/ScaleSizeScope.kt +0 -17
@@ -1,5 +1,7 @@
1
1
  package vn.momo.kits.navigation.component
2
2
 
3
+ import vn.momo.kits.modifier.InternalApi
4
+
3
5
  import androidx.compose.animation.core.animateFloatAsState
4
6
  import androidx.compose.foundation.background
5
7
  import androidx.compose.foundation.border
@@ -42,12 +44,13 @@ import vn.momo.kits.navigation.LocalOptions
42
44
  import vn.momo.kits.navigation.LocalScrollState
43
45
  import vn.momo.kits.navigation.getInputSearchType
44
46
 
45
- const val HEADER_HEIGHT = 52
46
- enum class InputSearchType { None, Header, Animated }
47
+ internal const val HEADER_HEIGHT = 52
48
+ internal enum class InputSearchType { None, Header, Animated }
47
49
  enum class TitlePosition { LEFT, CENTER }
48
50
 
51
+ @Suppress("FrequentlyChangingValue")
49
52
  @Composable
50
- fun Header(onBackHandler: (() -> Unit)? = null) {
53
+ internal fun Header(onBackHandler: (() -> Unit)? = null) {
51
54
  val options = LocalOptions.current
52
55
  val navigator = LocalNavigator.current
53
56
  val scrollState = LocalScrollState.current
@@ -106,7 +109,7 @@ fun Header(onBackHandler: (() -> Unit)? = null) {
106
109
  backgroundButton = headerColor.backgroundButton,
107
110
  tintIconColor = headerColor.tintIconColor,
108
111
  onBackHandler = {
109
- onBackHandler?.invoke() ?: navigator.onBackSafe { }
112
+ navigator.onBackSafe { }
110
113
  }
111
114
  )
112
115
  Spacer(Modifier.width(Spacing.S))
@@ -168,7 +171,7 @@ private fun BackButton(borderColor: Color, backgroundButton: Color, tintIconColo
168
171
  }
169
172
 
170
173
  @Composable
171
- fun HeaderContent(
174
+ internal fun HeaderContent(
172
175
  headerTitle: HeaderTitle,
173
176
  tintIconColor: Color,
174
177
  titlePosition: TitlePosition = TitlePosition.LEFT,
@@ -199,7 +202,7 @@ fun HeaderContent(
199
202
  }
200
203
 
201
204
  @Composable
202
- fun VerticalShadow(opacity: Float){
205
+ internal fun VerticalShadow(opacity: Float){
203
206
  if(opacity == 1f){
204
207
  Box(modifier = Modifier
205
208
  .fillMaxWidth()
@@ -282,8 +285,9 @@ data class HeaderBackProps(
282
285
  val preventBack: PopupNotifyProps? = null,
283
286
  )
284
287
 
288
+ @InternalApi
285
289
  data class HeaderColor(val tintIconColor: Color, val backgroundButton: Color, val borderColor: Color)
286
- fun getHeaderColor(headerType: HeaderType, opacity: Float, tintColor: Color?, defaultColor: Color): HeaderColor{
290
+ internal fun getHeaderColor(headerType: HeaderType, opacity: Float, tintColor: Color?, defaultColor: Color): HeaderColor{
287
291
  return if(headerType is HeaderType.Animated) {
288
292
  if (opacity == 1f || !headerType.isSurface)
289
293
  HeaderColor(
@@ -27,8 +27,9 @@ enum class AnimatedHeaderRatio(val value: Float){
27
27
  RATIO_3_2(3f / 2f)
28
28
  }
29
29
 
30
+ @Suppress("FrequentlyChangingValue")
30
31
  @Composable
31
- fun HeaderBackground() {
32
+ internal fun HeaderBackground() {
32
33
  val density = LocalDensity.current
33
34
  val theme = AppTheme.current
34
35
  val options = LocalOptions.current
@@ -1,5 +1,7 @@
1
1
  package vn.momo.kits.navigation.component
2
2
 
3
+ import vn.momo.kits.modifier.InternalApi
4
+
3
5
  import androidx.compose.foundation.background
4
6
  import androidx.compose.foundation.border
5
7
  import androidx.compose.foundation.layout.Arrangement
@@ -35,6 +37,7 @@ import vn.momo.kits.modifier.activeOpacityClickable
35
37
  import vn.momo.kits.navigation.LocalMaxApi
36
38
 
37
39
  @Composable
40
+ @InternalApi
38
41
  fun HeaderRight(
39
42
  headerRight: HeaderRight,
40
43
  tintColor: Color? = null,
@@ -57,7 +60,7 @@ fun HeaderRight(
57
60
  }
58
61
 
59
62
  @Composable
60
- fun Toolkit(
63
+ internal fun Toolkit(
61
64
  headerRight: HeaderRight.Toolkit,
62
65
  tintColor: Color? = null,
63
66
  headerColor: HeaderColor
@@ -186,7 +189,7 @@ fun Toolkit(
186
189
 
187
190
 
188
191
  @Composable
189
- fun NavigationButton(
192
+ internal fun NavigationButton(
190
193
  disabled: Boolean,
191
194
  icon: String,
192
195
  showBadge: Boolean? = false,
@@ -300,7 +303,7 @@ data class Tool(
300
303
  }
301
304
  }
302
305
 
303
- data class NavigationButtonConfig(
306
+ private data class NavigationButtonConfig(
304
307
  val icon: String,
305
308
  val onPress: () -> Unit
306
309
  )
@@ -13,7 +13,7 @@ import vn.momo.kits.const.Typography
13
13
  import vn.momo.kits.modifier.setAutomationId
14
14
 
15
15
  @Composable
16
- fun HeaderTitle(
16
+ internal fun HeaderTitle(
17
17
  title: String = "",
18
18
  color: Color? = null,
19
19
  modifier: Modifier = Modifier.fillMaxWidth(),
@@ -2,17 +2,7 @@ package vn.momo.kits.navigation.component
2
2
 
3
3
  import androidx.compose.foundation.background
4
4
  import androidx.compose.foundation.border
5
- import androidx.compose.foundation.layout.Arrangement
6
- import androidx.compose.foundation.layout.Box
7
- import androidx.compose.foundation.layout.Column
8
- import androidx.compose.foundation.layout.Row
9
- import androidx.compose.foundation.layout.Spacer
10
- import androidx.compose.foundation.layout.fillMaxWidth
11
- import androidx.compose.foundation.layout.height
12
- import androidx.compose.foundation.layout.padding
13
- import androidx.compose.foundation.layout.size
14
- import androidx.compose.foundation.layout.width
15
- import androidx.compose.foundation.layout.widthIn
5
+ import androidx.compose.foundation.layout.*
16
6
  import androidx.compose.foundation.shape.CircleShape
17
7
  import androidx.compose.foundation.shape.RoundedCornerShape
18
8
  import androidx.compose.foundation.text.BasicText
@@ -43,7 +33,7 @@ import vn.momo.kits.navigation.component.HeaderTitle.User
43
33
  import vn.momo.kits.platform.getScreenDimensions
44
34
 
45
35
  @Composable
46
- fun HeaderUser(
36
+ internal fun HeaderUser(
47
37
  data: HeaderTitle
48
38
  ) {
49
39
  if (data !is User) return
@@ -367,4 +357,4 @@ private fun RemoteIcon16(url: String) {
367
357
  }
368
358
 
369
359
  @Immutable
370
- data class AvatarUrls(val items: List<String>)
360
+ private data class AvatarUrls(val items: List<String>)
@@ -29,6 +29,7 @@ import vn.momo.kits.navigation.LocalFooterHeightPx
29
29
  import vn.momo.kits.navigation.LocalNavigator
30
30
  import vn.momo.kits.navigation.LocalOptions
31
31
  import vn.momo.kits.navigation.OverplayComponentRegistry
32
+ import kotlin.time.Duration.Companion.milliseconds
32
33
 
33
34
  sealed class SnackBar(open val duration: Long? = null) {
34
35
  data class Custom(
@@ -42,7 +43,7 @@ sealed class SnackBar(open val duration: Long? = null) {
42
43
  }
43
44
 
44
45
  @Composable
45
- fun SnackBar(
46
+ internal fun SnackBar(
46
47
  data: SnackBar,
47
48
  onDismiss: (() -> Unit)?
48
49
  ) {
@@ -95,7 +96,7 @@ fun SnackBar(
95
96
  LaunchedEffect(data.duration) {
96
97
  val duration = data.duration
97
98
  if (duration != null) {
98
- delay(duration)
99
+ delay(duration.milliseconds)
99
100
  navigator.hideSnackBar()
100
101
  }
101
102
  }
@@ -5,13 +5,9 @@ import vn.momo.maxapi.IMaxApi
5
5
  import kotlin.time.Clock
6
6
  import kotlin.time.ExperimentalTime
7
7
 
8
- /**
9
- * Screen tracking state holder
10
- */
11
8
  class ScreenTrackingState {
12
9
  @OptIn(ExperimentalTime::class)
13
- var startTime: Long = Clock.System.now().toEpochMilliseconds()
14
- var endTime: Long = startTime
10
+ var time: Long = Clock.System.now().toEpochMilliseconds()
15
11
  var releaseNavigated: Boolean = false
16
12
  var releaseLoad: Boolean = false
17
13
  var releaseInteraction: Boolean = false
@@ -19,22 +15,10 @@ class ScreenTrackingState {
19
15
  var action: String = "push"
20
16
  }
21
17
 
22
- /**
23
- * Screen tracker for auto tracking events
24
- *
25
- * Tracks 3 main events:
26
- * - auto_screen_navigated: When screen is focused
27
- * - auto_screen_displayed: When screen finished loading
28
- * - auto_screen_interacted: When screen is ready for interaction
29
- */
30
18
  object ScreenTracker {
31
19
 
32
20
  private var lastScreenName: String? = null
33
21
 
34
- /**
35
- * Track screen navigation event
36
- * Called when screen is focused
37
- */
38
22
  fun trackScreenNavigated(
39
23
  maxApi: IMaxApi?,
40
24
  context: MiniAppContext?,
@@ -61,10 +45,6 @@ object ScreenTracker {
61
45
  state.previousScreenName = previousScreen
62
46
  }
63
47
 
64
- /**
65
- * Track screen displayed event
66
- * Called when screen finished loading all elements
67
- */
68
48
  fun trackScreenDisplayed(
69
49
  maxApi: IMaxApi?,
70
50
  context: MiniAppContext?,
@@ -85,10 +65,6 @@ object ScreenTracker {
85
65
  state.releaseLoad = true
86
66
  }
87
67
 
88
- /**
89
- * Track screen interacted event
90
- * Called when screen is ready for user interaction
91
- */
92
68
  fun trackScreenInteracted(
93
69
  maxApi: IMaxApi?,
94
70
  context: MiniAppContext?,
@@ -111,9 +87,6 @@ object ScreenTracker {
111
87
  state.releaseInteraction = true
112
88
  }
113
89
 
114
- /**
115
- * Build base tracking params from MiniAppContext
116
- */
117
90
  private fun buildBaseParams(
118
91
  context: MiniAppContext?,
119
92
  screenName: String,
@@ -128,12 +101,6 @@ object ScreenTracker {
128
101
  )
129
102
  }
130
103
 
131
- /**
132
- * Track popup/modal displayed event
133
- *
134
- * @param popupName name of the popup/modal
135
- * @param parentScreenName the screen that shows the popup
136
- */
137
104
  fun trackPopupDisplayed(
138
105
  maxApi: IMaxApi?,
139
106
  context: MiniAppContext?,
@@ -152,14 +119,8 @@ object ScreenTracker {
152
119
  )
153
120
  }
154
121
 
155
- /**
156
- * Get previous screen name for back navigation detection
157
- */
158
122
  fun getLastScreenName(): String? = lastScreenName
159
123
 
160
- /**
161
- * Reset tracker (for testing or cleanup)
162
- */
163
124
  @Suppress("UNUSED")
164
125
  fun reset() {
165
126
  lastScreenName = null
@@ -36,8 +36,6 @@ internal fun ComposeLottieAnimation(
36
36
  LottieCompositionSpec.JsonString(json)
37
37
  }
38
38
 
39
- // Recolor only the fill/stroke color slots (matching the native lottie-ios per-keypath tint)
40
- // instead of a global ColorFilter.tint, which would flatten a multicolor animation to a silhouette.
41
39
  val dynamicProperties = if (tintColor != null) {
42
40
  rememberLottieDynamicProperties(tintColor) {
43
41
  shapeLayer("**") {
@@ -43,14 +43,6 @@ fun supportsImePadding(): Boolean = when (val v = getOSVersion()) {
43
43
  is OSVersion.Android -> v.sdk > 29
44
44
  is OSVersion.IOS -> true
45
45
  }
46
-
47
- /**
48
- * @param useCompose when `true`, renders via the pure-Compose Compottie engine instead of the
49
- * platform-native engine (airbnb-lottie on Android, lottie-ios on iOS). Defaults to `false` for
50
- * backward compatibility. Note: when `useCompose = true`, `tintColor` recolors only the fill/stroke
51
- * color slots (matching the native lottie-ios per-keypath tint), so gradient and text-layer colors
52
- * are left untinted; `placedAsOverlay` is a no-op.
53
- */
54
46
  @Composable
55
47
  expect fun LottieAnimation(
56
48
  path: String,
@@ -1,28 +1,13 @@
1
1
  package vn.momo.kits.utils
2
2
 
3
- import androidx.compose.runtime.Composable
4
- import androidx.compose.runtime.LaunchedEffect
5
- import androidx.compose.runtime.MutableState
6
- import androidx.compose.runtime.getValue
7
- import androidx.compose.runtime.mutableStateOf
8
- import androidx.compose.runtime.remember
3
+ import androidx.compose.runtime.*
9
4
  import org.jetbrains.compose.resources.DrawableResource
10
5
  import org.jetbrains.compose.resources.InternalResourceApi
11
6
  import org.jetbrains.compose.resources.ResourceItem
12
7
  import org.jetbrains.compose.resources.readResourceBytes
13
-
14
- @OptIn(InternalResourceApi::class)
15
- @Composable
16
- fun getResource(name: String): DrawableResource {
17
- return DrawableResource(
18
- "drawable:$name",
19
- setOf(ResourceItem(setOf(), "drawable/$name", -1, -1))
20
- )
21
- }
22
-
23
8
  @OptIn(InternalResourceApi::class)
24
9
  @Composable
25
- fun readJson(name: String): String {
10
+ internal fun readJson(name: String): String {
26
11
  val path = name.plus(".json")
27
12
  val candidatePaths = listOf(
28
13
  path,
@@ -4,7 +4,7 @@ import androidx.compose.runtime.Composable
4
4
  import vn.momo.kits.application.LocalComponentInformation
5
5
 
6
6
  @Composable
7
- fun getComponentId(
7
+ internal fun getComponentId(
8
8
  componentName: String? = null,
9
9
  accessibilityLabel: String? = null,
10
10
  ): String {
@@ -41,8 +41,8 @@ internal fun Modifier.bottomBorder(strokeWidth: Dp, color: Color) = composed(
41
41
  }
42
42
  )
43
43
 
44
- inline fun <T> Boolean.ifTrue(trueCase: T, falseCase: T): T = if (this) trueCase else falseCase
45
- inline fun <T> String.ifNotNull(trueCase: T, falseCase: T): T =
44
+ fun <T> Boolean.ifTrue(trueCase: T, falseCase: T): T = if (this) trueCase else falseCase
45
+ fun <T> String.ifNotNull(trueCase: T, falseCase: T): T =
46
46
  if (this.isBlank()) falseCase else trueCase
47
47
 
48
48
  fun formatNumberToMoney(number: Long, currency: String = "đ"): String {
@@ -91,7 +91,7 @@ fun getAppStatusBarHeight(): Dp {
91
91
  }
92
92
 
93
93
  @Composable
94
- fun getNavigationBarHeight(): Dp {
94
+ internal fun getNavigationBarHeight(): Dp {
95
95
  return if (AppNavigationBar.current == 0.dp) {
96
96
  val systemBottomPadding = WindowInsets.systemBars.asPaddingValues().calculateBottomPadding()
97
97
  if (getPlatformName() == "iOS") {
@@ -13,14 +13,13 @@ private const val STATUS_BAR_TAPPED_NOTIFICATION = "statusBarSelected"
13
13
  internal actual fun RegisterScrollToTop(callback: (() -> Unit)?) {
14
14
  val maxApi = LocalMaxApi.current
15
15
  DisposableEffect(callback) {
16
- val cb = callback
17
- val token: NSObjectProtocol? = if (cb != null) {
16
+ val token: NSObjectProtocol? = if (callback != null) {
18
17
  NSNotificationCenter.defaultCenter.addObserverForName(
19
18
  name = STATUS_BAR_TAPPED_NOTIFICATION,
20
19
  `object` = null,
21
20
  queue = NSOperationQueue.mainQueue,
22
21
  ) { _: NSNotification? ->
23
- runCatching { cb() }.onFailure {
22
+ runCatching { callback() }.onFailure {
24
23
  maxApi?.logFile("[ScrollToTop] callback threw: ${it.message}") {}
25
24
 
26
25
  }
@@ -19,8 +19,6 @@ import androidx.compose.ui.backhandler.LocalCompatNavigationEventDispatcherOwner
19
19
  import androidx.compose.ui.graphics.Color
20
20
  import androidx.compose.ui.graphics.NativePaint
21
21
  import androidx.compose.ui.graphics.toArgb
22
- import androidx.compose.ui.semantics.SemanticsPropertyKey
23
- import androidx.compose.ui.semantics.semantics
24
22
  import androidx.compose.ui.unit.Dp
25
23
  import androidx.compose.ui.unit.dp
26
24
  import androidx.compose.ui.viewinterop.UIKitInteropProperties
package/gradle.properties CHANGED
@@ -18,7 +18,7 @@ kotlin.apple.xcodeCompatibility.nowarn=true
18
18
  name="ComposeKits"
19
19
  group=vn.momo.kits
20
20
  artifact.id=kits
21
- version=0.162.4
21
+ version=0.162.5
22
22
 
23
23
  repo=GitLab
24
24
  url=https://gitlab.mservice.com.vn/api/v4/projects/5400/packages/maven
@@ -46,5 +46,6 @@ public class ApplicationEnvironment: ObservableObject {
46
46
  self.applicationContext = applicationContext
47
47
  self.composeApi = composeApi
48
48
  self.config = config
49
+ FontScaleStore.shared.bind(composeApi)
49
50
  }
50
51
  }
@@ -0,0 +1,59 @@
1
+ import SwiftUI
2
+
3
+ public struct FontScaleConfig {
4
+ public var useOSFontScale: Bool
5
+ public var userScaleRate: CGFloat?
6
+
7
+ public init(useOSFontScale: Bool = true, userScaleRate: CGFloat? = nil) {
8
+ self.useOSFontScale = useOSFontScale
9
+ self.userScaleRate = userScaleRate
10
+ }
11
+ }
12
+
13
+ public final class FontScaleStore: ObservableObject {
14
+ public static let shared = FontScaleStore()
15
+
16
+ @Published public private(set) var config = FontScaleConfig()
17
+
18
+ private var didBind = false
19
+ private var observerId: String?
20
+
21
+ private init() {}
22
+
23
+ public func update(_ newConfig: FontScaleConfig) {
24
+ if Thread.isMainThread {
25
+ config = newConfig
26
+ } else {
27
+ DispatchQueue.main.async { [weak self] in self?.config = newConfig }
28
+ }
29
+ }
30
+
31
+ public func bind(_ api: KitComposeApi?) {
32
+ guard let api = api, !didBind else { return }
33
+ didBind = true
34
+
35
+ apply(api.request(funcName: "getFontScaleConfig", params: nil))
36
+ observerId = api.request(funcName: "observer", params: ["font_scale_config"]) { [weak self] response in
37
+ self?.apply(response)
38
+ }
39
+ }
40
+
41
+ private func apply(_ response: String) {
42
+ guard let parsed = FontScaleStore.parse(response) else { return }
43
+ update(parsed)
44
+ }
45
+
46
+ static func parse(_ response: String) -> FontScaleConfig? {
47
+ guard
48
+ let data = response.data(using: .utf8),
49
+ let json = (try? JSONSerialization.jsonObject(with: data)) as? [String: Any]
50
+ else { return nil }
51
+
52
+ let obj = (json["response"] as? [String: Any]) ?? (json["data"] as? [String: Any]) ?? json
53
+ guard obj["useOSFontScale"] != nil || obj["userScaleRate"] != nil else { return nil }
54
+
55
+ let useOS = (obj["useOSFontScale"] as? Bool) ?? true
56
+ let rate = (obj["userScaleRate"] as? NSNumber).map { CGFloat($0.doubleValue) }
57
+ return FontScaleConfig(useOSFontScale: useOS, userScaleRate: rate)
58
+ }
59
+ }
@@ -1,27 +1,30 @@
1
1
  import SwiftUI
2
2
 
3
3
  public func scaleSize(_ size: CGFloat, _ scaleRate: CGFloat? = nil) -> CGFloat {
4
+ let config = FontScaleStore.shared.config
4
5
  let defaultScreenSize: CGFloat = 375
5
6
  let maxFontScale: CGFloat = scaleRate ?? 1.5
6
7
  let maxDeviceScale: CGFloat = 5
7
8
 
8
- let deviceWidth = UIScreen.main.bounds.width
9
- let deviceScale = deviceWidth / defaultScreenSize
9
+ if !config.useOSFontScale {
10
+ let customRate = config.userScaleRate ?? 1
11
+ return customRate > 1 ? size * customRate : size
12
+ }
13
+
14
+ let deviceScale = UIScreen.main.bounds.width / defaultScreenSize
10
15
 
11
16
  let defaultFont = UIFont.systemFont(ofSize: UIFont.labelFontSize)
12
17
  let scaledFont = UIFontMetrics.default.scaledFont(for: defaultFont)
13
- let fontScale = scaledFont.pointSize / defaultFont.pointSize
18
+ let osFontScale = scaledFont.pointSize / defaultFont.pointSize
14
19
 
15
20
  var fontSizeDeviceScale = size
16
21
  var fontSizeOSScale = size
17
22
 
18
-
19
23
  if deviceScale > 1 {
20
24
  fontSizeDeviceScale = min(fontSizeDeviceScale * deviceScale, fontSizeDeviceScale + maxDeviceScale)
21
25
  }
22
-
23
- if fontScale > 1 {
24
- fontSizeOSScale = min(fontSizeOSScale * fontScale, fontSizeOSScale * maxFontScale)
26
+ if osFontScale > 1 {
27
+ fontSizeOSScale = min(fontSizeOSScale * osFontScale, fontSizeOSScale * maxFontScale)
25
28
  }
26
29
 
27
30
  return max(fontSizeDeviceScale, fontSizeOSScale)
@@ -118,6 +121,7 @@ public struct MomoText: View {
118
121
  private let content: String
119
122
  private let typography: TypographyStyle
120
123
  private let color: Color
124
+ @ObservedObject private var fontScale = FontScaleStore.shared
121
125
 
122
126
  public init(
123
127
  _ content: String,
@@ -130,6 +134,7 @@ public struct MomoText: View {
130
134
  }
131
135
 
132
136
  public var body: some View {
137
+ _ = fontScale.config
133
138
  let text = SwiftUI.Text(content)
134
139
  .font(.system(size: scaleSize(typography.fontSize), weight: typography.fontWeight))
135
140
  .foregroundColor(color)
@@ -11,25 +11,30 @@ public extension View {
11
11
 
12
12
  public extension Font {
13
13
  static func appFont(size: CGFloat) -> Font {
14
+ let config = FontScaleStore.shared.config
14
15
  let defaultScreenSize: CGFloat = 375
15
16
  let maxFontScale: CGFloat = 1.5
16
17
  let maxDeviceScale: CGFloat = 5
17
-
18
- let deviceWidth = UIScreen.main.bounds.width
19
- let deviceScale = deviceWidth / defaultScreenSize
20
-
18
+
19
+ if !config.useOSFontScale {
20
+ let customRate = config.userScaleRate ?? 1
21
+ let scaled = customRate > 1 ? size * customRate : size
22
+ return Font.system(size: scaled)
23
+ }
24
+
25
+ let deviceScale = UIScreen.main.bounds.width / defaultScreenSize
26
+
21
27
  let defaultFont = UIFont.systemFont(ofSize: UIFont.labelFontSize)
22
28
  let scaledFont = UIFontMetrics.default.scaledFont(for: defaultFont)
23
- let fontScale = scaledFont.pointSize / defaultFont.pointSize
29
+ let osFontScale = scaledFont.pointSize / defaultFont.pointSize
24
30
 
25
31
  var fontSize = size
26
32
 
27
33
  if deviceScale > 1 {
28
34
  fontSize = min(fontSize * deviceScale, fontSize + maxDeviceScale)
29
35
  }
30
-
31
- if fontScale > 1 {
32
- fontSize = min(fontSize * fontScale, fontSize * maxFontScale)
36
+ if osFontScale > 1 {
37
+ fontSize = min(fontSize * osFontScale, fontSize * maxFontScale)
33
38
  }
34
39
 
35
40
  return Font.system(size: fontSize)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/native-kits",
3
- "version": "0.162.4-debug",
3
+ "version": "0.162.5-debug",
4
4
  "private": false,
5
5
  "dependencies": {},
6
6
  "devDependencies": {},
@@ -1,17 +0,0 @@
1
- package vn.momo.kits.components
2
-
3
- import androidx.compose.runtime.Composable
4
- import androidx.compose.runtime.CompositionLocalProvider
5
- import vn.momo.kits.application.ScaleSizeMaxRate
6
-
7
- @Composable
8
- fun ScaleSizeScope(
9
- scaleSizeMaxRate: Float? = null,
10
- content: @Composable () -> Unit
11
- ) {
12
- CompositionLocalProvider(
13
- ScaleSizeMaxRate provides scaleSizeMaxRate,
14
- ) {
15
- content()
16
- }
17
- }