@momo-kits/native-kits 0.300.3 → 0.300.4-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 (272) hide show
  1. package/CLAUDE.md +51 -7
  2. package/README.md +2 -2
  3. package/build.gradle.kts +13 -0
  4. package/compose/build.gradle.kts +197 -0
  5. package/compose/build.gradle.kts.backup +197 -0
  6. package/compose/compose.podspec +47 -0
  7. package/compose/src/androidMain/kotlin/vn/momo/kits/const/HostFont.android.kt +20 -0
  8. package/compose/src/androidMain/kotlin/vn/momo/kits/navigation/ScrollToTop.android.kt +6 -0
  9. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/BackGesture.android.kt +12 -0
  10. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/OsFontScale.android.kt +7 -0
  11. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/Platform.android.kt +153 -0
  12. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/ReservedRegions.android.kt +6 -0
  13. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Context.kt +110 -0
  14. package/compose/src/commonMain/kotlin/vn/momo/kits/application/DesignSystemKits.kt +62 -0
  15. package/compose/src/commonMain/kotlin/vn/momo/kits/application/LiteScreen.kt +1071 -0
  16. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Localize.kt +269 -0
  17. package/compose/src/commonMain/kotlin/vn/momo/kits/application/WidgetContainer.kt +65 -0
  18. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Avatar.kt +157 -0
  19. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Badge.kt +81 -0
  20. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeDot.kt +32 -0
  21. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeRibbon.kt +338 -0
  22. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BaselineView.kt +175 -0
  23. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +357 -0
  24. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Carousel.kt +115 -0
  25. package/compose/src/commonMain/kotlin/vn/momo/kits/components/CheckBox.kt +89 -0
  26. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Chip.kt +128 -0
  27. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Collapse.kt +209 -0
  28. package/compose/src/commonMain/kotlin/vn/momo/kits/components/CupertinoOverscroll.kt +542 -0
  29. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Divider.kt +49 -0
  30. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Icon.kt +86 -0
  31. package/compose/src/commonMain/kotlin/vn/momo/kits/components/IconButton.kt +125 -0
  32. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Image.kt +231 -0
  33. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Information.kt +189 -0
  34. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +478 -0
  35. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputDropDown.kt +114 -0
  36. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputMoney.kt +265 -0
  37. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputOTP.kt +235 -0
  38. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputPhoneNumber.kt +223 -0
  39. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +265 -0
  40. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +185 -0
  41. package/compose/src/commonMain/kotlin/vn/momo/kits/components/LazyColumnWithBouncing.kt +343 -0
  42. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Loader.kt +108 -0
  43. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationDot.kt +56 -0
  44. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationNumber.kt +41 -0
  45. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationScroll.kt +84 -0
  46. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationWhiteDot.kt +40 -0
  47. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +361 -0
  48. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupPromotion.kt +108 -0
  49. package/compose/src/commonMain/kotlin/vn/momo/kits/components/ProgressInfo.kt +308 -0
  50. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Radio.kt +59 -0
  51. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Rating.kt +87 -0
  52. package/compose/src/commonMain/kotlin/vn/momo/kits/components/ScaleSizeScope.kt +21 -0
  53. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Skeleton.kt +90 -0
  54. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Slider.kt +330 -0
  55. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Stepper.kt +220 -0
  56. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Steps.kt +473 -0
  57. package/compose/src/commonMain/kotlin/vn/momo/kits/components/SuggestAction.kt +122 -0
  58. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Swipe.kt +207 -0
  59. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Switch.kt +92 -0
  60. package/compose/src/commonMain/kotlin/vn/momo/kits/components/TabView.kt +560 -0
  61. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tag.kt +86 -0
  62. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +125 -0
  63. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Title.kt +207 -0
  64. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tooltip.kt +501 -0
  65. package/compose/src/commonMain/kotlin/vn/momo/kits/components/TrustBanner.kt +176 -0
  66. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Uploader.kt +182 -0
  67. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePicker.kt +193 -0
  68. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerTypes.kt +29 -0
  69. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerUtils.kt +236 -0
  70. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/WheelPicker.kt +180 -0
  71. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Colors.kt +325 -0
  72. package/compose/src/commonMain/kotlin/vn/momo/kits/const/HostFont.kt +17 -0
  73. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Radius.kt +12 -0
  74. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Spacing.kt +16 -0
  75. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Theme.kt +194 -0
  76. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +287 -0
  77. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Card.kt +54 -0
  78. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Item.kt +50 -0
  79. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/ScreenLayout.kt +306 -0
  80. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Section.kt +41 -0
  81. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/AutomationId.kt +52 -0
  82. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Clickable.kt +66 -0
  83. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Conditional.kt +11 -0
  84. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/DeprecatedModifier.kt +104 -0
  85. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Shadow.kt +48 -0
  86. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Size.kt +51 -0
  87. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/BottomSheet.kt +338 -0
  88. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/HostBackGestureBridge.kt +58 -0
  89. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ModalScreen.kt +137 -0
  90. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigation.kt +116 -0
  91. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +215 -0
  92. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigator.kt +404 -0
  93. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ScrollToTop.kt +8 -0
  94. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +732 -0
  95. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackTransition.kt +148 -0
  96. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/SwipeBackHaptic.kt +40 -0
  97. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTab.kt +233 -0
  98. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +217 -0
  99. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/CurvedContainer.kt +86 -0
  100. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/DuoBarCompression.kt +97 -0
  101. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/DuoTabBar.kt +377 -0
  102. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/FloatingButton.kt +169 -0
  103. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +455 -0
  104. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderBackground.kt +103 -0
  105. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderJourney.kt +106 -0
  106. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderLocation.kt +74 -0
  107. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderRight.kt +413 -0
  108. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderTitle.kt +39 -0
  109. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderUser.kt +363 -0
  110. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HelpCenterRequest.kt +37 -0
  111. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SideBar.kt +192 -0
  112. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SnackBar.kt +133 -0
  113. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/ToolkitRequests.kt +41 -0
  114. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/tracking/ScreenTracker.kt +135 -0
  115. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/BackGesture.kt +12 -0
  116. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/ComposeLottieAnimation.kt +91 -0
  117. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/OsFontScale.kt +9 -0
  118. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +74 -0
  119. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/ReservedRegions.kt +20 -0
  120. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Icons.kt +1329 -0
  121. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Resources.kt +55 -0
  122. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Tracking.kt +15 -0
  123. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Utils.kt +118 -0
  124. package/compose/src/commonTest/kotlin/vn/momo/kits/navigation/component/HelpCenterRequestTest.kt +44 -0
  125. package/compose/src/commonTest/kotlin/vn/momo/kits/navigation/component/ToolkitRequestsTest.kt +62 -0
  126. package/compose/src/iosMain/kotlin/vn/momo/kits/const/HostFont.ios.kt +42 -0
  127. package/compose/src/iosMain/kotlin/vn/momo/kits/navigation/HostBackGesture.ios.kt +45 -0
  128. package/compose/src/iosMain/kotlin/vn/momo/kits/navigation/ScrollToTop.ios.kt +36 -0
  129. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/BackGesture.ios.kt +38 -0
  130. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/OsFontScale.ios.kt +66 -0
  131. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +217 -0
  132. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/ReservedRegions.ios.kt +138 -0
  133. package/gradle/libs.versions.toml +68 -0
  134. package/gradle/wrapper/gradle-wrapper.jar +0 -0
  135. package/gradle/wrapper/gradle-wrapper.properties +8 -0
  136. package/gradle.properties +26 -0
  137. package/gradlew +252 -0
  138. package/gradlew.bat +94 -0
  139. package/ios/Application/ApplicationEnvironment.swift +24 -6
  140. package/ios/Application/DesignSystemKits.swift +100 -0
  141. package/ios/Application/DesignSystemKitsPayload.swift +68 -0
  142. package/ios/Application/MaxApi.swift +30 -3
  143. package/ios/Avatar/Avatar.swift +4 -3
  144. package/ios/Badge/Badge.swift +6 -4
  145. package/ios/Badge/BadgeDot.swift +1 -1
  146. package/ios/Badge/BadgeRibbon.swift +8 -2
  147. package/ios/Button/Button.swift +15 -12
  148. package/ios/CalculatorKeyboard/CalculatorKeyboard.swift +64 -18
  149. package/ios/Carousel/Carousel.swift +29 -12
  150. package/ios/Checkbox/Checkbox.swift +7 -3
  151. package/ios/Chip/Chip.swift +5 -4
  152. package/ios/Collapse/Collapse.swift +70 -19
  153. package/ios/Colors+Radius+Spacing/Colors.swift +10 -1
  154. package/ios/Colors+Radius+Spacing/Radius.swift +6 -0
  155. package/ios/DateTimePicker/DateTimePicker.swift +54 -20
  156. package/ios/DateTimePicker/WheelPicker.swift +103 -105
  157. package/ios/Divider/Divider.swift +37 -4
  158. package/ios/Extensions/Color++.swift +38 -9
  159. package/ios/Extensions/OptionalEnvironmentObject.swift +12 -0
  160. package/ios/Extensions/SkeletonUICompat.swift +11 -0
  161. package/ios/Icon/Icon.swift +21 -23
  162. package/ios/Icon/Icons.swift +1329 -0
  163. package/ios/IconButton/IconButton.swift +15 -7
  164. package/ios/Image/Image.swift +7 -23
  165. package/ios/Information/Information.swift +27 -9
  166. package/ios/Input/ErrorView.swift +2 -2
  167. package/ios/Input/Input.swift +171 -148
  168. package/ios/Input/InputPhoneNumber.swift +10 -9
  169. package/ios/Input/InputSearch.swift +107 -78
  170. package/ios/Input/InputTextArea.swift +133 -148
  171. package/ios/InputDropDown/InputDropDown.swift +10 -7
  172. package/ios/InputMoney/InputMoney.swift +32 -11
  173. package/ios/InputOTP/InputOTP.swift +22 -12
  174. package/ios/Layout/Card.swift +50 -0
  175. package/ios/Layout/GridContext.swift +187 -3
  176. package/ios/Layout/Item.swift +5 -4
  177. package/ios/Layout/ScreenLayout.swift +415 -0
  178. package/ios/Layout/Section.swift +4 -100
  179. package/ios/Loader/Loader.swift +5 -9
  180. package/ios/Lottie/LottieView.swift +14 -2
  181. package/ios/{Application/Navigation/Overplay → Navigation}/BottomSheet.swift +169 -29
  182. package/ios/Navigation/BottomTab/BottomTab.swift +332 -0
  183. package/ios/{Application/Navigation → Navigation}/BottomTab/BottomTabBar.swift +18 -7
  184. package/ios/Navigation/BottomTab/DuoBarCompression.swift +104 -0
  185. package/ios/Navigation/BottomTab/DuoTabBar.swift +329 -0
  186. package/ios/{Application → Navigation/Component}/FloatingButton.swift +43 -54
  187. package/ios/Navigation/Component/Header.swift +545 -0
  188. package/ios/Navigation/Component/HeaderBackground.swift +154 -0
  189. package/ios/Navigation/Component/HeaderJourney.swift +73 -0
  190. package/ios/Navigation/Component/HeaderLocation.swift +48 -0
  191. package/ios/Navigation/Component/HeaderRight.swift +425 -0
  192. package/ios/Navigation/Component/HeaderTitle.swift +36 -0
  193. package/ios/{Application/Navigation → Navigation/Component}/HeaderUser.swift +21 -24
  194. package/ios/Navigation/Component/SideBar.swift +183 -0
  195. package/ios/{Application/Navigation/Overplay → Navigation/Component}/SnackBar.swift +8 -8
  196. package/ios/Navigation/HostBackGestureBridge.swift +78 -0
  197. package/ios/{Application/Navigation/Overplay → Navigation}/ModalScreen.swift +9 -2
  198. package/ios/Navigation/Navigation.swift +204 -0
  199. package/ios/Navigation/NavigationContainer.swift +195 -0
  200. package/ios/{Application/Navigation → Navigation}/Navigator.swift +207 -107
  201. package/ios/Navigation/StackScreen.swift +930 -0
  202. package/ios/Navigation/StackTransition.swift +400 -0
  203. package/ios/Navigation/SwipeBackHaptic.swift +33 -0
  204. package/ios/{Application/Navigation → Navigation}/Tracking/ScreenTracker.swift +12 -5
  205. package/ios/OTPKeyboard/OTPKeyboard.swift +8 -11
  206. package/ios/Pagination/PaginationScroll.swift +2 -2
  207. package/ios/Popup/PopupDisplay.swift +72 -135
  208. package/ios/Popup/PopupInput.swift +10 -13
  209. package/ios/Popup/PopupLayout.swift +138 -0
  210. package/ios/Popup/PopupNotify.swift +59 -69
  211. package/ios/Popup/PopupPromotion.swift +31 -47
  212. package/ios/PopupView/FullscreenPopup.swift +13 -19
  213. package/ios/PopupView/PopupView.swift +1 -1
  214. package/ios/PopupView/Utils++.swift +0 -8
  215. package/ios/ProgressInfo/ProgressInfo.swift +4 -2
  216. package/ios/Radio/Radio.swift +2 -1
  217. package/ios/Rating/Rating.swift +9 -1
  218. package/ios/Resources/dot_loading.json +558 -0
  219. package/ios/Resources/lottie_circle_loader.json +1 -0
  220. package/ios/ScrollIndicator/ScrollIndicator.swift +11 -10
  221. package/ios/Skeleton/Skeleton.swift +22 -27
  222. package/ios/Slider/Slider.swift +16 -18
  223. package/ios/Stepper/Stepper.swift +7 -3
  224. package/ios/Steps/Steps.swift +8 -6
  225. package/ios/SuggestAction/SuggestAction.swift +5 -0
  226. package/ios/Swipeable/SwipeCell.swift +10 -6
  227. package/ios/Switch/Switch.swift +22 -20
  228. package/ios/TabView/TabView.swift +102 -21
  229. package/ios/Tag/Tag.swift +15 -4
  230. package/ios/Template/Logo/Logo.swift +2 -1
  231. package/ios/Template/TrustBanner/TrustBanner.swift +109 -55
  232. package/ios/Title/Title.swift +6 -17
  233. package/ios/Tooltip/Tooltip.swift +29 -14
  234. package/ios/Typography/FontScale.swift +17 -14
  235. package/ios/Typography/Text.swift +156 -20
  236. package/ios/Typography/Typography.swift +2 -2
  237. package/ios/Uploader/Uploader.swift +3 -1
  238. package/ios/native-kits.podspec +2 -3
  239. package/ios-demo/MoMoUIKitsDemo.podspec +1 -3
  240. package/ios-demo/README.md +120 -0
  241. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ContentView.swift +1 -1
  242. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DuoTabDemo.swift +80 -0
  243. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/Home.swift +2 -0
  244. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/IPhoneDuoDemo.swift +173 -0
  245. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/NavigationDemo.swift +77 -1
  246. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupDisplayDemo.swift +1 -0
  247. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupNotifyDemo.swift +2 -2
  248. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupPromotionDemo.swift +2 -0
  249. package/package.json +1 -1
  250. package/publish.sh +19 -2
  251. package/scripts/gen-ios-icons.mjs +36 -0
  252. package/settings.gradle.kts +64 -0
  253. package/ios/Application/Components.swift +0 -270
  254. package/ios/Application/ComposeApi.swift +0 -22
  255. package/ios/Application/HeaderRight.swift +0 -306
  256. package/ios/Application/Navigation/BottomTab/BottomTab.swift +0 -104
  257. package/ios/Application/Navigation/HeaderBackProps.swift +0 -66
  258. package/ios/Application/Navigation/HeaderTitle.swift +0 -57
  259. package/ios/Application/Navigation/NavigationContainer.swift +0 -213
  260. package/ios/Application/Navigation/NavigationOptions.swift +0 -109
  261. package/ios/Application/Navigation/NavigatorManager.swift +0 -22
  262. package/ios/Application/Navigation/component/Header.swift +0 -178
  263. package/ios/Application/Navigation/component/HeaderBackground.swift +0 -83
  264. package/ios/Application/Navigation/component/HeaderColor.swift +0 -65
  265. package/ios/Application/Navigation/component/HeaderRightWidthKey.swift +0 -11
  266. package/ios/Application/Navigation/component/NavigationFooter.swift +0 -90
  267. package/ios/Application/Navigation/component/NavigationHeaderRight.swift +0 -196
  268. package/ios/Application/Screen.swift +0 -250
  269. package/ios/Application/StackScreen.swift +0 -492
  270. package/ios/Typography/FontScaleStore.swift +0 -58
  271. package/ios/Typography/KitDesignSystem.swift +0 -17
  272. /package/ios/{Application/Navigation → Navigation}/BottomTab/CurvedContainer.swift +0 -0
