@momo-kits/native-kits 0.162.2-test.2-debug → 0.162.2-test.21-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 (132) hide show
  1. package/.claude/settings.local.json +14 -0
  2. package/CLAUDE.md +78 -0
  3. package/compose/build.gradle.kts +12 -8
  4. package/compose/build.gradle.kts.backup +15 -11
  5. package/compose/compose.podspec +1 -1
  6. package/compose/src/commonMain/kotlin/vn/momo/kits/application/AnimationSearchInput.kt +2 -7
  7. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Context.kt +6 -10
  8. package/compose/src/commonMain/kotlin/vn/momo/kits/application/FloatingButton.kt +6 -24
  9. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Header.kt +4 -19
  10. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderAnimated.kt +1 -10
  11. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderBackground.kt +2 -2
  12. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderDefault.kt +1 -1
  13. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderExtended.kt +1 -1
  14. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderRight.kt +6 -17
  15. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderTitle.kt +1 -1
  16. package/compose/src/commonMain/kotlin/vn/momo/kits/application/LiteScreen.kt +6 -101
  17. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Localize.kt +269 -0
  18. package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +5 -19
  19. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +8 -33
  20. package/compose/src/commonMain/kotlin/vn/momo/kits/application/useHeaderSearchAnimation.kt +1 -1
  21. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Badge.kt +22 -25
  22. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeRibbon.kt +27 -29
  23. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BaselineView.kt +3 -26
  24. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +30 -31
  25. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Carousel.kt +3 -13
  26. package/compose/src/commonMain/kotlin/vn/momo/kits/components/CheckBox.kt +0 -5
  27. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Chip.kt +3 -11
  28. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Collapse.kt +3 -18
  29. package/compose/src/commonMain/kotlin/vn/momo/kits/components/CupertinoOverscroll.kt +11 -11
  30. package/compose/src/commonMain/kotlin/vn/momo/kits/components/IconButton.kt +3 -11
  31. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Image.kt +69 -26
  32. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Information.kt +1 -5
  33. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +84 -59
  34. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputDropDown.kt +13 -71
  35. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputMoney.kt +10 -51
  36. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputOTP.kt +6 -1
  37. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputPhoneNumber.kt +4 -21
  38. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +1 -1
  39. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +16 -75
  40. package/compose/src/commonMain/kotlin/vn/momo/kits/components/LazyColumnWithBouncing.kt +5 -26
  41. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationDot.kt +1 -1
  42. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationScroll.kt +3 -11
  43. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +16 -40
  44. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupPromotion.kt +3 -9
  45. package/compose/src/commonMain/kotlin/vn/momo/kits/components/ProgressInfo.kt +0 -28
  46. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Radio.kt +2 -13
  47. package/compose/src/commonMain/kotlin/vn/momo/kits/components/ScaleSizeScope.kt +17 -0
  48. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Skeleton.kt +4 -10
  49. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Slider.kt +3 -28
  50. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Stepper.kt +8 -47
  51. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Steps.kt +4 -25
  52. package/compose/src/commonMain/kotlin/vn/momo/kits/components/SuggestAction.kt +2 -11
  53. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Swipe.kt +1 -17
  54. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Switch.kt +1 -6
  55. package/compose/src/commonMain/kotlin/vn/momo/kits/components/TabView.kt +50 -111
  56. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tag.kt +1 -5
  57. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +1 -5
  58. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Title.kt +1 -12
  59. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tooltip.kt +4 -96
  60. package/compose/src/commonMain/kotlin/vn/momo/kits/components/TrustBanner.kt +5 -7
  61. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Uploader.kt +2 -12
  62. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePicker.kt +9 -21
  63. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerTypes.kt +2 -2
  64. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerUtils.kt +9 -14
  65. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/WheelPicker.kt +8 -11
  66. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Theme.kt +1 -1
  67. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +7 -27
  68. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Item.kt +1 -1
  69. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/AutomationId.kt +0 -5
  70. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Clickable.kt +0 -2
  71. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/DeprecatedModifier.kt +94 -4
  72. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Shadow.kt +0 -2
  73. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/BottomSheet.kt +2 -2
  74. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ModalScreen.kt +3 -7
  75. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigation.kt +12 -16
  76. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +33 -27
  77. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigator.kt +48 -33
  78. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +91 -63
  79. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTab.kt +9 -14
  80. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +13 -31
  81. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/CurvedContainer.kt +1 -1
  82. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/FloatingButton.kt +6 -24
  83. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +11 -6
  84. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderBackground.kt +2 -1
  85. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderRight.kt +9 -6
  86. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderTitle.kt +1 -1
  87. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderUser.kt +3 -13
  88. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SnackBar.kt +3 -2
  89. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/tracking/ScreenTracker.kt +1 -40
  90. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/ComposeLottieAnimation.kt +0 -2
  91. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +0 -8
  92. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Resources.kt +2 -17
  93. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Tracking.kt +1 -1
  94. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Utils.kt +3 -3
  95. package/compose/src/iosMain/kotlin/vn/momo/kits/navigation/ScrollToTop.ios.kt +2 -3
  96. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +0 -2
  97. package/gradle/libs.versions.toml +2 -0
  98. package/gradle.properties +1 -1
  99. package/ios/Application/Components.swift +1 -0
  100. package/ios/Application/FloatingButton.swift +1 -0
  101. package/ios/Badge/Badge.swift +1 -0
  102. package/ios/Badge/BadgeRibbon.swift +2 -0
  103. package/ios/Button/Button.swift +1 -1
  104. package/ios/Checkbox/Checkbox.swift +1 -0
  105. package/ios/Information/Information.swift +151 -0
  106. package/ios/Input/Input.swift +1 -0
  107. package/ios/Input/InputPhoneNumber.swift +1 -0
  108. package/ios/Input/InputSearch.swift +3 -0
  109. package/ios/Input/InputTextArea.swift +1 -0
  110. package/ios/OTPKeyboard/KeyboardButton.swift +1 -1
  111. package/ios/Popup/PopupDisplay.swift +6 -0
  112. package/ios/Popup/PopupInput.swift +2 -0
  113. package/ios/Template/TrustBanner/TrustBanner.swift +2 -0
  114. package/ios/Typography/Text.swift +1 -0
  115. package/ios/Typography/Typography.swift +14 -5
  116. package/local.properties +2 -2
  117. package/package.json +1 -1
  118. package/compose/src/commonMain/kotlin/vn/momo/kits/application/FontScaleStore.kt +0 -77
  119. package/example/ios/Example.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/Example.xcscheme +0 -32
  120. package/example/ios/Example.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
  121. package/example/ios/Example.xcworkspace/xcuserdata/sonnguyen.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  122. package/example/ios/Example.xcworkspace/xcuserdata/sonnguyen.xcuserdatad/WorkspaceSettings.xcsettings +0 -16
  123. package/example/ios/Example.xcworkspace/xcuserdata/sonnguyen.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +0 -6
  124. package/example/ios/Example.xcworkspace/xcuserdata/sonnguyen.xcuserdatad/xcschemes/xcschememanagement.plist +0 -5
  125. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/MoMoUIKits.xcscheme +0 -58
  126. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/Pods-Example.xcscheme +0 -58
  127. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/SDWebImage.xcscheme +0 -58
  128. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/SDWebImageSwiftUI.xcscheme +0 -58
  129. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/SkeletonUI.xcscheme +0 -58
  130. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/lottie-ios-LottiePrivacyInfo.xcscheme +0 -58
  131. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/lottie-ios.xcscheme +0 -58
  132. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/xcschememanagement.plist +0 -60
