@momo-kits/native-kits 0.162.0-debug → 0.162.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 (104) hide show
  1. package/.claude/settings.local.json +32 -0
  2. package/compose/build.gradle.kts +66 -63
  3. package/compose/build.gradle.kts.backup +66 -63
  4. package/compose/compose.podspec +1 -1
  5. package/compose/src/commonMain/kotlin/vn/momo/kits/application/AnimationSearchInput.kt +2 -7
  6. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Context.kt +1 -1
  7. package/compose/src/commonMain/kotlin/vn/momo/kits/application/FloatingButton.kt +6 -24
  8. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Header.kt +4 -19
  9. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderAnimated.kt +1 -10
  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 +5 -16
  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 +6 -101
  16. package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +4 -16
  17. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +9 -34
  18. package/compose/src/commonMain/kotlin/vn/momo/kits/application/useHeaderSearchAnimation.kt +1 -1
  19. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Badge.kt +1 -6
  20. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeRibbon.kt +27 -29
  21. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BaselineView.kt +3 -26
  22. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +27 -30
  23. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Carousel.kt +3 -13
  24. package/compose/src/commonMain/kotlin/vn/momo/kits/components/CheckBox.kt +0 -5
  25. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Chip.kt +3 -11
  26. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Collapse.kt +3 -18
  27. package/compose/src/commonMain/kotlin/vn/momo/kits/components/CupertinoOverscroll.kt +11 -11
  28. package/compose/src/commonMain/kotlin/vn/momo/kits/components/IconButton.kt +3 -11
  29. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Information.kt +1 -5
  30. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +84 -59
  31. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputDropDown.kt +13 -71
  32. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputMoney.kt +10 -51
  33. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputOTP.kt +6 -1
  34. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputPhoneNumber.kt +4 -21
  35. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +1 -1
  36. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +15 -76
  37. package/compose/src/commonMain/kotlin/vn/momo/kits/components/LazyColumnWithBouncing.kt +5 -26
  38. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationDot.kt +1 -1
  39. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationScroll.kt +3 -11
  40. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +15 -36
  41. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupPromotion.kt +3 -9
  42. package/compose/src/commonMain/kotlin/vn/momo/kits/components/ProgressInfo.kt +0 -28
  43. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Radio.kt +2 -13
  44. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Skeleton.kt +4 -10
  45. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Slider.kt +3 -28
  46. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Stepper.kt +8 -47
  47. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Steps.kt +4 -25
  48. package/compose/src/commonMain/kotlin/vn/momo/kits/components/SuggestAction.kt +2 -11
  49. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Swipe.kt +1 -17
  50. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Switch.kt +1 -6
  51. package/compose/src/commonMain/kotlin/vn/momo/kits/components/TabView.kt +50 -111
  52. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tag.kt +1 -5
  53. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +1 -5
  54. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Title.kt +1 -12
  55. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tooltip.kt +4 -96
  56. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Uploader.kt +2 -12
  57. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePicker.kt +9 -21
  58. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerTypes.kt +2 -2
  59. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerUtils.kt +9 -14
  60. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/WheelPicker.kt +8 -11
  61. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Theme.kt +1 -1
  62. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +3 -18
  63. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Item.kt +1 -1
  64. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/AutomationId.kt +0 -5
  65. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Clickable.kt +0 -2
  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 -12
  69. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigator.kt +6 -5
  70. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +55 -55
  71. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTab.kt +3 -9
  72. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +12 -32
  73. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/CurvedContainer.kt +1 -1
  74. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/FloatingButton.kt +6 -24
  75. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +55 -15
  76. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderBackground.kt +2 -1
  77. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderRight.kt +6 -3
  78. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderTitle.kt +5 -3
  79. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderUser.kt +3 -13
  80. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SnackBar.kt +3 -2
  81. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/tracking/ScreenTracker.kt +1 -40
  82. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/ComposeLottieAnimation.kt +0 -2
  83. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +0 -8
  84. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Deprecated.kt +107 -0
  85. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Resources.kt +3 -8
  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/local.properties +2 -2
  92. package/package.json +1 -1
  93. package/publish.sh +2 -2
  94. package/compose/src/commonMain/kotlin/vn/momo/kits/components/ScaleSizeScope.kt +0 -17
  95. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/DeprecatedModifier.kt +0 -14
  96. package/example/ios/Example.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
  97. package/example/ios/Example.xcworkspace/xcuserdata/huynhdung.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  98. package/example/ios/Example.xcworkspace/xcuserdata/huynhdung.xcuserdatad/xcschemes/xcschememanagement.plist +0 -5
  99. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/MoMoUIKits.xcscheme +0 -58
  100. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/Pods-Example.xcscheme +0 -58
  101. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/SDWebImage.xcscheme +0 -58
  102. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/SDWebImageSwiftUI.xcscheme +0 -58
  103. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/SkeletonUI.xcscheme +0 -58
  104. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/xcschememanagement.plist +0 -46
