Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit a3b192fc authored by Wolf Montwé's avatar Wolf Montwé
Browse files

Add ResponsiveContent to design system

parent b16bd8c4
Loading
Loading
Loading
Loading
+49 −28
Original line number Diff line number Diff line
@@ -10,7 +10,10 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import app.k9mail.core.ui.compose.common.DevicePreviews
import app.k9mail.core.ui.compose.designsystem.atom.Surface
import app.k9mail.core.ui.compose.designsystem.template.ResponsiveContent
import app.k9mail.core.ui.compose.theme.K9Theme
import app.k9mail.core.ui.compose.theme.MainTheme
import app.k9mail.core.ui.compose.theme.ThunderbirdTheme
import app.k9mail.ui.catalog.items.buttonItems
import app.k9mail.ui.catalog.items.colorItems
import app.k9mail.ui.catalog.items.imageItems
@@ -30,6 +33,7 @@ fun CatalogContent(
    modifier: Modifier = Modifier,
) {
    Surface {
        ResponsiveContent {
            LazyVerticalGrid(
                columns = GridCells.Adaptive(300.dp),
                contentPadding = contentPadding,
@@ -54,10 +58,12 @@ fun CatalogContent(
            }
        }
    }
}

@DevicePreviews
@Composable
internal fun CatalogContentPreview() {
internal fun CatalogContentK9ThemePreview() {
    K9Theme {
        CatalogContent(
            catalogTheme = CatalogTheme.K9,
            catalogThemeVariant = CatalogThemeVariant.LIGHT,
@@ -66,3 +72,18 @@ internal fun CatalogContentPreview() {
            contentPadding = PaddingValues(),
        )
    }
}

@DevicePreviews
@Composable
internal fun CatalogContentThunderbirdThemePreview() {
    ThunderbirdTheme {
        CatalogContent(
            catalogTheme = CatalogTheme.THUNDERBIRD,
            catalogThemeVariant = CatalogThemeVariant.LIGHT,
            onThemeChange = {},
            onThemeVariantChange = {},
            contentPadding = PaddingValues(),
        )
    }
}
+4 −4
Original line number Diff line number Diff line
@@ -12,11 +12,11 @@ enum class WindowSizeClass {
    ;

    companion object {
        private const val COMPACT_MAX_WIDTH = 600
        private const val COMPACT_MAX_HEIGHT = 480
        const val COMPACT_MAX_WIDTH = 600
        const val COMPACT_MAX_HEIGHT = 480

        private const val MEDIUM_MAX_WIDTH = 840
        private const val MEDIUM_MAX_HEIGHT = 900
        const val MEDIUM_MAX_WIDTH = 840
        const val MEDIUM_MAX_HEIGHT = 900

        fun fromWidth(width: Int): WindowSizeClass {
            return when {
+3 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import app.k9mail.core.ui.compose.theme.MainTheme
import app.k9mail.core.ui.compose.theme.PreviewWithThemes
import androidx.compose.material.Surface as MaterialSurface
@@ -13,11 +14,13 @@ import androidx.compose.material.Surface as MaterialSurface
fun Surface(
    modifier: Modifier = Modifier,
    color: Color = MainTheme.colors.surface,
    elevation: Dp = MainTheme.elevations.default,
    content: @Composable () -> Unit,
) {
    MaterialSurface(
        modifier = modifier,
        content = content,
        elevation = elevation,
        color = color,
    )
}
+129 −0
Original line number Diff line number Diff line
package app.k9mail.core.ui.compose.designsystem.template

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.requiredWidth
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import app.k9mail.core.ui.compose.common.DevicePreviews
import app.k9mail.core.ui.compose.common.window.WindowSizeClass
import app.k9mail.core.ui.compose.common.window.getWindowSizeInfo
import app.k9mail.core.ui.compose.designsystem.atom.Surface
import app.k9mail.core.ui.compose.theme.K9Theme
import app.k9mail.core.ui.compose.theme.MainTheme

/**
 * The [ResponsiveContent] composable automatically adapts its child content to different screen sizes and resolutions,
 * providing a responsive layout for a better user experience.
 *
 * It uses the [WindowSizeClass] (Compact, Medium, or Expanded) to make appropriate layout adjustments.
 *
 * @param modifier The modifier to be applied to the layout.
 * @param content The content to be displayed.
 */
@Composable
fun ResponsiveContent(
    modifier: Modifier = Modifier,
    content: @Composable () -> Unit,
) {
    val windowSizeClass = getWindowSizeInfo()

    when (windowSizeClass.screenWidthSizeClass) {
        WindowSizeClass.Compact -> CompactContent(modifier = modifier, content = content)
        WindowSizeClass.Medium -> MediumContent(modifier = modifier, content = content)
        WindowSizeClass.Expanded -> ExpandedContent(modifier = modifier, content = content)
    }
}

@Composable
private fun CompactContent(
    modifier: Modifier = Modifier,
    content: @Composable () -> Unit,
) {
    Box(
        modifier = Modifier
            .fillMaxSize()
            .then(modifier),
    ) {
        content()
    }
}

@Composable
private fun MediumContent(
    modifier: Modifier = Modifier,
    content: @Composable () -> Unit,
) {
    Box(
        modifier = Modifier
            .fillMaxSize()
            .then(modifier),
        contentAlignment = Alignment.TopCenter,
    ) {
        Box(
            modifier = Modifier.requiredWidth(WindowSizeClass.COMPACT_MAX_WIDTH.dp),
        ) {
            content()
        }
    }
}

@Composable
private fun ExpandedContent(
    modifier: Modifier = Modifier,
    content: @Composable () -> Unit,
) {
    when (getWindowSizeInfo().screenHeightSizeClass) {
        WindowSizeClass.Compact -> MediumContent(modifier, content)
        WindowSizeClass.Medium -> {
            Box(
                modifier = Modifier
                    .fillMaxSize()
                    .then(modifier),
                contentAlignment = Alignment.TopCenter,
            ) {
                Surface(
                    modifier = Modifier.requiredWidth(WindowSizeClass.MEDIUM_MAX_WIDTH.dp),
                    elevation = MainTheme.elevations.raised,
                ) {
                    content()
                }
            }
        }
        WindowSizeClass.Expanded -> {
            Box(
                modifier = Modifier
                    .fillMaxSize()
                    .then(modifier),
                contentAlignment = Alignment.Center,
            ) {
                Surface(
                    modifier = Modifier
                        .requiredWidth(WindowSizeClass.MEDIUM_MAX_WIDTH.dp)
                        .requiredHeight(WindowSizeClass.MEDIUM_MAX_HEIGHT.dp),
                    elevation = MainTheme.elevations.raised,
                ) {
                    content()
                }
            }
        }
    }
}

@Composable
@DevicePreviews
internal fun ResponsiveContentPreview() {
    K9Theme {
        Surface {
            ResponsiveContent {
                Surface(
                    color = MainTheme.colors.info,
                    modifier = Modifier.fillMaxSize(),
                ) {}
            }
        }
    }
}
+3 −1
Original line number Diff line number Diff line
@@ -7,7 +7,9 @@ import androidx.compose.ui.unit.dp

@Immutable
data class Elevations(
    val card: Dp = 0.dp,
    val default: Dp = 0.dp,
    val raised: Dp = 2.dp,
    val card: Dp = 4.dp,
)

internal val LocalElevations = staticCompositionLocalOf { Elevations() }