@@ -5,28 +5,9 @@ import androidx.compose.foundation.background
5
5
  import androidx.compose.foundation.border
6
6
  import androidx.compose.foundation.clickable
7
7
  import androidx.compose.foundation.interaction.MutableInteractionSource
8
- import androidx.compose.foundation.layout.Arrangement
9
- import androidx.compose.foundation.layout.Box
10
- import androidx.compose.foundation.layout.Column
11
- import androidx.compose.foundation.layout.IntrinsicSize
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.height
16
- import androidx.compose.foundation.layout.offset
17
- import androidx.compose.foundation.layout.padding
18
- import androidx.compose.foundation.layout.size
19
- import androidx.compose.foundation.layout.width
20
- import androidx.compose.foundation.layout.widthIn
21
- import androidx.compose.foundation.layout.wrapContentSize
8
+ import androidx.compose.foundation.layout.*
22
9
  import androidx.compose.foundation.shape.RoundedCornerShape
23
- import androidx.compose.runtime.Composable
24
- import androidx.compose.runtime.LaunchedEffect
25
- import androidx.compose.runtime.Stable
26
- import androidx.compose.runtime.getValue
27
- import androidx.compose.runtime.mutableStateOf
28
- import androidx.compose.runtime.remember
29
- import androidx.compose.runtime.setValue
10
+ import androidx.compose.runtime.*
30
11
  import androidx.compose.ui.Alignment
