@momo-kits/native-kits 0.167.1-duo.1-debug → 0.167.1-duo.10

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 (260) hide show
  1. package/CLAUDE.md +32 -0
  2. package/ios/Application/ApplicationEnvironment.swift +17 -0
  3. package/ios/Application/ComposeApi.swift +2 -1
  4. package/ios/Application/{Components.swift → LegacyHeader.swift} +7 -65
  5. package/ios/Application/Screen.swift +3 -2
  6. package/ios/Avatar/Avatar.swift +4 -3
  7. package/ios/Badge/Badge.swift +6 -4
  8. package/ios/Badge/BadgeDot.swift +1 -1
  9. package/ios/Badge/BadgeRibbon.swift +0 -1
  10. package/ios/Button/Button.swift +15 -12
  11. package/ios/CalculatorKeyboard/CalculatorKeyboard.swift +64 -18
  12. package/ios/Carousel/Carousel.swift +29 -12
  13. package/ios/Checkbox/Checkbox.swift +7 -3
  14. package/ios/Chip/Chip.swift +5 -4
  15. package/ios/Collapse/Collapse.swift +70 -19
  16. package/ios/Colors+Radius+Spacing/Colors.swift +10 -1
  17. package/ios/DateTimePicker/DateTimePicker.swift +54 -20
  18. package/ios/DateTimePicker/WheelPicker.swift +103 -105
  19. package/ios/Divider/Divider.swift +37 -4
  20. package/ios/Extensions/Color++.swift +38 -9
  21. package/ios/Extensions/OptionalEnvironmentObject.swift +12 -0
  22. package/ios/Extensions/SkeletonUICompat.swift +11 -0
  23. package/ios/Icon/Icon.swift +21 -23
  24. package/ios/Icon/Icons.swift +1329 -0
  25. package/ios/IconButton/IconButton.swift +15 -7
  26. package/ios/Image/Image.swift +7 -23
  27. package/ios/Information/Information.swift +27 -9
  28. package/ios/Input/ErrorView.swift +2 -2
  29. package/ios/Input/Input.swift +160 -147
  30. package/ios/Input/InputPhoneNumber.swift +12 -9
  31. package/ios/Input/InputSearch.swift +102 -75
  32. package/ios/Input/InputTextArea.swift +128 -145
  33. package/ios/InputDropDown/InputDropDown.swift +10 -7
  34. package/ios/InputMoney/InputMoney.swift +33 -11
  35. package/ios/InputOTP/InputOTP.swift +22 -12
  36. package/ios/Layout/Card.swift +50 -0
  37. package/ios/Layout/GridContext.swift +123 -3
  38. package/ios/Layout/Item.swift +5 -4
  39. package/ios/Layout/ScreenLayout.swift +312 -0
  40. package/ios/Layout/Section.swift +4 -100
  41. package/ios/Loader/Loader.swift +5 -9
  42. package/ios/Lottie/LottieView.swift +14 -2
  43. package/ios/{Application/Navigation/Overplay → Navigation}/BottomSheet.swift +97 -8
  44. package/ios/Navigation/BottomTab/BottomTab.swift +187 -0
  45. package/ios/{Application/Navigation → Navigation}/BottomTab/BottomTabBar.swift +15 -7
  46. package/ios/Navigation/BottomTab/DuoBarCompression.swift +105 -0
  47. package/ios/Navigation/BottomTab/DuoTabBar.swift +304 -0
  48. package/ios/{Application → Navigation/Component}/FloatingButton.swift +14 -3
  49. package/ios/Navigation/Component/Header.swift +493 -0
  50. package/ios/Navigation/Component/HeaderBackground.swift +134 -0
  51. package/ios/Navigation/Component/HeaderJourney.swift +73 -0
  52. package/ios/Navigation/Component/HeaderLocation.swift +48 -0
  53. package/ios/Navigation/Component/HeaderRight.swift +386 -0
  54. package/ios/Navigation/Component/HeaderTitle.swift +36 -0
  55. package/ios/{Application/Navigation → Navigation/Component}/HeaderUser.swift +21 -24
  56. package/ios/Navigation/Component/SideBar.swift +176 -0
  57. package/ios/{Application/Navigation/Overplay → Navigation/Component}/SnackBar.swift +5 -5
  58. package/ios/Navigation/HostBackGestureBridge.swift +57 -0
  59. package/ios/{Application/Navigation/Overplay → Navigation}/ModalScreen.swift +5 -1
  60. package/ios/Navigation/Navigation.swift +190 -0
  61. package/ios/{Application/Navigation → Navigation}/NavigationContainer.swift +92 -81
  62. package/ios/{Application/Navigation → Navigation}/Navigator.swift +185 -36
  63. package/ios/Navigation/StackScreen.swift +782 -0
  64. package/ios/{Application/Navigation → Navigation}/Tracking/ScreenTracker.swift +12 -5
  65. package/ios/OTPKeyboard/OTPKeyboard.swift +8 -11
  66. package/ios/Pagination/PaginationScroll.swift +2 -2
  67. package/ios/Popup/PopupDisplay.swift +72 -136
  68. package/ios/Popup/PopupInput.swift +10 -13
  69. package/ios/Popup/PopupLayout.swift +140 -0
  70. package/ios/Popup/PopupNotify.swift +56 -73
  71. package/ios/Popup/PopupPromotion.swift +31 -47
  72. package/ios/PopupView/FullscreenPopup.swift +13 -19
  73. package/ios/PopupView/PopupView.swift +1 -1
  74. package/ios/PopupView/Utils++.swift +0 -8
  75. package/ios/ProgressInfo/ProgressInfo.swift +4 -2
  76. package/ios/Radio/Radio.swift +2 -1
  77. package/ios/Rating/Rating.swift +9 -1
  78. package/ios/Resources/dot_loading.json +558 -0
  79. package/ios/Resources/lottie_circle_loader.json +1 -0
  80. package/ios/ScrollIndicator/ScrollIndicator.swift +11 -10
  81. package/ios/Skeleton/Skeleton.swift +22 -27
  82. package/ios/Slider/Slider.swift +16 -18
  83. package/ios/Stepper/Stepper.swift +6 -1
  84. package/ios/Steps/Steps.swift +8 -6
  85. package/ios/SuggestAction/SuggestAction.swift +5 -0
  86. package/ios/Swipeable/SwipeCell.swift +10 -6
  87. package/ios/Switch/Switch.swift +22 -20
  88. package/ios/TabView/TabView.swift +102 -21
  89. package/ios/Tag/Tag.swift +15 -4
  90. package/ios/Template/Logo/Logo.swift +2 -1
  91. package/ios/Template/TrustBanner/TrustBanner.swift +106 -54
  92. package/ios/Title/Title.swift +6 -17
  93. package/ios/Tooltip/Tooltip.swift +29 -14
  94. package/ios/Typography/Text.swift +61 -19
  95. package/ios/Uploader/Uploader.swift +3 -1
  96. package/ios/native-kits.podspec +2 -1
  97. package/ios-demo/MoMoUIKitsDemo.podspec +1 -1
  98. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ContentView.swift +1 -1
  99. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DuoTabDemo.swift +80 -0
  100. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/Home.swift +1 -0
  101. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/IPhoneDuoDemo.swift +173 -0
  102. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/NavigationDemo.swift +77 -1
  103. package/package.json +1 -1
  104. package/scripts/gen-ios-icons.mjs +36 -0
  105. package/.claude/settings.local.json +0 -185
  106. package/build.gradle.kts +0 -11
  107. package/compose/build.gradle.kts +0 -190
  108. package/compose/build.gradle.kts.backup +0 -190
  109. package/compose/compose.podspec +0 -47
  110. package/compose/src/androidMain/kotlin/vn/momo/kits/const/HostFont.android.kt +0 -19
  111. package/compose/src/androidMain/kotlin/vn/momo/kits/navigation/ScrollToTop.android.kt +0 -6
  112. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/BackGesture.android.kt +0 -12
  113. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/OsFontScale.android.kt +0 -7
  114. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/Platform.android.kt +0 -151
  115. package/compose/src/commonMain/kotlin/vn/momo/kits/application/AnimationSearchInput.kt +0 -52
  116. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Context.kt +0 -124
  117. package/compose/src/commonMain/kotlin/vn/momo/kits/application/FloatingButton.kt +0 -183
  118. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Header.kt +0 -207
  119. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderAnimated.kt +0 -39
  120. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderBackground.kt +0 -86
  121. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderDefault.kt +0 -76
  122. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderExtended.kt +0 -76
  123. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderRight.kt +0 -293
  124. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderTitle.kt +0 -33
  125. package/compose/src/commonMain/kotlin/vn/momo/kits/application/LiteScreen.kt +0 -831
  126. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Localize.kt +0 -269
  127. package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +0 -110
  128. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +0 -378
  129. package/compose/src/commonMain/kotlin/vn/momo/kits/application/WidgetContainer.kt +0 -56
  130. package/compose/src/commonMain/kotlin/vn/momo/kits/application/useHeaderSearchAnimation.kt +0 -69
  131. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Avatar.kt +0 -157
  132. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Badge.kt +0 -82
  133. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeDot.kt +0 -32
  134. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeRibbon.kt +0 -338
  135. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BaselineView.kt +0 -175
  136. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +0 -356
  137. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Carousel.kt +0 -113
  138. package/compose/src/commonMain/kotlin/vn/momo/kits/components/CheckBox.kt +0 -89
  139. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Chip.kt +0 -128
  140. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Collapse.kt +0 -209
  141. package/compose/src/commonMain/kotlin/vn/momo/kits/components/CupertinoOverscroll.kt +0 -542
  142. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Divider.kt +0 -49
  143. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Icon.kt +0 -76
  144. package/compose/src/commonMain/kotlin/vn/momo/kits/components/IconButton.kt +0 -125
  145. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Image.kt +0 -231
  146. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Information.kt +0 -189
  147. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +0 -475
  148. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputDropDown.kt +0 -114
  149. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputMoney.kt +0 -266
  150. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputOTP.kt +0 -240
  151. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputPhoneNumber.kt +0 -223
  152. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +0 -264
  153. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +0 -185
  154. package/compose/src/commonMain/kotlin/vn/momo/kits/components/LazyColumnWithBouncing.kt +0 -343
  155. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Loader.kt +0 -108
  156. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationDot.kt +0 -56
  157. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationNumber.kt +0 -41
  158. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationScroll.kt +0 -84
  159. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationWhiteDot.kt +0 -40
  160. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +0 -334
  161. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupPromotion.kt +0 -98
  162. package/compose/src/commonMain/kotlin/vn/momo/kits/components/ProgressInfo.kt +0 -310
  163. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Radio.kt +0 -59
  164. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Rating.kt +0 -87
  165. package/compose/src/commonMain/kotlin/vn/momo/kits/components/ScaleSizeScope.kt +0 -21
  166. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Skeleton.kt +0 -90
  167. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Slider.kt +0 -323
  168. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Stepper.kt +0 -220
  169. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Steps.kt +0 -473
  170. package/compose/src/commonMain/kotlin/vn/momo/kits/components/SuggestAction.kt +0 -122
  171. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Swipe.kt +0 -199
  172. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Switch.kt +0 -91
  173. package/compose/src/commonMain/kotlin/vn/momo/kits/components/TabView.kt +0 -552
  174. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tag.kt +0 -88
  175. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +0 -125
  176. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Title.kt +0 -207
  177. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tooltip.kt +0 -498
  178. package/compose/src/commonMain/kotlin/vn/momo/kits/components/TrustBanner.kt +0 -176
  179. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Uploader.kt +0 -182
  180. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePicker.kt +0 -193
  181. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerTypes.kt +0 -29
  182. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerUtils.kt +0 -234
  183. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/WheelPicker.kt +0 -188
  184. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Colors.kt +0 -325
  185. package/compose/src/commonMain/kotlin/vn/momo/kits/const/HostFont.kt +0 -16
  186. package/compose/src/commonMain/kotlin/vn/momo/kits/const/KitDesignSystem.kt +0 -18
  187. package/compose/src/commonMain/kotlin/vn/momo/kits/const/KitFontScale.kt +0 -22
  188. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Radius.kt +0 -12
  189. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Spacing.kt +0 -16
  190. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Theme.kt +0 -188
  191. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +0 -297
  192. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Card.kt +0 -52
  193. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Item.kt +0 -38
  194. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Section.kt +0 -39
  195. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/AutomationId.kt +0 -52
  196. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Clickable.kt +0 -66
  197. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Conditional.kt +0 -11
  198. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/DeprecatedModifier.kt +0 -104
  199. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Shadow.kt +0 -48
  200. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Size.kt +0 -51
  201. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/BottomSheet.kt +0 -299
  202. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/HostBackGestureBridge.kt +0 -58
  203. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ModalScreen.kt +0 -129
  204. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigation.kt +0 -106
  205. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +0 -201
  206. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigator.kt +0 -393
  207. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ScrollToTop.kt +0 -8
  208. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +0 -596
  209. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackTransition.kt +0 -148
  210. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/SwipeBackHaptic.kt +0 -35
  211. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTab.kt +0 -175
  212. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +0 -225
  213. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/CurvedContainer.kt +0 -86
  214. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/FloatingButton.kt +0 -169
  215. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +0 -360
  216. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderBackground.kt +0 -83
  217. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderJourney.kt +0 -106
  218. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderLocation.kt +0 -75
  219. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderRight.kt +0 -309
  220. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderTitle.kt +0 -37
  221. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderUser.kt +0 -364
  222. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SnackBar.kt +0 -132
  223. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/tracking/ScreenTracker.kt +0 -127
  224. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/BackGesture.kt +0 -12
  225. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/ComposeLottieAnimation.kt +0 -91
  226. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/OsFontScale.kt +0 -9
  227. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +0 -71
  228. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Icons.kt +0 -1329
  229. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Resources.kt +0 -55
  230. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Tracking.kt +0 -15
  231. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Utils.kt +0 -115
  232. package/compose/src/iosMain/kotlin/vn/momo/kits/const/HostFont.ios.kt +0 -40
  233. package/compose/src/iosMain/kotlin/vn/momo/kits/navigation/HostBackGesture.ios.kt +0 -45
  234. package/compose/src/iosMain/kotlin/vn/momo/kits/navigation/ScrollToTop.ios.kt +0 -32
  235. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/BackGesture.ios.kt +0 -38
  236. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/OsFontScale.ios.kt +0 -66
  237. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +0 -213
  238. package/gradle/libs.versions.toml +0 -69
  239. package/gradle/wrapper/gradle-wrapper.jar +0 -0
  240. package/gradle/wrapper/gradle-wrapper.properties +0 -8
  241. package/gradle.properties +0 -26
  242. package/gradlew +0 -252
  243. package/gradlew.bat +0 -94
  244. package/ios/Application/HeaderRight.swift +0 -306
  245. package/ios/Application/Navigation/BottomTab/BottomTab.swift +0 -104
  246. package/ios/Application/Navigation/HeaderBackProps.swift +0 -66
  247. package/ios/Application/Navigation/HeaderTitle.swift +0 -57
  248. package/ios/Application/Navigation/NavigationOptions.swift +0 -109
  249. package/ios/Application/Navigation/NavigatorManager.swift +0 -22
  250. package/ios/Application/Navigation/component/Header.swift +0 -178
  251. package/ios/Application/Navigation/component/HeaderBackground.swift +0 -83
  252. package/ios/Application/Navigation/component/HeaderColor.swift +0 -65
  253. package/ios/Application/Navigation/component/HeaderRightWidthKey.swift +0 -11
  254. package/ios/Application/Navigation/component/NavigationFooter.swift +0 -90
  255. package/ios/Application/Navigation/component/NavigationHeaderRight.swift +0 -196
  256. package/ios/Application/StackScreen.swift +0 -492
  257. package/ios-demo/README.md +0 -120
  258. package/local.properties +0 -8
  259. package/settings.gradle.kts +0 -64
  260. /package/ios/{Application/Navigation → Navigation}/BottomTab/CurvedContainer.swift +0 -0
