@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
@@ -0,0 +1,153 @@
1
+ import SwiftUI
2
+
3
+ public enum InformationState {
4
+ case `default`
5
+ case warning
6
+ case error
7
+ }
8
+
9
+ public struct Information: View {
10
+ @Environment(\.appTheme) private var theme
11
+
12
+ private let title: String?
13
+ private let description: String
14
+ private let state: InformationState
15
+ private let image: String?
16
+ private let onPressAction: (() -> Void)?
17
+ private let showIcon: Bool
18
+ private let action: String?
19
+ private let showIconClose: Bool
20
+ private let onPressClose: (() -> Void)?
21
+
22
+ public init(
23
+ title: String? = nil,
24
+ description: String = "Description",
25
+ state: InformationState = .default,
26
+ image: String? = nil,
27
+ onPressAction: (() -> Void)? = nil,
28
+ showIcon: Bool = true,
29
+ action: String? = nil,
30
+ showIconClose: Bool = true,
31
+ onPressClose: (() -> Void)? = nil
32
+ ) {
33
+ self.title = title
34
+ self.description = description
35
+ self.state = state
36
+ self.image = image
37
+ self.onPressAction = onPressAction
38
+ self.showIcon = showIcon
39
+ self.action = action
40
+ self.showIconClose = showIconClose
41
+ self.onPressClose = onPressClose
42
+ }
43
+
44
+ private var borderColor: Color {
45
+ switch state {
46
+ case .default: return Colors.blue07
47
+ case .warning: return Colors.yellow06
48
+ case .error: return Colors.red07
49
+ }
50
+ }
51
+
52
+ private var backgroundColor: Color {
53
+ switch state {
54
+ case .default: return Colors.blue10
55
+ case .warning: return Colors.yellow09
56
+ case .error: return Colors.red10
57
+ }
58
+ }
59
+
60
+ private var accentColor: Color {
61
+ switch state {
62
+ case .default: return Colors.blue03
63
+ case .warning: return Colors.orange03
64
+ case .error: return Colors.red03
65
+ }
66
+ }
67
+
68
+ private var iconSource: String {
69
+ switch state {
70
+ case .default: return "notifications_info"
71
+ case .warning: return "24_notifications_alert_triangle"
72
+ case .error: return "24_notifications_alert_octagon"
73
+ }
74
+ }
75
+
76
+ public var body: some View {
77
+ VStack(alignment: .leading, spacing: 0) {
78
+ HStack(alignment: .top, spacing: 0) {
79
+ if let image {
80
+ ImageView(image)
81
+ .frame(width: 40, height: 40)
82
+ .clipShape(RoundedRectangle(cornerRadius: Radius.S))
83
+ .padding(.trailing, Spacing.S)
84
+ } else if showIcon {
85
+ Icon(source: iconSource, size: 16, color: accentColor)
86
+ .padding(.trailing, Spacing.S)
87
+ }
88
+
89
+ VStack(alignment: .leading, spacing: 0) {
90
+ if let title {
91
+ MomoText(title, typography: .labelDefaultMedium)
92
+ }
93
+ MomoText(description, typography: .descriptionDefaultRegular)
94
+ }
95
+ .frame(maxWidth: .infinity, alignment: .leading)
96
+
97
+ if let onPressClose, showIconClose {
98
+ Icon(source: "navigation_close", size: 16, color: theme.colors.text.default)
99
+ .contentShape(Rectangle())
100
+ .onTapGesture(perform: onPressClose)
101
+ }
102
+ }
103
+
104
+ if let action, let onPressAction {
105
+ MomoText(action, typography: .actionXsBold, color: accentColor)
106
+ .frame(maxWidth: .infinity, alignment: .trailing)
107
+ .contentShape(Rectangle())
108
+ .onTapGesture(perform: onPressAction)
109
+ .padding(.top, Spacing.S)
110
+ }
111
+ }
112
+ .padding(Spacing.M)
113
+ .background(
114
+ RoundedRectangle(cornerRadius: Radius.S)
115
+ .fill(backgroundColor)
116
+ )
117
+ .overlay(
118
+ RoundedRectangle(cornerRadius: Radius.S)
119
+ .stroke(borderColor, lineWidth: 0.5)
120
+ )
121
+ }
122
+ }
123
+
124
+ // MARK: - Preview
125
+ #if DEBUG
126
+ struct Information_Previews: PreviewProvider {
127
+ static var previews: some View {
128
+ VStack(spacing: 16) {
129
+ Information(
130
+ title: "Information",
131
+ description: "This is a default information message."
132
+ )
133
+ Information(
134
+ title: "Warning",
135
+ description: "This is a warning message.",
136
+ state: .warning
137
+ )
138
+ Information(
139
+ title: "Error",
140
+ description: "This is an error message.",
141
+ state: .error,
142
+ onPressAction: {}, action: "Retry"
143
+ )
144
+ Information(
145
+ description: "Dismissible information.",
146
+ onPressClose: {}
147
+ )
148
+ }
149
+ .padding()
150
+ .previewLayout(.sizeThatFits)
151
+ }
152
+ }
153
+ #endif
@@ -8,6 +8,8 @@
8
8
  import SwiftUI
