@momo-kits/native-kits 0.167.1-duo.8-debug → 0.167.1-duo.9

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 (254) hide show
  1. package/CLAUDE.md +4 -1
  2. package/ios/Application/ApplicationEnvironment.swift +11 -0
  3. package/ios/Application/ComposeApi.swift +2 -1
  4. package/ios/Application/{Components.swift → LegacyHeader.swift} +6 -62
  5. package/ios/Application/Screen.swift +3 -2
  6. package/ios/Avatar/Avatar.swift +4 -3
  7. package/ios/Badge/Badge.swift +6 -4
  8. package/ios/Badge/BadgeDot.swift +1 -1
  9. package/ios/Badge/BadgeRibbon.swift +0 -1
  10. package/ios/Button/Button.swift +15 -12
  11. package/ios/CalculatorKeyboard/CalculatorKeyboard.swift +12 -20
  12. package/ios/Carousel/Carousel.swift +29 -12
  13. package/ios/Checkbox/Checkbox.swift +7 -3
  14. package/ios/Chip/Chip.swift +5 -4
  15. package/ios/Collapse/Collapse.swift +70 -19
  16. package/ios/Colors+Radius+Spacing/Colors.swift +9 -0
  17. package/ios/DateTimePicker/DateTimePicker.swift +54 -20
  18. package/ios/DateTimePicker/WheelPicker.swift +103 -105
  19. package/ios/Divider/Divider.swift +37 -4
  20. package/ios/Extensions/Color++.swift +18 -0
  21. package/ios/Icon/Icon.swift +7 -1
  22. package/ios/IconButton/IconButton.swift +15 -7
  23. package/ios/Image/Image.swift +7 -34
  24. package/ios/Information/Information.swift +27 -9
  25. package/ios/Input/ErrorView.swift +2 -2
  26. package/ios/Input/Input.swift +160 -147
  27. package/ios/Input/InputPhoneNumber.swift +12 -9
  28. package/ios/Input/InputSearch.swift +102 -75
  29. package/ios/Input/InputTextArea.swift +128 -145
  30. package/ios/InputDropDown/InputDropDown.swift +10 -7
  31. package/ios/InputMoney/InputMoney.swift +33 -11
  32. package/ios/InputOTP/InputOTP.swift +22 -12
  33. package/ios/Layout/Card.swift +50 -0
  34. package/ios/Layout/GridContext.swift +123 -3
  35. package/ios/Layout/Item.swift +5 -4
  36. package/ios/Layout/Section.swift +4 -100
  37. package/ios/Loader/Loader.swift +5 -9
  38. package/ios/Lottie/LottieView.swift +10 -0
  39. package/ios/{Application/Navigation/Overplay → Navigation}/BottomSheet.swift +61 -9
  40. package/ios/{Application/Navigation → Navigation}/BottomTab/BottomTab.swift +60 -34
  41. package/ios/{Application/Navigation → Navigation}/BottomTab/BottomTabBar.swift +11 -6
  42. package/ios/{Application → Navigation/Component}/FloatingButton.swift +14 -3
  43. package/ios/Navigation/Component/Header.swift +493 -0
  44. package/ios/Navigation/Component/HeaderBackground.swift +134 -0
  45. package/ios/Navigation/Component/HeaderJourney.swift +73 -0
  46. package/ios/Navigation/Component/HeaderLocation.swift +48 -0
  47. package/ios/Navigation/Component/HeaderRight.swift +386 -0
  48. package/ios/Navigation/Component/HeaderTitle.swift +36 -0
  49. package/ios/{Application/Navigation → Navigation/Component}/HeaderUser.swift +20 -23
  50. package/ios/{Application/Navigation/component → Navigation/Component}/SideBar.swift +49 -28
  51. package/ios/{Application/Navigation/Overplay → Navigation/Component}/SnackBar.swift +5 -5
  52. package/ios/Navigation/HostBackGestureBridge.swift +57 -0
  53. package/ios/Navigation/Navigation.swift +190 -0
  54. package/ios/{Application/Navigation → Navigation}/NavigationContainer.swift +46 -41
  55. package/ios/{Application/Navigation → Navigation}/Navigator.swift +65 -9
  56. package/ios/{Application → Navigation}/StackScreen.swift +236 -103
  57. package/ios/{Application/Navigation → Navigation}/Tracking/ScreenTracker.swift +12 -5
  58. package/ios/OTPKeyboard/OTPKeyboard.swift +8 -11
  59. package/ios/Pagination/PaginationScroll.swift +2 -2
  60. package/ios/Popup/PopupDisplay.swift +79 -159
  61. package/ios/Popup/PopupInput.swift +10 -13
  62. package/ios/Popup/PopupLayout.swift +97 -2
  63. package/ios/Popup/PopupNotify.swift +27 -55
  64. package/ios/Popup/PopupPromotion.swift +22 -50
  65. package/ios/PopupView/FullscreenPopup.swift +13 -19
  66. package/ios/PopupView/PopupView.swift +1 -1
  67. package/ios/PopupView/Utils++.swift +0 -8
  68. package/ios/ProgressInfo/ProgressInfo.swift +4 -2
  69. package/ios/Radio/Radio.swift +2 -1
  70. package/ios/Rating/Rating.swift +9 -1
  71. package/ios/ScrollIndicator/ScrollIndicator.swift +11 -10
  72. package/ios/Skeleton/Skeleton.swift +22 -27
  73. package/ios/Slider/Slider.swift +16 -18
  74. package/ios/Stepper/Stepper.swift +6 -1
  75. package/ios/Steps/Steps.swift +8 -6
  76. package/ios/SuggestAction/SuggestAction.swift +5 -0
  77. package/ios/Swipeable/SwipeCell.swift +10 -6
  78. package/ios/Switch/Switch.swift +22 -20
  79. package/ios/TabView/TabView.swift +102 -21
  80. package/ios/Tag/Tag.swift +15 -4
  81. package/ios/Template/Logo/Logo.swift +2 -1
  82. package/ios/Template/TrustBanner/TrustBanner.swift +41 -27
  83. package/ios/Title/Title.swift +6 -17
  84. package/ios/Tooltip/Tooltip.swift +29 -14
  85. package/ios/Typography/Text.swift +61 -19
  86. package/ios/Uploader/Uploader.swift +3 -1
  87. package/ios/native-kits.podspec +1 -0
  88. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ContentView.swift +1 -1
  89. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/NavigationDemo.swift +77 -1
  90. package/package.json +1 -1
  91. package/build.gradle.kts +0 -11
  92. package/compose/build.gradle.kts +0 -204
  93. package/compose/build.gradle.kts.backup +0 -204
  94. package/compose/compose.podspec +0 -47
  95. package/compose/src/androidMain/kotlin/vn/momo/kits/const/HostFont.android.kt +0 -19
  96. package/compose/src/androidMain/kotlin/vn/momo/kits/navigation/ScrollToTop.android.kt +0 -6
  97. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/BackGesture.android.kt +0 -12
  98. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/OsFontScale.android.kt +0 -7
  99. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/Platform.android.kt +0 -153
  100. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/ReservedRegions.android.kt +0 -6
  101. package/compose/src/commonMain/kotlin/vn/momo/kits/application/AnimationSearchInput.kt +0 -52
  102. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Context.kt +0 -124
  103. package/compose/src/commonMain/kotlin/vn/momo/kits/application/FloatingButton.kt +0 -183
  104. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Header.kt +0 -207
  105. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderAnimated.kt +0 -39
  106. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderBackground.kt +0 -86
  107. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderDefault.kt +0 -76
  108. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderExtended.kt +0 -76
  109. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderRight.kt +0 -293
  110. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderTitle.kt +0 -33
  111. package/compose/src/commonMain/kotlin/vn/momo/kits/application/LiteScreen.kt +0 -831
  112. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Localize.kt +0 -269
  113. package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +0 -110
  114. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +0 -378
  115. package/compose/src/commonMain/kotlin/vn/momo/kits/application/WidgetContainer.kt +0 -56
  116. package/compose/src/commonMain/kotlin/vn/momo/kits/application/useHeaderSearchAnimation.kt +0 -69
  117. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Avatar.kt +0 -157
  118. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Badge.kt +0 -82
  119. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeDot.kt +0 -32
  120. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeRibbon.kt +0 -338
  121. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BaselineView.kt +0 -175
  122. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +0 -356
  123. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Carousel.kt +0 -113
  124. package/compose/src/commonMain/kotlin/vn/momo/kits/components/CheckBox.kt +0 -89
  125. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Chip.kt +0 -128
  126. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Collapse.kt +0 -209
  127. package/compose/src/commonMain/kotlin/vn/momo/kits/components/CupertinoOverscroll.kt +0 -542
  128. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Divider.kt +0 -49
  129. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Icon.kt +0 -76
  130. package/compose/src/commonMain/kotlin/vn/momo/kits/components/IconButton.kt +0 -125
  131. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Image.kt +0 -231
  132. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Information.kt +0 -189
  133. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +0 -475
  134. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputDropDown.kt +0 -114
  135. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputMoney.kt +0 -266
  136. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputOTP.kt +0 -240
  137. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputPhoneNumber.kt +0 -223
  138. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +0 -264
  139. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +0 -185
  140. package/compose/src/commonMain/kotlin/vn/momo/kits/components/LazyColumnWithBouncing.kt +0 -343
  141. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Loader.kt +0 -108
  142. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationDot.kt +0 -56
  143. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationNumber.kt +0 -41
  144. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationScroll.kt +0 -84
  145. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationWhiteDot.kt +0 -40
  146. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +0 -361
  147. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupPromotion.kt +0 -108
  148. package/compose/src/commonMain/kotlin/vn/momo/kits/components/ProgressInfo.kt +0 -310
  149. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Radio.kt +0 -59
  150. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Rating.kt +0 -87
  151. package/compose/src/commonMain/kotlin/vn/momo/kits/components/ScaleSizeScope.kt +0 -21
  152. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Skeleton.kt +0 -90
  153. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Slider.kt +0 -323
  154. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Stepper.kt +0 -220
  155. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Steps.kt +0 -473
  156. package/compose/src/commonMain/kotlin/vn/momo/kits/components/SuggestAction.kt +0 -122
  157. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Swipe.kt +0 -199
  158. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Switch.kt +0 -91
  159. package/compose/src/commonMain/kotlin/vn/momo/kits/components/TabView.kt +0 -552
  160. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tag.kt +0 -88
  161. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +0 -125
  162. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Title.kt +0 -207
  163. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tooltip.kt +0 -498
  164. package/compose/src/commonMain/kotlin/vn/momo/kits/components/TrustBanner.kt +0 -176
  165. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Uploader.kt +0 -182
  166. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePicker.kt +0 -193
  167. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerTypes.kt +0 -29
  168. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerUtils.kt +0 -234
  169. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/WheelPicker.kt +0 -188
  170. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Colors.kt +0 -325
  171. package/compose/src/commonMain/kotlin/vn/momo/kits/const/HostFont.kt +0 -16
  172. package/compose/src/commonMain/kotlin/vn/momo/kits/const/KitDesignSystem.kt +0 -18
  173. package/compose/src/commonMain/kotlin/vn/momo/kits/const/KitFontScale.kt +0 -22
  174. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Radius.kt +0 -12
  175. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Spacing.kt +0 -16
  176. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Theme.kt +0 -188
  177. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +0 -297
  178. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Card.kt +0 -54
  179. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Item.kt +0 -50
  180. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/ScreenLayout.kt +0 -232
  181. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Section.kt +0 -41
  182. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/AutomationId.kt +0 -52
  183. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Clickable.kt +0 -66
  184. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Conditional.kt +0 -11
  185. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/DeprecatedModifier.kt +0 -104
  186. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Shadow.kt +0 -48
  187. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Size.kt +0 -51
  188. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/BottomSheet.kt +0 -338
  189. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/HostBackGestureBridge.kt +0 -58
  190. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ModalScreen.kt +0 -137
  191. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigation.kt +0 -106
  192. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +0 -205
  193. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigator.kt +0 -393
  194. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ScrollToTop.kt +0 -8
  195. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +0 -708
  196. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackTransition.kt +0 -148
  197. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/SwipeBackHaptic.kt +0 -35
  198. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTab.kt +0 -203
  199. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +0 -232
  200. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/CurvedContainer.kt +0 -86
  201. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/DuoBarCompression.kt +0 -98
  202. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/DuoTabBar.kt +0 -312
  203. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/FloatingButton.kt +0 -169
  204. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +0 -408
  205. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderBackground.kt +0 -92
  206. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderJourney.kt +0 -105
  207. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderLocation.kt +0 -74
  208. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderRight.kt +0 -366
  209. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderTitle.kt +0 -37
  210. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderUser.kt +0 -363
  211. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SideBar.kt +0 -185
  212. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SnackBar.kt +0 -132
  213. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/tracking/ScreenTracker.kt +0 -127
  214. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/BackGesture.kt +0 -12
  215. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/ComposeLottieAnimation.kt +0 -91
  216. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/OsFontScale.kt +0 -9
  217. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +0 -74
  218. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/ReservedRegions.kt +0 -13
  219. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Icons.kt +0 -1329
  220. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Resources.kt +0 -55
  221. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Tracking.kt +0 -15
  222. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Utils.kt +0 -118
  223. package/compose/src/iosMain/kotlin/vn/momo/kits/const/HostFont.ios.kt +0 -40
  224. package/compose/src/iosMain/kotlin/vn/momo/kits/navigation/HostBackGesture.ios.kt +0 -45
  225. package/compose/src/iosMain/kotlin/vn/momo/kits/navigation/ScrollToTop.ios.kt +0 -32
  226. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/BackGesture.ios.kt +0 -38
  227. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/OsFontScale.ios.kt +0 -66
  228. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +0 -217
  229. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/ReservedRegions.ios.kt +0 -86
  230. package/gradle/libs.versions.toml +0 -69
  231. package/gradle/wrapper/gradle-wrapper.jar +0 -0
  232. package/gradle/wrapper/gradle-wrapper.properties +0 -8
  233. package/gradle.properties +0 -26
  234. package/gradlew +0 -252
  235. package/gradlew.bat +0 -94
  236. package/ios/Application/HeaderRight.swift +0 -324
  237. package/ios/Application/Navigation/HeaderBackProps.swift +0 -66
  238. package/ios/Application/Navigation/HeaderTitle.swift +0 -57
  239. package/ios/Application/Navigation/NavigationOptions.swift +0 -109
  240. package/ios/Application/Navigation/NavigatorManager.swift +0 -29
  241. package/ios/Application/Navigation/component/DuoScrollGradient.swift +0 -54
  242. package/ios/Application/Navigation/component/Header.swift +0 -183
  243. package/ios/Application/Navigation/component/HeaderBackground.swift +0 -84
  244. package/ios/Application/Navigation/component/HeaderColor.swift +0 -65
  245. package/ios/Application/Navigation/component/HeaderRightWidthKey.swift +0 -11
  246. package/ios/Application/Navigation/component/NavigationFooter.swift +0 -90
  247. package/ios/Application/Navigation/component/NavigationHeaderRight.swift +0 -280
  248. package/ios-demo/README.md +0 -120
  249. package/settings.gradle.kts +0 -64
  250. /package/ios/{Application/Layout → Layout}/ScreenLayout.swift +0 -0
  251. /package/ios/{Application/Navigation → Navigation}/BottomTab/CurvedContainer.swift +0 -0
  252. /package/ios/{Application/Navigation → Navigation}/BottomTab/DuoBarCompression.swift +0 -0
  253. /package/ios/{Application/Navigation → Navigation}/BottomTab/DuoTabBar.swift +0 -0
  254. /package/ios/{Application/Navigation/Overplay → Navigation}/ModalScreen.swift +0 -0
