Add catalog implementation using a LazyVerticalGrid and adding all components from the design system

This commit is contained in:
Wolf Montwé 2023-03-14 14:43:10 +01:00
parent 0b572ec088
commit 6a88a33c75
No known key found for this signature in database
GPG key ID: 6D45B21512ACBF72
20 changed files with 508 additions and 120 deletions

View file

@ -14,6 +14,7 @@ android {
dependencies {
implementation(projects.core.ui.compose.designsystem)
implementation(libs.androidx.compose.material)
androidTestImplementation(libs.androidx.test.ext.junit.ktx)
androidTestImplementation(libs.androidx.test.espresso.core)

View file

@ -10,7 +10,7 @@
android:theme="@style/Theme.Thunderbird"
>
<activity
android:name=".MainActivity"
android:name=".CatalogActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

View file

@ -3,12 +3,16 @@ package app.k9mail.ui.catalog
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
class MainActivity : ComponentActivity() {
import androidx.core.view.WindowCompat
class CatalogActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(window, false)
setContent {
MainView()
CatalogScreen()
}
}
}

View file

@ -0,0 +1,66 @@
package app.k9mail.ui.catalog
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.runtime.Composable
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.theme.MainTheme
import app.k9mail.ui.catalog.items.buttonItems
import app.k9mail.ui.catalog.items.colorItems
import app.k9mail.ui.catalog.items.imageItems
import app.k9mail.ui.catalog.items.selectionControlItems
import app.k9mail.ui.catalog.items.themeHeaderItem
import app.k9mail.ui.catalog.items.themeSelectorItems
import app.k9mail.ui.catalog.items.typographyItems
@Composable
fun CatalogContent(
catalogTheme: CatalogTheme,
catalogThemeVariant: CatalogThemeVariant,
onThemeChange: () -> Unit,
onThemeVariantChange: () -> Unit,
contentPadding: PaddingValues,
modifier: Modifier = Modifier,
) {
Surface {
LazyVerticalGrid(
columns = GridCells.Adaptive(300.dp),
contentPadding = contentPadding,
horizontalArrangement = Arrangement.spacedBy(MainTheme.spacings.double),
verticalArrangement = Arrangement.spacedBy(MainTheme.spacings.double),
modifier = modifier.padding(MainTheme.spacings.double),
) {
themeHeaderItem(text = "Thunderbird Catalog")
themeSelectorItems(
catalogTheme = catalogTheme,
catalogThemeVariant = catalogThemeVariant,
onThemeChange = onThemeChange,
onThemeVariantChange = onThemeVariantChange,
)
typographyItems()
colorItems()
buttonItems()
selectionControlItems()
imageItems()
}
}
}
@DevicePreviews
@Composable
internal fun CatalogContentPreview() {
CatalogContent(
catalogTheme = CatalogTheme.K9,
catalogThemeVariant = CatalogThemeVariant.LIGHT,
onThemeChange = {},
onThemeVariantChange = {},
contentPadding = PaddingValues(),
)
}

View file

@ -0,0 +1,50 @@
package app.k9mail.ui.catalog
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.systemBars
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import app.k9mail.core.ui.compose.common.DevicePreviews
@Composable
fun CatalogScreen(
modifier: Modifier = Modifier,
) {
val themeState = remember { mutableStateOf(CatalogTheme.K9) }
val themeVariantState = remember { mutableStateOf(CatalogThemeVariant.LIGHT) }
CatalogThemeSwitch(theme = themeState.value, themeVariation = themeVariantState.value) {
val contentPadding = WindowInsets.systemBars.asPaddingValues()
CatalogContent(
catalogTheme = themeState.value,
catalogThemeVariant = themeVariantState.value,
onThemeChange = {
themeState.value = when (themeState.value) {
CatalogTheme.K9 -> CatalogTheme.THUNDERBIRD
CatalogTheme.THUNDERBIRD -> CatalogTheme.K9
}
},
onThemeVariantChange = {
themeVariantState.value = when (themeVariantState.value) {
CatalogThemeVariant.LIGHT -> CatalogThemeVariant.DARK
CatalogThemeVariant.DARK -> CatalogThemeVariant.LIGHT
}
},
contentPadding = contentPadding,
modifier = Modifier
.fillMaxSize()
.then(modifier),
)
}
}
@DevicePreviews
@Composable
internal fun CatalogScreenPreview() {
CatalogScreen()
}

View file

@ -0,0 +1,13 @@
package app.k9mail.ui.catalog
enum class CatalogTheme(
private val displayName: String,
) {
K9("K-9"),
THUNDERBIRD("Thunderbird"),
;
override fun toString(): String {
return displayName
}
}

View file

@ -0,0 +1,29 @@
package app.k9mail.ui.catalog
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import app.k9mail.core.ui.compose.designsystem.atom.button.Button
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBody1
import app.k9mail.core.ui.compose.theme.MainTheme
@Composable
fun CatalogThemeSelector(
catalogTheme: CatalogTheme,
modifier: Modifier = Modifier,
onThemeChangeClick: () -> Unit,
) {
Row(
modifier = modifier,
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(MainTheme.spacings.default),
) {
TextBody1(text = "Change theme:")
Button(
text = catalogTheme.toString(),
onClick = onThemeChangeClick,
)
}
}

View file

@ -0,0 +1,26 @@
package app.k9mail.ui.catalog
import androidx.compose.runtime.Composable
import app.k9mail.core.ui.compose.theme.K9Theme
import app.k9mail.core.ui.compose.theme.ThunderbirdTheme
@Composable
fun CatalogThemeSwitch(
theme: CatalogTheme,
themeVariation: CatalogThemeVariant,
content: @Composable () -> Unit,
) {
when (theme) {
CatalogTheme.K9 -> K9Theme(
darkTheme = isDarkVariation(themeVariation),
content = content,
)
CatalogTheme.THUNDERBIRD -> ThunderbirdTheme(
darkTheme = isDarkVariation(themeVariation),
content = content,
)
}
}
private fun isDarkVariation(themeVariation: CatalogThemeVariant): Boolean =
themeVariation == CatalogThemeVariant.DARK

View file

@ -0,0 +1,5 @@
package app.k9mail.ui.catalog
enum class CatalogThemeVariant {
LIGHT, DARK
}

View file

@ -0,0 +1,29 @@
package app.k9mail.ui.catalog
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import app.k9mail.core.ui.compose.designsystem.atom.Checkbox
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBody1
import app.k9mail.core.ui.compose.theme.MainTheme
@Composable
fun CatalogThemeVariantSelector(
catalogThemeVariant: CatalogThemeVariant,
modifier: Modifier = Modifier,
onThemeVariantChange: () -> Unit,
) {
Row(
modifier = modifier,
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(MainTheme.spacings.default),
) {
TextBody1(text = "Set dark mode:")
Checkbox(
checked = catalogThemeVariant == CatalogThemeVariant.DARK,
onCheckedChange = { onThemeVariantChange() },
)
}
}

View file

@ -1,117 +0,0 @@
package app.k9mail.ui.catalog
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.atom.Surface
import app.k9mail.core.ui.compose.designsystem.atom.button.Button
import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonOutlined
import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonText
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBody1
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBody2
import app.k9mail.core.ui.compose.designsystem.atom.text.TextButton
import app.k9mail.core.ui.compose.designsystem.atom.text.TextCaption
import app.k9mail.core.ui.compose.designsystem.atom.text.TextHeadline1
import app.k9mail.core.ui.compose.designsystem.atom.text.TextHeadline2
import app.k9mail.core.ui.compose.designsystem.atom.text.TextHeadline3
import app.k9mail.core.ui.compose.designsystem.atom.text.TextHeadline4
import app.k9mail.core.ui.compose.designsystem.atom.text.TextHeadline5
import app.k9mail.core.ui.compose.designsystem.atom.text.TextHeadline6
import app.k9mail.core.ui.compose.designsystem.atom.text.TextOverline
import app.k9mail.core.ui.compose.designsystem.atom.text.TextSubtitle1
import app.k9mail.core.ui.compose.designsystem.atom.text.TextSubtitle2
import app.k9mail.core.ui.compose.theme.K9Theme
import app.k9mail.core.ui.compose.theme.MainTheme
import app.k9mail.core.ui.compose.theme.ThunderbirdTheme
@Composable
fun MainView(
modifier: Modifier = Modifier,
) {
val scrollState = rememberScrollState()
Column(
modifier = Modifier
.fillMaxSize()
.verticalScroll(scrollState)
.then(modifier),
) {
K9Theme {
MainContent(name = "K-9")
}
K9Theme(darkTheme = true) {
MainContent(name = "K-9 dark")
}
ThunderbirdTheme {
MainContent(name = "Thunderbird")
}
ThunderbirdTheme(darkTheme = true) {
MainContent(name = "Thunderbird dark")
}
}
}
@Composable
private fun MainContent(
name: String,
modifier: Modifier = Modifier,
) {
Surface(
modifier = Modifier
.fillMaxWidth()
.then(modifier),
) {
Column {
TextHeadline4(text = "$name theme")
Image(painter = painterResource(id = MainTheme.images.logo), contentDescription = "logo")
ButtonContent()
TypographyContent()
}
}
}
@Composable
private fun ButtonContent() {
Column {
TextHeadline6(text = "Buttons")
Button(text = "Button", onClick = { })
ButtonOutlined(text = "ButtonOutlined", onClick = { })
ButtonText(text = "ButtonText", onClick = { })
}
}
@Composable
private fun TypographyContent() {
Column {
TextHeadline6(text = "Typography")
TextHeadline1(text = "Headline1")
TextHeadline2(text = "Headline2")
TextHeadline3(text = "Headline3")
TextHeadline4(text = "Headline4")
TextHeadline5(text = "Headline5")
TextHeadline6(text = "Headline6")
TextSubtitle1(text = "Subtitle1")
TextSubtitle2(text = "Subtitle2")
TextBody1(text = "Body1")
TextBody2(text = "Body2")
TextButton(text = "Button")
TextCaption(text = "Caption")
TextOverline(text = "Overline")
}
}
@Preview(showBackground = true)
@Composable
fun Preview() {
MainView()
}

View file

@ -0,0 +1,40 @@
package app.k9mail.ui.catalog.items
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.lazy.grid.LazyGridScope
import app.k9mail.core.ui.compose.designsystem.atom.button.Button
import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonOutlined
import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonText
import app.k9mail.core.ui.compose.theme.MainTheme
fun LazyGridScope.buttonItems() {
sectionHeaderItem(text = "Buttons")
sectionSubtitleItem(text = "Contained")
item {
Row(
horizontalArrangement = Arrangement.spacedBy(MainTheme.spacings.default),
) {
Button(text = "Enabled", onClick = { })
Button(text = "Disabled", onClick = { }, enabled = false)
}
}
sectionSubtitleItem(text = "Outlined")
item {
Row(
horizontalArrangement = Arrangement.spacedBy(MainTheme.spacings.default),
) {
ButtonOutlined(text = "Enabled", onClick = { })
ButtonOutlined(text = "Disabled", onClick = { }, enabled = false)
}
}
sectionSubtitleItem(text = "Text")
item {
Row(
horizontalArrangement = Arrangement.spacedBy(MainTheme.spacings.default),
) {
ButtonText(text = "Enabled", onClick = { })
ButtonText(text = "Disabled", onClick = { }, enabled = false)
}
}
}

View file

@ -0,0 +1,78 @@
package app.k9mail.ui.catalog.items
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.grid.LazyGridScope
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import app.k9mail.core.ui.compose.designsystem.atom.Surface
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBody1
import app.k9mail.core.ui.compose.theme.MainTheme
fun LazyGridScope.colorItems() {
sectionHeaderItem(text = "Colors")
item {
ColorContent(
name = "Primary",
color = MainTheme.colors.primary,
)
}
item {
ColorContent(
name = "Primary Variant",
color = MainTheme.colors.primaryVariant,
)
}
item {
ColorContent(
name = "Secondary",
color = MainTheme.colors.secondary,
)
}
item {
ColorContent(
name = "Secondary Variant",
color = MainTheme.colors.secondaryVariant,
)
}
item {
ColorContent(
name = "Background",
color = MainTheme.colors.background,
)
}
item {
ColorContent(
name = "Surface",
color = MainTheme.colors.surface,
)
}
item {
ColorContent(
name = "Error",
color = MainTheme.colors.error,
)
}
}
@Composable
private fun ColorContent(
name: String,
color: Color,
modifier: Modifier = Modifier,
) {
Surface(
color = color,
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center,
modifier = modifier.padding(MainTheme.spacings.double),
) {
TextBody1(text = name)
}
}
}