31
12
  import androidx.compose.ui.Modifier
32
13
  import androidx.compose.ui.draw.clip
@@ -36,63 +17,32 @@ import androidx.compose.ui.graphics.PathEffect
36
17
  import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
37
18
  import androidx.compose.ui.platform.LocalDensity
38
19
  import androidx.compose.ui.text.style.TextOverflow
39
- import androidx.compose.ui.unit.IntOffset
40
- import androidx.compose.ui.unit.IntRect
41
- import androidx.compose.ui.unit.IntSize
42
- import androidx.compose.ui.unit.LayoutDirection
43
- import androidx.compose.ui.unit.dp
20
+ import androidx.compose.ui.unit.*
44
21
  import androidx.compose.ui.window.Popup
45
22
  import androidx.compose.ui.window.PopupPositionProvider
46
23
  import androidx.compose.ui.window.PopupProperties
47
24
  import vn.momo.kits.application.IsShowBaseLineDebug
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.scaleSize
25
+ import vn.momo.kits.const.*
53
26
  import vn.momo.kits.modifier.activeOpacityClickable
54
27
  import vn.momo.kits.modifier.conditional
55
28
 
56
29
 
57
- // region Types
58
-
59
- /**
60
- * Tooltip placement relative to the anchor element.
61
- */
62
30
  enum class TooltipPlacement {
63
31
  TOP,
64
32
  BOTTOM,
65
33
  LEFT,
66
34
  RIGHT,
67
35
  }
68
-
69
- /**
70
- * Cross-axis alignment of the tooltip relative to the anchor.
71
- */
72
36
  enum class TooltipAlign {
73
37
  START,
74
38
  CENTER,
75
39
  END,
76
40
  }
77
-
78
- /**
79
- * Describes a single action button displayed in the tooltip.
80
- *
81
- * @param title Text label for the button (used for text buttons).
82
- * @param icon Icon source for the button (used for icon buttons).
83
- * @param onPress Callback invoked when the button is pressed.
84
- */
85
41
  data class TooltipButton(
86
42
  val title: String? = null,
87
43
  val icon: String? = null,
88
44
  val onPress: (() -> Unit)? = null,
89
45
  )
90
-
91
-
92
- /**
93
- * State holder for controlling tooltip visibility imperatively.
94
- * Equivalent to the React Native `useImperativeHandle` ref pattern.
95
- */
96
46
  @Stable
97
47
  class TooltipState {
98
48
  var isVisible by mutableStateOf(false)
@@ -113,30 +63,12 @@ class TooltipState {
113
63
  isVisible = !isVisible
114
64
  }
115
65
  }
116
-
117
- /**
118
- * Creates and remembers a [TooltipState].
119
- */
120
66
  @Composable
121
67
  fun rememberTooltipState(): TooltipState {
122
68
  return remember { TooltipState() }
123
69
  }
124
70
  private val TOOLTIP_OFFSET = Spacing.S
125
71
  private val ARROW_SIZE = 6.dp
