@momo-kits/native-kits 0.162.6-debug → 0.163.1-beta.1-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 (123) hide show
  1. package/CLAUDE.md +78 -0
  2. package/compose/build.gradle.kts +8 -11
  3. package/compose/build.gradle.kts.backup +7 -10
  4. package/compose/compose.podspec +1 -1
  5. package/compose/src/commonMain/kotlin/vn/momo/kits/application/AnimationSearchInput.kt +7 -2
  6. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Context.kt +5 -12
  7. package/compose/src/commonMain/kotlin/vn/momo/kits/application/FloatingButton.kt +24 -6
  8. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Header.kt +19 -4
  9. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderAnimated.kt +10 -1
  10. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderBackground.kt +2 -2
  11. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderDefault.kt +1 -1
  12. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderExtended.kt +1 -1
  13. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderRight.kt +16 -5
  14. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderTitle.kt +1 -1
  15. package/compose/src/commonMain/kotlin/vn/momo/kits/application/LiteScreen.kt +101 -6
  16. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Localize.kt +269 -0
  17. package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +15 -4
  18. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +33 -8
  19. package/compose/src/commonMain/kotlin/vn/momo/kits/application/useHeaderSearchAnimation.kt +1 -1
  20. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Badge.kt +25 -22
  21. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeRibbon.kt +29 -27
  22. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BaselineView.kt +26 -3
  23. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +30 -27
  24. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Carousel.kt +13 -3
  25. package/compose/src/commonMain/kotlin/vn/momo/kits/components/CheckBox.kt +5 -0
  26. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Chip.kt +11 -3
  27. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Collapse.kt +18 -3
  28. package/compose/src/commonMain/kotlin/vn/momo/kits/components/CupertinoOverscroll.kt +11 -11
  29. package/compose/src/commonMain/kotlin/vn/momo/kits/components/IconButton.kt +11 -3
  30. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Information.kt +5 -1
  31. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +59 -84
  32. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputDropDown.kt +71 -13
  33. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputMoney.kt +51 -10
  34. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputOTP.kt +1 -6
  35. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputPhoneNumber.kt +21 -4
  36. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +1 -1
  37. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +75 -16
  38. package/compose/src/commonMain/kotlin/vn/momo/kits/components/LazyColumnWithBouncing.kt +26 -5
  39. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationDot.kt +1 -1
  40. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationScroll.kt +11 -3
  41. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +36 -15
  42. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupPromotion.kt +9 -3
  43. package/compose/src/commonMain/kotlin/vn/momo/kits/components/ProgressInfo.kt +28 -0
  44. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Radio.kt +13 -2
  45. package/compose/src/commonMain/kotlin/vn/momo/kits/components/ScaleSizeScope.kt +17 -0
  46. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Skeleton.kt +10 -4
  47. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Slider.kt +28 -3
  48. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Stepper.kt +47 -8
  49. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Steps.kt +25 -4
  50. package/compose/src/commonMain/kotlin/vn/momo/kits/components/SuggestAction.kt +11 -2
  51. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Swipe.kt +17 -1
  52. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Switch.kt +6 -1
  53. package/compose/src/commonMain/kotlin/vn/momo/kits/components/TabView.kt +111 -50
  54. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tag.kt +5 -1
  55. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +8 -7
  56. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Title.kt +12 -1
  57. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tooltip.kt +96 -4
  58. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Uploader.kt +12 -2
  59. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePicker.kt +21 -9
  60. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerTypes.kt +2 -2
  61. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerUtils.kt +14 -9
  62. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/WheelPicker.kt +11 -8
  63. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Theme.kt +1 -1
  64. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +40 -24
  65. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Item.kt +1 -1
  66. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/AutomationId.kt +5 -0
  67. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Clickable.kt +2 -0
  68. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/DeprecatedModifier.kt +4 -94
  69. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Shadow.kt +2 -0
  70. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ModalScreen.kt +5 -1
  71. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigation.kt +15 -5
  72. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +14 -65
  73. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigator.kt +33 -48
  74. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +55 -56
  75. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTab.kt +9 -3
  76. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +31 -13
  77. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/CurvedContainer.kt +1 -1
  78. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/FloatingButton.kt +24 -6
  79. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +6 -11
  80. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderBackground.kt +1 -2
  81. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderRight.kt +3 -6
  82. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderTitle.kt +1 -1
  83. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderUser.kt +13 -3
  84. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SnackBar.kt +2 -3
  85. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/tracking/ScreenTracker.kt +40 -1
  86. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/ComposeLottieAnimation.kt +2 -0
  87. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +8 -0
  88. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Resources.kt +17 -2
  89. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Tracking.kt +1 -1
  90. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Utils.kt +3 -3
  91. package/compose/src/iosMain/kotlin/vn/momo/kits/navigation/ScrollToTop.ios.kt +3 -2
  92. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +2 -0
  93. package/example/ios/Example.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/xcschememanagement.plist +14 -0
  94. package/example/ios/Example.xcworkspace/xcuserdata/huynhdung.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  95. package/example/ios/Example.xcworkspace/xcuserdata/huynhdung.xcuserdatad/xcschemes/xcschememanagement.plist +5 -0
  96. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/MoMoUIKits.xcscheme +58 -0
  97. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/Pods-Example.xcscheme +58 -0
  98. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/SDWebImage.xcscheme +58 -0
  99. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/SDWebImageSwiftUI.xcscheme +58 -0
  100. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/SkeletonUI.xcscheme +58 -0
  101. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/xcschememanagement.plist +46 -0
  102. package/gradle.properties +1 -1
  103. package/ios/Application/ApplicationEnvironment.swift +0 -1
  104. package/ios/Application/Components.swift +0 -1
  105. package/ios/Application/FloatingButton.swift +0 -1
  106. package/ios/Badge/Badge.swift +0 -1
  107. package/ios/Badge/BadgeRibbon.swift +0 -2
  108. package/ios/Button/Button.swift +1 -1
  109. package/ios/Checkbox/Checkbox.swift +0 -1
  110. package/ios/Input/Input.swift +0 -1
  111. package/ios/Input/InputPhoneNumber.swift +0 -1
  112. package/ios/Input/InputSearch.swift +0 -3
  113. package/ios/Input/InputTextArea.swift +0 -1
  114. package/ios/OTPKeyboard/KeyboardButton.swift +1 -1
  115. package/ios/Popup/PopupDisplay.swift +0 -6
  116. package/ios/Popup/PopupInput.swift +0 -2
  117. package/ios/Template/TrustBanner/TrustBanner.swift +0 -2
  118. package/ios/Typography/Text.swift +7 -13
  119. package/ios/Typography/Typography.swift +8 -22
  120. package/local.properties +8 -0
  121. package/package.json +1 -1
  122. package/ios/Application/FontScaleStore.swift +0 -59
  123. package/ios/Information/Information.swift +0 -151
