@momo-kits/native-kits 0.300.3-debug → 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 (218) hide show
  1. package/CLAUDE.md +51 -7
  2. package/README.md +2 -2
  3. package/compose/build.gradle.kts +10 -2
  4. package/compose/build.gradle.kts.backup +8 -0
  5. package/compose/compose.podspec +1 -3
  6. package/compose/src/androidMain/kotlin/vn/momo/kits/const/HostFont.android.kt +4 -3
  7. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/Platform.android.kt +2 -0
  8. package/compose/src/androidMain/kotlin/vn/momo/kits/platform/ReservedRegions.android.kt +6 -0
  9. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Context.kt +0 -14
  10. package/compose/src/commonMain/kotlin/vn/momo/kits/application/DesignSystemKits.kt +62 -0
  11. package/compose/src/commonMain/kotlin/vn/momo/kits/application/LiteScreen.kt +351 -111
  12. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Badge.kt +20 -21
  13. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +2 -1
  14. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Carousel.kt +4 -2
  15. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Chip.kt +1 -1
  16. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Icon.kt +1 -1
  17. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Information.kt +1 -1
  18. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +9 -6
  19. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputMoney.kt +11 -12
  20. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputOTP.kt +4 -9
  21. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputPhoneNumber.kt +2 -2
  22. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +10 -9
  23. package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +6 -6
  24. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +55 -22
  25. package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupPromotion.kt +12 -1
  26. package/compose/src/commonMain/kotlin/vn/momo/kits/components/ProgressInfo.kt +7 -9
  27. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Radio.kt +1 -1
  28. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Slider.kt +13 -6
  29. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Swipe.kt +13 -5
  30. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Switch.kt +3 -2
  31. package/compose/src/commonMain/kotlin/vn/momo/kits/components/TabView.kt +14 -6
  32. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tag.kt +19 -21
  33. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +2 -2
  34. package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tooltip.kt +5 -2
  35. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerUtils.kt +3 -1
  36. package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/WheelPicker.kt +7 -15
  37. package/compose/src/commonMain/kotlin/vn/momo/kits/const/HostFont.kt +2 -1
  38. package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +20 -15
  39. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Item.kt +1 -2
  40. package/compose/src/commonMain/kotlin/vn/momo/kits/layout/ScreenLayout.kt +306 -0
  41. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/BottomSheet.kt +43 -4
  42. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ModalScreen.kt +8 -0
  43. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigation.kt +10 -0
  44. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +6 -2
  45. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigator.kt +6 -0
  46. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +197 -60
  47. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTab.kt +132 -83
  48. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +54 -62
  49. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/DuoBarCompression.kt +97 -0
  50. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/DuoTabBar.kt +377 -0
  51. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +122 -24
  52. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderBackground.kt +34 -14
  53. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderJourney.kt +3 -3
  54. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderLocation.kt +1 -2
  55. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderRight.kt +113 -26
  56. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderTitle.kt +2 -2
  57. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderUser.kt +1 -2
  58. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HelpCenterRequest.kt +37 -0
  59. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SideBar.kt +192 -0
  60. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SnackBar.kt +2 -1
  61. package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/ToolkitRequests.kt +8 -0
  62. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +3 -0
  63. package/compose/src/commonMain/kotlin/vn/momo/kits/platform/ReservedRegions.kt +20 -0
  64. package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Utils.kt +13 -0
  65. package/compose/src/commonTest/kotlin/vn/momo/kits/navigation/component/HelpCenterRequestTest.kt +44 -0
  66. package/compose/src/commonTest/kotlin/vn/momo/kits/navigation/component/ToolkitRequestsTest.kt +15 -0
  67. package/compose/src/iosMain/kotlin/vn/momo/kits/const/HostFont.ios.kt +3 -1
  68. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +4 -0
  69. package/compose/src/iosMain/kotlin/vn/momo/kits/platform/ReservedRegions.ios.kt +138 -0
  70. package/gradle/libs.versions.toml +3 -14
  71. package/gradle/wrapper/gradle-wrapper.properties +0 -2
  72. package/gradle.properties +3 -5
  73. package/ios/Application/ApplicationEnvironment.swift +24 -6
  74. package/ios/Application/DesignSystemKits.swift +100 -0
  75. package/ios/Application/DesignSystemKitsPayload.swift +68 -0
  76. package/ios/Application/MaxApi.swift +30 -3
  77. package/ios/Avatar/Avatar.swift +4 -3
  78. package/ios/Badge/Badge.swift +6 -4
  79. package/ios/Badge/BadgeDot.swift +1 -1
  80. package/ios/Badge/BadgeRibbon.swift +8 -2
  81. package/ios/Button/Button.swift +15 -12
  82. package/ios/CalculatorKeyboard/CalculatorKeyboard.swift +64 -18
  83. package/ios/Carousel/Carousel.swift +29 -12
  84. package/ios/Checkbox/Checkbox.swift +7 -3
  85. package/ios/Chip/Chip.swift +5 -4
  86. package/ios/Collapse/Collapse.swift +70 -19
  87. package/ios/Colors+Radius+Spacing/Colors.swift +10 -1
  88. package/ios/Colors+Radius+Spacing/Radius.swift +6 -0
  89. package/ios/DateTimePicker/DateTimePicker.swift +54 -20
  90. package/ios/DateTimePicker/WheelPicker.swift +103 -105
  91. package/ios/Divider/Divider.swift +37 -4
  92. package/ios/Extensions/Color++.swift +38 -9
  93. package/ios/Extensions/OptionalEnvironmentObject.swift +12 -0
  94. package/ios/Extensions/SkeletonUICompat.swift +11 -0
  95. package/ios/Icon/Icon.swift +21 -23
  96. package/ios/Icon/Icons.swift +1329 -0
  97. package/ios/IconButton/IconButton.swift +15 -7
  98. package/ios/Image/Image.swift +7 -23
  99. package/ios/Information/Information.swift +27 -9
  100. package/ios/Input/ErrorView.swift +2 -2
  101. package/ios/Input/Input.swift +171 -148
  102. package/ios/Input/InputPhoneNumber.swift +10 -9
  103. package/ios/Input/InputSearch.swift +107 -78
  104. package/ios/Input/InputTextArea.swift +133 -148
  105. package/ios/InputDropDown/InputDropDown.swift +10 -7
  106. package/ios/InputMoney/InputMoney.swift +32 -11
  107. package/ios/InputOTP/InputOTP.swift +22 -12
  108. package/ios/Layout/Card.swift +50 -0
  109. package/ios/Layout/GridContext.swift +187 -3
  110. package/ios/Layout/Item.swift +5 -4
  111. package/ios/Layout/ScreenLayout.swift +415 -0
  112. package/ios/Layout/Section.swift +4 -100
  113. package/ios/Loader/Loader.swift +5 -9
  114. package/ios/Lottie/LottieView.swift +14 -2
  115. package/ios/{Application/Navigation/Overplay → Navigation}/BottomSheet.swift +169 -29
  116. package/ios/Navigation/BottomTab/BottomTab.swift +332 -0
  117. package/ios/{Application/Navigation → Navigation}/BottomTab/BottomTabBar.swift +18 -7
  118. package/ios/Navigation/BottomTab/DuoBarCompression.swift +104 -0
  119. package/ios/Navigation/BottomTab/DuoTabBar.swift +329 -0
  120. package/ios/{Application → Navigation/Component}/FloatingButton.swift +43 -54
  121. package/ios/Navigation/Component/Header.swift +545 -0
  122. package/ios/Navigation/Component/HeaderBackground.swift +154 -0
  123. package/ios/Navigation/Component/HeaderJourney.swift +73 -0
  124. package/ios/Navigation/Component/HeaderLocation.swift +48 -0
  125. package/ios/Navigation/Component/HeaderRight.swift +425 -0
  126. package/ios/Navigation/Component/HeaderTitle.swift +36 -0
  127. package/ios/{Application/Navigation → Navigation/Component}/HeaderUser.swift +21 -24
  128. package/ios/Navigation/Component/SideBar.swift +183 -0
  129. package/ios/{Application/Navigation/Overplay → Navigation/Component}/SnackBar.swift +8 -8
  130. package/ios/Navigation/HostBackGestureBridge.swift +78 -0
  131. package/ios/{Application/Navigation/Overplay → Navigation}/ModalScreen.swift +9 -2
  132. package/ios/Navigation/Navigation.swift +204 -0
  133. package/ios/Navigation/NavigationContainer.swift +195 -0
  134. package/ios/{Application/Navigation → Navigation}/Navigator.swift +207 -107
  135. package/ios/Navigation/StackScreen.swift +930 -0
  136. package/ios/Navigation/StackTransition.swift +400 -0
  137. package/ios/Navigation/SwipeBackHaptic.swift +33 -0
  138. package/ios/{Application/Navigation → Navigation}/Tracking/ScreenTracker.swift +12 -5
  139. package/ios/OTPKeyboard/OTPKeyboard.swift +8 -11
  140. package/ios/Pagination/PaginationScroll.swift +2 -2
  141. package/ios/Popup/PopupDisplay.swift +72 -135
  142. package/ios/Popup/PopupInput.swift +10 -13
  143. package/ios/Popup/PopupLayout.swift +138 -0
  144. package/ios/Popup/PopupNotify.swift +59 -69
  145. package/ios/Popup/PopupPromotion.swift +31 -47
  146. package/ios/PopupView/FullscreenPopup.swift +13 -19
  147. package/ios/PopupView/PopupView.swift +1 -1
  148. package/ios/PopupView/Utils++.swift +0 -8
  149. package/ios/ProgressInfo/ProgressInfo.swift +4 -2
  150. package/ios/Radio/Radio.swift +2 -1
  151. package/ios/Rating/Rating.swift +9 -1
  152. package/ios/Resources/dot_loading.json +558 -0
  153. package/ios/Resources/lottie_circle_loader.json +1 -0
  154. package/ios/ScrollIndicator/ScrollIndicator.swift +11 -10
  155. package/ios/Skeleton/Skeleton.swift +22 -27
  156. package/ios/Slider/Slider.swift +16 -18
  157. package/ios/Stepper/Stepper.swift +7 -3
  158. package/ios/Steps/Steps.swift +8 -6
  159. package/ios/SuggestAction/SuggestAction.swift +5 -0
  160. package/ios/Swipeable/SwipeCell.swift +10 -6
  161. package/ios/Switch/Switch.swift +22 -20
  162. package/ios/TabView/TabView.swift +102 -21
  163. package/ios/Tag/Tag.swift +15 -4
  164. package/ios/Template/Logo/Logo.swift +2 -1
  165. package/ios/Template/TrustBanner/TrustBanner.swift +109 -55
  166. package/ios/Title/Title.swift +6 -17
  167. package/ios/Tooltip/Tooltip.swift +29 -14
  168. package/ios/Typography/FontScale.swift +17 -14
  169. package/ios/Typography/Text.swift +156 -20
  170. package/ios/Typography/Typography.swift +2 -2
  171. package/ios/Uploader/Uploader.swift +3 -1
  172. package/ios/native-kits.podspec +2 -3
  173. package/ios-demo/MoMoUIKitsDemo.podspec +1 -3
  174. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/ContentView.swift +1 -1
  175. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/DuoTabDemo.swift +80 -0
  176. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/Home.swift +2 -0
  177. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/IPhoneDuoDemo.swift +173 -0
  178. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/NavigationDemo.swift +77 -1
  179. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupDisplayDemo.swift +1 -0
  180. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupNotifyDemo.swift +2 -2
  181. package/ios-demo/Sources/MoMoUIKitsDemo/SampleDemos/PopupPromotionDemo.swift +2 -0
  182. package/package.json +1 -1
  183. package/publish.sh +19 -2
  184. package/scripts/gen-ios-icons.mjs +36 -0
  185. package/compose/src/commonMain/kotlin/vn/momo/kits/application/AnimationSearchInput.kt +0 -52
  186. package/compose/src/commonMain/kotlin/vn/momo/kits/application/FloatingButton.kt +0 -183
  187. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Header.kt +0 -207
  188. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderAnimated.kt +0 -39
  189. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderBackground.kt +0 -86
  190. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderDefault.kt +0 -76
  191. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderExtended.kt +0 -76
  192. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderRight.kt +0 -293
  193. package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderTitle.kt +0 -33
  194. package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +0 -110
  195. package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +0 -378
  196. package/compose/src/commonMain/kotlin/vn/momo/kits/application/useHeaderSearchAnimation.kt +0 -69
  197. package/compose/src/commonMain/kotlin/vn/momo/kits/const/KitDesignSystem.kt +0 -18
  198. package/compose/src/commonMain/kotlin/vn/momo/kits/const/KitFontScale.kt +0 -22
  199. package/ios/Application/Components.swift +0 -270
  200. package/ios/Application/ComposeApi.swift +0 -22
  201. package/ios/Application/HeaderRight.swift +0 -306
  202. package/ios/Application/Navigation/BottomTab/BottomTab.swift +0 -104
  203. package/ios/Application/Navigation/HeaderBackProps.swift +0 -66
  204. package/ios/Application/Navigation/HeaderTitle.swift +0 -57
  205. package/ios/Application/Navigation/NavigationContainer.swift +0 -213
  206. package/ios/Application/Navigation/NavigationOptions.swift +0 -109
  207. package/ios/Application/Navigation/NavigatorManager.swift +0 -22
  208. package/ios/Application/Navigation/component/Header.swift +0 -178
  209. package/ios/Application/Navigation/component/HeaderBackground.swift +0 -83
  210. package/ios/Application/Navigation/component/HeaderColor.swift +0 -65
  211. package/ios/Application/Navigation/component/HeaderRightWidthKey.swift +0 -11
  212. package/ios/Application/Navigation/component/NavigationFooter.swift +0 -90
  213. package/ios/Application/Navigation/component/NavigationHeaderRight.swift +0 -196
  214. package/ios/Application/Screen.swift +0 -250
  215. package/ios/Application/StackScreen.swift +0 -492
  216. package/ios/Typography/FontScaleStore.swift +0 -58
  217. package/ios/Typography/KitDesignSystem.swift +0 -17
  218. /package/ios/{Application/Navigation → Navigation}/BottomTab/CurvedContainer.swift +0 -0