View file

@ -0,0 +1,13 @@
package app.k9mail.ui.catalog.items
import androidx.compose.foundation.Image
import androidx.compose.foundation.lazy.grid.LazyGridScope
import androidx.compose.ui.res.painterResource
import app.k9mail.core.ui.compose.theme.MainTheme
fun LazyGridScope.imageItems() {
sectionHeaderItem(text = "Images")
item {
Image(painter = painterResource(id = MainTheme.images.logo), contentDescription = "logo")
}
}

View file

@ -0,0 +1,16 @@
package app.k9mail.ui.catalog.items
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.grid.GridItemSpan
import androidx.compose.foundation.lazy.grid.LazyGridScope
import androidx.compose.ui.Modifier
import app.k9mail.core.ui.compose.designsystem.atom.text.TextHeadline6
import app.k9mail.core.ui.compose.theme.MainTheme
fun LazyGridScope.sectionHeaderItem(
text: String,
) {
item(span = { GridItemSpan(maxLineSpan) }) {
TextHeadline6(text = text, modifier = Modifier.padding(top = MainTheme.spacings.default))
}
}

View file

@ -0,0 +1,16 @@
package app.k9mail.ui.catalog.items
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.grid.GridItemSpan
import androidx.compose.foundation.lazy.grid.LazyGridScope
import androidx.compose.ui.Modifier
import app.k9mail.core.ui.compose.designsystem.atom.text.TextSubtitle1
import app.k9mail.core.ui.compose.theme.MainTheme
fun LazyGridScope.sectionSubtitleItem(
text: String,
) {
item(span = { GridItemSpan(maxLineSpan) }) {
TextSubtitle1(text = text, modifier = Modifier.padding(top = MainTheme.spacings.default))
}
}

