Screen Scaffold

Screen Scaffolds are handy for setting up theming defaults for your individual screens.

They also automatically render the sidebar slot on wide screens, and the bottomBar on mobile.

import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.composables.icons.lucide.ChartNoAxesCombined
import com.composables.icons.lucide.Cog
import com.composables.icons.lucide.House
import com.composables.icons.lucide.Lucide
import com.composables.icons.lucide.Package
import com.composables.uikit.components.BottomNavigationBar
import com.composables.uikit.components.Icon
import com.composables.uikit.components.PrimaryTab
import com.composables.uikit.components.SideBar
import com.composables.uikit.components.SideBarItem
import com.composables.uikit.components.Text
import com.composables.uikit.scaffolds.ScreenScaffold

@Composable
fun ScreenScaffoldExample() {
    class TopLevelDestination(val route: String, val name: String, val icon: ImageVector)

    val destinations = listOf(
        TopLevelDestination("home", "Home", Lucide.House),
        TopLevelDestination("orders", "Orders", Lucide.ChartNoAxesCombined),
        TopLevelDestination("products", "Products", Lucide.Package),
        TopLevelDestination("settings", "Settings", Lucide.Cog)
    )

    var currentRoute by remember { mutableStateOf(destinations.first()) }

    ScreenScaffold(
        sideBar = {
            SideBar(
                modifier = Modifier.fillMaxHeight(),
                navigationItems = {
                    destinations.forEach { destination ->
                        val selected = currentRoute == destination
                        SideBarItem(
                            onClick = { currentRoute = destination },
                            selected = selected,
                            modifier = Modifier.fillMaxWidth(),
                            icon = { Icon(destination.icon, contentDescription = null) },
                            title = { Text(destination.name) }
                        )
                    }
                },
            )
        },
        bottomBar = {
            BottomNavigationBar {
                destinations.forEach { destination ->
                    val selected = currentRoute == destination
                    PrimaryTab(
                        selected = selected,
                        onSelected = { currentRoute = destination },
                        modifier = Modifier.weight(1f),
                        icon = {
                            Icon(destination.icon, contentDescription = null)
                        },
                        title = {
                            Text(
                                text = destination.name,
                                overflow = TextOverflow.Ellipsis,
                                singleLine = true
                            )
                        },
                    )
                }
            }
        }
    ) {
        // screen content
    }
}