Merge pull request #6890 from thundernest/add_account_setup_atoms_and_molecules

Add account setup atoms and molecules
This commit is contained in:
Wolf-Martell Montwé 2023-05-11 08:32:30 +00:00 committed by GitHub
commit e21041a0da
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
35 changed files with 1263 additions and 86 deletions

View file

@ -16,7 +16,9 @@ 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.iconItems
import app.k9mail.ui.catalog.items.imageItems
import app.k9mail.ui.catalog.items.moleculeItems
import app.k9mail.ui.catalog.items.selectionControlItems
import app.k9mail.ui.catalog.items.textFieldItems
import app.k9mail.ui.catalog.items.themeHeaderItem
@ -55,6 +57,9 @@ fun CatalogContent(
selectionControlItems()
textFieldItems()
imageItems()
iconItems()
moleculeItems()
}
}
}

View file

@ -0,0 +1,15 @@
package app.k9mail.ui.catalog.helper
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@Composable
internal fun <T> WithRememberedState(
input: T,
content: @Composable (state: MutableState<T>) -> Unit,
) {
val state = remember { mutableStateOf(input) }
content(state)
}

View file

@ -0,0 +1,49 @@
package app.k9mail.ui.catalog.items
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
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 androidx.compose.ui.graphics.vector.ImageVector
import app.k9mail.core.ui.compose.designsystem.atom.Icon
import app.k9mail.core.ui.compose.designsystem.atom.text.TextCaption
import app.k9mail.core.ui.compose.theme.Icons
import app.k9mail.core.ui.compose.theme.MainTheme
fun LazyGridScope.iconItems() {
sectionHeaderItem(text = "Icons")
item {
IconItem(
name = "Error",
imageVector = Icons.error,
)
}
}
@Composable
private fun IconItem(
name: String,
imageVector: ImageVector,
) {
Column(
modifier = Modifier.padding(MainTheme.spacings.default),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(MainTheme.spacings.default),
) {
Row {
Icon(
imageVector = imageVector,
)
Icon(
imageVector = imageVector,
tint = Color.Magenta,
)
}
TextCaption(text = name)
}
}

View file

@ -0,0 +1,108 @@
package app.k9mail.ui.catalog.items
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.lazy.grid.LazyGridScope
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import app.k9mail.core.ui.compose.designsystem.atom.text.TextSubtitle1
import app.k9mail.core.ui.compose.designsystem.molecule.EmailAddressInput
import app.k9mail.core.ui.compose.designsystem.molecule.ErrorView
import app.k9mail.core.ui.compose.designsystem.molecule.LoadingView
import app.k9mail.core.ui.compose.designsystem.molecule.PasswordInput
import app.k9mail.core.ui.compose.theme.MainTheme
import app.k9mail.ui.catalog.helper.WithRememberedState
@Suppress("LongMethod")
fun LazyGridScope.moleculeItems() {
sectionHeaderItem(text = "Molecules")
item {
MoleculeWrapper(title = "ErrorView") {
ErrorView(
title = "Error",
message = "Something went wrong",
)
}
}
item {
MoleculeWrapper(title = "LoadingView") {
LoadingView()
}
}
item {
MoleculeWrapper(title = "LoadingView with message") {
LoadingView(
message = "Loading...",
)
}
}
item {
MoleculeWrapper(title = "EmailAddressInput") {
WithRememberedState(input = "") { state ->
EmailAddressInput(
emailAddress = state.value,
onEmailAddressChange = { state.value = it },
)
}
}
}
item {
MoleculeWrapper(title = "EmailAddressInput with error") {
WithRememberedState(input = "wrong email address") { state ->
EmailAddressInput(
emailAddress = state.value,
onEmailAddressChange = { state.value = it },
errorMessage = "Invalid email address",
)
}
}
}
item {
MoleculeWrapper(title = "PasswordInput") {
WithRememberedState(input = "") { state ->
PasswordInput(
password = state.value,
onPasswordChange = { state.value = it },
)
}
}
}
item {
MoleculeWrapper(title = "PasswordInput with error") {
WithRememberedState(input = "wrong password") { state ->
PasswordInput(
password = state.value,
onPasswordChange = { state.value = it },
errorMessage = "Invalid password",
)
}
}
}
}
@Composable
private fun MoleculeWrapper(
title: String,
content: @Composable () -> Unit,
) {
Column(
verticalArrangement = Arrangement.spacedBy(MainTheme.spacings.default),
) {
TextSubtitle1(text = title)
Box(
modifier = Modifier
.border(1.dp, Color.Gray)
.fillMaxWidth(),
) {
content()
}
}
}

View file