View file

@ -0,0 +1,39 @@
package app.k9mail.ui.catalog.items
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.lazy.grid.LazyGridScope
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import app.k9mail.core.ui.compose.designsystem.atom.Checkbox
import app.k9mail.core.ui.compose.designsystem.atom.text.TextCaption
fun LazyGridScope.selectionControlItems() {
sectionHeaderItem(text = "Selection Controls")
sectionSubtitleItem(text = "Checkbox")
captionItem(caption = "Checked") {
Checkbox(checked = true, onCheckedChange = {})
}
captionItem(caption = "Unchecked") {
Checkbox(checked = false, onCheckedChange = {})
}
captionItem(caption = "Disabled Checked") {
Checkbox(checked = true, onCheckedChange = {}, enabled = false)
}
captionItem(caption = "Disabled") {
Checkbox(checked = false, onCheckedChange = {}, enabled = false)
}
}
private fun LazyGridScope.captionItem(
caption: String,
content: @Composable () -> Unit,
) {
item {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
) {
content()
TextCaption(text = caption)
}
}
}

View file

@ -0,0 +1,16 @@
package app.k9mail.ui.catalog.items
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.grid.GridItemSpan
import androidx.compose.foundation.lazy.grid.LazyGridScope
import androidx.compose.ui.Modifier
import app.k9mail.core.ui.compose.designsystem.atom.text.TextHeadline4
import app.k9mail.core.ui.compose.theme.MainTheme
fun LazyGridScope.themeHeaderItem(
text: String,
) {
item(span = { GridItemSpan(maxLineSpan) }) {
TextHeadline4(text = text, modifier = Modifier.padding(top = MainTheme.spacings.default))
}
}

