@momo-kits/native-kits 0.163.1-beta.2-debug → 0.163.1-beta.20-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 (245) hide show
  1. package/.claude/settings.local.json +112 -0
  2. package/CLAUDE.md +1 -1
  3. package/compose/build.gradle.kts +2 -1
  4. package/compose/build.gradle.kts.backup +1 -0
  5. package/compose/compose.podspec +1 -1
  6. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/OsFontScale.android.kt +7 -0
  7. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/Platform.android.kt +30 -3
  8. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Context.kt +8 -10
  9. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderRight.kt +2 -3
  10. package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +3 -0
  11. package/compose/src/commonMain/kotlin/vn/momo/kits/application/WidgetContainer.kt +56 -0
  12. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +11 -9
  13. package/compose/src/commonMain/kotlin/vn/momo/kits/components/CupertinoOverscroll.kt +0 -1
  14. package/compose/src/commonMain/kotlin/vn/momo/kits/components/IconButton.kt +40 -55
  15. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Image.kt +69 -26
  16. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +5 -5
  17. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +3 -1
  18. package/compose/src/commonMain/kotlin/vn/momo/kits/components/ScaleSizeScope.kt +21 -0
  19. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +3 -6
  20. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Colors.kt +19 -0
  21. package/compose/src/commonMain/kotlin/vn/momo/kits/const/KitFontScale.kt +22 -0
  22. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +28 -21
  23. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Card.kt +50 -0
  24. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Item.kt +25 -22
  25. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Section.kt +37 -0
  26. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/BottomSheet.kt +68 -22
  27. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ModalScreen.kt +1 -1
  28. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigation.kt +7 -1
  29. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +112 -115
  30. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigator.kt +15 -3
  31. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +33 -9
  32. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTab.kt +6 -5
  33. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +3 -1
  34. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +2 -1
  35. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/tracking/ScreenTracker.kt +0 -1
  36. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/ComposeLottieAnimation.kt +23 -2
  37. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/OsFontScale.kt +9 -0
  38. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +11 -0
  39. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/OsFontScale.ios.kt +66 -0
  40. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +26 -3
  41. package/gradle/libs.versions.toml +2 -0
  42. package/gradle.properties +1 -1
  43. package/ios/Application/ApplicationEnvironment.swift +15 -3
  44. package/ios/Application/Components.swift +36 -30
  45. package/ios/Application/FloatingButton.swift +10 -9
  46. package/ios/Application/Localize.swift +309 -0
  47. package/ios/Application/MaxApi.swift +18 -0
  48. package/ios/Application/Navigation/BottomTab/BottomTab.swift +104 -0
  49. package/ios/Application/Navigation/BottomTab/BottomTabBar.swift +215 -0
  50. package/ios/Application/Navigation/BottomTab/CurvedContainer.swift +65 -0
  51. package/ios/Application/Navigation/HeaderBackProps.swift +66 -0
  52. package/ios/Application/Navigation/HeaderTitle.swift +57 -0
  53. package/ios/Application/Navigation/HeaderUser.swift +209 -0
  54. package/ios/Application/Navigation/NavigationContainer.swift +203 -0
  55. package/ios/Application/Navigation/NavigationOptions.swift +109 -0
  56. package/ios/Application/Navigation/Navigator.swift +385 -0
  57. package/ios/Application/Navigation/Overplay/BottomSheet.swift +256 -0
  58. package/ios/Application/Navigation/Overplay/ModalScreen.swift +74 -0
  59. package/ios/Application/Navigation/Overplay/SnackBar.swift +144 -0
  60. package/ios/Application/Navigation/Tracking/ScreenTracker.swift +117 -0
  61. package/ios/Application/Navigation/component/Header.swift +178 -0
  62. package/ios/Application/Navigation/component/HeaderBackground.swift +83 -0
  63. package/ios/Application/Navigation/component/HeaderColor.swift +65 -0
  64. package/ios/Application/Navigation/component/HeaderRightWidthKey.swift +11 -0
  65. package/ios/Application/Navigation/component/NavigationHeaderRight.swift +196 -0
  66. package/ios/Application/Screen.swift +2 -1
  67. package/ios/Application/StackScreen.swift +501 -0
  68. package/ios/Avatar/Avatar.swift +193 -0
  69. package/ios/Badge/Badge.swift +11 -14
  70. package/ios/Badge/BadgeRibbon.swift +91 -17
  71. package/ios/BaselineView/BaselineView.swift +163 -0
  72. package/ios/Button/Button.swift +137 -28
  73. package/ios/Carousel/Carousel.swift +196 -0
  74. package/ios/Checkbox/Checkbox.swift +23 -28
  75. package/ios/Chip/Chip.swift +56 -33
  76. package/ios/Collapse/Collapse.swift +192 -0
  77. package/ios/Colors+Radius+Spacing/Colors.swift +20 -17
  78. package/ios/Colors+Radius+Spacing/Spacing.swift +3 -1
  79. package/ios/Colors+Radius+Spacing/Theme.swift +295 -0
  80. package/ios/DateTimePicker/DateTimePicker.swift +212 -0
  81. package/ios/DateTimePicker/DateTimePickerTypes.swift +55 -0
  82. package/ios/DateTimePicker/DateTimePickerUtils.swift +167 -0
  83. package/ios/DateTimePicker/WheelPicker.swift +165 -0
  84. package/ios/Divider/Divider.swift +16 -0
  85. package/ios/Extensions/ActiveOpacityButtonStyle.swift +14 -0
  86. package/ios/Extensions/Color++.swift +32 -0
  87. package/ios/Icon/Icon.swift +10 -1
  88. package/ios/IconButton/IconButton.swift +140 -0
  89. package/ios/Image/Image.swift +16 -3
  90. package/ios/Information/Information.swift +3 -1
  91. package/ios/Input/ErrorView.swift +3 -1
  92. package/ios/Input/Input.swift +72 -33
  93. package/ios/Input/InputPhoneNumber.swift +33 -21
  94. package/ios/Input/InputSearch.swift +107 -48
  95. package/ios/Input/InputTextArea.swift +134 -64
  96. package/ios/InputDropDown/InputDropDown.swift +201 -0
  97. package/ios/InputMoney/InputMoney.swift +347 -0
  98. package/ios/InputOTP/InputOTP.swift +210 -0
  99. package/ios/Loader/Loader.swift +113 -0
  100. package/ios/MoMoUIKits.podspec +5 -0
  101. package/ios/Pagination/PaginationDot.swift +61 -0
  102. package/ios/Pagination/PaginationNumber.swift +35 -0
  103. package/ios/Pagination/PaginationScroll.swift +101 -0
  104. package/ios/Pagination/PaginationWhiteDot.swift +37 -0
  105. package/ios/Popup/PopupDisplay.swift +11 -20
  106. package/ios/Popup/PopupInput.swift +2 -8
  107. package/ios/Popup/PopupNotify.swift +218 -0
  108. package/ios/Popup/PopupPromotion.swift +5 -3
  109. package/ios/ProgressInfo/ProgressInfo.swift +296 -0
  110. package/ios/Radio/Radio.swift +69 -0
  111. package/ios/Rating/Rating.swift +82 -0
  112. package/ios/Resources/MoMoUIKitsColors.xcassets/AccentColor.colorset/Contents.json +11 -0
  113. package/ios/Resources/MoMoUIKitsColors.xcassets/Background.colorset/Contents.json +38 -0
  114. package/ios/Resources/MoMoUIKitsColors.xcassets/Border.colorset/Contents.json +38 -0
  115. package/ios/Resources/MoMoUIKitsColors.xcassets/Card.colorset/Contents.json +38 -0
  116. package/ios/Resources/MoMoUIKitsColors.xcassets/Contents.json +6 -0
  117. package/ios/Resources/MoMoUIKitsColors.xcassets/Error.colorset/Contents.json +38 -0
  118. package/ios/Resources/MoMoUIKitsColors.xcassets/Primary.colorset/Contents.json +38 -0
  119. package/ios/Resources/MoMoUIKitsColors.xcassets/PrimaryDark.colorset/Contents.json +38 -0
  120. package/ios/Resources/MoMoUIKitsColors.xcassets/PrimaryLight.colorset/Contents.json +38 -0
  121. package/ios/Resources/MoMoUIKitsColors.xcassets/Secondary.colorset/Contents.json +38 -0
  122. package/ios/Resources/MoMoUIKitsColors.xcassets/Success.colorset/Contents.json +38 -0
  123. package/ios/Resources/MoMoUIKitsColors.xcassets/Text.colorset/Contents.json +38 -0
  124. package/ios/Resources/MoMoUIKitsColors.xcassets/TextSecondary.colorset/Contents.json +38 -0
  125. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/Contents.json +9 -0
  126. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-default.colorset/Contents.json +38 -0
  127. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-disable.colorset/Contents.json +38 -0
  128. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-pressed.colorset/Contents.json +38 -0
  129. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-selected.colorset/Contents.json +38 -0
  130. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-surface.colorset/Contents.json +38 -0
  131. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-tonal.colorset/Contents.json +38 -0
  132. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/border-default.colorset/Contents.json +38 -0
  133. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/border-disable.colorset/Contents.json +38 -0
  134. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/gradient.colorset/Contents.json +38 -0
  135. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/primary.colorset/Contents.json +38 -0
  136. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/secondary.colorset/Contents.json +38 -0
  137. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/success-container.colorset/Contents.json +38 -0
  138. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/success-primary.colorset/Contents.json +38 -0
  139. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/success-secondary.colorset/Contents.json +38 -0
  140. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-default.colorset/Contents.json +38 -0
  141. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-disable.colorset/Contents.json +38 -0
  142. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-hint.colorset/Contents.json +38 -0
  143. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-secondary.colorset/Contents.json +38 -0
  144. package/ios/Resources/MoMoUIKitsColors.xcassets/Warning.colorset/Contents.json +38 -0
  145. package/ios/Skeleton/Skeleton.swift +99 -0
  146. package/ios/Slider/Slider.swift +237 -0
  147. package/ios/Stepper/Stepper.swift +220 -0
  148. package/ios/Steps/Steps.swift +467 -0
  149. package/ios/SuggestAction/SuggestAction.swift +99 -0
  150. package/ios/Swipeable/SwipeCell.swift +187 -0
  151. package/ios/Swipeable/SwipeCellModel.swift +21 -0
  152. package/ios/Switch/Switch.swift +53 -28
  153. package/ios/TabView/TabView.swift +534 -0
  154. package/ios/Tag/Tag.swift +98 -0
  155. package/ios/Template/TrustBanner/TrustBanner.swift +7 -8
  156. package/ios/Title/Title.swift +269 -0
  157. package/ios/Tooltip/Tooltip.swift +485 -0
  158. package/ios/Typography/FontScaleStore.swift +19 -0
  159. package/ios/Typography/Text.swift +86 -17
  160. package/ios/Typography/Typography.swift +12 -14
  161. package/ios/Uploader/Uploader.swift +174 -0
  162. package/ios/native-kits.podspec +61 -8
  163. package/ios-demo/MoMoUIKitsDemo.podspec +20 -0
  164. package/ios-demo/README.md +120 -0
  165. package/ios-demo/Resources/dot_loading.json +558 -0
  166. package/ios-demo/Resources/icon.json +4052 -0
  167. package/ios-demo/Resources/lottie_circle_loader.json +1 -0
  168. package/ios-demo/Sources/MoMoUIKitsDemo/DemoScaffold.swift +48 -0
  169. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsBadgeDemoView.swift +25 -0
  170. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsButtonDemoView.swift +26 -0
  171. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsCheckboxDemoView.swift +19 -0
  172. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsChipDemoView.swift +33 -0
  173. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsInputDemoView.swift +48 -0
  174. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsPopupDemoView.swift +21 -0
  175. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsRadioDemoView.swift +17 -0
  176. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsTypographyDemoView.swift +28 -0
  177. package/ios-demo/Sources/MoMoUIKitsDemo/MoMoUIKitsDemoContext.swift +31 -0
  178. package/ios-demo/Sources/MoMoUIKitsDemo/MoMoUIKitsDemoFactory.swift +24 -0
  179. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/AnimatedHeaderDemo.swift +110 -0
  180. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/AvatarDemo.swift +93 -0
  181. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BadgeDemo.swift +269 -0
  182. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BaselineView.swift +117 -0
  183. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BottomTabDemo.swift +89 -0
  184. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ButtonDemo.swift +100 -0
  185. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CarouselDemo.swift +126 -0
  186. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CheckboxDemo.swift +64 -0
  187. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ChipDemo.swift +20 -0
  188. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CollapseDemo.swift +93 -0
  189. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ContentView.swift +107 -0
  190. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DateTimePickerDemo.swift +124 -0
  191. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DividerDemo.swift +14 -0
  192. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/HeaderUserDemo.swift +49 -0
  193. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/Home.swift +279 -0
  194. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/IconButtonDemo.swift +58 -0
  195. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ImageDemo.swift +78 -0
  196. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InformationDemo.swift +138 -0
  197. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputDemo.swift +111 -0
  198. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputDropDownDemo.swift +136 -0
  199. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputMoneyDemo.swift +107 -0
  200. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputOTPDemo.swift +73 -0
  201. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputPhoneNumberDemo.swift +100 -0
  202. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputSearchDemo.swift +32 -0
  203. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputTextAreaDemo.swift +57 -0
  204. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/LoaderDemo.swift +70 -0
  205. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/LocalizeDemo.swift +188 -0
  206. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/NavigationDemo.swift +229 -0
  207. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PaginationDemo.swift +72 -0
  208. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupDisplayDemo.swift +175 -0
  209. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupNotifyDemo.swift +121 -0
  210. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupPromotionDemo.swift +76 -0
  211. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ProgressInfoDemo.swift +89 -0
  212. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/RadioDemo.swift +32 -0
  213. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/RatingDemo.swift +56 -0
  214. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SkeletonDemo.swift +32 -0
  215. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SliderDemo.swift +150 -0
  216. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SnackBarDemo.swift +138 -0
  217. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/StepperDemo.swift +103 -0
  218. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/StepsDemo.swift +94 -0
  219. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SuggestActionDemo.swift +79 -0
  220. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SwipeDemo.swift +152 -0
  221. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SwitchDemo.swift +33 -0
  222. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TabViewDemo.swift +190 -0
  223. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TagDemo.swift +34 -0
  224. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ThemeDemo.swift +182 -0
  225. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TitleDemo.swift +109 -0
  226. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TooltipDemo.swift +187 -0
  227. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TypographyDemo.swift +87 -0
  228. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/UploaderDemo.swift +131 -0
  229. package/ios-demo/Sources/MoMoUIKitsDemo/SwiftUIDemoBrowserView.swift +51 -0
  230. package/ios-demo/Sources/MoMoUIKitsDemo/UIKitsDemoModels.swift +15 -0
  231. package/ios-demo/Sources/MoMoUIKitsDemo/UIKitsDemoRegistry.swift +73 -0
  232. package/local.properties +2 -2
  233. package/package.json +1 -1
  234. package/publish.sh +53 -0
  235. package/scripts/gen-ios-color.mjs +136 -0
  236. package/example/ios/Example.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
  237. package/example/ios/Example.xcworkspace/xcuserdata/huynhdung.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  238. package/example/ios/Example.xcworkspace/xcuserdata/huynhdung.xcuserdatad/xcschemes/xcschememanagement.plist +0 -5
  239. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/MoMoUIKits.xcscheme +0 -58
  240. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/Pods-Example.xcscheme +0 -58
  241. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/SDWebImage.xcscheme +0 -58
  242. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/SDWebImageSwiftUI.xcscheme +0 -58
  243. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/SkeletonUI.xcscheme +0 -58
  244. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/huynhdung.xcuserdatad/xcschemes/xcschememanagement.plist +0 -46
  245. package/ios/Application/FontScaleStore.swift +0 -59
