@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
@@ -18,6 +18,8 @@ import vn.momo.kits.application.IsShowBaseLineDebug
18
18
  import vn.momo.kits.const.*
19
19
  import vn.momo.kits.modifier.conditional
20
20
 
21
+ // ─── Data model ───────────────────────────────────────────────────────────────
22
+
21
23
  data class ProgressInfoItem(
22
24
  val title: String,
23
25
  val description: String? = null,
@@ -27,6 +29,25 @@ enum class ProgressInfoSize { Small, Large }
27
29
 
28
30
  enum class ProgressInfoAlign { Left, Right, Center, Stretch }
29
31
 
32
+ // ─── Public entry-point ───────────────────────────────────────────────────────
33
+
34
+ /**
35
+ * Display-only step progress indicator migrated from the React Native ProgressInfo component.
36
+ *
37
+ * @param steps Ordered list of steps; each has a [ProgressInfoItem.title] and an
38
+ * optional [ProgressInfoItem.description].
39
+ * @param horizontal When `true` renders steps in a horizontal row with connector lines;
40
+ * when `false` (default) renders a vertical column.
41
+ * @param size Icon diameter: [ProgressInfoSize.Small] = 16 dp,
42
+ * [ProgressInfoSize.Large] = 24 dp (default).
43
+ * @param useNumber Show the 1-based step index inside the icon instead of the default dot.
44
+ * @param align Alignment of icon + text for the horizontal variant.
45
+ * @param showTitle Whether step titles are rendered (default `true`).
46
+ * @param showDescription Whether step descriptions are rendered (default `true`).
47
+ * @param customIcon Icon source key rendered inside each step circle (overrides the dot;
48
+ * itself overridden by [useNumber]).
49
+ * @param modifier Modifier applied to the root layout.
50
+ */
30
51
  @Composable
31
52
  fun ProgressInfo(
32
53
  steps: List<ProgressInfoItem>,
@@ -63,6 +84,8 @@ fun ProgressInfo(
63
84
  }
64
85
  }
65
86
 
87
+ // ─── Horizontal variant ───────────────────────────────────────────────────────
88
+
66
89
  @Composable
67
90
  private fun ProgressInfoHorizontal(
68
91
  steps: List<ProgressInfoItem>,
@@ -167,6 +190,7 @@ private fun ProgressInfoHorizontal(
167
190
  }
168
191
  }
169
192
 
193
+ // ─── Vertical variant ─────────────────────────────────────────────────────────
170
194
 
171
195
  @Composable
172
196
  private fun ProgressInfoVertical(
@@ -251,6 +275,8 @@ private fun ProgressInfoVertical(
251
275
  }
252
276
  }
253
277
 
278
+ // ─── Step icon ────────────────────────────────────────────────────────────────
279
+
254
280
  @Composable
255
281
  private fun ProgressInfoStepIcon(
256
282
  index: Int,
@@ -300,6 +326,8 @@ private fun ProgressInfoStepIcon(
300
326
  }
301
327
  }
302
328
 
329
+ // ─── Horizontal connector line ────────────────────────────────────────────────
330
+
303
331
  @Composable
304
332
  private fun ProgressInfoHorizontalLine(modifier: Modifier = Modifier) {
305
333
  Box(
@@ -1,15 +1,26 @@
1
1
  package vn.momo.kits.components
2
2
 
3
3
  import androidx.compose.foundation.border
4
- import androidx.compose.foundation.layout.*
4
+ import androidx.compose.foundation.clickable
5
+ import androidx.compose.foundation.interaction.MutableInteractionSource
6
+ import androidx.compose.foundation.layout.Arrangement
7
+ import androidx.compose.foundation.layout.Box
8
+ import androidx.compose.foundation.layout.Row
9
+ import androidx.compose.foundation.layout.padding
10
+ import androidx.compose.foundation.layout.size
5
11
  import androidx.compose.foundation.shape.RoundedCornerShape
6
12
  import androidx.compose.runtime.Composable
13
+ import androidx.compose.runtime.remember
7
14
  import androidx.compose.ui.Alignment
8
15
  import androidx.compose.ui.Modifier
9
16
  import androidx.compose.ui.draw.clip
10
17
  import androidx.compose.ui.unit.dp
11
18
  import vn.momo.kits.application.IsShowBaseLineDebug
12
- import vn.momo.kits.const.*
19
+ import vn.momo.kits.const.AppTheme
20
+ import vn.momo.kits.const.Colors
21
+ import vn.momo.kits.const.Radius
22
+ import vn.momo.kits.const.Spacing
23
+ import vn.momo.kits.const.Typography
13
24
  import vn.momo.kits.modifier.activeOpacityClickable
14
25
  import vn.momo.kits.modifier.conditional
15
26
 
@@ -0,0 +1,17 @@
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
+ }
@@ -1,8 +1,11 @@
1
1
  package vn.momo.kits.components
2
2
 
3
- import vn.momo.kits.modifier.InternalApi
4
-
5
- import androidx.compose.animation.core.*
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
6
9
  import androidx.compose.foundation.background
7
10
  import androidx.compose.foundation.border
8
11
  import androidx.compose.foundation.layout.Box
@@ -19,17 +22,21 @@ import vn.momo.kits.application.IsShowBaseLineDebug
19
22
  import vn.momo.kits.const.Colors
20
23
  import vn.momo.kits.modifier.conditional
21
24
 
25
+ // Pre-computed shimmer colors to avoid repeated list creation
22
26
  private val shimmerColors = listOf(
23
27
  Colors.black_05,
24
28
  Colors.black_03,
25
29
  Colors.black_05,
26
30
  )
31
+
32
+ // Constants for better performance
27
33
  private const val SHADOW_BRUSH_PERCENTAGE = 0.6f
28
34
  private const val DEFAULT_DURATION_MILLIS = 1000
29
35
 
30
36
  @Composable
31
37
  fun Skeleton() {
32
38
  BoxWithConstraints(modifier = Modifier.fillMaxSize()) {
39
+ // Memoize width calculation
33
40
  val maxWidthValue = remember(maxWidth) { maxWidth.value.toInt() }
34
41
 
35
42
  Box(
@@ -45,7 +52,6 @@ fun Skeleton() {
45
52
  }
46
53
 
47
54
  @Composable
48
- @InternalApi
49
55
  fun Modifier.shimmerLoadingAnimation(
50
56
  maxWidth: Int,
51
57
  angleOfAxisY: Float = 0f,
@@ -4,12 +4,25 @@ import androidx.compose.animation.core.animateFloatAsState
4
4
  import androidx.compose.animation.core.spring
5
5
  import androidx.compose.foundation.background
6
6
  import androidx.compose.foundation.border
7
- import androidx.compose.foundation.layout.*
7
+ import androidx.compose.foundation.layout.Box
8
+ import androidx.compose.foundation.layout.BoxWithConstraints
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.size
14
+ import androidx.compose.foundation.layout.width
8
15
  import androidx.compose.foundation.shape.RoundedCornerShape
9
- import androidx.compose.runtime.*
16
+ import androidx.compose.runtime.Composable
17
+ import androidx.compose.runtime.getValue
18
+ import androidx.compose.runtime.mutableFloatStateOf
19
+ import androidx.compose.runtime.mutableStateOf
20
+ import androidx.compose.runtime.remember
21
+ import androidx.compose.runtime.setValue
10
22
  import androidx.compose.ui.Alignment
11
23
  import androidx.compose.ui.Modifier
12
24
  import androidx.compose.ui.draw.clip
25
+ import androidx.compose.ui.graphics.Color
13
26
  import androidx.compose.ui.input.pointer.pointerInput
14
27
  import androidx.compose.ui.layout.onGloballyPositioned
15
28
  import androidx.compose.ui.platform.LocalDensity
@@ -17,12 +30,19 @@ import androidx.compose.ui.text.style.TextAlign
17
30
  import androidx.compose.ui.unit.IntOffset
18
31
  import androidx.compose.ui.unit.dp
19
32
  import vn.momo.kits.application.IsShowBaseLineDebug
20
- import vn.momo.kits.const.*
33
+ import vn.momo.kits.const.AppTheme
34
+ import vn.momo.kits.const.Colors
35
+ import vn.momo.kits.const.Radius
36
+ import vn.momo.kits.const.Spacing
37
+ import vn.momo.kits.const.Typography
21
38
  import vn.momo.kits.modifier.conditional
39
+ import vn.momo.kits.modifier.shadow
22
40
  import kotlin.math.abs
23
41
  import kotlin.math.min
24
42
  import kotlin.math.roundToInt
25
43
 
44
+ // ── Design constants ─────────────────────────────────────────────────────────
45
+
26
46
  private val THUMB_SIZE = 20.dp
27
47
  private val THUMB_BORDER = 3.dp
28
48
  private val TRACK_HEIGHT = 4.dp
@@ -30,10 +50,15 @@ private val LABEL_PAD_H = Spacing.XS
30
50
  private val LABEL_PAD_V = Spacing.XXS
31
51
  private val LABEL_GAP = Spacing.XS // space between label and thumb top
32
52
 
53
+ // ── Pure helpers (mirrors RN helpers.ts) ─────────────────────────────────────
33
54
 
34
55
  private fun clamp(value: Float, min: Float, max: Float): Float =
35
56
  min(kotlin.math.max(value, min), max)
36
57
 
58
+ /**
59
+ * Converts a raw touch position into a snapped slider value.
60
+ * Direct port of RN getValueForPosition().
61
+ */
37
62
  private fun getValueForPosition(
38
63
  positionInView: Float,
39
64
  containerWidth: Float,
@@ -2,12 +2,21 @@ 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.*
5
+ import androidx.compose.foundation.layout.Box
6
+ import androidx.compose.foundation.layout.Row
7
+ import androidx.compose.foundation.layout.defaultMinSize
8
+ import androidx.compose.foundation.layout.height
9
+ import androidx.compose.foundation.layout.padding
10
+ import androidx.compose.foundation.layout.size
6
11
  import androidx.compose.foundation.shape.CircleShape
7
12
  import androidx.compose.foundation.shape.RoundedCornerShape
8
13
  import androidx.compose.foundation.text.BasicTextField
9
14
  import androidx.compose.foundation.text.KeyboardOptions
10
- import androidx.compose.runtime.*
15
+ import androidx.compose.runtime.Composable
16
+ import androidx.compose.runtime.getValue
17
+ import androidx.compose.runtime.mutableStateOf
18
+ import androidx.compose.runtime.remember
19
+ import androidx.compose.runtime.setValue
11
20
  import androidx.compose.ui.Alignment
12
21
  import androidx.compose.ui.Modifier
13
22
  import androidx.compose.ui.graphics.Color
@@ -18,10 +27,18 @@ import androidx.compose.ui.unit.Dp
18
27
  import androidx.compose.ui.unit.dp
19
28
  import androidx.compose.ui.unit.sp
20
29
  import vn.momo.kits.application.IsShowBaseLineDebug
21
- import vn.momo.kits.const.*
30
+ import vn.momo.kits.const.AppTheme
31
+ import vn.momo.kits.const.Colors
32
+ import vn.momo.kits.const.Radius
33
+ import vn.momo.kits.const.Spacing
34
+ import vn.momo.kits.const.scaleSize
22
35
  import vn.momo.kits.modifier.activeOpacityClickable
23
36
  import vn.momo.kits.modifier.conditional
24
37
 
38
+ // ---------------------------------------------------------------------------
39
+ // Size variant
40
+ // ---------------------------------------------------------------------------
41
+
25
42
  enum class StepperSize {
26
43
  LARGE,
27
44
  SMALL
@@ -49,6 +66,10 @@ private val stepperSizeSpecs: Map<StepperSize, StepperSizeSpec> = mapOf(
49
66
  ),
50
67
  )
51
68
 
69
+ // ---------------------------------------------------------------------------
70
+ // Private sub-composables
71
+ // ---------------------------------------------------------------------------
72
+
52
73
  @Composable
53
74
  private fun StepperButton(
54
75
  sign: String = "+",
@@ -136,6 +157,26 @@ private fun StepperNumberView(
136
157
  }
137
158
  }
138
159
 
160
+ // ---------------------------------------------------------------------------
161
+ // Public API
162
+ // ---------------------------------------------------------------------------
163
+
164
+ /**
165
+ * Stepper — migrated from React Native Stepper.
166
+ *
167
+ * Layout: [− button] [value display] [+ button]
168
+ *
169
+ * @param defaultValue Initial value (default 0). Clamped to [min]..[max] on first composition.
170
+ * @param min Minimum allowed value (default 0). Minus button is auto-disabled at this bound.
171
+ * @param max Maximum allowed value (default 100). Plus button is auto-disabled at this bound.
172
+ * @param step Amount added/subtracted per button press (default 1).
173
+ * @param disabled Disable state. Pass `true` to disable everything, or a [BooleanArray] of
174
+ * size >= 2 where index 0 = minus button, index 1 = plus button.
175
+ * @param size Visual size variant: [StepperSize.LARGE] (default) or [StepperSize.SMALL].
176
+ * @param editable When `true` the number display becomes a direct keyboard input (default false).
177
+ * @param onValueChange Callback invoked with the new [Int] value on every change.
178
+ * @param modifier Modifier applied to the root [Row].
179
+ */
139
180
  @Composable
140
181
  fun Stepper(
141
182
  defaultValue: Int = 0,
@@ -162,19 +203,17 @@ fun Stepper(
162
203
  val disabledPlus: Boolean
163
204
  val disabledNumber: Boolean
164
205
 
165
- when (disabled) {
166
- is BooleanArray if disabled.size >= 2 -> {
206
+ when {
207
+ disabled is BooleanArray && disabled.size >= 2 -> {
167
208
  disabledMinus = disabled[0]
168
209
  disabledPlus = disabled[1]
169
210
  disabledNumber = disabled[0] && disabled[1]
170
211
  }
171
-
172
- is Boolean if disabled -> {
212
+ disabled is Boolean && disabled -> {
173
213
  disabledMinus = true
174
214
  disabledPlus = true
175
215
  disabledNumber = true
176
216
  }
177
-
178
217
  else -> {
179
218
  disabledMinus = false
180
219
  disabledPlus = false
@@ -2,7 +2,16 @@ 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.*
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
6
15
  import androidx.compose.foundation.shape.CircleShape
7
16
  import androidx.compose.foundation.shape.RoundedCornerShape
8
17
  import androidx.compose.runtime.Composable
@@ -14,10 +23,15 @@ import androidx.compose.ui.text.style.TextAlign
14
23
  import androidx.compose.ui.unit.Dp
15
24
  import androidx.compose.ui.unit.dp
16
25
  import vn.momo.kits.application.IsShowBaseLineDebug
17
- import vn.momo.kits.const.*
26
+ import vn.momo.kits.const.AppTheme
27
+ import vn.momo.kits.const.Colors
28
+ import vn.momo.kits.const.Radius
29
+ import vn.momo.kits.const.Spacing
30
+ import vn.momo.kits.const.Typography
18
31
  import vn.momo.kits.modifier.activeOpacityClickable
19
32
  import vn.momo.kits.modifier.conditional
20
33
 
34
+ // ─── Data model ────────────────────────────────────────────────────────────────
21
35
 
22
36
  data class StepItem(
23
37
  val title: String,
@@ -26,11 +40,13 @@ data class StepItem(
26
40
  val time: String? = null,
27
41
  )
28
42
 
43
+ // ─── Enumerations ──────────────────────────────────────────────────────────────
29
44
 
30
45
  enum class StepsSize { SMALL, LARGE }
31
46
 
32
47
  enum class StepsAlign { LEFT, RIGHT, CENTER, STRETCH }
33
48
 
49
+ // ─── Internal status ───────────────────────────────────────────────────────────
34
50
 
35
51
  private enum class StepStatus { INCOMPLETE, CURRENT, COMPLETED, ERROR, DISABLED }
36
52
 
@@ -47,6 +63,7 @@ private fun resolveStatus(
47
63
  else -> StepStatus.INCOMPLETE
48
64
  }
49
65
 
66
+ // ─── Color helpers ─────────────────────────────────────────────────────────────
50
67
 
51
68
  @Composable
52
69
  private fun resolveIconBgAndBorder(status: StepStatus): Pair<Color, Color> {
@@ -74,6 +91,8 @@ private fun resolveTitleColor(status: StepStatus): Color {
74
91
  }
75
92
  }
76
93
 
94
+ // ─── Step bubble ───────────────────────────────────────────────────────────────
95
+
77
96
  @Composable
78
97
  private fun StepBubble(
79
98
  index: Int,
@@ -134,6 +153,7 @@ private fun StepBubble(
134
153
  }
135
154
  }
136
155
 
156
+ // ─── Horizontal layout ─────────────────────────────────────────────────────────
137
157
 
138
158
  @Composable
139
159
  private fun StepsHorizontal(
@@ -208,7 +228,7 @@ private fun StepsHorizontal(
208
228
  modifier = Modifier
209
229
  .weight(1f)
210
230
  .then(
211
- if (clickable) Modifier.activeOpacityClickable { onPress.invoke(item, index) }
231
+ if (clickable) Modifier.activeOpacityClickable { onPress?.invoke(item, index) }
212
232
  else Modifier
213
233
  ),
214
234
  horizontalAlignment = colAlign,
@@ -298,6 +318,7 @@ private fun StepsHorizontal(
298
318
  }
299
319
  }
300
320
 
321
+ // ─── Vertical layout ───────────────────────────────────────────────────────────
301
322
 
302
323
  @Composable
303
324
  private fun StepsVertical(
@@ -341,7 +362,7 @@ private fun StepsVertical(
341
362
  modifier = Modifier
342
363
  .fillMaxWidth()
343
364
  .then(
344
- if (clickable) Modifier.activeOpacityClickable { onPress.invoke(item, index) }
365
+ if (clickable) Modifier.activeOpacityClickable { onPress?.invoke(item, index) }
345
366
  else Modifier
346
367
  ),
347
368
  ) {
@@ -5,7 +5,12 @@ import androidx.compose.animation.fadeIn
5
5
  import androidx.compose.animation.fadeOut
6
6
  import androidx.compose.foundation.background
7
7
  import androidx.compose.foundation.border
8
- import androidx.compose.foundation.layout.*
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.padding
12
+ import androidx.compose.foundation.layout.size
13
+ import androidx.compose.foundation.layout.width
9
14
  import androidx.compose.foundation.shape.RoundedCornerShape
10
15
  import androidx.compose.runtime.Composable
11
16
  import androidx.compose.runtime.remember
@@ -18,7 +23,11 @@ import androidx.compose.ui.text.font.FontWeight
18
23
  import androidx.compose.ui.text.withStyle
19
24
  import androidx.compose.ui.unit.dp
20
25
  import vn.momo.kits.application.IsShowBaseLineDebug
21
- import vn.momo.kits.const.*
26
+ import vn.momo.kits.const.AppTheme
27
+ import vn.momo.kits.const.Colors
28
+ import vn.momo.kits.const.Radius
29
+ import vn.momo.kits.const.Spacing
30
+ import vn.momo.kits.const.Typography
22
31
  import vn.momo.kits.modifier.activeOpacityClickable
23
32
  import vn.momo.kits.modifier.conditional
24
33
  import vn.momo.kits.modifier.shadow
@@ -5,7 +5,14 @@ import androidx.compose.animation.core.tween
5
5
  import androidx.compose.foundation.background
6
6
  import androidx.compose.foundation.border
7
7
  import androidx.compose.foundation.gestures.detectHorizontalDragGestures
8
- import androidx.compose.foundation.layout.*
8
+ import androidx.compose.foundation.layout.Box
9
+ import androidx.compose.foundation.layout.Column
10
+ import androidx.compose.foundation.layout.Row
11
+ import androidx.compose.foundation.layout.fillMaxHeight
12
+ import androidx.compose.foundation.layout.fillMaxWidth
13
+ import androidx.compose.foundation.layout.height
14
+ import androidx.compose.foundation.layout.offset
15
+ import androidx.compose.foundation.layout.width
9
16
  import androidx.compose.foundation.shape.RoundedCornerShape
10
17
  import androidx.compose.runtime.Composable
11
18
  import androidx.compose.runtime.remember
@@ -23,6 +30,8 @@ import kotlinx.coroutines.launch
23
30
  import vn.momo.kits.application.IsShowBaseLineDebug
24
31
  import vn.momo.kits.const.AppTheme
25
32
  import vn.momo.kits.const.Colors
33
+ import vn.momo.kits.const.Radius
34
+ import vn.momo.kits.const.Spacing
26
35
  import vn.momo.kits.const.Typography
27
36
  import vn.momo.kits.modifier.activeOpacityClickable
28
37
  import vn.momo.kits.modifier.conditional
@@ -89,6 +98,13 @@ fun Swipe(
89
98
  }
90
99
  }
91
100
 
101
+ fun close() {
102
+ scope.launch {
103
+ offsetX.animateTo(0f, tween(200))
104
+ onSwipeableClose()
105
+ }
106
+ }
107
+
92
108
  Box(
93
109
  modifier = modifier
94
110
  .fillMaxWidth()
@@ -3,7 +3,11 @@ 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.*
6
+ import androidx.compose.foundation.layout.Box
7
+ import androidx.compose.foundation.layout.height
8
+ import androidx.compose.foundation.layout.padding
9
+ import androidx.compose.foundation.layout.size
10
+ import androidx.compose.foundation.layout.width
7
11
  import androidx.compose.foundation.shape.RoundedCornerShape
8
12
  import androidx.compose.runtime.Composable
9
13
  import androidx.compose.runtime.remember
@@ -18,6 +22,7 @@ import vn.momo.kits.const.Spacing
18
22
  import vn.momo.kits.modifier.conditional
19
23
  import vn.momo.kits.modifier.setAutomationId
20
24
 
25
+ // Pre-computed shapes to avoid repeated creation
21
26
  private val switchShape = RoundedCornerShape(20.dp)
22
27
  private val circleShape = RoundedCornerShape(percent = 100)
23
28