View file

@ -0,0 +1,31 @@
package app.k9mail.ui.catalog.items
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.lazy.grid.LazyGridScope
import androidx.compose.ui.Modifier
import app.k9mail.ui.catalog.CatalogTheme
import app.k9mail.ui.catalog.CatalogThemeSelector
import app.k9mail.ui.catalog.CatalogThemeVariant
import app.k9mail.ui.catalog.CatalogThemeVariantSelector
fun LazyGridScope.themeSelectorItems(
catalogTheme: CatalogTheme,
catalogThemeVariant: CatalogThemeVariant,
onThemeChange: () -> Unit,
onThemeVariantChange: () -> Unit,
) {
item {
CatalogThemeSelector(
catalogTheme = catalogTheme,
modifier = Modifier.fillMaxWidth(),
onThemeChangeClick = onThemeChange,
)
}
item {
CatalogThemeVariantSelector(
catalogThemeVariant = catalogThemeVariant,
modifier = Modifier.fillMaxWidth(),
onThemeVariantChange = onThemeVariantChange,
)
}
}

View file

@ -0,0 +1,33 @@
package app.k9mail.ui.catalog.items
import androidx.compose.foundation.lazy.grid.LazyGridScope
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBody1
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBody2
import app.k9mail.core.ui.compose.designsystem.atom.text.TextButton
import app.k9mail.core.ui.compose.designsystem.atom.text.TextCaption
import app.k9mail.core.ui.compose.designsystem.atom.text.TextHeadline1
import app.k9mail.core.ui.compose.designsystem.atom.text.TextHeadline2
import app.k9mail.core.ui.compose.designsystem.atom.text.TextHeadline3
import app.k9mail.core.ui.compose.designsystem.atom.text.TextHeadline4
import app.k9mail.core.ui.compose.designsystem.atom.text.TextHeadline5
import app.k9mail.core.ui.compose.designsystem.atom.text.TextHeadline6
import app.k9mail.core.ui.compose.designsystem.atom.text.TextOverline
import app.k9mail.core.ui.compose.designsystem.atom.text.TextSubtitle1
import app.k9mail.core.ui.compose.designsystem.atom.text.TextSubtitle2
fun LazyGridScope.typographyItems() {
sectionHeaderItem(text = "Typography")
item { TextHeadline1(text = "Headline1") }
item { TextHeadline2(text = "Headline2") }
item { TextHeadline3(text = "Headline3") }
item { TextHeadline4(text = "Headline4") }
item { TextHeadline5(text = "Headline5") }
item { TextHeadline6(text = "Headline6") }
item { TextSubtitle1(text = "Subtitle1") }
item { TextSubtitle2(text = "Subtitle2") }
item { TextBody1(text = "Body1") }
item { TextBody2(text = "Body2") }
item { TextButton(text = "Button") }
item { TextCaption(text = "Caption") }
item { TextOverline(text = "Overline") }
}