@momo-kits/native-kits 0.163.1-beta.8 → 0.163.1-beta.9-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 (334) hide show
  1. package/CLAUDE.md +1 -1
  2. package/build.gradle.kts +11 -0
  3. package/compose/build.gradle.kts +190 -0
  4. package/compose/build.gradle.kts.backup +190 -0
  5. package/compose/compose.podspec +47 -0
  6. package/compose/src/androidMain/kotlin/vn/momo/kits/navigation/ScrollToTop.android.kt +6 -0
  7. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/OsFontScale.android.kt +7 -0
  8. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/Platform.android.kt +150 -0
  9. package/compose/src/commonMain/composeResources/font/momosignature.otf +0 -0
  10. package/compose/src/commonMain/composeResources/font/momotrustdisplay.otf +0 -0
  11. package/compose/src/commonMain/composeResources/font/sfprotext_black.otf +0 -0
  12. package/compose/src/commonMain/composeResources/font/sfprotext_black.ttf +0 -0
  13. package/compose/src/commonMain/composeResources/font/sfprotext_bold.ttf +0 -0
  14. package/compose/src/commonMain/composeResources/font/sfprotext_heavy.ttf +0 -0
  15. package/compose/src/commonMain/composeResources/font/sfprotext_light.ttf +0 -0
  16. package/compose/src/commonMain/composeResources/font/sfprotext_medium.ttf +0 -0
  17. package/compose/src/commonMain/composeResources/font/sfprotext_regular.ttf +0 -0
  18. package/compose/src/commonMain/composeResources/font/sfprotext_semibold.ttf +0 -0
  19. package/compose/src/commonMain/composeResources/font/sfprotext_thin.otf +0 -0
  20. package/compose/src/commonMain/composeResources/font/sfprotext_thin.ttf +0 -0
  21. package/compose/src/commonMain/composeResources/font/sfprotext_ultralight.otf +0 -0
  22. package/compose/src/commonMain/composeResources/font/sfprotext_ultralight.ttf +0 -0
  23. package/compose/src/commonMain/kotlin/vn/momo/kits/application/AnimationSearchInput.kt +52 -0
  24. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Context.kt +106 -0
  25. package/compose/src/commonMain/kotlin/vn/momo/kits/application/FloatingButton.kt +183 -0
  26. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Header.kt +207 -0
  27. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderAnimated.kt +39 -0
  28. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderBackground.kt +86 -0
  29. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderDefault.kt +76 -0
  30. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderExtended.kt +76 -0
  31. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderRight.kt +294 -0
  32. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderTitle.kt +33 -0
  33. package/compose/src/commonMain/kotlin/vn/momo/kits/application/LiteScreen.kt +826 -0
  34. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Localize.kt +269 -0
  35. package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +110 -0
  36. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +378 -0
  37. package/compose/src/commonMain/kotlin/vn/momo/kits/application/WidgetContainer.kt +56 -0
  38. package/compose/src/commonMain/kotlin/vn/momo/kits/application/useHeaderSearchAnimation.kt +69 -0
  39. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Avatar.kt +157 -0
  40. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Badge.kt +82 -0
  41. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeDot.kt +32 -0
  42. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeRibbon.kt +338 -0
  43. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BaselineView.kt +175 -0
  44. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +356 -0
  45. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Carousel.kt +113 -0
  46. package/compose/src/commonMain/kotlin/vn/momo/kits/components/CheckBox.kt +89 -0
  47. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Chip.kt +128 -0
  48. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Collapse.kt +209 -0
  49. package/compose/src/commonMain/kotlin/vn/momo/kits/components/CupertinoOverscroll.kt +543 -0
  50. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Divider.kt +23 -0
  51. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Icon.kt +76 -0
  52. package/compose/src/commonMain/kotlin/vn/momo/kits/components/IconButton.kt +125 -0
  53. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Image.kt +231 -0
  54. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Information.kt +112 -0
  55. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +477 -0
  56. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputDropDown.kt +114 -0
  57. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputMoney.kt +214 -0
  58. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputOTP.kt +240 -0
  59. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputPhoneNumber.kt +216 -0
  60. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +259 -0
  61. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +182 -0
  62. package/compose/src/commonMain/kotlin/vn/momo/kits/components/LazyColumnWithBouncing.kt +343 -0
  63. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Loader.kt +108 -0
  64. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationDot.kt +56 -0
  65. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationNumber.kt +41 -0
  66. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationScroll.kt +84 -0
  67. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationWhiteDot.kt +40 -0
  68. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +328 -0
  69. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupPromotion.kt +97 -0
  70. package/compose/src/commonMain/kotlin/vn/momo/kits/components/ProgressInfo.kt +310 -0
  71. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Radio.kt +59 -0
  72. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Rating.kt +87 -0
  73. package/compose/src/commonMain/kotlin/vn/momo/kits/components/ScaleSizeScope.kt +21 -0
  74. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Skeleton.kt +90 -0
  75. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Slider.kt +323 -0
  76. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Stepper.kt +217 -0
  77. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Steps.kt +473 -0
  78. package/compose/src/commonMain/kotlin/vn/momo/kits/components/SuggestAction.kt +122 -0
  79. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Swipe.kt +199 -0
  80. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Switch.kt +91 -0
  81. package/compose/src/commonMain/kotlin/vn/momo/kits/components/TabView.kt +470 -0
  82. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tag.kt +88 -0
  83. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +131 -0
  84. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Title.kt +203 -0
  85. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tooltip.kt +498 -0
  86. package/compose/src/commonMain/kotlin/vn/momo/kits/components/TrustBanner.kt +175 -0
  87. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Uploader.kt +182 -0
  88. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePicker.kt +193 -0
  89. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerTypes.kt +29 -0
  90. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerUtils.kt +234 -0
  91. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/WheelPicker.kt +188 -0
  92. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Colors.kt +306 -0
  93. package/compose/src/commonMain/kotlin/vn/momo/kits/const/KitFontScale.kt +22 -0
  94. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Radius.kt +12 -0
  95. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Spacing.kt +16 -0
  96. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Theme.kt +188 -0
  97. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +276 -0
  98. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Card.kt +65 -0
  99. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Item.kt +48 -0
  100. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Section.kt +51 -0
  101. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/AutomationId.kt +52 -0
  102. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Clickable.kt +66 -0
  103. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Conditional.kt +11 -0
  104. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/DeprecatedModifier.kt +104 -0
  105. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Shadow.kt +48 -0
  106. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Size.kt +51 -0
  107. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/BottomSheet.kt +253 -0
  108. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ModalScreen.kt +129 -0
  109. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigation.kt +100 -0
  110. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +172 -0
  111. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigator.kt +360 -0
  112. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ScrollToTop.kt +8 -0
  113. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +581 -0
  114. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTab.kt +156 -0
  115. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +225 -0
  116. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/CurvedContainer.kt +86 -0
  117. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/FloatingButton.kt +169 -0
  118. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +320 -0
  119. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderBackground.kt +81 -0
  120. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderRight.kt +309 -0
  121. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderTitle.kt +34 -0
  122. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderUser.kt +360 -0
  123. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SnackBar.kt +132 -0
  124. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/tracking/ScreenTracker.kt +128 -0
  125. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/ComposeLottieAnimation.kt +91 -0
  126. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/OsFontScale.kt +9 -0
  127. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +69 -0
  128. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Icons.kt +1329 -0
  129. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Resources.kt +55 -0
  130. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Tracking.kt +15 -0
  131. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Utils.kt +105 -0
  132. package/compose/src/iosMain/kotlin/vn/momo/kits/navigation/ScrollToTop.ios.kt +32 -0
  133. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/OsFontScale.ios.kt +66 -0
  134. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +207 -0
  135. package/gradle/libs.versions.toml +69 -0
  136. package/gradle/wrapper/gradle-wrapper.jar +0 -0
  137. package/gradle/wrapper/gradle-wrapper.properties +8 -0
  138. package/gradle.properties +26 -0
  139. package/gradlew +252 -0
  140. package/gradlew.bat +94 -0
  141. package/ios/Application/ApplicationEnvironment.swift +15 -2
  142. package/ios/Application/Components.swift +50 -44
  143. package/ios/Application/FloatingButton.swift +10 -9
  144. package/ios/Application/HeaderRight.swift +79 -45
  145. package/ios/Application/Localize.swift +277 -0
  146. package/ios/Application/MaxApi.swift +18 -0
  147. package/ios/Application/Navigation/BottomTab/BottomTab.swift +104 -0
  148. package/ios/Application/Navigation/BottomTab/BottomTabBar.swift +215 -0
  149. package/ios/Application/Navigation/BottomTab/CurvedContainer.swift +65 -0
  150. package/ios/Application/Navigation/HeaderBackProps.swift +66 -0
  151. package/ios/Application/Navigation/HeaderTitle.swift +57 -0
  152. package/ios/Application/Navigation/HeaderUser.swift +209 -0
  153. package/ios/Application/Navigation/NavigationContainer.swift +200 -0
  154. package/ios/Application/Navigation/NavigationOptions.swift +109 -0
  155. package/ios/Application/Navigation/Navigator.swift +385 -0
  156. package/ios/Application/Navigation/Overplay/BottomSheet.swift +256 -0
  157. package/ios/Application/Navigation/Overplay/ModalScreen.swift +74 -0
  158. package/ios/Application/Navigation/Overplay/SnackBar.swift +144 -0
  159. package/ios/Application/Navigation/Tracking/ScreenTracker.swift +117 -0
  160. package/ios/Application/Navigation/component/Header.swift +178 -0
  161. package/ios/Application/Navigation/component/HeaderBackground.swift +83 -0
  162. package/ios/Application/Navigation/component/HeaderColor.swift +65 -0
  163. package/ios/Application/Screen.swift +2 -1
  164. package/ios/Application/StackScreen.swift +501 -0
  165. package/ios/Avatar/Avatar.swift +193 -0
  166. package/ios/Badge/Badge.swift +11 -14
  167. package/ios/Badge/BadgeRibbon.swift +92 -21
  168. package/ios/BaselineView/BaselineView.swift +163 -0
  169. package/ios/Button/Button.swift +124 -29
  170. package/ios/Carousel/Carousel.swift +196 -0
  171. package/ios/Checkbox/Checkbox.swift +23 -28
  172. package/ios/Chip/Chip.swift +56 -33
  173. package/ios/Collapse/Collapse.swift +192 -0
  174. package/ios/Colors+Radius+Spacing/Colors.swift +20 -17
  175. package/ios/Colors+Radius+Spacing/Spacing.swift +3 -1
  176. package/ios/Colors+Radius+Spacing/Theme.swift +295 -0
  177. package/ios/DateTimePicker/DateTimePicker.swift +212 -0
  178. package/ios/DateTimePicker/DateTimePickerTypes.swift +55 -0
  179. package/ios/DateTimePicker/DateTimePickerUtils.swift +167 -0
  180. package/ios/DateTimePicker/WheelPicker.swift +165 -0
  181. package/ios/Divider/Divider.swift +16 -0
  182. package/ios/Extensions/ActiveOpacityButtonStyle.swift +14 -0
  183. package/ios/Extensions/Color++.swift +32 -0
  184. package/ios/Icon/Icon.swift +10 -1
  185. package/ios/IconButton/IconButton.swift +140 -0
  186. package/ios/Image/Image.swift +16 -3
  187. package/ios/Information/Information.swift +3 -1
  188. package/ios/Input/ErrorView.swift +3 -1
  189. package/ios/Input/Input.swift +72 -33
  190. package/ios/Input/InputPhoneNumber.swift +33 -21
  191. package/ios/Input/InputSearch.swift +107 -48
  192. package/ios/Input/InputTextArea.swift +134 -64
  193. package/ios/InputDropDown/InputDropDown.swift +201 -0
  194. package/ios/InputMoney/InputMoney.swift +347 -0
  195. package/ios/InputOTP/InputOTP.swift +210 -0
  196. package/ios/Loader/Loader.swift +113 -0
  197. package/ios/MoMoUIKits.podspec +5 -0
  198. package/ios/Pagination/PaginationDot.swift +61 -0
  199. package/ios/Pagination/PaginationNumber.swift +35 -0
  200. package/ios/Pagination/PaginationScroll.swift +101 -0
  201. package/ios/Pagination/PaginationWhiteDot.swift +37 -0
  202. package/ios/Popup/PopupDisplay.swift +11 -20
  203. package/ios/Popup/PopupInput.swift +2 -8
  204. package/ios/Popup/PopupNotify.swift +218 -0
  205. package/ios/Popup/PopupPromotion.swift +16 -8
  206. package/ios/ProgressInfo/ProgressInfo.swift +296 -0
  207. package/ios/Radio/Radio.swift +69 -0
  208. package/ios/Rating/Rating.swift +82 -0
  209. package/ios/Resources/MoMoUIKitsColors.xcassets/AccentColor.colorset/Contents.json +11 -0
  210. package/ios/Resources/MoMoUIKitsColors.xcassets/Background.colorset/Contents.json +38 -0
  211. package/ios/Resources/MoMoUIKitsColors.xcassets/Border.colorset/Contents.json +38 -0
  212. package/ios/Resources/MoMoUIKitsColors.xcassets/Card.colorset/Contents.json +38 -0
  213. package/ios/Resources/MoMoUIKitsColors.xcassets/Contents.json +6 -0
  214. package/ios/Resources/MoMoUIKitsColors.xcassets/Error.colorset/Contents.json +38 -0
  215. package/ios/Resources/MoMoUIKitsColors.xcassets/Primary.colorset/Contents.json +38 -0
  216. package/ios/Resources/MoMoUIKitsColors.xcassets/PrimaryDark.colorset/Contents.json +38 -0
  217. package/ios/Resources/MoMoUIKitsColors.xcassets/PrimaryLight.colorset/Contents.json +38 -0
  218. package/ios/Resources/MoMoUIKitsColors.xcassets/Secondary.colorset/Contents.json +38 -0
  219. package/ios/Resources/MoMoUIKitsColors.xcassets/Success.colorset/Contents.json +38 -0
  220. package/ios/Resources/MoMoUIKitsColors.xcassets/Text.colorset/Contents.json +38 -0
  221. package/ios/Resources/MoMoUIKitsColors.xcassets/TextSecondary.colorset/Contents.json +38 -0
  222. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/Contents.json +9 -0
  223. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-default.colorset/Contents.json +38 -0
  224. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-disable.colorset/Contents.json +38 -0
  225. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-pressed.colorset/Contents.json +38 -0
  226. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-selected.colorset/Contents.json +38 -0
  227. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-surface.colorset/Contents.json +38 -0
  228. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-tonal.colorset/Contents.json +38 -0
  229. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/border-default.colorset/Contents.json +38 -0
  230. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/border-disable.colorset/Contents.json +38 -0
  231. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/gradient.colorset/Contents.json +38 -0
  232. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/primary.colorset/Contents.json +38 -0
  233. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/secondary.colorset/Contents.json +38 -0
  234. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/success-container.colorset/Contents.json +38 -0
  235. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/success-primary.colorset/Contents.json +38 -0
  236. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/success-secondary.colorset/Contents.json +38 -0
  237. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-default.colorset/Contents.json +38 -0
  238. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-disable.colorset/Contents.json +38 -0
  239. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-hint.colorset/Contents.json +38 -0
  240. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-secondary.colorset/Contents.json +38 -0
  241. package/ios/Resources/MoMoUIKitsColors.xcassets/Warning.colorset/Contents.json +38 -0
  242. package/ios/Skeleton/Skeleton.swift +99 -0
  243. package/ios/Slider/Slider.swift +237 -0
  244. package/ios/Stepper/Stepper.swift +220 -0
  245. package/ios/Steps/Steps.swift +467 -0
  246. package/ios/SuggestAction/SuggestAction.swift +99 -0
  247. package/ios/Swipeable/SwipeCell.swift +187 -0
  248. package/ios/Swipeable/SwipeCellModel.swift +21 -0
  249. package/ios/Switch/Switch.swift +53 -28
  250. package/ios/TabView/TabView.swift +534 -0
  251. package/ios/Tag/Tag.swift +98 -0
  252. package/ios/Template/TrustBanner/TrustBanner.swift +6 -7
  253. package/ios/Title/Title.swift +269 -0
  254. package/ios/Tooltip/Tooltip.swift +485 -0
  255. package/ios/Typography/FontScaleStore.swift +19 -0
  256. package/ios/Typography/Text.swift +79 -5
  257. package/ios/Typography/Typography.swift +3 -0
  258. package/ios/Uploader/Uploader.swift +174 -0
  259. package/ios/native-kits.podspec +61 -8
  260. package/ios-demo/MoMoUIKitsDemo.podspec +20 -0
  261. package/ios-demo/README.md +120 -0
  262. package/ios-demo/Resources/dot_loading.json +558 -0
  263. package/ios-demo/Resources/icon.json +4052 -0
  264. package/ios-demo/Resources/lottie_circle_loader.json +1 -0
  265. package/ios-demo/Sources/MoMoUIKitsDemo/DemoScaffold.swift +48 -0
  266. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsBadgeDemoView.swift +25 -0
  267. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsButtonDemoView.swift +26 -0
  268. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsCheckboxDemoView.swift +19 -0
  269. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsChipDemoView.swift +33 -0
  270. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsInputDemoView.swift +48 -0
  271. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsPopupDemoView.swift +21 -0
  272. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsRadioDemoView.swift +17 -0
  273. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsTypographyDemoView.swift +28 -0
  274. package/ios-demo/Sources/MoMoUIKitsDemo/MoMoUIKitsDemoContext.swift +31 -0
  275. package/ios-demo/Sources/MoMoUIKitsDemo/MoMoUIKitsDemoFactory.swift +24 -0
  276. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/AnimatedHeaderDemo.swift +110 -0
  277. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/AvatarDemo.swift +93 -0
  278. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BadgeDemo.swift +269 -0
  279. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BaselineView.swift +117 -0
  280. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BottomTabDemo.swift +89 -0
  281. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ButtonDemo.swift +100 -0
  282. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CarouselDemo.swift +126 -0
  283. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CheckboxDemo.swift +63 -0
  284. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ChipDemo.swift +20 -0
  285. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CollapseDemo.swift +93 -0
  286. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ContentView.swift +107 -0
  287. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DateTimePickerDemo.swift +124 -0
  288. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DividerDemo.swift +14 -0
  289. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/HeaderUserDemo.swift +49 -0
  290. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/Home.swift +279 -0
  291. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/IconButtonDemo.swift +58 -0
  292. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ImageDemo.swift +78 -0
  293. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InformationDemo.swift +138 -0
  294. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputDemo.swift +111 -0
  295. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputDropDownDemo.swift +136 -0
  296. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputMoneyDemo.swift +107 -0
  297. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputOTPDemo.swift +73 -0
  298. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputPhoneNumberDemo.swift +100 -0
  299. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputSearchDemo.swift +32 -0
  300. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputTextAreaDemo.swift +57 -0
  301. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/LoaderDemo.swift +70 -0
  302. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/LocalizeDemo.swift +188 -0
  303. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/NavigationDemo.swift +229 -0
  304. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PaginationDemo.swift +72 -0
  305. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupDisplayDemo.swift +175 -0
  306. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupNotifyDemo.swift +121 -0
  307. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupPromotionDemo.swift +76 -0
  308. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ProgressInfoDemo.swift +89 -0
  309. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/RadioDemo.swift +32 -0
  310. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/RatingDemo.swift +56 -0
  311. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SkeletonDemo.swift +32 -0
  312. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SliderDemo.swift +150 -0
  313. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SnackBarDemo.swift +138 -0
  314. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/StepperDemo.swift +103 -0
  315. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/StepsDemo.swift +94 -0
  316. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SuggestActionDemo.swift +79 -0
  317. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SwipeDemo.swift +152 -0
  318. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SwitchDemo.swift +33 -0
  319. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TabViewDemo.swift +190 -0
  320. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TagDemo.swift +34 -0
  321. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ThemeDemo.swift +182 -0
  322. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TitleDemo.swift +109 -0
  323. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TooltipDemo.swift +187 -0
  324. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TypographyDemo.swift +87 -0
  325. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/UploaderDemo.swift +131 -0
  326. package/ios-demo/Sources/MoMoUIKitsDemo/SwiftUIDemoBrowserView.swift +51 -0
  327. package/ios-demo/Sources/MoMoUIKitsDemo/UIKitsDemoModels.swift +15 -0
  328. package/ios-demo/Sources/MoMoUIKitsDemo/UIKitsDemoRegistry.swift +73 -0
  329. package/local.properties +8 -0
  330. package/package.json +1 -1
  331. package/publish.sh +53 -0
  332. package/scripts/gen-ios-color.mjs +136 -0
  333. package/settings.gradle.kts +64 -0
  334. package/.claude/settings.local.json +0 -62