@@ -1,475 +0,0 @@
1
- package vn.momo.kits.components
2
-
3
- import vn.momo.kits.modifier.InternalApi
4
-
5
- import androidx.compose.foundation.background
6
- import androidx.compose.foundation.border
7
- import androidx.compose.foundation.clickable
8
- import androidx.compose.foundation.interaction.MutableInteractionSource
9
- import androidx.compose.foundation.layout.*
10
- import androidx.compose.foundation.shape.RoundedCornerShape
11
- import androidx.compose.foundation.text.BasicTextField
12
- import androidx.compose.foundation.text.KeyboardOptions
13
- import androidx.compose.material3.CircularProgressIndicator
14
- import androidx.compose.runtime.*
15
- import androidx.compose.ui.Alignment
16
- import androidx.compose.ui.Modifier
17
- import androidx.compose.ui.focus.onFocusChanged
18
- import androidx.compose.ui.graphics.Color
19
- import androidx.compose.ui.text.AnnotatedString
20
- import androidx.compose.ui.text.SpanStyle
21
- import androidx.compose.ui.text.TextStyle
22
- import androidx.compose.ui.text.font.FontFamily
23
- import androidx.compose.ui.text.font.FontWeight
24
- import androidx.compose.ui.text.input.KeyboardType
25
- import androidx.compose.ui.text.input.OffsetMapping
26
- import androidx.compose.ui.text.input.TransformedText
27
- import androidx.compose.ui.text.input.VisualTransformation
28
- import androidx.compose.ui.text.style.TextAlign
29
- import androidx.compose.ui.unit.Dp
30
- import androidx.compose.ui.unit.TextUnit
31
- import androidx.compose.ui.unit.dp
32
- import androidx.compose.ui.unit.sp
33
- import androidx.compose.ui.zIndex
34
- import vn.momo.kits.application.IsShowBaseLineDebug
35
- import vn.momo.kits.const.*
36
- import vn.momo.kits.modifier.conditional
37
- import vn.momo.kits.modifier.setAutomationId
38
-
39
- data class InputSizeDetail(
40
- val borderWidth: Dp,
41
- val borderRadius: Dp,
42
- val height: Dp,
43
- )
44
-
45
- enum class InputSize(val values: InputSizeDetail) {
46
- SMALL(
47
- InputSizeDetail(
48
- borderWidth = 1.dp,
49
- borderRadius = Radius.S,
50
- height = 48.dp
51
- )
52
- ),
53
- LARGE(
54
- InputSizeDetail(
55
- borderWidth = 1.dp,
56
- borderRadius = Radius.S,
57
- height = 56.dp
58
- )
59
- )
60
- }
61
-
62
- enum class InputFontWeight(val value: FontWeight) {
63
- REGULAR(
64
- FontWeight(400)
65
- ),
66
- BOLD(
67
- FontWeight(700)
68
- )
69
- }
70
-
71
- data class InputState(
72
- val isFocused: Boolean = false,
73
- val passHidden: Boolean = false,
74
- val hasBeenBlurred: Boolean = false
75
- )
76
-
77
- private class PasswordVisualTransformation(
78
- private val fontFamily: FontFamily,
79
- private val fontSize: TextUnit
80
- ) : VisualTransformation {
81
- private val mask: Char = '\u2022'
82
-
83
- override fun filter(text: AnnotatedString): TransformedText {
84
-
85
- val maskedText = AnnotatedString(
86
- text = mask.toString().repeat(text.length),
87
- spanStyles = listOf(
88
- AnnotatedString.Range(
89
- SpanStyle(fontSize = fontSize, letterSpacing = 0.sp, fontFamily = fontFamily),
90
- 0,
91
- text.length
92
- )
93
- )
94
- )
95
- return TransformedText(maskedText, OffsetMapping.Identity)
96
- }
97
-
98
- override fun equals(other: Any?): Boolean {
99
- if (this === other) return true
100
- if (other !is PasswordVisualTransformation) return false
101
- return mask == other.mask && fontSize == other.fontSize
102
- }
103
-
104
- override fun hashCode(): Int {
105
- return 31 * mask.hashCode() + fontSize.hashCode()
106
- }
107
- }
108
-
109
- @Composable
110
- @InternalApi
111
- fun getBorderColor(isFocused: Boolean, error: String, disabled: Boolean): Color {
112
- val theme = AppTheme.current
113
- return remember(isFocused, error, disabled, theme) {
114
- when {
115
- disabled -> theme.colors.border.disable
116
- error.isNotEmpty() -> theme.colors.error.primary
117
- isFocused -> theme.colors.primary
118
- else -> theme.colors.border.default
119
- }
120
- }
121
- }
122
-
123
- @Composable
124
- @InternalApi
125
- fun RenderRightIcon(loading: Boolean, icon: String, color: Color, onClick: () -> Unit, modifier: Modifier = Modifier) {
126
- if (loading) {
127
- Box {
128
- CircularProgressIndicator(
129
- modifier = Modifier.size(16.dp),
130
- color = color,
131
- trackColor = Color.Transparent,
132
- strokeWidth = 2.dp
133
- )
134
- }
135
- }
136
- if (icon.isNotEmpty()) {
137
- Icon(
138
- source = icon,
139
- color = color,
140
- size = 24.dp,
141
- modifier = modifier.clickable(
142
- onClick = onClick,
143
- interactionSource = remember { MutableInteractionSource() },
144
- indication = null
145
- )
146
- )
147
- }
148
- }
149
-
150
- @Composable
151
- @InternalApi
152
- fun ErrorView(errorMessage: String, errorSpacing: Boolean, hintText: String) {
153
- val theme = AppTheme.current
154
- val errorColor = remember(theme) { theme.colors.error.primary }
155
- val hintColor = remember(theme) { theme.colors.text.hint }
156
- val hintTextDefault = remember(hintText) { hintText.ifEmpty { "Không thể chỉnh sửa" } }
157
-
158
- if (errorMessage.isNotEmpty() || hintText.isNotEmpty()) {
159
- val color = if (errorMessage.isNotEmpty()) errorColor else hintColor
160
- Row(
161
- Modifier.padding(top = Spacing.XS),
162
- verticalAlignment = Alignment.Top
163
- ) {
164
- Icon(
165
- size = 16.dp,
166
- color = color,
167
- source = "ic_error"
168
- )
169
- Text(
170
- errorMessage.ifEmpty { hintTextDefault },
171
- style = Typography.descriptionDefaultRegular,
172
- modifier = Modifier.padding(start = Spacing.XS),
173
- color = color,
174
- )
175
- }
176
- } else if (errorSpacing) {
177
- Spacer(Modifier.padding(top = Spacing.XS).height(18.dp))
178
- }
179
- }
180
-
181
- @Composable
182
- fun Input(
183
- text: MutableState<String> = remember { mutableStateOf("") },
184
- floatingValue: String = "",
185
- floatingValueColor: Color = AppTheme.current.colors.text.hint,
186
- floatingIcon: String = "",
187
- floatingIconColor: Color = AppTheme.current.colors.text.default,
188
- placeholder: String = "",
189
- size: InputSize = InputSize.SMALL,
190
- onChangeText: (String) -> Unit = {},
191
- hintText: String = "",
192
- error: String = "",
193
- errorSpacing: Boolean = false,
194
- disabled: Boolean = false,
195
- readOnly: Boolean = false,
196
- secureTextEntry: Boolean = false,
197
- icon: String = "",
198
- iconColor: Color = AppTheme.current.colors.text.default,
199
- onRightIconPressed: () -> Unit = {},
200
- leadingIcon: String = "",
201
- leadingIconColor: Color = AppTheme.current.colors.text.hint,
202
- onFocus: () -> Unit = {},
203
- onBlur: () -> Unit = {},
204
- loading: Boolean = false,
205
- required: Boolean = false,
206
- maxLength: Int? = null,
207
- fontWeight: InputFontWeight = InputFontWeight.REGULAR,
208
- keyboardType: KeyboardType = KeyboardType.Text,
209
- modifier: Modifier = Modifier,
210
- inputModifier: Modifier = Modifier,
211
- ) {
212
- // Consolidated state management
213
- var inputState by remember { mutableStateOf(InputState()) }
214
-
215
- // Memoized color calculations
216
- val theme = AppTheme.current
217
- val colors = remember(disabled, theme) {
218
- if (disabled) {
219
- val disabledColor = theme.colors.text.disable
220
- Triple(disabledColor, disabledColor, disabledColor)
221
- } else {
222
- Triple(
223
- theme.colors.text.default, // textColor
224
- theme.colors.text.hint, // placeholderColor
225
- iconColor // iconTintColor
226
- )
227
- }
228
- }
229
-
230
- val (textColor, placeholderColor, iconTintColor) = colors
231
-
232
- val floatingTitleColor = remember(disabled, floatingValueColor, theme) {
233
- if (disabled) theme.colors.text.disable else floatingValueColor
234
- }
235
-
236
- val floatingIconTintColor = remember(disabled, floatingIconColor, theme) {
237
- if (disabled) theme.colors.text.disable else floatingIconColor
238
- }
239
-
240
- val fontSize = 14.sp
241
- val lineHeight = 24.sp
242
- val scaleFontSize = scaleSize(fontSize)
243
- val scaleLineHeight = scaleSize(lineHeight)
244
-
245
- val textStyle = remember(textColor, fontWeight) {
246
- TextStyle(
247
- color = textColor,
248
- fontSize = scaleFontSize,
249
- lineHeight = scaleLineHeight,
250
- fontWeight = fontWeight.value
251
- )
252
- }
253
-
254
- val placeholderStyle = remember(placeholderColor, fontWeight) {
255
- TextStyle(
256
- fontSize = fontSize,
257
- lineHeight = lineHeight,
258
- fontWeight = fontWeight.value,
259
- textAlign = TextAlign.Center
260
- )
261
- }
262
-
263
- val keyboardOptionsConfig = remember(secureTextEntry, keyboardType) {
264
- KeyboardOptions.Default.copy(
265
- keyboardType = keyboardType
266
- )
267
- }
268
-
269
- val passwordFontFamily = getFontFamily(AppTheme.current.font, FontWeight.Normal)
270
- val passwordFontSize = scaleSize(24.sp)
271
- val visualTransformation = remember(secureTextEntry, inputState.passHidden, passwordFontFamily) {
272
- if (secureTextEntry && !inputState.passHidden)
273
- PasswordVisualTransformation(fontFamily = passwordFontFamily, fontSize = passwordFontSize)
274
- else
275
- VisualTransformation.None
276
- }
277
-
278
- Column(modifier = modifier
279
- .conditional(IsShowBaseLineDebug) {
280
- border(1.dp, Colors.blue_03)
281
- }) {
282
- BasicTextField(
283
- enabled = !disabled,
284
- readOnly = readOnly,
285
- singleLine = true,
286
- value = text.value,
287
- textStyle = textStyle,
288
- visualTransformation = visualTransformation,
289
- keyboardOptions = keyboardOptionsConfig,
290
- modifier = inputModifier
291
- .height(scaleSize(size.values.height.value).dp)
292
- .onFocusChanged { focusState ->
293
- val wasFocused = inputState.isFocused
294
- inputState = inputState.copy(
295
- isFocused = focusState.isFocused,
296
- hasBeenBlurred = inputState.hasBeenBlurred || wasFocused
297
- )
298
-
299
- if (focusState.isFocused) {
300
- onFocus()
301
- } else if (inputState.hasBeenBlurred) {
302
- onBlur()
303
- }
304
- },
305
- onValueChange = { newText ->
306
- val limitedText = maxLength?.let { newText.take(it) } ?: newText
307
- onChangeText(limitedText)
308
- },
309
- decorationBox = { innerTextField ->
310
- // Floating label
311
- FloatingLabel(
312
- floatingValue = floatingValue,
313
- floatingIcon = floatingIcon,
314
- titleColor = floatingTitleColor,
315
- iconColor = floatingIconTintColor,
316
- offsetY = -size.values.height / 2,
317
- required = required,
318
- )
319
-
320
- // Input container
321
- Box(
322
- modifier = Modifier
323
- .fillMaxWidth()
324
- .background(
325
- color = AppTheme.current.colors.background.surface,
326
- shape = RoundedCornerShape(size.values.borderRadius)
327
- )
328
- .border(
329
- 1.dp,
330
- getBorderColor(inputState.isFocused, error, disabled),
331
- RoundedCornerShape(size.values.borderRadius)
332
- ),
333
- contentAlignment = Alignment.CenterStart
334
- ) {
335
- Row(
336
- modifier = Modifier.padding(horizontal = Spacing.M),
337
- verticalAlignment = Alignment.CenterVertically
338
- ) {
339
- // Leading icon
340
- if (leadingIcon.isNotEmpty()) {
341
- Icon(
342
- source = leadingIcon,
343
- modifier = Modifier.padding(end = Spacing.M),
344
- size = if (size == InputSize.SMALL) 24.dp else 32.dp,
345
- color = leadingIconColor
346
- )
347
- }
348
-
349
- Box(Modifier.weight(1f), contentAlignment = Alignment.CenterStart) {
350
- if (text.value.isEmpty()) {
351
- Text(
352
- text = placeholder,
353
- style = placeholderStyle,
354
- color = placeholderColor
355
- )
356
-
357
- }
358
- innerTextField()
359
- }
360
-
361
- // Clear button
362
- if (inputState.isFocused && text.value.isNotEmpty()) {
363
- Row(Modifier.padding(horizontal = Spacing.XS)) {
364
- Icon(
365
- source = "24_navigation_close_circle_full",
366
- size = 16.dp,
367
- color = theme.colors.text.hint,
368
- modifier = Modifier.clickable(
369
- onClick = {
370
- text.value = ""
371
- onChangeText.invoke("")
372
- },
373
- interactionSource = remember { MutableInteractionSource() },
374
- indication = null
375
- ).setAutomationId("ic_clear")
376
- )
377
- }
378
- }
379
-
380
- // Right icon (password toggle or custom icon)
381
- when {
382
- secureTextEntry && text.value.isNotEmpty() -> {
383
- val iconName = if (inputState.passHidden) "24_security_eye_open" else "24_security_eye_off"
384
- val togglePassword = {
385
- onRightIconPressed()
386
- inputState = inputState.copy(passHidden = !inputState.passHidden)
387
- }
388
- RenderRightIcon(
389
- loading = loading,
390
- icon = iconName,
391
- color = iconTintColor,
392
- onClick = togglePassword,
393
- modifier = Modifier.setAutomationId("ic_show_hide"))
394
- }
395
- else -> {
396
- RenderRightIcon(loading, icon, iconTintColor, onRightIconPressed)
397
- }
398
- }
399
- }
400
- }
401
- },
402
- )
403
-
404
- // Error/hint display
405
- ErrorView(error, errorSpacing, hintText)
406
- }
407
- }
408
-
409
- internal data class InputColors(
410
- val text: Color,
411
- val placeholder: Color,
412
- val iconTint: Color,
413
- val floatingTitle: Color,
414
- val floatingIcon: Color,
415
- )
416
-
417
- @Composable
418
- internal fun getInputColors(
419
- disabled: Boolean,
420
- iconColor: Color,
421
- floatingValueColor: Color,
422
- floatingIconColor: Color,
423
- ): InputColors {
424
- val theme = AppTheme.current
425
- val disabledColor = theme.colors.text.disable
426
- return InputColors(
427
- text = if (disabled) disabledColor else theme.colors.text.default,
428
- placeholder = if (disabled) disabledColor else theme.colors.text.hint,
429
- iconTint = if (disabled) disabledColor else iconColor,
430
- floatingTitle = if (disabled) disabledColor else floatingValueColor,
431
- floatingIcon = if (disabled) disabledColor else floatingIconColor,
432
- )
433
- }
434
-
435
- @Composable
436
- internal fun FloatingLabel(
437
- floatingValue: String,
438
- floatingIcon: String,
439
- titleColor: Color,
440
- iconColor: Color,
441
- offsetY: Dp,
442
- offsetX: Dp = Spacing.S,
443
- required: Boolean = false,
444
- ) {
445
- if (floatingValue.isEmpty() && floatingIcon.isEmpty()) return
446
- Box(
447
- modifier = Modifier
448
- .wrapContentSize()
449
- .offset(y = offsetY, x = offsetX)
450
- .background(AppTheme.current.colors.background.surface)
451
- .zIndex(10f),
452
- ) {
453
- Row(
454
- modifier = Modifier.padding(horizontal = Spacing.S),
455
- verticalAlignment = Alignment.CenterVertically,
456
- ) {
457
- Text(floatingValue, style = Typography.labelSMedium, color = titleColor)
458
- if (required) {
459
- Text(
460
- "*",
461
- style = Typography.labelSMedium,
462
- color = AppTheme.current.colors.error.primary,
463
- )
464
- }
465
- if (floatingIcon.isNotEmpty()) {
466
- Icon(
467
- source = floatingIcon,
468
- modifier = Modifier.padding(start = Spacing.XS),
469
- size = 16.dp,
470
- color = iconColor,
471
- )
472
- }
473
- }
474
- }
475
- }
@@ -1,114 +0,0 @@
1
- package vn.momo.kits.components
2
-
3
- import androidx.compose.foundation.background
4
- import androidx.compose.foundation.border
5
- import androidx.compose.foundation.clickable
6
- import androidx.compose.foundation.layout.*
7
- import androidx.compose.foundation.shape.RoundedCornerShape
8
- import androidx.compose.runtime.*
9
- import androidx.compose.ui.Alignment
10
- import androidx.compose.ui.Modifier
11
- import androidx.compose.ui.graphics.Color
12
- import androidx.compose.ui.semantics.contentDescription
13
- import androidx.compose.ui.semantics.semantics
14
- import androidx.compose.ui.semantics.testTag
15
- import androidx.compose.ui.text.TextStyle
16
- import androidx.compose.ui.unit.dp
17
- import androidx.compose.ui.unit.sp
18
- import androidx.compose.ui.zIndex
19
- import vn.momo.kits.application.IsShowBaseLineDebug
20
- import vn.momo.kits.const.*
21
- import vn.momo.kits.modifier.conditional
22
-
23
- @Composable
24
- fun InputDropDown(
25
- value: MutableState<String> = remember { mutableStateOf("") },
26
- floatingValue: String = "",
27
- floatingValueColor: Color = AppTheme.current.colors.text.hint,
28
- floatingIcon: String = "",
29
- floatingIconColor: Color = AppTheme.current.colors.text.default,
30
- placeholder: String = "",
31
- size: InputSize = InputSize.SMALL,
32
- onPress: () -> Unit = {},
33
- hintText: String = "",
34
- error: String = "",
35
- errorSpacing: Boolean = false,
36
- disabled: Boolean = false,
37
- icon: String = "arrow_chevron_down_small",
38
- iconColor: Color = AppTheme.current.colors.text.default,
39
- onRightIconPressed: () -> Unit = {},
40
- leadingIcon: String = "",
41
- leadingIconColor: Color = AppTheme.current.colors.text.hint,
42
- loading: Boolean = false,
43
- required: Boolean = false,
44
- ) {
45
- val isFocused by remember { mutableStateOf(false) }
46
-
47
- val (textColor, placeholderColor, iconTintColor, floatingTitleColor, floatingIconTintColor) =
48
- getInputColors(disabled, iconColor, floatingValueColor, floatingIconColor)
49
-
50
- val testId = if (disabled) "input_${floatingValue}_disabled" else "input_$floatingValue"
51
-
52
- val fontSize = scaleSize(16.sp)
53
- val lineHeight = scaleSize(24.sp)
54
-
55
- Column(modifier = Modifier
56
- .conditional(IsShowBaseLineDebug) {
57
- border(1.dp, Colors.blue_03)
58
- }
59
- .clickable(enabled = !disabled, onClick = onPress)
60
- .semantics {
61
- contentDescription = floatingValue; testTag = testId
62
- }) {
63
- Box {
64
- FloatingLabel(
65
- floatingValue = floatingValue,
66
- floatingIcon = floatingIcon,
67
- titleColor = floatingTitleColor,
68
- iconColor = floatingIconTintColor,
69
- offsetY = -Spacing.S,
70
- required = required,
71
- )
72
- Box(
73
- modifier = Modifier.fillMaxWidth()
74
- .height(if (size == InputSize.SMALL) 48.dp else 56.dp)
75
- .border(
76
- 1.dp,
77
- getBorderColor(isFocused, error, disabled),
78
- RoundedCornerShape(size.values.borderRadius)
79
- ),
80
- contentAlignment = Alignment.CenterStart
81
- ) {
82
- Row(
83
- modifier = Modifier.padding(horizontal = Spacing.M),
84
- verticalAlignment = Alignment.CenterVertically
85
- ) {
86
- //leading icon
87
- if (leadingIcon.isNotEmpty()) {
88
- Icon(
89
- source = leadingIcon,
90
- modifier = Modifier.padding(end = Spacing.M),
91
- size = if (size.name == InputSize.SMALL.name) 24.dp else 32.dp,
92
- color = leadingIconColor
93
- )
94
- }
95
- Box(Modifier.weight(1f)) {
96
- Text(
97
- text = value.value.ifEmpty { placeholder },
98
- style = TextStyle(
99
- fontSize = fontSize,
100
- lineHeight = lineHeight
101
- ),
102
- color = if (value.value.isEmpty()) placeholderColor else textColor
103
- )
104
- }
105
- RenderRightIcon(
106
- loading, icon, iconTintColor,
107
- onRightIconPressed
108
- )
109
- }
110
- }
111
- }
112
- ErrorView(error, errorSpacing, hintText)
113
- }
114
- }