126
- /**
127
- * Custom [PopupPositionProvider] that positions the tooltip relative to the anchor.
128
- *
129
- * Mirrors the React Native `placementStyle` calculation:
130
- * - TOP: tooltip bottom edge sits at `anchorTop - TOOLTIP_OFFSET`
131
- * - BOTTOM: tooltip top edge sits at `anchorBottom + TOOLTIP_OFFSET`
132
- * - LEFT: tooltip right edge sits at `anchorLeft - TOOLTIP_OFFSET`
133
- * - RIGHT: tooltip left edge sits at `anchorRight + TOOLTIP_OFFSET`
134
- *
135
- * Cross-axis alignment:
136
- * - start: tooltip aligns to anchor start edge
137
- * - center: tooltip centers on anchor
138
- * - end: tooltip aligns to anchor end edge
139
- */
140
72
  private class TooltipPositionProvider(
141
73
  private val placement: TooltipPlacement,
142
74
  private val align: TooltipAlign,
@@ -199,27 +131,6 @@ private class TooltipPositionProvider(
199
131
  }
200
132
  }
201
133
 
202
- // endregion
203
-
204
- // region Tooltip Composable
205
-
206
- /**
207
- * A tooltip component that wraps [content] (the anchor) and shows a positioned
208
- * tooltip popup with title, description, close button, and action buttons.
209
- *
210
- * Port of the React Native `Tooltip` component.
211
- *
212
- * @param state Controls visibility (use [rememberTooltipState]).
213
- * @param title Title text displayed in the tooltip header.
214
- * @param description Description text shown under the title.
215
- * @param buttons Action buttons rendered at the bottom.
216
- * @param placement Tooltip position relative to the anchor (default TOP).
217
- * @param align Cross-axis alignment (default CENTER).
218
- * @param onVisibleChange Callback when visibility changes.
219
- * @param onPressClose Callback when the close button (X) is pressed.
220
- * @param modifier Modifier for the anchor wrapper.
221
- * @param content The anchor element that the tooltip is attached to.
222
- */
223
134
  @Composable
224
135
  fun Tooltip(
225
136
  state: TooltipState,
@@ -525,9 +436,6 @@ private fun TooltipSingleButton(btn: TooltipButton) {
525
436
  )
526
437
  }
527
438
  }
528
-
529
- private const val MAX_BUTTON_LENGTH = 16
530
-
531
439
  private fun String.limitWithEllipsis(max: Int = 16): String {
532
440
  return if (length > max) take(max) + "…" else this
533
441
  }
@@ -18,8 +18,7 @@ import androidx.compose.ui.draw.clip
18
18
  import androidx.compose.ui.graphics.Color
19
19
  import androidx.compose.ui.layout.ContentScale
20
20
  import androidx.compose.ui.unit.dp
21
- import vn.momo.kits.application.AppConfig
22
- import vn.momo.kits.application.AppLanguage
21
+ import vn.momo.kits.application.LocalLocalize
23
22
  import vn.momo.kits.application.IsShowBaseLineDebug
24
23
  import vn.momo.kits.const.Colors
25
24
  import vn.momo.kits.const.Typography