@ -1,46 +1,45 @@
package app.k9mail.ui.catalog.items
import androidx.compose.foundation.lazy.grid.LazyGridScope
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import app.k9mail.core.ui.compose.designsystem.atom.textfield.PasswordTextFieldOutlined
import app.k9mail.core.ui.compose.designsystem.atom.textfield.TextFieldOutlined
import app.k9mail.core.ui.compose.designsystem.atom.textfield.TextFieldOutlinedEmailAddress
import app.k9mail.core.ui.compose.designsystem.atom.textfield.TextFieldOutlinedPassword
import app.k9mail.ui.catalog.helper.WithRememberedState
fun LazyGridScope.textFieldItems() {
sectionHeaderItem(text = "Text fields")
textFieldOutlinedItems()
passwordTextFieldOutlinedItems()
emailTextFieldOutlinedItems()
}
private fun LazyGridScope.textFieldOutlinedItems() {
sectionSubtitleItem(text = "Outlined")
item {
WithRememberedInput(text = "Initial text") { input ->
WithRememberedState(input = "Initial text") { state ->
TextFieldOutlined(
value = input.value,
value = state.value,
label = "Label",
onValueChange = { input.value = it },
onValueChange = { state.value = it },
)
}
}
item {
WithRememberedInput(text = "Input text with error") { input ->
WithRememberedState(input = "Input text with error") { state ->
TextFieldOutlined(
value = input.value,
value = state.value,
label = "Label",
onValueChange = { input.value = it },
onValueChange = { state.value = it },
isError = true,
)
}
}
item {
WithRememberedInput(text = "Input text disabled") { input ->
WithRememberedState(input = "Input text disabled") { state ->
TextFieldOutlined(
value = input.value,
value = state.value,
label = "Label",
onValueChange = { input.value = it },
onValueChange = { state.value = it },
enabled = false,
)
}
@ -50,41 +49,65 @@ private fun LazyGridScope.textFieldOutlinedItems() {
private fun LazyGridScope.passwordTextFieldOutlinedItems() {
sectionSubtitleItem(text = "Password outlined")
item {
WithRememberedInput(text = "Input text") { input ->
PasswordTextFieldOutlined(
value = input.value,
label = "Label",
onValueChange = { input.value = it },
WithRememberedState(input = "") { state ->
TextFieldOutlinedPassword(
value = state.value,
label = "Password",
onValueChange = { state.value = it },
)
}
}
item {
WithRememberedInput(text = "Input text with error") { input ->
PasswordTextFieldOutlined(
value = input.value,
label = "Label",
onValueChange = { input.value = it },
WithRememberedState(input = "Password") { state ->
TextFieldOutlinedPassword(
value = state.value,
label = "Password with error",
onValueChange = { state.value = it },
isError = true,
)
}
}
item {
WithRememberedInput(text = "Input text disabled") { input ->
PasswordTextFieldOutlined(
value = input.value,
label = "Label",
onValueChange = { input.value = it },
WithRememberedState(input = "Password disabled") { state ->
TextFieldOutlinedPassword(
value = state.value,
label = "Password",
onValueChange = { state.value = it },
enabled = false,
)
}
}
}
@Composable
private fun WithRememberedInput(
text: String,
content: @Composable (text: MutableState<String>) -> Unit,
) {
val inputText = remember { mutableStateOf(text) }
content(inputText)
private fun LazyGridScope.emailTextFieldOutlinedItems() {
sectionSubtitleItem(text = "Email outlined")
item {
WithRememberedState(input = "") { state ->
TextFieldOutlinedEmailAddress(
value = state.value,
label = "Email address",
onValueChange = { state.value = it },
)
}
}
item {
WithRememberedState(input = "email@example.com") { state ->
TextFieldOutlinedEmailAddress(
value = state.value,
label = "Email address with error",
onValueChange = { state.value = it },
isError = true,
)
}
}
item {
WithRememberedState(input = "email@example.com disabled") { state ->
TextFieldOutlinedEmailAddress(
value = state.value,
label = "Email address",
onValueChange = { state.value = it },
enabled = false,
)
}
}
}

View file

@ -1,6 +1,11 @@
package app.k9mail.ui.catalog.items
import androidx.compose.foundation.lazy.grid.LazyGridScope
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.withStyle
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
@ -17,6 +22,7 @@ import app.k9mail.core.ui.compose.designsystem.atom.text.TextSubtitle2
fun LazyGridScope.typographyItems() {
sectionHeaderItem(text = "Typography")
sectionSubtitleItem(text = "Normal")
item { TextHeadline1(text = "Headline1") }
item { TextHeadline2(text = "Headline2") }
item { TextHeadline3(text = "Headline3") }
@ -30,4 +36,39 @@ fun LazyGridScope.typographyItems() {
item { TextButton(text = "Button") }
item { TextCaption(text = "Caption") }
item { TextOverline(text = "Overline") }
sectionSubtitleItem(text = "colored")
item { TextHeadline1(text = "Headline1", color = Color.Magenta) }
item { TextHeadline2(text = "Headline2", color = Color.Magenta) }
item { TextHeadline3(text = "Headline3", color = Color.Magenta) }
item { TextHeadline4(text = "Headline4", color = Color.Magenta) }
item { TextHeadline5(text = "Headline5", color = Color.Magenta) }
item { TextHeadline6(text = "Headline6", color = Color.Magenta) }
item { TextSubtitle1(text = "Subtitle1", color = Color.Magenta) }
item { TextSubtitle2(text = "Subtitle2", color = Color.Magenta) }
item { TextBody1(text = "Body1", color = Color.Magenta) }
item { TextBody2(text = "Body2", color = Color.Magenta) }
item { TextButton(text = "Button", color = Color.Magenta) }
item { TextCaption(text = "Caption", color = Color.Magenta) }
item { TextOverline(text = "Overline", color = Color.Magenta) }
sectionSubtitleItem(text = "Annotated")
item { TextHeadline1(text = annotatedString("Headline1")) }
item { TextHeadline2(text = annotatedString("Headline2")) }
item { TextHeadline3(text = annotatedString("Headline3")) }
item { TextHeadline4(text = annotatedString("Headline4")) }
item { TextHeadline5(text = annotatedString("Headline5")) }
item { TextHeadline6(text = annotatedString("Headline6")) }
item { TextSubtitle1(text = annotatedString("Subtitle1")) }
item { TextSubtitle2(text = annotatedString("Subtitle2")) }
item { TextBody1(text = annotatedString("Body1")) }
item { TextBody2(text = annotatedString("Body2")) }
item { TextButton(text = annotatedString("Button")) }
item { TextCaption(text = annotatedString("Caption")) }
item { TextOverline(text = annotatedString("Overline")) }
}
private fun annotatedString(name: String) = buildAnnotatedString {
append(name)
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append("Annotated")
}
}

View file

@ -10,7 +10,6 @@ android {
dependencies {
api(projects.core.ui.compose.theme)
implementation(libs.androidx.compose.material)
implementation(libs.androidx.compose.material.icons.extended)
testImplementation(projects.core.ui.compose.testing)
}

View file

@ -0,0 +1,47 @@
package app.k9mail.core.ui.compose.designsystem.atom
import androidx.compose.material.LocalContentAlpha
import androidx.compose.material.LocalContentColor
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.theme.Icons
import app.k9mail.core.ui.compose.theme.PreviewWithThemes
import androidx.compose.material.Icon as MaterialIcon
@Composable
fun Icon(
imageVector: ImageVector,
modifier: Modifier = Modifier,
tint: Color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current),
) {
MaterialIcon(
imageVector = imageVector,
contentDescription = null,
modifier = modifier,
tint = tint,
)
}
@Preview(showBackground = true)
@Composable
internal fun IconPreview() {
PreviewWithThemes {
Icon(
imageVector = Icons.error,
)
}
}
@Preview(showBackground = true)
@Composable
internal fun IconTintedPreview() {
PreviewWithThemes {
Icon(
imageVector = Icons.error,
tint = Color.Magenta,
)
}
}

View file

@ -2,12 +2,18 @@ package app.k9mail.core.ui.compose.designsystem.atom.button
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.runtime.Composable
import androidx.compose.ui.unit.Dp
import app.k9mail.core.ui.compose.theme.MainTheme
@Composable
fun buttonContentPadding(): PaddingValues = PaddingValues(
start = MainTheme.spacings.quadruple,
top = MainTheme.spacings.default,
end = MainTheme.spacings.quadruple,
bottom = MainTheme.spacings.default,
fun buttonContentPadding(
start: Dp = MainTheme.spacings.quadruple,
top: Dp = MainTheme.spacings.default,
end: Dp = MainTheme.spacings.quadruple,
bottom: Dp = MainTheme.spacings.default,
): PaddingValues = PaddingValues(
start = start,
top = top,
end = end,
bottom = bottom,
)

View file

@ -2,6 +2,12 @@ package app.k9mail.core.ui.compose.designsystem.atom.text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.theme.MainTheme
import app.k9mail.core.ui.compose.theme.PreviewWithThemes
@ -11,11 +17,27 @@ import androidx.compose.material.Text as MaterialText
fun TextBody1(
text: String,
modifier: Modifier = Modifier,
color: Color = Color.Unspecified,
) {
MaterialText(
text = text,
style = MainTheme.typography.body1,
modifier = modifier,
color = color,
)
}
@Composable
fun TextBody1(
text: AnnotatedString,
modifier: Modifier = Modifier,
color: Color = Color.Unspecified,
) {
MaterialText(
text = text,
style = MainTheme.typography.body1,
modifier = modifier,
color = color,
)
}
@ -26,3 +48,18 @@ internal fun TextBody1Preview() {
TextBody1(text = "TextBody1")
}
}
@Preview(showBackground = true)
@Composable
internal fun TextBody1WithAnnotatedStringPreview() {
PreviewWithThemes {
TextBody1(
text = buildAnnotatedString {
append("Normal")
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append("Annotated")
}
},
)
}
}

View file

@ -2,6 +2,12 @@ package app.k9mail.core.ui.compose.designsystem.atom.text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.theme.MainTheme
import app.k9mail.core.ui.compose.theme.PreviewWithThemes
@ -11,11 +17,27 @@ import androidx.compose.material.Text as MaterialText
fun TextBody2(
text: String,
modifier: Modifier = Modifier,
color: Color = Color.Unspecified,
) {
MaterialText(
text = text,
style = MainTheme.typography.body2,
modifier = modifier,
color = color,
)
}
@Composable
fun TextBody2(
text: AnnotatedString,
modifier: Modifier = Modifier,
color: Color = Color.Unspecified,
) {
MaterialText(
text = text,
style = MainTheme.typography.body2,
modifier = modifier,
color = color,
)
}
@ -26,3 +48,18 @@ internal fun TextBody2Preview() {
TextBody2(text = "TextBody2")
}
}
@Preview(showBackground = true)
@Composable
internal fun TextBody2WithAnnotatedStringPreview() {
PreviewWithThemes {
TextBody2(
text = buildAnnotatedString {
append("Normal")
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append("Annotated")
}
},
)
}
}

View file

@ -2,6 +2,12 @@ package app.k9mail.core.ui.compose.designsystem.atom.text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.theme.MainTheme
import app.k9mail.core.ui.compose.theme.PreviewWithThemes
@ -11,11 +17,31 @@ import androidx.compose.material.Text as MaterialText
fun TextButton(
text: String,
modifier: Modifier = Modifier,
color: Color = Color.Unspecified,
) {
MaterialText(
text = text.uppercase(),
style = MainTheme.typography.button,
modifier = modifier,
color = color,
)
}
@Composable
fun TextButton(
text: AnnotatedString,
modifier: Modifier = Modifier,
color: Color = Color.Unspecified,
) {
MaterialText(
text = AnnotatedString(
text = text.text.uppercase(),
spanStyles = text.spanStyles,
paragraphStyles = text.paragraphStyles,
),
style = MainTheme.typography.button,
modifier = modifier,
color = color,
)
}
@ -26,3 +52,18 @@ internal fun TextButtonPreview() {
TextButton(text = "TextButton")
}
}
@Preview(showBackground = true)
@Composable
internal fun TextButtonWithAnnotatedStringPreview() {
PreviewWithThemes {
TextButton(
text = buildAnnotatedString {
append("Normal")
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append("Annotated")
}
},
)
}
}

View file

@ -2,6 +2,12 @@ package app.k9mail.core.ui.compose.designsystem.atom.text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.theme.MainTheme
import app.k9mail.core.ui.compose.theme.PreviewWithThemes
@ -11,11 +17,27 @@ import androidx.compose.material.Text as MaterialText
fun TextCaption(
text: String,
modifier: Modifier = Modifier,
color: Color = Color.Unspecified,
) {
MaterialText(
text = text,
style = MainTheme.typography.caption,
modifier = modifier,
color = color,
)
}
@Composable
fun TextCaption(
text: AnnotatedString,
modifier: Modifier = Modifier,
color: Color = Color.Unspecified,
) {
MaterialText(
text = text,
style = MainTheme.typography.caption,
modifier = modifier,
color = color,
)
}
@ -26,3 +48,18 @@ internal fun TextCaptionPreview() {
TextCaption(text = "TextCaption")
}
}
@Preview(showBackground = true)
@Composable
internal fun TextCaptionWithAnnotatedStringPreview() {
PreviewWithThemes {
TextCaption(
text = buildAnnotatedString {
append("Normal")
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append("Annotated")
}
},
)
}
}

View file

@ -2,6 +2,12 @@ package app.k9mail.core.ui.compose.designsystem.atom.text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.theme.MainTheme
import app.k9mail.core.ui.compose.theme.PreviewWithThemes
@ -11,11 +17,27 @@ import androidx.compose.material.Text as MaterialText
fun TextHeadline1(
text: String,
modifier: Modifier = Modifier,
color: Color = Color.Unspecified,
) {
MaterialText(
text = text,
style = MainTheme.typography.h1,
modifier = modifier,
color = color,
)
}
@Composable
fun TextHeadline1(
text: AnnotatedString,
modifier: Modifier = Modifier,
color: Color = Color.Unspecified,
) {
MaterialText(
text = text,
style = MainTheme.typography.h1,
modifier = modifier,
color = color,
)
}
@ -26,3 +48,18 @@ internal fun TextHeadline1Preview() {
TextHeadline1(text = "TextHeadline1")
}
}
@Preview(showBackground = true)
@Composable
internal fun TextHeadline1WithAnnotatedStringPreview() {
PreviewWithThemes {
TextHeadline1(
text = buildAnnotatedString {
append("Normal")
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append("Annotated")
}
},
)
}
}

View file

@ -2,6 +2,12 @@ package app.k9mail.core.ui.compose.designsystem.atom.text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.theme.MainTheme
import app.k9mail.core.ui.compose.theme.PreviewWithThemes
@ -11,11 +17,27 @@ import androidx.compose.material.Text as MaterialText
fun TextHeadline2(
text: String,
modifier: Modifier = Modifier,
color: Color = Color.Unspecified,
) {
MaterialText(
text = text,
style = MainTheme.typography.h2,
modifier = modifier,
color = color,
)
}
@Composable
fun TextHeadline2(
text: AnnotatedString,
modifier: Modifier = Modifier,
color: Color = Color.Unspecified,
) {
MaterialText(
text = text,
style = MainTheme.typography.h2,
modifier = modifier,
color = color,
)
}
@ -26,3 +48,18 @@ internal fun TextHeadline2Preview() {
TextHeadline2(text = "TextHeadline2")
}
}
@Preview(showBackground = true)
@Composable
internal fun TextHeadline2WithAnnotatedStringPreview() {
PreviewWithThemes {
TextHeadline2(
text = buildAnnotatedString {
append("Normal")
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append("Annotated")
}
},
)
}
}

View file

@ -2,6 +2,12 @@ package app.k9mail.core.ui.compose.designsystem.atom.text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.theme.MainTheme
import app.k9mail.core.ui.compose.theme.PreviewWithThemes
@ -11,11 +17,27 @@ import androidx.compose.material.Text as MaterialText
fun TextHeadline3(
text: String,
modifier: Modifier = Modifier,
color: Color = Color.Unspecified,
) {
MaterialText(
text = text,
style = MainTheme.typography.h3,
modifier = modifier,
color = color,
)
}
@Composable
fun TextHeadline3(
text: AnnotatedString,
modifier: Modifier = Modifier,
color: Color = Color.Unspecified,
) {
MaterialText(
text = text,
style = MainTheme.typography.h3,
modifier = modifier,
color = color,
)
}
@ -26,3 +48,18 @@ internal fun TextHeadline3Preview() {
TextHeadline3(text = "TextHeadline3")
}
}
@Preview(showBackground = true)
@Composable
internal fun TextHeadline3WithAnnotatedStringPreview() {
PreviewWithThemes {
TextHeadline3(
text = buildAnnotatedString {
append("Normal")
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append("Annotated")
}
},
)
}
}