@@ -2,7 +2,7 @@
2
2
  // BottomSheet.swift
3
3
  // MoMoUIKits
4
4
  //
5
- // SwiftUI mirror of Compose's `BottomSheet` (navigation/BottomSheet.kt).
5
+ // SwiftUI mirror of Compose's `navigation/BottomSheet.kt`.
6
6
  // A sheet that slides up from the bottom over a dimmed scrim, with a drag
7
7
  // handle, a header (title or custom), a divider and the content body.
8
8
  // Dragging down past a threshold (or tapping the scrim) dismisses it.
@@ -40,6 +40,10 @@ struct BottomSheetView<Content: View>: View {
40
40
  let header: BottomSheetHeader
41
41
  let isSurface: Bool
42
42
  let barrierDismissible: Bool
43
+ var draggable: Bool = true
44
+ /// Keeps the content above the home indicator (Compose `AppNavigationBar` padding).
45
+ var useBottomInset: Bool = true
46
+ var footer: (() -> AnyView)? = nil
43
47
  let content: () -> Content
44
48
 
45
49
  @EnvironmentObject private var navigator: Navigator
@@ -93,11 +97,10 @@ struct BottomSheetView<Content: View>: View {
93
97
  }
94
98
 
95
99
  /// The keyboard filler is part of the sheet, so capping the sheet shrinks the content by it.
96
- private var duoMaxHeight: CGFloat? {
97
- guard isDuo else { return nil }
98
- return layout.height - max(layout.duoTopInset, Spacing.XL)
100
+ private var maxHeight: CGFloat {
101
+ isDuo ? layout.height - max(layout.duoTopInset, Spacing.XL) : screenHeight - 90
99
102
  }
100
- private var bottomInset: CGFloat { safeAreaBottomInset() }
103
+ private var bottomInset: CGFloat { useBottomInset ? safeAreaBottomInset() : 0 }
101
104
  /// While the keyboard is up, it already covers the home-indicator area, so it
102
105
  /// replaces (rather than adds to) the usual bottom-inset filler.
103
106
  private var effectiveBottomInset: CGFloat { keyboardHeight > 0 ? keyboardHeight : bottomInset }
@@ -174,7 +177,7 @@ struct BottomSheetView<Content: View>: View {
174
177
  .frame(maxWidth: .infinity)
175
178
  .frame(height: 72)
176
179
  .contentShape(Rectangle())
177
- .gesture(dragGesture)
180
+ .gesture(dragGesture, including: draggable ? .all : .subviews)
178
181
 
179
182
  Rectangle()
180
183
  .fill(theme.colors.border.default)
@@ -183,14 +186,18 @@ struct BottomSheetView<Content: View>: View {
183
186
  content()
184
187
  .padding(.leading, sideInsetLeading)
185
188
  .padding(.trailing, sideInsetTrailing)
186
- // a tall sheet on iPhone Duo keeps its header and gives the content what is left
189
+ // a tall sheet keeps its header (and footer) and gives the content what is left
187
190
  .layoutPriority(-1)
188
191
 
189
- backgroundColor
192
+ if let footer {
193
+ BottomSheetFooter(content: footer)
194
+ }
195
+
196
+ (footer != nil ? theme.colors.background.surface : backgroundColor)
190
197
  .frame(height: effectiveBottomInset)
191
198
  }
192
199
  .frame(maxWidth: isDuoCentered ? duoCenteredWidth : .infinity)
193
- .frame(maxHeight: duoMaxHeight, alignment: .bottom)
200
+ .modifier(CapHeight(maxHeight: maxHeight))
194
201
  .clipped()
195
202
  .background(
196
203
  GeometryReader { geo in
@@ -284,6 +291,51 @@ struct BottomSheetView<Content: View>: View {
284
291
  }
285
292
  }
286
293
 
294
+ /// Compose's `heightIn(max:)`: caps the sheet but keeps it hugging its content, which
295
+ /// `.frame(maxHeight:)` would not — a flexible frame grows to the cap.
296
+ @available(iOS 16.0, *)
297
+ private struct CapHeight: ViewModifier {
298
+ let maxHeight: CGFloat
299
+
300
+ func body(content: Content) -> some View {
301
+ CapHeightLayout(maxHeight: maxHeight) { content }
302
+ }
303
+ }
304
+
305
+ @available(iOS 16.0, *)
306
+ private struct CapHeightLayout: Layout {
307
+ let maxHeight: CGFloat
308
+
309
+ func sizeThatFits(proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) -> CGSize {
310
+ let height = min(proposal.height ?? .infinity, maxHeight)
311
+ return subviews.first?.sizeThatFits(ProposedViewSize(width: proposal.width, height: height)) ?? .zero
312
+ }
313
+
314
+ func placeSubviews(in bounds: CGRect, proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) {
315
+ subviews.first?.place(at: bounds.origin, proposal: ProposedViewSize(bounds.size))
316
+ }
317
+ }
318
+
319
+ /// Mirrors Compose's `BottomSheetFooter`: a surface band with a soft shadow cast on the content.
320
+ private struct BottomSheetFooter: View {
321
+ let content: () -> AnyView
322
+
323
+ @Environment(\.appTheme) private var theme
324
+
325
+ var body: some View {
326
+ content()
327
+ .frame(maxWidth: .infinity)
328
+ .padding(.vertical, Spacing.S)
329
+ .background(theme.colors.background.surface)
330
+ .overlay(alignment: .top) {
331
+ LinearGradient(colors: [.clear, Color.black.opacity(0.05)], startPoint: .top, endPoint: .bottom)
332
+ .frame(height: 6)
333
+ .offset(y: -6)
334
+ .allowsHitTesting(false)
335
+ }
336
+ }
337
+ }
338
+
287
339
  @available(iOS 16.0, *)
288
340
  private func safeAreaBottomInset() -> CGFloat {
289
341
  let bottomInset = UIApplication.shared.connectedScenes
@@ -2,10 +2,9 @@
2
2
  // BottomTab.swift
3
3
  // MoMoUIKits
4
4
  //
5
- // SwiftUI mirror of Compose's `BottomTab` (navigation/bottomtab/BottomTab.kt).
6
- // Hosts a set of tabbed screens, each wrapped in `StackScreen` chrome built
7
- // from that tab's `NavigationOptions`, with a `BottomTabBar` pinned to the
8
- // bottom. Switching tabs cross-fades + scales the content (parity with Compose).
5
+ // SwiftUI mirror of Compose's `navigation/bottomtab/BottomTab.kt`: tabbed screens, each in
6
+ // `StackScreen` chrome built from its own `Navigation`, over a `BottomTabBar` (or the iPhone Duo
7
+ // rail / floating bar). Switching tabs cross-fades + scales the content.
9
8
  //
10
9
 
11
10
  import SwiftUI
@@ -17,7 +16,11 @@ public struct BottomTab: View {
17
16
  private let compressionBehavior: DuoBarCompressionBehavior
18
17
 
19
18
  @EnvironmentObject private var navigator: Navigator
19
+ /// The screen hosting the tabs (Compose's `LocalNavigation` in BottomTab).
20
+ @OptionalEnvironmentObject private var hostNavigation: Navigation?
20
21
  @Environment(\.screenLayout) private var layout
22
+ @Environment(\.appTheme) private var theme
23
+ @StateObject private var tabNavigations = TabNavigations()
21
24
  @State private var selectedIndex: Int = 0
22
25
  @State private var toolbarHeight = DuoBarCompression.defaultToolbarHeight
23
26
  @State private var expandedBar: DuoBar?
@@ -101,7 +104,7 @@ public struct BottomTab: View {
101
104
  selectedIndex: selectedIndex,
102
105
  onTabSelected: selectTab
103
106
  )
104
- Colors.black01
107
+ theme.colors.background.surface
105
108
  .frame(height: bottomInset + Spacing.S)
106
109
  .ignoresSafeArea(edges: .horizontal)
107
110
  }
@@ -110,44 +113,67 @@ public struct BottomTab: View {
110
113
  .frame(maxWidth: .infinity, maxHeight: .infinity)
111
114
  .ignoresSafeArea(edges: .bottom)
112
115
  .preference(key: IsBottomTabRootKey.self, value: true)
116
+ .onAppear {
117
+ hostNavigation?.setOptions {
118
+ $0.headerType = .none
119
+ $0.useAvoidKeyboard = false
120
+ }
121
+ updateTabBack()
122
+ }
123
+ .onChange(of: selectedIndex) { _ in updateTabBack() }
124
+ .onDisappear {
125
+ // both live outside this view
126
+ navigator.tabBackHandler = nil
127
+ HostBackGestureBridge.shared.shouldUseFloatingArrowBack = false
128
+ }
113
129
  }
114
130
 
115
131
  private func selectTab(_ index: Int) {
116
132
  if index != selectedIndex { selectedIndex = index }
117
133
  }
118
134
 
119
- @ViewBuilder
135
+ /// Back off the first tab returns to it; the host shows its floating arrow there (RN parity).
136
+ private func updateTabBack() {
137
+ let isFirstTab = selectedIndex == 0
138
+ HostBackGestureBridge.shared.shouldUseFloatingArrowBack = !isFirstTab
139
+ navigator.tabBackHandler = isFirstTab ? nil : (hostNavigation?.id ?? -1, { selectedIndex = 0 })
140
+ }
141
+
120
142
  private func tabScreen(for index: Int) -> some View {
121
143
  let item = items[index]
122
- let options = item.options ?? NavigationOptions()
123
- StackScreen(
124
- backgroundColor: options.backgroundColor,
125
- headerTransparent: options.headerTransparent,
126
- fullScreenContent: options.fullScreenContent,
127
- tintColor: options.tintColor ?? Colors.black17,
128
- isBack: !options.hiddenBack,
129
- headerType: options.headerType,
130
- useAnimated: options.useAnimated,
131
- title: options.title,
132
- headerTitle: options.headerTitle,
133
- titlePosition: options.titlePosition,
134
- // Tab back: non-first tab returns to the first tab, first tab
135
- // delegates to the navigator (mirrors Compose's onBackHandler).
136
- goBack: options.hiddenBack ? nil : {
137
- if index != 0 { selectedIndex = 0 } else { navigator.onBackSafe() }
138
- },
139
- scrollable: options.scrollable,
140
- scrollToTopCallback: options.scrollToTopCallback,
141
- useAvoidKeyboard: options.useAvoidKeyboard,
142
- keyboardShouldPersistTaps: options.keyboardShouldPersistTaps,
143
- footer: options.footer,
144
- headerRight: options.resolvedHeaderRight,
145
- animatedHeader: options.animatedHeader,
146
- layoutOffset: options.layoutOffset,
147
- inputSearchProps: options.inputSearchProps,
148
- fabProps: options.fabProps,
149
- content: { item.screen() }
144
+ return TabScreenHost(
145
+ navigation: tabNavigations.navigation(for: index, options: item.options),
146
+ screen: item.screen,
147
+ goBack: { navigator.onBackSafe() }
148
+ )
149
+ }
150
+ }
151
+
152
+ /// Keeps each tab's `Navigation`, so options a tab set at runtime survive switching away.
153
+ private final class TabNavigations: ObservableObject {
154
+ private var navigations: [Int: Navigation] = [:]
155
+
156
+ func navigation(for index: Int, options: NavigationOptions?) -> Navigation {
157
+ if let navigation = navigations[index] { return navigation }
158
+ let navigation = Navigation(bottomTabIndex: index, options: options)
159
+ navigations[index] = navigation
160
+ return navigation
161
+ }
162
+ }
163
+
164
+ private struct TabScreenHost: View {
165
+ @ObservedObject var navigation: Navigation
166
+ let screen: () -> AnyView
167
+ let goBack: () -> Void
168
+
169
+ var body: some View {
170
+ OptionsStackScreen(
171
+ options: navigation.options,
172
+ screenName: navigation.options.screenName ?? "",
173
+ goBack: goBack,
174
+ content: screen
150
175
  )
176
+ .environmentObject(navigation)
151
177
  }
152
178
  }
153
179
 
@@ -2,7 +2,7 @@
2
2
  // BottomTabBar.swift
3
3
  // MoMoUIKits
4
4
  //
5
- // SwiftUI mirror of Compose's `BottomTabBar` (navigation/bottomtab/BottomTabBar.kt).
5
+ // SwiftUI mirror of Compose's `navigation/bottomtab/BottomTabBar.kt`.
6
6
  // Renders the row of tab items, an animated selection indicator, a top shadow,
7
7
  // badges/dots, and an optional center floating button (with the curved notch).
8
8
  //
@@ -66,6 +66,7 @@ struct BottomTabBar: View {
66
66
  let onTabSelected: (Int) -> Void
67
67
 
68
68
  @Environment(\.screenLayout) private var layout
69
+ @Environment(\.appTheme) private var theme
69
70
 
70
71
  // the bar sits between the side safe areas
71
72
  private var screenWidth: CGFloat { layout.width - layout.insets.leading - layout.insets.trailing }
@@ -98,11 +99,11 @@ struct BottomTabBar: View {
98
99
  }
99
100
  .frame(maxWidth: .infinity)
100
101
  .frame(height: BOTTOM_TAB_BAR_HEIGHT)
101
- .background(Colors.black01.ignoresSafeArea(edges: .horizontal))
102
+ .background(theme.colors.background.surface.ignoresSafeArea(edges: .horizontal))
102
103
 
103
104
  // Animated selection indicator.
104
105
  RoundedRectangle(cornerRadius: 2)
105
- .fill(Colors.primary)
106
+ .fill(theme.colors.primary)
106
107
  .frame(width: 44, height: 2)
107
108
  .offset(x: indicatorOffset, y: -BOTTOM_TAB_BAR_HEIGHT + 2)
108
109
  .animation(.easeInOut(duration: 0.25), value: selectedIndex)
@@ -143,7 +144,9 @@ private struct TabBarItem: View {
143
144
  let selected: Bool
144
145
  let onClick: () -> Void
145
146
 
146
- private var tintColor: Color { selected ? Colors.primary : Colors.black10 }
147
+ @Environment(\.appTheme) private var theme
148
+
149
+ private var tintColor: Color { selected ? theme.colors.primary : theme.colors.text.hint }
147
150
 
148
151
  /// Mirrors Compose's `formatLabel`: hide a badge that is the number "0".
149
152
  private var badgeLabel: String? {
@@ -195,18 +198,20 @@ private struct TabBarItem: View {
195
198
  private struct CenterFloatingButton: View {
196
199
  let data: BottomTabFloatingButton
197
200
 
201
+ @Environment(\.appTheme) private var theme
202
+
198
203
  var body: some View {
199
204
  VStack(spacing: 0) {
200
205
  CurvedContainer()
201
206
  Circle()
202
- .fill(Colors.primary)
207
+ .fill(theme.colors.primary)
203
208
  .frame(width: 48, height: 48)
204
209
  .overlay(Icon(source: data.icon, size: 28, color: .white))
205
210
  Spacer().frame(height: 4)
206
211
  MomoText(data.label, typography: .labelXsMedium, color: Colors.black01, textAlign: .center, maxLines: 1)
207
212
  .frame(maxWidth: .infinity)
208
213
  .frame(height: 14)
209
- .background(Colors.primary)
214
+ .background(theme.colors.primary)
210
215
  .clipShape(RoundedRectangle(cornerRadius: Radius.XL))
211
216
  }
212
217
  .frame(width: bottomTabFloatingButtonWidth)
@@ -1,3 +1,11 @@
1
+ //
2
+ // FloatingButton.swift
3
+ // MoMoUIKits
4
+ //
5
+ // SwiftUI mirror of Compose's `navigation/component/FloatingButton.kt`: the screen FAB, whose
6
+ // label collapses while the content scrolls down.
7
+ //
8
+
1
9
  import SwiftUI
2
10
  import Combine
3
11
 
@@ -111,13 +119,16 @@ public struct FloatingButton: View {
111
119
  content
112
120
  }
113
121
  }
114
- .onTapGesture {
115
- onClick?()
116
- }
117
122
  .padding(Spacing.M)
118
123
  .frame(height: height + (Spacing.M * 2))
119
124
  .background(containerColor)
120
125
  .cornerRadius(100)
126
+ // Compose FloatingActionButton elevation 4dp
127
+ .shadow(color: Color.black.opacity(0.2), radius: 4, x: 0, y: 2)
128
+ .contentShape(Capsule())
129
+ .onTapGesture {
130
+ onClick?()
131
+ }
121
132
  .padding(.bottom, bottomPadding)
122
133
  .frame(alignment: position == .center ? .center : .trailing)
123
134
  .onAppear {