Skip to content

Commit 2e67ab3

Browse files
committed
4
1 parent bc81470 commit 2e67ab3

File tree

3 files changed

+80
-133
lines changed

3 files changed

+80
-133
lines changed

example/src/commonMain/kotlin/UITest.kt

Lines changed: 62 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
1+
import androidx.compose.animation.AnimatedContent
12
import androidx.compose.animation.AnimatedVisibility
23
import androidx.compose.animation.expandHorizontally
34
import androidx.compose.animation.expandVertically
45
import androidx.compose.animation.fadeIn
56
import androidx.compose.animation.fadeOut
67
import androidx.compose.animation.shrinkHorizontally
78
import androidx.compose.animation.shrinkVertically
9+
import androidx.compose.animation.slideInVertically
10+
import androidx.compose.animation.slideOutVertically
811
import androidx.compose.foundation.layout.BoxWithConstraints
12+
import androidx.compose.foundation.layout.Column
913
import androidx.compose.foundation.layout.PaddingValues
14+
import androidx.compose.foundation.layout.Row
1015
import androidx.compose.foundation.layout.WindowInsets
1116
import androidx.compose.foundation.layout.WindowInsetsSides
1217
import androidx.compose.foundation.layout.captionBarPadding
@@ -33,7 +38,6 @@ import androidx.compose.ui.Alignment
3338
import androidx.compose.ui.Alignment.Companion.CenterHorizontally
3439
import androidx.compose.ui.Modifier
3540
import androidx.compose.ui.graphics.Color
36-
import androidx.compose.ui.graphics.vector.ImageVector
3741
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
3842
import androidx.compose.ui.platform.LocalHapticFeedback
3943
import androidx.compose.ui.platform.LocalUriHandler
@@ -43,14 +47,13 @@ import dev.chrisbanes.haze.HazeStyle
4347
import dev.chrisbanes.haze.HazeTint
4448
import dev.chrisbanes.haze.hazeEffect
4549
import dev.chrisbanes.haze.hazeSource
50+
import kotlinx.coroutines.CoroutineScope
4651
import kotlinx.coroutines.launch
4752
import top.yukonga.miuix.kmp.basic.FabPosition
4853
import top.yukonga.miuix.kmp.basic.FloatingActionButton
4954
import top.yukonga.miuix.kmp.basic.FloatingNavigationBar
5055
import top.yukonga.miuix.kmp.basic.FloatingNavigationBarMode
5156
import top.yukonga.miuix.kmp.basic.FloatingToolbar
52-
import top.yukonga.miuix.kmp.basic.FloatingToolbarItem
53-
import top.yukonga.miuix.kmp.basic.FloatingToolbarOrientation
5457
import top.yukonga.miuix.kmp.basic.Icon
5558
import top.yukonga.miuix.kmp.basic.IconButton
5659
import top.yukonga.miuix.kmp.basic.ListPopup
@@ -102,23 +105,12 @@ fun UITest(
102105
val selectedPage by remember { derivedStateOf { pagerState.currentPage } }
103106
val currentScrollBehavior = topAppBarScrollBehaviorList[selectedPage]
104107

105-
106-
@Composable
107-
fun rememberCommonItems(): List<Pair<String, ImageVector>> {
108-
return remember {
109-
listOf(
110-
"HomePage" to MiuixIcons.Useful.NavigatorSwitch,
111-
"DropDown" to MiuixIcons.Useful.Order,
112-
"Settings" to MiuixIcons.Useful.Settings
113-
)
114-
}
115-
}
116-
117-
val navigationItem = rememberCommonItems().map { (label, icon) ->
118-
NavigationItem(label, icon)
119-
}
120-
val floatingToolbarItem = rememberCommonItems().map { (label, icon) ->
121-
FloatingToolbarItem(label, icon)
108+
val navigationItem = remember {
109+
listOf(
110+
NavigationItem("HomePage", MiuixIcons.Useful.NavigatorSwitch),
111+
NavigationItem("DropDown", MiuixIcons.Useful.Order),
112+
NavigationItem("Settings", MiuixIcons.Useful.Settings)
113+
)
122114
}
123115

124116
var uiState by remember { mutableStateOf(UIState()) }
@@ -241,29 +233,35 @@ fun UITest(
241233
floatingToolbar = {
242234
AnimatedVisibility(
243235
visible = uiState.showFloatingToolbar,
244-
enter = fadeIn(),
245-
exit = fadeOut(),
236+
enter = fadeIn() + slideInVertically(initialOffsetY = { it }) + expandVertically(),
237+
exit = fadeOut() + slideOutVertically(targetOffsetY = { it }) + shrinkVertically()
246238
) {
247239
FloatingToolbar(
248-
items = floatingToolbarItem,
249-
selected = selectedPage,
250-
onClick = { index ->
251-
coroutineScope.launch {
252-
pagerState.animateScrollToPage(index)
253-
}
254-
},
255240
modifier = Modifier
256241
.hazeEffect(hazeState) {
257242
style = hazeStyle
258243
blurRadius = 25.dp
259244
noiseFactor = 0f
260245
},
261-
color = Color.Transparent,
262-
targetState = when (uiState.floatingToolbarOrientation) {
263-
0 -> FloatingToolbarOrientation.Horizontal
264-
else -> FloatingToolbarOrientation.Vertical
265-
},
266-
)
246+
color = Color.Transparent
247+
) {
248+
AnimatedContent(
249+
targetState = uiState.floatingToolbarOrientation,
250+
) { orientation ->
251+
val floatingToolbarContent = @Composable {
252+
FloatingToolbarContent(
253+
items = navigationItem,
254+
pagerState = pagerState,
255+
coroutineScope = coroutineScope,
256+
selectedPage = selectedPage
257+
)
258+
}
259+
when (orientation) {
260+
0 -> Row { floatingToolbarContent() }
261+
else -> Column { floatingToolbarContent() }
262+
}
263+
}
264+
}
267265
}
268266
},
269267
floatingToolbarPosition = when (uiState.floatingToolbarPosition) {
@@ -481,3 +479,32 @@ fun AppHorizontalPager(
481479
}
482480
)
483481
}
482+
483+
@Composable
484+
fun FloatingToolbarContent(
485+
items: List<NavigationItem>,
486+
pagerState: PagerState,
487+
coroutineScope: CoroutineScope,
488+
selectedPage: Int
489+
) {
490+
items.forEachIndexed { index, item ->
491+
IconButton(
492+
onClick = {
493+
coroutineScope.launch {
494+
pagerState.animateScrollToPage(index)
495+
}
496+
},
497+
modifier = Modifier.padding(8.dp)
498+
) {
499+
Icon(
500+
imageVector = item.icon,
501+
tint = if (selectedPage == index) {
502+
MiuixTheme.colorScheme.onSurfaceContainer
503+
} else {
504+
MiuixTheme.colorScheme.onSurfaceContainerVariant
505+
},
506+
contentDescription = item.label
507+
)
508+
}
509+
}
510+
}
Lines changed: 13 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,23 @@
11
package top.yukonga.miuix.kmp.basic
22

3-
import androidx.compose.animation.AnimatedContent
4-
import androidx.compose.animation.fadeIn
5-
import androidx.compose.animation.fadeOut
6-
import androidx.compose.animation.togetherWith
73
import androidx.compose.foundation.background
8-
import androidx.compose.foundation.layout.Arrangement
9-
import androidx.compose.foundation.layout.Column
4+
import androidx.compose.foundation.gestures.detectTapGestures
5+
import androidx.compose.foundation.layout.Box
106
import androidx.compose.foundation.layout.PaddingValues
11-
import androidx.compose.foundation.layout.Row
127
import androidx.compose.foundation.layout.WindowInsets
138
import androidx.compose.foundation.layout.WindowInsetsSides
149
import androidx.compose.foundation.layout.captionBar
1510
import androidx.compose.foundation.layout.displayCutout
1611
import androidx.compose.foundation.layout.navigationBars
1712
import androidx.compose.foundation.layout.only
1813
import androidx.compose.foundation.layout.padding
19-
import androidx.compose.foundation.layout.size
2014
import androidx.compose.foundation.layout.statusBars
2115
import androidx.compose.foundation.layout.windowInsetsPadding
2216
import androidx.compose.runtime.Composable
23-
import androidx.compose.ui.Alignment
2417
import androidx.compose.ui.Modifier
2518
import androidx.compose.ui.draw.clip
2619
import androidx.compose.ui.graphics.Color
27-
import androidx.compose.ui.graphics.vector.ImageVector
20+
import androidx.compose.ui.input.pointer.pointerInput
2821
import androidx.compose.ui.unit.Dp
2922
import androidx.compose.ui.unit.dp
3023
import top.yukonga.miuix.kmp.theme.MiuixTheme
@@ -34,32 +27,24 @@ import top.yukonga.miuix.kmp.utils.SmoothRoundedCornerShape
3427
* A [FloatingToolbar] that renders its content in a Card, arranged either horizontally or vertically.
3528
* The actual placement on screen is handled by the parent, typically Scaffold.
3629
*
37-
* @param items The list of [NavigationItem]s to display in the toolbar.
38-
* @param selected The index of the currently selected item.
39-
* @param onClick The callback invoked when an item is clicked.
4030
* @param modifier The modifier to be applied to the [FloatingToolbar].
41-
* @param targetState The orientation of the buttons inside the [FloatingToolbar] (Horizontal or Vertical).
42-
* @param cornerRadius Corner radius of the [FloatingToolbar] background Card.
4331
* @param color Background color of the [FloatingToolbar].
44-
* @param contentPadding Padding inside the [FloatingToolbar], around the buttons.
32+
* @param cornerRadius Corner radius of the [FloatingToolbar].
4533
* @param outSidePadding Padding outside the [FloatingToolbar].
34+
* @param showBorder Whether to show a border around the [FloatingToolbar].
4635
* @param defaultWindowInsetsPadding Whether to apply default window insets padding to the [FloatingToolbar].
4736
*/
4837
@Composable
4938
fun FloatingToolbar(
50-
items: List<FloatingToolbarItem>,
51-
selected: Int,
52-
onClick: (Int) -> Unit,
5339
modifier: Modifier = Modifier,
54-
targetState: FloatingToolbarOrientation = FloatingToolbarDefaults.Orientation,
55-
cornerRadius: Dp = FloatingToolbarDefaults.CornerRadius,
5640
color: Color = FloatingToolbarDefaults.DefaultColor(),
57-
contentPadding: PaddingValues = FloatingToolbarDefaults.ContentPadding,
41+
cornerRadius: Dp = FloatingToolbarDefaults.CornerRadius,
5842
outSidePadding: PaddingValues = FloatingToolbarDefaults.OutSidePadding,
5943
showBorder: Boolean = true,
6044
defaultWindowInsetsPadding: Boolean = true,
45+
content: @Composable () -> Unit
6146
) {
62-
Column(
47+
Box(
6348
modifier = Modifier
6449
.padding(outSidePadding)
6550
.then(
@@ -71,7 +56,6 @@ fun FloatingToolbar(
7156
.windowInsetsPadding(WindowInsets.navigationBars)
7257
} else Modifier
7358
)
74-
7559
.background(color = color)
7660
.then(
7761
if (showBorder) {
@@ -81,67 +65,18 @@ fun FloatingToolbar(
8165
} else Modifier
8266
)
8367
.clip(SmoothRoundedCornerShape(cornerRadius))
68+
.pointerInput(Unit) { detectTapGestures { /* Do nothing to consume the click */ } }
8469
) {
85-
AnimatedContent(
86-
modifier = modifier,
87-
targetState = targetState,
88-
transitionSpec = { fadeIn() togetherWith fadeOut() },
89-
label = "toolbar-animation"
90-
) { targetOrientation ->
91-
val layoutModifier = Modifier.padding(contentPadding)
92-
val content = @Composable {
93-
items.forEachIndexed { index, item ->
94-
IconButton(
95-
modifier = Modifier.size(48.dp),
96-
onClick = { onClick(index) }
97-
) {
98-
Icon(
99-
item.icon,
100-
contentDescription = item.label,
101-
tint = if (selected == index) {
102-
MiuixTheme.colorScheme.onSurfaceContainer
103-
} else {
104-
MiuixTheme.colorScheme.onSurfaceContainerVariant
105-
}
106-
)
107-
}
108-
}
109-
}
110-
when (targetOrientation) {
111-
FloatingToolbarOrientation.Horizontal -> {
112-
Row(
113-
horizontalArrangement = Arrangement.spacedBy(12.dp),
114-
verticalAlignment = Alignment.CenterVertically,
115-
modifier = layoutModifier
116-
) { content() }
117-
}
118-
119-
FloatingToolbarOrientation.Vertical -> {
120-
Column(
121-
verticalArrangement = Arrangement.spacedBy(12.dp),
122-
horizontalAlignment = Alignment.CenterHorizontally,
123-
modifier = layoutModifier
124-
) { content() }
125-
}
126-
}
70+
Box(
71+
modifier = modifier
72+
) {
73+
content()
12774
}
12875
}
12976
}
13077

131-
/**
132-
* Represents the orientation of the FloatingToolbar's content.
133-
*/
134-
enum class FloatingToolbarOrientation {
135-
Horizontal, Vertical
136-
}
137-
13878
object FloatingToolbarDefaults {
13979

140-
/**
141-
* Default orientation of the context of the [FloatingToolbar].
142-
*/
143-
val Orientation = FloatingToolbarOrientation.Horizontal
144-
14580
/**
14681
* Default corner radius of the [FloatingToolbar].
14782
*/
@@ -153,25 +88,8 @@ object FloatingToolbarDefaults {
15388
@Composable
15489
fun DefaultColor() = MiuixTheme.colorScheme.surfaceContainer
15590

156-
/**
157-
* Default padding inside the [FloatingToolbar].
158-
*/
159-
val ContentPadding = PaddingValues(8.dp)
160-
16191
/**
16292
* Default padding outside the [FloatingToolbar].
16393
*/
16494
val OutSidePadding = PaddingValues(12.dp, 8.dp)
16595
}
166-
167-
168-
/**
169-
* The data class for [FloatingToolbar].
170-
*
171-
* @param label The label of the item.
172-
* @param icon The icon of the item.
173-
*/
174-
data class FloatingToolbarItem(
175-
val label: String,
176-
val icon: ImageVector
177-
)

miuix/src/commonMain/kotlin/top/yukonga/miuix/kmp/basic/NavigationBar.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,11 +182,13 @@ fun FloatingNavigationBar(
182182
) {
183183
require(items.size in 2..5) { "FloatingNavigationBar must have between 2 and 5 items" }
184184
Column(
185-
modifier = Modifier.fillMaxWidth()
185+
modifier = Modifier
186+
.fillMaxWidth()
187+
.pointerInput(Unit) { detectTapGestures { /* Do nothing to consume the click */ } }
186188
) {
187189
Row(
188190
modifier = Modifier
189-
.padding(bottom = if (platform() != Platform.IOS) 40.dp else 34.dp)
191+
.padding(bottom = if (platform() != Platform.IOS) 36.dp else 30.dp)
190192
.then(
191193
if (defaultWindowInsetsPadding) {
192194
Modifier
@@ -270,7 +272,7 @@ fun FloatingNavigationBar(
270272
)
271273
} else {
272274
Image(
273-
modifier = Modifier.padding(vertical = 12.dp, horizontal = 12.dp).size(28.dp),
275+
modifier = Modifier.padding(vertical = 10.dp, horizontal = 10.dp).size(28.dp),
274276
imageVector = item.icon,
275277
contentDescription = item.label,
276278
colorFilter = ColorFilter.tint(tint)

0 commit comments

Comments
 (0)