View file

@ -2,6 +2,12 @@ package app.k9mail.core.ui.compose.designsystem.atom.text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.theme.MainTheme
import app.k9mail.core.ui.compose.theme.PreviewWithThemes
@ -11,11 +17,27 @@ import androidx.compose.material.Text as MaterialText
fun TextHeadline4(
text: String,
modifier: Modifier = Modifier,
color: Color = Color.Unspecified,
) {
MaterialText(
text = text,
style = MainTheme.typography.h4,
modifier = modifier,
color = color,
)
}
@Composable
fun TextHeadline4(
text: AnnotatedString,
modifier: Modifier = Modifier,
color: Color = Color.Unspecified,
) {
MaterialText(
text = text,
style = MainTheme.typography.h4,
modifier = modifier,
color = color,
)
}
@ -26,3 +48,18 @@ internal fun TextHeadline4Preview() {
TextHeadline4(text = "TextHeadline4")
}
}
@Preview(showBackground = true)
@Composable
internal fun TextHeadline4WithAnnotatedStringPreview() {
PreviewWithThemes {
TextHeadline4(
text = buildAnnotatedString {
append("Normal")
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append("Annotated")
}
},
)
}
}

View file

@ -2,6 +2,12 @@ package app.k9mail.core.ui.compose.designsystem.atom.text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.theme.MainTheme
import app.k9mail.core.ui.compose.theme.PreviewWithThemes
@ -11,11 +17,27 @@ import androidx.compose.material.Text as MaterialText
fun TextHeadline5(
text: String,
modifier: Modifier = Modifier,
color: Color = Color.Unspecified,
) {
MaterialText(
text = text,
style = MainTheme.typography.h5,
modifier = modifier,
color = color,
)
}
@Composable
fun TextHeadline5(
text: AnnotatedString,
modifier: Modifier = Modifier,
color: Color = Color.Unspecified,
) {
MaterialText(
text = text,
style = MainTheme.typography.h5,
modifier = modifier,
color = color,
)
}
@ -26,3 +48,18 @@ internal fun TextHeadline5Preview() {
TextHeadline5(text = "TextHeadline5")
}
}
@Preview(showBackground = true)
@Composable
internal fun TextHeadline5WithAnnotatedStringPreview() {
PreviewWithThemes {
TextHeadline5(
text = buildAnnotatedString {
append("Normal")
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append("Annotated")
}
},
)
}
}