@@ -1,22 +1,41 @@
1
1
  package vn.momo.kits.application
2
2
 
3
3
  import androidx.annotation.FloatRange
4
- import androidx.compose.animation.animateContentSize
5
- import androidx.compose.foundation.*
4
+ import androidx.compose.foundation.ScrollState
5
+ import androidx.compose.foundation.background
6
+ import androidx.compose.foundation.border
6
7
  import androidx.compose.foundation.gestures.detectTapGestures
7
8
  import androidx.compose.foundation.interaction.FocusInteraction
8
9
  import androidx.compose.foundation.interaction.MutableInteractionSource
9
- import androidx.compose.foundation.layout.*
10
+ import androidx.compose.foundation.layout.Arrangement
11
+ import androidx.compose.foundation.layout.Box
12
+ import androidx.compose.foundation.layout.Row
13
+ import androidx.compose.foundation.layout.fillMaxSize
14
+ import androidx.compose.foundation.layout.padding
15
+ import androidx.compose.foundation.layout.size
16
+ import androidx.compose.foundation.rememberScrollState
10
17
  import androidx.compose.foundation.shape.CircleShape
11
18
  import androidx.compose.foundation.text.BasicTextField
12
19
  import androidx.compose.foundation.text.KeyboardActions
13
20
  import androidx.compose.foundation.text.KeyboardOptions