9
9
 
10
10
  public struct ErrorView: View {
11
+ @Environment(\.appTheme) private var theme
12
+
11
13
  public var errorMessage: String
12
14
  public var errorSpacing: Bool
13
15
  public var hintText: String
@@ -43,7 +45,7 @@ public struct ErrorView: View {
43
45
  // MARK: - Helpers
44
46
 
45
47
  private func displayColor() -> Color {
46
- !errorMessage.isEmpty ? Colors.red03 : Colors.black12
48
+ !errorMessage.isEmpty ? theme.colors.error.primary : theme.colors.text.hint
47
49
  }
48
50
 
49
51
  private func displayText() -> String {
@@ -3,12 +3,14 @@ import SwiftUI
3
3
  import Combine
4
4
 
5
5
  public struct Input: View {
6
+ @Environment(\.appTheme) private var theme
6
7
  @Binding public var text: String
7
8
 
8
9
  public var placeholder: String
9
10
  public var floatingValue: String
11
+ public var floatingValueColor: Color?
10
12
  public var floatingIcon: String
11
- public var floatingIconColor: Color
13
+ public var floatingIconColor: Color?
12
14
  public var size: InputSize
13
15
  public var hintText: String
14
16
  public var error: String
@@ -17,9 +19,9 @@ public struct Input: View {
17
19
  public var readOnly: Bool
18
20
  public var secureTextEntry: Bool
19
21
  public var rightIcon: String
20
- public var rightIconColor: Color
22
+ public var rightIconColor: Color?
21
23
  public var leadingIcon: String
22
- public var leadingIconColor: Color
24
+ public var leadingIconColor: Color?
23
25
  public var loading: Bool
24
26
  public var required: Bool
25
27
  public var maxLength: Int?
@@ -33,13 +35,16 @@ public struct Input: View {
33
35
 
34
36
  @State private var isFocused: Bool = false
35
37
  @State private var isPasswordHidden: Bool = true
38
+ @FocusState private var isFieldFocused: Bool
39
+ @State private var floatingLabelHeight: CGFloat = 16
36
40
 
37
41
  public init(
38
42
  text: Binding<String>,
39
43
  placeholder: String = "",
40
44
  floatingValue: String = "",
45
+ floatingValueColor: Color? = nil,
41
46
  floatingIcon: String = "",
42
- floatingIconColor: Color = Colors.primary,
47
+ floatingIconColor: Color? = nil,
43
48
  size: InputSize = .small,
44
49
  hintText: String = "",
45
50
  error: String = "",
@@ -48,9 +53,9 @@ public struct Input: View {
48
53
  readOnly: Bool = false,
49
54
  secureTextEntry: Bool = false,
50
55
  rightIcon: String = "",
51
- rightIconColor: Color = Colors.black17,
56
+ rightIconColor: Color? = nil,
52
57
  leadingIcon: String = "",
53
- leadingIconColor: Color = Colors.black12,
58
+ leadingIconColor: Color? = nil,
54
59
  loading: Bool = false,
55
60
  required: Bool = false,
56
61
  maxLength: Int? = nil,
@@ -65,6 +70,7 @@ public struct Input: View {
65
70
  self._text = text
66
71
  self.placeholder = placeholder
67
72
  self.floatingValue = floatingValue
73
+ self.floatingValueColor = floatingValueColor
68
74
  self.floatingIcon = floatingIcon
69
75
  self.floatingIconColor = floatingIconColor
70
76
  self.size = size
@@ -95,8 +101,13 @@ public struct Input: View {
95
101
  let textBinding = Binding<String>(
96
102
  get: { self.text },
97
103
  set: { newValue in
98
- self.text = newValue
99
- self.onChangeText?(limitText(newValue))
104
+ // Trim atomically before publishing, mirroring Kotlin's `onValueChange`
105
+ // (`newText.take(maxLength)` before the state ever updates) — avoids a
106
+ // render with the untrimmed value that a separate `.onChange` correction
107
+ // would otherwise briefly show.
108
+ let limited = limitText(newValue)
109
+ self.text = limited
110
+ self.onChangeText?(limited)
100
111
  }
101
112
  )
102
113
 
@@ -107,15 +118,26 @@ public struct Input: View {
107
118
  HStack(spacing: Spacing.XS) {
108
119
  MomoText(floatingValue, typography: .labelSMedium, color: getFloatingColor())
109
120
  if required {
110
- MomoText("*", typography: .labelSMedium, color: Colors.red03)
121
+ MomoText("*", typography: .labelSMedium, color: theme.colors.error.primary)
111
122
  }
112
123
  if !floatingIcon.isEmpty {
113
124
  Icon(source: floatingIcon, size: 16, color: getFloatingIconColor())
114
125
  }
115
126
  }
116
127
  .padding(.horizontal, Spacing.S)
117
- .background(Colors.black01)
118
- .offset(x: Spacing.S, y: -8)
128
+ .background(
129
+ GeometryReader { geo in
130
+ Color.clear.onAppear { floatingLabelHeight = geo.size.height }
131
+ }
132
+ )
133
+ .background(theme.colors.background.surface)
134
+ // Kotlin centers the label within the (box-height-tall) decorationBox
135
+ // by default, then applies `offsetY = -size.values.height / 2` — net
136
+ // effect: the label ends up centered exactly on the box's top border
137
+ // (spanning -labelHeight/2 ... +labelHeight/2 around y=0). Our ZStack
138
+ // anchors top-leading instead, so reproducing that requires offsetting
139
+ // by half the label's OWN measured height, not half the box height.
140
+ .offset(x: Spacing.S, y: -floatingLabelHeight / 2)
119
141
  .zIndex(10)
120
142
  }
121
143
 
@@ -123,7 +145,7 @@ public struct Input: View {
123
145
  HStack(alignment: .center, spacing: 0) {
124
146
  // Leading icon
125
147
  if !leadingIcon.isEmpty {
126
- Icon(source: leadingIcon, size: size == .small ? 24 : 32, color: leadingIconColor)
148
+ Icon(source: leadingIcon, size: size == .small ? 24 : 32, color: getLeadingIconColor())
127
149
  .padding(.trailing, Spacing.M)
128
150
  }
129
151
 
@@ -144,8 +166,10 @@ public struct Input: View {
144
166
  fontSize: scaleSize(14),
145
167
  fontWeight: fontWeight == .bold ? .bold : .regular,
146
168
  textColor: UIColor(getTextColor()),
169
+ cursorColor: UIColor(theme.colors.primary),
147
170
  isDisabled: disabled || readOnly,
148
171
  maxLength: maxLength,
172
+ autofocus: autofocus,
149
173
  onFocusChange: { focused in
150
174
  handleFocusChange(focused)
151
175
  },
@@ -157,14 +181,13 @@ public struct Input: View {
157
181
  })
158
182
  .keyboardType(keyboardType)
159
183
  .font(fontWeight == .bold ? .action_s_bold : .body_default_regular)
184
+ .ignoreBoldTextSetting()
160
185
  .foregroundColor(getTextColor())
161
186
  .disabled(disabled || readOnly)
162
- .applyPrimaryCursorColor()
163
- .onChange(of: text) { newValue in
164
- let limited = limitText(newValue)
165
- if limited != newValue {
166
- text = limited
167
- }
187
+ .applyCursorColor(theme.colors.primary)
188
+ .focused($isFieldFocused)
189
+ .onAppear {
190
+ if autofocus { isFieldFocused = true }
168
191
  }
169
192
  }
170
193
  }
@@ -175,7 +198,7 @@ public struct Input: View {
175
198
  text = ""
176
199
  onChangeText?("")
177
200
  }) {
178
- Icon(source: "24_navigation_close_circle_full", size: 16, color: Colors.black12)
201
+ Icon(source: "24_navigation_close_circle_full", size: 16, color: theme.colors.text.hint)
179
202
  .padding(.leading, Spacing.S).accessibility(identifier: "ic_clear")
180
203
  }
181
204
  }
@@ -194,14 +217,14 @@ public struct Input: View {
194
217
  Icon(
195
218
  source: isPasswordHidden ? "24_security_eye_off" : "24_security_eye_open",
196
219
  size: 24,
197
- color: rightIconColor
220
+ color: getRightIconColor()
198
221
  )
199
222
  .padding(.leading, Spacing.S).accessibility(identifier: "ic_show_hide")
200
223
  }
201
224
  }
202
225
  } else if !rightIcon.isEmpty {
203
226
  SwiftUI.Button(action: { onRightIconPressed?() }) {
204
- Icon(source: rightIcon, size: 24, color: rightIconColor)
227
+ Icon(source: rightIcon, size: 24, color: getRightIconColor())
205
228
  .padding(.leading, Spacing.S)
206
229
  }
207
230
  }
@@ -210,7 +233,7 @@ public struct Input: View {
210
233
  .frame(height: scaleSize(size == .small ? 48 : 56, 1.1))
211
234
  .background(
212
235
  RoundedRectangle(cornerRadius: Radius.S)
213
- .fill(Colors.black01)
236
+ .fill(theme.colors.background.surface)
214
237
  )
215
238
  .overlay(
216
239
  RoundedRectangle(cornerRadius: Radius.S)
@@ -259,31 +282,39 @@ public struct Input: View {
259
282
 
260
283
  private func borderColor() -> Color {
261
284
  if disabled {
262
- return Colors.black04 // border.disable
285
+ return theme.colors.border.disable
263
286
  }
264
287
  if !error.isEmpty {
265
- return Colors.red03 // error.primary
288
+ return theme.colors.error.primary
266
289
  }
267
290
  if isFocused {
268
- return Colors.primary
291
+ return theme.colors.primary
269
292
  }
270
- return Colors.black04 // border.default
293
+ return theme.colors.border.default
271
294
  }
272
295
 
273
296
  private func getTextColor() -> Color {
274
- return disabled ? Colors.black09 : Colors.black17
297
+ return disabled ? theme.colors.text.disable : theme.colors.text.default
275
298
  }
276
299
 
277
300
  private func getPlaceholderColor() -> Color {
278
- return disabled ? Colors.black09 : Colors.black12
301
+ return disabled ? theme.colors.text.disable : theme.colors.text.hint
279
302
  }
280
303
 
281
304
  private func getFloatingColor() -> Color {
282
- return disabled ? Colors.black09 : Colors.black12
305
+ return disabled ? theme.colors.text.disable : (floatingValueColor ?? theme.colors.text.hint)
283
306
  }
284
307
 
285
308
  private func getFloatingIconColor() -> Color {
286
- return disabled ? Colors.black09 : floatingIconColor
309
+ return disabled ? theme.colors.text.disable : (floatingIconColor ?? theme.colors.text.default)
310
+ }
311
+
312
+ private func getLeadingIconColor() -> Color {
313
+ return disabled ? theme.colors.text.disable : (leadingIconColor ?? theme.colors.text.hint)
314
+ }
315
+
316
+ private func getRightIconColor() -> Color {
317
+ return disabled ? theme.colors.text.disable : (rightIconColor ?? theme.colors.text.default)
287
318
  }
288
319
  }
289
320
 
@@ -295,8 +326,10 @@ private struct SecureInputField: UIViewRepresentable {
295
326
  var fontSize: CGFloat
296
327
  var fontWeight: UIFont.Weight
297
328
  var textColor: UIColor
329
+ var cursorColor: UIColor
298
330
  var isDisabled: Bool
299
331
  var maxLength: Int?
332
+ var autofocus: Bool = false
300
333
  var onFocusChange: (Bool) -> Void
301
334
  var onChangeText: ((String) -> Void)?
302
335
 
@@ -315,12 +348,17 @@ private struct SecureInputField: UIViewRepresentable {
315
348
  textField.setContentHuggingPriority(.defaultLow, for: .horizontal)
316
349
  textField.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
317
350
  textField.text = text
318
- textField.tintColor = UIColor(Colors.primary)
351
+ textField.tintColor = cursorColor
319
352
  textField.addTarget(
320
353
  context.coordinator,
321
354
  action: #selector(Coordinator.textFieldDidChange(_:)),
322
355
  for: .editingChanged
323
356
  )
357
+ if autofocus {
358
+ DispatchQueue.main.async {
359
+ textField.becomeFirstResponder()
360
+ }
361
+ }
324
362
  return textField
325
363
  }
326
364
 
@@ -330,6 +368,8 @@ private struct SecureInputField: UIViewRepresentable {
330
368
  textField.text = text
331
369
  }
332
370
  textField.isEnabled = !isDisabled
371
+ textField.textColor = textColor
372
+ textField.tintColor = cursorColor
333
373
  if textField.keyboardType != keyboardType {
334
374
  textField.keyboardType = keyboardType
335
375
  textField.reloadInputViews()
@@ -400,9 +440,9 @@ private struct SecureInputField: UIViewRepresentable {
400
440
 
401
441
  // MARK: - Helper Extension
402
442
  private extension View {
403
- func applyPrimaryCursorColor() -> some View {
443
+ func applyCursorColor(_ color: Color) -> some View {
404
444
  if #available(iOS 15.0, *) {
405
- return self.tint(Colors.primary)
445
+ return self.tint(color)
406
446
  } else {
407
447
  return self
408
448
  }
@@ -7,23 +7,27 @@
7
7
 
8
8
  import SwiftUI
9
9
  public struct InputPhoneNumber: View {
10
+ @Environment(\.appTheme) private var theme
10
11
  @Binding public var text: String
11
12
 
12
13
  public var placeholder: String
13
14
  public var size: InputSize
14
15
  public var hintText: String
15
16
  public var error: String
17
+ public var errorSpacing: Bool
16
18
  public var loading: Bool
19
+ public var required: Bool
17
20
  public var rightIcon: String
18
- public var rightIconColor: Color
21
+ public var rightIconColor: Color?
19
22
  public var autofocus: Bool
20
23
  public var onChangeText: ((String) -> Void)?
21
24
  public var onFocus: (() -> Void)?
22
25
  public var onBlur: (() -> Void)?
23
26
  public var onRightIconPressed: (() -> Void)?
24
27
  public var accessibilityLabel: String?
25
-
28
+
26
29
  @State private var isFocused: Bool = false
30
+ @FocusState private var isFieldFocused: Bool
27
31
 
28
32
  public init(
29
33
  text: Binding<String>,
@@ -31,10 +35,11 @@ public struct InputPhoneNumber: View {
31
35
  size: InputSize = .small,
32
36
  hintText: String = "",
33
37
  error: String = "",
38
+ errorSpacing: Bool = false,
34
39
  loading: Bool = false,
35
40
  required: Bool = false,
36
41
  rightIcon: String = "",
37
- rightIconColor: Color = Colors.black12,
42
+ rightIconColor: Color? = nil,
38
43
  autofocus: Bool = false,
39
44
  onChangeText: ((String) -> Void)? = nil,
40
45
  onFocus: (() -> Void)? = nil,
@@ -47,7 +52,9 @@ public struct InputPhoneNumber: View {
47
52
  self.size = size
48
53
  self.hintText = hintText
49
54
  self.error = error
55
+ self.errorSpacing = errorSpacing
50
56
  self.loading = loading
57
+ self.required = required
51
58
  self.rightIcon = rightIcon
52
59
  self.rightIconColor = rightIconColor
53
60
  self.autofocus = autofocus
@@ -76,27 +83,36 @@ public struct InputPhoneNumber: View {
76
83
  .padding(.trailing, Spacing.XS)
77
84
 
78
85
  MomoText("+84", typography: size == .small ? .headerSSemibold : .headerMBold)
79
- .foregroundColor(Colors.black17)
86
+ .foregroundColor(theme.colors.text.default)
80
87
 
81
88
  Rectangle()
82
- .fill(Colors.black04)
89
+ .fill(theme.colors.border.default)
83
90
  .frame(width: 1, height: size == .small ? 24 : 32)
84
91
  .padding(.horizontal, Spacing.M)
85
92
 
86
93
  // Text input
87
94
  ZStack(alignment: .leading) {
88
95
  if text.isEmpty {
89
- MomoText(placeholder, typography: size == .small ? .headerSSemibold : .headerMBold, color: Colors.black12)
96
+ MomoText(
97
+ placeholder + (required ? " *" : ""),
98
+ typography: size == .small ? .headerSSemibold : .headerMBold,
99
+ color: theme.colors.text.hint
100
+ )
90
101
  }
91
-
102
+
92
103
  TextField("", text: textBinding, onEditingChanged: { focused in
93
104
  handleFocusChange(focused)
94
105
  })
95
106
  .keyboardType(.numberPad)
96
107
  .font(size == .small ? .header_s_semibold : .header_m_bold)
97
- .foregroundColor(Colors.black17)
98
- .applyPrimaryCursorColor()
108
+ .ignoreBoldTextSetting()
109
+ .foregroundColor(theme.colors.text.default)
110
+ .applyCursorColor(theme.colors.primary)
99
111
  .lineLimit(1)
112
+ .focused($isFieldFocused)
113
+ .onAppear {
114
+ if autofocus { isFieldFocused = true }
115
+ }
100
116
  .accessibility(identifier: accessibilityLabel ?? "")
101
117
  .accessibilityValue(textBinding.wrappedValue.isEmpty ? placeholder : textBinding.wrappedValue)
102
118
  }
@@ -107,7 +123,7 @@ public struct InputPhoneNumber: View {
107
123
  text = ""
108
124
  onChangeText?("")
109
125
  }) {
110
- Icon(source: "24_navigation_close_circle_full", size: 16, color: Colors.black12)
126
+ Icon(source: "24_navigation_close_circle_full", size: 16, color: theme.colors.text.hint)
111
127
  .padding(.leading, Spacing.S).accessibility(identifier: "ic_clear")
112
128
  }
113
129
  }
@@ -121,7 +137,7 @@ public struct InputPhoneNumber: View {
121
137
  // ✅ Right icon
122
138
  if !rightIcon.isEmpty {
123
139
  SwiftUI.Button(action: { onRightIconPressed?() }) {
124
- Icon(source: rightIcon, size: 24, color: rightIconColor)
140
+ Icon(source: rightIcon, size: 24, color: rightIconColor ?? theme.colors.text.default)
125
141
  .padding(.leading, Spacing.S)
126
142
  }
127
143
  }
@@ -130,7 +146,7 @@ public struct InputPhoneNumber: View {
130
146
  .frame(height: scaleSize(size == .small ? 48 : 56, 1.1))
131
147
  .background(
132
148
  RoundedRectangle(cornerRadius: Radius.S)
133
- .fill(Colors.black01)
149
+ .fill(theme.colors.background.surface)
134
150
  )
135
151
  .overlay(
136
152
  RoundedRectangle(cornerRadius: Radius.S)
@@ -140,7 +156,7 @@ public struct InputPhoneNumber: View {
140
156
  // Error or hint
141
157
  ErrorView(
142
158
  errorMessage: error,
143
- errorSpacing: false,
159
+ errorSpacing: errorSpacing,
144
160
  hintText: hintText
145
161
  )
146
162
  }
@@ -158,21 +174,18 @@ public struct InputPhoneNumber: View {
158
174
  }
159
175
 
160
176
  private func borderColor() -> Color {
161
- if !error.isEmpty { return Colors.red03 }
162
- if isFocused { return Colors.primary }
163
- return Colors.black04
177
+ if !error.isEmpty { return theme.colors.error.primary }
178
+ if isFocused { return theme.colors.primary }
179
+ return theme.colors.border.default
164
180
  }
165
181
  }
166
182
 
167
183
  private extension View {
168
- func applyPrimaryCursorColor() -> some View {
184
+ func applyCursorColor(_ color: Color) -> some View {
169
185
  if #available(iOS 15.0, *) {
170
- // Modern SwiftUI: use .tint() for cursor
171
- return self.tint(Colors.primary)
186
+ return self.tint(color)
172
187
  } else {
173
- // iOS 13–14: return unchanged (no tint support)
174
188
  return self
175
189
  }
176
190
  }
177
191
  }
178
-