@@ -68,9 +67,8 @@ fun TrustBanner(
68
67
  onPress: ((Map<String, String>) -> Unit)? = null,
69
68
  trackEvent: ((String, Map<String, String>) -> Unit)? = null
70
69
  ) {
71
- val appConfig = AppConfig.current
72
- val language = AppLanguage.current ?: "vi"
73
- val trustBanner = appConfig?.trustBanner ?: defaultBanner
70
+ val localize = LocalLocalize.current
71
+ val trustBanner = defaultBanner
74
72
  val trackParams = mapOf(
75
73
  "service_name" to serviceName,
76
74
  "screen_name" to screenName,
@@ -124,7 +122,7 @@ fun TrustBanner(
124
122
  .padding(start = 10.dp)
125
123
  ) {
126
124
  Text(
127
- text = trustBanner.content[language] ?: "",
125
+ text = localize.translateData(trustBanner.content),
128
126
  modifier = Modifier.padding(bottom = 8.dp),
129
127
  color = Color(contentColor),
130
128
  style = Typography.descriptionDefaultRegular,
@@ -138,7 +136,7 @@ fun TrustBanner(
138
136
  verticalAlignment = Alignment.CenterVertically,
139
137
  ) {
140
138
  Text(
141
- text = trustBanner.subContent[language] ?: "",
139
+ text = localize.translateData(trustBanner.subContent),
142
140
  color = Color(subContentColor),
143
141
  style = Typography.actionXsBold,
144
142
  maxLines = 2
@@ -3,13 +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.horizontalScroll
6
- import androidx.compose.foundation.layout.Arrangement
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.fillMaxSize
11
- import androidx.compose.foundation.layout.padding
12
- import androidx.compose.foundation.layout.size
6
+ import androidx.compose.foundation.layout.*
13
7
  import androidx.compose.foundation.rememberScrollState
14
8
  import androidx.compose.foundation.shape.RoundedCornerShape
15
9
  import androidx.compose.runtime.Composable
@@ -25,11 +19,7 @@ import androidx.compose.ui.graphics.drawscope.Stroke
25
19
  import androidx.compose.ui.unit.Dp
26
20
  import androidx.compose.ui.unit.dp
27
21
  import vn.momo.kits.application.IsShowBaseLineDebug
28
- import vn.momo.kits.const.AppTheme
29
- import vn.momo.kits.const.Colors
30
- import vn.momo.kits.const.Radius
31
- import vn.momo.kits.const.Spacing
32
- import vn.momo.kits.const.Typography
22
+ import vn.momo.kits.const.*
33
23
  import vn.momo.kits.modifier.activeOpacityClickable
34
24
  import vn.momo.kits.modifier.conditional
35
25
 
@@ -2,20 +2,8 @@ package vn.momo.kits.components.datetimepicker
2
2
 
3
3
  import androidx.compose.foundation.background
4
4
  import androidx.compose.foundation.border
5
- import androidx.compose.foundation.layout.Column
6
- import androidx.compose.foundation.layout.Row
7
- import androidx.compose.foundation.layout.Spacer
8
- import androidx.compose.foundation.layout.fillMaxWidth
9
- import androidx.compose.foundation.layout.height
10
- import androidx.compose.foundation.layout.padding
11
- import androidx.compose.foundation.layout.width
12
- import androidx.compose.runtime.Composable
13
- import androidx.compose.runtime.LaunchedEffect
14
- import androidx.compose.runtime.getValue
15
- import androidx.compose.runtime.mutableStateOf
16
- import androidx.compose.runtime.remember
17
- import androidx.compose.runtime.setValue
18
- import androidx.compose.runtime.snapshotFlow
5
+ import androidx.compose.foundation.layout.*
6
+ import androidx.compose.runtime.*
19
7
  import androidx.compose.ui.Alignment
20
8
  import androidx.compose.ui.Modifier
21
9
  import androidx.compose.ui.unit.dp
@@ -74,7 +62,7 @@ fun DateTimePicker(
74
62
  var currentDate by remember(initialValue) {
75
63
  mutableStateOf(
76
64
  PickerData(
77
- day = initialValue.dayOfMonth,
65
+ day = initialValue.day,
78
66
  month = initialValue.month.number,
79
67
  year = initialValue.year,
80
68
  hour = initialValue.hour,
@@ -95,10 +83,10 @@ fun DateTimePicker(
95
83
  month = when (year) {
96
84
  effectiveMaxDate.year -> month.coerceIn(
97
85
  1,
98
- effectiveMaxDate.monthNumber
86
+ effectiveMaxDate.month.number
99
87
  )
100
88
  effectiveMinDate.year -> month.coerceIn(
101
- effectiveMinDate.monthNumber,
89
+ effectiveMinDate.month.number,
102
90
  12,
103
91
  )
104
92
  else -> month
@@ -112,11 +100,11 @@ fun DateTimePicker(
112
100
  }
113
101
 
114
102
  day = when {
115
- year == effectiveMaxDate.year && month == effectiveMaxDate.monthNumber ->
116
- day.coerceIn(1, effectiveMaxDate.dayOfMonth)
103
+ year == effectiveMaxDate.year && month == effectiveMaxDate.month.number ->
104
+ day.coerceIn(1, effectiveMaxDate.day)
117
105
 
118
- year == effectiveMinDate.year && month == effectiveMinDate.monthNumber ->
119
- day.coerceIn(effectiveMinDate.dayOfMonth, maxDayOfMonth)
106
+ year == effectiveMinDate.year && month == effectiveMinDate.month.number ->
107
+ day.coerceIn(effectiveMinDate.day, maxDayOfMonth)
120
108
 
121
109
  day > maxDayOfMonth -> maxDayOfMonth
122
110
  else -> day
@@ -13,8 +13,8 @@ data class PickerData(
13
13
  fun toLocalDateTime(): LocalDateTime {
14
14
  return LocalDateTime(
15
15
  year = year,
16
- monthNumber = month,
17
- dayOfMonth = day,
16
+ month = month,
17
+ day = day,
18
18
  hour = hour,
19
19
  minute = minute,
20
20
  second = 0,
@@ -2,15 +2,10 @@ package vn.momo.kits.components.datetimepicker
2
2
 
3
3
  import androidx.compose.runtime.Composable
4
4
  import androidx.compose.runtime.remember
5
+ import kotlinx.datetime.*
6
+ import kotlinx.datetime.number
5
7
  import kotlin.time.Clock
6
8
  import kotlin.time.ExperimentalTime
7
- import kotlinx.datetime.DatePeriod
8
- import kotlinx.datetime.LocalDateTime
9
- import kotlinx.datetime.TimeZone
10
- import kotlinx.datetime.minus
11
- import kotlinx.datetime.number
12
- import kotlinx.datetime.plus
13
- import kotlinx.datetime.toLocalDateTime
14
9
 
15
10
  /**
16
11
  * Format a LocalDateTime object into a string
@@ -19,13 +14,13 @@ fun formatLocalDateTime(dateTime: LocalDateTime, format: String = "yyyy-MM-dd HH
19
14
  return when (format) {
20
15
  "yyyy-MM-dd HH:mm" -> "${dateTime.year}-${paddingNum(dateTime.month.number)}-${
21
16
  paddingNum(
22
- dateTime.dayOfMonth
17
+ dateTime.day
23
18
  )
24
19
  } ${paddingNum(dateTime.hour)}:${paddingNum(dateTime.minute)}"
25
20
 
26
- "dd-MM-yyyy" -> "${paddingNum(dateTime.dayOfMonth)}-${paddingNum(dateTime.month.number)}-${dateTime.year}"
21
+ "dd-MM-yyyy" -> "${paddingNum(dateTime.day)}-${paddingNum(dateTime.month.number)}-${dateTime.year}"
27
22
  "HH:mm" -> "${paddingNum(dateTime.hour)}:${paddingNum(dateTime.minute)}"
28
- else -> "${dateTime.year}-${paddingNum(dateTime.month.number)}-${paddingNum(dateTime.dayOfMonth)} ${
23
+ else -> "${dateTime.year}-${paddingNum(dateTime.month.number)}-${paddingNum(dateTime.day)} ${
29
24
  paddingNum(
30
25
  dateTime.hour
31
26
  )
@@ -60,11 +55,11 @@ fun getDaysInMonth(
60
55
  var endDay = daysInMonth
61
56
 
62
57
  if (year == minDate.year && month == minDate.month.number) {
63
- startDay = minDate.dayOfMonth
58
+ startDay = minDate.day
64
59
  }
65
60
 
66
61
  if (year == maxDate.year && month == maxDate.month.number) {
67
- endDay = maxDate.dayOfMonth
62
+ endDay = maxDate.day
68
63
  }
69
64
 
70
65
  val days = mutableListOf<String>()
@@ -170,8 +165,8 @@ fun createRelativeDate(years: Int): LocalDateTime {
170
165
 
171
166
  return LocalDateTime(
172
167
  adjustedDate.year,
173
- adjustedDate.monthNumber,
174
- adjustedDate.dayOfMonth,
168
+ adjustedDate.month.number,
169
+ adjustedDate.day,
175
170
  currentDateTime.hour,
176
171
  currentDateTime.minute
177
172
  )
@@ -10,13 +10,7 @@ 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.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
13
+ import androidx.compose.runtime.*
20
14
  import androidx.compose.ui.Alignment
21
15
  import androidx.compose.ui.Modifier
22
16
  import androidx.compose.ui.draw.alpha
@@ -25,6 +19,7 @@ import androidx.compose.ui.platform.LocalDensity
25
19
  import androidx.compose.ui.unit.Dp
26
20
  import androidx.compose.ui.unit.dp
27
21
  import androidx.compose.ui.zIndex
22
+ import kotlinx.coroutines.FlowPreview
28
23
  import kotlinx.coroutines.delay
29
24
  import kotlinx.coroutines.flow.collect
30
25
  import kotlinx.coroutines.flow.debounce
@@ -36,12 +31,14 @@ import vn.momo.kits.const.Colors
36
31
  import vn.momo.kits.const.Radius
37
32
  import vn.momo.kits.const.Typography
38
33
  import kotlin.math.abs
34
+ import kotlin.time.Duration.Companion.milliseconds
39
35
 
40
36
  private val wheelItemHeight = 42.dp
41
37
  private val wheelPickerBorderWidth = 1.dp
42
38
 
39
+ @OptIn(FlowPreview::class)
43
40
  @Composable
44
- fun WheelPicker(
41
+ internal fun WheelPicker(
45
42
  name: String,
46
43
  data: List<String>,
47
44
  selectedData: String,
@@ -68,7 +65,7 @@ fun WheelPicker(
68
65
  LaunchedEffect(paddedData) {
69
66
  snapshotFlow { selectedIndex }
70
67
  .distinctUntilChanged()
71
- .debounce(50)
68
+ .debounce(50.milliseconds)
72
69
  .onEach {
73
70
  val value = paddedData.getOrNull(it)
74
71
  if (!value.isNullOrEmpty()) {
@@ -95,7 +92,7 @@ fun WheelPicker(
95
92
  } else {
96
93
  -abs(firstItemOffset)
97
94
  }
98
- delay(50)
95
+ delay(50.milliseconds)
99
96
  listState.animateScrollBy(offset.toFloat())
100
97
  val centeredIndex = firstItemIdx + (if (isScrollUp) 1 else 0) + 2
101
98
  if (centeredIndex in 2 until paddedData.size - 2) {
@@ -145,7 +142,7 @@ fun WheelPicker(
145
142
  }
146
143
 
147
144
  @Composable
148
- fun WheelPickerItem(
145
+ internal fun WheelPickerItem(
149
146
  text: String,
150
147
  isSelected: Boolean,
151
148
  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 != null && assets.headerBackground.isNotEmpty()
67
+ return !assets.headerBackground.isNullOrEmpty()
68
68
  }
69
69
  }
70
70
  val defaultTheme = Theme(
@@ -7,28 +7,13 @@ 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.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
10
+ import androidx.compose.ui.unit.*
15
11
  import org.jetbrains.compose.resources.Font
16
12
  import org.jetbrains.compose.resources.FontResource
17
13
  import org.jetbrains.compose.resources.InternalResourceApi
18
- import vn.momo.kits.application.FontScaleStore
14
+ import vn.momo.kits.application.ScaleSizeMaxRate
19
15
  import vn.momo.kits.platform.getScreenDimensions
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
16
+ import vn.momo.uikits.resources.*
32
17
  import kotlin.math.max
33
18
  import kotlin.math.min
34
19
 
@@ -38,8 +23,7 @@ const val MAX_DEVICE_SCALE = 5
38
23
 
39
24
  @Composable
40
25
  fun scaleSize(size: Float): Float {
41
- val useDeviceFontScale = FontScaleStore.useDeviceFontScale
42
- val appFontScale = FontScaleStore.appFontScale
26
+ val scaleSizeMaxRate: Float = ScaleSizeMaxRate.current ?: MAX_FONT_SCALE
43
27
  val deviceWidth = getScreenDimensions().width
44
28
  val deviceScale = deviceWidth / DEFAULT_SCREEN_SIZE
45
29
 
@@ -54,12 +38,8 @@ fun scaleSize(size: Float): Float {
54
38
  min(deviceScale * fontSizeScaleDevice, fontSizeScaleDevice + MAX_DEVICE_SCALE)
55
39
  }
56
40
 
57
- if (useDeviceFontScale) {
58
- if (fontScale > 1) {
59
- fontSizeScaleOS = min(fontScale * fontSizeScaleOS, fontSizeScaleOS * MAX_FONT_SCALE)
60
- }
61
- } else {
62
- fontSizeScaleOS = size * appFontScale
41
+ if (fontScale > 1) {
42
+ fontSizeScaleOS = min(fontScale * fontSizeScaleOS, fontSizeScaleOS * scaleSizeMaxRate)
63
43
  }
64
44
 
65
45
  return max(
@@ -103,7 +83,7 @@ fun scaleSize(textStyle: TextStyle): TextStyle {
103
83
 
104
84
  @OptIn(InternalResourceApi::class)
105
85
  @Composable
106
- fun getFont(font: FontResource): FontFamily {
86
+ internal fun getFont(font: FontResource): FontFamily {
107
87
  return FontFamily(Font(font))
108
88
  }
109
89
 
@@ -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,11 +20,6 @@ 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
- * */
28
23
  fun Modifier.kitsAutomationId(accessibilityId: String, label: String? = null) =
29
24
  this then KitsAutomationIdElement(accessibilityId, label)
30
25
 
@@ -53,8 +53,6 @@ fun Modifier.activeOpacityClickable(
53
53
  onClick
54
54
  )
55
55
  }
56
-
57
-
58
56
  fun Modifier.hideKeyboardOnTap() = composed {
59
57
  val focusManager = LocalFocusManager.current
60
58
  val keyboardManager = LocalSoftwareKeyboardController.current
@@ -1,14 +1,104 @@
1
1
  package vn.momo.kits.modifier
2
2
 
3
- import androidx.compose.foundation.background
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
4
9
  import androidx.compose.runtime.Composable
10
+ import androidx.compose.runtime.getValue
5
11
  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
6
21
  import vn.momo.kits.application.IsShowBaseLineDebug
7
22
  import vn.momo.kits.const.Colors
8
23
 
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
+
9
45
  @Composable
10
- fun DeprecatedModifier(): Modifier {
11
- return Modifier.conditional(IsShowBaseLineDebug) {
12
- background(Colors.red_01.copy(alpha = 0.5f))
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
+ }
13
103
  }
14
104
  }
@@ -9,8 +9,6 @@ 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
-
14
12
  fun Modifier.shadow(
15
13
  color: Color = Color.Black,
16
14
  borderRadius: Dp = 0.dp,
@@ -41,7 +41,7 @@ import vn.momo.kits.const.AppTheme
41
41
  import vn.momo.kits.const.Colors
42
42
  import vn.momo.kits.const.Radius
43
43
  import vn.momo.kits.const.Spacing
44
- import vn.momo.kits.application.ApplicationContext
44
+ import vn.momo.kits.application.LocalContext
45
45
  import vn.momo.kits.application.IsShowBaseLineDebug
46
46
  import vn.momo.kits.const.Typography
47
47
  import vn.momo.kits.navigation.tracking.ScreenTracker
@@ -73,7 +73,7 @@ internal fun BottomSheet(
73
73
  val coroutineScope = rememberCoroutineScope()
74
74
 
75
75
  val maxApi = LocalMaxApi.current
76
- val context = ApplicationContext.current
76
+ val context = LocalContext.current
77
77
 
78
78
  DisposableEffect(Unit) {
79
79
  ScreenTracker.trackPopupDisplayed(