14
- import androidx.compose.runtime.*
21
+ import androidx.compose.foundation.verticalScroll
22
+ import androidx.compose.runtime.Composable
23
+ import androidx.compose.runtime.CompositionLocalProvider
24
+ import androidx.compose.runtime.LaunchedEffect
25
+ import androidx.compose.runtime.MutableState
26
+ import androidx.compose.runtime.Stable
27
+ import androidx.compose.runtime.State
28
+ import androidx.compose.runtime.derivedStateOf
29
+ import androidx.compose.runtime.getValue
30
+ import androidx.compose.runtime.mutableStateOf
31
+ import androidx.compose.runtime.remember
32
+ import androidx.compose.runtime.rememberUpdatedState
33
+ import androidx.compose.runtime.staticCompositionLocalOf
15
34
  import androidx.compose.ui.Alignment
16
35
  import androidx.compose.ui.Modifier
17
36
  import androidx.compose.ui.composed
18
37
  import androidx.compose.ui.draw.clip
19
- import androidx.compose.ui.draw.drawBehind
38
+ import androidx.compose.ui.draw.drawWithCache
20
39
  import androidx.compose.ui.draw.drawWithContent
21
40
  import androidx.compose.ui.geometry.Offset
22
41
  import androidx.compose.ui.geometry.Rect
@@ -25,13 +44,25 @@ import androidx.compose.ui.graphics.Color
25
44
  import androidx.compose.ui.graphics.SolidColor
26
45
  import androidx.compose.ui.graphics.graphicsLayer
27
46
  import androidx.compose.ui.input.pointer.pointerInput
28
- import androidx.compose.ui.layout.*
47
+ import androidx.compose.ui.layout.Layout
48
+ import androidx.compose.ui.layout.Measurable
49
+ import androidx.compose.ui.layout.MeasurePolicy
50
+ import androidx.compose.ui.layout.MeasureResult
51
+ import androidx.compose.ui.layout.MeasureScope
52
+ import androidx.compose.ui.layout.Placeable
53
+ import androidx.compose.ui.layout.layoutId
29
54
  import androidx.compose.ui.platform.LocalDensity
30
55
  import androidx.compose.ui.platform.LocalFocusManager
31
56
  import androidx.compose.ui.platform.LocalSoftwareKeyboardController
32
57
  import androidx.compose.ui.text.TextStyle
33
58
  import androidx.compose.ui.text.style.TextOverflow
34
- import androidx.compose.ui.unit.*
59
+ import androidx.compose.ui.unit.Constraints
60
+ import androidx.compose.ui.unit.Dp
61
+ import androidx.compose.ui.unit.IntOffset
62
+ import androidx.compose.ui.unit.LayoutDirection
63
+ import androidx.compose.ui.unit.dp
64
+ import androidx.compose.ui.unit.lerp
65
+ import androidx.compose.ui.unit.sp
35
66
  import kotlinx.coroutines.flow.collectLatest