@@ -0,0 +1,338 @@
1
+ package vn.momo.kits.navigation
2
+
3
+ import androidx.compose.animation.core.Animatable
4
+ import androidx.compose.animation.core.CubicBezierEasing
5
+ import androidx.compose.animation.core.tween
6
+ import androidx.compose.foundation.background
7
+ import androidx.compose.foundation.border
8
+ import androidx.compose.foundation.gestures.detectDragGestures
9
+ import androidx.compose.foundation.layout.Box
10
+ import androidx.compose.foundation.layout.BoxWithConstraints
11
+ import androidx.compose.foundation.layout.Column
12
+ import androidx.compose.foundation.layout.Row
13
+ import androidx.compose.foundation.layout.Spacer
14
+ import androidx.compose.foundation.layout.fillMaxHeight
15
+ import androidx.compose.foundation.layout.fillMaxSize
16
+ import androidx.compose.foundation.layout.fillMaxWidth
17
+ import androidx.compose.foundation.layout.height
18
+ import androidx.compose.foundation.layout.heightIn
19
+ import androidx.compose.foundation.layout.offset
20
+ import androidx.compose.foundation.layout.padding
21
+ import androidx.compose.foundation.layout.size
22
+ import androidx.compose.foundation.layout.width
23
+ import androidx.compose.foundation.layout.absolutePadding
24
+ import androidx.compose.foundation.shape.RoundedCornerShape
25
+ import androidx.compose.runtime.Composable
26
+ import androidx.compose.runtime.DisposableEffect
27
+ import androidx.compose.runtime.LaunchedEffect
28
+ import androidx.compose.runtime.remember
29
+ import androidx.compose.runtime.rememberCoroutineScope
30
+ import androidx.compose.ui.Alignment
31
+ import androidx.compose.ui.Modifier
32
+ import androidx.compose.ui.graphics.Brush
33
+ import androidx.compose.ui.graphics.Color
34
+ import androidx.compose.ui.input.pointer.pointerInput
35
+ import androidx.compose.ui.platform.LocalDensity
36
+ import androidx.compose.ui.unit.IntOffset
37
+ import androidx.compose.ui.unit.dp
38
+ import kotlinx.coroutines.launch
39
+ import vn.momo.kits.components.Divider
40
+ import vn.momo.kits.components.Icon
41
+ import vn.momo.kits.components.Text
42
+ import vn.momo.kits.const.AppTheme
43
+ import vn.momo.kits.const.Colors
44
+ import vn.momo.kits.const.Radius
45
+ import vn.momo.kits.const.Spacing
46
+ import vn.momo.kits.application.LocalContext
47
+ import vn.momo.kits.application.IsShowBaseLineDebug
48
+ import vn.momo.kits.const.AppNavigationBar
49
+ import vn.momo.kits.const.Typography
50
+ import vn.momo.kits.navigation.tracking.ScreenTracker
51
+ import vn.momo.kits.modifier.conditional
52
+ import vn.momo.kits.modifier.noFeedbackClickable
53
+ import vn.momo.kits.platform.BackHandler
54
+ import vn.momo.kits.platform.getScreenHeight
55
+ import vn.momo.kits.layout.getScreenLayout
56
+
57
+ // iPhone Duo inner display: center the sheet instead of spanning the width (RN BottomSheet).
58
+ private val DUO_REGULAR_MIN_WIDTH = 600.dp
59
+
60
+ @Composable
61
+ internal fun BottomSheet(
62
+ content: @Composable () -> Unit,
63
+ header: BottomHeader,
64
+ isSurface: Boolean = false,
65
+ barrierDismissible: Boolean = true,
66
+ draggable: Boolean = true,
67
+ useBottomInset: Boolean = true,
68
+ footerComponent: (@Composable () -> Unit)? = null,
69
+ onDismiss: (() -> Unit)?
70
+ ) {
71
+ val layout = getScreenLayout()
72
+ val isDuo = layout.isIPhoneDuoDevice
73
+ val isDuoCentered = isDuo && layout.width >= DUO_REGULAR_MIN_WIDTH
74
+ // the screen is the outer display on iPhone Duo, even when unfolded
75
+ val screenHeightDp = if (isDuo) layout.height else getScreenHeight()
76
+ val screenHeightPx = with(LocalDensity.current) { screenHeightDp.toPx() }
77
+ val sheetOffset = remember { Animatable(screenHeightPx) }
78
+
79
+ val backgroundAlpha = remember { Animatable(0f) }
80
+ val dynamicAlpha = ((1f - (sheetOffset.value / screenHeightPx)).coerceIn(0f, 1f)) * 0.3f
81
+ val alpha = backgroundAlpha.value + dynamicAlpha
82
+
83
+ val sheetCloseOffset = with(LocalDensity.current) { 100.dp.toPx() }
84
+
85
+ val coroutineScope = rememberCoroutineScope()
86
+
87
+ val maxApi = LocalMaxApi.current
88
+ val context = LocalContext.current
89
+
90
+ DisposableEffect(Unit) {
91
+ ScreenTracker.trackPopupDisplayed(
92
+ maxApi = maxApi,
93
+ context = context,
94
+ parentScreenName = ScreenTracker.getLastScreenName()
95
+ )
96
+ onDispose { }
97
+ }
98
+
99
+ suspend fun openEvent(){
100
+ backgroundAlpha.animateTo(
101
+ targetValue = 0.3f,
102
+ animationSpec = tween(
103
+ durationMillis = 100,
104
+ easing = CubicBezierEasing(0.05f, 0.7f, 0.1f, 1f)
105
+ )
106
+ )
107
+ sheetOffset.animateTo(
108
+ targetValue = 0f,
109
+ animationSpec = tween(
110
+ durationMillis = 350,
111
+ easing = CubicBezierEasing(0.05f, 0.7f, 0.1f, 1f)
112
+ )
113
+ )
114
+ }
115
+
116
+ fun closeEvent(){
117
+ coroutineScope.launch {
118
+ sheetOffset.animateTo(
119
+ targetValue = screenHeightPx,
120
+ animationSpec = tween(
121
+ durationMillis = 200,
122
+ easing = CubicBezierEasing(0.3f, 0.0f, 0.8f, 0.15f)
123
+ )
124
+ )
125
+ backgroundAlpha.animateTo(
126
+ targetValue = 0f,
127
+ animationSpec = tween(
128
+ durationMillis = 100,
129
+ easing = CubicBezierEasing(0.3f, 0.0f, 0.8f, 0.15f)
130
+ )
131
+ )
132
+ OverplayComponentRegistry.hardClearAfterDismiss()
133
+ }
134
+ }
135
+
136
+ LaunchedEffect(Unit) {
137
+ openEvent()
138
+ }
139
+
140
+ DisposableEffect(Unit) {
141
+ OverplayComponentRegistry.bindClose { closeEvent() }
142
+ onDispose {
143
+ onDismiss?.invoke()
144
+ }
145
+ }
146
+
147
+ BackHandler(true){
148
+ closeEvent()
149
+ }
150
+
151
+ BoxWithConstraints(
152
+ modifier = Modifier
153
+ .fillMaxSize()
154
+ .background(Color.Black.copy(alpha = alpha))
155
+ .noFeedbackClickable {
156
+ if(barrierDismissible) closeEvent()
157
+ }
158
+ ) {
159
+ val parentHeight = with(LocalDensity.current) { constraints.maxHeight.toDp() }
160
+ val maxHeight = if (isDuo) {
161
+ parentHeight - maxOf(layout.duoTopInset, Spacing.XL)
162
+ } else {
163
+ parentHeight - 90.dp
164
+ }
165
+ // landscape side buttons span the full height; in portrait the side status bar only covers the top
166
+ val sideInset = isDuo && !isDuoCentered && layout.width > layout.height
167
+
168
+ Box(
169
+ modifier = Modifier
170
+ .align(Alignment.BottomCenter)
171
+ .offset { IntOffset(x = 0, y = sheetOffset.value.toInt()) }
172
+ .then(
173
+ if (isDuoCentered) {
174
+ // keeps the portrait width in landscape, like system sheets
175
+ Modifier.width(
176
+ minOf(
177
+ minOf(layout.width, layout.height) - Spacing.L * 2,
178
+ layout.width - maxOf(layout.insetLeft, layout.insetRight, Spacing.L) * 2,
179
+ )
180
+ )
181
+ } else {
182
+ Modifier.fillMaxWidth()
183
+ }
184
+ )
185
+ .heightIn(max = maxHeight)
186
+ .background(
187
+ color = if (isSurface) AppTheme.current.colors.background.surface else AppTheme.current.colors.background.default,
188
+ shape = RoundedCornerShape(topStart = Radius.M, topEnd = Radius.M)
189
+ )
190
+ .conditional(IsShowBaseLineDebug) {
191
+ border(1.dp, Colors.blue_03)
192
+ }
193
+ .noFeedbackClickable { },
194
+ contentAlignment = Alignment.BottomCenter
195
+ ) {
196
+ val bottomInset = if (useBottomInset) {
197
+ (AppNavigationBar.current - keyboardSizeState().value).coerceAtLeast(0.dp)
198
+ } else 0.dp
199
+ Column(
200
+ Modifier
201
+ .padding(bottom = bottomInset)
202
+ .conditional(sideInset) {
203
+ absolutePadding(left = layout.insetLeft, right = layout.insetRight)
204
+ }
205
+ ) {
206
+ Box(
207
+ modifier = Modifier
208
+ .height(72.dp)
209
+ .fillMaxWidth()
210
+ .conditional(draggable) {
211
+ pointerInput(Unit) {
212
+ detectDragGestures(
213
+ onDrag = { change, dragAmount ->
214
+ change.consume()
215
+ coroutineScope.launch {
216
+ val newOffset = (sheetOffset.value + dragAmount.y).coerceAtLeast(0f)
217
+ sheetOffset.snapTo(newOffset)
218
+ }
219
+ },
220
+ onDragEnd = {
221
+ coroutineScope.launch {
222
+ if (sheetOffset.value > sheetCloseOffset) {
223
+ closeEvent()
224
+ } else {
225
+ sheetOffset.animateTo(0f)
226
+ }
227
+ }
228
+ }
229
+ )
230
+ }
231
+ }
232
+ ) {
233
+ Column(
234
+ modifier = Modifier
235
+ .fillMaxSize()
236
+ .padding(horizontal = Spacing.M),
237
+ horizontalAlignment = Alignment.CenterHorizontally
238
+ ) {
239
+ Spacer(Modifier.height(8.dp))
240
+ Box(
241
+ modifier = Modifier
242
+ .height(4.dp)
243
+ .width(40.dp)
244
+ .background(
245
+ color = Colors.black_06,
246
+ shape = RoundedCornerShape(Radius.S)
247
+ )
248
+ )
249
+ Spacer(Modifier.height(4.dp))
250
+ Box(Modifier.fillMaxWidth().height(56.dp), contentAlignment = Alignment.Center){
251
+ when (header) {
252
+ is BottomHeader.Title -> {
253
+ Row(modifier = Modifier.fillMaxSize(), verticalAlignment = Alignment.CenterVertically) {
254
+ Box(Modifier.size(24.dp))
255
+ Box(Modifier.fillMaxHeight().weight(1f), contentAlignment = Alignment.Center){
256
+ Text(
257
+ text = header.data,
258
+ color = Colors.black_17,
259
+ style = Typography.headerDefaultBold
260
+ )
261
+ }
262
+ Box(Modifier
263
+ .size(24.dp)
264
+ .noFeedbackClickable {
265
+ closeEvent()
266
+ },
267
+ contentAlignment = Alignment.Center
268
+ ){
269
+ Icon(source = "navigation_close")
270
+ }
271
+ }
272
+ }
273
+ is BottomHeader.Custom -> {
274
+ header.content()
275
+ }
276
+ }
277
+ }
278
+ }
279
+ }
280
+ Divider()
281
+ if (footerComponent != null) {
282
+ Box(Modifier.weight(1f, fill = false)) {
283
+ content()
284
+ }
285
+ BottomSheetFooter(footerComponent)
286
+ } else if (isDuo) {
287
+ // content shrinks so a tall sheet keeps its header
288
+ Box(Modifier.weight(1f, fill = false)) {
289
+ content()
290
+ }
291
+ } else {
292
+ content()
293
+ }
294
+ }
295
+ }
296
+ }
297
+ }
298
+
299
+ @Composable
300
+ private fun BottomSheetFooter(footerComponent: @Composable () -> Unit) {
301
+ val shadowBrush = remember {
302
+ Brush.verticalGradient(
303
+ colors = listOf(Color.Transparent, Color.Black.copy(alpha = 0.05f))
304
+ )
305
+ }
306
+
307
+ Box {
308
+ Box(
309
+ Modifier
310
+ .fillMaxWidth()
311
+ .background(AppTheme.current.colors.background.surface)
312
+ .conditional(IsShowBaseLineDebug) {
313
+ border(1.dp, Colors.blue_03)
314
+ }
315
+ .padding(vertical = Spacing.S)
316
+ ) {
317
+ footerComponent()
318
+ }
319
+
320
+ Box(
321
+ modifier = Modifier
322
+ .fillMaxWidth()
323
+ .height(6.dp)
324
+ .offset(x = 0.dp, y = (-6).dp)
325
+ .background(shadowBrush)
326
+ )
327
+ }
328
+ }
329
+
330
+ sealed class BottomHeader {
331
+ data class Title(
332
+ val data: String = "Bottom Sheet Title",
333
+ ) : BottomHeader()
334
+
335
+ data class Custom(
336
+ val content: @Composable () -> Unit
337
+ ) : BottomHeader()
338
+ }
@@ -0,0 +1,58 @@
1
+ package vn.momo.kits.navigation
2
+
3
+ interface HostBackTarget {
4
+ fun canPop(): Boolean
5
+
6
+ fun onBack()
7
+
8
+ fun backStarted()
9
+ fun backProgressed(progress: Float)
10
+ fun backCompleted()
11
+ fun backCancelled()
12
+ }
13
+
14
+ object HostBackGestureBridge {
15
+ private val targets = mutableListOf<HostBackTarget>()
16
+ private var gestureTarget: HostBackTarget? = null
17
+
18
+ var shouldUseFloatingArrowBack: Boolean = false
19
+
20
+ fun checkCanPop(): Boolean = targets.isNotEmpty()
21
+
22
+ fun canPopInner(): Boolean = top()?.canPop() == true
23
+
24
+ fun pop() {
25
+ top()?.onBack()
26
+ }
27
+
28
+ fun started() {
29
+ val target = top() ?: return
30
+ gestureTarget = target
31
+ target.backStarted()
32
+ }
33
+
34
+ fun progressed(progress: Float) {
35
+ gestureTarget?.backProgressed(progress.coerceIn(0f, 1f))
36
+ }
37
+
38
+ fun completed() {
39
+ (gestureTarget ?: top())?.backCompleted()
40
+ gestureTarget = null
41
+ }
42
+
43
+ fun cancelled() {
44
+ gestureTarget?.backCancelled()
45
+ gestureTarget = null
46
+ }
47
+
48
+ fun attach(target: HostBackTarget) {
49
+ targets += target
50
+ }
51
+
52
+ fun detach(target: HostBackTarget) {
53
+ targets -= target
54
+ if (gestureTarget === target) gestureTarget = null
55
+ }
56
+
57
+ private fun top(): HostBackTarget? = targets.lastOrNull()
58
+ }
@@ -0,0 +1,137 @@
1
+ package vn.momo.kits.navigation
2
+
3
+ import androidx.compose.animation.core.Animatable
4
+ import androidx.compose.animation.core.CubicBezierEasing
5
+ import androidx.compose.animation.core.tween
6
+ import androidx.compose.foundation.background
7
+ import androidx.compose.foundation.border
8
+ import androidx.compose.foundation.clickable
9
+ import androidx.compose.foundation.interaction.MutableInteractionSource
10
+ import androidx.compose.foundation.layout.Box
11
+ import androidx.compose.foundation.layout.fillMaxSize
12
+ import androidx.compose.foundation.layout.padding
13
+ import androidx.compose.foundation.layout.wrapContentSize
14
+ import androidx.compose.runtime.*
15
+ import androidx.compose.ui.Alignment
16
+ import androidx.compose.ui.Modifier
17
+ import androidx.compose.ui.draw.alpha
18
+ import androidx.compose.ui.draw.scale
19
+ import androidx.compose.ui.graphics.Color
20
+ import androidx.compose.ui.unit.dp
21
+ import kotlinx.coroutines.launch
22
+ import vn.momo.kits.application.LocalContext
23
+ import vn.momo.kits.application.IsShowBaseLineDebug
24
+ import vn.momo.kits.const.Colors
25
+ import vn.momo.kits.modifier.conditional
26
+ import vn.momo.kits.modifier.noFeedbackClickable
27
+ import vn.momo.kits.navigation.tracking.ScreenTracker
28
+ import vn.momo.kits.platform.BackHandler
29
+ import vn.momo.kits.layout.getScreenLayout
30
+
31
+ @Composable
32
+ internal fun ModalScreen(
33
+ content: @Composable () -> Unit,
34
+ barrierDismissible: Boolean = true,
35
+ onDismiss: (() -> Unit)? = null
36
+ ) {
37
+ val navigator = LocalNavigator.current
38
+
39
+ val alpha = remember { Animatable(0f) }
40
+ val scale = remember { Animatable(0.8f) }
41
+
42
+ val coroutineScope = rememberCoroutineScope()
43
+
44
+ val maxApi = LocalMaxApi.current
45
+ val context = LocalContext.current
46
+
47
+ DisposableEffect(Unit) {
48
+ ScreenTracker.trackPopupDisplayed(
49
+ maxApi = maxApi,
50
+ context = context,
51
+ parentScreenName = ScreenTracker.getLastScreenName()
52
+ )
53
+ onDispose { }
54
+ }
55
+
56
+ fun openEvent() {
57
+ coroutineScope.launch {
58
+ launch {
59
+ alpha.animateTo(
60
+ targetValue = 1f,
61
+ animationSpec = tween(durationMillis = 250)
62
+ )
63
+ }
64
+ launch {
65
+ scale.animateTo(
66
+ targetValue = 1f,
67
+ animationSpec = tween(
68
+ durationMillis = 250,
69
+ easing = CubicBezierEasing(0.2f, 0.0f, 0f, 1f)
70
+ )
71
+ )
72
+ }
73
+ }
74
+ }
75
+
76
+ fun closeEvent() {
77
+ coroutineScope.launch {
78
+ alpha.animateTo(
79
+ targetValue = 0f,
80
+ animationSpec = tween(durationMillis = 200)
81
+ )
82
+ scale.animateTo(
83
+ targetValue = 0.8f,
84
+ animationSpec = tween(durationMillis = 200)
85
+ )
86
+ OverplayComponentRegistry.hardClearAfterDismiss()
87
+ }
88
+ }
89
+
90
+ LaunchedEffect(Unit) {
91
+ openEvent()
92
+ }
93
+
94
+ DisposableEffect(Unit) {
95
+ OverplayComponentRegistry.bindClose { closeEvent() }
96
+ onDispose {
97
+ onDismiss?.invoke()
98
+ }
99
+ }
100
+
101
+ BackHandler(enabled = true) {
102
+ closeEvent()
103
+ }
104
+
105
+ val layout = getScreenLayout()
106
+
107
+ Box(
108
+ modifier = Modifier
109
+ .fillMaxSize()
110
+ .background(Color.Black.copy(alpha = 0.6f * alpha.value))
111
+ .noFeedbackClickable {
112
+ if(barrierDismissible) closeEvent()
113
+ }
114
+ // center below the side status bar and above the home indicator
115
+ .conditional(layout.isIPhoneDuoDevice) {
116
+ padding(top = layout.duoTopInset, bottom = layout.insetBottom)
117
+ },
118
+ contentAlignment = Alignment.Center
119
+ ) {
120
+ Box(
121
+ modifier = Modifier
122
+ .scale(scale.value)
123
+ .alpha(alpha.value)
124
+ .wrapContentSize()
125
+ .conditional(IsShowBaseLineDebug) {
126
+ border(1.dp, Colors.blue_03)
127
+ }
128
+ .clickable(
129
+ indication = null,
130
+ interactionSource = remember { MutableInteractionSource() }
131
+ ) {},
132
+ contentAlignment = Alignment.Center
133
+ ) {
134
+ content()
135
+ }
136
+ }
137
+ }
@@ -0,0 +1,116 @@
1
+ package vn.momo.kits.navigation
2
+
3
+ import androidx.compose.foundation.gestures.ScrollableState
4
+ import androidx.compose.runtime.*
5
+ import androidx.compose.ui.graphics.Color
6
+ import vn.momo.kits.navigation.bottomtab.setBottomTabOption
7
+ import vn.momo.kits.navigation.component.*
8
+
9
+ class Navigation(
10
+ val id: Int = -1,
11
+ val bottomTabIndex: Int = -1,
12
+ val initOptions: NavigationOptions? = null,
13
+ private val registry: DynamicScreenRegistry? = null
14
+ ) {
15
+ private val _options = mutableStateOf(initOptions ?: NavigationOptions())
16
+ val currentOptions: State<NavigationOptions> get() = _options
17
+ val options: NavigationOptions get() = _options.value
18
+
19
+ private val _isBottomTabRoot = mutableStateOf(false)
20
+ internal val isBottomTabRoot: Boolean get() = _isBottomTabRoot.value
21
+ internal fun markAsBottomTabRoot() { _isBottomTabRoot.value = true }
22
+
23
+ fun setOptions(
24
+ onBackHandler: (() -> Unit)? = null,
25
+ hiddenBack: Boolean? = null,
26
+ headerBackProps: HeaderBackProps? = null,
27
+ headerTitle: HeaderTitle? = null,
28
+ titlePosition: TitlePosition? = null,
29
+ headerRight: HeaderRight? = null,
30
+ headerType: HeaderType? = null,
31
+ scrollData: ScrollData? = null,
32
+ backgroundColor: Color? = null,
33
+ // AI-GENERATED START: custom screen background
34
+ backgroundComponent: (@Composable () -> Unit)? = null,
35
+ // AI-GENERATED END: custom screen background
36
+ tintColor: Color? = null,
37
+ footerComponent: (@Composable () -> Unit)? = null,
38
+ footerTransparent: Boolean? = null,
39
+ footerUseMargin: Boolean? = null,
40
+ floatingButtonProps: FloatingButtonProps? = null,
41
+ keyboardOptions: KeyboardOptions? = null
42
+ ) {
43
+ updateOptions(
44
+ options.copy(
45
+ onBackHandler = onBackHandler ?: options.onBackHandler,
46
+ hiddenBack = hiddenBack ?: options.hiddenBack,
47
+ headerBackProps = headerBackProps ?: options.headerBackProps,
48
+ headerTitle = headerTitle ?: options.headerTitle,
49
+ titlePosition = titlePosition ?: options.titlePosition,
50
+ headerRight = headerRight ?: options.headerRight,
51
+ headerType = headerType ?: options.headerType,
52
+ scrollData = scrollData ?: options.scrollData,
53
+ backgroundColor = backgroundColor ?: options.backgroundColor,
54
+ // AI-GENERATED START: custom screen background
55
+ backgroundComponent = backgroundComponent ?: options.backgroundComponent,
56
+ // AI-GENERATED END: custom screen background
57
+ tintColor = tintColor ?: options.tintColor,
58
+ footerComponent = footerComponent ?: options.footerComponent,
59
+ footerTransparent = footerTransparent ?: options.footerTransparent,
60
+ footerUseMargin = footerUseMargin ?: options.footerUseMargin,
61
+ floatingButtonProps = floatingButtonProps ?: options.floatingButtonProps,
62
+ keyboardOptions = keyboardOptions ?: options.keyboardOptions,
63
+ )
64
+ )
65
+ }
66
+
67
+ fun setOptions(newOptions: NavigationOptions) {
68
+ updateOptions(newOptions)
69
+ }
70
+
71
+ private fun updateOptions(updated: NavigationOptions) {
72
+ _options.value = updated
73
+ if (bottomTabIndex != -1) setBottomTabOption(bottomTabIndex, updated)
74
+ if (id != -1) registry?.setOptions(id, updated)
75
+ }
76
+ }
77
+
78
+ val LocalNavigation = staticCompositionLocalOf<Navigation> {
79
+ error("No NavigationStack provided")
80
+ }
81
+
82
+ @Stable
83
+ data class NavigationOptions(
84
+ val screenName: String? = null,
85
+ val onBackHandler: (() -> Unit)? = null,
86
+ val hiddenBack: Boolean = false,
87
+ val headerBackProps: HeaderBackProps = HeaderBackProps(),
88
+ val headerTitle: HeaderTitle = HeaderTitle.Default("Stack"),
89
+ val titlePosition: TitlePosition = TitlePosition.LEFT,
90
+ val headerRight: HeaderRight = HeaderRight.Toolkit(),
91
+ val headerType: HeaderType = HeaderType.Default(),
92
+ val scrollData: ScrollData = ScrollData(),
93
+ val backgroundColor: Color? = null,
94
+ // AI-GENERATED START: custom screen background (SwiftUI `NavigationOptions.background`)
95
+ /** Drawn instead of `backgroundColor` over the whole screen: under the header, outside the keyboard padding. */
96
+ val backgroundComponent: @Composable (() -> Unit)? = null,
97
+ // AI-GENERATED END: custom screen background (SwiftUI `NavigationOptions.background`)
98
+ val tintColor: Color? = null,
99
+ val footerComponent: @Composable (() -> Unit)? = null,
100
+ val footerTransparent: Boolean = false,
101
+ val footerUseMargin: Boolean = true,
102
+ val floatingButtonProps: FloatingButtonProps? = null,
103
+ val keyboardOptions: KeyboardOptions = KeyboardOptions()
104
+ ) {
105
+ internal fun hasFooter() : Boolean = footerComponent != null
106
+ }
107
+
108
+ data class KeyboardOptions(
109
+ val keyboardShouldPersistTaps: Boolean = false,
110
+ val useAvoidKeyboard: Boolean = true
111
+ )
112
+ data class ScrollData(
113
+ val scrollable: Boolean = true,
114
+ val scrollState: ScrollableState? = null,
115
+ val scrollToTopCallback: (() -> Unit)? = null,
116
+ )