@momo-kits/native-kits 0.167.1-duo.2-debug → 0.167.1-duo.20

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 (266) hide show
  1. package/CLAUDE.md +36 -8
  2. package/README.md +2 -2
  3. package/ios/Application/ApplicationEnvironment.swift +17 -0
  4. package/ios/Application/MaxApi.swift +12 -3
  5. package/ios/Avatar/Avatar.swift +4 -3
  6. package/ios/Badge/Badge.swift +6 -4
  7. package/ios/Badge/BadgeDot.swift +1 -1
  8. package/ios/Badge/BadgeRibbon.swift +0 -1
  9. package/ios/Button/Button.swift +15 -12
  10. package/ios/CalculatorKeyboard/CalculatorKeyboard.swift +64 -18
  11. package/ios/Carousel/Carousel.swift +29 -12
  12. package/ios/Checkbox/Checkbox.swift +7 -3
  13. package/ios/Chip/Chip.swift +5 -4
  14. package/ios/Collapse/Collapse.swift +70 -19
  15. package/ios/Colors+Radius+Spacing/Colors.swift +10 -1
  16. package/ios/Colors+Radius+Spacing/Radius.swift +6 -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 +38 -9
  21. package/ios/Extensions/OptionalEnvironmentObject.swift +12 -0
  22. package/ios/Extensions/SkeletonUICompat.swift +11 -0
  23. package/ios/Icon/Icon.swift +21 -23
  24. package/ios/Icon/Icons.swift +1329 -0
  25. package/ios/IconButton/IconButton.swift +15 -7
  26. package/ios/Image/Image.swift +7 -23
  27. package/ios/Information/Information.swift +27 -9
  28. package/ios/Input/ErrorView.swift +2 -2
  29. package/ios/Input/Input.swift +160 -147
  30. package/ios/Input/InputPhoneNumber.swift +12 -9
  31. package/ios/Input/InputSearch.swift +102 -75
  32. package/ios/Input/InputTextArea.swift +128 -145
  33. package/ios/InputDropDown/InputDropDown.swift +10 -7
  34. package/ios/InputMoney/InputMoney.swift +33 -11
  35. package/ios/InputOTP/InputOTP.swift +22 -12
  36. package/ios/Layout/Card.swift +50 -0
  37. package/ios/Layout/GridContext.swift +187 -3
  38. package/ios/Layout/Item.swift +5 -4
  39. package/ios/Layout/ScreenLayout.swift +380 -0
  40. package/ios/Layout/Section.swift +4 -100
  41. package/ios/Loader/Loader.swift +5 -9
  42. package/ios/Lottie/LottieView.swift +14 -2
  43. package/ios/{Application/Navigation/Overplay → Navigation}/BottomSheet.swift +128 -9
  44. package/ios/Navigation/BottomTab/BottomTab.swift +185 -0
  45. package/ios/{Application/Navigation → Navigation}/BottomTab/BottomTabBar.swift +15 -7
  46. package/ios/Navigation/BottomTab/DuoBarCompression.swift +105 -0
  47. package/ios/Navigation/BottomTab/DuoTabBar.swift +304 -0
  48. package/ios/{Application → Navigation/Component}/FloatingButton.swift +14 -3
  49. package/ios/Navigation/Component/Header.swift +531 -0
  50. package/ios/Navigation/Component/HeaderBackground.swift +133 -0
  51. package/ios/Navigation/Component/HeaderJourney.swift +73 -0
  52. package/ios/Navigation/Component/HeaderLocation.swift +48 -0
  53. package/ios/Navigation/Component/HeaderRight.swift +377 -0
  54. package/ios/Navigation/Component/HeaderTitle.swift +36 -0
  55. package/ios/{Application/Navigation → Navigation/Component}/HeaderUser.swift +21 -24
  56. package/ios/Navigation/Component/SideBar.swift +183 -0
  57. package/ios/{Application/Navigation/Overplay → Navigation/Component}/SnackBar.swift +5 -6
  58. package/ios/Navigation/HostBackGestureBridge.swift +78 -0
  59. package/ios/{Application/Navigation/Overplay → Navigation}/ModalScreen.swift +5 -2
  60. package/ios/Navigation/Navigation.swift +204 -0
  61. package/ios/Navigation/NavigationContainer.swift +194 -0
  62. package/ios/{Application/Navigation → Navigation}/Navigator.swift +177 -91
  63. package/ios/Navigation/StackScreen.swift +820 -0
  64. package/ios/Navigation/StackTransition.swift +400 -0
  65. package/ios/Navigation/SwipeBackHaptic.swift +33 -0
  66. package/ios/{Application/Navigation → Navigation}/Tracking/ScreenTracker.swift +12 -5
  67. package/ios/OTPKeyboard/OTPKeyboard.swift +8 -11
  68. package/ios/Pagination/PaginationScroll.swift +2 -2
  69. package/ios/Popup/PopupDisplay.swift +72 -136
  70. package/ios/Popup/PopupInput.swift +10 -13
  71. package/ios/Popup/PopupLayout.swift +140 -0
  72. package/ios/Popup/PopupNotify.swift +56 -73
  73. package/ios/Popup/PopupPromotion.swift +31 -47
  74. package/ios/PopupView/FullscreenPopup.swift +13 -19
  75. package/ios/PopupView/PopupView.swift +1 -1
  76. package/ios/PopupView/Utils++.swift +0 -8
  77. package/ios/ProgressInfo/ProgressInfo.swift +4 -2
  78. package/ios/Radio/Radio.swift +2 -1
  79. package/ios/Rating/Rating.swift +9 -1
  80. package/ios/Resources/dot_loading.json +558 -0
  81. package/ios/Resources/lottie_circle_loader.json +1 -0
  82. package/ios/ScrollIndicator/ScrollIndicator.swift +11 -10
  83. package/ios/Skeleton/Skeleton.swift +22 -27
  84. package/ios/Slider/Slider.swift +16 -18
  85. package/ios/Stepper/Stepper.swift +6 -1
  86. package/ios/Steps/Steps.swift +8 -6
  87. package/ios/SuggestAction/SuggestAction.swift +5 -0
  88. package/ios/Swipeable/SwipeCell.swift +10 -6
  89. package/ios/Switch/Switch.swift +22 -20
  90. package/ios/TabView/TabView.swift +102 -21
  91. package/ios/Tag/Tag.swift +15 -4
  92. package/ios/Template/Logo/Logo.swift +2 -1
  93. package/ios/Template/TrustBanner/TrustBanner.swift +106 -54
  94. package/ios/Title/Title.swift +6 -17
  95. package/ios/Tooltip/Tooltip.swift +29 -14
  96. package/ios/Typography/Text.swift +61 -19
  97. package/ios/Uploader/Uploader.swift +3 -1
  98. package/ios/native-kits.podspec +2 -1
  99. package/ios-demo/MoMoUIKitsDemo.podspec +1 -1
  100. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ContentView.swift +1 -1
  101. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DuoTabDemo.swift +80 -0
  102. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/Home.swift +1 -0
  103. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/IPhoneDuoDemo.swift +173 -0
  104. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/NavigationDemo.swift +77 -1
  105. package/package.json +1 -1
  106. package/scripts/gen-ios-icons.mjs +36 -0
  107. package/build.gradle.kts +0 -11
  108. package/compose/build.gradle.kts +0 -190
  109. package/compose/build.gradle.kts.backup +0 -190
  110. package/compose/compose.podspec +0 -47
  111. package/compose/src/androidMain/kotlin/vn/momo/kits/const/HostFont.android.kt +0 -19
  112. package/compose/src/androidMain/kotlin/vn/momo/kits/navigation/ScrollToTop.android.kt +0 -6
  113. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/BackGesture.android.kt +0 -12
  114. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/OsFontScale.android.kt +0 -7
  115. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/Platform.android.kt +0 -151
  116. package/compose/src/commonMain/kotlin/vn/momo/kits/application/AnimationSearchInput.kt +0 -52
  117. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Context.kt +0 -124
  118. package/compose/src/commonMain/kotlin/vn/momo/kits/application/FloatingButton.kt +0 -183
  119. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Header.kt +0 -207
  120. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderAnimated.kt +0 -39
  121. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderBackground.kt +0 -86
  122. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderDefault.kt +0 -76
  123. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderExtended.kt +0 -76
  124. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderRight.kt +0 -293
  125. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderTitle.kt +0 -33
  126. package/compose/src/commonMain/kotlin/vn/momo/kits/application/LiteScreen.kt +0 -831
  127. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Localize.kt +0 -269
  128. package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +0 -110
  129. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +0 -378
  130. package/compose/src/commonMain/kotlin/vn/momo/kits/application/WidgetContainer.kt +0 -56
  131. package/compose/src/commonMain/kotlin/vn/momo/kits/application/useHeaderSearchAnimation.kt +0 -69
  132. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Avatar.kt +0 -157
  133. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Badge.kt +0 -82
  134. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeDot.kt +0 -32
  135. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeRibbon.kt +0 -338
  136. package/compose/src/commonMain/kotlin/vn/momo/kits/components/BaselineView.kt +0 -175
  137. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +0 -356
  138. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Carousel.kt +0 -113
  139. package/compose/src/commonMain/kotlin/vn/momo/kits/components/CheckBox.kt +0 -89
  140. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Chip.kt +0 -128
  141. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Collapse.kt +0 -209
  142. package/compose/src/commonMain/kotlin/vn/momo/kits/components/CupertinoOverscroll.kt +0 -542
  143. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Divider.kt +0 -49
  144. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Icon.kt +0 -76
  145. package/compose/src/commonMain/kotlin/vn/momo/kits/components/IconButton.kt +0 -125
  146. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Image.kt +0 -231
  147. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Information.kt +0 -189
  148. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +0 -475
  149. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputDropDown.kt +0 -114
  150. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputMoney.kt +0 -266
  151. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputOTP.kt +0 -240
  152. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputPhoneNumber.kt +0 -223
  153. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +0 -264
  154. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +0 -185
  155. package/compose/src/commonMain/kotlin/vn/momo/kits/components/LazyColumnWithBouncing.kt +0 -343
  156. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Loader.kt +0 -108
  157. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationDot.kt +0 -56
  158. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationNumber.kt +0 -41
  159. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationScroll.kt +0 -84
  160. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationWhiteDot.kt +0 -40
  161. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +0 -334
  162. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupPromotion.kt +0 -98
  163. package/compose/src/commonMain/kotlin/vn/momo/kits/components/ProgressInfo.kt +0 -310
  164. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Radio.kt +0 -59
  165. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Rating.kt +0 -87
  166. package/compose/src/commonMain/kotlin/vn/momo/kits/components/ScaleSizeScope.kt +0 -21
  167. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Skeleton.kt +0 -90
  168. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Slider.kt +0 -323
  169. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Stepper.kt +0 -220
  170. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Steps.kt +0 -473
  171. package/compose/src/commonMain/kotlin/vn/momo/kits/components/SuggestAction.kt +0 -122
  172. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Swipe.kt +0 -199
  173. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Switch.kt +0 -91
  174. package/compose/src/commonMain/kotlin/vn/momo/kits/components/TabView.kt +0 -552
  175. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tag.kt +0 -88
  176. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +0 -125
  177. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Title.kt +0 -207
  178. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tooltip.kt +0 -498
  179. package/compose/src/commonMain/kotlin/vn/momo/kits/components/TrustBanner.kt +0 -176
  180. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Uploader.kt +0 -182
  181. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePicker.kt +0 -193
  182. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerTypes.kt +0 -29
  183. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerUtils.kt +0 -234
  184. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/WheelPicker.kt +0 -188
  185. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Colors.kt +0 -325
  186. package/compose/src/commonMain/kotlin/vn/momo/kits/const/HostFont.kt +0 -16
  187. package/compose/src/commonMain/kotlin/vn/momo/kits/const/KitDesignSystem.kt +0 -18
  188. package/compose/src/commonMain/kotlin/vn/momo/kits/const/KitFontScale.kt +0 -22
  189. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Radius.kt +0 -12
  190. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Spacing.kt +0 -16
  191. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Theme.kt +0 -188
  192. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +0 -297
  193. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Card.kt +0 -54
  194. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Item.kt +0 -50
  195. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/ScreenLayout.kt +0 -157
  196. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Section.kt +0 -41
  197. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/AutomationId.kt +0 -52
  198. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Clickable.kt +0 -66
  199. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Conditional.kt +0 -11
  200. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/DeprecatedModifier.kt +0 -104
  201. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Shadow.kt +0 -48
  202. package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Size.kt +0 -51
  203. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/BottomSheet.kt +0 -299
  204. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/HostBackGestureBridge.kt +0 -58
  205. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ModalScreen.kt +0 -129
  206. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigation.kt +0 -106
  207. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +0 -205
  208. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigator.kt +0 -393
  209. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ScrollToTop.kt +0 -8
  210. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +0 -622
  211. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackTransition.kt +0 -148
  212. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/SwipeBackHaptic.kt +0 -35
  213. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTab.kt +0 -175
  214. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +0 -232
  215. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/CurvedContainer.kt +0 -86
  216. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/FloatingButton.kt +0 -169
  217. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +0 -381
  218. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderBackground.kt +0 -83
  219. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderJourney.kt +0 -105
  220. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderLocation.kt +0 -74
  221. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderRight.kt +0 -347
  222. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderTitle.kt +0 -37
  223. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderUser.kt +0 -363
  224. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SideBar.kt +0 -169
  225. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SnackBar.kt +0 -132
  226. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/tracking/ScreenTracker.kt +0 -127
  227. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/BackGesture.kt +0 -12
  228. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/ComposeLottieAnimation.kt +0 -91
  229. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/OsFontScale.kt +0 -9
  230. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +0 -71
  231. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Icons.kt +0 -1329
  232. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Resources.kt +0 -55
  233. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Tracking.kt +0 -15
  234. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Utils.kt +0 -118
  235. package/compose/src/iosMain/kotlin/vn/momo/kits/const/HostFont.ios.kt +0 -40
  236. package/compose/src/iosMain/kotlin/vn/momo/kits/navigation/HostBackGesture.ios.kt +0 -45
  237. package/compose/src/iosMain/kotlin/vn/momo/kits/navigation/ScrollToTop.ios.kt +0 -32
  238. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/BackGesture.ios.kt +0 -38
  239. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/OsFontScale.ios.kt +0 -66
  240. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +0 -213
  241. package/gradle/libs.versions.toml +0 -69
  242. package/gradle/wrapper/gradle-wrapper.jar +0 -0
  243. package/gradle/wrapper/gradle-wrapper.properties +0 -8
  244. package/gradle.properties +0 -26
  245. package/gradlew +0 -252
  246. package/gradlew.bat +0 -94
  247. package/ios/Application/Components.swift +0 -270
  248. package/ios/Application/ComposeApi.swift +0 -22
  249. package/ios/Application/HeaderRight.swift +0 -306
  250. package/ios/Application/Navigation/BottomTab/BottomTab.swift +0 -104
  251. package/ios/Application/Navigation/HeaderBackProps.swift +0 -66
  252. package/ios/Application/Navigation/HeaderTitle.swift +0 -57
  253. package/ios/Application/Navigation/NavigationContainer.swift +0 -213
  254. package/ios/Application/Navigation/NavigationOptions.swift +0 -109
  255. package/ios/Application/Navigation/NavigatorManager.swift +0 -22
  256. package/ios/Application/Navigation/component/Header.swift +0 -178
  257. package/ios/Application/Navigation/component/HeaderBackground.swift +0 -83
  258. package/ios/Application/Navigation/component/HeaderColor.swift +0 -65
  259. package/ios/Application/Navigation/component/HeaderRightWidthKey.swift +0 -11
  260. package/ios/Application/Navigation/component/NavigationFooter.swift +0 -90
  261. package/ios/Application/Navigation/component/NavigationHeaderRight.swift +0 -196
  262. package/ios/Application/Screen.swift +0 -250
  263. package/ios/Application/StackScreen.swift +0 -492
  264. package/ios-demo/README.md +0 -120
  265. package/settings.gradle.kts +0 -64
  266. /package/ios/{Application/Navigation → Navigation}/BottomTab/CurvedContainer.swift +0 -0
