diff --git a/fluent/src/commonMain/kotlin/com/konyaco/fluent/component/NavigationView.kt b/fluent/src/commonMain/kotlin/com/konyaco/fluent/component/NavigationView.kt index e83f4e71..d05520e2 100644 --- a/fluent/src/commonMain/kotlin/com/konyaco/fluent/component/NavigationView.kt +++ b/fluent/src/commonMain/kotlin/com/konyaco/fluent/component/NavigationView.kt @@ -507,7 +507,7 @@ private fun LeftCompactLayout( state: NavigationState, contentPadding: PaddingValues, pane: @Composable () -> Unit, - autoSuggestBox: @Composable() (NavigationAutoSuggestBoxScope.() -> Unit)?, + autoSuggestBox: @Composable (NavigationAutoSuggestBoxScope.() -> Unit)?, title: @Composable () -> Unit, backButton: @Composable () -> Unit, expandedButton: @Composable () -> Unit, @@ -659,16 +659,28 @@ interface NavigationMenuScope { fun NavigationMenuScope.menuItem( selected: Boolean, onClick: (selected: Boolean) -> Unit, - key: Any? = null, - contentType: Any? = null, text: @Composable () -> Unit, icon: (@Composable () -> Unit)?, + key: Any? = null, + contentType: Any? = null, expandItems: Boolean = false, + enabled: Boolean = true, onExpandItemsChanged: (Boolean) -> Unit = {}, + interactionSource: MutableInteractionSource? = null, items: (@Composable MenuFlyoutContainerScope.() -> Unit)? = null ) { item(key, contentType) { - MenuItem(selected, onClick, expandItems, onExpandItemsChanged, text, icon, items) + MenuItem( + selected = selected, + onClick = onClick, + text = text, + icon = icon, + expandItems = expandItems, + onExpandItemsChanged = onExpandItemsChanged, + interactionSource = interactionSource, + items = items, + enabled = enabled + ) } } @@ -677,10 +689,31 @@ fun NavigationMenuScope.menuItem( fun NavigationMenuItemScope.MenuItem( selected: Boolean, onClick: (selected: Boolean) -> Unit, - expandItems: Boolean = false, - onExpandItemsChanged: (Boolean) -> Unit = {}, text: @Composable () -> Unit, icon: (@Composable () -> Unit)?, + expandItems: Boolean = false, + enabled: Boolean = true, + indicatorState: IndicatorState? = LocalIndicatorState.current, + onExpandItemsChanged: (Boolean) -> Unit = {}, + interactionSource: MutableInteractionSource? = null, + colors: NavigationItemColorScheme = if (displayMode == NavigationDisplayMode.Top) { + NavigationDefaults.defaultTopItemColors() + } else { + NavigationDefaults.defaultSideItemColors() + }, + indicator: @Composable IndicatorScope.(color: Color) -> Unit = if (displayMode == NavigationDisplayMode.Top) { + { color -> + NavigationDefaults.HorizontalIndicator( + color = color, + modifier = Modifier.indicatorOffset { selected }) + } + } else { + { color -> + NavigationDefaults.VerticalIndicator( + color = color, + modifier = Modifier.indicatorOffset { selected }) + } + }, items: (@Composable MenuFlyoutContainerScope.() -> Unit)? = null ) { @@ -695,8 +728,13 @@ fun NavigationMenuItemScope.MenuItem( text = if (isFooter) null else text, flyoutVisible = flyoutVisible, onFlyoutVisibleChanged = { flyoutVisible = it }, + indicatorState = indicatorState, icon = icon, - items = items + items = items, + enabled = enabled, + interactionSource = interactionSource, + colors = colors, + indicator = indicator ) } else { val isExpanded = LocalNavigationExpand.current @@ -711,13 +749,17 @@ fun NavigationMenuItemScope.MenuItem( } }, text = { text() }, - indicatorState = LocalIndicatorState.current, + indicatorState = indicatorState, flyoutVisible = flyoutVisible && !isExpanded, onFlyoutVisibleChanged = { flyoutVisible = it }, icon = icon, expandItems = expandItems, onExpandItemsChanged = onExpandItemsChanged, - items = items + items = items, + enabled = enabled, + interactionSource = interactionSource, + colors = colors, + indicator = indicator ) } } @@ -726,12 +768,33 @@ fun NavigationMenuItemScope.MenuItem( fun NavigationMenuItemScope.MenuItem( selected: Boolean, onClick: (selected: Boolean) -> Unit, - expandItems: Boolean = false, - onExpandItemsChanged: (Boolean) -> Unit = {}, text: @Composable () -> Unit, icon: (@Composable () -> Unit)?, header: (@Composable () -> Unit)?, + expandItems: Boolean = false, + enabled: Boolean = true, separatorVisible: Boolean = false, + indicatorState: IndicatorState? = LocalIndicatorState.current, + onExpandItemsChanged: (Boolean) -> Unit = {}, + interactionSource: MutableInteractionSource? = null, + colors: NavigationItemColorScheme = if (displayMode == NavigationDisplayMode.Top) { + NavigationDefaults.defaultTopItemColors() + } else { + NavigationDefaults.defaultSideItemColors() + }, + indicator: @Composable IndicatorScope.(color: Color) -> Unit = if (displayMode == NavigationDisplayMode.Top) { + { color -> + NavigationDefaults.HorizontalIndicator( + color = color, + modifier = Modifier.indicatorOffset { selected }) + } + } else { + { color -> + NavigationDefaults.VerticalIndicator( + color = color, + modifier = Modifier.indicatorOffset { selected }) + } + }, items: (@Composable MenuFlyoutContainerScope.() -> Unit)? = null ) { if (displayMode == NavigationDisplayMode.Top) { @@ -744,6 +807,12 @@ fun NavigationMenuItemScope.MenuItem( onExpandItemsChanged = onExpandItemsChanged, text = text, icon = icon, + interactionSource = interactionSource, + enabled = enabled, + items = items, + indicatorState = indicatorState, + indicator = indicator, + colors = colors ) if (separatorVisible) { MenuItemSeparator() @@ -758,8 +827,13 @@ fun NavigationMenuItemScope.MenuItem( text = text, icon = icon, expandItems = expandItems, + enabled = enabled, onExpandItemsChanged = onExpandItemsChanged, - items = items + items = items, + interactionSource = interactionSource, + indicatorState = indicatorState, + indicator = indicator, + colors = colors ) if (separatorVisible) { MenuItemSeparator() @@ -1118,9 +1192,9 @@ internal fun Modifier.indicatorOffsetAnimation( return layout { measurable, constraints -> val stickSize = size.toPx() val containerSize = if (isVertical) { - constraints.maxHeight + constraints.maxHeight.toFloat() } else { - constraints.maxWidth + constraints.maxWidth.toFloat() } val goBackward = if (isVertical) { selectedPosition.currentState.y > selectedPosition.targetState.y @@ -1173,10 +1247,11 @@ internal fun Modifier.indicatorOffsetAnimation( else -> 0f } } + val sizeInt = currentSize.roundToInt().coerceAtLeast(0) val placeable = if (isVertical) { - measurable.measure(Constraints.fixedHeight(currentSize.roundToInt().coerceAtLeast(0))) + measurable.measure(Constraints.fixedHeight(sizeInt)) } else { - measurable.measure(Constraints.fixedWidth(currentSize.roundToInt().coerceAtLeast(0))) + measurable.measure(Constraints.fixedWidth(sizeInt)) } layout( @@ -1184,13 +1259,13 @@ internal fun Modifier.indicatorOffsetAnimation( height = if (isVertical) constraints.maxHeight else placeable.height ) { val offset = when { - goBackward && !indicatorState.targetState && currentFraction <= 0.25f -> extendSize - currentSize + goBackward && !indicatorState.targetState && currentFraction <= 0.25f -> extendSize - sizeInt goBackward && !indicatorState.targetState -> 0f !goBackward && !indicatorState.targetState && currentFraction <= 0.25f -> contentPadding - !goBackward && !indicatorState.targetState -> containerSize - currentSize + !goBackward && !indicatorState.targetState -> containerSize - sizeInt goBackward && currentFraction > 0.75f -> contentPadding - goBackward && currentFraction > 0.5f -> containerSize - currentSize - !goBackward && currentFraction > 0.75f -> extendSize - currentSize + goBackward && currentFraction > 0.5f -> containerSize - sizeInt + !goBackward && currentFraction > 0.75f -> extendSize - sizeInt !goBackward && currentFraction > 0.5f -> 0f else -> 0f } diff --git a/fluent/src/commonMain/kotlin/com/konyaco/fluent/component/SideNav.kt b/fluent/src/commonMain/kotlin/com/konyaco/fluent/component/SideNav.kt index 72714682..422125e6 100644 --- a/fluent/src/commonMain/kotlin/com/konyaco/fluent/component/SideNav.kt +++ b/fluent/src/commonMain/kotlin/com/konyaco/fluent/component/SideNav.kt @@ -13,6 +13,7 @@ import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.shrinkVertically import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.InteractionSource import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -250,9 +251,10 @@ fun SideNavItem( color = it ) }, + interactionSource: MutableInteractionSource? = null, text: @Composable RowScope.() -> Unit ) { - val interaction = remember { MutableInteractionSource() } + val interaction = interactionSource ?: remember { MutableInteractionSource() } val color = colors.schemeFor(interaction.collectVisualState(!enabled)) diff --git a/gallery/src/androidMain/kotlin/com/konyaco/fluent/gallery/MainActivity.kt b/gallery/src/androidMain/kotlin/com/konyaco/fluent/gallery/MainActivity.kt index 0e09d113..2c7cf5f6 100644 --- a/gallery/src/androidMain/kotlin/com/konyaco/fluent/gallery/MainActivity.kt +++ b/gallery/src/androidMain/kotlin/com/konyaco/fluent/gallery/MainActivity.kt @@ -19,7 +19,11 @@ class MainActivity : ComponentActivity() { componentNavigator.navigateUp() } GalleryTheme { - App(componentNavigator, WindowInsets.systemBars) + App( + navigator = componentNavigator, + windowInset = WindowInsets.systemBars, + collapseWindowInset = WindowInsets.systemBars + ) } } } diff --git a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/App.kt b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/App.kt index 771f1f3b..cfefa1a7 100644 --- a/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/App.kt +++ b/gallery/src/commonMain/kotlin/com/konyaco/fluent/gallery/App.kt @@ -11,7 +11,6 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.WindowInsetsSides -import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.only @@ -69,6 +68,7 @@ fun App( navigator: ComponentNavigator = rememberComponentNavigator(components.first()), windowInset: WindowInsets = WindowInsets(0), contentInset: WindowInsets = WindowInsets(0), + collapseWindowInset: WindowInsets = WindowInsets(0), icon: Painter? = null, title: String = "", ) { @@ -98,19 +98,15 @@ fun App( val store = LocalStore.current val isCollapsed = store.navigationDisplayMode == NavigationDisplayMode.LeftCollapsed NavigationView( - modifier = Modifier.then( - if (!isCollapsed) { - Modifier.windowInsetsPadding(insets = windowInset) - } else { - Modifier - } + modifier = Modifier.windowInsetsPadding( + insets = if (isCollapsed) collapseWindowInset else windowInset ), state = rememberNavigationState(), displayMode = store.navigationDisplayMode, contentPadding = if (!isCollapsed) { PaddingValues() } else { - windowInset.asPaddingValues() + PaddingValues(top = 48.dp) }, menuItems = { components.forEach { navItem -> diff --git a/gallery/src/desktopMain/kotlin/com/konyaco/fluent/gallery/Main.kt b/gallery/src/desktopMain/kotlin/com/konyaco/fluent/gallery/Main.kt index 5e4fa226..60fc4b65 100644 --- a/gallery/src/desktopMain/kotlin/com/konyaco/fluent/gallery/Main.kt +++ b/gallery/src/desktopMain/kotlin/com/konyaco/fluent/gallery/Main.kt @@ -12,6 +12,7 @@ import com.konyaco.fluent.gallery.window.WindowFrame import fluentdesign.gallery.generated.resources.Res import fluentdesign.gallery.generated.resources.icon import org.jetbrains.compose.resources.painterResource +import org.jetbrains.skiko.hostOs fun main() = application { val state = rememberWindowState( @@ -34,6 +35,7 @@ fun main() = application { state = state, backButtonEnabled = navigator.canNavigateUp, backButtonClick = { navigator.navigateUp() }, + backButtonVisible = hostOs.isWindows ) { windowInset, contentInset -> App( windowInset = windowInset, diff --git a/gallery/src/iosMain/kotlin/main.kt b/gallery/src/iosMain/kotlin/main.kt index 0eb18bfe..61a2dc95 100644 --- a/gallery/src/iosMain/kotlin/main.kt +++ b/gallery/src/iosMain/kotlin/main.kt @@ -7,6 +7,6 @@ import platform.UIKit.UIViewController fun MainViewController(): UIViewController = ComposeUIViewController { GalleryTheme { - App(windowInset = WindowInsets.safeContent) + App(windowInset = WindowInsets.safeContent, collapseWindowInset = WindowInsets.safeContent) } }