@@ -8,13 +8,7 @@ import androidx.compose.foundation.layout.PaddingValues
8
8
  import androidx.compose.foundation.layout.fillMaxWidth
9
9
  import androidx.compose.foundation.pager.HorizontalPager
10
10
  import androidx.compose.foundation.pager.rememberPagerState
11
- import androidx.compose.runtime.Composable
12
- import androidx.compose.runtime.LaunchedEffect
13
- import androidx.compose.runtime.getValue
14
- import androidx.compose.runtime.mutableStateOf
15
- import androidx.compose.runtime.remember
16
- import androidx.compose.runtime.setValue
17
- import androidx.compose.runtime.snapshotFlow
11
+ import androidx.compose.runtime.*
18
12
  import androidx.compose.ui.Modifier
19
13
  import androidx.compose.ui.graphics.graphicsLayer
20
14
  import androidx.compose.ui.unit.dp
@@ -24,6 +18,7 @@ import vn.momo.kits.application.IsShowBaseLineDebug
24
18
  import vn.momo.kits.const.Colors
25
19
  import vn.momo.kits.modifier.conditional
26
20
  import kotlin.math.absoluteValue
21
+ import kotlin.time.Duration.Companion.milliseconds
27
22
 
28
23
  @Composable
29
24
  fun Carousel(
@@ -32,7 +27,6 @@ fun Carousel(
32
27
  loop: Boolean = false,
33
28
  autoplay: Boolean = false,
34
29
  autoplayInterval: Long = 3000L,
35
- enableSnap: Boolean = true,
36
30
  scrollEnabled: Boolean = true,
37
31
  inactiveSlideOpacity: Float = 1f,
38
32
  inactiveSlideScale: Float = 1f,
@@ -48,18 +42,15 @@ fun Carousel(
48
42
 
49
43
  val pagerState = rememberPagerState(initialPage = startPage) { virtualPageCount }
50
44
 
51
- // Map virtual page to real index
52
45
  val realIndex: (Int) -> Int = { page -> page % itemCount }
53
46
 
54
- // Track user interaction for autoplay pause
55
47
  var isUserScrolling by remember { mutableStateOf(false) }
56
48
 
57
- // Autoplay
58
49
  if (autoplay && itemCount > 1) {
59
50
  LaunchedEffect(autoplayInterval, isUserScrolling) {
60
51
  if (isUserScrolling) return@LaunchedEffect
61
52
  while (isActive) {
62
- delay(autoplayInterval)
53
+ delay(autoplayInterval.milliseconds)
63
54
  if (!isUserScrolling) {
64
55
  val nextPage = pagerState.currentPage + 1
65
56
  if (nextPage < virtualPageCount) {
@@ -70,7 +61,6 @@ fun Carousel(
70
61
  }
71
62
  }
72
63
 
73
- // Track scroll state for callbacks
74
64
  LaunchedEffect(pagerState) {
75
65
  snapshotFlow { pagerState.isScrollInProgress }.collect { scrolling ->
76
66
  isUserScrolling = scrolling
@@ -22,7 +22,6 @@ import vn.momo.kits.const.Typography
22
22
  import vn.momo.kits.modifier.activeOpacityClickable
23
23
  import vn.momo.kits.modifier.conditional
24
24
 
25
- // Pre-computed shape for performance
26
25
  private val checkboxShape = RoundedCornerShape(Radius.XS)
27
26
 
28
27
  @Composable
@@ -33,10 +32,8 @@ fun CheckBox(
33
32
  indeterminate: Boolean = false,
34
33
  title: String = "",
35
34
  ) {
36
- // Cache theme access
37
35
  val theme = AppTheme.current
38
36
 
39
- // Memoize color calculations to avoid repeated conditional logic
40
37
  val colors = remember(checked, disabled, theme) {
41
38
  when {
42
39
  disabled && checked -> Pair(theme.colors.background.tonal, theme.colors.background.tonal)
@@ -48,12 +45,10 @@ fun CheckBox(
48
45
 
49
46
  val (borderColor, backgroundColor) = colors
50
47
 
51
- // Memoize icon source to avoid repeated conditional check
52
48
  val iconSource = remember(indeterminate) {
53
49
  if (indeterminate) "navigation_minus" else "ic_checked"
54
50
  }
55
51
 
56
- // Memoize click handler to avoid lambda recreation
57
52
  val onClickHandler = remember(onCheckedChange, checked) {
58
53
  { onCheckedChange(!checked) }
59
54
  }
@@ -2,11 +2,7 @@ package vn.momo.kits.components
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.Row
7
- import androidx.compose.foundation.layout.height
8
- import androidx.compose.foundation.layout.padding
9
- import androidx.compose.foundation.layout.wrapContentWidth
5
+ import androidx.compose.foundation.layout.*
10
6
  import androidx.compose.foundation.shape.RoundedCornerShape
11
7
  import androidx.compose.runtime.Composable
12
8
  import androidx.compose.runtime.Immutable
@@ -17,12 +13,8 @@ import androidx.compose.ui.graphics.Color
17
13
  import androidx.compose.ui.text.style.TextAlign
18
14
  import androidx.compose.ui.text.style.TextOverflow
19
15
  import androidx.compose.ui.unit.dp
20
- import vn.momo.kits.const.AppTheme
21
- import vn.momo.kits.const.Colors
22
- import vn.momo.kits.const.Radius
23
- import vn.momo.kits.const.Typography
24
16
  import vn.momo.kits.application.IsShowBaseLineDebug
25
- import vn.momo.kits.const.scaleSize
17
+ import vn.momo.kits.const.*
26
18
  import vn.momo.kits.modifier.activeOpacityClickable
27
19
  import vn.momo.kits.modifier.conditional
28
20
  import vn.momo.kits.modifier.setAutomationId
@@ -111,7 +103,7 @@ fun Chip(
111
103
 
112
104
  enum class ChipSize { SMALL, LARGE }
113
105
 
114
- object ChipDefaults {
106
+ private object ChipDefaults {
115
107
  @Immutable
116
108
  data class Dimensions(
117
109
  val height: Float,
@@ -7,20 +7,9 @@ import androidx.compose.animation.expandVertically
7
7
  import androidx.compose.animation.shrinkVertically
8
8
  import androidx.compose.foundation.background
9
9
  import androidx.compose.foundation.border
10
- import androidx.compose.foundation.layout.Box
11
- import androidx.compose.foundation.layout.Column
12
- import androidx.compose.foundation.layout.Row
13
- import androidx.compose.foundation.layout.Spacer
14
- import androidx.compose.foundation.layout.fillMaxWidth
15
- import androidx.compose.foundation.layout.padding
16
- import androidx.compose.foundation.layout.size
17
- import androidx.compose.foundation.layout.width
10
+ import androidx.compose.foundation.layout.*
18
11
  import androidx.compose.foundation.shape.RoundedCornerShape
19
- import androidx.compose.runtime.Composable
20
- import androidx.compose.runtime.getValue
21
- import androidx.compose.runtime.mutableStateOf
22
- import androidx.compose.runtime.remember
23
- import androidx.compose.runtime.setValue
12
+ import androidx.compose.runtime.*
24
13
  import androidx.compose.ui.Alignment
25
14
  import androidx.compose.ui.Modifier
26
15
  import androidx.compose.ui.draw.clip
@@ -29,11 +18,7 @@ import androidx.compose.ui.graphics.Color
29
18
  import androidx.compose.ui.text.TextStyle
30
19
  import androidx.compose.ui.unit.dp
31
20
  import vn.momo.kits.application.IsShowBaseLineDebug
32
- import vn.momo.kits.const.AppTheme
33
- import vn.momo.kits.const.Colors
34
- import vn.momo.kits.const.Radius
35
- import vn.momo.kits.const.Spacing
36
- import vn.momo.kits.const.Typography
21
+ import vn.momo.kits.const.*
37
22
  import vn.momo.kits.modifier.activeOpacityClickable
38
23
  import vn.momo.kits.modifier.conditional
39
24
  import vn.momo.kits.modifier.setAutomationId
@@ -42,8 +42,8 @@ import androidx.compose.ui.unit.toOffset
42
42
  import androidx.compose.ui.unit.toSize
43
43
  import kotlinx.coroutines.CoroutineScope
44
44
  import kotlinx.coroutines.cancel
45
+ import kotlinx.coroutines.currentCoroutineContext
45
46
  import kotlinx.coroutines.isActive
46
- import kotlin.coroutines.coroutineContext
47
47
  import kotlin.math.abs
48
48
  import kotlin.math.sign
49
49
 
@@ -103,7 +103,7 @@ internal class CupertinoOverscrollEffect(
103
103
  * end at the same time, which is not the case:
104
104
  * Spring->Fling->Spring, Fling->Spring, Spring->Fling effects can have different timing per dimension
105
105
  * (see Notes of https://github.com/JetBrains/compose-multiplatform-core/pull/609),
106
- * which is not possible to express without changing API. Hence this effect will be fixed to latest
106
+ * which is not possible to express without changing API. Hence, this effect will be fixed to latest
107
107
  * received delta.
108
108
  */
109
109
  private var direction: CupertinoOverscrollDirection = CupertinoOverscrollDirection.UNKNOWN
@@ -151,7 +151,7 @@ internal class CupertinoOverscrollEffect(
151
151
  override val node: DelegatableNode get() = overscrollNode
152
152
 
153
153
  private fun onDraw() {
154
- // Fix an issue where scrolling was cancelled but the overscroll effect was not completed.
154
+ // Fix an issue where scrolling was canceled but the overscroll effect was not completed.
155
155
  // Reset the overscroll effect when no ongoing animation or interaction is applied.
156
156
  if (!drawCallScheduledByOffsetChange && isInProgress && overscrollNode.pointersDown == 0) {
157
157
  overscrollOffsetState.value = Offset.Zero
@@ -289,7 +289,7 @@ internal class CupertinoOverscrollEffect(
289
289
  }
290
290
 
291
291
  private fun applyPullToRefresh() {
292
- val (isRefresh, refresh, threshHold, _, sendHaptic) = pullRefreshState ?: return
292
+ val (isRefresh, refresh, threshHold, _, _) = pullRefreshState ?: return
293
293
  val overscrollY = overscrollOffset.y
294
294
  if (isRefresh.value || overscrollY < threshHold.value * density) return
295
295
  refresh.invoke()
@@ -398,7 +398,7 @@ internal class CupertinoOverscrollEffect(
398
398
  }
399
399
 
400
400
  springAnimationScope?.cancel()
401
- springAnimationScope = CoroutineScope(coroutineContext)
401
+ springAnimationScope = CoroutineScope(currentCoroutineContext())
402
402
  springAnimationScope?.run {
403
403
  AnimationState(
404
404
  Float.VectorConverter,
@@ -414,7 +414,7 @@ internal class CupertinoOverscrollEffect(
414
414
  } ?: (value * density).toOffset()
415
415
  currentVelocity = velocity * density
416
416
 
417
- // If it was fling from overscroll, cancel animation and return velocity
417
+ // If it was flung from overscroll, cancel animation and return velocity
418
418
  if (reason == CupertinoSpringAnimationReason.FLING_FROM_OVERSCROLL &&
419
419
  initialSign != 0f &&
420
420
  sign(value) != initialSign
@@ -425,7 +425,7 @@ internal class CupertinoOverscrollEffect(
425
425
  springAnimationScope = null
426
426
  }
427
427
 
428
- if (coroutineContext.isActive) {
428
+ if (currentCoroutineContext().isActive) {
429
429
  // The spring is critically damped, so in case spring-fling-spring sequence is slightly
430
430
  // offset and velocity is of the opposite sign, it will end up with no animation
431
431
  overscrollOffset = Offset.Zero
@@ -447,8 +447,8 @@ internal class CupertinoOverscrollEffect(
447
447
  val dpSize = scrollSize / density
448
448
 
449
449
  return Offset(
450
- rubberBandedValue(dpOffset.x, dpSize.width, RUBBER_BAND_COEFFICIENT),
451
- rubberBandedValue(dpOffset.y, dpSize.height, RUBBER_BAND_COEFFICIENT)
450
+ rubberBandedValue(dpOffset.x, dpSize.width),
451
+ rubberBandedValue(dpOffset.y, dpSize.height)
452
452
  ) * density
453
453
  }
454
454
 
@@ -456,8 +456,8 @@ internal class CupertinoOverscrollEffect(
456
456
  * Maps raw delta offset [value] on an axis within scroll container with [dimension]
457
457
  * to actual visible offset
458
458
  */
459
- private fun rubberBandedValue(value: Float, dimension: Float, coefficient: Float) =
460
- sign(value) * (1f - (1f / (abs(value) * coefficient / dimension + 1f))) * dimension
459
+ private fun rubberBandedValue(value: Float, dimension: Float) =
460
+ sign(value) * (1f - (1f / (abs(value) * RUBBER_BAND_COEFFICIENT / dimension + 1f))) * dimension
461
461
 
462
462
  companion object Companion {
463
463
  private const val RUBBER_BAND_COEFFICIENT = 0.55f
@@ -56,7 +56,7 @@ private val iconSizeMap = mapOf(
56
56
  )
57
57
 
58
58
  @Composable
59
- fun getIconStyle(type: ButtonType, color: Color? = null): Modifier {
59
+ internal fun getIconStyle(type: ButtonType, color: Color? = null): Modifier {
60
60
  val theme = AppTheme.current
61
61
 
62
62
  return remember(type, color, theme) {
@@ -91,18 +91,10 @@ fun getIconStyle(type: ButtonType, color: Color? = null): Modifier {
91
91
  }
92
92
 
93
93
  @Composable
94
- fun getIconColor(type: ButtonType): Color {
94
+ internal fun getIconColor(type: ButtonType): Color {
95
95
  val theme = AppTheme.current
96
96
  return remember(type, theme) {
97
- when (type) {
98
- ButtonType.DISABLED -> theme.colors.text.disable
99
- ButtonType.PRIMARY -> Colors.black_01
100
- ButtonType.SECONDARY -> theme.colors.text.default
101
- ButtonType.OUTLINE -> theme.colors.primary
102
- ButtonType.TONAL -> theme.colors.primary
103
- ButtonType.DANGER -> Colors.black_01
104
- ButtonType.TEXT -> theme.colors.primary
105
- }
97
+ getButtonColor(type, theme)
106
98
  }
107
99
  }
108
100
 
@@ -3,11 +3,7 @@ package vn.momo.kits.components
3
3
  import androidx.compose.foundation.background
4
4
  import androidx.compose.foundation.border
5
5
  import androidx.compose.foundation.clickable
6
- import androidx.compose.foundation.layout.Column
7
- import androidx.compose.foundation.layout.Row
8
- import androidx.compose.foundation.layout.height
9
- import androidx.compose.foundation.layout.padding
10
- import androidx.compose.foundation.layout.width
6
+ import androidx.compose.foundation.layout.*
11
7
  import androidx.compose.foundation.shape.RoundedCornerShape
12
8
  import androidx.compose.runtime.Composable
13
9
  import androidx.compose.ui.Modifier
@@ -1,29 +1,17 @@
1
1
  package vn.momo.kits.components
2
2
 
3
+ import vn.momo.kits.utils.Deprecated.InternalApi
4
+
3
5
  import androidx.compose.foundation.background
4
6
  import androidx.compose.foundation.border
5
7
  import androidx.compose.foundation.clickable
6
8
  import androidx.compose.foundation.interaction.MutableInteractionSource
7
- import androidx.compose.foundation.layout.Box
8
- import androidx.compose.foundation.layout.Column
9
- import androidx.compose.foundation.layout.Row
10
- import androidx.compose.foundation.layout.Spacer
11
- import androidx.compose.foundation.layout.fillMaxWidth
12
- import androidx.compose.foundation.layout.height
13
- import androidx.compose.foundation.layout.offset
14
- import androidx.compose.foundation.layout.padding
15
- import androidx.compose.foundation.layout.size
16
- import androidx.compose.foundation.layout.wrapContentSize
9
+ import androidx.compose.foundation.layout.*
17
10
  import androidx.compose.foundation.shape.RoundedCornerShape
18
11
  import androidx.compose.foundation.text.BasicTextField
19
12
  import androidx.compose.foundation.text.KeyboardOptions
20
13
  import androidx.compose.material3.CircularProgressIndicator
21
- import androidx.compose.runtime.Composable
22
- import androidx.compose.runtime.MutableState
23
- import androidx.compose.runtime.getValue
24
- import androidx.compose.runtime.mutableStateOf
25
- import androidx.compose.runtime.remember
26
- import androidx.compose.runtime.setValue
14
+ import androidx.compose.runtime.*
27
15
  import androidx.compose.ui.Alignment
28
16
  import androidx.compose.ui.Modifier
29
17
  import androidx.compose.ui.focus.onFocusChanged
@@ -44,13 +32,7 @@ import androidx.compose.ui.unit.dp
44
32
  import androidx.compose.ui.unit.sp
45
33
  import androidx.compose.ui.zIndex
46
34
  import vn.momo.kits.application.IsShowBaseLineDebug
47
- import vn.momo.kits.const.AppTheme
48
- import vn.momo.kits.const.Colors
49
- import vn.momo.kits.const.Radius
50
- import vn.momo.kits.const.Spacing
51
- import vn.momo.kits.const.Typography
52
- import vn.momo.kits.const.getFont
53
- import vn.momo.kits.const.scaleSize
35
+ import vn.momo.kits.const.*
54
36
  import vn.momo.kits.modifier.conditional
55
37
  import vn.momo.kits.modifier.setAutomationId
56
38
  import vn.momo.uikits.resources.Res
@@ -88,7 +70,6 @@ enum class InputFontWeight(val value: FontWeight) {
88
70
  )
89
71
  }
90
72
 
91
- // Consolidated input state for better performance
92
73
  data class InputState(
93
74
  val isFocused: Boolean = false,
94
75
  val passHidden: Boolean = false,
@@ -128,6 +109,7 @@ private class PasswordVisualTransformation(
128
109
  }
129
110
 
130
111
  @Composable
112
+ @InternalApi
131
113
  fun getBorderColor(isFocused: Boolean, error: String, disabled: Boolean): Color {
132
114
  val theme = AppTheme.current
133
115
  return remember(isFocused, error, disabled, theme) {
@@ -141,6 +123,7 @@ fun getBorderColor(isFocused: Boolean, error: String, disabled: Boolean): Color
141
123
  }
142
124
 
143
125
  @Composable
126
+ @InternalApi
144
127
  fun RenderRightIcon(loading: Boolean, icon: String, color: Color, onClick: () -> Unit, modifier: Modifier = Modifier) {
145
128
  if (loading) {
146
129
  Box {
@@ -167,6 +150,7 @@ fun RenderRightIcon(loading: Boolean, icon: String, color: Color, onClick: () ->
167
150
  }
168
151
 
169
152
  @Composable
153
+ @InternalApi
170
154
  fun ErrorView(errorMessage: String, errorSpacing: Boolean, hintText: String) {
171
155
  val theme = AppTheme.current
172
156
  val errorColor = remember(theme) { theme.colors.error.primary }
@@ -326,41 +310,14 @@ fun Input(
326
310
  },
327
311
  decorationBox = { innerTextField ->
328
312
  // Floating label
329
- if (floatingValue.isNotEmpty() || floatingIcon.isNotEmpty()) {
330
- Box(
331
- modifier = Modifier
332
- .wrapContentSize()
333
- .offset(y = (-size.values.height / 2), x = Spacing.S)
334
- .background(theme.colors.background.surface)
335
- .zIndex(10f),
336
- ) {
337
- Row(
338
- modifier = Modifier.padding(horizontal = Spacing.S),
339
- verticalAlignment = Alignment.CenterVertically
340
- ) {
341
- Text(
342
- floatingValue,
343
- style = Typography.labelSMedium,
344
- color = floatingTitleColor
345
- )
346
- if (required) {
347
- Text(
348
- "*",
349
- style = Typography.labelSMedium,
350
- color = theme.colors.error.primary,
351
- )
352
- }
353
- if (floatingIcon.isNotEmpty()) {
354
- Icon(
355
- source = floatingIcon,
356
- modifier = Modifier.padding(start = Spacing.XS),
357
- size = 16.dp,
358
- color = floatingIconTintColor
359
- )
360
- }
361
- }
362
- }
363
- }
313
+ FloatingLabel(
314
+ floatingValue = floatingValue,
315
+ floatingIcon = floatingIcon,
316
+ titleColor = floatingTitleColor,
317
+ iconColor = floatingIconTintColor,
318
+ offsetY = -size.values.height / 2,
319
+ required = required,
320
+ )
364
321
 
365
322
  // Input container
366
323
  Box(
@@ -450,3 +407,71 @@ fun Input(
450
407
  ErrorView(error, errorSpacing, hintText)
451
408
  }
452
409
  }
410
+
411
+ internal data class InputColors(
412
+ val text: Color,
413
+ val placeholder: Color,
414
+ val iconTint: Color,
415
+ val floatingTitle: Color,
416
+ val floatingIcon: Color,
417
+ )
418
+
419
+ @Composable
420
+ internal fun getInputColors(
421
+ disabled: Boolean,
422
+ iconColor: Color,
423
+ floatingValueColor: Color,
424
+ floatingIconColor: Color,
425
+ ): InputColors {
426
+ val theme = AppTheme.current
427
+ val disabledColor = theme.colors.text.disable
428
+ return InputColors(
429
+ text = if (disabled) disabledColor else theme.colors.text.default,
430
+ placeholder = if (disabled) disabledColor else theme.colors.text.hint,
431
+ iconTint = if (disabled) disabledColor else iconColor,
432
+ floatingTitle = if (disabled) disabledColor else floatingValueColor,
433
+ floatingIcon = if (disabled) disabledColor else floatingIconColor,
434
+ )
435
+ }
436
+
437
+ @Composable
438
+ internal fun FloatingLabel(
439
+ floatingValue: String,
440
+ floatingIcon: String,
441
+ titleColor: Color,
442
+ iconColor: Color,
443
+ offsetY: Dp,
444
+ offsetX: Dp = Spacing.S,
445
+ required: Boolean = false,
446
+ ) {
447
+ if (floatingValue.isEmpty() && floatingIcon.isEmpty()) return
448
+ Box(
449
+ modifier = Modifier
450
+ .wrapContentSize()
451
+ .offset(y = offsetY, x = offsetX)
452
+ .background(AppTheme.current.colors.background.surface)
453
+ .zIndex(10f),
454
+ ) {
455
+ Row(
456
+ modifier = Modifier.padding(horizontal = Spacing.S),
457
+ verticalAlignment = Alignment.CenterVertically,
458
+ ) {
459
+ Text(floatingValue, style = Typography.labelSMedium, color = titleColor)
460
+ if (required) {
461
+ Text(
462
+ "*",
463
+ style = Typography.labelSMedium,
464
+ color = AppTheme.current.colors.error.primary,
465
+ )
466
+ }
467
+ if (floatingIcon.isNotEmpty()) {
468
+ Icon(
469
+ source = floatingIcon,
470
+ modifier = Modifier.padding(start = Spacing.XS),
471
+ size = 16.dp,
472
+ color = iconColor,
473
+ )
474
+ }
475
+ }
476
+ }
477
+ }
@@ -3,20 +3,9 @@ package vn.momo.kits.components
3
3
  import androidx.compose.foundation.background
4
4
  import androidx.compose.foundation.border
5
5
  import androidx.compose.foundation.clickable
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.fillMaxWidth
10
- import androidx.compose.foundation.layout.height
11
- import androidx.compose.foundation.layout.offset
12
- import androidx.compose.foundation.layout.padding
13
- import androidx.compose.foundation.layout.wrapContentSize
6
+ import androidx.compose.foundation.layout.*
14
7
  import androidx.compose.foundation.shape.RoundedCornerShape
15
- import androidx.compose.runtime.Composable
16
- import androidx.compose.runtime.MutableState
17
- import androidx.compose.runtime.getValue
18
- import androidx.compose.runtime.mutableStateOf
19
- import androidx.compose.runtime.remember
8
+ import androidx.compose.runtime.*
20
9
  import androidx.compose.ui.Alignment
21
10
  import androidx.compose.ui.Modifier
22
11
  import androidx.compose.ui.graphics.Color
@@ -27,12 +16,8 @@ import androidx.compose.ui.text.TextStyle
27
16
  import androidx.compose.ui.unit.dp
28
17
  import androidx.compose.ui.unit.sp
29
18
  import androidx.compose.ui.zIndex
30
- import vn.momo.kits.const.AppTheme
31
- import vn.momo.kits.const.Spacing
32
19
  import vn.momo.kits.application.IsShowBaseLineDebug
33
- import vn.momo.kits.const.Colors
34
- import vn.momo.kits.const.Typography
35
- import vn.momo.kits.const.scaleSize
20
+ import vn.momo.kits.const.*
36
21
  import vn.momo.kits.modifier.conditional
37
22
 
38
23
  @Composable
@@ -59,24 +44,8 @@ fun InputDropDown(
59
44
  ) {
60
45
  val isFocused by remember { mutableStateOf(false) }
61
46
 
62
- val disabledColor = AppTheme.current.colors.text.disable
63
- var textColor = AppTheme.current.colors.text.default
64
- var placeholderColor = AppTheme.current.colors.text.hint
65
- var iconTintColor = iconColor
66
- val floatingTitleColor = when {
67
- disabled -> AppTheme.current.colors.text.disable
68
- else -> floatingValueColor
69
- }
70
- val floatingIconTintColor = when {
71
- disabled -> AppTheme.current.colors.text.disable
72
- else -> floatingIconColor
73
- }
74
-
75
- if (disabled) {
76
- textColor = disabledColor
77
- placeholderColor = disabledColor
78
- iconTintColor = disabledColor
79
- }
47
+ val (textColor, placeholderColor, iconTintColor, floatingTitleColor, floatingIconTintColor) =
48
+ getInputColors(disabled, iconColor, floatingValueColor, floatingIconColor)
80
49
 
81
50
  val testId = if (disabled) "input_${floatingValue}_disabled" else "input_$floatingValue"
82
51
 
@@ -92,41 +61,14 @@ fun InputDropDown(
92
61
  contentDescription = floatingValue; testTag = testId
93
62
  }) {
94
63
  Box {
95
- if (floatingValue.isNotEmpty() || floatingIcon.isNotEmpty()) {
96
- Box(
97
- modifier = Modifier.wrapContentSize()
98
- .offset(y = -Spacing.S, x = Spacing.S)
99
- .background(AppTheme.current.colors.background.surface)
100
- .zIndex(10f),
101
- ) {
102
- Row(
103
- modifier = Modifier
104
- .padding(horizontal = Spacing.S),
105
- verticalAlignment = Alignment.CenterVertically
106
- ) {
107
- Text(
108
- floatingValue,
109
- style = Typography.labelSMedium,
110
- color = floatingTitleColor
111
- )
112
- if (required) {
113
- Text(
114
- "*",
115
- style = Typography.labelSMedium,
116
- color = AppTheme.current.colors.error.primary,
117
- )
118
- }
119
- if (floatingIcon.isNotEmpty()) {
120
- Icon(
121
- source = floatingIcon,
122
- modifier = Modifier.padding(start = Spacing.XS),
123
- size = 16.dp,
124
- color = floatingIconTintColor
125
- )
126
- }
127
- }
128
- }
129
- }
64
+ FloatingLabel(
65
+ floatingValue = floatingValue,
66
+ floatingIcon = floatingIcon,
67
+ titleColor = floatingTitleColor,
68
+ iconColor = floatingIconTintColor,
69
+ offsetY = -Spacing.S,
70
+ required = required,
71
+ )
130
72
  Box(
131
73
  modifier = Modifier.fillMaxWidth()
132
74
  .height(if (size == InputSize.SMALL) 48.dp else 56.dp)
@@ -102,24 +102,8 @@ fun InputMoney(
102
102
  ) {
103
103
  var isFocused by remember { mutableStateOf(false) }
104
104
  var isBlurred = false
105
- val disabledColor = AppTheme.current.colors.text.disable
106
- var textColor = AppTheme.current.colors.text.default
107
- var placeholderColor = AppTheme.current.colors.text.hint
108
- var iconTintColor = iconColor
109
- val floatingTitleColor = when {
110
- disabled -> AppTheme.current.colors.text.disable
111
- else -> floatingValueColor
112
- }
113
- val floatingIconTintColor = when {
114
- disabled -> AppTheme.current.colors.text.disable
115
- else -> floatingIconColor
116
- }
117
-
118
- if (disabled) {
119
- textColor = disabledColor
120
- placeholderColor = disabledColor
121
- iconTintColor = disabledColor
122
- }
105
+ val (textColor, placeholderColor, iconTintColor, floatingTitleColor, floatingIconTintColor) =
106
+ getInputColors(disabled, iconColor, floatingValueColor, floatingIconColor)
123
107
 
124
108
  val testId = if (disabled) "input_${floatingValue}_disabled" else "input_$floatingValue"
125
109
 
@@ -156,39 +140,14 @@ fun InputMoney(
156
140
  },
157
141
  decorationBox = { innerTextField ->
158
142
  // Floating Icon
159
- if (floatingValue.isNotEmpty() || floatingIcon.isNotEmpty()) {
160
- Box(
161
- modifier = Modifier.wrapContentSize()
162
- .offset(y = (-size.values.height / 2), x = (Spacing.S))
163
- .background(AppTheme.current.colors.background.surface)
164
- .zIndex(10f),
165
- ) {
166
- Row(
167
- modifier = Modifier.padding(horizontal = Spacing.S),
168
- ) {
169
- Text(
170
- floatingValue,
171
- style = Typography.labelSMedium,
172
- color = floatingTitleColor
173
- )
174
- if (required) {
175
- Text(
176
- "*",
177
- style = Typography.labelSMedium,
178
- color = AppTheme.current.colors.error.primary,
179
- )
180
- }
181
- if (floatingIcon.isNotEmpty()) {
182
- Icon(
183
- source = floatingIcon,
184
- modifier = Modifier.padding(start = Spacing.XS),
185
- size = 16.dp,
186
- color = floatingIconTintColor
187
- )
188
- }
189
- }
190
- }
191
- }
143
+ FloatingLabel(
144
+ floatingValue = floatingValue,
145
+ floatingIcon = floatingIcon,
146
+ titleColor = floatingTitleColor,
147
+ iconColor = floatingIconTintColor,
148
+ offsetY = -size.values.height / 2,
149
+ required = required,
150
+ )
192
151
  //input box wrapper
193
152
  Box(
194
153
  modifier = Modifier.fillMaxWidth()