@@ -0,0 +1,295 @@
1
+ //
2
+ // Theme.swift
3
+ // MoMoUIKits
4
+ //
5
+ // Created by sophia on 25/2/26.
6
+ //
7
+
8
+ import Foundation
9
+ import SwiftUI
10
+
11
+ // MARK: - Background
12
+
13
+ public struct Background {
14
+ public let `default`: Color
15
+ public let surface: Color
16
+ public let tonal: Color
17
+ public let pressed: Color
18
+ public let selected: Color
19
+ public let disable: Color
20
+
21
+ public init(
22
+ default defaultColor: Color,
23
+ surface: Color,
24
+ tonal: Color,
25
+ pressed: Color,
26
+ selected: Color,
27
+ disable: Color
28
+ ) {
29
+ self.default = defaultColor
30
+ self.surface = surface
31
+ self.tonal = tonal
32
+ self.pressed = pressed
33
+ self.selected = selected
34
+ self.disable = disable
35
+ }
36
+ }
37
+
38
+ // MARK: - TextColors
39
+
40
+ public struct TextColors {
41
+ public let `default`: Color
42
+ public let secondary: Color
43
+ public let hint: Color
44
+ public let disable: Color
45
+
46
+ public init(
47
+ default defaultColor: Color,
48
+ secondary: Color,
49
+ hint: Color,
50
+ disable: Color
51
+ ) {
52
+ self.default = defaultColor
53
+ self.secondary = secondary
54
+ self.hint = hint
55
+ self.disable = disable
56
+ }
57
+ }
58
+
59
+ // MARK: - BorderColors
60
+
61
+ public struct BorderColors {
62
+ public let `default`: Color
63
+ public let disable: Color
64
+
65
+ public init(default defaultColor: Color, disable: Color) {
66
+ self.default = defaultColor
67
+ self.disable = disable
68
+ }
69
+ }
70
+
71
+ // MARK: - ColorSet
72
+
73
+ public struct ColorSet {
74
+ public let primary: Color
75
+ public let secondary: Color
76
+ public let container: Color
77
+
78
+ public init(primary: Color, secondary: Color, container: Color) {
79
+ self.primary = primary
80
+ self.secondary = secondary
81
+ self.container = container
82
+ }
83
+ }
84
+
85
+ // MARK: - ColorScheme
86
+
87
+ public struct ColorScheme {
88
+ public let primary: Color
89
+ public let secondary: Color
90
+ public let gradient: Color
91
+ public let background: Background
92
+ public let text: TextColors
93
+ public let border: BorderColors
94
+ public let success: ColorSet
95
+ public let warning: ColorSet
96
+ public let error: ColorSet
97
+ public let highlight: ColorSet
98
+ public let interactive: ColorSet
99
+
100
+ public init(
101
+ primary: Color,
102
+ secondary: Color,
103
+ gradient: Color,
104
+ background: Background,
105
+ text: TextColors,
106
+ border: BorderColors,
107
+ success: ColorSet,
108
+ warning: ColorSet,
109
+ error: ColorSet,
110
+ highlight: ColorSet,
111
+ interactive: ColorSet
112
+ ) {
113
+ self.primary = primary
114
+ self.secondary = secondary
115
+ self.gradient = gradient
116
+ self.background = background
117
+ self.text = text
118
+ self.border = border
119
+ self.success = success
120
+ self.warning = warning
121
+ self.error = error
122
+ self.highlight = highlight
123
+ self.interactive = interactive
124
+ }
125
+ }
126
+
127
+ // MARK: - ThemeAssets
128
+
129
+ public struct ThemeAssets {
130
+ public let headerBackground: String?
131
+
132
+ public init(headerBackground: String? = nil) {
133
+ self.headerBackground = headerBackground
134
+ }
135
+
136
+ public var isHeaderImage: Bool {
137
+ guard let url = headerBackground else { return false }
138
+ return !url.isEmpty
139
+ }
140
+ }
141
+
142
+ // MARK: - Theme
143
+
144
+ public struct Theme {
145
+ public let dark: Bool
146
+ public let colors: ColorScheme
147
+ public let font: String
148
+ public let assets: ThemeAssets
149
+
150
+ public init(dark: Bool, colors: ColorScheme, font: String, assets: ThemeAssets) {
151
+ self.dark = dark
152
+ self.colors = colors
153
+ self.font = font
154
+ self.assets = assets
155
+ }
156
+
157
+ public func copy(
158
+ dark: Bool? = nil,
159
+ colors: ColorScheme? = nil,
160
+ font: String? = nil,
161
+ assets: ThemeAssets? = nil
162
+ ) -> Theme {
163
+ Theme(
164
+ dark: dark ?? self.dark,
165
+ colors: colors ?? self.colors,
166
+ font: font ?? self.font,
167
+ assets: assets ?? self.assets
168
+ )
169
+ }
170
+ }
171
+
172
+ // MARK: - Default Theme (Light)
173
+
174
+ public let defaultTheme = Theme(
175
+ dark: false,
176
+ colors: ColorScheme(
177
+ primary: Color.momoAsset("ThemeColors/primary"),
178
+ secondary: Color.momoAsset("ThemeColors/secondary"),
179
+ gradient: Color.momoAsset("ThemeColors/gradient"),
180
+ background: Background(
181
+ default: Color.momoAsset("ThemeColors/background-default"),
182
+ surface: Color.momoAsset("ThemeColors/background-surface"),
183
+ tonal: Color.momoAsset("ThemeColors/background-tonal"),
184
+ pressed: Color.momoAsset("ThemeColors/background-pressed"),
185
+ selected: Color.momoAsset("ThemeColors/background-selected"),
186
+ disable: Color.momoAsset("ThemeColors/background-disable")
187
+ ),
188
+ text: TextColors(
189
+ default: Color.momoAsset("ThemeColors/text-default"),
190
+ secondary: Color.momoAsset("ThemeColors/text-secondary"),
191
+ hint: Color.momoAsset("ThemeColors/text-hint"),
192
+ disable: Color.momoAsset("ThemeColors/text-disable")
193
+ ),
194
+ border: BorderColors(
195
+ default: Color.momoAsset("ThemeColors/border-default"),
196
+ disable: Color.momoAsset("ThemeColors/border-disable")
197
+ ),
198
+ success: ColorSet(
199
+ primary: Colors.green03,
200
+ secondary: Colors.green07,
201
+ container: Colors.green08
202
+ ),
203
+ warning: ColorSet(
204
+ primary: Colors.orange03,
205
+ secondary: Colors.orange07,
206
+ container: Colors.orange08
207
+ ),
208
+ error: ColorSet(
209
+ primary: Colors.red03,
210
+ secondary: Colors.red07,
211
+ container: Colors.red08
212
+ ),
213
+ highlight: ColorSet(
214
+ primary: Colors.mint03,
215
+ secondary: Colors.mint07,
216
+ container: Colors.mint08
217
+ ),
218
+ interactive: ColorSet(
219
+ primary: Colors.blue03,
220
+ secondary: Colors.blue07,
221
+ container: Colors.blue08
222
+ )
223
+ ),
224
+ font: "SFProText",
225
+ assets: ThemeAssets(headerBackground: nil)
226
+ )
227
+
228
+ // MARK: - Dark Theme
229
+
230
+ public let darkTheme = Theme(
231
+ dark: true,
232
+ colors: ColorScheme(
233
+ primary: Colors.pink04,
234
+ secondary: Colors.pink08,
235
+ gradient: Color(hex: "FDCADE"),
236
+ background: Background(
237
+ default: Color(hex: "121212"),
238
+ surface: Color(hex: "1E1E1E"),
239
+ tonal: Colors.pink10,
240
+ pressed: Color(hex: "1A1A1A"),
241
+ selected: Colors.pink11,
242
+ disable: Color(hex: "303030")
243
+ ),
244
+ text: TextColors(
245
+ default: Color.white,
246
+ secondary: Color(hex: "B0B0B0"),
247
+ hint: Color(hex: "727272"),
248
+ disable: Color(hex: "505050")
249
+ ),
250
+ border: BorderColors(
251
+ default: Color(hex: "2A2A2A"),
252
+ disable: Color(hex: "242424")
253
+ ),
254
+ success: ColorSet(
255
+ primary: Colors.green03,
256
+ secondary: Colors.green07,
257
+ container: Colors.green08
258
+ ),
259
+ warning: ColorSet(
260
+ primary: Colors.orange03,
261
+ secondary: Colors.orange07,
262
+ container: Colors.orange08
263
+ ),
264
+ error: ColorSet(
265
+ primary: Colors.red03,
266
+ secondary: Colors.red07,
267
+ container: Colors.red08
268
+ ),
269
+ highlight: ColorSet(
270
+ primary: Colors.mint03,
271
+ secondary: Colors.mint07,
272
+ container: Colors.mint08
273
+ ),
274
+ interactive: ColorSet(
275
+ primary: Colors.blue03,
276
+ secondary: Colors.blue07,
277
+ container: Colors.blue08
278
+ )
279
+ ),
280
+ font: "SFProText",
281
+ assets: ThemeAssets(headerBackground: nil)
282
+ )
283
+
284
+ // MARK: - AppTheme Environment Key
285
+
286
+ private struct AppThemeKey: EnvironmentKey {
287
+ static let defaultValue: Theme = defaultTheme
288
+ }
289
+
290
+ public extension EnvironmentValues {
291
+ var appTheme: Theme {
292
+ get { self[AppThemeKey.self] }
293
+ set { self[AppThemeKey.self] = newValue }
294
+ }
295
+ }
@@ -0,0 +1,212 @@
1
+ import SwiftUI
2
+
3
+ // MARK: - Constants
4
+
5
+ private let datePickerHeight: CGFloat = 210
6
+ private let datePickerWithLabelsHeight: CGFloat = 238
7
+
8
+ // MARK: - DateTimePicker
9
+
10
+ /// A wheel-style date/time picker matching Compose `DateTimePicker`.
11
+ ///
12
+ /// The `format` string drives which columns are shown:
13
+ /// - `DD` day, `MM` month, `YYYY` year, `HH` hour, `mm` minute.
14
+ /// - `"HH:mm"` shows hour + minute; a lone `"HH"` switches the hour wheel to a
15
+ /// 12-hour clock with an AM/PM column.
16
+ public struct DateTimePicker: View {
17
+ @Environment(\.appTheme) private var theme
18
+
19
+ // MARK: Lifecycle
20
+
21
+ public init(
22
+ format: String = "DD-MM-YYYY",
23
+ minuteInterval: Int = 1,
24
+ selectedValue: Date? = nil,
25
+ minDate: Date? = nil,
26
+ maxDate: Date? = nil,
27
+ arrayLabelTime: [String] = [],
28
+ onChange: @escaping (Date) -> Void
29
+ ) {
30
+ self.format = format
31
+ self.minuteInterval = minuteInterval
32
+ self.selectedValue = selectedValue
33
+ self.minDate = minDate
34
+ self.maxDate = maxDate
35
+ self.arrayLabelTime = arrayLabelTime
36
+ self.onChange = onChange
37
+
38
+ let calendar = Calendar.current
39
+ let effectiveSelected = selectedValue ?? DateTimePickerUtils.getCurrentDateTime()
40
+ let effectiveMin = minDate ?? DateTimePickerUtils.createRelativeDate(years: -10)
41
+ let effectiveMax = maxDate ?? DateTimePickerUtils.createRelativeDate(years: 10)
42
+
43
+ // needCheckRange is true only when the caller supplied no bounds.
44
+ let needCheckRange = (minDate == nil && maxDate == nil)
45
+
46
+ let initialValue: Date
47
+ if !needCheckRange {
48
+ initialValue = effectiveSelected
49
+ } else if effectiveSelected < effectiveMin {
50
+ initialValue = effectiveMin
51
+ } else if effectiveSelected > effectiveMax {
52
+ initialValue = effectiveMax
53
+ } else {
54
+ initialValue = effectiveSelected
55
+ }
56
+
57
+ let comps = calendar.dateComponents([.year, .month, .day, .hour, .minute], from: initialValue)
58
+ self._currentData = State(initialValue: DateTimePickerData(
59
+ day: comps.day ?? 1,
60
+ month: comps.month ?? 1,
61
+ year: comps.year ?? 2000,
62
+ hour: comps.hour ?? 0,
63
+ minute: comps.minute ?? 0
64
+ ))
65
+
66
+ self.effectiveMinComponents = calendar.dateComponents([.year, .month, .day, .hour, .minute], from: effectiveMin)
67
+ self.effectiveMaxComponents = calendar.dateComponents([.year, .month, .day, .hour, .minute], from: effectiveMax)
68
+ self.needCheckRange = needCheckRange
69
+ }
70
+
71
+ // MARK: Public
72
+
73
+ public var body: some View {
74
+ let components = DateTimePickerUtils.getDateComponents(
75
+ format: format,
76
+ currentData: currentData,
77
+ minDate: effectiveMinComponents,
78
+ maxDate: effectiveMaxComponents,
79
+ minuteInterval: minuteInterval
80
+ )
81
+ let pickerHeight = arrayLabelTime.isEmpty ? datePickerHeight : datePickerWithLabelsHeight
82
+
83
+ return HStack(spacing: Spacing.M) {
84
+ ForEach(Array(components.enumerated()), id: \.offset) { index, component in
85
+ let hasLabel = index < arrayLabelTime.count && !arrayLabelTime[index].isEmpty
86
+
87
+ VStack(spacing: 0) {
88
+ if hasLabel {
89
+ MomoText(arrayLabelTime[index], typography: .actionSBold, color: theme.colors.text.default)
90
+ .padding(.bottom, Spacing.S)
91
+ }
92
+
93
+ WheelPicker(
94
+ name: component.name,
95
+ data: component.data,
96
+ selectedData: selectedDataFor(component.name),
97
+ onChange: onWheelChange
98
+ )
99
+ }
100
+ .frame(maxWidth: .infinity)
101
+ }
102
+ }
103
+ .frame(maxWidth: .infinity)
104
+ .frame(height: pickerHeight)
105
+ .background(theme.colors.background.surface)
106
+ .padding(.horizontal, Spacing.M)
107
+ .onAppear { emitIfValid() }
108
+ }
109
+
110
+ // MARK: Internal
111
+
112
+ let format: String
113
+ let minuteInterval: Int
114
+ let selectedValue: Date?
115
+ let minDate: Date?
116
+ let maxDate: Date?
117
+ let arrayLabelTime: [String]
118
+ let onChange: (Date) -> Void
119
+
120
+ @State private var currentData: DateTimePickerData
121
+
122
+ private let effectiveMinComponents: DateComponents
123
+ private let effectiveMaxComponents: DateComponents
124
+ private let needCheckRange: Bool
125
+
126
+ private func selectedDataFor(_ name: String) -> String {
127
+ switch name {
128
+ case "day": return DateTimePickerUtils.paddingNum(currentData.day)
129
+ case "month": return DateTimePickerUtils.paddingNum(currentData.month)
130
+ case "year": return String(currentData.year)
131
+ case "hour": return DateTimePickerUtils.paddingNum(currentData.hour)
132
+ case "minute": return DateTimePickerUtils.paddingNum(currentData.minute)
133
+ case "timeMode": return currentData.timeMode
134
+ default: return ""
135
+ }
136
+ }
137
+
138
+ /// Mirrors Compose `onWheelChangeValue`: applies value and coerces day/month
139
+ /// to stay within the effective min/max bounds.
140
+ private func onWheelChange(_ name: String, _ value: String) {
141
+ var day = name == "day" ? (Int(value) ?? currentData.day) : currentData.day
142
+ var month = name == "month" ? (Int(value) ?? currentData.month) : currentData.month
143
+ let year = name == "year" ? (Int(value) ?? currentData.year) : currentData.year
144
+ let hour = name == "hour" ? (Int(value) ?? currentData.hour) : currentData.hour
145
+ let minute = name == "minute" ? (Int(value) ?? currentData.minute) : currentData.minute
146
+ let timeMode = name == "timeMode" ? value : currentData.timeMode
147
+
148
+ let maxYear = effectiveMaxComponents.year ?? year
149
+ let minYear = effectiveMinComponents.year ?? year
150
+ let maxMonth = effectiveMaxComponents.month ?? 12
151
+ let minMonth = effectiveMinComponents.month ?? 1
152
+ let maxDayBound = effectiveMaxComponents.day ?? 31
153
+ let minDayBound = effectiveMinComponents.day ?? 1
154
+
155
+ if name == "year" {
156
+ if year == maxYear {
157
+ month = min(max(month, 1), maxMonth)
158
+ } else if year == minYear {
159
+ month = min(max(month, minMonth), 12)
160
+ }
161
+ }
162
+
163
+ if name == "month" || name == "year" {
164
+ let maxDayOfMonth: Int
165
+ switch month {
166
+ case 4, 6, 9, 11: maxDayOfMonth = 30
167
+ case 2: maxDayOfMonth = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) ? 29 : 28
168
+ default: maxDayOfMonth = 31
169
+ }
170
+
171
+ if year == maxYear && month == maxMonth {
172
+ day = min(max(day, 1), maxDayBound)
173
+ } else if year == minYear && month == minMonth {
174
+ day = min(max(day, minDayBound), maxDayOfMonth)
175
+ } else if day > maxDayOfMonth {
176
+ day = maxDayOfMonth
177
+ }
178
+ }
179
+
180
+ currentData = DateTimePickerData(
181
+ day: day,
182
+ month: month,
183
+ year: year,
184
+ hour: hour,
185
+ minute: minute,
186
+ timeMode: timeMode
187
+ )
188
+ emitIfValid()
189
+ }
190
+
191
+ /// Emit `onChange` only when the assembled date is valid and (when bounds were
192
+ /// not supplied) within the effective min/max range. Mirrors the Compose
193
+ /// `snapshotFlow.mapNotNull` filter.
194
+ private func emitIfValid() {
195
+ guard let date = currentData.toDate() else { return }
196
+ if !needCheckRange {
197
+ onChange(date)
198
+ return
199
+ }
200
+ let calendar = Calendar.current
201
+ guard
202
+ let minDate = calendar.date(from: effectiveMinComponents),
203
+ let maxDate = calendar.date(from: effectiveMaxComponents)
204
+ else {
205
+ onChange(date)
206
+ return
207
+ }
208
+ if date >= minDate && date <= maxDate {
209
+ onChange(date)
210
+ }
211
+ }
212
+ }
@@ -0,0 +1,55 @@
1
+ import Foundation
2
+
3
+ // MARK: - PickerData
4
+
5
+ /// Internal mutable representation of the picker's current selection.
6
+ /// Mirrors Compose `PickerData`.
7
+ public struct DateTimePickerData: Equatable {
8
+ public var day: Int
9
+ public var month: Int
10
+ public var year: Int
11
+ public var hour: Int
12
+ public var minute: Int
13
+ public var timeMode: String
14
+
15
+ public init(
16
+ day: Int,
17
+ month: Int,
18
+ year: Int,
19
+ hour: Int = 0,
20
+ minute: Int = 0,
21
+ timeMode: String = ""
22
+ ) {
23
+ self.day = day
24
+ self.month = month
25
+ self.year = year
26
+ self.hour = hour
27
+ self.minute = minute
28
+ self.timeMode = timeMode
29
+ }
30
+
31
+ /// Convert to a `DateComponents` based value. Returns `nil` if the date is invalid.
32
+ public func toDate(calendar: Calendar = Calendar.current) -> Date? {
33
+ var components = DateComponents()
34
+ components.year = year
35
+ components.month = month
36
+ components.day = day
37
+ components.hour = hour
38
+ components.minute = minute
39
+ components.second = 0
40
+ return calendar.date(from: components)
41
+ }
42
+ }
43
+
44
+ // MARK: - DateComponent
45
+
46
+ /// A single wheel column descriptor. Mirrors Compose `DateComponent`.
47
+ public struct DateTimePickerComponent: Equatable {
48
+ public let name: String
49
+ public let data: [String]
50
+
51
+ public init(name: String, data: [String]) {
52
+ self.name = name
53
+ self.data = data
54
+ }
55
+ }