View file

@ -2,6 +2,12 @@ package app.k9mail.core.ui.compose.designsystem.atom.text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.theme.MainTheme
import app.k9mail.core.ui.compose.theme.PreviewWithThemes
@ -11,11 +17,27 @@ import androidx.compose.material.Text as MaterialText
fun TextHeadline6(
text: String,
modifier: Modifier = Modifier,
color: Color = Color.Unspecified,
) {
MaterialText(
text = text,
style = MainTheme.typography.h6,
modifier = modifier,
color = color,
)
}
@Composable
fun TextHeadline6(
text: AnnotatedString,
modifier: Modifier = Modifier,
color: Color = Color.Unspecified,
) {
MaterialText(
text = text,
style = MainTheme.typography.h6,
modifier = modifier,
color = color,
)
}
@ -26,3 +48,18 @@ internal fun TextHeadline6Preview() {
TextHeadline6(text = "TextHeadline6")
}
}
@Preview(showBackground = true)
@Composable
internal fun TextHeadline6WithAnnotatedStringPreview() {
PreviewWithThemes {
TextHeadline6(
text = buildAnnotatedString {
append("Normal")
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append("Annotated")
}
},
)
}
}

View file

@ -2,6 +2,12 @@ package app.k9mail.core.ui.compose.designsystem.atom.text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.theme.MainTheme
import app.k9mail.core.ui.compose.theme.PreviewWithThemes
@ -11,11 +17,31 @@ import androidx.compose.material.Text as MaterialText
fun TextOverline(
text: String,
modifier: Modifier = Modifier,
color: Color = Color.Unspecified,
) {
MaterialText(
text = text.uppercase(),
style = MainTheme.typography.overline,
modifier = modifier,
color = color,
)
}
@Composable
fun TextOverline(
text: AnnotatedString,
modifier: Modifier = Modifier,
color: Color = Color.Unspecified,
) {
MaterialText(
text = AnnotatedString(
text = text.text.uppercase(),
spanStyles = text.spanStyles,
paragraphStyles = text.paragraphStyles,
),
style = MainTheme.typography.overline,
modifier = modifier,
color = color,
)
}
@ -26,3 +52,18 @@ internal fun TextOverlinePreview() {
TextOverline(text = "TextOverline")
}
}
@Preview(showBackground = true)
@Composable
internal fun TextOverlineWithAnnotatedStringPreview() {
PreviewWithThemes {
TextOverline(
text = buildAnnotatedString {
append("Normal")
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append("Annotated")
}
},
)
}
}