@@ -10,7 +10,13 @@ import androidx.compose.foundation.lazy.LazyColumn
10
10
  import androidx.compose.foundation.lazy.LazyListState
11
11
  import androidx.compose.foundation.lazy.rememberLazyListState
12
12
  import androidx.compose.foundation.shape.RoundedCornerShape
13
- import androidx.compose.runtime.*
13
+ import androidx.compose.runtime.Composable
14
+ import androidx.compose.runtime.LaunchedEffect
15
+ import androidx.compose.runtime.getValue
16
+ import androidx.compose.runtime.mutableStateOf
17
+ import androidx.compose.runtime.remember
18
+ import androidx.compose.runtime.setValue
19
+ import androidx.compose.runtime.snapshotFlow
14
20
  import androidx.compose.ui.Alignment
15
21
  import androidx.compose.ui.Modifier
16
22
  import androidx.compose.ui.draw.alpha
@@ -19,7 +25,6 @@ import androidx.compose.ui.platform.LocalDensity
19
25
  import androidx.compose.ui.unit.Dp
20
26
  import androidx.compose.ui.unit.dp
21
27
  import androidx.compose.ui.zIndex
22
- import kotlinx.coroutines.FlowPreview
23
28
  import kotlinx.coroutines.delay
24
29
  import kotlinx.coroutines.flow.collect
25
30
  import kotlinx.coroutines.flow.debounce