@@ -1,622 +0,0 @@
1
- package vn.momo.kits.navigation
2
-
3
- import androidx.compose.animation.animateColorAsState
4
- import androidx.compose.foundation.ScrollState
5
- import androidx.compose.foundation.background
6
- import androidx.compose.foundation.border
7
- import androidx.compose.foundation.gestures.ScrollableState
8
- import androidx.compose.foundation.gestures.animateScrollBy
9
- import androidx.compose.foundation.layout.Box
10
- import androidx.compose.foundation.layout.Column
11
- import androidx.compose.foundation.layout.ColumnScope
12
- import androidx.compose.foundation.layout.Spacer
13
- import androidx.compose.foundation.layout.WindowInsets
14
- import androidx.compose.foundation.layout.asPaddingValues
15
- import androidx.compose.foundation.layout.aspectRatio
16
- import androidx.compose.foundation.layout.fillMaxSize
17
- import androidx.compose.foundation.layout.fillMaxWidth
18
- import androidx.compose.foundation.layout.height
19
- import androidx.compose.foundation.layout.ime
20
- import androidx.compose.foundation.layout.imePadding
21
- import androidx.compose.foundation.layout.offset
22
- import androidx.compose.foundation.layout.padding
23
- import androidx.compose.foundation.lazy.LazyListState
24
- import androidx.compose.foundation.rememberScrollState
25
- import androidx.compose.foundation.verticalScroll
26
- import androidx.compose.material.ExperimentalMaterialApi
27
- import androidx.compose.runtime.Composable
28
- import androidx.compose.runtime.CompositionLocalProvider
29
- import androidx.compose.runtime.LaunchedEffect
30
- import androidx.compose.runtime.State
31
- import androidx.compose.runtime.getValue
32
- import androidx.compose.runtime.mutableIntStateOf
33
- import androidx.compose.runtime.mutableStateOf
34
- import androidx.compose.runtime.remember
35
- import androidx.compose.runtime.rememberUpdatedState
36
- import androidx.compose.runtime.snapshotFlow
37
- import androidx.compose.runtime.staticCompositionLocalOf
38
- import androidx.compose.ui.Alignment
39
- import androidx.compose.ui.Modifier
40
- import androidx.compose.ui.graphics.Brush
41
- import androidx.compose.ui.graphics.Color
42
- import androidx.compose.ui.graphics.lerp
43
- import androidx.compose.ui.layout.onGloballyPositioned
44
- import androidx.compose.ui.platform.LocalDensity
45
- import androidx.compose.ui.unit.Dp
46
- import androidx.compose.ui.unit.dp
47
- import androidx.compose.ui.unit.lerp
48
- import androidx.compose.ui.zIndex
49
- import kotlinx.coroutines.flow.Flow
50
- import kotlinx.coroutines.flow.filter
51
- import kotlinx.coroutines.launch
52
- import vn.momo.kits.components.InputSearch
53
- import vn.momo.kits.const.AppNavigationBar
54
- import vn.momo.kits.const.AppTheme
55
- import vn.momo.kits.application.IsShowBaseLineDebug
56
- import vn.momo.kits.const.Colors
57
- import vn.momo.kits.const.Spacing
58
- import vn.momo.kits.modifier.conditional
59
- import vn.momo.kits.modifier.hideKeyboardOnTap
60
- import vn.momo.kits.navigation.bottomtab.BOTTOM_TAB_BAR_HEIGHT
61
- import vn.momo.kits.navigation.component.FABPosition
62
- import vn.momo.kits.navigation.component.FloatingButton
63
- import vn.momo.kits.navigation.component.HEADER_HEIGHT
64
- import vn.momo.kits.navigation.component.Header
65
- import vn.momo.kits.navigation.component.HeaderBackground
66
- import vn.momo.kits.navigation.component.HeaderRight
67
- import vn.momo.kits.navigation.component.HeaderSideBar
68
- import vn.momo.kits.navigation.component.HeaderType
69
- import vn.momo.kits.navigation.component.InputSearchType
70
- import vn.momo.kits.platform.BackHandler
71
- import vn.momo.kits.platform.supportsImePadding
72
- import vn.momo.kits.navigation.tracking.ScreenTracker
73
- import vn.momo.kits.navigation.tracking.ScreenTrackingState
74
- import kotlinx.coroutines.delay
75
- import vn.momo.kits.application.LocalContext
76
- import vn.momo.kits.utils.horizontalSafeAreaPadding
77
- import vn.momo.kits.layout.LocalScreenLayout
78
- import vn.momo.kits.layout.consumeHorizontalInsets
79
- import vn.momo.kits.layout.getScreenLayout
80
- import kotlin.time.Clock
81
- import kotlin.time.Duration.Companion.milliseconds
82
- import kotlin.time.ExperimentalTime
83
-
84
- internal val LocalFooterHeightPx = staticCompositionLocalOf { mutableIntStateOf(0) }
85
- internal val LocalHeaderRightWidthPx = staticCompositionLocalOf { mutableIntStateOf(0) }
86
-
87
- @Composable
88
- private fun bottomTabBarInset(): Dp {
89
- if (LocalNavigation.current.bottomTabIndex == -1) return 0.dp
90
- val keyboard = keyboardSizeState().value
91
- return (BOTTOM_TAB_BAR_HEIGHT.dp + Spacing.S - keyboard).coerceAtLeast(0.dp)
92
- }
93
-
94
- @OptIn(ExperimentalMaterialApi::class, ExperimentalTime::class)
95
- @Composable
96
- internal fun StackScreen(
97
- content: @Composable () -> Unit,
98
- navigationOptions: NavigationOptions? = null,
99
- id: Int = -1,
100
- name: String = "",
101
- bottomTabIndex: Int = -1,
102
- onBackHandler: (() -> Unit)? = null,
103
- ) {
104
- val navigator = LocalNavigator.current
105
- val maxApi = LocalMaxApi.current
106
- val context = LocalContext.current
107
- val screenLayout = getScreenLayout()
108
- val density = LocalDensity.current
109
- val screenRegistry = LocalDynamicScreenRegistry.current
110
- val navigation = remember { Navigation(id = id, bottomTabIndex = bottomTabIndex, initOptions = navigationOptions, registry = screenRegistry) }
111
-
112
- val options by navigation.currentOptions
113
- val isBottomTabChild = bottomTabIndex != -1
114
- val isBottomTabRoot = navigation.isBottomTabRoot
115
-
116
- // Auto tracking state
117
- val trackingState = remember {
118
- ScreenTrackingState().apply {
119
- time = Clock.System.now().toEpochMilliseconds()
120
- }
121
- }
122
-
123
- // Determine action: push or back
124
- val action = remember {
125
- if (ScreenTracker.getLastScreenName() != null) "push" else "back"
126
- }
127
-
128
- // Auto tracking effects
129
- LaunchedEffect(name) {
130
- // Track screen navigated immediately
131
- ScreenTracker.trackScreenNavigated(
132
- maxApi = maxApi,
133
- context = context,
134
- screenName = name,
135
- action = action,
136
- state = trackingState
137
- )
138
-
139
- // Track screen displayed after 2 seconds (debounce)
140
- delay(2000.milliseconds)
141
- val loadTime = Clock.System.now().toEpochMilliseconds() - trackingState.time
142
- ScreenTracker.trackScreenDisplayed(
143
- maxApi = maxApi,
144
- context = context,
145
- screenName = name,
146
- duration = loadTime,
147
- state = trackingState
148
- )
149
-
150
- // Track screen interacted after displayed
151
- val interactionTime = Clock.System.now().toEpochMilliseconds() - trackingState.time
152
- ScreenTracker.trackScreenInteracted(
153
- maxApi = maxApi,
154
- context = context,
155
- screenName = name,
156
- duration = interactionTime - loadTime,
157
- totalDuration = interactionTime,
158
- state = trackingState
159
- )
160
- }
161
-
162
- val limit = with(density) {
163
- screenLayout.headerHeight.toPx()
164
- }.toInt()
165
-
166
- val lazyListState = options.scrollData.scrollState as? LazyListState
167
- val (scrollState, _) = if (lazyListState != null)
168
- lazyListState.proxyScrollState(limit, 1)
169
- else
170
- (options.scrollData.scrollState as? ScrollState ?: rememberScrollState()).proxyLimitedScrollState(limit, 1)
171
- val snapState: ScrollableState = lazyListState ?: scrollState
172
-
173
- val footerHeightPx = remember { mutableIntStateOf(0) }
174
- val headerRightWidthPx = remember { mutableIntStateOf(0) }
175
-
176
- if (navigation.options.scrollData.scrollToTopCallback != null) {
177
- RegisterScrollToTop(navigation.options.scrollData.scrollToTopCallback)
178
- }
179
-
180
- val canPop = navigator.canPop()
181
-
182
- val hasCustomBackHandling = !SwipeBackConfig.enabled ||
183
- OverplayComponentRegistry.isOverplayShowing() ||
184
- !canPop
185
-
186
- BackHandler(hasCustomBackHandling) { navigator.onBackSafe() }
187
-
188
- CompositionLocalProvider(
189
- StackScreenScrollableState provides options.scrollData.scrollState,
190
- LocalNavigation provides navigation,
191
- LocalScrollState provides scrollState,
192
- LocalOptions provides options,
193
- LocalFooterHeightPx provides footerHeightPx,
194
- LocalHeaderRightWidthPx provides headerRightWidthPx
195
- ) {
196
- Box(
197
- Modifier
198
- .fillMaxSize()
199
- .background(options.backgroundColor ?: AppTheme.current.colors.background.default)
200
- .conditional(options.keyboardOptions.keyboardShouldPersistTaps) {
201
- hideKeyboardOnTap()
202
- }
203
- .conditional(options.keyboardOptions.useAvoidKeyboard && supportsImePadding()) {
204
- imePadding()
205
- }
206
- ) {
207
- Box(Modifier.zIndex(1f)) {
208
- HeaderBackground()
209
- }
210
-
211
- Box(Modifier.zIndex(4f)) {
212
- Header(onBackHandler)
213
- }
214
-
215
- HeaderSideBar(bottomInset = bottomBarsHeight(isBottomTabChild), modifier = Modifier.zIndex(4f))
216
-
217
- Column(Modifier.zIndex(5f).horizontalSafeAreaPadding()) {
218
- SearchAnimated(snapState = snapState)
219
- }
220
-
221
- Column(Modifier.zIndex(2f).fillMaxSize()) {
222
- MainContent(content = content, isBottomTabRoot = isBottomTabRoot, isBottomTabChild = isBottomTabChild)
223
- FooterContent()
224
- }
225
-
226
- Box(Modifier.zIndex(6f).horizontalSafeAreaPadding()) {
227
- FloatingContent(isBottomTabChild = isBottomTabChild)
228
- }
229
-
230
- OverplayView(isBottomTabChild = isBottomTabChild, id = id)
231
- }
232
- }
233
- }
234
-
235
- // Height the footer, tab bar or home indicator takes from the bottom of the screen.
236
- @Composable
237
- private fun bottomBarsHeight(isBottomTabChild: Boolean): Dp {
238
- val options = LocalOptions.current
239
- val navigationBar = AppNavigationBar.current
240
- return when {
241
- options.hasFooter() -> with(LocalDensity.current) { LocalFooterHeightPx.current.intValue.toDp() }
242
- isBottomTabChild -> bottomTabBarInset() + (navigationBar - keyboardSizeState().value).coerceAtLeast(0.dp)
243
- else -> navigationBar
244
- }
245
- }
246
-
247
- @Suppress("FrequentlyChangingValue")
248
- @Composable
249
- internal fun FloatingContent(isBottomTabChild: Boolean) {
250
- val options = LocalOptions.current
251
- val scrollState = LocalScrollState.current
252
-
253
- val fabProps = options.floatingButtonProps ?: return
254
- val bottomPadding = fabProps.bottom ?: (Spacing.M + bottomBarsHeight(isBottomTabChild))
255
-
256
- FloatingButton(
257
- scrollPosition = fabProps.scrollState?.value ?: scrollState.value,
258
- onClick = fabProps.onClick,
259
- containerColor = AppTheme.current.colors.primary,
260
- bottom = bottomPadding,
261
- icon = fabProps.icon,
262
- iconColor = fabProps.iconColor,
263
- text = fabProps.label,
264
- size = fabProps.size,
265
- position = fabProps.position ?: FABPosition.END,
266
- )
267
- }
268
-
269
- @Composable
270
- internal fun ColumnScope.MainContent(content: @Composable () -> Unit, isBottomTabRoot: Boolean, isBottomTabChild: Boolean) {
271
- val options = LocalOptions.current
272
- val inputSearchType = getInputSearchType(options)
273
- val density = LocalDensity.current
274
- val scrollState = LocalScrollState.current
275
- val navigationBar = AppNavigationBar.current
276
- val screenLayout = getScreenLayout()
277
-
278
- Spacer(
279
- Modifier.height(
280
- if (options.headerType is HeaderType.DefaultOrExtended || (options.headerType is HeaderType.Transparent && !options.headerType.isFullScreenContent))
281
- screenLayout.headerHeight else 0.dp
282
- )
283
- )
284
- if (inputSearchType == InputSearchType.Animated) {
285
- val scrollDp = with(density) { scrollState.value.toDp() }
286
-
287
- Spacer(Modifier.height((HEADER_HEIGHT.dp - scrollDp).coerceIn(0.dp, HEADER_HEIGHT.dp)))
288
- }
289
- // a bottom tab root stays full width: the tab bar and each tab's own StackScreen handle the insets
290
- Column(
291
- Modifier
292
- .fillMaxWidth()
293
- .weight(1f)
294
- .conditional(!isBottomTabRoot) {
295
- horizontalSafeAreaPadding()
296
- }
297
- .conditional(options.scrollData.scrollable && options.scrollData.scrollState is ScrollState) {
298
- verticalScroll(scrollState)
299
- }
300
- .padding(
301
- bottom = when {
302
- options.hasFooter() || isBottomTabRoot -> 0.dp
303
- isBottomTabChild -> bottomTabBarInset() + (navigationBar - keyboardSizeState().value).coerceAtLeast(0.dp)
304
- !options.scrollData.scrollable && options.scrollData.scrollState == null -> 0.dp
305
- else -> navigationBar
306
- }
307
- )
308
- ) {
309
- CompositionLocalProvider(
310
- LocalScreenLayout provides if (isBottomTabRoot) screenLayout else screenLayout.consumeHorizontalInsets()
311
- ) {
312
- ScreenContent(content = content)
313
- }
314
- }
315
-
316
- }
317
-
318
- @Composable
319
- internal fun ScreenContent(content: @Composable () -> Unit) {
320
- val scrollState = LocalScrollState.current
321
- val options = LocalOptions.current
322
-
323
- if (options.headerType is HeaderType.Animated) {
324
- val animatedHeader = options.headerType
325
- Box {
326
- val bannerModifier = animatedHeader.height
327
- ?.let { Modifier.fillMaxWidth().height(it) }
328
- ?: Modifier.fillMaxWidth().aspectRatio(animatedHeader.aspectRatio.value)
329
- Box(bannerModifier) {
330
- animatedHeader.composable.invoke(scrollState.value)
331
- }
332
- Box(Modifier.padding(top = getScreenLayout().headerHeight + animatedHeader.layoutOffSet)) {
333
- content()
334
- }
335
- }
336
- } else {
337
- content()
338
- }
339
- }
340
-
341
- @Composable
342
- internal fun FooterContent() {
343
- val options = LocalOptions.current
344
- if (options.hasFooter()) {
345
- val keyboardSize = keyboardSizeState()
346
- val bottomPadding = (AppNavigationBar.current - keyboardSize.value).coerceAtLeast(0.dp)
347
- Footer(
348
- footerComponent = options.footerComponent,
349
- bottomPadding = bottomPadding,
350
- transparent = options.footerTransparent,
351
- useMargin = options.footerUseMargin
352
- )
353
- }
354
- }
355
-
356
- @Composable
357
- internal fun keyboardSizeState(): State<Dp> {
358
- val bottom = WindowInsets.ime.asPaddingValues()
359
- return rememberUpdatedState(bottom.calculateBottomPadding())
360
- }
361
-
362
- @Composable
363
- internal fun OverplayView(isBottomTabChild: Boolean, id: Int) {
364
- val overplayType = OverplayComponentRegistry.getOverplayType()
365
-
366
- if (overplayType != null) {
367
- Box(Modifier.zIndex(if (overplayType == OverplayComponentType.SNACK_BAR) 3f else 7f).fillMaxSize()) {
368
- if (isBottomTabChild) return@Box
369
- if (OverplayComponentRegistry.currentRootId() != id) return@Box
370
- OverplayComponentRegistry.OverlayComponent()
371
- }
372
- }
373
- }
374
-
375
- @Composable
376
- fun Footer(
377
- footerComponent: @Composable (() -> Unit)?,
378
- bottomPadding: Dp,
379
- transparent: Boolean = false,
380
- useMargin: Boolean = true,
381
- ) {
382
- if (footerComponent == null) return
383
-
384
- val footerHeightPx = LocalFooterHeightPx.current
385
-
386
- val shadowBrush = remember {
387
- Brush.verticalGradient(
388
- colors = listOf(Color.Transparent, Color.Black.copy(alpha = 0.05f))
389
- )
390
- }
391
-
392
- val backgroundColor = if (transparent) Color.Transparent else AppTheme.current.colors.background.surface
393
-
394
- Box(Modifier.onGloballyPositioned {
395
- if (footerHeightPx.intValue != it.size.height) footerHeightPx.intValue = it.size.height
396
- }) {
397
- Box(
398
- Modifier
399
- .fillMaxWidth()
400
- .background(backgroundColor)
401
- .conditional(IsShowBaseLineDebug) {
402
- border(1.dp, Colors.blue_03)
403
- }
404
- .horizontalSafeAreaPadding()
405
- .padding(
406
- top = if (useMargin) Spacing.S else 0.dp,
407
- start = if (useMargin) Spacing.M else 0.dp,
408
- end = if (useMargin) Spacing.M else 0.dp,
409
- bottom = bottomPadding + if (useMargin) Spacing.S else 0.dp,
410
- )
411
- ) {
412
- footerComponent.invoke()
413
- }
414
-
415
- if (!transparent) {
416
- Box(
417
- modifier = Modifier
418
- .fillMaxWidth()
419
- .height(6.dp)
420
- .offset(x = 0.dp, y = (-6).dp)
421
- .background(shadowBrush)
422
- )
423
- }
424
- }
425
- }
426
-
427
- data class InputSearchLayoutParams(
428
- val topPadding: Dp,
429
- val startPadding: Dp,
430
- val endPadding: Dp
431
- )
432
-
433
- @Suppress("FrequentlyChangingValue")
434
- @Composable
435
- internal fun SearchAnimated(
436
- snapState: ScrollableState
437
- ) {
438
- val scrollState = LocalScrollState.current
439
- val options = LocalOptions.current
440
- val navigator = LocalNavigator.current
441
- val density = LocalDensity.current
442
-
443
- val scrollDp = with(density) { scrollState.value.toDp() }
444
-
445
- val inputSearchType = getInputSearchType(options)
446
- val headerRightWidthPx = LocalHeaderRightWidthPx.current
447
- val headerRightWidthDp = with(density) { headerRightWidthPx.intValue.toDp() }
448
-
449
- if (inputSearchType == InputSearchType.None) return
450
- val inputSearchProps = (options.headerType as? HeaderType.DefaultOrExtended)?.inputSearchProps ?: return
451
-
452
- val screenLayout = getScreenLayout()
453
- val useSideBar = screenLayout.sideBar != null
454
- // collapsed, the search is centered in the bar row
455
- val minTopPadding = screenLayout.headerStatusBarHeight + (screenLayout.headerBarHeight - HEADER_HEIGHT.dp) / 2
456
- val maxTopPadding = screenLayout.headerHeight
457
- val minStartPadding = Spacing.M
458
- val maxStartPadding = if (options.hiddenBack || useSideBar) Spacing.M else 48.dp // button back: size + left +right = 28 + 12 + 8 = 48
459
- val minEndPadding = Spacing.M
460
- val maxEndPadding = when {
461
- options.headerRight is HeaderRight.None -> Spacing.M
462
- useSideBar && options.headerRight is HeaderRight.Toolkit -> Spacing.M
463
- else -> headerRightWidthDp + Spacing.M * 2
464
- }
465
-
466
- val targetColor = lerp(
467
- AppTheme.current.colors.background.surface,
468
- AppTheme.current.colors.background.default,
469
- (scrollDp / minTopPadding.coerceAtLeast(1.dp)).coerceIn(0f, 1f)
470
- )
471
- val animatedColor by animateColorAsState(targetValue = targetColor, label = "BackgroundColor")
472
-
473
- val layoutParams = when (inputSearchType) {
474
- InputSearchType.Header -> {
475
- InputSearchLayoutParams(
476
- topPadding = minTopPadding,
477
- startPadding = maxStartPadding,
478
- endPadding = maxEndPadding
479
- )
480
- }
481
-
482
- InputSearchType.Animated -> {
483
- val collapsePx = with(density) { HEADER_HEIGHT.dp.roundToPx() }
484
- val progress = (scrollState.value / collapsePx.toFloat()).coerceIn(0f, 1f)
485
-
486
- LaunchedEffect(snapState, collapsePx) {
487
- snapshotFlow { snapState.isScrollInProgress }
488
- .filter { !it }
489
- .collect {
490
- val offset = snapState.headerOffsetPx() ?: return@collect
491
- if (offset <= 0 || offset >= collapsePx) return@collect
492
- val target = if (offset < collapsePx / 2) 0 else collapsePx
493
- launch { snapState.animateScrollBy((target - offset).toFloat()) }
494
- }
495
- }
496
-
497
- InputSearchLayoutParams(
498
- topPadding = lerp(maxTopPadding, minTopPadding, progress),
499
- startPadding = lerp(minStartPadding, maxStartPadding, progress),
500
- endPadding = lerp(minEndPadding, maxEndPadding, progress)
501
- )
502
- }
503
-
504
- InputSearchType.None -> return
505
- }
506
-
507
- Spacer(Modifier.height(layoutParams.topPadding))
508
- Box(
509
- modifier = Modifier
510
- .height(HEADER_HEIGHT.dp)
511
- .fillMaxWidth()
512
- .padding(
513
- start = layoutParams.startPadding,
514
- end = layoutParams.endPadding
515
- ),
516
- contentAlignment = Alignment.Center
517
- ) {
518
- InputSearch(
519
- inputSearchProps = inputSearchProps.copy(
520
- backgroundColor = animatedColor,
521
- onPressButtonText = {
522
- navigator.pop()
523
- }
524
- )
525
- )
526
- }
527
- }
528
-
529
- private fun ScrollableState.headerOffsetPx(): Int? = when (this) {
530
- is LazyListState -> if (firstVisibleItemIndex == 0) firstVisibleItemScrollOffset else null
531
- is ScrollState -> value
532
- else -> null
533
- }
534
-
535
- private fun quantize(value: Int, stepPx: Int): Int {
536
- if (stepPx <= 1) return value
537
- return (value / stepPx) * stepPx
538
- }
539
-
540
- @Composable
541
- internal fun LazyListState.proxyScrollState(
542
- thresholdPx: Int = 200,
543
- stepPx: Int = 4
544
- ): Pair<ScrollState, Boolean> = proxyScroll(
545
- source = this,
546
- thresholdPx = thresholdPx,
547
- stepPx = stepPx,
548
- isScrollInProgress = { isScrollInProgress },
549
- rawTargetFlow = {
550
- snapshotFlow {
551
- if (firstVisibleItemIndex == 0) firstVisibleItemScrollOffset
552
- else SCROLLED_PAST_FIRST_ITEM_THRESHOLD
553
- }
554
- },
555
- )
556
-
557
- @Composable
558
- internal fun ScrollState.proxyLimitedScrollState(
559
- thresholdPx: Int = 200,
560
- stepPx: Int = 4
561
- ): Pair<ScrollState, Boolean> = proxyScroll(
562
- source = this,
563
- thresholdPx = thresholdPx,
564
- stepPx = stepPx,
565
- isScrollInProgress = { isScrollInProgress },
566
- rawTargetFlow = { snapshotFlow { value } },
567
- )
568
-
569
- @Composable
570
- private fun proxyScroll(
571
- source: Any,
572
- thresholdPx: Int,
573
- stepPx: Int,
574
- isScrollInProgress: () -> Boolean,
575
- rawTargetFlow: () -> Flow<Int>,
576
- ): Pair<ScrollState, Boolean> {
577
- val proxy = rememberScrollState()
578
- val locked = remember { mutableStateOf(false) }
579
-
580
- LaunchedEffect(source, proxy, thresholdPx, stepPx) {
581
- rawTargetFlow().collect { rawTarget ->
582
- val shouldLock = rawTarget > thresholdPx
583
- if (locked.value != shouldLock) locked.value = shouldLock
584
-
585
- val desired = if (shouldLock) thresholdPx else quantize(rawTarget, stepPx)
586
-
587
- if (proxy.value != desired) {
588
- proxy.scrollTo(desired.coerceAtLeast(0))
589
- }
590
- }
591
- }
592
-
593
- val inProgress = remember { mutableStateOf(false) }
594
- LaunchedEffect(source, thresholdPx) {
595
- snapshotFlow { isScrollInProgress() }
596
- .collect { progressing ->
597
- inProgress.value = if (locked.value) false else progressing
598
- }
599
- }
600
-
601
- return proxy to inProgress.value
602
- }
603
-
604
- private const val SCROLLED_PAST_FIRST_ITEM_THRESHOLD = 10_000
605
-
606
- internal val LocalScrollState = staticCompositionLocalOf<ScrollState> { error("No Scroll State provided") }
607
- internal val LocalOptions = staticCompositionLocalOf<NavigationOptions> { error("No NavigationOptions provided") }
608
-
609
- val StackScreenScrollableState = staticCompositionLocalOf<ScrollableState?> { null }
610
-
611
- internal fun getInputSearchType(options: NavigationOptions): InputSearchType {
612
- return when (val headerType = options.headerType) {
613
- is HeaderType.DefaultOrExtended -> when {
614
- headerType.inputSearchProps == null -> InputSearchType.None
615
- headerType.useAnimated -> InputSearchType.Animated
616
- else -> InputSearchType.Header
617
- }
618
-
619
- else -> InputSearchType.None
620
- }
621
- }
622
-