View file

@ -2,6 +2,12 @@ package app.k9mail.core.ui.compose.designsystem.atom.text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.theme.MainTheme
import app.k9mail.core.ui.compose.theme.PreviewWithThemes
@ -11,11 +17,27 @@ import androidx.compose.material.Text as MaterialText
fun TextSubtitle1(
text: String,
modifier: Modifier = Modifier,
color: Color = Color.Unspecified,
) {
MaterialText(
text = text,
style = MainTheme.typography.subtitle1,
modifier = modifier,
color = color,
)
}
@Composable
fun TextSubtitle1(
text: AnnotatedString,
modifier: Modifier = Modifier,
color: Color = Color.Unspecified,
) {
MaterialText(
text = text,
style = MainTheme.typography.subtitle1,
modifier = modifier,
color = color,
)
}
@ -26,3 +48,18 @@ internal fun TextSubtitle1Preview() {
TextSubtitle1(text = "TextSubtitle1")
}
}
@Preview(showBackground = true)
@Composable
internal fun TextSubtitle1WithAnnotatedStringPreview() {
PreviewWithThemes {
TextSubtitle1(
text = buildAnnotatedString {
append("Normal")
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append("Annotated")
}
},
)
}
}

View file

@ -2,6 +2,12 @@ package app.k9mail.core.ui.compose.designsystem.atom.text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.theme.MainTheme
import app.k9mail.core.ui.compose.theme.PreviewWithThemes
@ -11,11 +17,27 @@ import androidx.compose.material.Text as MaterialText
fun TextSubtitle2(
text: String,
modifier: Modifier = Modifier,
color: Color = Color.Unspecified,
) {
MaterialText(
text = text,
style = MainTheme.typography.subtitle2,
modifier = modifier,
color = color,
)
}
@Composable
fun TextSubtitle2(
text: AnnotatedString,
modifier: Modifier = Modifier,
color: Color = Color.Unspecified,
) {
MaterialText(
text = text,
style = MainTheme.typography.subtitle2,
modifier = modifier,
color = color,
)
}
@ -26,3 +48,18 @@ internal fun TextSubtitle2Preview() {
TextSubtitle2(text = "TextSubtitle2")
}
}
@Preview(showBackground = true)
@Composable
internal fun TextSubtitle2WithAnnotatedStringPreview() {
PreviewWithThemes {
TextSubtitle2(
text = buildAnnotatedString {
append("Normal")
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append("Annotated")
}
},
)
}
}