@@ -31,14 +36,12 @@ import vn.momo.kits.const.Colors
31
36
  import vn.momo.kits.const.Radius
32
37
  import vn.momo.kits.const.Typography
33
38
  import kotlin.math.abs
34
- import kotlin.time.Duration.Companion.milliseconds
35
39
 
36
40
  private val wheelItemHeight = 42.dp
37
41
  private val wheelPickerBorderWidth = 1.dp
38
42
 
39
- @OptIn(FlowPreview::class)
40
43
  @Composable
41
- internal fun WheelPicker(
44
+ fun WheelPicker(
42
45
  name: String,
43
46
  data: List<String>,
44
47
  selectedData: String,
@@ -65,7 +68,7 @@ internal fun WheelPicker(
65
68
  LaunchedEffect(paddedData) {
66
69
  snapshotFlow { selectedIndex }
67
70
  .distinctUntilChanged()
68
- .debounce(50.milliseconds)
71
+ .debounce(50)
69
72
  .onEach {
70
73
  val value = paddedData.getOrNull(it)
71
74
  if (!value.isNullOrEmpty()) {
@@ -92,7 +95,7 @@ internal fun WheelPicker(
92
95
  } else {
93
96
  -abs(firstItemOffset)
94
97
  }
95
- delay(50.milliseconds)
98
+ delay(50)
96
99
  listState.animateScrollBy(offset.toFloat())
97
100
  val centeredIndex = firstItemIdx + (if (isScrollUp) 1 else 0) + 2
98
101
  if (centeredIndex in 2 until paddedData.size - 2) {
@@ -142,7 +145,7 @@ internal fun WheelPicker(
142
145
  }
143
146
 
144
147
  @Composable
145
- internal fun WheelPickerItem(
148
+ fun WheelPickerItem(
146
149
  text: String,
147
150
  isSelected: Boolean,
148
151
  index: Int,
@@ -64,7 +64,7 @@ data class Theme(
64
64
  val assets: ThemeAssets
65
65
  ) {
66
66
  fun isHeaderImage(): Boolean {
67
- return !assets.headerBackground.isNullOrEmpty()
67
+ return assets.headerBackground != null && assets.headerBackground.isNotEmpty()
68
68
  }
69
69
  }
70
70
  val defaultTheme = Theme(
@@ -7,13 +7,28 @@ import androidx.compose.ui.text.TextStyle
7
7
  import androidx.compose.ui.text.font.FontFamily
8
8
  import androidx.compose.ui.text.font.FontWeight
9
9
  import androidx.compose.ui.text.style.TextDecoration
10
- import androidx.compose.ui.unit.*
10
+ import androidx.compose.ui.unit.Dp
11
+ import androidx.compose.ui.unit.TextUnit
12
+ import androidx.compose.ui.unit.TextUnitType
13
+ import androidx.compose.ui.unit.dp
14
+ import androidx.compose.ui.unit.sp
11
15
  import org.jetbrains.compose.resources.Font
12
16
  import org.jetbrains.compose.resources.FontResource
13
17
  import org.jetbrains.compose.resources.InternalResourceApi
14
- import vn.momo.kits.application.LocalFontScaleConfig
18
+ import vn.momo.kits.application.ScaleSizeMaxRate
15
19
  import vn.momo.kits.platform.getScreenDimensions
16
- import vn.momo.uikits.resources.*
20
+ import vn.momo.uikits.resources.Res
21
+ import vn.momo.uikits.resources.momosignature
22
+ import vn.momo.uikits.resources.momotrustdisplay
23
+ import vn.momo.uikits.resources.sfprotext_black
24
+ import vn.momo.uikits.resources.sfprotext_bold
25
+ import vn.momo.uikits.resources.sfprotext_heavy
26
+ import vn.momo.uikits.resources.sfprotext_light
27
+ import vn.momo.uikits.resources.sfprotext_medium
28
+ import vn.momo.uikits.resources.sfprotext_regular
29
+ import vn.momo.uikits.resources.sfprotext_semibold
30
+ import vn.momo.uikits.resources.sfprotext_thin
31
+ import vn.momo.uikits.resources.sfprotext_ultralight
17
32
  import kotlin.math.max
18
33
  import kotlin.math.min
19
34
 
@@ -22,58 +37,59 @@ const val MAX_FONT_SCALE = 1.5f
22
37
  const val MAX_DEVICE_SCALE = 5
23
38
 
24
39
  @Composable
25
- fun scaleSize(size: Float, userScaleRate: Float? = null): Float {
26
- val fontScaleConfig = LocalFontScaleConfig.current
27
- val useOSFontScale = fontScaleConfig.useOSFontScale
28
- val customRate = userScaleRate ?: fontScaleConfig.userScaleRate ?: 1f
40
+ fun scaleSize(size: Float): Float {
41
+ val scaleSizeMaxRate: Float = ScaleSizeMaxRate.current ?: MAX_FONT_SCALE
42
+ val deviceWidth = getScreenDimensions().width
43
+ val deviceScale = deviceWidth / DEFAULT_SCREEN_SIZE
29
44
 
30
- val deviceScale = getScreenDimensions().width / DEFAULT_SCREEN_SIZE
31
- val fontScale = fontScaleConfig.osFontScale ?: LocalDensity.current.fontScale
32
-
33
- if (!useOSFontScale) {
34
- return if (customRate > 1f) customRate * size else size
35
- }
45
+ val density = LocalDensity.current
46
+ val fontScale = density.fontScale
36
47
 
37
48
  var fontSizeScaleDevice = size
38
49
  var fontSizeScaleOS = size
50
+
39
51
  if (deviceScale > 1) {
40
52
  fontSizeScaleDevice =
41
53
  min(deviceScale * fontSizeScaleDevice, fontSizeScaleDevice + MAX_DEVICE_SCALE)
42
54
  }
43
- if (fontScale > 1f) {
44
- fontSizeScaleOS = min(fontScale * fontSizeScaleOS, fontSizeScaleOS * MAX_FONT_SCALE)
55
+
56
+ if (fontScale > 1) {
57
+ fontSizeScaleOS = min(fontScale * fontSizeScaleOS, fontSizeScaleOS * scaleSizeMaxRate)
45
58
  }
46
59
 
47
- return max(fontSizeScaleDevice, fontSizeScaleOS)
60
+ return max(
61
+ fontSizeScaleDevice,
62
+ fontSizeScaleOS
63
+ )
48
64
  }
49
65
 
50
66
  @Composable
51
- fun scaleSize(size: TextUnit, userScaleRate: Float? = null): TextUnit {
67
+ fun scaleSize(size: TextUnit): TextUnit {
52
68
  if (!size.isSp) return size
53
69
 
54
70
  val density = LocalDensity.current
55
71
 
56
- val scaled = scaleSize(size.value, userScaleRate)
72
+ val scaled = scaleSize(size.value)
57
73
  val spValue = scaled / density.fontScale
58
74
 
59
75
  return TextUnit(value = spValue, type = TextUnitType.Sp)
60
76
  }
61
77
 
62
78
  @Composable
63
- fun scaleSize(size: Dp, userScaleRate: Float? = null): Dp {
64
- return scaleSize(size.value, userScaleRate).dp
79
+ fun scaleSize(size: Dp): Dp {
80
+ return scaleSize(size.value).dp
65
81
  }
66
82
 
67
83
  @Composable
68
- fun scaleSize(textStyle: TextStyle, userScaleRate: Float? = null): TextStyle {
84
+ fun scaleSize(textStyle: TextStyle): TextStyle {
69
85
  return textStyle.copy(
70
86
  fontSize = if (textStyle.fontSize != TextUnit.Unspecified)
71
- scaleSize(textStyle.fontSize, userScaleRate)
87
+ scaleSize(textStyle.fontSize)
72
88
  else
73
89
  TextUnit.Unspecified,
74
90
 
75
91
  lineHeight = if (textStyle.lineHeight != TextUnit.Unspecified)
76
- scaleSize(textStyle.lineHeight, userScaleRate)
92
+ scaleSize(textStyle.lineHeight)
77
93
  else
78
94
  TextUnit.Unspecified,
79
95
  )
@@ -82,7 +98,7 @@ fun scaleSize(textStyle: TextStyle, userScaleRate: Float? = null): TextStyle {
82
98
 
83
99
  @OptIn(InternalResourceApi::class)
84
100
  @Composable
85
- internal fun getFont(font: FontResource): FontFamily {
101
+ fun getFont(font: FontResource): FontFamily {
86
102
  return FontFamily(Font(font))
87
103
  }
88
104
 
@@ -18,7 +18,7 @@ data class GridContext(
18
18
  fun Item(
19
19
  heightSpan: Number = 1,
20
20
  widthSpan: Number = 1,
21
- content: @Composable () -> Unit,
21
+ content: @Composable() () -> Unit,
22
22
  modifier: Modifier = Modifier,
23
23
  grid: GridContext
24
24
  ) {
@@ -20,6 +20,11 @@ fun Modifier.setAutomationId(accessibilityId: String, mergeDescendants: Boolean
20
20
  }
21
21
  }}
22
22
 
23
+ /**
24
+ * Alternative for [setAutomationId]
25
+ *
26
+ * reason: [link](https://developer.android.com/develop/ui/compose/custom-modifiers#composable_function_modifiers_are_never_skipped)
27
+ * */
23
28
  fun Modifier.kitsAutomationId(accessibilityId: String, label: String? = null) =
24
29
  this then KitsAutomationIdElement(accessibilityId, label)
25
30
 
@@ -53,6 +53,8 @@ fun Modifier.activeOpacityClickable(
53
53
  onClick
54
54
  )
55
55
  }
56
+
57
+
56
58
  fun Modifier.hideKeyboardOnTap() = composed {
57
59
  val focusManager = LocalFocusManager.current
58
60
  val keyboardManager = LocalSoftwareKeyboardController.current
@@ -1,104 +1,14 @@
1
1
  package vn.momo.kits.modifier
2
2
 
3
- import androidx.compose.animation.core.LinearEasing
4
- import androidx.compose.animation.core.RepeatMode
5
- import androidx.compose.animation.core.animateFloat
6
- import androidx.compose.animation.core.infiniteRepeatable
7
- import androidx.compose.animation.core.rememberInfiniteTransition
8
- import androidx.compose.animation.core.tween
3
+ import androidx.compose.foundation.background
9
4
  import androidx.compose.runtime.Composable
10
- import androidx.compose.runtime.getValue
11
5
  import androidx.compose.ui.Modifier
12
- import androidx.compose.ui.draw.drawWithContent
13
- import androidx.compose.ui.geometry.Offset
14
- import androidx.compose.ui.graphics.Color
15
- import androidx.compose.ui.graphics.drawscope.clipRect
16
- import androidx.compose.ui.text.TextStyle
17
- import androidx.compose.ui.text.drawText
18
- import androidx.compose.ui.text.font.FontWeight
19
- import androidx.compose.ui.text.rememberTextMeasurer
20
- import androidx.compose.ui.unit.sp
21
6
  import vn.momo.kits.application.IsShowBaseLineDebug
22
7
  import vn.momo.kits.const.Colors
23
8
 
24
- @Suppress("ExperimentalAnnotationRetention")
25
- @RequiresOptIn(
26
- message = "This is internal API of native-kits, become internal in next sprint",
27
- level = RequiresOptIn.Level.WARNING,
28
- )
29
- @Retention(AnnotationRetention.BINARY)
30
- @Target(
31
- AnnotationTarget.CLASS,
32
- AnnotationTarget.FUNCTION,
33
- AnnotationTarget.PROPERTY,
34
- )
35
- annotation class InternalApi
36
-
37
- @Composable
38
- fun DeprecatedModifier(text: String = "Deprecated component"): Modifier = debugMarker(
39
- label = text,
40
- background = Colors.red_04.copy(alpha = 0.7f),
41
- textColor = Colors.red_01,
42
- animationLabel = "deprecatedMarquee",
43
- )
44
-
45
9
  @Composable
46
- private fun debugMarker(
47
- label: String,
48
- background: Color,
49
- textColor: Color,
50
- animationLabel: String,
51
- ): Modifier {
52
- if (!IsShowBaseLineDebug) return Modifier
53
-
54
- val textMeasurer = rememberTextMeasurer()
55
- val marquee = rememberInfiniteTransition(label = animationLabel)
56
- val progress by marquee.animateFloat(
57
- initialValue = 0f,
58
- targetValue = 1f,
59
- animationSpec = infiniteRepeatable(
60
- animation = tween(durationMillis = 4000, easing = LinearEasing),
61
- repeatMode = RepeatMode.Restart,
62
- ),
63
- label = "${animationLabel}Progress",
64
- )
65
-
66
- return Modifier.drawWithContent {
67
- drawContent()
68
- drawRect(color = background)
69
-
70
- if (size.width <= 0f || size.height <= 0f) return@drawWithContent
71
-
72
- val fontPx = (size.width * 0.1f).coerceIn(12.sp.toPx(), 20.sp.toPx())
73
- val style = TextStyle(
74
- color = textColor,
75
- fontSize = fontPx.toSp(),
76
- fontWeight = FontWeight.Bold,
77
- )
78
-
79
- val intrinsic = textMeasurer.measure(
80
- text = label,
81
- style = style,
82
- maxLines = 1,
83
- softWrap = false,
84
- )
85
- val textW = intrinsic.size.width
86
- val textH = intrinsic.size.height
87
- val y = (size.height - textH) / 2f
88
-
89
- if (textW <= size.width) {
90
- drawText(
91
- textLayoutResult = intrinsic,
92
- topLeft = Offset((size.width - textW) / 2f, y),
93
- )
94
- } else {
95
- clipRect(right = size.width, bottom = size.height) {
96
- val gap = textW * 0.5f
97
- val travel = textW + gap
98
- val x = -progress * travel
99
- drawText(textLayoutResult = intrinsic, topLeft = Offset(x, y))
100
- drawText(textLayoutResult = intrinsic, topLeft = Offset(x + travel, y))
101
- }
102
- }
10
+ fun DeprecatedModifier(): Modifier {
11
+ return Modifier.conditional(IsShowBaseLineDebug) {
12
+ background(Colors.red_01.copy(alpha = 0.5f))
103
13
  }
104
14
  }
@@ -9,6 +9,8 @@ import androidx.compose.ui.unit.Dp
9
9
  import androidx.compose.ui.unit.dp
10
10
  import vn.momo.kits.platform.setColor
11
11
  import vn.momo.kits.platform.setMaskFilter
12
+
13
+
12
14
  fun Modifier.shadow(
13
15
  color: Color = Color.Black,
14
16
  borderRadius: Dp = 0.dp,
@@ -10,7 +10,11 @@ import androidx.compose.foundation.interaction.MutableInteractionSource
10
10
  import androidx.compose.foundation.layout.Box
11
11
  import androidx.compose.foundation.layout.fillMaxSize
12
12
  import androidx.compose.foundation.layout.wrapContentSize
13
- import androidx.compose.runtime.*
13
+ import androidx.compose.runtime.Composable
14
+ import androidx.compose.runtime.DisposableEffect
15
+ import androidx.compose.runtime.LaunchedEffect
16
+ import androidx.compose.runtime.remember
17
+ import androidx.compose.runtime.rememberCoroutineScope
14
18
  import androidx.compose.ui.Alignment
15
19
  import androidx.compose.ui.Modifier
16
20
  import androidx.compose.ui.draw.alpha
@@ -1,16 +1,24 @@
1
1
  package vn.momo.kits.navigation
2
2
 
3
3
  import androidx.compose.foundation.gestures.ScrollableState
4
- import androidx.compose.runtime.*
4
+ import androidx.compose.runtime.Composable
5
+ import androidx.compose.runtime.Stable
6
+ import androidx.compose.runtime.State
7
+ import androidx.compose.runtime.mutableStateOf
8
+ import androidx.compose.runtime.staticCompositionLocalOf
5
9
  import androidx.compose.ui.graphics.Color
6
10
  import vn.momo.kits.navigation.bottomtab.setBottomTabOption
7
- import vn.momo.kits.navigation.component.*
11
+ import vn.momo.kits.navigation.component.FloatingButtonProps
12
+ import vn.momo.kits.navigation.component.HeaderBackProps
13
+ import vn.momo.kits.navigation.component.HeaderRight
14
+ import vn.momo.kits.navigation.component.HeaderTitle
15
+ import vn.momo.kits.navigation.component.HeaderType
16
+ import vn.momo.kits.navigation.component.TitlePosition
8
17
 
9
18
  class Navigation(
10
19
  val id: Int = -1,
11
20
  val bottomTabIndex: Int = -1,
12
- val initOptions: NavigationOptions? = null,
13
- private val registry: DynamicScreenRegistry? = null
21
+ val initOptions: NavigationOptions? = null
14
22
  ) {
15
23
  private val _options = mutableStateOf(initOptions ?: NavigationOptions())
16
24
  val currentOptions: State<NavigationOptions> get() = _options
@@ -57,7 +65,7 @@ class Navigation(
57
65
  private fun updateOptions(updated: NavigationOptions) {
58
66
  _options.value = updated
59
67
  if (bottomTabIndex != -1) setBottomTabOption(bottomTabIndex, updated)
60
- if (id != -1) registry?.setOptions(id, updated)
68
+ if (id != -1) DynamicScreenRegistry.setOptions(id, updated)
61
69
  }
62
70
  }
63
71
 
@@ -87,6 +95,8 @@ data class KeyboardOptions(
87
95
  val keyboardShouldPersistTaps: Boolean = false,
88
96
  val useAvoidKeyboard: Boolean = true
89
97
  )
98
+
99
+
90
100
  data class ScrollData(
91
101
  val scrollable: Boolean = true,
92
102
  val scrollState: ScrollableState? = null,
@@ -9,7 +9,6 @@ import androidx.navigation.compose.NavHost
9
9
  import androidx.navigation.compose.composable
10
10
  import androidx.navigation.compose.rememberNavController
11
11
  import androidx.navigation.toRoute
12
- import kotlinx.coroutines.flow.collect
13
12
  import vn.momo.kits.application.*
14
13
  import vn.momo.kits.const.*
15
14
  import vn.momo.kits.platform.ProvideNavigationEventDispatcherOwner
@@ -23,61 +22,39 @@ fun NavigationContainer(
23
22
  initialScreen: @Composable () -> Unit,
24
23
  options: NavigationOptions? = null,
25
24
  initialTheme: Theme = defaultTheme,
26
- applicationContext: MiniAppContext? = null,
27
- maxApi: IMaxApi? = null,
25
+ miniappContext: MiniAppContext? = null,
26
+ maxApi: IMaxApi?,
28
27
  setNavigator: ((Navigator) -> Unit)? = null,
29
28
  statusBarHeight: Dp? = null,
30
- config: KitConfig? = null,
31
- language: String? = null
29
+ localize: Localize? = null,
32
30
  ){
33
31
  val navController = rememberNavController()
34
- val registry = remember { DynamicScreenRegistry() }
35
- val navigator = remember { Navigator(navController = navController, maxApi = maxApi, registry = registry) }
32
+ val navigator = remember { Navigator(navController = navController, maxApi = maxApi) }
36
33
  val statusBarHeight = statusBarHeight ?: getAppStatusBarHeight()
37
34
  val navigationBarHeight = getNavigationBarHeight()
38
35
 
39
36
  val parentContext = ApplicationContext.current
40
- val mergedContext = MiniAppContext.merge(parentContext, applicationContext)
41
-
42
- var observerFontScaleConfig by remember { mutableStateOf(mergedContext?.fontScaleConfig) }
43
- LaunchedEffect(maxApi) {
44
- val api = maxApi ?: return@LaunchedEffect
45
- runCatching {
46
- api.observer(FONT_SCALE_OBSERVER_KEY).collect { data ->
47
- observerFontScaleConfig = parseFontScaleConfig(data)
48
- }
49
- }
50
- }
37
+ val mergedContext = MiniAppContext.merge(parentContext, miniappContext)
51
38
 
52
39
  val theme = remember { mutableStateOf(initialTheme) }
53
40
 
54
- LaunchedEffect(Unit) {
55
- val headerBar = config?.headerBar
56
- if (headerBar != null && theme.value.assets.headerBackground == null) {
57
- theme.value = theme.value.copy(
58
- assets = ThemeAssets(
59
- headerBackground = headerBar
60
- )
61
- )
62
- }
63
- }
41
+ val fallbackLocalize = remember { Localize() }
42
+ val resolvedLocalize = localize ?: fallbackLocalize
64
43
 
65
- val screenId = rememberSaveable { registry.nextId() }
66
- registry.bind(screenId, initialScreenName, initialScreen, options)
44
+ val screenId = rememberSaveable { DynamicScreenRegistry.nextId() }
45
+ DynamicScreenRegistry.bind(screenId, initialScreenName, initialScreen, options)
67
46
  val startDestination = remember(screenId) { DynamicScreenRoute(screenId) }
68
47
 
69
48
  ProvideNavigationEventDispatcherOwner {
70
49
  CompositionLocalProvider(
71
50
  LocalNavigator provides navigator,
72
- LocalDynamicScreenRegistry provides registry,
73
51
  LocalMaxApi provides maxApi,
74
52
  AppTheme provides theme.value,
75
53
  AppStatusBar provides statusBarHeight,
76
54
  AppNavigationBar provides navigationBarHeight,
77
55
  ApplicationContext provides mergedContext,
78
- AppConfig provides config,
79
- AppLanguage provides language,
80
- LocalFontScaleConfig provides (observerFontScaleConfig ?: LocalFontScaleConfig.current),
56
+ AppLanguage provides resolvedLocalize.currentLanguage,
57
+ LocalLocalize provides resolvedLocalize,
81
58
  ) {
82
59
  LaunchedEffect(Unit) {
83
60
  setNavigator?.invoke(navigator)
@@ -101,7 +78,7 @@ fun NavigationContainer(
101
78
  }
102
79
  ) { backStackEntry ->
103
80
  val route = backStackEntry.toRoute<DynamicScreenRoute>()
104
- val screen = registry.getScreen(route.id)
81
+ val screen = DynamicScreenRegistry.getScreen(route.id)
105
82
 
106
83
  if (screen != null) {
107
84
  StackScreen(
@@ -130,7 +107,7 @@ fun NavigationContainer(
130
107
  }
131
108
  ) { backStackEntry ->
132
109
  val route = backStackEntry.toRoute<DynamicDialogRoute>()
133
- val screen = registry.getScreen(route.id)
110
+ val screen = DynamicScreenRegistry.getScreen(route.id)
134
111
 
135
112
  if (screen != null) {
136
113
  StackScreen(
@@ -148,7 +125,7 @@ fun NavigationContainer(
148
125
  DisposableEffect(Unit) {
149
126
  onDispose {
150
127
  navigator.dispose()
151
- registry.unregisterScreen(screenId)
128
+ DynamicScreenRegistry.unregisterScreen(screenId)
152
129
  }
153
130
  }
154
131
  }
@@ -156,31 +133,3 @@ fun NavigationContainer(
156
133
  val LocalMaxApi = staticCompositionLocalOf<IMaxApi?> {
157
134
  error("No MaxApi provided")
158
135
  }
159
-
160
- private const val FONT_SCALE_OBSERVER_KEY = "font_scale_config"
161
-
162
- private fun parseFontScaleConfig(raw: Map<String, Any?>?): FontScaleConfig? {
163
- if (raw.isNullOrEmpty()) return null
164
- @Suppress("UNCHECKED_CAST")
165
- val data = (raw["response"] as? Map<String, Any?>)
166
- ?: (raw["data"] as? Map<String, Any?>)
167
- ?: raw
168
- if (!data.containsKey("useOSFontScale") && !data.containsKey("userScaleRate")) return null
169
- val useOS = when (val v = data["useOSFontScale"]) {
170
- is Boolean -> v
171
- is String -> v.equals("true", ignoreCase = true)
172
- is Number -> v.toInt() != 0
173
- else -> true
174
- }
175
- val rate = when (val v = data["userScaleRate"]) {
176
- is Number -> v.toFloat()
177
- is String -> v.toFloatOrNull()
178
- else -> null
179
- }
180
- val osScale = when (val v = data["osFontScale"]) {
181
- is Number -> v.toFloat()
182
- is String -> v.toFloatOrNull()
183
- else -> null
184
- }
185
- return FontScaleConfig(useOSFontScale = useOS, userScaleRate = rate, osFontScale = osScale)
186
- }