@@ -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
  },
@@ -160,12 +184,10 @@ public struct Input: View {
160
184
  .ignoreBoldTextSetting()
161
185
  .foregroundColor(getTextColor())
162
186
  .disabled(disabled || readOnly)
163
- .applyPrimaryCursorColor()
164
- .onChange(of: text) { newValue in
165
- let limited = limitText(newValue)
166
- if limited != newValue {
167
- text = limited
168
- }
187
+ .applyCursorColor(theme.colors.primary)
188
+ .focused($isFieldFocused)
189
+ .onAppear {
190
+ if autofocus { isFieldFocused = true }
169
191
  }
170
192
  }
171
193
  }
@@ -176,7 +198,7 @@ public struct Input: View {
176
198
  text = ""
177
199
  onChangeText?("")
178
200
  }) {
179
- 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)
180
202
  .padding(.leading, Spacing.S).accessibility(identifier: "ic_clear")
181
203
  }
182
204
  }
@@ -195,14 +217,14 @@ public struct Input: View {
195
217
  Icon(
196
218
  source: isPasswordHidden ? "24_security_eye_off" : "24_security_eye_open",
197
219
  size: 24,
198
- color: rightIconColor
220
+ color: getRightIconColor()
199
221
  )
200
222
  .padding(.leading, Spacing.S).accessibility(identifier: "ic_show_hide")
201
223
  }