36
67
  import kotlinx.coroutines.flow.mapNotNull
37
68
  import vn.momo.kits.components.Icon
@@ -41,14 +72,28 @@ import vn.momo.kits.const.Colors
41
72
  import vn.momo.kits.const.Spacing
42
73
  import vn.momo.kits.const.Typography
43
74
  import vn.momo.kits.const.getFontFamily
75
+ import vn.momo.kits.layout.DuoMetrics
76
+ import vn.momo.kits.layout.ScreenLayout
77
+ import vn.momo.kits.layout.SideBarEdge
78
+ import vn.momo.kits.layout.getScreenLayout
79
+ import vn.momo.kits.modifier.hideKeyboardOnTap
80
+ import vn.momo.kits.utils.horizontalSafeAreaPadding
44
81
  import vn.momo.kits.modifier.kitsAutomationId
45
82
  import vn.momo.kits.modifier.noFeedbackClickable
46
83
  import vn.momo.kits.modifier.setAutomationId
47
84
  import vn.momo.kits.navigation.component.headerFontFamily
48
85
  import vn.momo.kits.navigation.component.HEADER_HEIGHT
86
+ import vn.momo.kits.navigation.component.HeaderColor
87
+ import vn.momo.kits.navigation.component.LocalHeaderColor
88
+ import vn.momo.kits.navigation.component.HeaderRight
89
+ import vn.momo.kits.navigation.component.SideBarButton
90
+ import vn.momo.kits.navigation.component.TitlePosition
91
+ import vn.momo.kits.navigation.component.ToolGroup
92
+ import vn.momo.kits.navigation.component.Toolkit
49
93
  import vn.momo.kits.utils.getAppStatusBarHeight
50
94
  import kotlin.math.max
51
95
  import kotlin.math.roundToInt
96
+ import vn.momo.kits.navigation.component.getHeaderColor as getNavigationHeaderColor
52
97
 
53
98
 