View file

@ -0,0 +1,14 @@
package app.k9mail.core.ui.compose.designsystem.atom.textfield
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
internal fun selectLabel(label: String?): @Composable (() -> Unit)? {
return if (label != null) {
{
Text(text = label)
}
} else {
null
}
}

View file

@ -1,6 +1,5 @@
package app.k9mail.core.ui.compose.designsystem.atom.textfield
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
@ -26,16 +25,6 @@ fun TextFieldOutlined(
)
}
private fun selectLabel(label: String?): @Composable (() -> Unit)? {
return if (label != null) {
{
Text(text = label)
}
} else {
null
}
}
@Preview(showBackground = true)
@Composable
internal fun TextFieldOutlinedPreview() {

View file

@ -0,0 +1,79 @@
package app.k9mail.core.ui.compose.designsystem.atom.textfield
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.theme.PreviewWithThemes
import androidx.compose.material.OutlinedTextField as MaterialOutlinedTextField
@Composable
fun TextFieldOutlinedEmailAddress(
value: String,
onValueChange: (String) -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
label: String? = null,
isError: Boolean = false,
) {
MaterialOutlinedTextField(
value = value,
onValueChange = onValueChange,
modifier = modifier,
enabled = enabled,
label = selectLabel(label),
isError = isError,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Email,
),
singleLine = true,
)
}
@Preview(showBackground = true)
@Composable
internal fun TextFieldOutlinedEmailAddressPreview() {
PreviewWithThemes {
TextFieldOutlined(
value = "Input text",
onValueChange = {},
)
}
}
@Preview(showBackground = true)
@Composable
internal fun TextFieldOutlinedEmailAddressWithLabelPreview() {
PreviewWithThemes {
TextFieldOutlinedEmailAddress(
value = "Input text",
label = "Label",
onValueChange = {},
)
}
}
@Preview(showBackground = true)
@Composable
internal fun TextFieldOutlinedEmailDisabledPreview() {
PreviewWithThemes {
TextFieldOutlinedEmailAddress(
value = "Input text",
onValueChange = {},
enabled = false,
)
}
}
@Preview(showBackground = true)
@Composable
internal fun TextFieldOutlinedEmailErrorPreview() {
PreviewWithThemes {
TextFieldOutlined(
value = "Input text",
onValueChange = {},
isError = true,
)
}
}

View file