202
224
  }
203
225
  } else if !rightIcon.isEmpty {
204
226
  SwiftUI.Button(action: { onRightIconPressed?() }) {
205
- Icon(source: rightIcon, size: 24, color: rightIconColor)
227
+ Icon(source: rightIcon, size: 24, color: getRightIconColor())
206
228
  .padding(.leading, Spacing.S)
207
229
  }
208
230
  }
@@ -211,7 +233,7 @@ public struct Input: View {
211
233
  .frame(height: scaleSize(size == .small ? 48 : 56, 1.1))
212
234
  .background(
213
235
  RoundedRectangle(cornerRadius: Radius.S)
214
- .fill(Colors.black01)
236
+ .fill(theme.colors.background.surface)
215
237
  )
216
238
  .overlay(
217
239
  RoundedRectangle(cornerRadius: Radius.S)
@@ -260,31 +282,39 @@ public struct Input: View {
260
282
 
261
283
  private func borderColor() -> Color {
262
284
  if disabled {
263
- return Colors.black04 // border.disable
285
+ return theme.colors.border.disable
264
286
  }
265
287
  if !error.isEmpty {
266
- return Colors.red03 // error.primary
288
+ return theme.colors.error.primary
267
289
  }
268
290
  if isFocused {
269
- return Colors.primary
291
+ return theme.colors.primary
270
292
  }
271
- return Colors.black04 // border.default
293
+ return theme.colors.border.default
272
294
  }
273
295
 
274
296
  private func getTextColor() -> Color {
275
- return disabled ? Colors.black09 : Colors.black17
297
+ return disabled ? theme.colors.text.disable : theme.colors.text.default
276
298
  }
277
299
 
278
300
  private func getPlaceholderColor() -> Color {
279
- return disabled ? Colors.black09 : Colors.black12
301
+ return disabled ? theme.colors.text.disable : theme.colors.text.hint
280
302
  }
281
303
 
282
304
  private func getFloatingColor() -> Color {
283
- return disabled ? Colors.black09 : Colors.black12
305
+ return disabled ? theme.colors.text.disable : (floatingValueColor ?? theme.colors.text.hint)
284
306
  }
285
307
 
286
308
  private func getFloatingIconColor() -> Color {
287
- 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)
288
318
  }
289
319
  }
290
320
 
@@ -296,8 +326,10 @@ private struct SecureInputField: UIViewRepresentable {
296
326
  var fontSize: CGFloat
297
327
  var fontWeight: UIFont.Weight
298
328
  var textColor: UIColor
329
+ var cursorColor: UIColor
299
330
  var isDisabled: Bool
300
331
  var maxLength: Int?
332
+ var autofocus: Bool = false
301
333
  var onFocusChange: (Bool) -> Void
302
334
  var onChangeText: ((String) -> Void)?
303
335
 
@@ -316,12 +348,17 @@ private struct SecureInputField: UIViewRepresentable {
316
348
  textField.setContentHuggingPriority(.defaultLow, for: .horizontal)
317
349
  textField.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
318
350
  textField.text = text
319
- textField.tintColor = UIColor(Colors.primary)
351
+ textField.tintColor = cursorColor
320
352
  textField.addTarget(
321
353
  context.coordinator,
322
354
  action: #selector(Coordinator.textFieldDidChange(_:)),
323
355
  for: .editingChanged
324
356
  )
357
+ if autofocus {
358
+ DispatchQueue.main.async {
359
+ textField.becomeFirstResponder()
360
+ }
361
+ }
325
362
  return textField
326
363
  }
327
364
 
@@ -331,6 +368,8 @@ private struct SecureInputField: UIViewRepresentable {
331
368
  textField.text = text
332
369
  }
333
370
  textField.isEnabled = !isDisabled
371
+ textField.textColor = textColor
372
+ textField.tintColor = cursorColor
334
373
  if textField.keyboardType != keyboardType {
335
374
  textField.keyboardType = keyboardType
336
375
  textField.reloadInputViews()
@@ -401,9 +440,9 @@ private struct SecureInputField: UIViewRepresentable {
401
440
 
402
441
  // MARK: - Helper Extension
403
442
  private extension View {
404
- func applyPrimaryCursorColor() -> some View {
443
+ func applyCursorColor(_ color: Color) -> some View {
405
444
  if #available(iOS 15.0, *) {
406
- return self.tint(Colors.primary)
445
+ return self.tint(color)
407
446
  } else {
408
447
  return self
409
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,28 +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
108
  .ignoreBoldTextSetting()
98
- .foregroundColor(Colors.black17)
99
- .applyPrimaryCursorColor()
109
+ .foregroundColor(theme.colors.text.default)
110
+ .applyCursorColor(theme.colors.primary)
100
111
  .lineLimit(1)
112
+ .focused($isFieldFocused)
113
+ .onAppear {
114
+ if autofocus { isFieldFocused = true }
115
+ }
101
116
  .accessibility(identifier: accessibilityLabel ?? "")
102
117
  .accessibilityValue(textBinding.wrappedValue.isEmpty ? placeholder : textBinding.wrappedValue)
103
118
  }
@@ -108,7 +123,7 @@ public struct InputPhoneNumber: View {
108
123
  text = ""
109
124
  onChangeText?("")
110
125
  }) {
111
- 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)
112
127
  .padding(.leading, Spacing.S).accessibility(identifier: "ic_clear")
113
128
  }
114
129
  }
@@ -122,7 +137,7 @@ public struct InputPhoneNumber: View {
122
137
  // ✅ Right icon
123
138
  if !rightIcon.isEmpty {
124
139
  SwiftUI.Button(action: { onRightIconPressed?() }) {
125
- Icon(source: rightIcon, size: 24, color: rightIconColor)
140
+ Icon(source: rightIcon, size: 24, color: rightIconColor ?? theme.colors.text.default)
126
141
  .padding(.leading, Spacing.S)
127
142
  }
128
143
  }
@@ -131,7 +146,7 @@ public struct InputPhoneNumber: View {
131
146
  .frame(height: scaleSize(size == .small ? 48 : 56, 1.1))
132
147
  .background(
133
148
  RoundedRectangle(cornerRadius: Radius.S)
134
- .fill(Colors.black01)
149
+ .fill(theme.colors.background.surface)
135
150
  )
136
151
  .overlay(
137
152
  RoundedRectangle(cornerRadius: Radius.S)
@@ -141,7 +156,7 @@ public struct InputPhoneNumber: View {
141
156
  // Error or hint
142
157
  ErrorView(
143
158
  errorMessage: error,
144
- errorSpacing: false,
159
+ errorSpacing: errorSpacing,
145
160
  hintText: hintText
146
161
  )
147
162
  }
@@ -159,21 +174,18 @@ public struct InputPhoneNumber: View {
159
174
  }
160
175
 
161
176
  private func borderColor() -> Color {
162
- if !error.isEmpty { return Colors.red03 }
163
- if isFocused { return Colors.primary }
164
- 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
165
180
  }
166
181
  }
167
182
 
168
183
  private extension View {
169
- func applyPrimaryCursorColor() -> some View {
184
+ func applyCursorColor(_ color: Color) -> some View {
170
185
  if #available(iOS 15.0, *) {
171
- // Modern SwiftUI: use .tint() for cursor
172
- return self.tint(Colors.primary)
186
+ return self.tint(color)
173
187
  } else {
174
- // iOS 13–14: return unchanged (no tint support)
175
188
  return self
176
189
  }
177
190
  }
178
191
  }
179
-