@momo-kits/native-kits 0.0.1-beta.4 → 0.0.2-alpha.1

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 (296) hide show
  1. package/CLAUDE.md +99 -0
  2. package/PUBLISH_GUIDE.md +675 -0
  3. package/README.md +184 -5
  4. package/ios/Application/ApplicationEnvironment.swift +71 -0
  5. package/ios/Application/Components.swift +270 -0
  6. package/ios/Application/ComposeApi.swift +22 -0
  7. package/ios/Application/FloatingButton.swift +174 -0
  8. package/ios/Application/HeaderRight.swift +306 -0
  9. package/ios/Application/LanguageSource.swift +93 -0
  10. package/ios/Application/Localize.swift +378 -0
  11. package/ios/Application/LocalizeModifier.swift +30 -0
  12. package/ios/Application/MaxApi.swift +18 -0
  13. package/ios/Application/Navigation/BottomTab/BottomTab.swift +104 -0
  14. package/ios/Application/Navigation/BottomTab/BottomTabBar.swift +215 -0
  15. package/ios/Application/Navigation/BottomTab/CurvedContainer.swift +65 -0
  16. package/ios/Application/Navigation/HeaderBackProps.swift +66 -0
  17. package/ios/Application/Navigation/HeaderTitle.swift +57 -0
  18. package/ios/Application/Navigation/HeaderUser.swift +209 -0
  19. package/ios/Application/Navigation/NavigationContainer.swift +213 -0
  20. package/ios/Application/Navigation/NavigationOptions.swift +109 -0
  21. package/ios/Application/Navigation/Navigator.swift +453 -0
  22. package/ios/Application/Navigation/NavigatorManager.swift +22 -0
  23. package/ios/Application/Navigation/Overplay/BottomSheet.swift +256 -0
  24. package/ios/Application/Navigation/Overplay/ModalScreen.swift +74 -0
  25. package/ios/Application/Navigation/Overplay/SnackBar.swift +144 -0
  26. package/ios/Application/Navigation/Tracking/ScreenTracker.swift +117 -0
  27. package/ios/Application/Navigation/component/Header.swift +178 -0
  28. package/ios/Application/Navigation/component/HeaderBackground.swift +83 -0
  29. package/ios/Application/Navigation/component/HeaderColor.swift +65 -0
  30. package/ios/Application/Navigation/component/HeaderRightWidthKey.swift +11 -0
  31. package/ios/Application/Navigation/component/NavigationFooter.swift +90 -0
  32. package/ios/Application/Navigation/component/NavigationHeaderRight.swift +196 -0
  33. package/ios/Application/Screen.swift +250 -0
  34. package/ios/Application/StackScreen.swift +492 -0
  35. package/ios/Avatar/Avatar.swift +193 -0
  36. package/ios/Badge/Badge.swift +84 -0
  37. package/ios/Badge/BadgeDot.swift +31 -0
  38. package/ios/Badge/BadgeRibbon.swift +319 -0
  39. package/ios/BaselineView/BaselineView.swift +163 -0
  40. package/ios/Button/Button.swift +232 -84
  41. package/ios/CalculatorKeyboard/CalculatorKeyboard.swift +126 -0
  42. package/ios/Carousel/Carousel.swift +196 -0
  43. package/ios/Checkbox/Checkbox.swift +77 -0
  44. package/ios/Chip/Chip.swift +120 -0
  45. package/ios/Collapse/Collapse.swift +192 -0
  46. package/ios/{Colors+Spacing → Colors+Radius+Spacing}/Colors.swift +42 -37
  47. package/ios/Colors+Radius+Spacing/Radius.swift +22 -0
  48. package/ios/{Colors+Spacing → Colors+Radius+Spacing}/Spacing.swift +3 -1
  49. package/ios/Colors+Radius+Spacing/Theme.swift +295 -0
  50. package/ios/DateTimePicker/DateTimePicker.swift +212 -0
  51. package/ios/DateTimePicker/DateTimePickerTypes.swift +55 -0
  52. package/ios/DateTimePicker/DateTimePickerUtils.swift +167 -0
  53. package/ios/DateTimePicker/WheelPicker.swift +165 -0
  54. package/ios/Divider/Divider.swift +16 -0
  55. package/ios/Extensions/ActiveOpacityButtonStyle.swift +14 -0
  56. package/ios/Extensions/Color++.swift +32 -0
  57. package/ios/Icon/Icon.swift +69 -0
  58. package/ios/IconButton/IconButton.swift +140 -0
  59. package/ios/Image/Image.swift +87 -0
  60. package/ios/Information/Information.swift +156 -0
  61. package/ios/Input/ErrorView.swift +58 -0
  62. package/ios/Input/Input.swift +461 -77
  63. package/ios/Input/InputPhoneNumber.swift +192 -0
  64. package/ios/Input/InputSearch.swift +301 -0
  65. package/ios/Input/InputTextArea.swift +318 -0
  66. package/ios/InputDropDown/InputDropDown.swift +201 -0
  67. package/ios/InputMoney/InputMoney.swift +405 -0
  68. package/ios/InputOTP/InputOTP.swift +211 -0
  69. package/ios/Layout/GridContext.swift +30 -0
  70. package/ios/Layout/Item.swift +42 -0
  71. package/ios/Layout/Section.swift +134 -0
  72. package/ios/Loader/Loader.swift +113 -0
  73. package/ios/Lottie/LottieView.swift +86 -0
  74. package/ios/MoMoUIKits.podspec +5 -0
  75. package/ios/OTPKeyboard/KeyboardButton.swift +13 -5
  76. package/ios/OTPKeyboard/OTPKeyboard.swift +1 -1
  77. package/ios/Pagination/PaginationDot.swift +61 -0
  78. package/ios/Pagination/PaginationNumber.swift +35 -0
  79. package/ios/Pagination/PaginationScroll.swift +101 -0
  80. package/ios/Pagination/PaginationWhiteDot.swift +37 -0
  81. package/ios/Popup/PopupDisplay.swift +279 -0
  82. package/ios/Popup/PopupInput.swift +92 -0
  83. package/ios/Popup/PopupNotify.swift +219 -0
  84. package/ios/Popup/PopupPromotion.swift +74 -0
  85. package/ios/PopupView/FullscreenPopup.swift +251 -0
  86. package/ios/{Popup → PopupView}/Modifiers.swift +6 -20
  87. package/ios/{Popup → PopupView}/PopupView.swift +38 -146
  88. package/ios/PopupView/Utils++.swift +281 -0
  89. package/ios/ProgressInfo/ProgressInfo.swift +297 -0
  90. package/ios/Radio/Radio.swift +69 -0
  91. package/ios/Rating/Rating.swift +83 -0
  92. package/{example/ios/Example/Preview Content/Preview Assets.xcassets/Contents.json → ios/Resources/MoMoUIKitsColors.xcassets/AccentColor.colorset/Contents.json} +5 -0
  93. package/{example/ios/Example/Assets.xcassets → ios/Resources/MoMoUIKitsColors.xcassets}/Text.colorset/Contents.json +3 -3
  94. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/Contents.json +9 -0
  95. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-default.colorset/Contents.json +38 -0
  96. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-disable.colorset/Contents.json +38 -0
  97. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-pressed.colorset/Contents.json +38 -0
  98. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-selected.colorset/Contents.json +38 -0
  99. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-surface.colorset/Contents.json +38 -0
  100. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/background-tonal.colorset/Contents.json +38 -0
  101. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/border-default.colorset/Contents.json +38 -0
  102. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/border-disable.colorset/Contents.json +38 -0
  103. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/gradient.colorset/Contents.json +38 -0
  104. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/primary.colorset/Contents.json +38 -0
  105. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/secondary.colorset/Contents.json +38 -0
  106. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/success-container.colorset/Contents.json +38 -0
  107. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/success-primary.colorset/Contents.json +38 -0
  108. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/success-secondary.colorset/Contents.json +38 -0
  109. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-default.colorset/Contents.json +38 -0
  110. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-disable.colorset/Contents.json +38 -0
  111. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-hint.colorset/Contents.json +38 -0
  112. package/ios/Resources/MoMoUIKitsColors.xcassets/ThemeColors/text-secondary.colorset/Contents.json +38 -0
  113. package/ios/ScrollIndicator/ScrollIndicator.swift +110 -0
  114. package/ios/Skeleton/Skeleton.swift +99 -0
  115. package/ios/Slider/Slider.swift +237 -0
  116. package/ios/StatusBarTap/StatusBarTap.h +13 -0
  117. package/ios/StatusBarTap/StatusBarTap.m +75 -0
  118. package/ios/Stepper/Stepper.swift +221 -0
  119. package/ios/Steps/Steps.swift +467 -0
  120. package/ios/SuggestAction/SuggestAction.swift +100 -0
  121. package/ios/Swipeable/SwipeCell.swift +226 -31
  122. package/ios/Swipeable/SwipeCellModel.swift +21 -0
  123. package/ios/Switch/Switch.swift +69 -0
  124. package/ios/TabView/TabView.swift +534 -0
  125. package/ios/Tag/Tag.swift +99 -0
  126. package/ios/Template/Logo/Logo.swift +75 -0
  127. package/ios/Template/TrustBanner/TrustBanner.swift +123 -0
  128. package/ios/Title/Title.swift +270 -0
  129. package/ios/Tooltip/Tooltip.swift +486 -0
  130. package/ios/Typography/FontScale.swift +103 -0
  131. package/ios/Typography/FontScaleStore.swift +58 -0
  132. package/ios/Typography/KitDesignSystem.swift +17 -0
  133. package/ios/Typography/Text.swift +262 -0
  134. package/ios/Typography/Typography.swift +80 -23
  135. package/ios/Uploader/Uploader.swift +174 -0
  136. package/ios/native-kits.podspec +73 -13
  137. package/ios-demo/MoMoUIKitsDemo.podspec +20 -0
  138. package/ios-demo/Resources/dot_loading.json +558 -0
  139. package/ios-demo/Resources/icon.json +4052 -0
  140. package/ios-demo/Resources/lottie_circle_loader.json +1 -0
  141. package/ios-demo/Sources/MoMoUIKitsDemo/DemoScaffold.swift +48 -0
  142. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsBadgeDemoView.swift +25 -0
  143. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsButtonDemoView.swift +26 -0
  144. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsCheckboxDemoView.swift +19 -0
  145. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsChipDemoView.swift +33 -0
  146. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsInputDemoView.swift +48 -0
  147. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsPopupDemoView.swift +21 -0
  148. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsRadioDemoView.swift +17 -0
  149. package/ios-demo/Sources/MoMoUIKitsDemo/Demos/UIKitsTypographyDemoView.swift +28 -0
  150. package/ios-demo/Sources/MoMoUIKitsDemo/MoMoUIKitsDemoContext.swift +31 -0
  151. package/ios-demo/Sources/MoMoUIKitsDemo/MoMoUIKitsDemoFactory.swift +24 -0
  152. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/AnimatedHeaderDemo.swift +110 -0
  153. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/AvatarDemo.swift +107 -0
  154. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BadgeDemo.swift +75 -0
  155. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BaselineView.swift +117 -0
  156. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/BottomTabDemo.swift +89 -0
  157. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ButtonDemo.swift +108 -0
  158. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CarouselDemo.swift +96 -0
  159. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CheckboxDemo.swift +60 -0
  160. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ChipDemo.swift +76 -0
  161. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/CollapseDemo.swift +102 -0
  162. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ContentView.swift +107 -0
  163. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DateTimePickerDemo.swift +100 -0
  164. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DemoScreen.swift +420 -0
  165. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DividerDemo.swift +56 -0
  166. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/HeaderUserDemo.swift +49 -0
  167. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/Home.swift +276 -0
  168. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/IconButtonDemo.swift +93 -0
  169. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/IconDemo.swift +81 -0
  170. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ImageDemo.swift +65 -0
  171. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InformationDemo.swift +96 -0
  172. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputDemo.swift +117 -0
  173. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputDropDownDemo.swift +94 -0
  174. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputMoneyDemo.swift +94 -0
  175. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputOTPDemo.swift +88 -0
  176. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputPhoneNumberDemo.swift +120 -0
  177. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputSearchDemo.swift +85 -0
  178. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/InputTextAreaDemo.swift +87 -0
  179. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/LoaderDemo.swift +73 -0
  180. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/LocalizeDemo.swift +235 -0
  181. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/NavigationDemo.swift +241 -0
  182. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PaginationDemo.swift +68 -0
  183. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PlaygroundData.swift +76 -0
  184. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupDisplayDemo.swift +175 -0
  185. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupNotifyDemo.swift +95 -0
  186. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupPromotionDemo.swift +67 -0
  187. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ProgressInfoDemo.swift +101 -0
  188. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/RadioDemo.swift +64 -0
  189. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/RatingDemo.swift +68 -0
  190. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SectionDemo.swift +83 -0
  191. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SkeletonDemo.swift +61 -0
  192. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SliderDemo.swift +90 -0
  193. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SnackBarDemo.swift +82 -0
  194. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/StepperDemo.swift +93 -0
  195. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/StepsDemo.swift +114 -0
  196. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SuggestActionDemo.swift +90 -0
  197. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SwipeDemo.swift +107 -0
  198. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/SwitchDemo.swift +58 -0
  199. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TabViewDemo.swift +114 -0
  200. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TagDemo.swift +86 -0
  201. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ThemeDemo.swift +181 -0
  202. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TitleDemo.swift +104 -0
  203. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TooltipDemo.swift +118 -0
  204. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/TypographyDemo.swift +87 -0
  205. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/UploaderDemo.swift +85 -0
  206. package/ios-demo/Sources/MoMoUIKitsDemo/SwiftUIDemoBrowserView.swift +53 -0
  207. package/ios-demo/Sources/MoMoUIKitsDemo/UIKitsDemoModels.swift +15 -0
  208. package/ios-demo/Sources/MoMoUIKitsDemo/UIKitsDemoRegistry.swift +73 -0
  209. package/package.json +6 -6
  210. package/publish.sh +554 -20
  211. package/scripts/gen-ios-color.mjs +136 -0
  212. package/CODE_OF_CONDUCT.md +0 -133
  213. package/CONTRIBUTING.md +0 -114
  214. package/LICENSE +0 -20
  215. package/android/build.gradle +0 -82
  216. package/android/gradle.properties +0 -5
  217. package/android/src/main/AndroidManifest.xml +0 -4
  218. package/android/src/main/java/com/momoplatform/nativekits/NativeKitsPackage.kt +0 -17
  219. package/android/src/main/java/com/momoplatform/nativekits/NativeKitsViewManager.kt +0 -20
  220. package/example/ios/Example/Assets.xcassets/AppIcon.appiconset/Contents.json +0 -63
  221. package/example/ios/Example/ComponentDetail.swift +0 -35
  222. package/example/ios/Example/ComponentItem.swift +0 -24
  223. package/example/ios/Example/ComponentModel.swift +0 -33
  224. package/example/ios/Example/ContentView.swift +0 -53
  225. package/example/ios/Example/Example.entitlements +0 -10
  226. package/example/ios/Example/Foundation/ButtonDemo.swift +0 -80
  227. package/example/ios/Example/Foundation/Popup/ActionSheets.swift +0 -136
  228. package/example/ios/Example/Foundation/Popup/Floats.swift +0 -127
  229. package/example/ios/Example/Foundation/Popup/Popups.swift +0 -101
  230. package/example/ios/Example/Foundation/PopupDemo.swift +0 -366
  231. package/example/ios/Example/Foundation/TextInputDemo.swift +0 -31
  232. package/example/ios/Example/Foundation/TypographyDemo.swift +0 -53
  233. package/example/ios/Example/Foundation.swift +0 -26
  234. package/example/ios/Example/Info.plist +0 -18
  235. package/example/ios/Example/Library/SwipeableDemo.swift +0 -105
  236. package/example/ios/Example/Library.swift +0 -26
  237. package/example/ios/Example/Main.swift +0 -11
  238. package/example/ios/Example/Overview.swift +0 -20
  239. package/example/ios/Example/Resource/SFProText-Black.ttf +0 -0
  240. package/example/ios/Example/Resource/SFProText-Bold.ttf +0 -0
  241. package/example/ios/Example/Resource/SFProText-Heavy.ttf +0 -0
  242. package/example/ios/Example/Resource/SFProText-Light.ttf +0 -0
  243. package/example/ios/Example/Resource/SFProText-Medium.ttf +0 -0
  244. package/example/ios/Example/Resource/SFProText-Regular.ttf +0 -0
  245. package/example/ios/Example/Resource/SFProText-Semibold.ttf +0 -0
  246. package/example/ios/Example/Resource/SFProText-Thin.ttf +0 -0
  247. package/example/ios/Example/Resource/SFProText-Ultralight.ttf +0 -0
  248. package/example/ios/Example/Resource/foundation.json +0 -33
  249. package/example/ios/Example/Resource/library.json +0 -8
  250. package/example/ios/Example/Utils.swift +0 -30
  251. package/example/ios/Example/ViewModifier/DarkViewModifier.swift +0 -22
  252. package/example/ios/Example.xcodeproj/project.pbxproj +0 -570
  253. package/example/ios/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
  254. package/example/ios/Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
  255. package/example/ios/Example.xcodeproj/project.xcworkspace/xcuserdata/wem.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  256. package/example/ios/Example.xcodeproj/xcuserdata/wem.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
  257. package/example/ios/Example.xcworkspace/contents.xcworkspacedata +0 -10
  258. package/example/ios/Example.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
  259. package/example/ios/Example.xcworkspace/xcuserdata/wem.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  260. package/example/ios/Example.xcworkspace/xcuserdata/wem.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +0 -6
  261. package/example/ios/Podfile +0 -6
  262. package/example/ios/Podfile.lock +0 -16
  263. package/example/ios/Pods/Local Podspecs/MoMoUIKits.podspec.json +0 -29
  264. package/example/ios/Pods/Manifest.lock +0 -16
  265. package/example/ios/Pods/Pods.xcodeproj/project.pbxproj +0 -661
  266. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/wem.xcuserdatad/xcschemes/MoMoUIKits.xcscheme +0 -58
  267. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/wem.xcuserdatad/xcschemes/Pods-Example.xcscheme +0 -58
  268. package/example/ios/Pods/Pods.xcodeproj/xcuserdata/wem.xcuserdatad/xcschemes/xcschememanagement.plist +0 -25
  269. package/example/ios/Pods/Target Support Files/MoMoUIKits/MoMoUIKits-dummy.m +0 -5
  270. package/example/ios/Pods/Target Support Files/MoMoUIKits/MoMoUIKits-prefix.pch +0 -12
  271. package/example/ios/Pods/Target Support Files/MoMoUIKits/MoMoUIKits-umbrella.h +0 -16
  272. package/example/ios/Pods/Target Support Files/MoMoUIKits/MoMoUIKits.debug.xcconfig +0 -12
  273. package/example/ios/Pods/Target Support Files/MoMoUIKits/MoMoUIKits.modulemap +0 -6
  274. package/example/ios/Pods/Target Support Files/MoMoUIKits/MoMoUIKits.release.xcconfig +0 -12
  275. package/example/ios/Pods/Target Support Files/Pods-Example/Pods-Example-acknowledgements.markdown +0 -3
  276. package/example/ios/Pods/Target Support Files/Pods-Example/Pods-Example-acknowledgements.plist +0 -29
  277. package/example/ios/Pods/Target Support Files/Pods-Example/Pods-Example-dummy.m +0 -5
  278. package/example/ios/Pods/Target Support Files/Pods-Example/Pods-Example-umbrella.h +0 -16
  279. package/example/ios/Pods/Target Support Files/Pods-Example/Pods-Example.debug.xcconfig +0 -14
  280. package/example/ios/Pods/Target Support Files/Pods-Example/Pods-Example.modulemap +0 -6
  281. package/example/ios/Pods/Target Support Files/Pods-Example/Pods-Example.release.xcconfig +0 -14
  282. package/ios/Colors+Spacing/Radius.swift +0 -11
  283. package/ios/Popup/Utils++.swift +0 -163
  284. package/ios/Theme.md +0 -18
  285. /package/{example/ios/Example/Assets.xcassets → ios/Resources/MoMoUIKitsColors.xcassets}/Background.colorset/Contents.json +0 -0
  286. /package/{example/ios/Example/Assets.xcassets → ios/Resources/MoMoUIKitsColors.xcassets}/Border.colorset/Contents.json +0 -0
  287. /package/{example/ios/Example/Assets.xcassets → ios/Resources/MoMoUIKitsColors.xcassets}/Card.colorset/Contents.json +0 -0
  288. /package/{example/ios/Example/Assets.xcassets → ios/Resources/MoMoUIKitsColors.xcassets}/Contents.json +0 -0
  289. /package/{example/ios/Example/Assets.xcassets → ios/Resources/MoMoUIKitsColors.xcassets}/Error.colorset/Contents.json +0 -0
  290. /package/{example/ios/Example/Assets.xcassets → ios/Resources/MoMoUIKitsColors.xcassets}/Primary.colorset/Contents.json +0 -0
  291. /package/{example/ios/Example/Assets.xcassets → ios/Resources/MoMoUIKitsColors.xcassets}/PrimaryDark.colorset/Contents.json +0 -0
  292. /package/{example/ios/Example/Assets.xcassets → ios/Resources/MoMoUIKitsColors.xcassets}/PrimaryLight.colorset/Contents.json +0 -0
  293. /package/{example/ios/Example/Assets.xcassets → ios/Resources/MoMoUIKitsColors.xcassets}/Secondary.colorset/Contents.json +0 -0
  294. /package/{example/ios/Example/Assets.xcassets → ios/Resources/MoMoUIKitsColors.xcassets}/Success.colorset/Contents.json +0 -0
  295. /package/{example/ios/Example/Assets.xcassets → ios/Resources/MoMoUIKitsColors.xcassets}/TextSecondary.colorset/Contents.json +0 -0
  296. /package/{example/ios/Example/Assets.xcassets → ios/Resources/MoMoUIKitsColors.xcassets}/Warning.colorset/Contents.json +0 -0