@ -3,10 +3,6 @@ package app.k9mail.core.ui.compose.designsystem.atom.textfield
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Visibility
import androidx.compose.material.icons.filled.VisibilityOff
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@ -19,11 +15,12 @@ import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.R
import app.k9mail.core.ui.compose.theme.Icons
import app.k9mail.core.ui.compose.theme.PreviewWithThemes
import androidx.compose.material.OutlinedTextField as MaterialOutlinedTextField
@Composable
fun PasswordTextFieldOutlined(
fun TextFieldOutlinedPassword(
value: String,
onValueChange: (String) -> Unit,
modifier: Modifier = Modifier,
@ -54,16 +51,6 @@ fun PasswordTextFieldOutlined(
)
}
private fun selectLabel(label: String?): @Composable (() -> Unit)? {
return if (label != null) {
{
Text(text = label)
}
} else {
null
}
}
private fun selectTrailingIcon(
isEnabled: Boolean,
isPasswordVisible: Boolean,
@ -73,9 +60,9 @@ private fun selectTrailingIcon(
return if (hasTrailingIcon) {
{
val image = if (isShowPasswordAllowed(isEnabled, isPasswordVisible)) {
Icons.Filled.Visibility
Icons.passwordVisibility
} else {
Icons.Filled.VisibilityOff
Icons.passwordVisibilityOff
}
val description = if (isShowPasswordAllowed(isEnabled, isPasswordVisible)) {
@ -110,7 +97,7 @@ private fun isShowPasswordAllowed(isEnabled: Boolean, isPasswordVisible: Boolean
@Composable
internal fun PasswordTextFieldOutlinedPreview() {
PreviewWithThemes {
PasswordTextFieldOutlined(
TextFieldOutlinedPassword(
value = "Input text",
onValueChange = {},
)
@ -119,9 +106,9 @@ internal fun PasswordTextFieldOutlinedPreview() {
@Preview(showBackground = true)
@Composable
internal fun PasswordTextFieldOutlinedWithLabelPreview() {
internal fun TextFieldOutlinedPasswordWithLabelPreview() {
PreviewWithThemes {
PasswordTextFieldOutlined(
TextFieldOutlinedPassword(
value = "Input text",
label = "Label",
onValueChange = {},
@ -131,9 +118,9 @@ internal fun PasswordTextFieldOutlinedWithLabelPreview() {
@Preview(showBackground = true)
@Composable
internal fun PasswordTextFieldOutlinedDisabledPreview() {
internal fun TextFieldOutlinedPasswordDisabledPreview() {
PreviewWithThemes {
PasswordTextFieldOutlined(
TextFieldOutlinedPassword(
value = "Input text",
onValueChange = {},
enabled = false,
@ -143,9 +130,9 @@ internal fun PasswordTextFieldOutlinedDisabledPreview() {
@Preview(showBackground = true)
@Composable
internal fun PasswordTextFieldOutlinedErrorPreview() {
internal fun TextFieldOutlinedPasswordErrorPreview() {
PreviewWithThemes {
PasswordTextFieldOutlined(
TextFieldOutlinedPassword(
value = "Input text",
onValueChange = {},
isError = true,

View file

@ -0,0 +1,68 @@
package app.k9mail.core.ui.compose.designsystem.molecule
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.R
import app.k9mail.core.ui.compose.designsystem.atom.text.TextCaption
import app.k9mail.core.ui.compose.designsystem.atom.textfield.TextFieldOutlinedEmailAddress
import app.k9mail.core.ui.compose.theme.MainTheme
import app.k9mail.core.ui.compose.theme.PreviewWithThemes
@Composable
fun EmailAddressInput(
onEmailAddressChange: (String) -> Unit,
modifier: Modifier = Modifier,
emailAddress: String = "",
errorMessage: String? = null,
) {
Column(
modifier = Modifier
.padding(
horizontal = MainTheme.spacings.double,
vertical = MainTheme.spacings.default,
)
.then(modifier),
horizontalAlignment = Alignment.CenterHorizontally,
) {
TextFieldOutlinedEmailAddress(
value = emailAddress,
onValueChange = onEmailAddressChange,
label = stringResource(id = R.string.designsystem_molecule_email_address_input_label),
isError = errorMessage != null,
)
AnimatedVisibility(visible = errorMessage != null) {
TextCaption(
text = errorMessage ?: "",
modifier = Modifier.padding(top = MainTheme.spacings.default),
color = MainTheme.colors.error,
)
}
}
}
@Preview(showBackground = true)
@Composable
internal fun EmailAddressInputPreview() {
PreviewWithThemes {
EmailAddressInput(
onEmailAddressChange = {},
)
}
}
@Preview(showBackground = true)
@Composable
internal fun EmailAddressInputWithErrorPreview() {
PreviewWithThemes {
EmailAddressInput(
onEmailAddressChange = {},
errorMessage = "Email address error",
)
}
}

View file

@ -0,0 +1,95 @@
package app.k9mail.core.ui.compose.designsystem.molecule
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.R
import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonText
import app.k9mail.core.ui.compose.designsystem.atom.button.buttonContentPadding
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBody2
import app.k9mail.core.ui.compose.designsystem.atom.text.TextSubtitle1
import app.k9mail.core.ui.compose.theme.Icons
import app.k9mail.core.ui.compose.theme.MainTheme
import app.k9mail.core.ui.compose.theme.PreviewWithThemes
@Composable
fun ErrorView(
title: String,
modifier: Modifier = Modifier,
message: String? = null,
onRetry: () -> Unit = { },
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(
vertical = MainTheme.spacings.default,
horizontal = MainTheme.spacings.double,
)
.then(modifier),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(MainTheme.spacings.default),
) {
Icon(
imageVector = Icons.error,
contentDescription = null,
tint = MainTheme.colors.error,
modifier = Modifier.padding(top = MainTheme.spacings.default),
)
TextSubtitle1(
text = title,
modifier = Modifier.padding(bottom = MainTheme.spacings.default),
)
if (message != null) {
TextBody2(
text = message,
modifier = Modifier
.fillMaxWidth(),
)
}
Row(
modifier = Modifier
.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.End,
) {
ButtonText(
text = stringResource(id = R.string.designsystem_molecule_error_view_button_retry),
onClick = onRetry,
contentPadding = buttonContentPadding(
start = MainTheme.spacings.double,
end = MainTheme.spacings.double,
),
)
}
}
}
@Preview(showBackground = true)
@Composable
internal fun ErrorViewPreview() {
PreviewWithThemes {
ErrorView(
title = "Error",
)
}
}
@Preview(showBackground = true)
@Composable
internal fun ErrorViewWithMessagePreview() {
PreviewWithThemes {
ErrorView(
title = "Error",
message = "Something went wrong.",
)
}
}

View file

@ -0,0 +1,57 @@
package app.k9mail.core.ui.compose.designsystem.molecule
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.atom.CircularProgressIndicator
import app.k9mail.core.ui.compose.designsystem.atom.text.TextSubtitle1
import app.k9mail.core.ui.compose.theme.MainTheme
import app.k9mail.core.ui.compose.theme.PreviewWithThemes
@Composable
fun LoadingView(
modifier: Modifier = Modifier,
message: String? = null,
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(MainTheme.spacings.default)
.then(modifier),
horizontalAlignment = Alignment.CenterHorizontally,
) {
if (message != null) {
TextSubtitle1(text = message)
}
Row(
modifier = Modifier.height(MainTheme.sizes.larger),
verticalAlignment = Alignment.CenterVertically,
) {
CircularProgressIndicator()
}
}
}
@Preview(showBackground = true)
@Composable
internal fun LoadingViewPreview() {
PreviewWithThemes {
LoadingView()
}
}
@Preview(showBackground = true)
@Composable
internal fun LoadingViewWithMessagePreview() {
PreviewWithThemes {
LoadingView(
message = "Loading ...",
)
}
}

View file

@ -0,0 +1,68 @@
package app.k9mail.core.ui.compose.designsystem.molecule
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.R
import app.k9mail.core.ui.compose.designsystem.atom.text.TextCaption
import app.k9mail.core.ui.compose.designsystem.atom.textfield.TextFieldOutlinedPassword
import app.k9mail.core.ui.compose.theme.MainTheme
import app.k9mail.core.ui.compose.theme.PreviewWithThemes
@Composable
fun PasswordInput(
onPasswordChange: (String) -> Unit,
modifier: Modifier = Modifier,
password: String = "",
errorMessage: String? = null,
) {
Column(
modifier = Modifier
.padding(
horizontal = MainTheme.spacings.double,
vertical = MainTheme.spacings.default,
)
.then(modifier),
horizontalAlignment = Alignment.CenterHorizontally,
) {
TextFieldOutlinedPassword(
value = password,
onValueChange = onPasswordChange,
label = stringResource(id = R.string.designsystem_molecule_password_input_label),
isError = errorMessage != null,
)
AnimatedVisibility(visible = errorMessage != null) {
TextCaption(
text = errorMessage ?: "",
modifier = Modifier.padding(top = MainTheme.spacings.default),
color = MainTheme.colors.error,
)
}
}
}
@Preview(showBackground = true)
@Composable
internal fun PasswordInputPreview() {
PreviewWithThemes {
PasswordInput(
onPasswordChange = {},
)
}
}
@Preview(showBackground = true)
@Composable
internal fun PasswordInputWithErrorPreview() {
PreviewWithThemes {
PasswordInput(
onPasswordChange = {},
errorMessage = "Password error",
)
}
}

View file

@ -2,4 +2,7 @@
<resources>
<string name="designsystem_atom_password_textfield_hide_password">Hide password</string>
<string name="designsystem_atom_password_textfield_show_password">Show password</string>
<string name="designsystem_molecule_email_address_input_label">Email address</string>
<string name="designsystem_molecule_password_input_label">Password</string>
<string name="designsystem_molecule_error_view_button_retry">Retry</string>
</resources>

View file

@ -106,6 +106,7 @@ class TextFieldKtTest(
companion object {
@JvmStatic
@ParameterizedRobolectricTestRunner.Parameters(name = "{0}")
@Suppress("LongMethod")
fun data(): List<TextFieldTestData> = listOf(
TextFieldTestData(
name = "TextFieldOutlined",
@ -129,10 +130,10 @@ class TextFieldKtTest(
},
),
TextFieldTestData(
name = "PasswordTextFieldOutlined",
name = "TextFieldOutlinedPassword",
content = { value, onValueChange, modifier, enabled, label ->
if (enabled != null) {
PasswordTextFieldOutlined(
TextFieldOutlinedPassword(
value = value,
onValueChange = onValueChange,
modifier = modifier,
@ -140,7 +141,28 @@ class TextFieldKtTest(
label = label,
)
} else {
PasswordTextFieldOutlined(
TextFieldOutlinedPassword(
value = value,
onValueChange = onValueChange,
modifier = modifier,
label = label,
)
}
},
),
TextFieldTestData(
name = "TextFieldOutlinedEmail",
content = { value, onValueChange, modifier, enabled, label ->
if (enabled != null) {
TextFieldOutlinedEmailAddress(
value = value,
onValueChange = onValueChange,
modifier = modifier,
enabled = enabled,
label = label,
)
} else {
TextFieldOutlinedEmailAddress(
value = value,
onValueChange = onValueChange,
modifier = modifier,

View file

@ -12,12 +12,12 @@ import org.junit.Test
private const val PASSWORD = "Password input"
class PasswordTextFieldOutlinedKtTest : ComposeTest() {
class TextFieldOutlinedPasswordKtTest : ComposeTest() {
@Test
fun `should not display password by default`() = runComposeTest {
setContent {
PasswordTextFieldOutlined(
TextFieldOutlinedPassword(
value = PASSWORD,
onValueChange = {},
)
@ -29,7 +29,7 @@ class PasswordTextFieldOutlinedKtTest : ComposeTest() {
@Test
fun `should display password when show password is clicked`() = runComposeTest {
setContent {
PasswordTextFieldOutlined(
TextFieldOutlinedPassword(
value = PASSWORD,
onValueChange = {},
)
@ -43,7 +43,7 @@ class PasswordTextFieldOutlinedKtTest : ComposeTest() {
@Test
fun `should not display password when hide password is clicked`() = runComposeTest {
setContent {
PasswordTextFieldOutlined(
TextFieldOutlinedPassword(
value = PASSWORD,
onValueChange = {},
)
@ -58,7 +58,7 @@ class PasswordTextFieldOutlinedKtTest : ComposeTest() {
@Test
fun `should display hide password icon when show password is clicked`() = runComposeTest {
setContent {
PasswordTextFieldOutlined(
TextFieldOutlinedPassword(
value = PASSWORD,
onValueChange = {},
)
@ -72,7 +72,7 @@ class PasswordTextFieldOutlinedKtTest : ComposeTest() {
@Test
fun `should display show password icon when hide password icon is clicked`() = runComposeTest {
setContent {
PasswordTextFieldOutlined(
TextFieldOutlinedPassword(
value = PASSWORD,
onValueChange = {},
)

View file

@ -11,4 +11,5 @@ dependencies {
api(projects.core.ui.compose.common)
implementation(libs.accompanist.systemuicontroller)
implementation(libs.androidx.compose.material)
implementation(libs.androidx.compose.material.icons.extended)
}

View file

@ -0,0 +1,12 @@
package app.k9mail.core.ui.compose.theme
import androidx.compose.material.icons.filled.Error
import androidx.compose.material.icons.filled.Visibility
import androidx.compose.material.icons.filled.VisibilityOff
import androidx.compose.material.icons.Icons as MaterialIcons
object Icons {
val error = MaterialIcons.Filled.Error
val passwordVisibility = MaterialIcons.Filled.Visibility
val passwordVisibilityOff = MaterialIcons.Filled.VisibilityOff
}