@momo-kits/native-kits 0.167.1-duo.8 → 0.167.1-duo.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 (254) hide show
  1. package/CLAUDE.md +4 -1
  2. package/build.gradle.kts +11 -0
  3. package/compose/build.gradle.kts +204 -0
  4. package/compose/build.gradle.kts.backup +204 -0
  5. package/compose/compose.podspec +47 -0
  6. package/compose/src/androidMain/kotlin/vn/momo/kits/const/HostFont.android.kt +19 -0
  7. package/compose/src/androidMain/kotlin/vn/momo/kits/navigation/ScrollToTop.android.kt +6 -0
  8. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/BackGesture.android.kt +12 -0
  9. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/OsFontScale.android.kt +7 -0
  10. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/Platform.android.kt +153 -0
  11. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/ReservedRegions.android.kt +6 -0
  12. package/compose/src/commonMain/kotlin/vn/momo/kits/application/AnimationSearchInput.kt +52 -0
  13. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Context.kt +124 -0
  14. package/compose/src/commonMain/kotlin/vn/momo/kits/application/FloatingButton.kt +183 -0
  15. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Header.kt +207 -0
  16. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderAnimated.kt +39 -0
  17. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderBackground.kt +86 -0
  18. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderDefault.kt +76 -0
  19. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderExtended.kt +76 -0
  20. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderRight.kt +293 -0
  21. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderTitle.kt +33 -0
  22. package/compose/src/commonMain/kotlin/vn/momo/kits/application/LiteScreen.kt +831 -0
  23. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Localize.kt +269 -0
  24. package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +110 -0
  25. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +378 -0
  26. package/compose/src/commonMain/kotlin/vn/momo/kits/application/WidgetContainer.kt +56 -0
  27. package/compose/src/commonMain/kotlin/vn/momo/kits/application/useHeaderSearchAnimation.kt +69 -0
  28. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Avatar.kt +157 -0
  29. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Badge.kt +81 -0
  30. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeDot.kt +32 -0
  31. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeRibbon.kt +338 -0
  32. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BaselineView.kt +175 -0
  33. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +357 -0
  34. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Carousel.kt +115 -0
  35. package/compose/src/commonMain/kotlin/vn/momo/kits/components/CheckBox.kt +89 -0
  36. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Chip.kt +128 -0
  37. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Collapse.kt +209 -0
  38. package/compose/src/commonMain/kotlin/vn/momo/kits/components/CupertinoOverscroll.kt +542 -0
  39. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Divider.kt +49 -0
  40. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Icon.kt +76 -0
  41. package/compose/src/commonMain/kotlin/vn/momo/kits/components/IconButton.kt +125 -0
  42. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Image.kt +231 -0
  43. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Information.kt +189 -0
  44. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +478 -0
  45. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputDropDown.kt +114 -0
  46. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputMoney.kt +265 -0
  47. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputOTP.kt +235 -0
  48. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputPhoneNumber.kt +223 -0
  49. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +265 -0
  50. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +185 -0
  51. package/compose/src/commonMain/kotlin/vn/momo/kits/components/LazyColumnWithBouncing.kt +343 -0
  52. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Loader.kt +108 -0
  53. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationDot.kt +56 -0
  54. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationNumber.kt +41 -0
  55. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationScroll.kt +84 -0
  56. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationWhiteDot.kt +40 -0
  57. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +361 -0
  58. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupPromotion.kt +108 -0
  59. package/compose/src/commonMain/kotlin/vn/momo/kits/components/ProgressInfo.kt +308 -0
  60. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Radio.kt +59 -0
  61. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Rating.kt +87 -0
  62. package/compose/src/commonMain/kotlin/vn/momo/kits/components/ScaleSizeScope.kt +21 -0
  63. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Skeleton.kt +90 -0
  64. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Slider.kt +330 -0
  65. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Stepper.kt +220 -0
  66. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Steps.kt +473 -0
  67. package/compose/src/commonMain/kotlin/vn/momo/kits/components/SuggestAction.kt +122 -0
  68. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Swipe.kt +207 -0
  69. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Switch.kt +92 -0
  70. package/compose/src/commonMain/kotlin/vn/momo/kits/components/TabView.kt +560 -0
  71. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tag.kt +86 -0
  72. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +125 -0
  73. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Title.kt +207 -0
  74. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tooltip.kt +501 -0
  75. package/compose/src/commonMain/kotlin/vn/momo/kits/components/TrustBanner.kt +176 -0
  76. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Uploader.kt +182 -0
  77. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePicker.kt +193 -0
  78. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerTypes.kt +29 -0
  79. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerUtils.kt +236 -0
  80. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/WheelPicker.kt +180 -0
  81. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Colors.kt +325 -0
  82. package/compose/src/commonMain/kotlin/vn/momo/kits/const/HostFont.kt +16 -0
  83. package/compose/src/commonMain/kotlin/vn/momo/kits/const/KitDesignSystem.kt +18 -0
  84. package/compose/src/commonMain/kotlin/vn/momo/kits/const/KitFontScale.kt +22 -0
  85. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Radius.kt +12 -0
  86. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Spacing.kt +16 -0
  87. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Theme.kt +188 -0
  88. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +297 -0
  89. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Card.kt +54 -0
  90. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Item.kt +50 -0
  91. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/ScreenLayout.kt +232 -0
  92. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Section.kt +41 -0
  93. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/AutomationId.kt +52 -0
  94. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Clickable.kt +66 -0
  95. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Conditional.kt +11 -0
  96. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/DeprecatedModifier.kt +104 -0
  97. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Shadow.kt +48 -0
  98. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Size.kt +51 -0
  99. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/BottomSheet.kt +338 -0
  100. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/HostBackGestureBridge.kt +58 -0
  101. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ModalScreen.kt +137 -0
  102. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigation.kt +106 -0
  103. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +205 -0
  104. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigator.kt +393 -0
  105. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ScrollToTop.kt +8 -0
  106. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +708 -0
  107. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackTransition.kt +148 -0
  108. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/SwipeBackHaptic.kt +35 -0
  109. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTab.kt +209 -0
  110. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +231 -0
  111. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/CurvedContainer.kt +86 -0
  112. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/DuoBarCompression.kt +98 -0
  113. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/DuoTabBar.kt +312 -0
  114. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/FloatingButton.kt +169 -0
  115. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +408 -0
  116. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderBackground.kt +92 -0
  117. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderJourney.kt +106 -0
  118. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderLocation.kt +74 -0
  119. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderRight.kt +366 -0
  120. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderTitle.kt +37 -0
  121. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderUser.kt +363 -0
  122. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SideBar.kt +185 -0
  123. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SnackBar.kt +133 -0
  124. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/tracking/ScreenTracker.kt +127 -0
  125. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/BackGesture.kt +12 -0
  126. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/ComposeLottieAnimation.kt +91 -0
  127. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/OsFontScale.kt +9 -0
  128. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +74 -0
  129. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/ReservedRegions.kt +13 -0
  130. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Icons.kt +1329 -0
  131. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Resources.kt +55 -0
  132. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Tracking.kt +15 -0
  133. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Utils.kt +118 -0
  134. package/compose/src/iosMain/kotlin/vn/momo/kits/const/HostFont.ios.kt +40 -0
  135. package/compose/src/iosMain/kotlin/vn/momo/kits/navigation/HostBackGesture.ios.kt +45 -0
  136. package/compose/src/iosMain/kotlin/vn/momo/kits/navigation/ScrollToTop.ios.kt +32 -0
  137. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/BackGesture.ios.kt +38 -0
  138. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/OsFontScale.ios.kt +66 -0
  139. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +217 -0
  140. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/ReservedRegions.ios.kt +86 -0
  141. package/gradle/libs.versions.toml +69 -0
  142. package/gradle/wrapper/gradle-wrapper.jar +0 -0
  143. package/gradle/wrapper/gradle-wrapper.properties +8 -0
  144. package/gradle.properties +26 -0
  145. package/gradlew +252 -0
  146. package/gradlew.bat +94 -0
  147. package/ios/Application/ApplicationEnvironment.swift +11 -0
  148. package/ios/Application/ComposeApi.swift +2 -1
  149. package/ios/Application/{Components.swift → LegacyHeader.swift} +6 -62
  150. package/ios/Application/Screen.swift +3 -2
  151. package/ios/Avatar/Avatar.swift +4 -3
  152. package/ios/Badge/Badge.swift +6 -4
  153. package/ios/Badge/BadgeDot.swift +1 -1
  154. package/ios/Badge/BadgeRibbon.swift +0 -1
  155. package/ios/Button/Button.swift +15 -12
  156. package/ios/CalculatorKeyboard/CalculatorKeyboard.swift +12 -20
  157. package/ios/Carousel/Carousel.swift +29 -12
  158. package/ios/Checkbox/Checkbox.swift +7 -3
  159. package/ios/Chip/Chip.swift +5 -4
  160. package/ios/Collapse/Collapse.swift +70 -19
  161. package/ios/Colors+Radius+Spacing/Colors.swift +9 -0
  162. package/ios/DateTimePicker/DateTimePicker.swift +54 -20
  163. package/ios/DateTimePicker/WheelPicker.swift +103 -105
  164. package/ios/Divider/Divider.swift +37 -4
  165. package/ios/Extensions/Color++.swift +18 -0
  166. package/ios/Icon/Icon.swift +7 -1
  167. package/ios/IconButton/IconButton.swift +15 -7
  168. package/ios/Image/Image.swift +7 -34
  169. package/ios/Information/Information.swift +27 -9
  170. package/ios/Input/ErrorView.swift +2 -2
  171. package/ios/Input/Input.swift +160 -147
  172. package/ios/Input/InputPhoneNumber.swift +12 -9
  173. package/ios/Input/InputSearch.swift +102 -75
  174. package/ios/Input/InputTextArea.swift +128 -145
  175. package/ios/InputDropDown/InputDropDown.swift +10 -7
  176. package/ios/InputMoney/InputMoney.swift +33 -11
  177. package/ios/InputOTP/InputOTP.swift +22 -12
  178. package/ios/Layout/Card.swift +50 -0
  179. package/ios/Layout/GridContext.swift +123 -3
  180. package/ios/Layout/Item.swift +5 -4
  181. package/ios/Layout/Section.swift +4 -100
  182. package/ios/Loader/Loader.swift +5 -9
  183. package/ios/Lottie/LottieView.swift +10 -0
  184. package/ios/{Application/Navigation/Overplay → Navigation}/BottomSheet.swift +61 -9
  185. package/ios/{Application/Navigation → Navigation}/BottomTab/BottomTab.swift +60 -34
  186. package/ios/{Application/Navigation → Navigation}/BottomTab/BottomTabBar.swift +11 -6
  187. package/ios/{Application → Navigation/Component}/FloatingButton.swift +14 -3
  188. package/ios/Navigation/Component/Header.swift +493 -0
  189. package/ios/Navigation/Component/HeaderBackground.swift +134 -0
  190. package/ios/Navigation/Component/HeaderJourney.swift +73 -0
  191. package/ios/Navigation/Component/HeaderLocation.swift +48 -0
  192. package/ios/Navigation/Component/HeaderRight.swift +386 -0
  193. package/ios/Navigation/Component/HeaderTitle.swift +36 -0
  194. package/ios/{Application/Navigation → Navigation/Component}/HeaderUser.swift +20 -23
  195. package/ios/{Application/Navigation/component → Navigation/Component}/SideBar.swift +49 -28
  196. package/ios/{Application/Navigation/Overplay → Navigation/Component}/SnackBar.swift +5 -5
  197. package/ios/Navigation/HostBackGestureBridge.swift +57 -0
  198. package/ios/Navigation/Navigation.swift +190 -0
  199. package/ios/{Application/Navigation → Navigation}/NavigationContainer.swift +46 -41
  200. package/ios/{Application/Navigation → Navigation}/Navigator.swift +65 -9
  201. package/ios/{Application → Navigation}/StackScreen.swift +236 -103
  202. package/ios/{Application/Navigation → Navigation}/Tracking/ScreenTracker.swift +12 -5
  203. package/ios/OTPKeyboard/OTPKeyboard.swift +8 -11
  204. package/ios/Pagination/PaginationScroll.swift +2 -2
  205. package/ios/Popup/PopupDisplay.swift +79 -159
  206. package/ios/Popup/PopupInput.swift +10 -13
  207. package/ios/Popup/PopupLayout.swift +97 -2
  208. package/ios/Popup/PopupNotify.swift +27 -55
  209. package/ios/Popup/PopupPromotion.swift +22 -50
  210. package/ios/PopupView/FullscreenPopup.swift +13 -19
  211. package/ios/PopupView/PopupView.swift +1 -1
  212. package/ios/PopupView/Utils++.swift +0 -8
  213. package/ios/ProgressInfo/ProgressInfo.swift +4 -2
  214. package/ios/Radio/Radio.swift +2 -1
  215. package/ios/Rating/Rating.swift +9 -1
  216. package/ios/ScrollIndicator/ScrollIndicator.swift +11 -10
  217. package/ios/Skeleton/Skeleton.swift +22 -27
  218. package/ios/Slider/Slider.swift +16 -18
  219. package/ios/Stepper/Stepper.swift +6 -1
  220. package/ios/Steps/Steps.swift +8 -6
  221. package/ios/SuggestAction/SuggestAction.swift +5 -0
  222. package/ios/Swipeable/SwipeCell.swift +10 -6
  223. package/ios/Switch/Switch.swift +22 -20
  224. package/ios/TabView/TabView.swift +102 -21
  225. package/ios/Tag/Tag.swift +15 -4
  226. package/ios/Template/Logo/Logo.swift +2 -1
  227. package/ios/Template/TrustBanner/TrustBanner.swift +41 -27
  228. package/ios/Title/Title.swift +6 -17
  229. package/ios/Tooltip/Tooltip.swift +29 -14
  230. package/ios/Typography/Text.swift +61 -19
  231. package/ios/Uploader/Uploader.swift +3 -1
  232. package/ios/native-kits.podspec +1 -0
  233. package/ios-demo/README.md +120 -0
  234. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ContentView.swift +1 -1
  235. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/NavigationDemo.swift +77 -1
  236. package/package.json +1 -1
  237. package/settings.gradle.kts +64 -0
  238. package/ios/Application/HeaderRight.swift +0 -324
  239. package/ios/Application/Navigation/HeaderBackProps.swift +0 -66
  240. package/ios/Application/Navigation/HeaderTitle.swift +0 -57
  241. package/ios/Application/Navigation/NavigationOptions.swift +0 -109
  242. package/ios/Application/Navigation/NavigatorManager.swift +0 -29
  243. package/ios/Application/Navigation/component/DuoScrollGradient.swift +0 -54
  244. package/ios/Application/Navigation/component/Header.swift +0 -183
  245. package/ios/Application/Navigation/component/HeaderBackground.swift +0 -84
  246. package/ios/Application/Navigation/component/HeaderColor.swift +0 -65
  247. package/ios/Application/Navigation/component/HeaderRightWidthKey.swift +0 -11
  248. package/ios/Application/Navigation/component/NavigationFooter.swift +0 -90
  249. package/ios/Application/Navigation/component/NavigationHeaderRight.swift +0 -280
  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 {