@@ -0,0 +1,453 @@
1
+ //
2
+ // Navigator.swift
3
+ // MoMoUIKits
4
+ //
5
+ // SwiftUI mirror of Compose's Navigator + DynamicScreenRegistry.
6
+ // Screens are registered by Int id; the NavigationStack path stores routes
7
+ // by id and looks up content from the registry on render.
8
+ //
9
+
10
+ import SwiftUI
11
+ import Combine
12
+
13
+ // MARK: - Routes
14
+
15
+ public struct DynamicScreenRoute: Hashable, Identifiable {
16
+ public let id: Int
17
+ }
18
+
19
+ public struct DynamicDialogRoute: Hashable, Identifiable {
20
+ public let id: Int
21
+ }
22
+
23
+ // MARK: - Registry
24
+
25
+ public struct DynamicScreen {
26
+ public let id: Int
27
+ public let name: String
28
+ public let content: () -> AnyView
29
+ public var options: NavigationOptions?
30
+ }
31
+
32
+ public final class DynamicScreenRegistry {
33
+ private var screens: [Int: DynamicScreen] = [:]
34
+ private var idCounter: Int = 1
35
+
36
+ public init() {}
37
+
38
+ @discardableResult
39
+ public func register(
40
+ screenName: String = "",
41
+ content: @escaping () -> AnyView,
42
+ options: NavigationOptions? = nil
43
+ ) -> DynamicScreenRoute {
44
+ let id = idCounter
45
+ idCounter += 1
46
+ screens[id] = DynamicScreen(id: id, name: screenName, content: content, options: options)
47
+ return DynamicScreenRoute(id: id)
48
+ }
49
+
50
+ public func unregister(id: Int) {
51
+ screens.removeValue(forKey: id)
52
+ }
53
+
54
+ public func unregisterAll() {
55
+ screens.removeAll()
56
+ }
57
+
58
+ public func getScreen(id: Int) -> DynamicScreen? { screens[id] }
59
+
60
+ public func latest() -> DynamicScreen? {
61
+ screens.max(by: { $0.key < $1.key })?.value
62
+ }
63
+
64
+ public func setOptions(id: Int, options: NavigationOptions) {
65
+ screens[id]?.options = options
66
+ }
67
+ }
68
+
69
+ // MARK: - Overplay
70
+
71
+ public enum OverplayType {
72
+ case modal, bottomSheet, snackBar
73
+ }
74
+
75
+ public struct OverplayItem: Identifiable {
76
+ public let id = UUID()
77
+ public let type: OverplayType
78
+ public let content: () -> AnyView
79
+ public let barrierDismissible: Bool
80
+ public let onDismiss: (() -> Void)?
81
+ // Bottom-sheet params (mirrors Compose's OverplayComponentParams.BottomSheet).
82
+ public var isSurface: Bool = false
83
+ public var header: BottomSheetHeader? = nil
84
+ // Snack-bar payload (mirrors Compose's SnackBar value).
85
+ public var snackBar: SnackBar? = nil
86
+ }
87
+
88
+ // MARK: - Navigator
89
+
90
+ @available(iOS 16.0, *)
91
+ public final class Navigator: ObservableObject {
92
+ @Published public var path: [DynamicScreenRoute] = [] {
93
+ // Disposal hangs off the path so every route that leaves the stack — pop,
94
+ // replace, reset — is released the same way, after its exit transition.
95
+ didSet { disposeScreens(droppedFrom: oldValue) }
96
+ }
97
+ @Published public var presented: DynamicDialogRoute?
98
+ @Published public var overplay: OverplayItem?
99
+
100
+ /// Owned per-Navigator (mirrors Compose's `remember { DynamicScreenRegistry() }` +
101
+ /// disposal): screens registered by this navigator are released via ARC when the
102
+ /// navigator itself deallocates, instead of accumulating in a process-wide singleton.
103
+ public let registry = DynamicScreenRegistry()
104
+
105
+ /// Animated-close handler registered by the active overplay component
106
+ /// (mirrors Compose's `OverplayComponentRegistry.bindClose`). When set, a
107
+ /// dismiss request runs the component's exit animation before the item is
108
+ /// actually removed via `finishOverplayDismiss`.
109
+ private var overplayDismissHandler: (() -> Void)?
110
+
111
+ public private(set) var rootRoute: DynamicScreenRoute
112
+ public var composeApi: KitComposeApi?
113
+
114
+ public init(
115
+ initialScreenName: String = "",
116
+ initialContent: @escaping () -> AnyView,
117
+ options: NavigationOptions? = nil,
118
+ composeApi: KitComposeApi? = nil
119
+ ) {
120
+ self.composeApi = composeApi
121
+ self.rootRoute = registry.register(
122
+ screenName: initialScreenName,
123
+ content: initialContent,
124
+ options: options
125
+ )
126
+ }
127
+
128
+ // MARK: Stack
129
+
130
+ public func push<V: View>(@ViewBuilder _ content: @escaping () -> V, options: NavigationOptions? = nil) {
131
+ let route = registry.register(
132
+ screenName: options?.screenName ?? "",
133
+ content: { AnyView(content()) },
134
+ options: options
135
+ )
136
+ path.append(route)
137
+ }
138
+
139
+ public func push<V: View>(
140
+ screenName: String,
141
+ @ViewBuilder _ content: @escaping () -> V,
142
+ options: NavigationOptions? = nil
143
+ ) {
144
+ let route = registry.register(
145
+ screenName: screenName,
146
+ content: { AnyView(content()) },
147
+ options: options
148
+ )
149
+ path.append(route)
150
+ }
151
+
152
+ public func replace<V: View>(@ViewBuilder _ content: @escaping () -> V, options: NavigationOptions? = nil) {
153
+ guard !path.isEmpty else { return }
154
+ path.removeLast()
155
+ push(content, options: options)
156
+ }
157
+
158
+ public func replace<V: View>(
159
+ screenName: String,
160
+ @ViewBuilder _ content: @escaping () -> V,
161
+ options: NavigationOptions? = nil
162
+ ) {
163
+ guard !path.isEmpty else { return }
164
+ path.removeLast()
165
+ push(screenName: screenName, content, options: options)
166
+ }
167
+
168
+ public func reset<V: View>(@ViewBuilder _ content: @escaping () -> V, options: NavigationOptions? = nil) {
169
+ let previousRoot = rootRoute.id
170
+ path.removeAll()
171
+ let route = registry.register(
172
+ screenName: options?.screenName ?? "",
173
+ content: { AnyView(content()) },
174
+ options: options
175
+ )
176
+ rootRoute = route
177
+ disposeScreens([previousRoot])
178
+ }
179
+
180
+ public func reset<V: View>(
181
+ screenName: String,
182
+ @ViewBuilder _ content: @escaping () -> V,
183
+ options: NavigationOptions? = nil
184
+ ) {
185
+ let previousRoot = rootRoute.id
186
+ path.removeAll()
187
+ let route = registry.register(
188
+ screenName: screenName,
189
+ content: { AnyView(content()) },
190
+ options: options
191
+ )
192
+ rootRoute = route
193
+ disposeScreens([previousRoot])
194
+ }
195
+
196
+ public func pop(_ count: Int = 1, callback: (() -> Void)? = nil) {
197
+ popStep(remaining: count, callback: callback)
198
+ }
199
+
200
+ /// One `pop` iteration. Compose runs the loop in a coroutine and suspends over the
201
+ /// overplay's exit animation before the next step; the same wait is needed here, or
202
+ /// a `pop(2)` (prevent-back: close the popup, then leave) would spend both steps on
203
+ /// the overplay that is still animating out and never pop the screen.
204
+ private func popStep(remaining: Int, callback: (() -> Void)?) {
205
+ guard remaining > 0 else {
206
+ callback?()
207
+ return
208
+ }
209
+
210
+ if overplay?.type == .snackBar {
211
+ // Mirrors Kotlin: a snackbar doesn't block back-navigation, so popping
212
+ // while one is showing pops the screen underneath and clears the
213
+ // snackbar immediately, without playing its dismiss animation.
214
+ overplayDismissHandler = nil
215
+ overplay = nil
216
+ guard popScreen() else {
217
+ callback?()
218
+ return
219
+ }
220
+ popStep(remaining: remaining - 1, callback: callback)
221
+ } else if overplay != nil {
222
+ hideOverplay()
223
+ DispatchQueue.main.asyncAfter(deadline: .now() + Self.overplayDismissDelay) { [weak self] in
224
+ guard let self else { return }
225
+ // The component reports back through `finishOverplayDismiss` once its exit
226
+ // animation ends; clear it here if it never did, so the step is not wasted.
227
+ if self.overplay != nil { self.finishOverplayDismiss() }
228
+ self.popStep(remaining: remaining - 1, callback: callback)
229
+ }
230
+ } else {
231
+ guard popScreen() else {
232
+ callback?()
233
+ return
234
+ }
235
+ popStep(remaining: remaining - 1, callback: callback)
236
+ }
237
+ }
238
+
239
+ /// Pops the topmost presented screen or stack entry. Returns `false` (and requests
240
+ /// a host dismiss) when there is nothing left to pop.
241
+ @discardableResult
242
+ private func popScreen() -> Bool {
243
+ if presented != nil {
244
+ let dismissedId = presented?.id
245
+ presented = nil
246
+ if let id = dismissedId { disposeScreens([id]) }
247
+ return true
248
+ } else if !path.isEmpty {
249
+ path.removeLast()
250
+ return true
251
+ } else {
252
+ composeApi?.requestCallback(funcName: "dismiss", params: nil, onResponse: nil)
253
+ return false
254
+ }
255
+ }
256
+
257
+ public func popToRoot() {
258
+ path.removeAll()
259
+ }
260
+
261
+ /// The entry a back action applies to — mirrors Compose's `currentScreen()`
262
+ /// (`navController.currentBackStackEntry`): a presented screen sits on top of
263
+ /// the stack, otherwise it is the last pushed screen, otherwise the root.
264
+ private func currentScreen() -> DynamicScreen? {
265
+ registry.getScreen(id: presented?.id ?? path.last?.id ?? rootRoute.id)
266
+ }
267
+
268
+ public func onBackSafe(callback: (() -> Void)? = nil) {
269
+ let latest = currentScreen()
270
+ if let onBack = latest?.options?.onBackHandler {
271
+ onBack()
272
+ return
273
+ }
274
+ if let preventBack = latest?.options?.headerBackProps?.preventBack {
275
+ showModal {
276
+ PopupNotify(
277
+ props: PopupNotifyProps(
278
+ image: preventBack.image,
279
+ title: preventBack.title,
280
+ description: preventBack.description,
281
+ error: preventBack.error,
282
+ primary: PopupAction(
283
+ title: preventBack.primary?.title ?? "",
284
+ onPress: { [weak self] in
285
+ preventBack.primary?.onPress?()
286
+ // Close the popup, then leave the screen (matches Compose's pop(2)).
287
+ self?.pop(2, callback: callback)
288
+ }
289
+ ),
290
+ secondary: preventBack.secondary.map { secondary in
291
+ PopupAction(
292
+ title: secondary.title,
293
+ onPress: { [weak self] in
294
+ secondary.onPress?()
295
+ self?.hideOverplay()
296
+ }
297
+ )
298
+ },
299
+ buttonDirection: preventBack.buttonDirection,
300
+ onIconClose: { [weak self] in
301
+ preventBack.onIconClose?()
302
+ self?.hideOverplay()
303
+ },
304
+ isShowCloseIcon: preventBack.isShowCloseIcon
305
+ )
306
+ )
307
+ }
308
+ return
309
+ }
310
+ pop(1, callback: callback)
311
+ }
312
+
313
+ // MARK: Modal-style screen (vertical slide)
314
+
315
+ public func present<V: View>(@ViewBuilder _ content: @escaping () -> V, options: NavigationOptions? = nil) {
316
+ let route = registry.register(
317
+ screenName: options?.screenName ?? "",
318
+ content: { AnyView(content()) },
319
+ options: options
320
+ )
321
+ presented = DynamicDialogRoute(id: route.id)
322
+ }
323
+
324
+ public func present<V: View>(
325
+ screenName: String,
326
+ @ViewBuilder _ content: @escaping () -> V,
327
+ options: NavigationOptions? = nil
328
+ ) {
329
+ let route = registry.register(
330
+ screenName: screenName,
331
+ content: { AnyView(content()) },
332
+ options: options
333
+ )
334
+ presented = DynamicDialogRoute(id: route.id)
335
+ }
336
+
337
+ public func dismiss() {
338
+ if let id = presented?.id {
339
+ registry.unregister(id: id)
340
+ }
341
+ presented = nil
342
+ }
343
+
344
+ // MARK: Overplay
345
+
346
+ public func showModal<V: View>(
347
+ @ViewBuilder _ content: @escaping () -> V,
348
+ barrierDismissible: Bool = true,
349
+ onDismiss: (() -> Void)? = nil
350
+ ) {
351
+ overplayDismissHandler = nil
352
+ overplay = OverplayItem(
353
+ type: .modal,
354
+ content: { AnyView(content()) },
355
+ barrierDismissible: barrierDismissible,
356
+ onDismiss: onDismiss
357
+ )
358
+ }
359
+
360
+ public func showBottomSheet<V: View>(
361
+ @ViewBuilder _ content: @escaping () -> V,
362
+ isSurface: Bool = false,
363
+ barrierDismissible: Bool = true,
364
+ header: BottomSheetHeader? = nil,
365
+ onDismiss: (() -> Void)? = nil
366
+ ) {
367
+ overplayDismissHandler = nil
368
+ overplay = OverplayItem(
369
+ type: .bottomSheet,
370
+ content: { AnyView(content()) },
371
+ barrierDismissible: barrierDismissible,
372
+ onDismiss: onDismiss,
373
+ isSurface: isSurface,
374
+ header: header
375
+ )
376
+ }
377
+
378
+ /// Mirrors Compose's `showSnackBar(snackBar:)`.
379
+ public func showSnackBar(_ snackBar: SnackBar, onDismiss: (() -> Void)? = nil) {
380
+ overplayDismissHandler = nil
381
+ overplay = OverplayItem(
382
+ type: .snackBar,
383
+ content: { AnyView(EmptyView()) },
384
+ barrierDismissible: false,
385
+ onDismiss: onDismiss,
386
+ snackBar: snackBar
387
+ )
388
+ }
389
+
390
+ // MARK: Overplay dismissal
391
+
392
+ /// Registered by the active overplay component so external dismiss requests
393
+ /// run its exit animation (mirrors Compose's `bindClose`).
394
+ public func registerOverplayDismiss(_ handler: @escaping () -> Void) {
395
+ overplayDismissHandler = handler
396
+ }
397
+
398
+ /// Removes the overplay and fires its `onDismiss` (mirrors Compose's
399
+ /// `hardClearAfterDismiss`). Called by a component once its exit animation
400
+ /// has completed.
401
+ public func finishOverplayDismiss() {
402
+ let dismissCallback = overplay?.onDismiss
403
+ overplayDismissHandler = nil
404
+ overplay = nil
405
+ dismissCallback?()
406
+ }
407
+
408
+ public func hideOverplay() {
409
+ if let close = overplayDismissHandler {
410
+ // Component runs its exit animation, then calls finishOverplayDismiss.
411
+ overplayDismissHandler = nil
412
+ close()
413
+ } else {
414
+ finishOverplayDismiss()
415
+ }
416
+ }
417
+
418
+ public func hideSnackBar() {
419
+ if overplay?.type == .snackBar { hideOverplay() }
420
+ }
421
+
422
+ // MARK: Screen disposal
423
+
424
+ /// Matches the `delay(300)` Compose waits in `dismissScreen` before unregistering,
425
+ /// with a little headroom for the pop transition.
426
+ private static let screenDisposeDelay: TimeInterval = 0.35
427
+
428
+ /// Longest overplay exit animation (the bottom sheet's), so a queued pop step runs
429
+ /// after the component has taken itself down.
430
+ private static let overplayDismissDelay: TimeInterval = 0.3
431
+
432
+ private func disposeScreens(droppedFrom previous: [DynamicScreenRoute]) {
433
+ let live = Set(path.map(\.id))
434
+ disposeScreens(previous.map(\.id).filter { !live.contains($0) })
435
+ }
436
+
437
+ /// Screens are released only once the pop transition has played out: the outgoing
438
+ /// view is still on screen while it animates and the registry is what renders it —
439
+ /// dropping it right away blanks the screen mid-transition. Liveness is re-checked
440
+ /// when the timer fires, so a route pushed back before then keeps its screen.
441
+ private func disposeScreens(_ ids: [Int]) {
442
+ guard !ids.isEmpty else { return }
443
+ DispatchQueue.main.asyncAfter(deadline: .now() + Self.screenDisposeDelay) { [weak self] in
444
+ guard let self else { return }
445
+ var live = Set(self.path.map(\.id))
446
+ live.insert(self.rootRoute.id)
447
+ if let presented = self.presented { live.insert(presented.id) }
448
+ for id in ids where !live.contains(id) {
449
+ self.registry.unregister(id: id)
450
+ }
451
+ }
452
+ }
453
+ }
@@ -0,0 +1,22 @@
1
+ import Foundation
2
+
3
+ @available(iOS 16.0, *)
4
+ public final class NavigatorManager {
5
+ public static let shared = NavigatorManager()
6
+ private init() {}
7
+
8
+ private var navigators: [Navigator] = []
9
+
10
+ public func push(_ navigator: Navigator) {
11
+ guard !navigators.contains(where: { $0 === navigator }) else { return }
12
+ navigators.append(navigator)
13
+ }
14
+
15
+ public func remove(_ navigator: Navigator) {
16
+ navigators.removeAll { $0 === navigator }
17
+ }
18
+
19
+ public func checkCanPop() -> Bool { !navigators.isEmpty }
20
+
21
+ public func pop() { navigators.last?.onBackSafe() }
22
+ }