@momo-kits/native-kits 0.120.0-navigation.3 → 0.120.0-navigation.4

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.
@@ -170,4 +170,6 @@ val darkTheme = Theme(
170
170
 
171
171
  val AppTheme = staticCompositionLocalOf { defaultTheme }
172
172
 
173
- val AppStatusBar = staticCompositionLocalOf { 0.dp }
173
+ val AppStatusBar = staticCompositionLocalOf { 0.dp }
174
+
175
+ val AppNavigationBar = staticCompositionLocalOf { 0.dp }
@@ -30,6 +30,8 @@ import androidx.compose.ui.unit.dp
30
30
  import kotlinx.coroutines.launch
31
31
  import vn.momo.kits.application.HEADER_HEIGHT
32
32
  import vn.momo.kits.components.Divider
33
+ import vn.momo.kits.const.AppNavigationBar
34
+ import vn.momo.kits.const.AppStatusBar
33
35
  import vn.momo.kits.const.AppTheme
34
36
  import vn.momo.kits.const.Radius
35
37
  import vn.momo.kits.modifier.noFeedbackClickable
@@ -44,9 +46,9 @@ fun BottomSheet(
44
46
  ) {
45
47
  val navigator = LocalNavigator.current
46
48
 
47
- val navigationBarHeight = WindowInsets.systemBars.asPaddingValues().calculateBottomPadding()
48
- val statusBarHeight = WindowInsets.systemBars.asPaddingValues().calculateTopPadding()
49
- val height = if(getPlatformName() == "iOS") getScreenDimensions().height.dp else getScreenDimensions().height.dp + statusBarHeight + navigationBarHeight
49
+ val height = if(getPlatformName() == "iOS")
50
+ getScreenDimensions().height.dp
51
+ else getScreenDimensions().height.dp + AppStatusBar.current + AppNavigationBar.current
50
52
  val screenHeight = with(LocalDensity.current) { height.toPx() }
51
53
  val sheetOffset = remember { Animatable(screenHeight) }
52
54
 
@@ -1,5 +1,6 @@
1
1
  package vn.momo.kits.navigation
2
2
 
3
+ import androidx.compose.foundation.ScrollState
3
4
  import androidx.compose.runtime.Composable
4
5
  import androidx.compose.runtime.State
5
6
  import androidx.compose.runtime.mutableStateOf
@@ -12,9 +13,10 @@ import vn.momo.kits.navigation.header.HeaderType
12
13
 
13
14
  class Navigation(
14
15
  val id: Int = -1,
15
- val bottomTabIndex: Int = -1
16
+ val bottomTabIndex: Int = -1,
17
+ val initOptions: NavigationOptions? = null
16
18
  ) {
17
- private val _options = mutableStateOf(NavigationOptions())
19
+ private val _options = mutableStateOf(initOptions ?: NavigationOptions())
18
20
  val currentOptions: State<NavigationOptions> get() = _options
19
21
  val options: NavigationOptions get() = _options.value
20
22
 
@@ -24,7 +26,7 @@ class Navigation(
24
26
  headerTitle: HeaderTitle? = null,
25
27
  headerRight: HeaderRight? = null,
26
28
  headerType: HeaderType? = null,
27
- scrollable: Boolean? = null,
29
+ scrollData: ScrollData? = null,
28
30
  backgroundColor: Color? = null,
29
31
  tintColor: Color? = null,
30
32
  footerComponent: (@Composable () -> Unit)? = null,
@@ -36,7 +38,7 @@ class Navigation(
36
38
  headerTitle = headerTitle ?: options.headerTitle,
37
39
  headerRight = headerRight ?: options.headerRight,
38
40
  headerType = headerType ?: options.headerType,
39
- scrollable = scrollable ?: options.scrollable,
41
+ scrollData = scrollData ?: options.scrollData,
40
42
  backgroundColor = backgroundColor ?: options.backgroundColor,
41
43
  tintColor = tintColor ?: options.tintColor,
42
44
  footerComponent = footerComponent ?: options.footerComponent,
@@ -65,8 +67,13 @@ data class NavigationOptions(
65
67
  val headerTitle: HeaderTitle = HeaderTitle.Default("Stack"),
66
68
  val headerRight: HeaderRight = HeaderRight.Toolkit(),
67
69
  val headerType: HeaderType = HeaderType.Default(),
68
- val scrollable: Boolean = true,
70
+ val scrollData: ScrollData = ScrollData(),
69
71
  val backgroundColor: Color? = null,
70
72
  val tintColor: Color? = null,
71
73
  val footerComponent: @Composable (() -> Unit)? = null,
74
+ )
75
+
76
+ data class ScrollData(
77
+ val scrollable: Boolean = true,
78
+ val scrollState: ScrollState? = null,
72
79
  )
@@ -1,6 +1,5 @@
1
1
  package vn.momo.kits.navigation
2
2
 
3
- import MeasureRenderTime
4
3
  import androidx.compose.animation.core.tween
5
4
  import androidx.compose.animation.slideInHorizontally
6
5
  import androidx.compose.animation.slideInVertically
@@ -19,9 +18,9 @@ import androidx.navigation.compose.composable
19
18
  import androidx.navigation.compose.dialog
20
19
  import androidx.navigation.compose.rememberNavController
21
20
  import androidx.navigation.toRoute
21
+ import vn.momo.kits.const.AppNavigationBar
22
22
  import vn.momo.kits.const.AppStatusBar
23
23
  import vn.momo.kits.platform.ConfigureDialog
24
- import vn.momo.kits.platform.getStatusBarHeight
25
24
 
26
25
  @Composable
27
26
  fun NavigationContainer(initialScreen: @Composable () -> Unit, initialScreenTitle: String?, options: NavigationOptions? = null){
@@ -32,12 +31,18 @@ fun NavigationContainer(initialScreen: @Composable () -> Unit, initialScreenTitl
32
31
  } else {
33
32
  AppStatusBar.current
34
33
  }
34
+ val navigationBarHeight = if (AppNavigationBar.current == 0.dp) {
35
+ WindowInsets.systemBars.asPaddingValues().calculateBottomPadding()
36
+ } else {
37
+ AppNavigationBar.current
38
+ }
35
39
 
36
40
  val startDestination = DynamicScreenRegistry.register(initialScreen, initialScreenTitle, options)
37
41
 
38
42
  CompositionLocalProvider(
39
43
  LocalNavigator provides navigator,
40
44
  AppStatusBar provides statusBarHeight,
45
+ AppNavigationBar provides navigationBarHeight,
41
46
  ) {
42
47
  NavHost(navController, startDestination = startDestination) {
43
48
  composable<DynamicScreenRoute>(
@@ -60,13 +65,12 @@ fun NavigationContainer(initialScreen: @Composable () -> Unit, initialScreenTitl
60
65
  val screen = DynamicScreenRegistry.getScreen(route.id)
61
66
 
62
67
  if (screen != null){
63
- MeasureRenderTime(route.title ?: "StackScreen${route.id}") {
64
- StackScreen(
65
- id = route.id,
66
- content = screen.content,
67
- navigationOptions = screen.options
68
- )
69
- }
68
+ StackScreen(
69
+ id = route.id,
70
+ title = route.title,
71
+ content = screen.content,
72
+ navigationOptions = screen.options
73
+ )
70
74
  }
71
75
  }
72
76
 
@@ -90,13 +94,12 @@ fun NavigationContainer(initialScreen: @Composable () -> Unit, initialScreenTitl
90
94
  val screen = DynamicScreenRegistry.getScreen(route.id)
91
95
 
92
96
  if (screen != null){
93
- MeasureRenderTime(route.title ?: "StackScreen${route.id}") {
94
- StackScreen(
95
- id = route.id,
96
- content = screen.content,
97
- navigationOptions = screen.options
98
- )
99
- }
97
+ StackScreen(
98
+ id = route.id,
99
+ title = route.title,
100
+ content = screen.content,
101
+ navigationOptions = screen.options
102
+ )
100
103
  }
101
104
  }
102
105
 
@@ -111,13 +114,9 @@ fun NavigationContainer(initialScreen: @Composable () -> Unit, initialScreenTitl
111
114
  if (screen != null){
112
115
  ConfigureDialog()
113
116
  if (route.isBottomSheet){
114
- MeasureRenderTime(route.title ?: "BottomSheet${route.id}") {
115
- BottomSheet(screen.content, screen.onDismiss)
116
- }
117
+ BottomSheet(screen.content, screen.onDismiss)
117
118
  } else {
118
- MeasureRenderTime(route.title ?: "ModalScreen${route.id}") {
119
- ModalScreen(screen.content, screen.onDismiss)
120
- }
119
+ ModalScreen(screen.content, screen.onDismiss)
121
120
  }
122
121
  }
123
122
  }
@@ -48,7 +48,7 @@ class Navigator(
48
48
 
49
49
  fun showBottomSheet(content: @Composable () -> Unit, title : String? = null, onDismiss: (() -> Unit)? = null){
50
50
  val route = DynamicScreenRegistry.registerModal(content, title, onDismiss)
51
- navController.navigate(DynamicModalRoute(route.id, title, isBottomSheet = true))
51
+ navController.navigate(DynamicModalRoute(route.id, route.title, isBottomSheet = true))
52
52
  }
53
53
  }
54
54
 
@@ -57,16 +57,17 @@ val LocalNavigator = staticCompositionLocalOf<Navigator> {
57
57
  }
58
58
 
59
59
  @Serializable
60
- data class DynamicScreenRoute(val id: Int, val title: String?)
60
+ data class DynamicScreenRoute(val id: Int, val title: String)
61
61
 
62
62
  @Serializable
63
- data class DynamicDialogRoute(val id: Int, val title: String?)
63
+ data class DynamicDialogRoute(val id: Int, val title: String)
64
64
 
65
65
  @Serializable
66
- data class DynamicModalRoute(val id: Int, val title: String?, val isBottomSheet: Boolean = false)
66
+ data class DynamicModalRoute(val id: Int, val title: String, val isBottomSheet: Boolean = false)
67
67
 
68
68
  data class DynamicScreen(
69
69
  val id: Int,
70
+ val title: String,
70
71
  val content: @Composable () -> Unit,
71
72
  val onDismiss: (() -> Unit)? = null,
72
73
  var options: NavigationOptions? = null
@@ -79,14 +80,17 @@ object DynamicScreenRegistry {
79
80
 
80
81
  fun register(content: @Composable () -> Unit, title: String?, options: NavigationOptions?): DynamicScreenRoute {
81
82
  val id = idCounter++
83
+ val screenTitle = title ?: "StackScreen$id"
82
84
  screens.add(
83
85
  DynamicScreen(
84
86
  id = id,
87
+ title = screenTitle,
85
88
  content = content,
86
89
  options = options
87
90
  )
88
91
  )
89
- return DynamicScreenRoute(id, title)
92
+
93
+ return DynamicScreenRoute(id, screenTitle)
90
94
  }
91
95
 
92
96
  fun registerModal(
@@ -95,8 +99,14 @@ object DynamicScreenRegistry {
95
99
  onDismiss: (() -> Unit)?
96
100
  ): DynamicModalRoute {
97
101
  val id = idCounter++
98
- screens.add(DynamicScreen(id, content, onDismiss))
99
- return DynamicModalRoute(id, title)
102
+ val modalTitle = title ?: "ModalScreen$id"
103
+ screens.add(DynamicScreen(
104
+ id = id,
105
+ title = modalTitle,
106
+ content = content,
107
+ onDismiss = onDismiss
108
+ ))
109
+ return DynamicModalRoute(id, modalTitle)
100
110
  }
101
111
 
102
112
  fun unregister() {
@@ -8,19 +8,17 @@ import androidx.compose.foundation.background
8
8
  import androidx.compose.foundation.layout.Box
9
9
  import androidx.compose.foundation.layout.Column
10
10
  import androidx.compose.foundation.layout.Spacer
11
- import androidx.compose.foundation.layout.WindowInsets
12
- import androidx.compose.foundation.layout.asPaddingValues
13
11
  import androidx.compose.foundation.layout.aspectRatio
14
12
  import androidx.compose.foundation.layout.fillMaxSize
15
13
  import androidx.compose.foundation.layout.fillMaxWidth
16
14
  import androidx.compose.foundation.layout.height
17
15
  import androidx.compose.foundation.layout.offset
18
16
  import androidx.compose.foundation.layout.padding
19
- import androidx.compose.foundation.layout.systemBars
20
17
  import androidx.compose.foundation.rememberScrollState
21
18
  import androidx.compose.foundation.verticalScroll
22
19
  import androidx.compose.runtime.Composable
23
20
  import androidx.compose.runtime.CompositionLocalProvider
21
+ import androidx.compose.runtime.DisposableEffect
24
22
  import androidx.compose.runtime.LaunchedEffect
25
23
  import androidx.compose.runtime.getValue
26
24
  import androidx.compose.runtime.remember
@@ -32,13 +30,16 @@ import androidx.compose.ui.graphics.lerp
32
30
  import androidx.compose.ui.platform.LocalDensity
33
31
  import androidx.compose.ui.unit.Dp
34
32
  import androidx.compose.ui.unit.dp
33
+ import androidx.compose.ui.unit.min
35
34
  import androidx.compose.ui.zIndex
36
35
  import kotlinx.coroutines.delay
37
36
  import vn.momo.kits.components.InputSearch
37
+ import vn.momo.kits.const.AppNavigationBar
38
38
  import vn.momo.kits.const.AppStatusBar
39
39
  import vn.momo.kits.const.AppTheme
40
40
  import vn.momo.kits.const.Colors
41
41
  import vn.momo.kits.const.Spacing
42
+ import vn.momo.kits.modifier.conditional
42
43
  import vn.momo.kits.navigation.header.Header
43
44
  import vn.momo.kits.navigation.header.HeaderBackground
44
45
  import vn.momo.kits.navigation.header.HeaderRight
@@ -55,15 +56,16 @@ fun StackScreen(
55
56
  content: @Composable () -> Unit,
56
57
  navigationOptions: NavigationOptions? = null,
57
58
  id: Int = -1,
59
+ title: String = "",
58
60
  bottomTabIndex: Int = -1,
59
61
  ) {
60
62
  val navigator = LocalNavigator.current
61
- val navigation = remember { Navigation(id = id, bottomTabIndex = bottomTabIndex) }
62
- val scrollState = rememberScrollState()
63
+ val navigation = remember { Navigation(id = id, bottomTabIndex = bottomTabIndex, initOptions = navigationOptions) }
63
64
 
64
- navigationOptions?.let { LaunchedEffect(Unit){ navigation.setOptions(navigationOptions) } }
65
65
  val options by navigation.currentOptions
66
66
 
67
+ val scrollState = options.scrollData.scrollState ?: rememberScrollState()
68
+
67
69
  val backgroundColor = options.backgroundColor ?: AppTheme.current.colors.background.default
68
70
  val inputSearchType = when (val headerType = options.headerType) {
69
71
  is HeaderType.DefaultOrExtended -> when {
@@ -120,7 +122,13 @@ fun StackScreen(
120
122
 
121
123
  Column(Modifier.zIndex(2f).fillMaxSize()) {
122
124
  Spacer(Modifier.height(if (options.headerType is HeaderType.DefaultOrExtended) AppStatusBar.current + HEADER_HEIGHT.dp else 0.dp))
123
- Column(Modifier.fillMaxWidth().weight(1f).verticalScroll(scrollState)){
125
+ Column (Modifier
126
+ .fillMaxWidth()
127
+ .weight(1f)
128
+ .conditional(options.scrollData.scrollable) {
129
+ verticalScroll(scrollState)
130
+ }
131
+ ){
124
132
  if (inputSearchType == InputSearchType.Animated) Spacer(Modifier.height(HEADER_HEIGHT.dp))
125
133
  renderContent(
126
134
  content = content,
@@ -130,7 +138,6 @@ fun StackScreen(
130
138
  }
131
139
  Footer(options.footerComponent)
132
140
  }
133
-
134
141
  }
135
142
  }
136
143
  }
@@ -138,7 +145,7 @@ fun StackScreen(
138
145
  @Composable
139
146
  fun renderContent(content: @Composable () -> Unit, scrollState: ScrollState, options: NavigationOptions){
140
147
  if (options.headerType is HeaderType.Animated){
141
- val animatedHeader = options.headerType as HeaderType.Animated
148
+ val animatedHeader = options.headerType
142
149
  Box {
143
150
  Box(Modifier.fillMaxWidth().aspectRatio(animatedHeader.aspectRatio.value)){
144
151
  animatedHeader.composable.invoke(scrollState.value)
@@ -155,13 +162,12 @@ fun renderContent(content: @Composable () -> Unit, scrollState: ScrollState, opt
155
162
  @Composable
156
163
  fun Footer(footerComponent: @Composable (() -> Unit)?) {
157
164
  if (footerComponent == null) return
158
- val navigationBarHeight = WindowInsets.systemBars.asPaddingValues().calculateBottomPadding()
159
165
 
160
166
  Box {
161
167
  Box(Modifier
162
168
  .fillMaxWidth()
163
169
  .background(AppTheme.current.colors.background.surface)
164
- .padding(top = Spacing.S, start = Spacing.S, end = Spacing.S, bottom = navigationBarHeight + if(getPlatformName() == "iOS") (-4).dp else 4.dp)
170
+ .padding(top = Spacing.S, start = Spacing.M, end = Spacing.M, bottom = min(AppNavigationBar.current, 21.dp) + Spacing.S)
165
171
  ){
166
172
  footerComponent.invoke()
167
173
  }
@@ -197,7 +203,7 @@ fun renderSearchAnimated(scrollState: ScrollState, inputSearchType: InputSearchT
197
203
  val minEndPadding = Spacing.M
198
204
  val maxEndPadding = when (val headerRight = options.headerRight) {
199
205
  is HeaderRight.Toolkit -> if (headerRight.useShortcut) 114.dp else 78.dp
200
- // TO DO
206
+ is HeaderRight.Custom -> headerRight.width + Spacing.M * 2
201
207
  else -> Spacing.M
202
208
  }
203
209
 
@@ -210,13 +216,14 @@ fun renderSearchAnimated(scrollState: ScrollState, inputSearchType: InputSearchT
210
216
  InputSearchLayoutParams(
211
217
  topPadding = minTopPadding,
212
218
  startPadding = maxStartPadding,
213
- endPadding = minEndPadding,
219
+ endPadding = maxEndPadding,
214
220
  backgroundColor = bgColor
215
221
  )
216
222
  }
217
223
 
218
224
  InputSearchType.Animated -> {
219
- val scrollDp = with(LocalDensity.current) { scrollState.value.toDp() }
225
+ val density = LocalDensity.current
226
+ val scrollDp = with(density) { scrollState.value.toDp() }
220
227
 
221
228
  val animatedTopPadding by animateDpAsState(
222
229
  targetValue = (maxTopPadding - scrollDp).coerceIn(minTopPadding, maxTopPadding),
@@ -240,6 +247,23 @@ fun renderSearchAnimated(scrollState: ScrollState, inputSearchType: InputSearchT
240
247
  )
241
248
  val animatedColor by animateColorAsState(targetValue = targetColor, label = "BackgroundColor")
242
249
 
250
+ val maxPadding = maxOf(maxEndPadding, maxStartPadding, maxTopPadding)
251
+ LaunchedEffect(scrollState.isScrollInProgress) {
252
+ if (scrollDp < maxPadding) {
253
+ if (!scrollState.isScrollInProgress) {
254
+ val midpoint = (maxTopPadding - minTopPadding) / 2
255
+ val currentScrollDp = with(density) { scrollState.value.toDp() }
256
+
257
+ if (currentScrollDp < midpoint) {
258
+ scrollState.animateScrollTo(0)
259
+ } else {
260
+ val snapScrollValue = with(density) { maxPadding.toPx().toInt() }
261
+ scrollState.animateScrollTo(snapScrollValue)
262
+ }
263
+ }
264
+ }
265
+ }
266
+
243
267
  InputSearchLayoutParams(
244
268
  topPadding = animatedTopPadding,
245
269
  startPadding = animatedStartPadding,
@@ -9,19 +9,23 @@ import androidx.compose.foundation.background
9
9
  import androidx.compose.foundation.layout.Box
10
10
  import androidx.compose.foundation.layout.Column
11
11
  import androidx.compose.foundation.layout.Spacer
12
- import androidx.compose.foundation.layout.WindowInsets
13
- import androidx.compose.foundation.layout.asPaddingValues
12
+ import androidx.compose.foundation.layout.fillMaxSize
14
13
  import androidx.compose.foundation.layout.fillMaxWidth
15
14
  import androidx.compose.foundation.layout.height
16
- import androidx.compose.foundation.layout.systemBars
15
+ import androidx.compose.foundation.layout.padding
17
16
  import androidx.compose.runtime.Composable
18
17
  import androidx.compose.runtime.LaunchedEffect
18
+ import androidx.compose.ui.Alignment
19
19
  import androidx.compose.ui.Modifier
20
20
  import androidx.compose.ui.unit.dp
21
+ import androidx.compose.ui.unit.min
21
22
  import androidx.navigation.compose.NavHost
22
23
  import androidx.navigation.compose.composable
23
24
  import androidx.navigation.compose.rememberNavController
25
+ import vn.momo.kits.const.AppNavigationBar
26
+ import vn.momo.kits.const.AppStatusBar
24
27
  import vn.momo.kits.const.AppTheme
28
+ import vn.momo.kits.const.Spacing
25
29
  import vn.momo.kits.navigation.LocalNavigation
26
30
  import vn.momo.kits.navigation.NavigationOptions
27
31
  import vn.momo.kits.navigation.StackScreen
@@ -49,9 +53,6 @@ fun BottomTab(
49
53
  val navigation = LocalNavigation.current
50
54
  val navController = rememberNavController()
51
55
 
52
- val navigationBarHeight = WindowInsets.systemBars.asPaddingValues().calculateBottomPadding()
53
- val statusBarHeight = WindowInsets.systemBars.asPaddingValues().calculateTopPadding()
54
-
55
56
  bottomTabOptionItems = items.map { it.options }.toMutableList()
56
57
 
57
58
  LaunchedEffect(Unit){
@@ -61,12 +62,12 @@ fun BottomTab(
61
62
  }
62
63
  val height = if(getPlatformName() == "iOS")
63
64
  getScreenDimensions().height.dp
64
- else getScreenDimensions().height.dp + statusBarHeight + navigationBarHeight
65
+ else getScreenDimensions().height.dp + AppStatusBar.current + AppNavigationBar.current
65
66
 
66
- Column(modifier = Modifier.fillMaxWidth().height(height)) {
67
+ Box(modifier = Modifier.fillMaxWidth().height(height), contentAlignment = Alignment.BottomCenter) {
67
68
  Box(modifier = Modifier
68
- .fillMaxWidth()
69
- .weight(1f)
69
+ .fillMaxSize()
70
+ .padding(bottom = BOTTOM_TAB_BAR_HEIGHT.dp + AppNavigationBar.current)
70
71
  ) {
71
72
  NavHost(
72
73
  navController = navController,
@@ -115,25 +116,28 @@ fun BottomTab(
115
116
  StackScreen(
116
117
  content = item.screen,
117
118
  navigationOptions = option,
118
- bottomTabIndex = index
119
+ bottomTabIndex = index,
120
+ title = "BottomTabItem$index"
119
121
  )
120
122
  }
121
123
  }
122
124
  }
123
125
  }
124
- BottomTabBar(
125
- items = items,
126
- floatingButton = floatingButton,
127
- navController = navController,
128
- onTabSelected = {
129
- val currentRoute = navController.currentBackStackEntry?.destination?.route
130
- val targetRoute = "option$it"
131
- if (currentRoute != targetRoute){
132
- navController.navigate(targetRoute)
126
+ Column {
127
+ BottomTabBar(
128
+ items = items,
129
+ floatingButton = floatingButton,
130
+ navController = navController,
131
+ onTabSelected = {
132
+ val currentRoute = navController.currentBackStackEntry?.destination?.route
133
+ val targetRoute = "option$it"
134
+ if (currentRoute != targetRoute){
135
+ navController.navigate(targetRoute)
136
+ }
133
137
  }
134
- }
135
- )
136
- Spacer(modifier = Modifier.fillMaxWidth().height(navigationBarHeight + if(getPlatformName() == "iOS") (-4).dp else 4.dp).background(AppTheme.current.colors.background.surface))
138
+ )
139
+ Spacer(modifier = Modifier.fillMaxWidth().height(min(AppNavigationBar.current, 21.dp) + Spacing.S).background(AppTheme.current.colors.background.surface))
140
+ }
137
141
  }
138
142
  }
139
143
 
@@ -43,6 +43,7 @@ import vn.momo.kits.modifier.noFeedbackClickable
43
43
  import vn.momo.kits.platform.getScreenDimensions
44
44
 
45
45
  val floatingButtonWidth = 75.dp
46
+ const val BOTTOM_TAB_BAR_HEIGHT = 56
46
47
 
47
48
  @Composable
48
49
  fun BottomTabBar(
@@ -77,7 +78,7 @@ fun BottomTabBar(
77
78
  Row(
78
79
  modifier = Modifier
79
80
  .fillMaxWidth()
80
- .height(56.dp)
81
+ .height(BOTTOM_TAB_BAR_HEIGHT.dp)
81
82
  .background(AppTheme.current.colors.background.surface),
82
83
  horizontalArrangement = Arrangement.SpaceAround,
83
84
  ) {
@@ -91,7 +92,7 @@ fun BottomTabBar(
91
92
  }
92
93
 
93
94
  Box(modifier = Modifier
94
- .offset(x = indicatorOffsetX, y = (-54).dp)
95
+ .offset(x = indicatorOffsetX, y = (-BOTTOM_TAB_BAR_HEIGHT + 2).dp)
95
96
  .height(2.dp)
96
97
  .width(44.dp)
97
98
  .background(
@@ -103,7 +104,7 @@ fun BottomTabBar(
103
104
  Box(modifier = Modifier
104
105
  .fillMaxWidth()
105
106
  .height(6.dp)
106
- .offset(x = 0.dp, y = (-56).dp)
107
+ .offset(x = 0.dp, y = (-BOTTOM_TAB_BAR_HEIGHT).dp)
107
108
  .background(
108
109
  brush = Brush.verticalGradient(
109
110
  colors = listOf(Color.Transparent, Color.Black.copy(alpha = 0.05f))
@@ -72,10 +72,12 @@ fun Header(
72
72
  )
73
73
  }
74
74
 
75
- renderHeaderContent(options.headerTitle, headerColor.tintIconColor)
76
- if (inputSearchType != InputSearchType.Header) {
77
- HeaderRight(options.headerRight, options.tintColor, headerColor)
78
- }
75
+ renderHeaderContent(
76
+ options.headerTitle,
77
+ headerColor.tintIconColor
78
+ .copy(alpha = if (inputSearchType == InputSearchType.Animated) 1f - animatedAlpha else 1f)
79
+ )
80
+ HeaderRight(options.headerRight, options.tintColor, headerColor)
79
81
  }
80
82
  renderVerticalShadow(opacity)
81
83
  }
@@ -5,6 +5,8 @@ import androidx.compose.foundation.border
5
5
  import androidx.compose.foundation.layout.Arrangement
6
6
  import androidx.compose.foundation.layout.Box
7
7
  import androidx.compose.foundation.layout.Row
8
+ import androidx.compose.foundation.layout.fillMaxHeight
9
+ import androidx.compose.foundation.layout.fillMaxWidth
8
10
  import androidx.compose.foundation.layout.height
9
11
  import androidx.compose.foundation.layout.offset
10
12
  import androidx.compose.foundation.layout.padding
@@ -17,6 +19,7 @@ import androidx.compose.ui.Alignment
17
19
  import androidx.compose.ui.Modifier
18
20
  import androidx.compose.ui.draw.clip
19
21
  import androidx.compose.ui.graphics.Color
22
+ import androidx.compose.ui.unit.Dp
20
23
  import androidx.compose.ui.unit.dp
21
24
  import vn.momo.kits.application.DesignSystemWhiteList
22
25
  import vn.momo.kits.application.Spacing
@@ -35,7 +38,11 @@ fun HeaderRight(
35
38
  ) {
36
39
  when (headerRight) {
37
40
  is HeaderRight.None -> {}
38
- is HeaderRight.Custom -> headerRight.content()
41
+ is HeaderRight.Custom -> {
42
+ Box(Modifier.fillMaxHeight().width(headerRight.width)){
43
+ headerRight.content()
44
+ }
45
+ }
39
46
  is HeaderRight.OnBoarding -> {}
40
47
  is HeaderRight.Toolkit -> {
41
48
  Toolkit(
@@ -148,7 +155,10 @@ fun NavigationButton(
148
155
 
149
156
  sealed interface HeaderRight {
150
157
  data object None : HeaderRight
151
- data class Custom(val content: @Composable () -> Unit) : HeaderRight
158
+ data class Custom(
159
+ val width: Dp,
160
+ val content: @Composable () -> Unit
161
+ ) : HeaderRight
152
162
  data object OnBoarding : HeaderRight
153
163
  data class Toolkit(
154
164
  val useShortcut: Boolean = false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/native-kits",
3
- "version": "0.120.0-navigation.3",
3
+ "version": "0.120.0-navigation.4",
4
4
  "private": false,
5
5
  "dependencies": {},
6
6
  "devDependencies": {},
@@ -1,27 +0,0 @@
1
- import androidx.compose.foundation.layout.Box
2
- import androidx.compose.runtime.Composable
3
- import androidx.compose.runtime.remember
4
- import androidx.compose.ui.Modifier
5
- import androidx.compose.ui.layout.onGloballyPositioned
6
- import kotlinx.datetime.Clock
7
-
8
-
9
- @Composable
10
- fun MeasureRenderTime(
11
- tag: String = "",
12
- content: @Composable () -> Unit
13
- ) {
14
- val startTime = remember { Clock.System.now() }
15
-
16
- Box(
17
- modifier = Modifier.onGloballyPositioned {
18
- val endTime = Clock.System.now()
19
- val duration = (endTime - startTime).inWholeMilliseconds
20
- println("TEST112 [$tag] rendered in $duration ms")
21
- }
22
- ) {
23
- content()
24
- }
25
- }
26
-
27
-