@momo-kits/native-kits 0.163.1-beta.1-debug → 0.163.1-beta.10-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 (307) hide show
  1. package/CLAUDE.md +1 -1
  2. package/compose/build.gradle.kts +12 -8
  3. package/compose/build.gradle.kts.backup +11 -7
  4. package/compose/compose.podspec +1 -1
  5. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/OsFontScale.android.kt +7 -0
  6. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/Platform.android.kt +30 -3
  7. package/compose/src/commonMain/kotlin/vn/momo/kits/application/AnimationSearchInput.kt +2 -7
  8. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Context.kt +6 -9
  9. package/compose/src/commonMain/kotlin/vn/momo/kits/application/FloatingButton.kt +6 -24
  10. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Header.kt +4 -19
  11. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderAnimated.kt +1 -10
  12. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderBackground.kt +2 -2
  13. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderDefault.kt +1 -1
  14. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderExtended.kt +1 -1
  15. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderRight.kt +5 -16
  16. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderTitle.kt +1 -1
  17. package/compose/src/commonMain/kotlin/vn/momo/kits/application/LiteScreen.kt +6 -101
  18. package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +6 -16
  19. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +8 -33
  20. package/compose/src/commonMain/kotlin/vn/momo/kits/application/WidgetContainer.kt +56 -0
  21. package/compose/src/commonMain/kotlin/vn/momo/kits/application/useHeaderSearchAnimation.kt +1 -1
  22. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Badge.kt +22 -25
  23. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeRibbon.kt +27 -29
  24. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BaselineView.kt +3 -26
  25. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +30 -31
  26. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Carousel.kt +3 -13
  27. package/compose/src/commonMain/kotlin/vn/momo/kits/components/CheckBox.kt +0 -5
  28. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Chip.kt +3 -11
  29. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Collapse.kt +3 -18
  30. package/compose/src/commonMain/kotlin/vn/momo/kits/components/CupertinoOverscroll.kt +11 -11
  31. package/compose/src/commonMain/kotlin/vn/momo/kits/components/IconButton.kt +42 -65
  32. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Image.kt +69 -26
  33. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Information.kt +1 -5
  34. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +84 -59
  35. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputDropDown.kt +13 -71
  36. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputMoney.kt +10 -51
  37. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputOTP.kt +6 -1
  38. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputPhoneNumber.kt +4 -21
  39. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +1 -1
  40. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +16 -75
  41. package/compose/src/commonMain/kotlin/vn/momo/kits/components/LazyColumnWithBouncing.kt +5 -26
  42. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationDot.kt +1 -1
  43. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationScroll.kt +3 -11
  44. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +16 -40
  45. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupPromotion.kt +3 -9
  46. package/compose/src/commonMain/kotlin/vn/momo/kits/components/ProgressInfo.kt +0 -28
  47. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Radio.kt +2 -13
  48. package/compose/src/commonMain/kotlin/vn/momo/kits/components/ScaleSizeScope.kt +4 -0
  49. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Skeleton.kt +4 -10
  50. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Slider.kt +3 -28
  51. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Stepper.kt +8 -47
  52. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Steps.kt +4 -25
  53. package/compose/src/commonMain/kotlin/vn/momo/kits/components/SuggestAction.kt +2 -11
  54. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Swipe.kt +1 -17
  55. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Switch.kt +1 -6
  56. package/compose/src/commonMain/kotlin/vn/momo/kits/components/TabView.kt +50 -111
  57. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tag.kt +1 -5
  58. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +1 -5
  59. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Title.kt +1 -12
  60. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tooltip.kt +4 -96
  61. package/compose/src/commonMain/kotlin/vn/momo/kits/components/TrustBanner.kt +5 -7
  62. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Uploader.kt +2 -12
  63. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePicker.kt +9 -21
  64. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerTypes.kt +2 -2
  65. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerUtils.kt +9 -14
  66. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/WheelPicker.kt +8 -11
  67. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Colors.kt +19 -0
  68. package/compose/src/commonMain/kotlin/vn/momo/kits/const/KitFontScale.kt +22 -0
  69. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Theme.kt +1 -1
  70. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +11 -20
  71. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Card.kt +50 -0
  72. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Item.kt +22 -21
  73. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Section.kt +37 -0
  74. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/AutomationId.kt +0 -5
  75. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Clickable.kt +0 -2
  76. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/DeprecatedModifier.kt +94 -4
  77. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Shadow.kt +0 -2
  78. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/BottomSheet.kt +5 -6
  79. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ModalScreen.kt +4 -8
  80. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigation.kt +12 -16
  81. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +121 -84
  82. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigator.kt +48 -33
  83. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +88 -63
  84. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTab.kt +9 -14
  85. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +13 -31
  86. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/CurvedContainer.kt +1 -1
  87. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/FloatingButton.kt +6 -24
  88. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +11 -6
  89. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderBackground.kt +2 -1
  90. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderRight.kt +9 -6
  91. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderTitle.kt +1 -1
  92. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderUser.kt +3 -13
  93. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SnackBar.kt +3 -2
  94. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/tracking/ScreenTracker.kt +1 -40
  95. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/ComposeLottieAnimation.kt +23 -4
  96. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/OsFontScale.kt +9 -0
  97. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +10 -7
  98. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Resources.kt +2 -17
  99. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Tracking.kt +1 -1
  100. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Utils.kt +3 -3
  101. package/compose/src/iosMain/kotlin/vn/momo/kits/navigation/ScrollToTop.ios.kt +2 -3
  102. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/OsFontScale.ios.kt +66 -0
  103. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +26 -5
  104. package/gradle/libs.versions.toml +2 -0
  105. package/gradle.properties +1 -1
  106. package/ios/Application/ApplicationEnvironment.swift +15 -2
  107. package/ios/Application/Components.swift +50 -43
  108. package/ios/Application/FloatingButton.swift +10 -8
  109. package/ios/Application/HeaderRight.swift +79 -45
  110. package/ios/Application/Localize.swift +277 -0
  111. package/ios/Application/MaxApi.swift +18 -0
  112. package/ios/Application/Navigation/BottomTab/BottomTab.swift +104 -0
  113. package/ios/Application/Navigation/BottomTab/BottomTabBar.swift +215 -0
  114. package/ios/Application/Navigation/BottomTab/CurvedContainer.swift +65 -0
  115. package/ios/Application/Navigation/HeaderBackProps.swift +66 -0
  116. package/ios/Application/Navigation/HeaderTitle.swift +57 -0
  117. package/ios/Application/Navigation/HeaderUser.swift +209 -0
  118. package/ios/Application/Navigation/NavigationContainer.swift +200 -0
  119. package/ios/Application/Navigation/NavigationOptions.swift +109 -0
  120. package/ios/Application/Navigation/Navigator.swift +385 -0
  121. package/ios/Application/Navigation/Overplay/BottomSheet.swift +256 -0
  122. package/ios/Application/Navigation/Overplay/ModalScreen.swift +74 -0
  123. package/ios/Application/Navigation/Overplay/SnackBar.swift +144 -0
  124. package/ios/Application/Navigation/Tracking/ScreenTracker.swift +117 -0
  125. package/ios/Application/Navigation/component/Header.swift +178 -0
  126. package/ios/Application/Navigation/component/HeaderBackground.swift +83 -0
  127. package/ios/Application/Navigation/component/HeaderColor.swift +65 -0
  128. package/ios/Application/Screen.swift +2 -1
  129. package/ios/Application/StackScreen.swift +501 -0
  130. package/ios/Avatar/Avatar.swift +193 -0
  131. package/ios/Badge/Badge.swift +11 -13
  132. package/ios/Badge/BadgeRibbon.swift +92 -19
  133. package/ios/BaselineView/BaselineView.swift +163 -0
  134. package/ios/Button/Button.swift +124 -29
  135. package/ios/Carousel/Carousel.swift +196 -0
  136. package/ios/Checkbox/Checkbox.swift +23 -27
  137. package/ios/Chip/Chip.swift +56 -33
  138. package/ios/Collapse/Collapse.swift +192 -0
  139. package/ios/Colors+Radius+Spacing/Colors.swift +20 -17
  140. package/ios/Colors+Radius+Spacing/Spacing.swift +3 -1
  141. package/ios/Colors+Radius+Spacing/Theme.swift +295 -0
  142. package/ios/DateTimePicker/DateTimePicker.swift +212 -0
  143. package/ios/DateTimePicker/DateTimePickerTypes.swift +55 -0
  144. package/ios/DateTimePicker/DateTimePickerUtils.swift +167 -0
  145. package/ios/DateTimePicker/WheelPicker.swift +165 -0
  146. package/ios/Divider/Divider.swift +16 -0
  147. package/ios/Extensions/ActiveOpacityButtonStyle.swift +14 -0
  148. package/ios/Extensions/Color++.swift +32 -0
  149. package/ios/Icon/Icon.swift +10 -1
  150. package/ios/IconButton/IconButton.swift +140 -0
  151. package/ios/Image/Image.swift +16 -3
  152. package/ios/Information/Information.swift +153 -0
  153. package/ios/Input/ErrorView.swift +3 -1
  154. package/ios/Input/Input.swift +73 -33
  155. package/ios/Input/InputPhoneNumber.swift +34 -21
  156. package/ios/Input/InputSearch.swift +108 -46
  157. package/ios/Input/InputTextArea.swift +135 -64
  158. package/ios/InputDropDown/InputDropDown.swift +201 -0
  159. package/ios/InputMoney/InputMoney.swift +347 -0
  160. package/ios/InputOTP/InputOTP.swift +210 -0
  161. package/ios/Loader/Loader.swift +113 -0
  162. package/ios/MoMoUIKits.podspec +5 -0
  163. package/ios/OTPKeyboard/KeyboardButton.swift +1 -1
  164. package/ios/Pagination/PaginationDot.swift +61 -0
  165. package/ios/Pagination/PaginationNumber.swift +35 -0
  166. package/ios/Pagination/PaginationScroll.swift +101 -0
  167. package/ios/Pagination/PaginationWhiteDot.swift +37 -0
  168. package/ios/Popup/PopupDisplay.swift +13 -16
  169. package/ios/Popup/PopupInput.swift +2 -6
  170. package/ios/Popup/PopupNotify.swift +218 -0
  171. package/ios/Popup/PopupPromotion.swift +16 -8
  172. package/ios/ProgressInfo/ProgressInfo.swift +296 -0
  173. package/ios/Radio/Radio.swift +69 -0
  174. package/ios/Rating/Rating.swift +82 -0
  175. package/ios/Resources/MoMoUIKitsColors.xcassets/AccentColor.colorset/Contents.json +11 -0
  176. package/ios/Resources/MoMoUIKitsColors.xcassets/Background.colorset/Contents.json +38 -0
  177. package/ios/Resources/MoMoUIKitsColors.xcassets/Border.colorset/Contents.json +38 -0
  178. package/ios/Resources/MoMoUIKitsColors.xcassets/Card.colorset/Contents.json +38 -0
  179. package/ios/Resources/MoMoUIKitsColors.xcassets/Contents.json +6 -0
  180. package/ios/Resources/MoMoUIKitsColors.xcassets/Error.colorset/Contents.json +38 -0
  181. package/ios/Resources/MoMoUIKitsColors.xcassets/Primary.colorset/Contents.json +38 -0
  182. package/ios/Resources/MoMoUIKitsColors.xcassets/PrimaryDark.colorset/Contents.json +38 -0
  183. package/ios/Resources/MoMoUIKitsColors.xcassets/PrimaryLight.colorset/Contents.json +38 -0
  184. package/ios/Resources/MoMoUIKitsColors.xcassets/Secondary.colorset/Contents.json +38 -0
  185. package/ios/Resources/MoMoUIKitsColors.xcassets/Success.colorset/Contents.json +38 -0
  186. package/ios/Resources/MoMoUIKitsColors.xcassets/Text.colorset/Contents.json +38 -0
  187. package/ios/Resources/MoMoUIKitsColors.xcassets/TextSecondary.colorset/Contents.json +38 -0
  188. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/Contents.json +9 -0
  189. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-default.colorset/Contents.json +38 -0
  190. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-disable.colorset/Contents.json +38 -0
  191. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-pressed.colorset/Contents.json +38 -0
  192. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-selected.colorset/Contents.json +38 -0
  193. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-surface.colorset/Contents.json +38 -0
  194. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-tonal.colorset/Contents.json +38 -0
  195. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/border-default.colorset/Contents.json +38 -0
  196. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/border-disable.colorset/Contents.json +38 -0
  197. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/gradient.colorset/Contents.json +38 -0
  198. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/primary.colorset/Contents.json +38 -0
  199. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/secondary.colorset/Contents.json +38 -0
  200. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/success-container.colorset/Contents.json +38 -0
  201. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/success-primary.colorset/Contents.json +38 -0
  202. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/success-secondary.colorset/Contents.json +38 -0
  203. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-default.colorset/Contents.json +38 -0
  204. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-disable.colorset/Contents.json +38 -0
  205. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-hint.colorset/Contents.json +38 -0
  206. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-secondary.colorset/Contents.json +38 -0
  207. package/ios/Resources/MoMoUIKitsColors.xcassets/Warning.colorset/Contents.json +38 -0
  208. package/ios/Skeleton/Skeleton.swift +99 -0
  209. package/ios/Slider/Slider.swift +237 -0
  210. package/ios/Stepper/Stepper.swift +220 -0
  211. package/ios/Steps/Steps.swift +467 -0
  212. package/ios/SuggestAction/SuggestAction.swift +99 -0
  213. package/ios/Swipeable/SwipeCell.swift +187 -0
  214. package/ios/Swipeable/SwipeCellModel.swift +21 -0
  215. package/ios/Switch/Switch.swift +53 -28
  216. package/ios/TabView/TabView.swift +534 -0
  217. package/ios/Tag/Tag.swift +98 -0
  218. package/ios/Template/TrustBanner/TrustBanner.swift +8 -7
  219. package/ios/Title/Title.swift +269 -0
  220. package/ios/Tooltip/Tooltip.swift +485 -0
  221. package/ios/Typography/FontScaleStore.swift +19 -0
  222. package/ios/Typography/Text.swift +80 -5
  223. package/ios/Typography/Typography.swift +17 -5
  224. package/ios/Uploader/Uploader.swift +174 -0
  225. package/ios/native-kits.podspec +61 -8
  226. package/ios-demo/MoMoUIKitsDemo.podspec +20 -0
  227. package/ios-demo/README.md +120 -0
  228. package/ios-demo/Resources/dot_loading.json +558 -0
  229. package/ios-demo/Resources/icon.json +4052 -0
  230. package/ios-demo/Resources/lottie_circle_loader.json +1 -0
  231. package/ios-demo/Sources/MoMoUIKitsDemo/DemoScaffold.swift +48 -0
  232. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsBadgeDemoView.swift +25 -0
  233. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsButtonDemoView.swift +26 -0
  234. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsCheckboxDemoView.swift +19 -0
  235. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsChipDemoView.swift +33 -0
  236. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsInputDemoView.swift +48 -0
  237. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsPopupDemoView.swift +21 -0
  238. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsRadioDemoView.swift +17 -0
  239. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsTypographyDemoView.swift +28 -0
  240. package/ios-demo/Sources/MoMoUIKitsDemo/MoMoUIKitsDemoContext.swift +31 -0
  241. package/ios-demo/Sources/MoMoUIKitsDemo/MoMoUIKitsDemoFactory.swift +24 -0
  242. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/AnimatedHeaderDemo.swift +110 -0
  243. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/AvatarDemo.swift +93 -0
  244. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BadgeDemo.swift +269 -0
  245. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BaselineView.swift +117 -0
  246. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BottomTabDemo.swift +89 -0
  247. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ButtonDemo.swift +100 -0
  248. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CarouselDemo.swift +126 -0
  249. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CheckboxDemo.swift +63 -0
  250. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ChipDemo.swift +20 -0
  251. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CollapseDemo.swift +93 -0
  252. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ContentView.swift +107 -0
  253. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DateTimePickerDemo.swift +124 -0
  254. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DividerDemo.swift +14 -0
  255. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/HeaderUserDemo.swift +49 -0
  256. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/Home.swift +279 -0
  257. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/IconButtonDemo.swift +58 -0
  258. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ImageDemo.swift +78 -0
  259. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InformationDemo.swift +138 -0
  260. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputDemo.swift +111 -0
  261. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputDropDownDemo.swift +136 -0
  262. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputMoneyDemo.swift +107 -0
  263. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputOTPDemo.swift +73 -0
  264. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputPhoneNumberDemo.swift +100 -0
  265. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputSearchDemo.swift +32 -0
  266. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputTextAreaDemo.swift +57 -0
  267. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/LoaderDemo.swift +70 -0
  268. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/LocalizeDemo.swift +188 -0
  269. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/NavigationDemo.swift +229 -0
  270. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PaginationDemo.swift +72 -0
  271. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupDisplayDemo.swift +175 -0
  272. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupNotifyDemo.swift +121 -0
  273. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupPromotionDemo.swift +76 -0
  274. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ProgressInfoDemo.swift +89 -0
  275. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/RadioDemo.swift +32 -0
  276. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/RatingDemo.swift +56 -0
  277. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SkeletonDemo.swift +32 -0
  278. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SliderDemo.swift +150 -0
  279. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SnackBarDemo.swift +138 -0
  280. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/StepperDemo.swift +103 -0
  281. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/StepsDemo.swift +94 -0
  282. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SuggestActionDemo.swift +79 -0
  283. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SwipeDemo.swift +152 -0
  284. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SwitchDemo.swift +33 -0
  285. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TabViewDemo.swift +190 -0
  286. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TagDemo.swift +34 -0
  287. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ThemeDemo.swift +182 -0
  288. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TitleDemo.swift +109 -0
  289. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TooltipDemo.swift +187 -0
  290. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TypographyDemo.swift +87 -0
  291. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/UploaderDemo.swift +131 -0
  292. package/ios-demo/Sources/MoMoUIKitsDemo/SwiftUIDemoBrowserView.swift +51 -0
  293. package/ios-demo/Sources/MoMoUIKitsDemo/UIKitsDemoModels.swift +15 -0
  294. package/ios-demo/Sources/MoMoUIKitsDemo/UIKitsDemoRegistry.swift +73 -0
  295. package/package.json +1 -1
  296. package/publish.sh +53 -0
  297. package/scripts/gen-ios-color.mjs +136 -0
  298. package/example/ios/Example.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
  299. package/example/ios/Example.xcworkspace/xcuserdata/huynhdung.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  300. package/example/ios/Example.xcworkspace/xcuserdata/huynhdung.xcuserdatad/xcschemes/xcschememanagement.plist +0 -5
  301. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/MoMoUIKits.xcscheme +0 -58
  302. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/Pods-Example.xcscheme +0 -58
  303. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/SDWebImage.xcscheme +0 -58
  304. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/SDWebImageSwiftUI.xcscheme +0 -58
  305. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/SkeletonUI.xcscheme +0 -58
  306. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/xcschememanagement.plist +0 -46
  307. package/local.properties +0 -8