54
99
  data class AnimationOption(
@@ -73,6 +118,30 @@ data class AnimationOption(
73
118
 
74
119
  val LocalAnimationOption = staticCompositionLocalOf<AnimationOption?> { null }
75
120
 
121
+ // LiteScreen's own header kinds; StackScreen uses the sealed navigation.component.HeaderType.
122
+ enum class HeaderType {
123
+ DEFAULT,
124
+ EXTENDED,
125
+ NONE
126
+ }
127
+
128
+ @Stable
129
+ data class HeaderRightData(
130
+ val useShortcut: Boolean = false,
131
+ val useMore: Boolean = false,
132
+ val useSystemTools: Boolean = true,
133
+ val tools: List<ToolGroup> = emptyList(),
134
+ val toolCallback: ((String) -> Unit)? = { _ -> }
135
+ ) {
136
+ internal fun toToolkit() = HeaderRight.Toolkit(
137
+ useShortcut = useShortcut,
138
+ useMore = useMore,
139
+ useSystemTools = useSystemTools,
140
+ tools = tools,
141
+ toolCallback = toolCallback,
142
+ )
143
+ }
144
+
76
145
  @Composable
77
146
  fun LiteScreen(
78
147
  scrollable: Boolean = true,
@@ -169,6 +238,8 @@ private fun LiteScreenLayout(
169
238
  content: @Composable () -> Unit,
170
239
  ) {
171
240
  val statusBarHeight = getAppStatusBarHeight()
241
+ val screenLayout = getScreenLayout()
242
+ val applySafeAreaPadding = screenLayout.sideBar != null
172
243
  val isHeaderNone = remember(headerType) {
173
244
  headerType == HeaderType.NONE
174
245
  }
@@ -204,18 +275,16 @@ private fun LiteScreenLayout(
204
275
  borderColor = Colors.black_20.copy(alpha = 0.2f)
205
276
  )
206
277
  }
278
+ val toolkit = remember(headerRightData) { (headerRightData ?: HeaderRightData()).toToolkit() }
207
279
 
208
- val scrollPercentage = produceState(
209
- initialValue = 0f,
210
- key1 = useAnimationSearch,
211
- key2 = scrollState,
212
- key3 = backgroundHeight,
213
- ) {
214
- if (!useAnimationSearch) return@produceState
215
- scrollState ?: return@produceState
216
- val rangePx = with(density) { backgroundHeight.toPx() }
217
- snapshotFlow { scrollState.value }.collectLatest {
218
- value = (it / rangePx).coerceIn(0f, 1f)
280
+ val scrollPercentage = remember(useAnimationSearch, scrollState, backgroundHeight, density) {
281
+ derivedStateOf {
282
+ if (!useAnimationSearch || scrollState == null) {
283
+ 0f
284
+ } else {
285
+ val rangePx = with(density) { backgroundHeight.toPx() }
286
+ (scrollState.value / rangePx).coerceIn(0f, 1f)
287
+ }
219
288
  }
220
289
  }
221
290
 
@@ -230,6 +299,12 @@ private fun LiteScreenLayout(
230
299
  val animationOpacityModifier = Modifier.graphicsLayer {
231
300
  alpha = animationOption?.animateOpacity ?: 1f
232
301
  }
302
+ val sideBarColor = getNavigationHeaderColor(
303
+ vn.momo.kits.navigation.component.HeaderType.Default(),
304
+ 1f,
305
+ null,
306
+ Colors.black_17,
307
+ )
233
308
  val titleModifier = Modifier
234
309
  .kitsAutomationId("title_navigation_header")
235
310
  .layoutId(HeaderId.TITLE_ID)
@@ -241,6 +316,8 @@ private fun LiteScreenLayout(
241
316
  }
242
317
 
243
318
  val policy = remember(
319
+ screenLayout,
320
+ applySafeAreaPadding,
244
321
  useAnimationSearch,
245
322
  isHeaderNone,
246
323
  isHeaderExtend,
@@ -253,6 +330,8 @@ private fun LiteScreenLayout(
253
330
  horizontalAlignment,
254
331
  ) {
255
332
  LiteScreenLayoutPolicy(
333
+ screenLayout = screenLayout,
334
+ applySafeAreaPadding = applySafeAreaPadding,
256
335
  useAnimationSearch = useAnimationSearch,
257
336
  isHeaderNone = isHeaderNone,
258
337
  isHeaderExtend = isHeaderExtend,
@@ -267,13 +346,13 @@ private fun LiteScreenLayout(
267
346
  }
268
347
 
269
348
  Layout(
270
- modifier = modifier
271
- .animateContentSize(),
349
+ modifier = modifier,
272
350
  content = {
273
351
  Box(
274
352
  modifier = animationOpacityModifier
275
353
  .layoutId(HeaderId.CONTENT_ID)
276
- .then(contentModifier),
354
+ .then(contentModifier)
355
+ .then(if (applySafeAreaPadding) Modifier.horizontalSafeAreaPadding() else Modifier),
277
356
  contentAlignment = Alignment.TopCenter,
278
357
  ) {
279
358
  content()
@@ -284,53 +363,71 @@ private fun LiteScreenLayout(
284
363
  modifier = Modifier
285
364
  .layoutId(HeaderId.BACKGROUND_ID)
286
365
  .then(animationOpacityModifier)
287
- .drawBehind {
288
- val headerHeight = max(
289
- HeaderId.EXTENDED_HEADER_HEIGHT.toPx(),
290
- size.height,
291
- )
292
- headerBackgroundColor?.let {
293
- drawRect(color = it)
294
- } ?: run {
295
- drawRect(color = Colors.black_01)
296
- drawRect(
297
- brush = Brush.linearGradient(
298
- colors = listGradientColors,
299
- start = Offset.Zero,
300
- end = Offset(
301
- x = 0f,
302
- y = headerHeight * (1 - scrollPercentage.value),
303
- ),
304
- )
366
+ .drawWithCache {
367
+ if (headerBackgroundColor != null) {
368
+ val backgroundColor = headerBackgroundColor
369
+ onDrawBehind { drawRect(color = backgroundColor) }
370
+ } else {
371
+ val headerHeight = max(
372
+ HeaderId.EXTENDED_HEADER_HEIGHT.toPx(),
373
+ size.height,
374
+ )
375
+ val gradientBrush = Brush.linearGradient(
376
+ colors = listGradientColors,
377
+ start = Offset.Zero,
378
+ end = Offset(
379
+ x = 0f,
380
+ y = headerHeight * (1 - scrollPercentage.value),
381
+ ),
305
382
  )
383
+ onDrawBehind {
384
+ drawRect(color = Colors.black_01)
385
+ drawRect(brush = gradientBrush)
386
+ }
306
387
  }
307
388
  },
308
389
  )
309
390
  }
310
391
 
311
392
  if (!isHeaderNone && onGoBack != null) {
312
- val coreModifier = Modifier
313
- .layoutId(HeaderId.BACK_ID)
314
- .then(animationOpacityModifier)
315
- .clip(CircleShape)
316
- .noFeedbackClickable(onClick = onGoBack)
317
- .setAutomationId("btn_navigation_back")
318
- inputSearchProps?.customBackIcon?.invoke(coreModifier) ?: Box(
319
- modifier = coreModifier
320
- .size(28.dp)
321
- .border(
322
- width = 0.2.dp,
323
- color = headerColor.borderColor,
324
- shape = CircleShape,
325
- )
326
- .background(color = headerColor.backgroundButton)
327
- .padding(Spacing.XS),
328
- ) {
329
- Icon(
330
- source = "arrow-back",
331
- color = headerColor.tintIconColor,
332
- size = 20.dp,
333
- )
393
+ when {
394
+ screenLayout.sideBar != null || screenLayout.statusBarClearance != null -> {
395
+ Box(
396
+ modifier = Modifier.layoutId(HeaderId.BACK_ID),
397
+ ) {
398
+ SideBarButton(
399
+ icon = "arrow-back",
400
+ headerColor = sideBarColor,
401
+ onClick = onGoBack,
402
+ automationId = "btn_navigation_back",
403
+ )
404
+ }
405
+ }
406
+ else -> {
407
+ val coreModifier = Modifier
408
+ .layoutId(HeaderId.BACK_ID)
409
+ .then(animationOpacityModifier)
410
+ .clip(CircleShape)
411
+ .noFeedbackClickable(onClick = onGoBack)
412
+ .setAutomationId("btn_navigation_back")
413
+ inputSearchProps?.customBackIcon?.invoke(coreModifier) ?: Box(
414
+ modifier = coreModifier
415
+ .size(28.dp)
416
+ .border(
417
+ width = 0.2.dp,
418
+ color = headerColor.borderColor,
419
+ shape = CircleShape,
420
+ )
421
+ .background(color = headerColor.backgroundButton)
422
+ .padding(Spacing.XS),
423
+ ) {
424
+ Icon(
425
+ source = "arrow-back",
426
+ color = headerColor.tintIconColor,
427
+ size = 20.dp,
428
+ )
429
+ }
430
+ }
334
431
  }
335
432
  }
336
433
 
@@ -341,11 +438,14 @@ private fun LiteScreenLayout(
341
438
  .then(animationOpacityModifier)
342
439
  ) {
343
440
  if (headerRight != null) {
344
- headerRight()
441
+ CompositionLocalProvider(LocalHeaderColor provides headerColor) {
442
+ headerRight()
443
+ }
345
444
  } else {
346
- HeaderRight(
347
- headerRight = headerRightData,
445
+ Toolkit(
446
+ headerRight = toolkit,
348
447
  tintColor = tintColor,
448
+ headerColor = headerColor,
349
449
  )
350
450
  }
351
451
  }
@@ -373,7 +473,128 @@ private fun LiteScreenLayout(
373
473
  )
374
474
  }
375
475
 
476
+ private interface LiteScreenGeometry {
477
+ fun MeasureScope.safeWidth(
478
+ screenLayout: ScreenLayout,
479
+ width: Int,
480
+ insetLeft: Int,
481
+ insetRight: Int,
482
+ ): Int
483
+
484
+ fun MeasureScope.searchStartX(
485
+ screenLayout: ScreenLayout,
486
+ insetLeft: Int,
487
+ spacing: Int,
488
+ ): Int
489
+
490
+ fun MeasureScope.headerHeight(screenLayout: ScreenLayout, statusBar: Int, rowHeight: Int): Int
491
+ fun MeasureScope.headerRightStartX(
492
+ screenLayout: ScreenLayout,
493
+ width: Int,
494
+ insetRight: Int,
495
+ spacing: Int,
496
+ rightWidth: Int,
497
+ ): Int
498
+
499
+ fun MeasureScope.collapsedHeaderHeight(screenLayout: ScreenLayout, statusBar: Int, rowHeight: Int): Int
500
+
501
+ fun MeasureScope.searchStartY(
502
+ screenLayout: ScreenLayout,
503
+ headerY: Int,
504
+ statusBar: Int,
505
+ rowHeight: Int,
506
+ ): Int
507
+ }
508
+
509
+ private class StandardPhoneLiteScreenGeometry : LiteScreenGeometry {
510
+ override fun MeasureScope.safeWidth(
511
+ screenLayout: ScreenLayout,
512
+ width: Int,
513
+ insetLeft: Int,
514
+ insetRight: Int,
515
+ ) = (width - insetLeft - insetRight).coerceAtLeast(0)
516
+
517
+ override fun MeasureScope.searchStartX(screenLayout: ScreenLayout, insetLeft: Int, spacing: Int) =
518
+ insetLeft + spacing
519
+
520
+ override fun MeasureScope.headerHeight(screenLayout: ScreenLayout, statusBar: Int, rowHeight: Int) =
521
+ statusBar + rowHeight
522
+ override fun MeasureScope.collapsedHeaderHeight(
523
+ screenLayout: ScreenLayout,
524
+ statusBar: Int,
525
+ rowHeight: Int,
526
+ ) = statusBar + rowHeight
527
+ override fun MeasureScope.headerRightStartX(
528
+ screenLayout: ScreenLayout,
529
+ width: Int,
530
+ insetRight: Int,
531
+ spacing: Int,
532
+ rightWidth: Int,
533
+ ) = width - insetRight - spacing - rightWidth
534
+
535
+ override fun MeasureScope.searchStartY(
536
+ screenLayout: ScreenLayout,
537
+ headerY: Int,
538
+ statusBar: Int,
539
+ rowHeight: Int,
540
+ ) = headerY + statusBar
541
+ }
542
+
543
+ private class IPhoneDuoLiteScreenGeometry : LiteScreenGeometry {
544
+ override fun MeasureScope.safeWidth(
545
+ screenLayout: ScreenLayout,
546
+ width: Int,
547
+ insetLeft: Int,
548
+ insetRight: Int,
549
+ ): Int {
550
+ val clearance = screenLayout.statusBarClearance
551
+ return (
552
+ width - insetLeft - insetRight -
553
+ (clearance?.left?.roundToPx() ?: 0) -
554
+ (clearance?.right?.roundToPx() ?: 0)
555
+ ).coerceAtLeast(0)
556
+ }
557
+
558
+ override fun MeasureScope.searchStartX(screenLayout: ScreenLayout, insetLeft: Int, spacing: Int) =
559
+ insetLeft + (screenLayout.statusBarClearance?.left?.roundToPx() ?: 0) + spacing
560
+
561
+ override fun MeasureScope.headerHeight(screenLayout: ScreenLayout, statusBar: Int, rowHeight: Int): Int {
562
+ val rowTop = screenLayout.headerStatusBarHeight +
563
+ (screenLayout.headerBarHeight - rowHeight.toDp()) / 2
564
+ return max(screenLayout.headerHeight.roundToPx(), rowTop.roundToPx() + rowHeight)
565
+ }
566
+ override fun MeasureScope.collapsedHeaderHeight(
567
+ screenLayout: ScreenLayout,
568
+ statusBar: Int,
569
+ rowHeight: Int,
570
+ ) = (
571
+ screenLayout.headerStatusBarHeight +
572
+ (screenLayout.headerBarHeight - rowHeight.toDp()) / 2
573
+ ).roundToPx() + rowHeight
574
+ override fun MeasureScope.headerRightStartX(
575
+ screenLayout: ScreenLayout,
576
+ width: Int,
577
+ insetRight: Int,
578
+ spacing: Int,
579
+ rightWidth: Int,
580
+ ) = width - insetRight -
581
+ (screenLayout.statusBarClearance?.right?.roundToPx() ?: 0) -
582
+ spacing - rightWidth
583
+
584
+ override fun MeasureScope.searchStartY(
585
+ screenLayout: ScreenLayout,
586
+ headerY: Int,
587
+ statusBar: Int,
588
+ rowHeight: Int,
589
+ ) = headerY + (
590
+ screenLayout.headerStatusBarHeight +
591
+ (screenLayout.headerBarHeight - rowHeight.toDp()) / 2
592
+ ).roundToPx()
593
+ }
594
+
376
595
  private class LiteScreenLayoutPolicy(
596
+ private val screenLayout: ScreenLayout,
597
+ private val applySafeAreaPadding: Boolean,
377
598
  private val useAnimationSearch: Boolean,
378
599
  private val isHeaderNone: Boolean,
379
600
  private val isHeaderExtend: Boolean,
@@ -385,6 +606,11 @@ private class LiteScreenLayoutPolicy(
385
606
  private val verticalArrangement: Arrangement.Vertical,
386
607
  private val horizontalAlignment: Alignment.Horizontal,
387
608
  ) : MeasurePolicy {
609
+ private val geometry = if (screenLayout.isIPhoneDuo) {
610
+ IPhoneDuoLiteScreenGeometry()
611
+ } else {
612
+ StandardPhoneLiteScreenGeometry()
613
+ }
388
614
 
389
615
  val searchStartPosition: IntOffset by lazy {
390
616
  if (animationOption == null) return@lazy IntOffset.Zero
@@ -407,11 +633,16 @@ private class LiteScreenLayoutPolicy(
407
633
 
408
634
  val contentMeasurable = measurables.find { it.layoutId == HeaderId.CONTENT_ID }
409
635
 
636
+ val insetLeft = if (applySafeAreaPadding) screenLayout.insetLeft.roundToPx() else 0
637
+ val insetRight = if (applySafeAreaPadding) screenLayout.insetRight.roundToPx() else 0
638
+ val safeLayoutWidth = with(geometry) {
639
+ safeWidth(screenLayout, constraints.maxWidth, insetLeft, insetRight)
640
+ }
641
+ val searchStartX = with(geometry) { searchStartX(screenLayout, insetLeft, spacing12) }
410
642
  val realConstraints = constraints.copy(
411
643
  minWidth = 0,
412
644
  minHeight = 0,
413
- maxWidth = (constraints.maxWidth - spacing12 * 2)
414
- .coerceAtLeast(0),
645
+ maxWidth = (safeLayoutWidth - spacing12 * 2).coerceAtLeast(0),
415
646
  )
416
647
  val backIconPlaceable =
417
648
  measurables.find { it.layoutId == HeaderId.BACK_ID }?.measure(realConstraints)
@@ -421,9 +652,10 @@ private class LiteScreenLayoutPolicy(
421
652
  maxWidth = realConstraints.maxWidth / 2,
422
653
  )
423
654
  )
655
+ val headerBackWidth = if (screenLayout.sideBar == null) backIconPlaceable.safeWidth else 0
424
656
  val baseInputSearchConstraints = if (isHeaderExtend) {
425
657
  val minWidth =
426
- if (useAnimationSearch) realConstraints.maxWidth - backIconPlaceable.safeWidth - headerRightPlaceable.safeWidth - spaceBetween * 2
658
+ if (useAnimationSearch) realConstraints.maxWidth - headerBackWidth - headerRightPlaceable.safeWidth - spaceBetween * 2
427
659
  else realConstraints.maxWidth
428
660
  realConstraints.copy(
429
661
  maxWidth = (realConstraints.maxWidth * (1 - scrollPercent)).toInt()
@@ -431,7 +663,7 @@ private class LiteScreenLayoutPolicy(
431
663
  )
432
664
  } else {
433
665
  var spaceConsumed = 0
434
- if (backIconPlaceable.safeWidth != 0) spaceConsumed += backIconPlaceable.safeWidth + spaceBetween
666
+ if (headerBackWidth != 0) spaceConsumed += headerBackWidth + spaceBetween
435
667
  if (headerRightPlaceable.safeWidth != 0) spaceConsumed += headerRightPlaceable.safeWidth + spaceBetween
436
668
  realConstraints.copy(
437
669
  maxWidth = realConstraints.maxWidth - spaceConsumed
@@ -442,28 +674,34 @@ private class LiteScreenLayoutPolicy(
442
674
  ?.measure(inputSearchConstraints)
443
675
  val titlePlaceable = measurables.find { it.layoutId == HeaderId.TITLE_ID }?.measure(
444
676
  constraints = realConstraints.copy(
445
- maxWidth = realConstraints.maxWidth - backIconPlaceable.safeWidth - headerRightPlaceable.safeWidth - spaceBetween * 2
677
+ maxWidth = realConstraints.maxWidth - headerBackWidth - headerRightPlaceable.safeWidth - spaceBetween * 2
446
678
  )
447
679
  )
448
680
 
449
681
  /**
450
682
  * replicate logic from [vn.momo.kits.navigation.component.HeaderBackground]
451
683
  * */
452
- var defaultHeight = statusBarPx + headerRowDefault
684
+ var defaultHeight = with(geometry) { headerHeight(screenLayout, statusBarPx, headerRowDefault) }
453
685
  if (isHeaderExtend) {
454
- defaultHeight = 154.dp.roundToPx()
686
+ defaultHeight = if (screenLayout.isIPhoneDuo) {
687
+ max(defaultHeight, 154.dp.roundToPx())
688
+ } else {
689
+ 154.dp.roundToPx()
690
+ }
455
691
  }
456
692
  val headerHeight = when {
457
693
  isHeaderNone -> statusBarPx
458
694
  !useAnimationSearch && !isHeaderExtend -> defaultHeight
459
695
  else -> {
460
- val collapsableSpace = defaultHeight - statusBarPx - headerRowDefault
696
+ val collapsableSpace = defaultHeight -
697
+ with(geometry) { collapsedHeaderHeight(screenLayout, statusBarPx, headerRowDefault) }
461
698
  (defaultHeight - scrollPercent * collapsableSpace).toInt()
462
699
  }
463
700
  }
464
701
 
465
702
  val layoutWidth = constraints.maxWidth
466
703
  val layoutHeight = constraints.maxHeight
704
+ val backgroundInsetLeft = if (!applySafeAreaPadding && screenLayout.sideBar != null) screenLayout.insetLeft.roundToPx() else 0
467
705
  val contentHeight = (layoutHeight - headerHeight).coerceAtLeast(0)
468
706
  val contentPlaceable = contentMeasurable?.measure(
469
707
  constraints.copy(
@@ -500,8 +738,10 @@ private class LiteScreenLayoutPolicy(
500
738
  ) {
501
739
  val progress = animationOption?.progress?.value ?: 1f
502
740
 
503
- val startX = spacing12
504
- val startY = headerY + statusBarPx
741
+ val startX = searchStartX
742
+ val startY = with(geometry) {
743
+ searchStartY(screenLayout, headerY, statusBarPx, headerRowDefault)
744
+ }
505
745
  var curX = startX
506
746
  var curY = startY
507
747
 
@@ -515,27 +755,46 @@ private class LiteScreenLayoutPolicy(
515
755
  )
516
756
 
517
757
  backgroundPlaceable?.place(
518
- x = 0,
758
+ x = -backgroundInsetLeft,
519
759
  y = headerY,
520
760
  )
521
761
 
522
762
  if (backIconPlaceable != null) {
523
- backIconPlaceable.place(
524
- x = startX,
525
- y = startY + backIconPlaceable.verticalCenterOffset(headerRowDefault),
526
- )
527
- curX += backIconPlaceable.safeWidth + spaceBetween
763
+ val sideBar = screenLayout.sideBar
764
+ if (sideBar == null) {
765
+ backIconPlaceable.place(
766
+ x = startX,
767
+ y = startY + backIconPlaceable.verticalCenterOffset(headerRowDefault),
768
+ )
769
+ curX += backIconPlaceable.safeWidth + spaceBetween
770
+ } else {
771
+ val x = when (sideBar.edge) {
772
+ SideBarEdge.LEFT -> insetLeft - screenLayout.insetLeft.roundToPx() + sideBar.width.roundToPx() - spacing12 - backIconPlaceable.width
773
+ SideBarEdge.RIGHT -> layoutWidth + (if (applySafeAreaPadding) 0 else screenLayout.insetRight.roundToPx()) - sideBar.width.roundToPx() + spacing12
774
+ }
775
+ backIconPlaceable.place(
776
+ x = x,
777
+ y = sideBar.top.roundToPx() + (DuoMetrics.controlSize.roundToPx() - backIconPlaceable.height) / 2,
778
+ )
779
+ }
528
780
  }
529
-
530
781
  headerRightPlaceable?.place(
531
- x = layoutWidth - spacing12 - headerRightPlaceable.safeWidth,
782
+ x = with(geometry) {
783
+ headerRightStartX(
784
+ screenLayout,
785
+ layoutWidth,
786
+ insetRight,
787
+ spacing12,
788
+ headerRightPlaceable.safeWidth,
789
+ )
790
+ },
532
791
  y = startY + headerRightPlaceable.verticalCenterOffset(headerRowDefault),
533
792
  )
534
793
 
535
794
  val titleOffset = IntOffset(
536
795
  x = if (titlePosition == TitlePosition.LEFT) curX
537
- else titlePlaceable.horizontalCenterOffset(
538
- space = layoutWidth,
796
+ else searchStartX - spacing12 + titlePlaceable.horizontalCenterOffset(
797
+ space = safeLayoutWidth - spacing12 * 2,
539
798
  layoutDirection = layoutDirection,
540
799
  ),
541
800
  y = startY + titlePlaceable.verticalCenterOffset(headerRowDefault),
@@ -543,7 +802,7 @@ private class LiteScreenLayoutPolicy(
543
802
 
544
803
  titlePlaceable?.place(titleOffset)
545
804
 
546
- if (backIconPlaceable != null || headerRightPlaceable != null || titlePlaceable != null) {
805
+ if ((backIconPlaceable != null && screenLayout.sideBar == null) || headerRightPlaceable != null || titlePlaceable != null) {
547
806
  curY += headerRowDefault
548
807
  }
549
808
 
@@ -553,7 +812,7 @@ private class LiteScreenLayoutPolicy(
553
812
  startY + inputSearchPlaceable.verticalCenterOffset(headerRowDefault)
554
813
  )
555
814
  IntOffset(
556
- x = startX + ((backIconPlaceable.safeWidth + spaceBetween) * (scrollPercent * 2f).coerceIn(
815
+ x = startX + ((headerBackWidth + spaceBetween) * (scrollPercent * 2f).coerceIn(
557
816
  0f, 1f
558
817
  )).toInt(),
559
818
  y = y,
@@ -686,11 +945,8 @@ private fun LiteInputSearch(
686
945
  val interactionSource = remember { MutableInteractionSource() }
687
946
  val textState by remember { inputSearchProps.textFieldState }
688
947
 
689
- val isShowBtnText by remember(inputSearchProps.isShowBtnText, inputSearchProps.btnText) {
690
- derivedStateOf {
691
- inputSearchProps.isShowBtnText && !inputSearchProps.btnText.isNullOrEmpty()
692
- }
693
- }
948
+ val isShowBtnText = inputSearchProps.isShowBtnText &&
949
+ !inputSearchProps.btnText.isNullOrEmpty()
694
950
  val inputFieldFontFamily = getFontFamily(theme.font, Typography.bodyDefaultRegular.fontWeight)
695
951
  val inputFieldStyle = remember(theme, inputFieldFontFamily) {
696
952
  Typography.bodyDefaultRegular.copy(
@@ -732,12 +988,8 @@ private fun LiteInputSearch(
732
988
  inputSearchProps.clearCondition?.invoke() == true || (isFocused.value && textState.isNotEmpty())
733
989
  }
734
990
  }
735
- val placeHolder by produceState<String?>(null, inputSearchProps.placeHolder) {
736
- if (inputSearchProps.placeHolder.isNullOrEmpty()) return@produceState
737
- snapshotFlow { textState }.collectLatest {
738
- value = if (it.isEmpty()) inputSearchProps.placeHolder else null
739
- }
740
- }
991
+ val placeHolder = inputSearchProps.placeHolder
992
+ ?.takeIf { textState.isEmpty() }
741
993
  val iconRightModifier = remember {
742
994
  Modifier
743
995
  .padding(start = Spacing.L)
@@ -780,7 +1032,7 @@ private fun LiteInputSearch(
780
1032
  ) {
781
1033
  if (!placeHolder.isNullOrEmpty()) {
782
1034
  inputSearchProps.customPlaceHolder?.invoke() ?: Text(
783
- text = placeHolder ?: "",
1035
+ text = placeHolder,
784
1036
  style = inputSearchProps.customTextStyle
785
1037
  ?: Typography.bodyDefaultRegular,
786
1038
  maxLines = 1,
@@ -808,7 +1060,7 @@ private fun LiteInputSearch(
808
1060
 
809
1061
  if (isShowBtnText) {
810
1062
  Text(
811
- text = inputSearchProps.btnText ?: "",
1063
+ text = inputSearchProps.btnText,
812
1064
  style = Typography.actionDefaultBold,
813
1065
  color = theme.colors.text.default,
814
1066
  modifier = Modifier.padding(start = Spacing.L)
@@ -817,15 +1069,3 @@ private fun LiteInputSearch(
817
1069
  }
818
1070
  }
819
1071
  }
820
-
821
- fun Modifier.hideKeyboardOnTap() = composed {
822
- val focusManager = LocalFocusManager.current
823
- val keyboardManager = LocalSoftwareKeyboardController.current
824
-
825
- pointerInput(Unit) {
826
- detectTapGestures {
827
- keyboardManager?.hide()
828
- focusManager.clearFocus()
829
- }
830
- }
831
- }