Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions AdaptiveJetStream/gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[versions]
activity-compose = "1.13.0"
android-gradle-plugin = "9.2.1"
android-test-plugin = "9.2.1"
android-gradle-plugin = "9.3.1"
android-test-plugin = "9.3.1"
androidx-baselineprofile = "1.5.0-alpha06"
benchmark-macro-junit4 = "1.4.1"
coil-compose = "2.7.0"
Expand All @@ -17,7 +17,7 @@ junit4 = "4.13.2"
kotlin-android = "2.3.21"
kotlinx-coroutines = "1.10.2"
kotlinx-serialization = "1.11.0"
ksp = "2.3.2"
ksp = "2.3.6"
lifecycle-runtime-ktx = "2.10.0"
material3-adaptive = "1.2.0"
material3-adaptive-navigation = "1.4.0"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.0-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,10 @@ private sealed interface AppLayout {
*/
object NavigationBar : AppLayout {
override val gridConfig: GridConfigurationScope.() -> Unit = {
column(GridTrackSize.MinMax(350.dp, 1.fr))
// MinMax(0.dp, 1.fr), not a plain Flex(1.fr): a Flex track queries its content's
// min-content intrinsic width, which crashes when the content row holds a lazy list
// (SubcomposeLayout-backed), as it does here for the Home screen's carousels.
column(GridTrackSize.MinMax(0.dp, 1.fr))
row(GridTrackSize.Auto)
row(GridTrackSize.MinMax(200.dp, 1.fr))
row(GridTrackSize.Auto)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ import androidx.compose.foundation.style.styleable
import androidx.compose.material3.Icon
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.NavigationRailItem
import androidx.compose.material3.PrimaryTabRow
import androidx.compose.material3.Tab
Expand All @@ -51,6 +53,7 @@ import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.xr.compose.material3.ExperimentalMaterial3XrApi
import androidx.xr.compose.material3.NavigationRail
Expand Down Expand Up @@ -142,15 +145,38 @@ object DefaultNavigation : JetStreamAppNavigation {
onNavigation: (Destination) -> Unit,
isVisible: Boolean,
) {
val direction =
when (LocalEngagementMode.current) {
is EngagementMode.Compact -> FlexDirection.Row
else -> FlexDirection.Column
// Compact devices use a dedicated bottom NavigationBar: unlike a FlexBox row of
// NavigationRailItems, it distributes items evenly so the bar always fits the
// available width instead of overflowing it on narrow screens.
if (LocalEngagementMode.current is EngagementMode.Compact) {
NavigationBar {
NavigationItem.RootDestinations.forEach { item ->
NavigationBarItem(
selected = item.destination == current,
onClick = { onNavigation(item.destination) },
icon = {
Icon(
painter = item.icon,
contentDescription = item.name,
modifier = Modifier.size(24.dp),
)
},
label = {
Text(
text = item.name,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
},
)
}
}
return
}

FlexBox(
config = {
direction(direction)
direction(FlexDirection.Column)
justifyContent(FlexJustifyContent.Center)
gap(4.dp)
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,21 @@ import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ProvidableCompositionLocal
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.window.core.layout.WindowSizeClass
import com.google.jetstream.presentation.components.feature.EngagementMode
import com.google.jetstream.presentation.components.feature.JetStreamUiMedia
import com.google.jetstream.presentation.components.feature.LocalEngagementMode

val LocalFeaturedCarouselHeight: ProvidableCompositionLocal<Dp> =
staticCompositionLocalOf {
324.dp
}

val LocalVerticalCardAspectRatio: ProvidableCompositionLocal<Float> =
staticCompositionLocalOf {
10.5f / 16f
}

val LocalCardWidth: ProvidableCompositionLocal<Dp> =
staticCompositionLocalOf {
126.dp
Expand All @@ -54,19 +51,6 @@ fun rememberFeaturedCarouselHeight(): Dp {
}
}

@Composable
fun rememberVerticalCardAspectRatio(): Float {
val engagementMode = LocalEngagementMode.current
return remember(engagementMode) {
when (engagementMode) {
is EngagementMode.Leanback, is EngagementMode.Cabin, is EngagementMode.Workstation -> 0.65625f

// 10.5f / 16f
else -> 0.67021f
}
}
}

@Composable
fun rememberCardWidth(
windowSizeClass: WindowSizeClass = currentWindowAdaptiveInfo().windowSizeClass,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.window.core.layout.WindowSizeClass
import com.google.jetstream.presentation.components.feature.EngagementMode
import com.google.jetstream.presentation.components.feature.LocalEngagementMode
import com.google.jetstream.presentation.components.feature.isWidthAtLeastExpanded
import com.google.jetstream.presentation.components.feature.isWidthAtLeastLarge
Expand All @@ -38,12 +39,13 @@ val LocalListItemGap: ProvidableCompositionLocal<Dp> =

@Composable
fun rememberListItemGap(): Dp {
val isFocusOptimized = LocalEngagementMode.current.isFocusOptimized()
return remember(isFocusOptimized) {
if (isFocusOptimized) {
20.dp
} else {
8.dp
val engagementMode = LocalEngagementMode.current
val isFocusOptimized = engagementMode.isFocusOptimized()
return remember(engagementMode, isFocusOptimized) {
when {
isFocusOptimized -> 20.dp
engagementMode is EngagementMode.Compact -> 4.dp
else -> 8.dp
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ fun JetStreamTheme(
// TODO: Consider refactoring this
CompositionLocalProvider(
LocalFeaturedCarouselHeight provides rememberFeaturedCarouselHeight(),
LocalVerticalCardAspectRatio provides rememberVerticalCardAspectRatio(),
LocalCardWidth provides rememberCardWidth(),
LocalListItemGap provides rememberListItemGap(),
LocalProminentCardStyle provides rememberProminentCardStyle(),
Expand Down