@@ -8,13 +8,7 @@ import androidx.compose.foundation.layout.PaddingValues
8
8
  import androidx.compose.foundation.layout.fillMaxWidth
9
9
  import androidx.compose.foundation.pager.HorizontalPager
10
10
  import androidx.compose.foundation.pager.rememberPagerState
11
- import androidx.compose.runtime.Composable
12
- import androidx.compose.runtime.LaunchedEffect
13
- import androidx.compose.runtime.getValue
14
- import androidx.compose.runtime.mutableStateOf
15
- import androidx.compose.runtime.remember
16
- import androidx.compose.runtime.setValue
17
- import androidx.compose.runtime.snapshotFlow
11
+ import androidx.compose.runtime.*
18
12
  import androidx.compose.ui.Modifier
19
13
  import androidx.compose.ui.graphics.graphicsLayer
20
14
  import androidx.compose.ui.unit.dp
@@ -24,6 +18,7 @@ import vn.momo.kits.application.IsShowBaseLineDebug
24
18
  import vn.momo.kits.const.Colors
25
19
  import vn.momo.kits.modifier.conditional
26
20
  import kotlin.math.absoluteValue
21
+ import kotlin.time.Duration.Companion.milliseconds
27
22
 
28
23
  @Composable
29
24
  fun Carousel(
@@ -32,7 +27,6 @@ fun Carousel(
32
27
  loop: Boolean = false,
33
28
  autoplay: Boolean = false,
34
29
  autoplayInterval: Long = 3000L,
35
- enableSnap: Boolean = true,
36
30
  scrollEnabled: Boolean = true,
37
31
  inactiveSlideOpacity: Float = 1f,
38
32
  inactiveSlideScale: Float = 1f,
@@ -48,18 +42,15 @@ fun Carousel(
48
42
 
49
43
  val pagerState = rememberPagerState(initialPage = startPage) { virtualPageCount }
50
44
 
51
- // Map virtual page to real index
52
45
  val realIndex: (Int) -> Int = { page -> page % itemCount }
53
46
 
54
- // Track user interaction for autoplay pause
55
47
  var isUserScrolling by remember { mutableStateOf(false) }
56
48
 
57
- // Autoplay
58
49
  if (autoplay && itemCount > 1) {
59
50
  LaunchedEffect(autoplayInterval, isUserScrolling) {
60
51
  if (isUserScrolling) return@LaunchedEffect
61
52
  while (isActive) {
62
- delay(autoplayInterval)
53
+ delay(autoplayInterval.milliseconds)
63
54
  if (!isUserScrolling) {
64
55
  val nextPage = pagerState.currentPage + 1
65
56
  if (nextPage < virtualPageCount) {
@@ -70,7 +61,6 @@ fun Carousel(
70
61
  }
71
62
  }
72
63
 
73
- // Track scroll state for callbacks
74
64
  LaunchedEffect(pagerState) {
75
65
  snapshotFlow { pagerState.isScrollInProgress }.collect { scrolling ->
76
66
  isUserScrolling = scrolling
@@ -22,7 +22,6 @@ import vn.momo.kits.const.Typography
22
22
  import vn.momo.kits.modifier.activeOpacityClickable
23
23
  import vn.momo.kits.modifier.conditional
24
24
 
25
- // Pre-computed shape for performance
26
25
  private val checkboxShape = RoundedCornerShape(Radius.XS)
27
26
 
28
27
  @Composable
@@ -33,10 +32,8 @@ fun CheckBox(
33
32
  indeterminate: Boolean = false,
34
33
  title: String = "",
35
34
  ) {
36
- // Cache theme access
37
35
  val theme = AppTheme.current
38
36
 
39
- // Memoize color calculations to avoid repeated conditional logic
40
37
  val colors = remember(checked, disabled, theme) {
41
38
  when {
42
39
  disabled && checked -> Pair(theme.colors.background.tonal, theme.colors.background.tonal)
@@ -48,12 +45,10 @@ fun CheckBox(
48
45
 
49
46
  val (borderColor, backgroundColor) = colors
50
47
 
51
- // Memoize icon source to avoid repeated conditional check
52
48
  val iconSource = remember(indeterminate) {
53
49
  if (indeterminate) "navigation_minus" else "ic_checked"
54
50
  }
55
51
 
56
- // Memoize click handler to avoid lambda recreation
57
52
  val onClickHandler = remember(onCheckedChange, checked) {
58
53
  { onCheckedChange(!checked) }
59
54
  }
@@ -2,11 +2,7 @@ package vn.momo.kits.components
2
2
 
3
3
  import androidx.compose.foundation.background
4
4
  import androidx.compose.foundation.border
5
- import androidx.compose.foundation.layout.Arrangement
6
- import androidx.compose.foundation.layout.Row
7
- import androidx.compose.foundation.layout.height
8
- import androidx.compose.foundation.layout.padding
9
- import androidx.compose.foundation.layout.wrapContentWidth
5
+ import androidx.compose.foundation.layout.*
10
6
  import androidx.compose.foundation.shape.RoundedCornerShape
11
7
  import androidx.compose.runtime.Composable
12
8
  import androidx.compose.runtime.Immutable
@@ -17,12 +13,8 @@ import androidx.compose.ui.graphics.Color
17
13
  import androidx.compose.ui.text.style.TextAlign
18
14
  import androidx.compose.ui.text.style.TextOverflow
19
15
  import androidx.compose.ui.unit.dp
20
- import vn.momo.kits.const.AppTheme
21
- import vn.momo.kits.const.Colors
22
- import vn.momo.kits.const.Radius
23
- import vn.momo.kits.const.Typography
24
16
  import vn.momo.kits.application.IsShowBaseLineDebug
25
- import vn.momo.kits.const.scaleSize
17
+ import vn.momo.kits.const.*
26
18
  import vn.momo.kits.modifier.activeOpacityClickable
27
19
  import vn.momo.kits.modifier.conditional
28
20
  import vn.momo.kits.modifier.setAutomationId
@@ -111,7 +103,7 @@ fun Chip(
111
103
 
112
104
  enum class ChipSize { SMALL, LARGE }
113
105
 
114
- object ChipDefaults {
106
+ private object ChipDefaults {
115
107
  @Immutable
116
108
  data class Dimensions(
117
109
  val height: Float,
@@ -7,20 +7,9 @@ import androidx.compose.animation.expandVertically
7
7
  import androidx.compose.animation.shrinkVertically
8
8
  import androidx.compose.foundation.background
9
9
  import androidx.compose.foundation.border
10
- import androidx.compose.foundation.layout.Box
11
- import androidx.compose.foundation.layout.Column
12
- import androidx.compose.foundation.layout.Row
13
- import androidx.compose.foundation.layout.Spacer
14
- import androidx.compose.foundation.layout.fillMaxWidth
15
- import androidx.compose.foundation.layout.padding
16
- import androidx.compose.foundation.layout.size
17
- import androidx.compose.foundation.layout.width
10
+ import androidx.compose.foundation.layout.*
18
11
  import androidx.compose.foundation.shape.RoundedCornerShape
19
- import androidx.compose.runtime.Composable
20
- import androidx.compose.runtime.getValue
21
- import androidx.compose.runtime.mutableStateOf
22
- import androidx.compose.runtime.remember
23
- import androidx.compose.runtime.setValue
12
+ import androidx.compose.runtime.*
24
13
  import androidx.compose.ui.Alignment
25
14
  import androidx.compose.ui.Modifier
26
15
  import androidx.compose.ui.draw.clip
@@ -29,11 +18,7 @@ import androidx.compose.ui.graphics.Color
29
18
  import androidx.compose.ui.text.TextStyle
30
19
  import androidx.compose.ui.unit.dp
31
20
  import vn.momo.kits.application.IsShowBaseLineDebug
32
- import vn.momo.kits.const.AppTheme
33
- import vn.momo.kits.const.Colors
34
- import vn.momo.kits.const.Radius
35
- import vn.momo.kits.const.Spacing
36
- import vn.momo.kits.const.Typography
21
+ import vn.momo.kits.const.*
37
22
  import vn.momo.kits.modifier.activeOpacityClickable
38
23
  import vn.momo.kits.modifier.conditional
39
24
  import vn.momo.kits.modifier.setAutomationId
@@ -42,8 +42,8 @@ import androidx.compose.ui.unit.toOffset
42
42
  import androidx.compose.ui.unit.toSize
43
43
  import kotlinx.coroutines.CoroutineScope
44
44
  import kotlinx.coroutines.cancel
45
+ import kotlinx.coroutines.currentCoroutineContext
45
46
  import kotlinx.coroutines.isActive
46
- import kotlin.coroutines.coroutineContext
47
47
  import kotlin.math.abs
48
48
  import kotlin.math.sign
49
49
 
@@ -103,7 +103,7 @@ internal class CupertinoOverscrollEffect(
103
103
  * end at the same time, which is not the case:
104
104
  * Spring->Fling->Spring, Fling->Spring, Spring->Fling effects can have different timing per dimension
105
105
  * (see Notes of https://github.com/JetBrains/compose-multiplatform-core/pull/609),
106
- * which is not possible to express without changing API. Hence this effect will be fixed to latest
106
+ * which is not possible to express without changing API. Hence, this effect will be fixed to latest
107
107
  * received delta.
108
108
  */
109
109
  private var direction: CupertinoOverscrollDirection = CupertinoOverscrollDirection.UNKNOWN
@@ -151,7 +151,7 @@ internal class CupertinoOverscrollEffect(
151
151
  override val node: DelegatableNode get() = overscrollNode
152
152
 
153
153
  private fun onDraw() {
154
- // Fix an issue where scrolling was cancelled but the overscroll effect was not completed.
154
+ // Fix an issue where scrolling was canceled but the overscroll effect was not completed.
155
155
  // Reset the overscroll effect when no ongoing animation or interaction is applied.
156
156
  if (!drawCallScheduledByOffsetChange && isInProgress && overscrollNode.pointersDown == 0) {
157
157
  overscrollOffsetState.value = Offset.Zero
@@ -289,7 +289,7 @@ internal class CupertinoOverscrollEffect(
289
289
  }
290
290
 
291
291
  private fun applyPullToRefresh() {
292
- val (isRefresh, refresh, threshHold, _, sendHaptic) = pullRefreshState ?: return
292
+ val (isRefresh, refresh, threshHold, _, _) = pullRefreshState ?: return
293
293
  val overscrollY = overscrollOffset.y
294
294
  if (isRefresh.value || overscrollY < threshHold.value * density) return
295
295
  refresh.invoke()
@@ -398,7 +398,7 @@ internal class CupertinoOverscrollEffect(
398
398
  }
399
399
 
400
400
  springAnimationScope?.cancel()
401
- springAnimationScope = CoroutineScope(coroutineContext)
401
+ springAnimationScope = CoroutineScope(currentCoroutineContext())
402
402
  springAnimationScope?.run {
403
403
  AnimationState(
404
404
  Float.VectorConverter,
@@ -414,7 +414,7 @@ internal class CupertinoOverscrollEffect(
414
414
  } ?: (value * density).toOffset()
415
415
  currentVelocity = velocity * density
416
416
 
417
- // If it was fling from overscroll, cancel animation and return velocity
417
+ // If it was flung from overscroll, cancel animation and return velocity
418
418
  if (reason == CupertinoSpringAnimationReason.FLING_FROM_OVERSCROLL &&
419
419
  initialSign != 0f &&
420
420
  sign(value) != initialSign
@@ -425,7 +425,7 @@ internal class CupertinoOverscrollEffect(
425
425
  springAnimationScope = null
426
426
  }
427
427
 
428
- if (coroutineContext.isActive) {
428
+ if (currentCoroutineContext().isActive) {
429
429
  // The spring is critically damped, so in case spring-fling-spring sequence is slightly
430
430
  // offset and velocity is of the opposite sign, it will end up with no animation
431
431
  overscrollOffset = Offset.Zero
@@ -447,8 +447,8 @@ internal class CupertinoOverscrollEffect(
447
447
  val dpSize = scrollSize / density
448
448
 
449
449
  return Offset(
450
- rubberBandedValue(dpOffset.x, dpSize.width, RUBBER_BAND_COEFFICIENT),
451
- rubberBandedValue(dpOffset.y, dpSize.height, RUBBER_BAND_COEFFICIENT)
450
+ rubberBandedValue(dpOffset.x, dpSize.width),
451
+ rubberBandedValue(dpOffset.y, dpSize.height)
452
452
  ) * density
453
453
  }
454
454
 
@@ -456,8 +456,8 @@ internal class CupertinoOverscrollEffect(
456
456
  * Maps raw delta offset [value] on an axis within scroll container with [dimension]
457
457
  * to actual visible offset
458
458
  */
459
- private fun rubberBandedValue(value: Float, dimension: Float, coefficient: Float) =
460
- sign(value) * (1f - (1f / (abs(value) * coefficient / dimension + 1f))) * dimension
459
+ private fun rubberBandedValue(value: Float, dimension: Float) =
460
+ sign(value) * (1f - (1f / (abs(value) * RUBBER_BAND_COEFFICIENT / dimension + 1f))) * dimension
461
461
 
462
462
  companion object Companion {
463
463
  private const val RUBBER_BAND_COEFFICIENT = 0.55f
@@ -5,6 +5,7 @@ import androidx.compose.foundation.border
5
5
  import androidx.compose.foundation.clickable
6
6
  import androidx.compose.foundation.layout.Box
7
7
  import androidx.compose.foundation.layout.size
8
+ import androidx.compose.foundation.shape.CircleShape
8
9
  import androidx.compose.foundation.shape.RoundedCornerShape
9
10
  import androidx.compose.runtime.Composable
10
11
  import androidx.compose.runtime.remember
@@ -12,6 +13,7 @@ import androidx.compose.ui.Alignment
12
13
  import androidx.compose.ui.Modifier
13
14
  import androidx.compose.ui.draw.clip
14
15
  import androidx.compose.ui.graphics.Color
16
+ import androidx.compose.ui.graphics.Shape
15
17
  import androidx.compose.ui.unit.Dp
16
18
  import androidx.compose.ui.unit.dp
17
19
  import vn.momo.kits.application.IsShowBaseLineDebug
@@ -21,69 +23,58 @@ import vn.momo.kits.const.Radius
21
23
  import vn.momo.kits.modifier.conditional
22
24
 
23
25
  data class IconSpecs(
24
- val width: Dp,
25
- val height: Dp,
26
- val radius: Dp,
27
- val size: Dp
26
+ val box: Dp,
27
+ val icon: Dp,
28
28
  )
29
29
 
30
30
  enum class IconSize(val value: IconSpecs) {
31
- LARGE(
32
- IconSpecs(
33
- height = 48.dp,
34
- radius = Radius.XL,
35
- width = 48.dp,
36
- size = 48.dp
37
- )
38
- ),
39
- SMALL(
40
- IconSpecs(
41
- height = 40.dp,
42
- radius = Radius.XL,
43
- width = 40.dp,
44
- size = 40.dp
45
- )
46
- )
31
+ LARGE(IconSpecs(box = 48.dp, icon = 24.dp)),
32
+ MEDIUM(IconSpecs(box = 36.dp, icon = 16.dp)),
33
+ SMALL(IconSpecs(box = 28.dp, icon = 16.dp)),
34
+ }
35
+
36
+ enum class IconShape {
37
+ CIRCLE,
38
+ SQUARE,
47
39
  }
48
40
 
49
- // Pre-computed shape to avoid repeated creation
50
- private val iconButtonShape = RoundedCornerShape(Radius.XL)
41
+ // Square keeps an 8dp rounded corner; circle is fully rounded regardless of size.
42
+ private val squareShape = RoundedCornerShape(Radius.S)
51
43
 
52
- // Cache for icon sizes to avoid repeated calculations
53
- private val iconSizeMap = mapOf(
54
- IconSize.SMALL to 16.dp,
55
- IconSize.LARGE to 24.dp
56
- )
44
+ private fun IconShape.toShape(): Shape = when (this) {
45
+ IconShape.CIRCLE -> CircleShape
46
+ IconShape.SQUARE -> squareShape
47
+ }
57
48
 
58
49
  @Composable
59
- fun getIconStyle(type: ButtonType, color: Color? = null): Modifier {
50
+ internal fun getIconStyle(type: ButtonType, shape: Shape, color: Color? = null): Modifier {
60
51
  val theme = AppTheme.current
61
52
 
62
- return remember(type, color, theme) {
53
+ return remember(type, shape, color, theme) {
63
54
  when (type) {
64
55
  ButtonType.DISABLED -> Modifier
65
- .background(theme.colors.background.disable, iconButtonShape)
66
- .border(0.dp, Color.Unspecified, iconButtonShape)
56
+ .background(theme.colors.background.disable, shape)
57
+ .border(0.dp, Color.Unspecified, shape)
67
58
 
68
59
  ButtonType.PRIMARY -> Modifier
69
- .background(theme.colors.primary, iconButtonShape)
70
- .border(0.dp, Color.Unspecified, iconButtonShape)
60
+ .background(theme.colors.primary, shape)
61
+ .border(0.dp, Color.Unspecified, shape)
71
62
 
72
63
  ButtonType.SECONDARY -> Modifier
73
- .background(theme.colors.background.surface, iconButtonShape)
74
- .border(1.dp, theme.colors.border.default, iconButtonShape)
64
+ .background(theme.colors.background.surface, shape)
65
+ .border(1.dp, theme.colors.border.default, shape)
75
66
 
76
67
  ButtonType.OUTLINE -> Modifier
77
- .background(theme.colors.background.surface, iconButtonShape)
78
- .border(1.dp, color ?: theme.colors.primary, iconButtonShape)
68
+ .background(theme.colors.background.surface, shape)
69
+ .border(1.dp, color ?: theme.colors.primary, shape)
79
70
 
80
71
  ButtonType.TONAL -> Modifier
81
- .background(theme.colors.background.tonal, iconButtonShape)
82
- .border(0.dp, Color.Unspecified, iconButtonShape)
72
+ .background(theme.colors.background.tonal, shape)
73
+ .border(0.dp, Color.Unspecified, shape)
83
74
 
84
75
  ButtonType.DANGER -> Modifier
85
- .background(theme.colors.error.primary, iconButtonShape)
86
- .border(0.dp, Color.Unspecified, iconButtonShape)
76
+ .background(theme.colors.error.primary, shape)
77
+ .border(0.dp, Color.Unspecified, shape)
87
78
 
88
79
  ButtonType.TEXT -> Modifier
89
80
  }
@@ -91,18 +82,10 @@ fun getIconStyle(type: ButtonType, color: Color? = null): Modifier {
91
82
  }
92
83
 
93
84
  @Composable
94
- fun getIconColor(type: ButtonType): Color {
85
+ internal fun getIconColor(type: ButtonType): Color {
95
86
  val theme = AppTheme.current
96
87
  return remember(type, theme) {
97
- when (type) {
98
- ButtonType.DISABLED -> theme.colors.text.disable
99
- ButtonType.PRIMARY -> Colors.black_01
100
- ButtonType.SECONDARY -> theme.colors.text.default
101
- ButtonType.OUTLINE -> theme.colors.primary
102
- ButtonType.TONAL -> theme.colors.primary
103
- ButtonType.DANGER -> Colors.black_01
104
- ButtonType.TEXT -> theme.colors.primary
105
- }
88
+ getButtonColor(type, theme)
106
89
  }
107
90
  }
108
91
 
@@ -111,38 +94,32 @@ fun IconButton(
111
94
  onClick: () -> Unit,
112
95
  type: ButtonType = ButtonType.PRIMARY,
113
96
  size: IconSize = IconSize.SMALL,
97
+ shape: IconShape = IconShape.CIRCLE,
114
98
  icon: String = "",
115
99
  ) {
116
- // Memoize icon size calculation
117
- val iconSize = remember(size) {
118
- iconSizeMap[size] ?: 16.dp
119
- }
100
+ val specs = size.value
120
101
 
121
- // Memoize enabled state
122
102
  val isEnabled = remember(type) {
123
103
  type != ButtonType.DISABLED
124
104
  }
125
105
 
126
- // Memoize radius for clipping
127
- val radius = remember(size) {
128
- size.value.radius
129
- }
106
+ val boxShape = remember(shape) { shape.toShape() }
130
107
 
131
108
  Box(
132
109
  modifier = Modifier
133
- .size(size.value.size)
134
- .then(getIconStyle(type))
110
+ .size(specs.box)
111
+ .then(getIconStyle(type, boxShape))
135
112
  .conditional(IsShowBaseLineDebug) {
136
113
  border(1.dp, Colors.blue_03)
137
114
  }
138
- .clip(RoundedCornerShape(radius))
115
+ .clip(boxShape)
139
116
  .clickable(enabled = isEnabled, onClick = onClick),
140
117
  contentAlignment = Alignment.Center
141
118
  ) {
142
119
  Icon(
143
120
  source = icon,
144
121
  color = getIconColor(type),
145
- size = iconSize,
122
+ size = specs.icon,
146
123
  )
147
124
  }
148
- }
125
+ }
@@ -1,7 +1,9 @@
1
1
  package vn.momo.kits.components
2
2
 
3
3
  import androidx.compose.foundation.border
4
+ import androidx.compose.foundation.layout.Box
4
5
  import androidx.compose.foundation.layout.BoxWithConstraints
6
+ import androidx.compose.foundation.layout.fillMaxSize
5
7
  import androidx.compose.runtime.Composable
6
8
  import androidx.compose.runtime.getValue
7
9
  import androidx.compose.runtime.mutableStateOf
@@ -17,10 +19,12 @@ import androidx.compose.ui.semantics.contentDescription
17
19
  import androidx.compose.ui.semantics.semantics
18
20
  import androidx.compose.ui.platform.LocalDensity
19
21
  import androidx.compose.ui.unit.dp
20
- import coil3.compose.AsyncImage
22
+ import coil3.compose.AsyncImage as CoilAsyncImage
21
23
  import vn.momo.kits.application.IsShowBaseLineDebug
22
24
  import vn.momo.kits.const.AppTheme
23
25
  import vn.momo.kits.const.Colors
26
+ import vn.momo.kits.gifimage.GifImage
27
+ import vn.momo.kits.gifimage.GifImageState
24
28
  import vn.momo.kits.modifier.conditional
25
29
 
26
30
  data class Options(
@@ -73,6 +77,19 @@ private fun getHostFromUrl(url: String): String? {
73
77
  }
74
78
  }
75
79
 
80
+ private fun isGifUrl(url: String): Boolean {
81
+ val path = url.substringBefore('#').substringBefore('?')
82
+ return path.endsWith(".gif", ignoreCase = true)
83
+ }
84
+
85
+ private fun GifImageState.toImageState(): ImageState {
86
+ return when (this) {
87
+ GifImageState.Success -> ImageState.Success
88
+ GifImageState.Error -> ImageState.Error
89
+ GifImageState.Loading -> ImageState.Loading
90
+ }
91
+ }
92
+
76
93
  // Optimized query parameter appending
77
94
  private fun appendSizeQueryParam(url: String, value: String): String {
78
95
  val fragmentIndex = url.indexOf('#')
@@ -95,12 +112,12 @@ fun Image(
95
112
  modifier: Modifier = Modifier,
96
113
  options: Options? = null,
97
114
  loading: Boolean = true,
115
+ onStateChanged: (ImageState) -> Unit = {},
98
116
  ) {
99
117
  val imageOptions = remember(options) {
100
118
  options ?: Options()
101
119
  }
102
120
 
103
- var imageState by remember { mutableStateOf(ImageState.Loading) }
104
121
  val density = LocalDensity.current
105
122
 
106
123
  BoxWithConstraints(
@@ -121,34 +138,46 @@ fun Image(
121
138
  processedUrl
122
139
  }
123
140
  }
124
- else -> source
141
+ else -> source.toString()
125
142
  }
126
143
  }
127
144
 
128
- AsyncImage(
129
- modifier = Modifier.matchParentSize(),
130
- model = urlToLoad,
131
- contentDescription = null,
132
- contentScale = imageOptions.contentScale,
133
- alignment = imageOptions.alignment,
134
- colorFilter = imageOptions.colorFilter,
135
- alpha = imageOptions.alpha,
136
- onLoading = { imageState = ImageState.Loading },
137
- onSuccess = { imageState = ImageState.Success },
138
- onError = { imageState = ImageState.Error },
139
- )
145
+ var imageState by remember(urlToLoad) { mutableStateOf(ImageState.Loading) }
146
+ fun updateImageState(state: ImageState) {
147
+ imageState = state
148
+ onStateChanged(state)
149
+ }
150
+
151
+ if (isGifUrl(urlToLoad)) {
152
+ GifImage(
153
+ modifier = Modifier.matchParentSize(),
154
+ url = urlToLoad,
155
+ contentDescription = null,
156
+ contentScale = imageOptions.contentScale,
157
+ alignment = imageOptions.alignment,
158
+ colorFilter = imageOptions.colorFilter,
159
+ alpha = imageOptions.alpha,
160
+ onStateChanged = { updateImageState(it.toImageState()) },
161
+ )
162
+ } else {
163
+ CoilAsyncImage(
164
+ modifier = Modifier.matchParentSize(),
165
+ model = urlToLoad,
166
+ contentDescription = null,
167
+ contentScale = imageOptions.contentScale,
168
+ alignment = imageOptions.alignment,
169
+ colorFilter = imageOptions.colorFilter,
170
+ alpha = imageOptions.alpha,
171
+ onLoading = { updateImageState(ImageState.Loading) },
172
+ onSuccess = { updateImageState(ImageState.Success) },
173
+ onError = { updateImageState(ImageState.Error) },
174
+ )
175
+ }
140
176
 
141
177
  when (imageState) {
142
- ImageState.Loading -> if (loading) Skeleton()
143
- ImageState.Error -> {
144
- val theme = AppTheme.current
145
- Icon(
146
- source = "media_fail",
147
- color = theme.colors.text.disable,
148
- modifier = Modifier.align(Alignment.Center)
149
- )
150
- }
151
178
  ImageState.Success -> {}
179
+ ImageState.Error -> ImageError()
180
+ ImageState.Loading -> if (loading) Skeleton()
152
181
  }
153
182
  }
154
183
  }
@@ -156,7 +185,7 @@ fun Image(
156
185
  // Extracted URL processing logic for better performance
157
186
  private fun processImageUrl(url: String, maxWidth: androidx.compose.ui.unit.Dp, density: androidx.compose.ui.unit.Density): String {
158
187
  val host = getHostFromUrl(url)
159
- return if (host != null && supportedDomains.contains(host)) {
188
+ return if (!isGifUrl(url) && host != null && supportedDomains.contains(host)) {
160
189
  val widthPx = with(density) { maxWidth.roundToPx() }
161
190
  val pixelRatio = density.density
162
191
  val pixelFitForWidth = widthPx * pixelRatio
@@ -167,6 +196,20 @@ private fun processImageUrl(url: String, maxWidth: androidx.compose.ui.unit.Dp,
167
196
  }
168
197
  }
169
198
 
199
+ @Composable
200
+ private fun ImageError() {
201
+ val theme = AppTheme.current
202
+ Box(
203
+ modifier = Modifier.fillMaxSize(),
204
+ contentAlignment = Alignment.Center
205
+ ) {
206
+ Icon(
207
+ source = "media_fail",
208
+ color = theme.colors.text.disable,
209
+ )
210
+ }
211
+ }
212
+
170
213
  @Composable
171
214
  fun Image(
172
215
  source: Painter,
@@ -185,4 +228,4 @@ fun Image(
185
228
  colorFilter = colorFilter,
186
229
  alpha = alpha,
187
230
  )
188
- }
231
+ }
@@ -3,11 +3,7 @@ package vn.momo.kits.components
3
3
  import androidx.compose.foundation.background
4
4
  import androidx.compose.foundation.border
5
5
  import androidx.compose.foundation.clickable
6
- import androidx.compose.foundation.layout.Column
7
- import androidx.compose.foundation.layout.Row
8
- import androidx.compose.foundation.layout.height
9
- import androidx.compose.foundation.layout.padding
10
- import androidx.compose.foundation.layout.width
6
+ import androidx.compose.foundation.layout.*
11
7
  import androidx.compose.foundation.shape.RoundedCornerShape
12
8
  import androidx.compose.runtime.Composable
13
9
  import androidx.compose.ui.Modifier