Repo created

This commit is contained in:
Fr4nz D13trich 2025-11-22 13:56:56 +01:00
parent 75dc487a7a
commit 39c29d175b
6317 changed files with 388324 additions and 2 deletions

View file

@ -0,0 +1,39 @@
## Core - UI - Compose - Design system
Uses [`:core:ui:compose:theme`](../theme/README.md)
## Background
[Jetpack Compose](https://developer.android.com/jetpack/compose) is a declarative UI toolkit for Android that provides a modern and efficient way to build UIs for Android apps. In this context, design systems and atomic design can help designers and developers create more scalable, maintainable, and reusable UIs.
### Design system
A design system is a collection of guidelines, principles, and tools that help teams create consistent and cohesive visual designs and user experiences.
It typically includes a set of reusable components, such as icons, typography, color palettes, and layouts, that can be combined and customized to create new designs.
The design system also provides documentation and resources for designers and developers to ensure that the designs are implemented consistently and efficiently across all platforms and devices.
The goal of a design system is to streamline the design process, improve design quality, and maintain brand consistency.
An example is Google's [Material Design](https://m3.material.io/) that is used to develop cohesive apps.
### Atomic Design
![Atomic design](assets/images/atomic_design.svg)
Atomic design is a methodology for creating user interfaces (UI) in a design system by breaking them down into smaller, reusable components.
These components are classified into five categories based on their level of abstraction: **atoms**, **molecules**, **organisms**, **templates**, and **pages**.
- **Atoms** are the smallest building blocks, such as buttons, labels, and input fields and could be combined to create more complex components.
- **Molecules** are groups of atoms that work together, like search bars, forms or menus
- **Organisms** are more complex components that combine molecules and atoms, such as headers or cards.
- **Templates** are pages with placeholders for components
- **Pages** are the final UI
By using atomic design, designers and developers can create more consistent and reusable UIs.
This can save time and improve the overall quality, as well as facilitate collaboration between team members.
## Acknowledgement
- [Atomic Design Methodology | Atomic Design by Brad Frost](https://atomicdesign.bradfrost.com/chapter-2/)
- [Atomic Design: Getting Started | Blog | We Are Mobile First](https://www.wearemobilefirst.com/blog/atomic-design)

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 17 KiB

View file

@ -0,0 +1,33 @@
plugins {
id(ThunderbirdPlugins.Library.androidCompose)
alias(libs.plugins.kotlin.parcelize)
}
android {
namespace = "app.k9mail.core.ui.compose.designsystem"
resourcePrefix = "designsystem_"
}
dependencies {
api(projects.core.ui.compose.theme2.common)
debugApi(projects.core.ui.compose.theme2.k9mail)
debugApi(projects.core.ui.compose.theme2.thunderbird)
implementation(libs.androidx.autofill)
implementation(libs.androidx.compose.material3)
implementation(libs.androidx.compose.material3.adaptive)
implementation(libs.androidx.compose.material3.adaptive.layout)
implementation(libs.androidx.compose.material3.adaptive.navigation)
implementation(libs.androidx.compose.material.icons.extended)
// Landscapist imports a lot of dependencies that we don't need. We exclude them here.
implementation(libs.lanscapist.coil) {
exclude(group = "io.coil-kt", module = "coil-gif")
exclude(group = "io.coil-kt", module = "coil-video")
exclude(group = "io.coil-kt.coil3", module = "coil-network-ktor3")
exclude(group = "io.ktor")
}
testImplementation(projects.core.ui.compose.testing)
}

View file

@ -0,0 +1,13 @@
package app.k9mail.core.ui.compose.designsystem
import android.content.res.Configuration.UI_MODE_NIGHT_YES
import android.content.res.Configuration.UI_MODE_TYPE_NORMAL
import androidx.compose.ui.tooling.preview.Preview
@Preview(name = "Light", device = "spec:width=673dp,height=841dp,orientation=landscape")
@Preview(
name = "Dark",
uiMode = UI_MODE_NIGHT_YES or UI_MODE_TYPE_NORMAL,
device = "spec:width=673dp,height=841dp,orientation=landscape",
)
annotation class PreviewLightDarkLandscape

View file

@ -0,0 +1,108 @@
package app.k9mail.core.ui.compose.designsystem
import androidx.compose.foundation.background
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.movableContentOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import app.k9mail.core.ui.compose.theme2.MainTheme
/**
* A Composable function that displays a preview of the content in both Thunderbird and K-9 Mail themes.
*
* It uses the current system theme (light or dark) for both previews.
*
* @param modifier The modifier to be applied to the layout.
* @param useRow Whether to display the previews in a row or column. Defaults to `false` (column).
* @param useScrim Whether to display a scrim behind the content. Defaults to `false`.
* @param scrimAlpha The alpha value for the scrim. Defaults to `0.8f`.
* @param scrimPadding The padding for the scrim. Defaults to `MainTheme.spacings.triple`.
* @param arrangement The arrangement for the previews. Defaults to `Arrangement.spacedBy(MainTheme.spacings.triple)`.
* @param content The content to be displayed in the previews.
*
* @see app.k9mail.core.ui.compose.theme2.default.defaultThemeSpacings for MainTheme.spacings
*/
@Composable
fun PreviewWithThemesLightDark(
modifier: Modifier = Modifier,
useRow: Boolean = false,
useScrim: Boolean = false,
scrimAlpha: Float = 0.8f,
scrimPadding: PaddingValues = PaddingValues(24.dp),
arrangement: Arrangement.HorizontalOrVertical = Arrangement.spacedBy(24.dp),
content: @Composable () -> Unit,
) {
val movableContent = remember {
movableContentOf {
PreviewWithThemeLightDark(
themeType = PreviewThemeType.THUNDERBIRD,
useScrim = useScrim,
scrimAlpha = scrimAlpha,
scrimPadding = scrimPadding,
content = content,
)
PreviewWithThemeLightDark(
themeType = PreviewThemeType.K9MAIL,
useScrim = useScrim,
scrimAlpha = scrimAlpha,
scrimPadding = scrimPadding,
content = content,
)
}
}
if (useRow) {
Row(
horizontalArrangement = arrangement,
modifier = modifier,
) {
movableContent()
}
} else {
Column(
verticalArrangement = arrangement,
modifier = modifier,
) {
movableContent()
}
}
}
@Suppress("ModifierMissing")
@Composable
fun PreviewWithThemeLightDark(
themeType: PreviewThemeType = PreviewThemeType.THUNDERBIRD,
useScrim: Boolean = false,
scrimAlpha: Float = 0f,
scrimPadding: PaddingValues = PaddingValues(0.dp),
content: @Composable (() -> Unit),
) {
val movableContent = remember { movableContentOf { content() } }
PreviewWithTheme(
themeType = themeType,
isDarkTheme = isSystemInDarkTheme(),
) {
PreviewSurface {
if (useScrim) {
Box(
modifier = Modifier
.background(MainTheme.colors.scrim.copy(alpha = scrimAlpha))
.padding(scrimPadding),
) {
movableContent()
}
} else {
movableContent()
}
PreviewHeader(themeName = themeType.name)
}
}
}

View file

@ -0,0 +1,127 @@
package app.k9mail.core.ui.compose.designsystem
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.sp
import app.k9mail.core.ui.compose.theme2.MainTheme
import app.k9mail.core.ui.compose.theme2.k9mail.K9MailTheme2
import app.k9mail.core.ui.compose.theme2.thunderbird.ThunderbirdTheme2
@Composable
fun PreviewWithThemes(
modifier: Modifier = Modifier,
content: @Composable () -> Unit,
) {
Column(
modifier = modifier,
) {
K9MailTheme2 {
PreviewSurface {
Column {
PreviewHeader(themeName = "K9Theme Light")
content()
}
}
}
K9MailTheme2(darkTheme = true) {
PreviewSurface {
Column {
PreviewHeader(themeName = "K9Theme Dark")
content()
}
}
}
ThunderbirdTheme2 {
PreviewSurface {
Column {
PreviewHeader(themeName = "ThunderbirdTheme Light")
content()
}
}
}
ThunderbirdTheme2(darkTheme = true) {
PreviewSurface {
Column {
PreviewHeader(themeName = "ThunderbirdTheme Dark")
content()
}
}
}
}
}
enum class PreviewThemeType {
K9MAIL,
THUNDERBIRD,
}
@Composable
fun PreviewWithTheme(
themeType: PreviewThemeType = PreviewThemeType.THUNDERBIRD,
isDarkTheme: Boolean = false,
content: @Composable () -> Unit,
) {
when (themeType) {
PreviewThemeType.K9MAIL -> {
PreviewWithK9MailTheme(isDarkTheme, content)
}
PreviewThemeType.THUNDERBIRD -> {
PreviewWithThunderbirdTheme(isDarkTheme, content)
}
}
}
@Composable
private fun PreviewWithK9MailTheme(
isDarkTheme: Boolean,
content: @Composable () -> Unit,
) {
K9MailTheme2(
darkTheme = isDarkTheme,
content = content,
)
}
@Composable
private fun PreviewWithThunderbirdTheme(
isDarkTheme: Boolean,
content: @Composable () -> Unit,
) {
ThunderbirdTheme2(
darkTheme = isDarkTheme,
content = content,
)
}
@Composable
internal fun PreviewHeader(
themeName: String,
) {
Surface(
color = MainTheme.colors.primary,
) {
Text(
text = themeName,
fontSize = 4.sp,
modifier = Modifier.padding(
start = MainTheme.spacings.half,
end = MainTheme.spacings.half,
),
)
}
}
@Composable
internal fun PreviewSurface(
content: @Composable () -> Unit,
) {
Surface(
color = MainTheme.colors.surface,
content = content,
)
}

View file

@ -0,0 +1,28 @@
package app.k9mail.core.ui.compose.designsystem.atom
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
@Composable
@Preview(showBackground = true)
internal fun CheckboxPreview() {
PreviewWithThemes {
Checkbox(
checked = true,
onCheckedChange = {},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun CheckboxDisabledPreview() {
PreviewWithThemes {
Checkbox(
checked = true,
onCheckedChange = {},
enabled = false,
)
}
}

View file

@ -0,0 +1,27 @@
package app.k9mail.core.ui.compose.designsystem.atom
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.theme2.MainTheme
@Composable
@Preview(showBackground = true)
internal fun CircularProgressIndicatorPreview() {
PreviewWithThemes {
CircularProgressIndicator(
progress = { 0.75f },
)
}
}
@Composable
@Preview(showBackground = true)
internal fun CircularProgressIndicatorColoredPreview() {
PreviewWithThemes {
CircularProgressIndicator(
progress = { 0.75f },
color = MainTheme.colors.secondary,
)
}
}

View file

@ -0,0 +1,26 @@
package app.k9mail.core.ui.compose.designsystem.atom
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.theme2.MainTheme
@Composable
@Preview(showBackground = true)
internal fun DividerHorizontalPreview() {
PreviewWithThemes {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(MainTheme.spacings.double),
) {
DividerHorizontal(
modifier = Modifier.fillMaxWidth(),
)
}
}
}

View file

@ -0,0 +1,26 @@
package app.k9mail.core.ui.compose.designsystem.atom
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.theme2.MainTheme
@Composable
@Preview(showBackground = true)
internal fun DividerVerticalPreview() {
PreviewWithThemes {
Row(
modifier = Modifier
.fillMaxHeight()
.padding(MainTheme.spacings.double),
) {
DividerVertical(
modifier = Modifier.fillMaxHeight(),
)
}
}
}

View file

@ -0,0 +1,48 @@
package app.k9mail.core.ui.compose.designsystem.atom
import androidx.compose.foundation.layout.padding
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.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.theme2.MainTheme
import kotlinx.collections.immutable.persistentListOf
val choice = persistentListOf(
Pair("1", "Native Android"),
Pair("2", "Native iOS"),
Pair("3", "KMM"),
Pair("4", "Flutter"),
)
@Composable
@Preview(showBackground = true)
internal fun RadioGroupSelectedPreview() {
PreviewWithThemes {
var selectedOption by remember { mutableStateOf(choice[0]) }
RadioGroup(
onClick = { selectedOption = it },
options = choice,
optionTitle = { it.second },
selectedOption = selectedOption,
modifier = Modifier.padding(MainTheme.spacings.default),
)
}
}
@Composable
@Preview(showBackground = true)
internal fun RadioGroupUnSelectedPreview() {
PreviewWithThemes {
RadioGroup(
onClick = {},
options = choice,
optionTitle = { it.second },
modifier = Modifier.padding(MainTheme.spacings.default),
)
}
}

View file

@ -0,0 +1,37 @@
package app.k9mail.core.ui.compose.designsystem.atom
import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.requiredWidth
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.theme2.MainTheme
@Composable
@Preview(showBackground = true)
internal fun SurfacePreview() {
PreviewWithThemes {
Surface(
modifier = Modifier
.requiredHeight(MainTheme.sizes.larger)
.requiredWidth(MainTheme.sizes.larger),
content = {},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun SurfaceWithShapePreview() {
PreviewWithThemes {
Surface(
modifier = Modifier
.requiredHeight(MainTheme.sizes.larger)
.requiredWidth(MainTheme.sizes.larger),
shape = MainTheme.shapes.small,
color = MainTheme.colors.primary,
content = {},
)
}
}

View file

@ -0,0 +1,28 @@
package app.k9mail.core.ui.compose.designsystem.atom
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
@Composable
@Preview(showBackground = true)
internal fun SwitchPreview() {
PreviewWithThemes {
Switch(
checked = true,
onCheckedChange = {},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun SwitchDisabledPreview() {
PreviewWithThemes {
Switch(
checked = true,
onCheckedChange = {},
enabled = false,
)
}
}

View file

@ -0,0 +1,39 @@
package app.k9mail.core.ui.compose.designsystem.atom.button
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
@Composable
@Preview(showBackground = true)
internal fun ButtonElevatedPreview() {
PreviewWithThemes {
ButtonElevated(
text = "Button Elevated",
onClick = {},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun ButtonElevatedDisabledPreview() {
PreviewWithThemes {
ButtonElevated(
text = "Button Elevated Disabled",
onClick = {},
enabled = false,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun ButtonElevatedMultiLinePreview() {
PreviewWithThemes {
ButtonElevated(
text = "First\nSecond line",
onClick = {},
)
}
}

View file

@ -0,0 +1,39 @@
package app.k9mail.core.ui.compose.designsystem.atom.button
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
@Composable
@Preview(showBackground = true)
internal fun ButtonFilledPreview() {
PreviewWithThemes {
ButtonFilled(
text = "Button Filled",
onClick = {},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun ButtonFilledDisabledPreview() {
PreviewWithThemes {
ButtonFilled(
text = "Button Filled Disabled",
onClick = {},
enabled = false,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun ButtonFilledMultiLinePreview() {
PreviewWithThemes {
ButtonFilled(
text = "First\nSecond line",
onClick = {},
)
}
}

View file

@ -0,0 +1,39 @@
package app.k9mail.core.ui.compose.designsystem.atom.button
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
@Composable
@Preview(showBackground = true)
internal fun ButtonFilledTonalPreview() {
PreviewWithThemes {
ButtonFilledTonal(
text = "Button Filled Tonal",
onClick = {},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun ButtonFilledTonalDisabledPreview() {
PreviewWithThemes {
ButtonFilledTonal(
text = "Button Filled Tonal Disabled",
onClick = {},
enabled = false,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun ButtonFilledTonalMultiLinePreview() {
PreviewWithThemes {
ButtonFilledTonal(
text = "First\nSecond line",
onClick = {},
)
}
}

View file

@ -0,0 +1,28 @@
package app.k9mail.core.ui.compose.designsystem.atom.button
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.designsystem.atom.icon.Icons
@Composable
@Preview(showBackground = true)
internal fun ButtonIconPreview() {
PreviewWithThemes {
ButtonIcon(
onClick = { },
imageVector = Icons.Outlined.Info,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun ButtonIconFilledPreview() {
PreviewWithThemes {
ButtonIcon(
onClick = { },
imageVector = Icons.Filled.Cancel,
)
}
}

View file

@ -0,0 +1,39 @@
package app.k9mail.core.ui.compose.designsystem.atom.button
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
@Composable
@Preview(showBackground = true)
internal fun ButtonOutlinedPreview() {
PreviewWithThemes {
ButtonOutlined(
text = "Button Outlined",
onClick = {},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun ButtonOutlinedDisabledPreview() {
PreviewWithThemes {
ButtonOutlined(
text = "Button Outlined Disabled",
onClick = {},
enabled = false,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun ButtonOutlinedMultiLinePreview() {
PreviewWithThemes {
ButtonOutlined(
text = "First\nSecond line",
onClick = {},
)
}
}

View file

@ -0,0 +1,55 @@
package app.k9mail.core.ui.compose.designsystem.atom.button
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import kotlinx.collections.immutable.persistentListOf
private val options = persistentListOf<String>(
"Option 1",
"Option 2",
"Option 3",
)
@Composable
@Preview(showBackground = true)
internal fun ButtonSegmentedSingleChoicePreview() {
PreviewWithThemes {
ButtonSegmentedSingleChoice(
modifier = Modifier,
onClick = {},
options = options,
optionTitle = { it },
selectedOption = null,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun ButtonSegmentedSingleChoiceWithSelectionPreview() {
PreviewWithThemes {
ButtonSegmentedSingleChoice(
modifier = Modifier,
onClick = {},
options = options,
optionTitle = { it },
selectedOption = options[1],
)
}
}
@Composable
@Preview(showBackground = true)
internal fun ButtonSegmentedSingleChoiceEmptyPreview() {
PreviewWithThemes {
ButtonSegmentedSingleChoice(
modifier = Modifier,
onClick = {},
options = persistentListOf<String>(),
optionTitle = { it },
selectedOption = null,
)
}
}

View file

@ -0,0 +1,52 @@
package app.k9mail.core.ui.compose.designsystem.atom.button
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
@Composable
@Preview(showBackground = true)
internal fun ButtonTextPreview() {
PreviewWithThemes {
ButtonText(
text = "Button Text",
onClick = {},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun ButtonTextColoredPreview() {
PreviewWithThemes {
ButtonText(
text = "Button Text Colored",
onClick = {},
color = Color.Magenta,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun ButtonTextDisabledPreview() {
PreviewWithThemes {
ButtonText(
text = "Button Text Disabled",
onClick = {},
enabled = false,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun ButtonTextMultiLinePreview() {
PreviewWithThemes {
ButtonText(
text = "First\nSecond line",
onClick = {},
)
}
}

View file

@ -0,0 +1,22 @@
package app.k9mail.core.ui.compose.designsystem.atom.card
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBodyMedium
import app.k9mail.core.ui.compose.theme2.MainTheme
@Composable
@Preview(showBackground = true)
internal fun CardElevatedPreview() {
PreviewWithThemes {
CardElevated {
Box(modifier = Modifier.padding(MainTheme.spacings.double)) {
TextBodyMedium("Text in card")
}
}
}
}

View file

@ -0,0 +1,22 @@
package app.k9mail.core.ui.compose.designsystem.atom.card
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBodyMedium
import app.k9mail.core.ui.compose.theme2.MainTheme
@Composable
@Preview(showBackground = true)
internal fun CardFilledPreview() {
PreviewWithThemes {
CardFilled {
Box(modifier = Modifier.padding(MainTheme.spacings.double)) {
TextBodyMedium("Text in card")
}
}
}
}

View file

@ -0,0 +1,25 @@
package app.k9mail.core.ui.compose.designsystem.atom.card
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.PreviewLightDark
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemesLightDark
import app.k9mail.core.ui.compose.designsystem.atom.Surface
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBodyMedium
import app.k9mail.core.ui.compose.theme2.MainTheme
@PreviewLightDark
@Composable
private fun CardOutlinedPreview() {
PreviewWithThemesLightDark {
Surface(modifier = Modifier.padding(MainTheme.spacings.quadruple)) {
CardOutlined {
Box(modifier = Modifier.padding(MainTheme.spacings.double)) {
TextBodyMedium("Text in card")
}
}
}
}
}

View file

@ -0,0 +1,27 @@
package app.k9mail.core.ui.compose.designsystem.atom.icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
@Preview(showBackground = true)
@Composable
internal fun IconPreview() {
PreviewWithThemes {
Icon(
imageVector = Icons.Outlined.Info,
)
}
}
@Preview(showBackground = true)
@Composable
internal fun IconTintedPreview() {
PreviewWithThemes {
Icon(
imageVector = Icons.Outlined.Info,
tint = Color.Magenta,
)
}
}

View file

@ -0,0 +1,76 @@
package app.k9mail.core.ui.compose.designsystem.atom.image
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
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.PreviewWithTheme
import app.k9mail.core.ui.compose.theme2.MainTheme
@Composable
@Preview(showBackground = true)
internal fun FixedScaleImageBottomCenterPreview() {
PreviewWithTheme {
Box(
modifier = Modifier
.width(MainTheme.sizes.huge)
.height(MainTheme.sizes.huge),
) {
FixedScaleImage(
id = MainTheme.images.logo,
alignment = Alignment.BottomCenter,
)
}
}
}
@Composable
@Preview(showBackground = true)
internal fun FixedScaleImageCroppedPreview() {
PreviewWithTheme {
Box(
modifier = Modifier
.width(MainTheme.sizes.medium)
.height(MainTheme.sizes.medium),
) {
FixedScaleImage(
id = MainTheme.images.logo,
)
}
}
}
@Composable
@Preview(showBackground = true)
internal fun FixedScaleImageHorizontallyCroppedPreview() {
PreviewWithTheme {
Box(
modifier = Modifier
.width(MainTheme.sizes.huge)
.height(MainTheme.sizes.medium),
) {
FixedScaleImage(
id = MainTheme.images.logo,
)
}
}
}
@Composable
@Preview(showBackground = true)
internal fun FixedScaleImageVerticallyCroppedPreview() {
PreviewWithTheme {
Box(
modifier = Modifier
.width(MainTheme.sizes.medium)
.height(MainTheme.sizes.huge),
) {
FixedScaleImage(
id = MainTheme.images.logo,
)
}
}
}

View file

@ -0,0 +1,23 @@
package app.k9mail.core.ui.compose.designsystem.atom.image
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithTheme
import app.k9mail.core.ui.compose.designsystem.atom.icon.Icons
import app.k9mail.core.ui.compose.theme2.MainTheme
@Composable
@Preview(showBackground = true)
fun RemoteImagePreview() {
PreviewWithTheme {
val painter = rememberVectorPainter(Icons.Outlined.AccountCircle)
RemoteImage(
url = "",
modifier = Modifier.size(MainTheme.sizes.large),
previewPlaceholder = painter,
)
}
}

View file

@ -0,0 +1,58 @@
package app.k9mail.core.ui.compose.designsystem.atom.text
import androidx.compose.runtime.Composable
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.theme2.MainTheme
@Composable
@Preview(showBackground = true)
internal fun TextBodyLargePreview() {
PreviewWithThemes {
TextBodyLarge(
text = "Text Body Large",
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextBodyLargeWithAnnotatedStringPreview() {
PreviewWithThemes {
TextBodyLarge(
text = buildAnnotatedString {
append("Text Body Large ")
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append("Annotated")
}
},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextBodyLargeWithColorPreview() {
PreviewWithThemes {
TextBodyLarge(
text = "Text Body Large with color",
color = MainTheme.colors.primary,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextBodyLargeWithTextAlignPreview() {
PreviewWithThemes {
TextBodyLarge(
text = "Text Body Large with TextAlign End",
textAlign = TextAlign.End,
)
}
}

View file

@ -0,0 +1,58 @@
package app.k9mail.core.ui.compose.designsystem.atom.text
import androidx.compose.runtime.Composable
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.theme2.MainTheme
@Composable
@Preview(showBackground = true)
internal fun TextBodyMediumPreview() {
PreviewWithThemes {
TextBodyMedium(
text = "Text Body Medium",
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextBodyMediumWithAnnotatedStringPreview() {
PreviewWithThemes {
TextBodyMedium(
text = buildAnnotatedString {
append("Text Body Medium ")
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append("Annotated")
}
},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextBodyMediumWithColorPreview() {
PreviewWithThemes {
TextBodyMedium(
text = "Text Body Medium with color",
color = MainTheme.colors.primary,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextBodyMediumWithTextAlignPreview() {
PreviewWithThemes {
TextBodyMedium(
text = "Text Body Medium with TextAlign End",
textAlign = TextAlign.End,
)
}
}

View file

@ -0,0 +1,58 @@
package app.k9mail.core.ui.compose.designsystem.atom.text
import androidx.compose.runtime.Composable
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.theme2.MainTheme
@Composable
@Preview(showBackground = true)
internal fun TextBodySmallPreview() {
PreviewWithThemes {
TextBodySmall(
text = "Text Body Small",
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextBodySmallWithAnnotatedStringPreview() {
PreviewWithThemes {
TextBodySmall(
text = buildAnnotatedString {
append("Text Body Small ")
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append("Annotated")
}
},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextBodySmallWithColorPreview() {
PreviewWithThemes {
TextBodySmall(
text = "Text Body Small with color",
color = MainTheme.colors.primary,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextBodySmallWithTextAlignPreview() {
PreviewWithThemes {
TextBodySmall(
text = "Text Body Small with TextAlign End",
textAlign = TextAlign.End,
)
}
}

View file

@ -0,0 +1,58 @@
package app.k9mail.core.ui.compose.designsystem.atom.text
import androidx.compose.runtime.Composable
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.theme2.MainTheme
@Composable
@Preview(showBackground = true)
internal fun TextDisplayLargePreview() {
PreviewWithThemes {
TextDisplayLarge(
text = "Text Display Large",
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextDisplayLargeWithAnnotatedStringPreview() {
PreviewWithThemes {
TextDisplayLarge(
text = buildAnnotatedString {
append("Text Display Large ")
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append("Annotated")
}
},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextDisplayLargeWithColorPreview() {
PreviewWithThemes {
TextDisplayLarge(
text = "Text Display Large with color",
color = MainTheme.colors.primary,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextDisplayLargeWithTextAlignPreview() {
PreviewWithThemes {
TextDisplayLarge(
text = "Text Display Large with TextAlign End",
textAlign = TextAlign.End,
)
}
}

View file

@ -0,0 +1,58 @@
package app.k9mail.core.ui.compose.designsystem.atom.text
import androidx.compose.runtime.Composable
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.theme2.MainTheme
@Composable
@Preview(showBackground = true)
internal fun TextDisplayMediumPreview() {
PreviewWithThemes {
TextDisplayMedium(
text = "Text Display Medium",
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextDisplayMediumWithAnnotatedStringPreview() {
PreviewWithThemes {
TextDisplayMedium(
text = buildAnnotatedString {
append("Text Display Medium ")
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append("Annotated")
}
},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextDisplayMediumWithColorPreview() {
PreviewWithThemes {
TextDisplayMedium(
text = "Text Display Medium with color",
color = MainTheme.colors.primary,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextDisplayMediumWithTextAlignPreview() {
PreviewWithThemes {
TextDisplayMedium(
text = "Text Display Medium with TextAlign End",
textAlign = TextAlign.End,
)
}
}

View file

@ -0,0 +1,58 @@
package app.k9mail.core.ui.compose.designsystem.atom.text
import androidx.compose.runtime.Composable
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.theme2.MainTheme
@Composable
@Preview(showBackground = true)
internal fun TextDisplaySmallPreview() {
PreviewWithThemes {
TextDisplaySmall(
text = "Text Display Small",
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextDisplaySmallWithAnnotatedStringPreview() {
PreviewWithThemes {
TextDisplaySmall(
text = buildAnnotatedString {
append("Text Display Small ")
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append("Annotated")
}
},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextDisplaySmallWithColorPreview() {
PreviewWithThemes {
TextDisplaySmall(
text = "Text Display Small with color",
color = MainTheme.colors.primary,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextDisplaySmallWithTextAlignPreview() {
PreviewWithThemes {
TextDisplaySmall(
text = "Text Display Small with TextAlign End",
textAlign = TextAlign.End,
)
}
}

View file

@ -0,0 +1,58 @@
package app.k9mail.core.ui.compose.designsystem.atom.text
import androidx.compose.runtime.Composable
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.theme2.MainTheme
@Composable
@Preview(showBackground = true)
internal fun TextHeadlineLargePreview() {
PreviewWithThemes {
TextHeadlineLarge(
text = "Text Headline Large",
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextHeadlineLargeWithAnnotatedStringPreview() {
PreviewWithThemes {
TextHeadlineLarge(
text = buildAnnotatedString {
append("Text Headline Large ")
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append("Annotated")
}
},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextHeadlineLargeWithColorPreview() {
PreviewWithThemes {
TextHeadlineLarge(
text = "Text Headline Large with color",
color = MainTheme.colors.primary,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextHeadlineLargeWithTextAlignPreview() {
PreviewWithThemes {
TextHeadlineLarge(
text = "Text Headline Large with TextAlign End",
textAlign = TextAlign.End,
)
}
}

View file

@ -0,0 +1,58 @@
package app.k9mail.core.ui.compose.designsystem.atom.text
import androidx.compose.runtime.Composable
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.theme2.MainTheme
@Composable
@Preview(showBackground = true)
internal fun TextHeadlineMediumPreview() {
PreviewWithThemes {
TextHeadlineMedium(
text = "Text Headline Medium",
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextHeadlineMediumWithAnnotatedStringPreview() {
PreviewWithThemes {
TextHeadlineMedium(
text = buildAnnotatedString {
append("Text Headline Medium ")
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append("Annotated")
}
},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextHeadlineMediumWithColorPreview() {
PreviewWithThemes {
TextHeadlineMedium(
text = "Text Headline Medium with color",
color = MainTheme.colors.primary,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextHeadlineMediumWithTextAlignPreview() {
PreviewWithThemes {
TextHeadlineMedium(
text = "Text Headline Medium with TextAlign End",
textAlign = TextAlign.End,
)
}
}

View file

@ -0,0 +1,58 @@
package app.k9mail.core.ui.compose.designsystem.atom.text
import androidx.compose.runtime.Composable
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.theme2.MainTheme
@Composable
@Preview(showBackground = true)
internal fun TextHeadlineSmallPreview() {
PreviewWithThemes {
TextHeadlineSmall(
text = "Text Headline Small",
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextHeadlineSmallWithAnnotatedStringPreview() {
PreviewWithThemes {
TextHeadlineSmall(
text = buildAnnotatedString {
append("Text Headline Small ")
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append("Annotated")
}
},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextHeadlineSmallWithColorPreview() {
PreviewWithThemes {
TextHeadlineSmall(
text = "Text Headline Small with color",
color = MainTheme.colors.primary,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextHeadlineSmallWithTextAlignPreview() {
PreviewWithThemes {
TextHeadlineSmall(
text = "Text Headline Small with TextAlign End",
textAlign = TextAlign.End,
)
}
}

View file

@ -0,0 +1,58 @@
package app.k9mail.core.ui.compose.designsystem.atom.text
import androidx.compose.runtime.Composable
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.theme2.MainTheme
@Composable
@Preview(showBackground = true)
internal fun TextLabelLargePreview() {
PreviewWithThemes {
TextLabelLarge(
text = "Text Label Large",
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextLabelLargeWithAnnotatedStringPreview() {
PreviewWithThemes {
TextLabelLarge(
text = buildAnnotatedString {
append("Text Label Large ")
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append("Annotated")
}
},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextLabelLargeWithColorPreview() {
PreviewWithThemes {
TextLabelLarge(
text = "Text Label Large with color",
color = MainTheme.colors.primary,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextLabelLargeWithTextAlignPreview() {
PreviewWithThemes {
TextLabelLarge(
text = "Text Label Large with TextAlign End",
textAlign = TextAlign.End,
)
}
}

View file

@ -0,0 +1,58 @@
package app.k9mail.core.ui.compose.designsystem.atom.text
import androidx.compose.runtime.Composable
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.theme2.MainTheme
@Composable
@Preview(showBackground = true)
internal fun TextLabelMediumPreview() {
PreviewWithThemes {
TextLabelMedium(
text = "Text Label Medium",
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextLabelMediumWithAnnotatedStringPreview() {
PreviewWithThemes {
TextLabelMedium(
text = buildAnnotatedString {
append("Text Label Medium ")
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append("Annotated")
}
},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextLabelMediumWithColorPreview() {
PreviewWithThemes {
TextLabelMedium(
text = "Text Label Medium with color",
color = MainTheme.colors.primary,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextLabelMediumWithTextAlignPreview() {
PreviewWithThemes {
TextLabelMedium(
text = "Text Label Medium with TextAlign End",
textAlign = TextAlign.End,
)
}
}

View file

@ -0,0 +1,58 @@
package app.k9mail.core.ui.compose.designsystem.atom.text
import androidx.compose.runtime.Composable
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.theme2.MainTheme
@Composable
@Preview(showBackground = true)
internal fun TextLabelSmallPreview() {
PreviewWithThemes {
TextLabelSmall(
text = "Text Label Small",
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextLabelSmallWithAnnotatedStringPreview() {
PreviewWithThemes {
TextLabelSmall(
text = buildAnnotatedString {
append("Text Label Small ")
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append("Annotated")
}
},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextLabelSmallWithColorPreview() {
PreviewWithThemes {
TextLabelSmall(
text = "Text Label Small with color",
color = MainTheme.colors.primary,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextLabelSmallWithTextAlignPreview() {
PreviewWithThemes {
TextLabelSmall(
text = "Text Label Small with TextAlign End",
textAlign = TextAlign.End,
)
}
}

View file

@ -0,0 +1,58 @@
package app.k9mail.core.ui.compose.designsystem.atom.text
import androidx.compose.runtime.Composable
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.theme2.MainTheme
@Composable
@Preview(showBackground = true)
internal fun TextTitleLargePreview() {
PreviewWithThemes {
TextTitleLarge(
text = "Text Title Large",
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextTitleLargeWithAnnotatedStringPreview() {
PreviewWithThemes {
TextTitleLarge(
text = buildAnnotatedString {
append("Text Title Large ")
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append("Annotated")
}
},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextTitleLargeWithColorPreview() {
PreviewWithThemes {
TextTitleLarge(
text = "Text Title Large with color",
color = MainTheme.colors.primary,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextTitleLargeWithTextAlignPreview() {
PreviewWithThemes {
TextTitleLarge(
text = "Text Title Large with TextAlign End",
textAlign = TextAlign.End,
)
}
}

View file

@ -0,0 +1,58 @@
package app.k9mail.core.ui.compose.designsystem.atom.text
import androidx.compose.runtime.Composable
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.theme2.MainTheme
@Composable
@Preview(showBackground = true)
internal fun TextTitleMediumPreview() {
PreviewWithThemes {
TextTitleMedium(
text = "Text Title Medium",
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextTitleMediumWithAnnotatedStringPreview() {
PreviewWithThemes {
TextTitleMedium(
text = buildAnnotatedString {
append("Text Title Medium ")
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append("Annotated")
}
},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextTitleMediumWithColorPreview() {
PreviewWithThemes {
TextTitleMedium(
text = "Text Title Medium with color",
color = MainTheme.colors.primary,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextTitleMediumWithTextAlignPreview() {
PreviewWithThemes {
TextTitleMedium(
text = "Text Title Medium with TextAlign End",
textAlign = TextAlign.End,
)
}
}

View file

@ -0,0 +1,58 @@
package app.k9mail.core.ui.compose.designsystem.atom.text
import androidx.compose.runtime.Composable
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.theme2.MainTheme
@Composable
@Preview(showBackground = true)
internal fun TextTitleSmallPreview() {
PreviewWithThemes {
TextTitleSmall(
text = "Text Title Small",
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextTitleSmallWithAnnotatedStringPreview() {
PreviewWithThemes {
TextTitleSmall(
text = buildAnnotatedString {
append("Text Title Small ")
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append("Annotated")
}
},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextTitleSmallWithColorPreview() {
PreviewWithThemes {
TextTitleSmall(
text = "Text Title Small with color",
color = MainTheme.colors.primary,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextTitleSmallWithTextAlignPreview() {
PreviewWithThemes {
TextTitleSmall(
text = "Text Title Small with TextAlign End",
textAlign = TextAlign.End,
)
}
}

View file

@ -0,0 +1,38 @@
package app.k9mail.core.ui.compose.designsystem.atom.textfield
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
@Composable
@Preview(showBackground = true)
internal fun TextFieldLabelPreview() {
PreviewWithThemes {
TextFieldLabel(
label = "Label",
isRequired = false,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextFieldLabelRequiredPreview() {
PreviewWithThemes {
TextFieldLabel(
label = "Label",
isRequired = true,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextFieldLabelRequiredEmptyLabelPreview() {
PreviewWithThemes {
TextFieldLabel(
label = "",
isRequired = true,
)
}
}

View file

@ -0,0 +1,52 @@
package app.k9mail.core.ui.compose.designsystem.atom.textfield
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
@Composable
@Preview(showBackground = true)
internal fun TextFieldOutlinedEmailAddressPreview() {
PreviewWithThemes {
TextFieldOutlinedEmailAddress(
value = "Input text",
onValueChange = {},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextFieldOutlinedEmailAddressWithLabelPreview() {
PreviewWithThemes {
TextFieldOutlinedEmailAddress(
value = "Input text",
label = "Label",
onValueChange = {},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextFieldOutlinedEmailDisabledPreview() {
PreviewWithThemes {
TextFieldOutlinedEmailAddress(
value = "Input text",
onValueChange = {},
isEnabled = false,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextFieldOutlinedEmailErrorPreview() {
PreviewWithThemes {
TextFieldOutlinedEmailAddress(
value = "Input text",
onValueChange = {},
hasError = true,
)
}
}

View file

@ -0,0 +1,28 @@
package app.k9mail.core.ui.compose.designsystem.atom.textfield
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
@Composable
@Preview(showBackground = true)
internal fun TextFieldOutlinedFakeSelectPreview() {
PreviewWithThemes {
TextFieldOutlinedFakeSelect(
text = "Current value",
onClick = {},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextFieldOutlinedFakeSelectPreviewWithLabel() {
PreviewWithThemes {
TextFieldOutlinedFakeSelect(
text = "Current value",
onClick = {},
label = "Label",
)
}
}

View file

@ -0,0 +1,52 @@
package app.k9mail.core.ui.compose.designsystem.atom.textfield
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
@Composable
@Preview(showBackground = true)
internal fun TextFieldOutlinedNumberPreview() {
PreviewWithThemes {
TextFieldOutlinedNumber(
value = 123L,
onValueChange = {},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextFieldOutlinedNumberWithLabelPreview() {
PreviewWithThemes {
TextFieldOutlinedNumber(
value = 123L,
label = "Label",
onValueChange = {},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextFieldOutlinedNumberDisabledPreview() {
PreviewWithThemes {
TextFieldOutlinedNumber(
value = 123L,
onValueChange = {},
isEnabled = false,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextFieldOutlinedNumberErrorPreview() {
PreviewWithThemes {
TextFieldOutlinedNumber(
value = 123L,
onValueChange = {},
hasError = true,
)
}
}

View file

@ -0,0 +1,52 @@
package app.k9mail.core.ui.compose.designsystem.atom.textfield
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
@Composable
@Preview(showBackground = true)
internal fun TextFieldOutlinedPasswordPreview() {
PreviewWithThemes {
TextFieldOutlinedPassword(
value = "Input text",
onValueChange = {},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextFieldOutlinedPasswordWithLabelPreview() {
PreviewWithThemes {
TextFieldOutlinedPassword(
value = "Input text",
label = "Label",
onValueChange = {},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextFieldOutlinedPasswordDisabledPreview() {
PreviewWithThemes {
TextFieldOutlinedPassword(
value = "Input text",
onValueChange = {},
isEnabled = false,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextFieldOutlinedPasswordErrorPreview() {
PreviewWithThemes {
TextFieldOutlinedPassword(
value = "Input text",
onValueChange = {},
hasError = true,
)
}
}

View file

@ -0,0 +1,80 @@
package app.k9mail.core.ui.compose.designsystem.atom.textfield
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.designsystem.atom.icon.Icon
import app.k9mail.core.ui.compose.designsystem.atom.icon.Icons
@Composable
@Preview(showBackground = true)
internal fun TextFieldOutlinedPreview() {
PreviewWithThemes {
TextFieldOutlined(
value = "Input text",
onValueChange = {},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextFieldOutlinedWithLabelPreview() {
PreviewWithThemes {
TextFieldOutlined(
value = "Input text",
onValueChange = {},
label = "Label",
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextFieldOutlinedDisabledPreview() {
PreviewWithThemes {
TextFieldOutlined(
value = "Input text",
onValueChange = {},
isEnabled = false,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextFieldOutlinedErrorPreview() {
PreviewWithThemes {
TextFieldOutlined(
value = "Input text",
onValueChange = {},
hasError = true,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextFieldOutlinedRequiredPreview() {
PreviewWithThemes {
TextFieldOutlined(
value = "",
onValueChange = {},
label = "Label",
isRequired = true,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextFieldOutlinedWithTrailingIconPreview() {
PreviewWithThemes {
TextFieldOutlined(
value = "",
onValueChange = {},
trailingIcon = { Icon(imageVector = Icons.Outlined.AccountCircle) },
isRequired = true,
)
}
}

View file

@ -0,0 +1,31 @@
package app.k9mail.core.ui.compose.designsystem.atom.textfield
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import kotlinx.collections.immutable.persistentListOf
@Composable
@Preview(showBackground = true)
internal fun TextFieldOutlinedSelectPreview() {
PreviewWithThemes {
TextFieldOutlinedSelect(
options = persistentListOf("Option 1", "Option 2", "Option 3"),
selectedOption = "Option 1",
onValueChange = {},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextFieldOutlinedSelectPreviewWithLabel() {
PreviewWithThemes {
TextFieldOutlinedSelect(
options = persistentListOf("Option 1", "Option 2", "Option 3"),
selectedOption = "Option 1",
onValueChange = {},
label = "Label",
)
}
}

View file

@ -0,0 +1,91 @@
package app.k9mail.core.ui.compose.designsystem.molecule
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.designsystem.atom.text.TextTitleMedium
@Composable
@Preview(showBackground = true)
internal fun ContentLoadingErrorViewContentPreview() {
PreviewWithThemes {
DefaultContentLoadingErrorView(
state = ContentLoadingErrorState.Content,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun ContentLoadingErrorViewLoadingPreview() {
PreviewWithThemes {
DefaultContentLoadingErrorView(
state = ContentLoadingErrorState.Loading,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun ContentLoadingErrorViewErrorPreview() {
PreviewWithThemes {
DefaultContentLoadingErrorView(
state = ContentLoadingErrorState.Error,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun ContentLoadingErrorViewInteractivePreview() {
PreviewWithThemes {
val state = remember {
mutableStateOf<ContentLoadingErrorState>(ContentLoadingErrorState.Loading)
}
DefaultContentLoadingErrorView(
state = state.value,
modifier = Modifier
.clickable {
when (state.value) {
ContentLoadingErrorState.Loading -> {
state.value = ContentLoadingErrorState.Content
}
ContentLoadingErrorState.Content -> {
state.value = ContentLoadingErrorState.Error
}
ContentLoadingErrorState.Error -> {
state.value = ContentLoadingErrorState.Loading
}
}
},
)
}
}
@Composable
private fun DefaultContentLoadingErrorView(
state: ContentLoadingErrorState,
modifier: Modifier = Modifier,
) {
ContentLoadingErrorView(
state = state,
error = {
TextTitleMedium(text = "Error")
},
loading = {
TextTitleMedium(text = "Loading...")
},
content = {
TextTitleMedium(text = "Content")
},
modifier = modifier.fillMaxSize(),
)
}

View file

@ -0,0 +1,79 @@
package app.k9mail.core.ui.compose.designsystem.molecule
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.designsystem.atom.text.TextTitleMedium
@Composable
@Preview(showBackground = true)
fun ContentLoadingViewPreview() {
PreviewWithThemes {
DefaultContentLoadingView(
state = ContentLoadingState.Content,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun ContentLoadingViewLoadingPreview() {
PreviewWithThemes {
DefaultContentLoadingView(
state = ContentLoadingState.Loading,
)
}
}
@Composable
private fun DefaultContentLoadingView(
state: ContentLoadingState,
modifier: Modifier = Modifier,
) {
ContentLoadingView(
state = state,
loading = {
TextTitleMedium(text = "Loading...")
},
content = {
TextTitleMedium(text = "Content")
},
modifier = modifier.fillMaxSize(),
)
}
@Composable
@Preview(showBackground = true)
internal fun ContentLoadingViewInteractivePreview() {
PreviewWithThemes {
val state = remember {
mutableStateOf(State(isLoading = true, content = "Hello world"))
}
ContentLoadingView(
state = state.value,
loading = {
TextTitleMedium(text = "Loading...")
},
content = { targetState ->
TextTitleMedium(text = targetState.content)
},
modifier = Modifier
.clickable {
val currentValue = state.value
state.value = currentValue.copy(isLoading = currentValue.isLoading.not())
}
.fillMaxSize(),
)
}
}
private data class State(
override val isLoading: Boolean,
val content: String,
) : LoadingState

View file

@ -0,0 +1,49 @@
package app.k9mail.core.ui.compose.designsystem.molecule
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
@Composable
@Preview(showBackground = true)
internal fun ErrorViewPreview() {
PreviewWithThemes {
ErrorView(
title = "Error",
)
}
}
@Composable
@Preview(showBackground = true)
internal fun ErrorViewWithMessagePreview() {
PreviewWithThemes {
ErrorView(
title = "Error",
message = "Something went wrong.",
)
}
}
@Composable
@Preview(showBackground = true)
internal fun ErrorViewWithRetryPreview() {
PreviewWithThemes {
ErrorView(
title = "Error",
onRetry = {},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun ErrorViewWithRetryAndMessagePreview() {
PreviewWithThemes {
ErrorView(
title = "Error",
message = "Something went wrong.",
onRetry = {},
)
}
}

View file

@ -0,0 +1,23 @@
package app.k9mail.core.ui.compose.designsystem.molecule
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
@Composable
@Preview(showBackground = true)
internal fun LoadingViewPreview() {
PreviewWithThemes {
LoadingView()
}
}
@Composable
@Preview(showBackground = true)
internal fun LoadingViewWithMessagePreview() {
PreviewWithThemes {
LoadingView(
message = "Loading ...",
)
}
}

View file

@ -0,0 +1,45 @@
package app.k9mail.core.ui.compose.designsystem.molecule
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.designsystem.atom.Surface
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBodyLarge
import app.k9mail.core.ui.compose.theme2.MainTheme
@Composable
@Preview(showBackground = true)
internal fun PullToRefreshBoxPreview() {
PreviewWithThemes {
PullToRefreshBox(
isRefreshing = false,
onRefresh = {},
modifier = Modifier.fillMaxWidth()
.height(MainTheme.sizes.medium),
) {
Surface {
TextBodyLarge("Pull to refresh")
}
}
}
}
@Composable
@Preview(showBackground = true)
internal fun PullToRefreshBoxRefreshingPreview() {
PreviewWithThemes {
PullToRefreshBox(
isRefreshing = true,
onRefresh = {},
modifier = Modifier.fillMaxWidth()
.height(MainTheme.sizes.medium),
) {
Surface {
TextBodyLarge("Refreshing ...")
}
}
}
}

View file

@ -0,0 +1,87 @@
package app.k9mail.core.ui.compose.designsystem.molecule.input
import androidx.compose.runtime.Composable
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextRange
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
@Composable
@Preview(showBackground = true)
internal fun AdvancedTextInputPreview() {
PreviewWithThemes {
AdvancedTextInput(
onTextChange = {},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun AdvancedTextInputIsRequiredPreview() {
PreviewWithThemes {
AdvancedTextInput(
onTextChange = {},
label = "Text input is required",
isRequired = true,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun AdvancedTextInputWithErrorPreview() {
PreviewWithThemes {
AdvancedTextInput(
onTextChange = {},
errorMessage = "Text input error",
)
}
}
@Composable
@Preview(showBackground = true)
internal fun AdvancedTextInputWithAnnotatedStringPreview() {
PreviewWithThemes {
AdvancedTextInput(
onTextChange = {},
text = TextFieldValue(
annotatedString = buildAnnotatedString {
append("Text input with ")
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append("Annotated")
}
},
),
)
}
}
@Composable
@Preview(showBackground = true)
internal fun AdvancedTextInputWithSelectionPreview() {
PreviewWithThemes {
AdvancedTextInput(
onTextChange = {},
text = TextFieldValue("Text input with selection", selection = TextRange(0, 4)),
)
}
}
@Composable
@Preview(showBackground = true)
internal fun AdvancedTextInputWithCompositionPreview() {
PreviewWithThemes {
AdvancedTextInput(
onTextChange = {},
text = TextFieldValue(
text = "Text input with composition",
composition = TextRange(0, 4),
),
)
}
}

View file

@ -0,0 +1,42 @@
package app.k9mail.core.ui.compose.designsystem.molecule.input
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
@Composable
@Preview(showBackground = true)
internal fun CheckboxInputPreview() {
PreviewWithThemes {
CheckboxInput(
text = "CheckboxInput",
checked = false,
onCheckedChange = {},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun CheckboxInputWithErrorPreview() {
PreviewWithThemes {
CheckboxInput(
text = "CheckboxInput",
checked = false,
onCheckedChange = {},
errorMessage = "Error message",
)
}
}
@Composable
@Preview(showBackground = true)
internal fun CheckboxInputCheckedPreview() {
PreviewWithThemes {
CheckboxInput(
text = "CheckboxInput",
checked = true,
onCheckedChange = {},
)
}
}

View file

@ -0,0 +1,26 @@
package app.k9mail.core.ui.compose.designsystem.molecule.input
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
@Composable
@Preview(showBackground = true)
internal fun EmailAddressInputPreview() {
PreviewWithThemes {
EmailAddressInput(
onEmailAddressChange = {},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun EmailAddressInputWithErrorPreview() {
PreviewWithThemes {
EmailAddressInput(
onEmailAddressChange = {},
errorMessage = "Email address error",
)
}
}

View file

@ -0,0 +1,40 @@
package app.k9mail.core.ui.compose.designsystem.molecule.input
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.designsystem.atom.textfield.TextFieldOutlined
@Composable
@Preview(showBackground = true)
internal fun InputLayoutPreview() {
PreviewWithThemes {
InputLayout {
TextFieldOutlined(value = "InputLayout", onValueChange = {})
}
}
}
@Composable
@Preview(showBackground = true)
internal fun InputLayoutWithErrorPreview() {
PreviewWithThemes {
InputLayout(
errorMessage = "Error message",
) {
TextFieldOutlined(value = "InputLayout", onValueChange = {})
}
}
}
@Composable
@Preview(showBackground = true)
internal fun InputLayoutWithWarningPreview() {
PreviewWithThemes {
InputLayout(
warningMessage = "Warning message",
) {
TextFieldOutlined(value = "InputLayout", onValueChange = {})
}
}
}

View file

@ -0,0 +1,38 @@
package app.k9mail.core.ui.compose.designsystem.molecule.input
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
@Composable
@Preview(showBackground = true)
internal fun NumberInputPreview() {
PreviewWithThemes {
NumberInput(
onValueChange = {},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun NumberInputIsRequiredPreview() {
PreviewWithThemes {
NumberInput(
onValueChange = {},
label = "Text input is required",
isRequired = true,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun NumberInputWithErrorPreview() {
PreviewWithThemes {
NumberInput(
onValueChange = {},
errorMessage = "Text input error",
)
}
}

View file

@ -0,0 +1,26 @@
package app.k9mail.core.ui.compose.designsystem.molecule.input
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
@Composable
@Preview(showBackground = true)
internal fun PasswordInputPreview() {
PreviewWithThemes {
PasswordInput(
onPasswordChange = {},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun PasswordInputWithErrorPreview() {
PreviewWithThemes {
PasswordInput(
onPasswordChange = {},
errorMessage = "Password error",
)
}
}

View file

@ -0,0 +1,18 @@
package app.k9mail.core.ui.compose.designsystem.molecule.input
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import kotlinx.collections.immutable.persistentListOf
@Composable
@Preview(showBackground = true)
internal fun SelectInputPreview() {
PreviewWithThemes {
SelectInput(
options = persistentListOf("Option 1", "Option 2", "Option 3"),
selectedOption = "Option 1",
onOptionChange = {},
)
}
}

View file

@ -0,0 +1,42 @@
package app.k9mail.core.ui.compose.designsystem.molecule.input
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
@Composable
@Preview(showBackground = true)
internal fun SwitchInputPreview() {
PreviewWithThemes {
SwitchInput(
text = "SwitchInput",
checked = false,
onCheckedChange = {},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun SwitchInputWithErrorPreview() {
PreviewWithThemes {
SwitchInput(
text = "SwitchInput",
checked = false,
onCheckedChange = {},
errorMessage = "Error message",
)
}
}
@Composable
@Preview(showBackground = true)
internal fun SwitchInputCheckedPreview() {
PreviewWithThemes {
SwitchInput(
text = "SwitchInput",
checked = true,
onCheckedChange = {},
)
}
}

View file

@ -0,0 +1,38 @@
package app.k9mail.core.ui.compose.designsystem.molecule.input
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
@Composable
@Preview(showBackground = true)
internal fun TextInputPreview() {
PreviewWithThemes {
TextInput(
onTextChange = {},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextInputIsRequiredPreview() {
PreviewWithThemes {
TextInput(
onTextChange = {},
label = "Text input is required",
isRequired = true,
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TextInputWithErrorPreview() {
PreviewWithThemes {
TextInput(
onTextChange = {},
errorMessage = "Text input error",
)
}
}

View file

@ -0,0 +1,28 @@
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.PreviewLightDark
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemesLightDark
import app.k9mail.core.ui.compose.designsystem.molecule.notification.NotificationActionButton
import app.k9mail.core.ui.compose.theme2.MainTheme
@PreviewLightDark
@Composable
private fun NotificationActionButtonPreview() {
PreviewWithThemesLightDark {
Column(
verticalArrangement = Arrangement.spacedBy(MainTheme.spacings.default),
) {
NotificationActionButton(
onClick = {},
text = "Sign in",
)
NotificationActionButton(
onClick = {},
text = "View support article",
isExternalLink = true,
)
}
}
}

View file

@ -0,0 +1,80 @@
package app.k9mail.core.ui.compose.designsystem.organism
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithTheme
import app.k9mail.core.ui.compose.designsystem.atom.icon.Icons
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBodyMedium
import app.k9mail.core.ui.compose.theme2.MainTheme
@Composable
@Preview(showBackground = true)
internal fun AlertDialogPreview() {
PreviewWithTheme {
AlertDialog(
title = "Title",
text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " +
"Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
confirmText = "Accept",
onConfirmClick = {},
onDismissRequest = {},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun AlertDialogWithIconPreview() {
PreviewWithTheme {
AlertDialog(
icon = Icons.Outlined.Info,
title = "Title",
text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " +
"Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
confirmText = "Accept",
onConfirmClick = {},
onDismissRequest = {},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun AlertDialogWithCancelPreview() {
PreviewWithTheme {
AlertDialog(
icon = Icons.Outlined.Info,
title = "Title",
text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " +
"Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
confirmText = "Accept",
dismissText = "Cancel",
onConfirmClick = {},
onDismissRequest = {},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun AlertDialogWithCustomContentPreview() {
PreviewWithTheme {
AlertDialog(
icon = Icons.Outlined.Info,
title = "Title",
confirmText = "Accept",
dismissText = "Cancel",
onConfirmClick = {},
onDismissRequest = {},
) {
Column(
verticalArrangement = Arrangement.spacedBy(MainTheme.spacings.double),
) {
TextBodyMedium("Lorem ipsum dolor sit amet, consectetur adipiscing elit.")
TextBodyMedium("Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.")
}
}
}
}

View file

@ -0,0 +1,147 @@
package app.k9mail.core.ui.compose.designsystem.organism
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Refresh
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
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.designsystem.PreviewLightDarkLandscape
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemesLightDark
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBodyMedium
import app.k9mail.core.ui.compose.designsystem.atom.text.TextHeadlineSmall
import app.k9mail.core.ui.compose.theme2.MainTheme
@PreviewLightDarkLandscape
@Composable
private fun BasicDialogPreview() {
PreviewWithThemesLightDark(
useRow = true,
useScrim = true,
scrimPadding = PaddingValues(32.dp),
arrangement = Arrangement.spacedBy(24.dp),
) {
BasicDialogContent(
headline = {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(MainTheme.spacings.double),
modifier = Modifier.fillMaxWidth(),
) {
Icon(imageVector = Icons.Default.Refresh, contentDescription = null)
TextHeadlineSmall(text = "Reset settings?")
}
},
supportingText = {
TextBodyMedium(
text = "This will reset your app preferences back to their default settings. " +
"The following accounts will also be signed out:",
color = MainTheme.colors.onSurfaceVariant,
)
},
content = {
Column(
verticalArrangement = Arrangement.spacedBy(MainTheme.spacings.double),
modifier = Modifier
.fillMaxWidth()
.padding(
start = MainTheme.spacings.triple,
end = MainTheme.spacings.triple,
),
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(MainTheme.spacings.double),
) {
Box(
modifier = Modifier
.size(MainTheme.sizes.iconAvatar)
.background(color = MainTheme.colors.primary, shape = CircleShape),
)
Text(text = "Account 1")
}
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(MainTheme.spacings.double),
) {
Box(
modifier = Modifier
.size(MainTheme.sizes.iconAvatar)
.background(color = MainTheme.colors.primary, shape = CircleShape),
)
Text(text = "Account 2")
}
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(MainTheme.spacings.double),
) {
Box(
modifier = Modifier
.size(MainTheme.sizes.iconAvatar)
.background(color = MainTheme.colors.primary, shape = CircleShape),
)
Text(text = "Account 3")
}
}
},
buttons = {
TextButton(onClick = {}) {
Text(text = "Cancel")
}
TextButton(onClick = {}) {
Text(text = "Accept")
}
},
showDividers = true,
modifier = Modifier.width(300.dp),
)
}
}
@PreviewLightDarkLandscape
@Composable
private fun PreviewOnlySupportingText() {
PreviewWithThemesLightDark(
useRow = true,
useScrim = true,
scrimPadding = PaddingValues(32.dp),
arrangement = Arrangement.spacedBy(24.dp),
) {
BasicDialogContent(
headline = {
TextHeadlineSmall(text = "Email can not be archived")
},
supportingText = {
TextBodyMedium(
text = "Configure archive folder now",
color = MainTheme.colors.onSurfaceVariant,
)
},
content = null,
buttons = {
TextButton(onClick = {}) {
Text(text = "Skip for now")
}
TextButton(onClick = {}) {
Text(text = "Set archive folder")
}
},
showDividers = false,
modifier = Modifier.width(300.dp),
)
}
}

View file

@ -0,0 +1,79 @@
package app.k9mail.core.ui.compose.designsystem.organism
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonIcon
import app.k9mail.core.ui.compose.designsystem.atom.icon.Icons
@Composable
@Preview(showBackground = true)
internal fun SubtitleTopAppBarPreview() {
PreviewWithThemes {
SubtitleTopAppBar(
title = "Title",
subtitle = "Subtitle",
)
}
}
@Composable
@Preview(showBackground = true)
internal fun SubtitleTopAppBarWithLongSubtitlePreview() {
PreviewWithThemes {
SubtitleTopAppBar(
title = "Title",
subtitle = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " +
"Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
)
}
}
@Composable
@Preview(showBackground = true)
internal fun SubtitleTopAppBarWithActionsPreview() {
PreviewWithThemes {
SubtitleTopAppBar(
title = "Title",
subtitle = "Subtitle",
actions = {
ButtonIcon(
onClick = {},
imageVector = Icons.Outlined.Info,
)
ButtonIcon(
onClick = {},
imageVector = Icons.Outlined.Check,
)
ButtonIcon(
onClick = {},
imageVector = Icons.Outlined.Visibility,
)
},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun SubtitleTopAppBarWithMenuButtonPreview() {
PreviewWithThemes {
SubtitleTopAppBarWithMenuButton(
title = "Title",
subtitle = "Subtitle",
onMenuClick = {},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun SubtitleTopAppBarWithBackButtonPreview() {
PreviewWithThemes {
SubtitleTopAppBarWithBackButton(
title = "Title",
subtitle = "Subtitle",
onBackClick = {},
)
}
}

View file

@ -0,0 +1,63 @@
package app.k9mail.core.ui.compose.designsystem.organism
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonIcon
import app.k9mail.core.ui.compose.designsystem.atom.icon.Icons
@Composable
@Preview(showBackground = true)
internal fun TopAppBarPreview() {
PreviewWithThemes {
TopAppBar(
title = "Title",
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TopAppBarWithActionsPreview() {
PreviewWithThemes {
TopAppBar(
title = "Title",
actions = {
ButtonIcon(
onClick = {},
imageVector = Icons.Outlined.Info,
)
ButtonIcon(
onClick = {},
imageVector = Icons.Outlined.Check,
)
ButtonIcon(
onClick = {},
imageVector = Icons.Outlined.Visibility,
)
},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TopAppBarWithMenuButtonPreview() {
PreviewWithThemes {
TopAppBarWithMenuButton(
title = "Title",
onMenuClick = {},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun TopAppBarWithBackButtonPreview() {
PreviewWithThemes {
TopAppBarWithBackButton(
title = "Title",
onBackClick = {},
)
}
}

View file

@ -0,0 +1,68 @@
package app.k9mail.core.ui.compose.designsystem.organism.banner.global
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
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.PreviewLightDark
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemesLightDark
import app.k9mail.core.ui.compose.designsystem.atom.Surface
import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonText
import app.k9mail.core.ui.compose.designsystem.atom.icon.Icon
import app.k9mail.core.ui.compose.designsystem.atom.icon.Icons
import app.k9mail.core.ui.compose.designsystem.atom.icon.outlined.Warning
import app.k9mail.core.ui.compose.designsystem.organism.banner.global.BannerGlobalNotificationCard
import app.k9mail.core.ui.compose.theme2.MainTheme
@PreviewLightDark
@Composable
private fun BannerGlobalNotificationCardStringTitlePreview() {
PreviewWithThemesLightDark {
Surface(
modifier = Modifier.fillMaxWidth(),
) {
BannerGlobalNotificationCard(
icon = { Icon(imageVector = Icons.Outlined.Warning) },
text = "Offline. No internet connection found.",
action = {
ButtonText(
text = "Retry",
onClick = {},
)
},
modifier = Modifier.padding(top = MainTheme.spacings.quadruple),
)
}
}
}
@PreviewLightDark
@Composable
private fun BannerGlobalNotificationCardAnnotatedStringTitlePreview() {
PreviewWithThemesLightDark {
Surface(
modifier = Modifier.fillMaxWidth(),
) {
BannerGlobalNotificationCard(
icon = { Icon(imageVector = Icons.Outlined.Warning) },
text = buildAnnotatedString {
withStyle(SpanStyle(fontWeight = FontWeight.Black)) {
append("Offline. ")
}
append("No internet connection found.")
},
action = {
ButtonText(
text = "Retry",
onClick = {},
)
},
modifier = Modifier.padding(top = MainTheme.spacings.quadruple),
)
}
}
}

View file

@ -0,0 +1,63 @@
package app.k9mail.core.ui.compose.designsystem.organism.banner.global
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
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.PreviewLightDark
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemesLightDark
import app.k9mail.core.ui.compose.designsystem.atom.Surface
import app.k9mail.core.ui.compose.designsystem.molecule.notification.NotificationActionButton
import app.k9mail.core.ui.compose.designsystem.organism.banner.global.ErrorBannerGlobalNotificationCard
import app.k9mail.core.ui.compose.theme2.MainTheme
@PreviewLightDark
@Composable
private fun ErrorBannerGlobalNotificationCardStringTitlePreview() {
PreviewWithThemesLightDark {
Surface(
modifier = Modifier.fillMaxWidth(),
) {
ErrorBannerGlobalNotificationCard(
text = "Offline. No internet connection found.",
action = {
NotificationActionButton(
text = "Retry",
onClick = {},
)
},
modifier = Modifier.padding(top = MainTheme.spacings.quadruple),
)
}
}
}
@PreviewLightDark
@Composable
private fun ErrorBannerGlobalNotificationCardAnnotatedStringTitlePreview() {
PreviewWithThemesLightDark {
Surface(
modifier = Modifier.fillMaxWidth(),
) {
ErrorBannerGlobalNotificationCard(
text = buildAnnotatedString {
withStyle(SpanStyle(fontWeight = FontWeight.Black)) {
append("Offline. ")
}
append("No internet connection found.")
},
action = {
NotificationActionButton(
text = "Retry",
onClick = {},
)
},
modifier = Modifier.padding(top = MainTheme.spacings.quadruple),
)
}
}
}

View file

@ -0,0 +1,120 @@
package app.k9mail.core.ui.compose.designsystem.organism.banner.global
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
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.PreviewLightDark
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.datasource.LoremIpsum
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemesLightDark
import app.k9mail.core.ui.compose.designsystem.atom.Surface
import app.k9mail.core.ui.compose.designsystem.molecule.notification.NotificationActionButton
import app.k9mail.core.ui.compose.designsystem.organism.banner.global.InfoBannerGlobalNotificationCard
import app.k9mail.core.ui.compose.theme2.MainTheme
@PreviewLightDark
@Composable
private fun InfoBannerGlobalNotificationCardStringTitlePreview() {
PreviewWithThemesLightDark {
Surface(
modifier = Modifier.fillMaxWidth(),
) {
InfoBannerGlobalNotificationCard(
text = "Offline. No internet connection found.",
action = {
NotificationActionButton(
text = "Retry",
onClick = {},
)
},
modifier = Modifier.padding(top = MainTheme.spacings.quadruple),
)
}
}
}
@PreviewLightDark
@Composable
private fun InfoBannerGlobalNotificationCardNoActionPreview() {
PreviewWithThemesLightDark {
Surface(
modifier = Modifier.fillMaxWidth(),
) {
InfoBannerGlobalNotificationCard(
text = "Offline. No internet connection found.",
modifier = Modifier.padding(top = MainTheme.spacings.quadruple),
)
}
}
}
@PreviewLightDark
@Composable
private fun InfoBannerGlobalNotificationCardLongTextPreview(
@PreviewParameter(LoremIpsum::class) text: String,
) {
PreviewWithThemesLightDark {
Surface(
modifier = Modifier.fillMaxWidth(),
) {
InfoBannerGlobalNotificationCard(
text = text,
action = {
NotificationActionButton(
text = "Retry",
onClick = {},
)
},
modifier = Modifier.padding(top = MainTheme.spacings.quadruple),
)
}
}
}
@PreviewLightDark
@Composable
private fun InfoBannerGlobalNotificationCardLongNoActionTextPreview(
@PreviewParameter(LoremIpsum::class) text: String,
) {
PreviewWithThemesLightDark {
Surface(
modifier = Modifier.fillMaxWidth(),
) {
InfoBannerGlobalNotificationCard(
text = text,
modifier = Modifier.padding(top = MainTheme.spacings.quadruple),
)
}
}
}
@PreviewLightDark
@Composable
private fun InfoBannerGlobalNotificationCardAnnotatedStringTitlePreview() {
PreviewWithThemesLightDark {
Surface(
modifier = Modifier.fillMaxWidth(),
) {
InfoBannerGlobalNotificationCard(
text = buildAnnotatedString {
withStyle(SpanStyle(fontWeight = FontWeight.Black)) {
append("Offline. ")
}
append("No internet connection found.")
},
action = {
NotificationActionButton(
text = "Retry",
onClick = {},
)
},
modifier = Modifier.padding(top = MainTheme.spacings.quadruple),
)
}
}
}

View file

@ -0,0 +1,120 @@
package app.k9mail.core.ui.compose.designsystem.organism.banner.global
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
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.PreviewLightDark
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.datasource.LoremIpsum
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemesLightDark
import app.k9mail.core.ui.compose.designsystem.atom.Surface
import app.k9mail.core.ui.compose.designsystem.molecule.notification.NotificationActionButton
import app.k9mail.core.ui.compose.designsystem.organism.banner.global.SuccessBannerGlobalNotificationCard
import app.k9mail.core.ui.compose.theme2.MainTheme
@PreviewLightDark
@Composable
private fun SuccessBannerGlobalNotificationCardStringTitlePreview() {
PreviewWithThemesLightDark {
Surface(
modifier = Modifier.fillMaxWidth(),
) {
SuccessBannerGlobalNotificationCard(
text = "What an awesome notification, isn't it?",
action = {
NotificationActionButton(
text = "Action",
onClick = {},
)
},
modifier = Modifier.padding(top = MainTheme.spacings.quadruple),
)
}
}
}
@PreviewLightDark
@Composable
private fun SuccessBannerGlobalNotificationCardNoActionPreview() {
PreviewWithThemesLightDark {
Surface(
modifier = Modifier.fillMaxWidth(),
) {
SuccessBannerGlobalNotificationCard(
text = "What an awesome notification, isn't it?",
modifier = Modifier.padding(top = MainTheme.spacings.quadruple),
)
}
}
}
@PreviewLightDark
@Composable
private fun SuccessBannerGlobalNotificationCardLongTextPreview(
@PreviewParameter(LoremIpsum::class) text: String,
) {
PreviewWithThemesLightDark {
Surface(
modifier = Modifier.fillMaxWidth(),
) {
SuccessBannerGlobalNotificationCard(
text = text,
action = {
NotificationActionButton(
text = "Retry",
onClick = {},
)
},
modifier = Modifier.padding(top = MainTheme.spacings.quadruple),
)
}
}
}
@PreviewLightDark
@Composable
private fun SuccessBannerGlobalNotificationCardLongNoActionTextPreview(
@PreviewParameter(LoremIpsum::class) text: String,
) {
PreviewWithThemesLightDark {
Surface(
modifier = Modifier.fillMaxWidth(),
) {
SuccessBannerGlobalNotificationCard(
text = text,
modifier = Modifier.padding(top = MainTheme.spacings.quadruple),
)
}
}
}
@PreviewLightDark
@Composable
private fun SuccessBannerGlobalNotificationCardAnnotatedStringTitlePreview() {
PreviewWithThemesLightDark {
Surface(
modifier = Modifier.fillMaxWidth(),
) {
SuccessBannerGlobalNotificationCard(
text = buildAnnotatedString {
withStyle(SpanStyle(fontWeight = FontWeight.Black)) {
append("Offline. ")
}
append("No internet connection found.")
},
action = {
NotificationActionButton(
text = "Retry",
onClick = {},
)
},
modifier = Modifier.padding(top = MainTheme.spacings.quadruple),
)
}
}
}

View file

@ -0,0 +1,120 @@
package app.k9mail.core.ui.compose.designsystem.organism.banner.global
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
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.PreviewLightDark
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.datasource.LoremIpsum
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemesLightDark
import app.k9mail.core.ui.compose.designsystem.atom.Surface
import app.k9mail.core.ui.compose.designsystem.molecule.notification.NotificationActionButton
import app.k9mail.core.ui.compose.designsystem.organism.banner.global.WarningBannerGlobalNotificationCard
import app.k9mail.core.ui.compose.theme2.MainTheme
@PreviewLightDark
@Composable
private fun WarningBannerGlobalNotificationCardStringTitlePreview() {
PreviewWithThemesLightDark {
Surface(
modifier = Modifier.fillMaxWidth(),
) {
WarningBannerGlobalNotificationCard(
text = "Offline. No internet connection found.",
action = {
NotificationActionButton(
text = "Retry",
onClick = {},
)
},
modifier = Modifier.padding(top = MainTheme.spacings.quadruple),
)
}
}
}
@PreviewLightDark
@Composable
private fun WarningBannerGlobalNotificationCardNoActionPreview() {
PreviewWithThemesLightDark {
Surface(
modifier = Modifier.fillMaxWidth(),
) {
WarningBannerGlobalNotificationCard(
text = "Offline. No internet connection found.",
modifier = Modifier.padding(top = MainTheme.spacings.quadruple),
)
}
}
}
@PreviewLightDark
@Composable
private fun WarningBannerGlobalNotificationCardLongTextPreview(
@PreviewParameter(LoremIpsum::class) text: String,
) {
PreviewWithThemesLightDark {
Surface(
modifier = Modifier.fillMaxWidth(),
) {
WarningBannerGlobalNotificationCard(
text = text,
action = {
NotificationActionButton(
text = "Retry",
onClick = {},
)
},
modifier = Modifier.padding(top = MainTheme.spacings.quadruple),
)
}
}
}
@PreviewLightDark
@Composable
private fun WarningBannerGlobalNotificationCardLongNoActionTextPreview(
@PreviewParameter(LoremIpsum::class) text: String,
) {
PreviewWithThemesLightDark {
Surface(
modifier = Modifier.fillMaxWidth(),
) {
WarningBannerGlobalNotificationCard(
text = text,
modifier = Modifier.padding(top = MainTheme.spacings.quadruple),
)
}
}
}
@PreviewLightDark
@Composable
private fun WarningBannerGlobalNotificationCardAnnotatedStringTitlePreview() {
PreviewWithThemesLightDark {
Surface(
modifier = Modifier.fillMaxWidth(),
) {
WarningBannerGlobalNotificationCard(
text = buildAnnotatedString {
withStyle(SpanStyle(fontWeight = FontWeight.Black)) {
append("Offline. ")
}
append("No internet connection found.")
},
action = {
NotificationActionButton(
text = "Retry",
onClick = {},
)
},
modifier = Modifier.padding(top = MainTheme.spacings.quadruple),
)
}
}
}

View file

@ -0,0 +1,151 @@
package app.k9mail.core.ui.compose.designsystem.organism.banner.inline
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
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.PreviewLightDark
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemesLightDark
import app.k9mail.core.ui.compose.designsystem.atom.Surface
import app.k9mail.core.ui.compose.designsystem.atom.icon.Icon
import app.k9mail.core.ui.compose.designsystem.atom.icon.Icons
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBodyMedium
import app.k9mail.core.ui.compose.designsystem.atom.text.TextTitleMedium
import app.k9mail.core.ui.compose.designsystem.molecule.notification.NotificationActionButton
import app.k9mail.core.ui.compose.theme2.MainTheme
@PreviewLightDark
@Composable
private fun BannerInlineNotificationCardCustomTitleAndDescriptionPreview() {
PreviewWithThemesLightDark {
Surface(modifier = Modifier.padding(MainTheme.spacings.triple)) {
BannerInlineNotificationCard(
icon = { Icon(imageVector = Icons.Outlined.Report) },
title = {
TextTitleMedium(text = "Authentication required")
},
supportingText = {
TextBodyMedium(text = "Sign in to authenticate username@domain3.example")
},
actions = {
NotificationActionButton(text = "Support article", onClick = {}, isExternalLink = true)
NotificationActionButton(text = "Sign in", onClick = {})
},
modifier = Modifier.padding(
vertical = MainTheme.spacings.quadruple,
horizontal = MainTheme.spacings.default,
),
)
}
}
}
@PreviewLightDark
@Composable
private fun BannerInlineNotificationCardTextPreview() {
PreviewWithThemesLightDark {
Surface(modifier = Modifier.padding(MainTheme.spacings.triple)) {
BannerInlineNotificationCard(
icon = { Icon(imageVector = Icons.Outlined.Report) },
title = "Missing encryption key",
supportingText = "To dismiss this error, disable encryption for this account or ensure " +
"encryption key is available in openKeychain app.",
actions = {
NotificationActionButton(text = "Support article", onClick = {}, isExternalLink = true)
NotificationActionButton(text = "Disable encryption", onClick = {})
},
modifier = Modifier.padding(
vertical = MainTheme.spacings.quadruple,
horizontal = MainTheme.spacings.default,
),
)
}
}
}
@PreviewLightDark
@Composable
private fun BannerInlineNotificationCardAnnotatedStringPreview() {
PreviewWithThemesLightDark {
Surface(modifier = Modifier.padding(MainTheme.spacings.triple)) {
BannerInlineNotificationCard(
icon = { Icon(imageVector = Icons.Outlined.Report) },
title = buildAnnotatedString {
withStyle(style = SpanStyle(color = MainTheme.colors.tertiaryContainer)) {
append("Missing encryption key")
}
},
supportingText = buildAnnotatedString {
append("To dismiss this error, ")
withStyle(style = SpanStyle(fontWeight = FontWeight.Black)) {
append("disable encryption for this account or ensure encryption key is available")
}
append("in openKeychain app.")
},
actions = {
NotificationActionButton(text = "Support article", onClick = {}, isExternalLink = true)
NotificationActionButton(text = "Disable encryption", onClick = {})
},
modifier = Modifier.padding(
vertical = MainTheme.spacings.quadruple,
horizontal = MainTheme.spacings.default,
),
)
}
}
}
@PreviewLightDark
@Composable
private fun BannerInlineNotificationClippedCardTextPreview() {
PreviewWithThemesLightDark {
Surface(modifier = Modifier.padding(MainTheme.spacings.triple)) {
BannerInlineNotificationCard(
icon = { Icon(imageVector = Icons.Outlined.Report) },
title = "Vestibulum tempor sed massa eget fermentum. Vivamus ut vitae aliquam e augue. " +
"Sed nec tincidunt arcu",
supportingText = "scelerisque fermentum. In lobortis pellentesque aliquet. Curabitur quam " +
"felis, sodales in leo ac, sodales rutrum quam. Quisque et odio id ex varius porta. " +
"Vestibulum tortor nibh, porta venenatis velit",
actions = {
NotificationActionButton(text = "Support article", onClick = {}, isExternalLink = true)
NotificationActionButton(text = "Disable encryption", onClick = {})
},
modifier = Modifier.padding(
vertical = MainTheme.spacings.quadruple,
horizontal = MainTheme.spacings.default,
),
behaviour = BannerInlineNotificationCardBehaviour.Clipped,
)
}
}
}
@PreviewLightDark
@Composable
private fun BannerInlineNotificationExpandedCardTextPreview() {
PreviewWithThemesLightDark {
Surface(modifier = Modifier.padding(MainTheme.spacings.triple)) {
BannerInlineNotificationCard(
icon = { Icon(imageVector = Icons.Outlined.Report) },
title = "Vestibulum tempor sed massa eget fermentum. Vivamus ut vitae aliquam e augue. " +
"Sed nec tincidunt arcu",
supportingText = "scelerisque fermentum. In lobortis pellentesque aliquet. Curabitur quam " +
"felis, sodales in leo ac, sodales rutrum quam. Quisque et odio id ex varius porta. " +
"Vestibulum tortor nibh, porta venenatis velit",
actions = {
NotificationActionButton(text = "Support article", onClick = {}, isExternalLink = true)
NotificationActionButton(text = "Disable encryption", onClick = {})
},
modifier = Modifier.padding(
vertical = MainTheme.spacings.quadruple,
horizontal = MainTheme.spacings.default,
),
behaviour = BannerInlineNotificationCardBehaviour.Expanded,
)
}
}
}

View file

@ -0,0 +1,59 @@
package app.k9mail.core.ui.compose.designsystem.organism.banner.inline
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.tooling.preview.datasource.LoremIpsum
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemesLightDark
import app.k9mail.core.ui.compose.designsystem.molecule.notification.NotificationActionButton
@PreviewLightDark
@Composable
private fun ErrorBannerInlineNotificationCardPreviewPreview() {
PreviewWithThemesLightDark {
ErrorBannerInlineNotificationCard(
title = "Notification title",
supportingText = "Supporting text",
actions = {
NotificationActionButton(text = "View support article", onClick = {}, isExternalLink = true)
NotificationActionButton(text = "Action 1", onClick = {})
},
)
}
}
@PreviewLightDark
@Composable
private fun ErrorBannerInlineNotificationCardLongTextClippedPreviewPreview() {
val title = remember { LoremIpsum(words = 20).values.joinToString(" ") }
val supportingText = remember { LoremIpsum(words = 60).values.joinToString(" ") }
PreviewWithThemesLightDark {
ErrorBannerInlineNotificationCard(
title = title,
supportingText = supportingText,
actions = {
NotificationActionButton(text = "View support article", onClick = {}, isExternalLink = true)
NotificationActionButton(text = "Action 1", onClick = {})
},
behaviour = BannerInlineNotificationCardBehaviour.Clipped,
)
}
}
@PreviewLightDark
@Composable
private fun ErrorBannerInlineNotificationCardLongTextExpandedPreviewPreview() {
val title = remember { LoremIpsum(words = 20).values.joinToString(" ") }
val supportingText = remember { LoremIpsum(words = 60).values.joinToString(" ") }
PreviewWithThemesLightDark {
ErrorBannerInlineNotificationCard(
title = title,
supportingText = supportingText,
actions = {
NotificationActionButton(text = "View support article", onClick = {}, isExternalLink = true)
NotificationActionButton(text = "Action 1", onClick = {})
},
behaviour = BannerInlineNotificationCardBehaviour.Expanded,
)
}
}

View file

@ -0,0 +1,59 @@
package app.k9mail.core.ui.compose.designsystem.organism.banner.inline
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.tooling.preview.datasource.LoremIpsum
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemesLightDark
import app.k9mail.core.ui.compose.designsystem.molecule.notification.NotificationActionButton
@PreviewLightDark
@Composable
private fun InfoBannerInlineNotificationCardPreviewPreview() {
PreviewWithThemesLightDark {
InfoBannerInlineNotificationCard(
title = "Notification title",
supportingText = "Supporting text",
actions = {
NotificationActionButton(text = "View support article", onClick = {}, isExternalLink = true)
NotificationActionButton(text = "Action 1", onClick = {})
},
)
}
}
@PreviewLightDark
@Composable
private fun InfoBannerInlineNotificationCardLongTextClippedPreviewPreview() {
val title = remember { LoremIpsum(words = 20).values.joinToString(" ") }
val supportingText = remember { LoremIpsum(words = 60).values.joinToString(" ") }
PreviewWithThemesLightDark {
InfoBannerInlineNotificationCard(
title = title,
supportingText = supportingText,
actions = {
NotificationActionButton(text = "View support article", onClick = {}, isExternalLink = true)
NotificationActionButton(text = "Action 1", onClick = {})
},
behaviour = BannerInlineNotificationCardBehaviour.Clipped,
)
}
}
@PreviewLightDark
@Composable
private fun InfoBannerInlineNotificationCardLongTextExpandedPreviewPreview() {
val title = remember { LoremIpsum(words = 20).values.joinToString(" ") }
val supportingText = remember { LoremIpsum(words = 60).values.joinToString(" ") }
PreviewWithThemesLightDark {
InfoBannerInlineNotificationCard(
title = title,
supportingText = supportingText,
actions = {
NotificationActionButton(text = "View support article", onClick = {}, isExternalLink = true)
NotificationActionButton(text = "Action 1", onClick = {})
},
behaviour = BannerInlineNotificationCardBehaviour.Expanded,
)
}
}

View file

@ -0,0 +1,59 @@
package app.k9mail.core.ui.compose.designsystem.organism.banner.inline
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.tooling.preview.datasource.LoremIpsum
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemesLightDark
import app.k9mail.core.ui.compose.designsystem.molecule.notification.NotificationActionButton
@PreviewLightDark
@Composable
private fun SuccessBannerInlineNotificationCardPreviewPreview() {
PreviewWithThemesLightDark {
SuccessBannerInlineNotificationCard(
title = "Notification title",
supportingText = "Supporting text",
actions = {
NotificationActionButton(text = "View support article", onClick = {}, isExternalLink = true)
NotificationActionButton(text = "Action 1", onClick = {})
},
)
}
}
@PreviewLightDark
@Composable
private fun SuccessBannerInlineNotificationCardLongTextClippedPreviewPreview() {
val title = remember { LoremIpsum(words = 20).values.joinToString(" ") }
val supportingText = remember { LoremIpsum(words = 60).values.joinToString(" ") }
PreviewWithThemesLightDark {
SuccessBannerInlineNotificationCard(
title = title,
supportingText = supportingText,
actions = {
NotificationActionButton(text = "View support article", onClick = {}, isExternalLink = true)
NotificationActionButton(text = "Action 1", onClick = {})
},
behaviour = BannerInlineNotificationCardBehaviour.Clipped,
)
}
}
@PreviewLightDark
@Composable
private fun SuccessBannerInlineNotificationCardLongTextExpandedPreviewPreview() {
val title = remember { LoremIpsum(words = 20).values.joinToString(" ") }
val supportingText = remember { LoremIpsum(words = 60).values.joinToString(" ") }
PreviewWithThemesLightDark {
SuccessBannerInlineNotificationCard(
title = title,
supportingText = supportingText,
actions = {
NotificationActionButton(text = "View support article", onClick = {}, isExternalLink = true)
NotificationActionButton(text = "Action 1", onClick = {})
},
behaviour = BannerInlineNotificationCardBehaviour.Expanded,
)
}
}

View file

@ -0,0 +1,59 @@
package app.k9mail.core.ui.compose.designsystem.organism.banner.inline
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.tooling.preview.datasource.LoremIpsum
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemesLightDark
import app.k9mail.core.ui.compose.designsystem.molecule.notification.NotificationActionButton
@PreviewLightDark
@Composable
private fun WarningBannerInlineNotificationCardPreviewPreview() {
PreviewWithThemesLightDark {
WarningBannerInlineNotificationCard(
title = "Notification title",
supportingText = "Supporting text",
actions = {
NotificationActionButton(text = "View support article", onClick = {}, isExternalLink = true)
NotificationActionButton(text = "Action 1", onClick = {})
},
)
}
}
@PreviewLightDark
@Composable
private fun WarningBannerInlineNotificationCardLongTextClippedPreviewPreview() {
val title = remember { LoremIpsum(words = 20).values.joinToString(" ") }
val supportingText = remember { LoremIpsum(words = 60).values.joinToString(" ") }
PreviewWithThemesLightDark {
WarningBannerInlineNotificationCard(
title = title,
supportingText = supportingText,
actions = {
NotificationActionButton(text = "View support article", onClick = {}, isExternalLink = true)
NotificationActionButton(text = "Action 1", onClick = {})
},
behaviour = BannerInlineNotificationCardBehaviour.Clipped,
)
}
}
@PreviewLightDark
@Composable
private fun WarningBannerInlineNotificationCardLongTextExpandedPreviewPreview() {
val title = remember { LoremIpsum(words = 20).values.joinToString(" ") }
val supportingText = remember { LoremIpsum(words = 60).values.joinToString(" ") }
PreviewWithThemesLightDark {
WarningBannerInlineNotificationCard(
title = title,
supportingText = supportingText,
actions = {
NotificationActionButton(text = "View support article", onClick = {}, isExternalLink = true)
NotificationActionButton(text = "Action 1", onClick = {})
},
behaviour = BannerInlineNotificationCardBehaviour.Expanded,
)
}
}

View file

@ -0,0 +1,27 @@
package app.k9mail.core.ui.compose.designsystem.organism.drawer
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.designsystem.atom.icon.Icons
@Composable
@Preview(showBackground = true)
internal fun NavigationDrawerItemBadgePreview() {
PreviewWithThemes {
NavigationDrawerItemBadge(
label = "99+",
)
}
}
@Composable
@Preview(showBackground = true)
internal fun NavigationDrawerItemBadgeWithIconPreview() {
PreviewWithThemes {
NavigationDrawerItemBadge(
label = "99+",
imageVector = Icons.Outlined.Info,
)
}
}

View file

@ -0,0 +1,67 @@
package app.k9mail.core.ui.compose.designsystem.organism.drawer
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.AccountBox
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.designsystem.atom.icon.Icon
import app.k9mail.core.ui.compose.designsystem.atom.text.TextLabelLarge
@Composable
@Preview(showBackground = true)
internal fun NavigationDrawerItemSelectedPreview() {
PreviewWithThemes {
NavigationDrawerItem(
label = "DrawerItem",
selected = true,
onClick = {},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun NavigationDrawerItemUnselectedPreview() {
PreviewWithThemes {
NavigationDrawerItem(
label = "DrawerItem",
selected = false,
onClick = {},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun NavigationDrawerItemWithIconPreview() {
PreviewWithThemes {
NavigationDrawerItem(
label = "DrawerItem",
selected = false,
onClick = {},
icon = {
Icon(
imageVector = Icons.Outlined.AccountBox,
)
},
)
}
}
@Composable
@Preview(showBackground = true)
internal fun NavigationDrawerItemWithLabelBadgePreview() {
PreviewWithThemes {
NavigationDrawerItem(
label = "DrawerItem",
selected = false,
onClick = {},
badge = {
TextLabelLarge(
text = "100+",
)
},
)
}
}

View file

@ -0,0 +1,32 @@
package app.k9mail.core.ui.compose.designsystem.template
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.fillMaxSize
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.PreviewWithTheme
import app.k9mail.core.ui.compose.designsystem.atom.Surface
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBodyLarge
import app.k9mail.core.ui.compose.designsystem.atom.text.TextTitleMedium
import app.k9mail.core.ui.compose.theme2.MainTheme
@Composable
@Preview(showBackground = true)
internal fun LazyColumnWithHeaderFooterPreview() {
PreviewWithTheme {
Surface {
LazyColumnWithHeaderFooter(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.spacedBy(MainTheme.spacings.double, Alignment.CenterVertically),
header = { TextTitleMedium(text = "Header") },
footer = { TextTitleMedium(text = "Footer") },
) {
items(10) {
TextBodyLarge(text = "Item $it")
}
}
}
}
}

View file

@ -0,0 +1,102 @@
package app.k9mail.core.ui.compose.designsystem.template
import android.os.Parcelable
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import app.k9mail.core.ui.compose.common.annotation.PreviewDevices
import app.k9mail.core.ui.compose.designsystem.PreviewWithTheme
import app.k9mail.core.ui.compose.designsystem.atom.Surface
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBodyMedium
import app.k9mail.core.ui.compose.designsystem.atom.text.TextTitleMedium
import kotlinx.coroutines.launch
import kotlinx.parcelize.Parcelize
@Composable
@PreviewDevices
internal fun ListDetailPanePreview() {
PreviewWithTheme {
val navigationController = rememberListDetailNavigationController<ListItem>()
val coroutineScope = rememberCoroutineScope()
ListDetailPane(
navigationController = navigationController,
listPane = {
Surface(
color = Color.Yellow,
modifier = Modifier.fillMaxSize(),
) {
LazyColumn {
itemsIndexed(createItems()) { index, item ->
ListItem(
item = item,
onClick = {
coroutineScope.launch {
navigationController.value.navigateToDetail(item)
}
},
)
}
}
}
},
detailPane = { item ->
Surface(
color = Color.Red,
modifier = Modifier.fillMaxSize(),
) {
ListItem(
item = item,
onClick = {
coroutineScope.launch {
navigationController.value.navigateBack()
}
},
)
}
},
)
}
}
@Composable
private fun ListItem(
item: ListItem,
onClick: () -> Unit,
) {
Column(
modifier = Modifier.clickable(onClick = onClick),
) {
TextTitleMedium(item.id)
TextBodyMedium(item.title)
}
}
@Parcelize
internal data class ListItem(
val id: String,
val title: String,
) : Parcelable
private fun createItems(): List<ListItem> {
return listOf(
ListItem(
id = "1",
title = "Item 1",
),
ListItem(
id = "2",
title = "Item 2",
),
ListItem(
id = "3",
title = "Item 3",
),
)
}

View file

@ -0,0 +1,25 @@
package app.k9mail.core.ui.compose.designsystem.template
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import app.k9mail.core.ui.compose.common.annotation.PreviewDevices
import app.k9mail.core.ui.compose.designsystem.PreviewWithTheme
import app.k9mail.core.ui.compose.designsystem.atom.Surface
import app.k9mail.core.ui.compose.theme2.MainTheme
@Composable
@PreviewDevices
internal fun ResponsiveContentPreview() {
PreviewWithTheme {
Surface {
ResponsiveContent { contentPadding ->
Surface(
color = MainTheme.colors.info,
modifier = Modifier.fillMaxSize().padding(contentPadding),
) {}
}
}
}
}

View file

@ -0,0 +1,26 @@
package app.k9mail.core.ui.compose.designsystem.template
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import app.k9mail.core.ui.compose.common.annotation.PreviewDevices
import app.k9mail.core.ui.compose.designsystem.PreviewWithTheme
import app.k9mail.core.ui.compose.designsystem.atom.Surface
import app.k9mail.core.ui.compose.theme2.MainTheme
@Composable
@PreviewDevices
internal fun ResponsiveContentWithBackgroundPreview() {
PreviewWithTheme {
ResponsiveContentWithSurface {
Surface(
color = MainTheme.colors.info,
modifier = Modifier
.fillMaxSize()
.padding(MainTheme.spacings.double),
content = {},
)
}
}
}

View file

@ -0,0 +1,30 @@
package app.k9mail.core.ui.compose.designsystem.template
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import app.k9mail.core.ui.compose.common.annotation.PreviewDevices
import app.k9mail.core.ui.compose.designsystem.PreviewWithTheme
import app.k9mail.core.ui.compose.designsystem.atom.Surface
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBodyLarge
import app.k9mail.core.ui.compose.theme2.MainTheme
@Composable
@PreviewDevices
internal fun ResponsiveWidthContainerPreview() {
PreviewWithTheme {
Surface {
ResponsiveWidthContainer { contentPadding ->
Surface(
color = MainTheme.colors.error,
modifier = Modifier
.fillMaxSize()
.padding(contentPadding),
) {
TextBodyLarge("Hello, World!")
}
}
}
}
}

View file

@ -0,0 +1,85 @@
package app.k9mail.core.ui.compose.designsystem.template
import androidx.compose.foundation.layout.fillMaxSize
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.Modifier
import androidx.compose.ui.tooling.preview.Preview
import app.k9mail.core.ui.compose.common.annotation.PreviewDevices
import app.k9mail.core.ui.compose.designsystem.PreviewWithTheme
import app.k9mail.core.ui.compose.designsystem.atom.Surface
import app.k9mail.core.ui.compose.designsystem.atom.button.ButtonIcon
import app.k9mail.core.ui.compose.designsystem.atom.icon.Icons
import app.k9mail.core.ui.compose.theme2.MainTheme
@Composable
@PreviewDevices
internal fun ScaffoldPreview() {
PreviewWithTheme {
Scaffold(
topBar = {
Surface(
color = MainTheme.colors.error,
modifier = Modifier
.fillMaxWidth()
.height(MainTheme.sizes.topBarHeight),
) {}
},
bottomBar = {
Surface(
color = MainTheme.colors.warning,
modifier = Modifier
.fillMaxWidth()
.height(MainTheme.sizes.bottomBarHeight),
) {}
},
) { contentPadding ->
Surface(
color = MainTheme.colors.info,
modifier = Modifier
.fillMaxSize()
.padding(contentPadding),
) {}
}
}
}
@Composable
@Preview(showBackground = true)
internal fun ScaffoldWitFabPreview() {
PreviewWithTheme {
Scaffold(
topBar = {
Surface(
color = MainTheme.colors.error,
modifier = Modifier
.fillMaxWidth()
.height(MainTheme.sizes.topBarHeight),
) {}
},
bottomBar = {
Surface(
color = MainTheme.colors.warning,
modifier = Modifier
.fillMaxWidth()
.height(MainTheme.sizes.bottomBarHeight),
) {}
},
floatingActionButton = {
ButtonIcon(
onClick = { },
imageVector = Icons.Outlined.Check,
)
},
) { contentPadding ->
Surface(
color = MainTheme.colors.surface,
modifier = Modifier
.fillMaxSize()
.padding(contentPadding),
) {}
}
}
}

View file

@ -0,0 +1,33 @@
package net.thunderbird.core.ui.compose.designsystem.atom.button
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import app.k9mail.core.ui.compose.designsystem.PreviewLightDarkLandscape
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemesLightDark
import app.k9mail.core.ui.compose.designsystem.atom.text.TextLabelLarge
import app.k9mail.core.ui.compose.theme2.MainTheme
@PreviewLightDarkLandscape
@Composable
private fun FavouriteButtonIconPreview() {
PreviewWithThemesLightDark(useRow = true) {
Column(
verticalArrangement = Arrangement.spacedBy(MainTheme.spacings.default),
modifier = Modifier.padding(
vertical = MainTheme.spacings.quadruple,
horizontal = MainTheme.spacings.default,
),
) {
TextLabelLarge(text = "Favourite = false")
FavouriteButtonIcon(favourite = false, onFavouriteChange = {})
Spacer(modifier = Modifier.height(MainTheme.spacings.default))
TextLabelLarge(text = "Favourite = true")
FavouriteButtonIcon(favourite = true, onFavouriteChange = {})
}
}
}

View file

@ -0,0 +1,93 @@
package net.thunderbird.core.ui.compose.designsystem.molecule.message
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
import androidx.compose.ui.tooling.preview.datasource.LoremIpsum
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.designsystem.atom.DividerHorizontal
import app.k9mail.core.ui.compose.designsystem.atom.text.TextBodySmall
import app.k9mail.core.ui.compose.designsystem.atom.text.TextLabelSmall
import app.k9mail.core.ui.compose.theme2.MainTheme
private data class MessageItemSenderTextPreviewParams(
val sender: String,
val subject: String,
val swapSenderWithSubject: Boolean,
val threadCount: Int,
)
private class MessageItemSenderTextPreviewCol : CollectionPreviewParameterProvider<MessageItemSenderTextPreviewParams>(
listOf(
MessageItemSenderTextPreviewParams(
sender = "Sender",
subject = "Subject",
swapSenderWithSubject = false,
threadCount = 0,
),
MessageItemSenderTextPreviewParams(
sender = "Sender",
subject = "Subject",
swapSenderWithSubject = true,
threadCount = 0,
),
MessageItemSenderTextPreviewParams(
sender = "Sender",
subject = "Subject",
swapSenderWithSubject = false,
threadCount = 10,
),
MessageItemSenderTextPreviewParams(
sender = "Sender",
subject = "Subject",
swapSenderWithSubject = true,
threadCount = 10,
),
MessageItemSenderTextPreviewParams(
sender = LoremIpsum(words = 10).values.joinToString(" "),
subject = "Subject",
swapSenderWithSubject = false,
threadCount = 10,
),
MessageItemSenderTextPreviewParams(
sender = "Sender",
subject = LoremIpsum(words = 10).values.joinToString(" "),
swapSenderWithSubject = true,
threadCount = 10,
),
),
)
@Preview
@Composable
private fun MessageItemSenderTextPreview(
@PreviewParameter(MessageItemSenderTextPreviewCol::class) params: MessageItemSenderTextPreviewParams,
) {
PreviewWithThemes {
Column(verticalArrangement = Arrangement.spacedBy(MainTheme.spacings.default)) {
DividerHorizontal(modifier = Modifier.padding(vertical = MainTheme.spacings.default))
TextBodySmall(text = "Params: $params")
DividerHorizontal(modifier = Modifier.padding(vertical = MainTheme.spacings.default))
TextLabelSmall(text = "MessageItemSenderTitleSmall:")
MessageItemSenderTitleSmall(
subject = params.subject,
sender = params.sender,
swapSenderWithSubject = params.swapSenderWithSubject,
threadCount = params.threadCount,
)
DividerHorizontal(modifier = Modifier.padding(vertical = MainTheme.spacings.default))
TextLabelSmall(text = "MessageItemSenderBodyMedium:")
MessageItemSenderBodyMedium(
subject = params.subject,
sender = params.sender,
swapSenderWithSubject = params.swapSenderWithSubject,
threadCount = params.threadCount,
)
}
}
}

View file

@ -0,0 +1,194 @@
package net.thunderbird.core.ui.compose.designsystem.organism.message
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
import androidx.compose.ui.tooling.preview.datasource.LoremIpsum
import androidx.compose.ui.unit.dp
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.designsystem.atom.text.TextTitleSmall
import app.k9mail.core.ui.compose.theme2.MainTheme
import kotlin.time.Clock
import kotlin.time.ExperimentalTime
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime
private class ActiveMessageItemPrevParamCol : CollectionPreviewParameterProvider<MessageItemPrevParams>(
collection = listOf(
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 3).values.joinToString(),
hasAttachments = false,
selected = false,
favourite = false,
threadCount = 0,
swapSenderWithSubject = false,
),
MessageItemPrevParams(
sender = LoremIpsum(words = 100).values.joinToString(),
subject = LoremIpsum(words = 100).values.joinToString(),
preview = LoremIpsum(words = 5).values.joinToString(),
hasAttachments = true,
selected = false,
favourite = false,
threadCount = 1,
swapSenderWithSubject = false,
),
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 10).values.joinToString(),
hasAttachments = false,
selected = true,
favourite = true,
threadCount = 10,
swapSenderWithSubject = false,
),
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 20).values.joinToString(),
hasAttachments = true,
selected = true,
favourite = true,
threadCount = 100,
swapSenderWithSubject = false,
),
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 3).values.joinToString(),
hasAttachments = false,
selected = false,
favourite = false,
threadCount = 0,
swapSenderWithSubject = true,
),
MessageItemPrevParams(
sender = LoremIpsum(words = 100).values.joinToString(),
subject = LoremIpsum(words = 100).values.joinToString(),
preview = LoremIpsum(words = 5).values.joinToString(),
hasAttachments = true,
selected = false,
favourite = false,
threadCount = 1,
swapSenderWithSubject = true,
),
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 10).values.joinToString(),
hasAttachments = false,
selected = true,
favourite = true,
threadCount = 10,
swapSenderWithSubject = true,
),
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 20).values.joinToString(),
hasAttachments = true,
selected = true,
favourite = true,
threadCount = 100,
swapSenderWithSubject = true,
),
),
)
@Preview
@Composable
private fun PreviewDefault(
@PreviewParameter(ActiveMessageItemPrevParamCol::class) params: MessageItemPrevParams,
) {
PreviewWithThemes {
ActiveMessageItem(
sender = params.sender,
subject = params.subject,
preview = params.preview,
receivedAt = @OptIn(ExperimentalTime::class) Clock.System.now().toLocalDateTime(TimeZone.UTC),
avatar = {
Box(
modifier = Modifier
.size(MainTheme.sizes.iconAvatar)
.background(
color = MainTheme.colors.primaryContainer.copy(alpha = 0.15f),
shape = CircleShape,
)
.border(width = 1.dp, color = MainTheme.colors.primary, shape = CircleShape),
) {
TextTitleSmall(text = "SN", modifier = Modifier.align(Alignment.Center))
}
},
onClick = { },
onFavouriteChange = {},
modifier = Modifier.padding(MainTheme.spacings.double),
hasAttachments = params.hasAttachments,
selected = params.selected,
favourite = params.favourite,
threadCount = params.threadCount,
swapSenderWithSubject = params.swapSenderWithSubject,
)
}
}
@Preview
@Composable
private fun PreviewCompact(
@PreviewParameter(ActiveMessageItemPrevParamCol::class) params: MessageItemPrevParams,
) {
PreviewWithThemes {
ActiveMessageItem(
sender = params.sender,
subject = params.subject,
preview = params.preview,
receivedAt = @OptIn(ExperimentalTime::class) Clock.System.now().toLocalDateTime(TimeZone.UTC),
avatar = { },
onClick = { },
onFavouriteChange = {},
modifier = Modifier.padding(MainTheme.spacings.double),
hasAttachments = params.hasAttachments,
selected = params.selected,
favourite = params.favourite,
threadCount = params.threadCount,
swapSenderWithSubject = params.swapSenderWithSubject,
contentPadding = MessageItemDefaults.compactContentPadding,
)
}
}
@Preview
@Composable
private fun PreviewRelaxed(
@PreviewParameter(ActiveMessageItemPrevParamCol::class) params: MessageItemPrevParams,
) {
PreviewWithThemes {
ActiveMessageItem(
sender = params.sender,
subject = params.subject,
preview = params.preview,
receivedAt = @OptIn(ExperimentalTime::class) Clock.System.now().toLocalDateTime(TimeZone.UTC),
avatar = { },
onClick = { },
onFavouriteChange = {},
modifier = Modifier.padding(MainTheme.spacings.double),
hasAttachments = params.hasAttachments,
selected = params.selected,
favourite = params.favourite,
threadCount = params.threadCount,
swapSenderWithSubject = params.swapSenderWithSubject,
contentPadding = MessageItemDefaults.relaxedContentPadding,
)
}
}

View file

@ -0,0 +1,183 @@
package net.thunderbird.core.ui.compose.designsystem.organism.message
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
import androidx.compose.ui.tooling.preview.datasource.LoremIpsum
import androidx.compose.ui.unit.dp
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.designsystem.atom.text.TextTitleSmall
import app.k9mail.core.ui.compose.theme2.MainTheme
import kotlin.time.Clock
import kotlin.time.ExperimentalTime
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime
private class JunkMessageItemPrevParamCol : CollectionPreviewParameterProvider<MessageItemPrevParams>(
collection = listOf(
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 3).values.joinToString(),
hasAttachments = false,
selected = false,
favourite = false,
threadCount = 0,
swapSenderWithSubject = false,
),
MessageItemPrevParams(
sender = LoremIpsum(words = 100).values.joinToString(),
subject = LoremIpsum(words = 100).values.joinToString(),
preview = LoremIpsum(words = 5).values.joinToString(),
hasAttachments = true,
selected = false,
favourite = false,
threadCount = 1,
swapSenderWithSubject = false,
),
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 10).values.joinToString(),
hasAttachments = false,
selected = true,
favourite = true,
threadCount = 10,
swapSenderWithSubject = false,
),
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 20).values.joinToString(),
hasAttachments = true,
selected = true,
threadCount = 100,
swapSenderWithSubject = false,
),
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 3).values.joinToString(),
hasAttachments = false,
selected = false,
threadCount = 0,
swapSenderWithSubject = true,
),
MessageItemPrevParams(
sender = LoremIpsum(words = 100).values.joinToString(),
subject = LoremIpsum(words = 100).values.joinToString(),
preview = LoremIpsum(words = 5).values.joinToString(),
hasAttachments = true,
selected = false,
threadCount = 1,
swapSenderWithSubject = true,
),
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 10).values.joinToString(),
hasAttachments = false,
selected = true,
threadCount = 10,
swapSenderWithSubject = true,
),
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 20).values.joinToString(),
hasAttachments = true,
selected = true,
threadCount = 100,
swapSenderWithSubject = true,
),
),
)
@Preview
@Composable
private fun PreviewDefault(
@PreviewParameter(JunkMessageItemPrevParamCol::class) params: MessageItemPrevParams,
) {
PreviewWithThemes {
JunkMessageItem(
sender = params.sender,
subject = params.subject,
preview = params.preview,
receivedAt = @OptIn(ExperimentalTime::class) Clock.System.now().toLocalDateTime(TimeZone.UTC),
avatar = {
Box(
modifier = Modifier
.size(MainTheme.sizes.iconAvatar)
.background(
color = MainTheme.colors.primaryContainer.copy(alpha = 0.15f),
shape = CircleShape,
)
.border(width = 1.dp, color = MainTheme.colors.primary, shape = CircleShape),
) {
TextTitleSmall(text = "SN", modifier = Modifier.align(Alignment.Center))
}
},
onClick = { },
modifier = Modifier.padding(MainTheme.spacings.double),
hasAttachments = params.hasAttachments,
selected = params.selected,
threadCount = params.threadCount,
swapSenderWithSubject = params.swapSenderWithSubject,
)
}
}
@Preview
@Composable
private fun PreviewCompact(
@PreviewParameter(JunkMessageItemPrevParamCol::class) params: MessageItemPrevParams,
) {
PreviewWithThemes {
JunkMessageItem(
sender = params.sender,
subject = params.subject,
preview = params.preview,
receivedAt = @OptIn(ExperimentalTime::class) Clock.System.now().toLocalDateTime(TimeZone.UTC),
avatar = { },
onClick = { },
modifier = Modifier.padding(MainTheme.spacings.double),
hasAttachments = params.hasAttachments,
selected = params.selected,
threadCount = params.threadCount,
swapSenderWithSubject = params.swapSenderWithSubject,
contentPadding = MessageItemDefaults.compactContentPadding,
)
}
}
@Preview
@Composable
private fun PreviewRelaxed(
@PreviewParameter(JunkMessageItemPrevParamCol::class) params: MessageItemPrevParams,
) {
PreviewWithThemes {
JunkMessageItem(
sender = params.sender,
subject = params.subject,
preview = params.preview,
receivedAt = @OptIn(ExperimentalTime::class) Clock.System.now().toLocalDateTime(TimeZone.UTC),
avatar = { },
onClick = { },
modifier = Modifier.padding(MainTheme.spacings.double),
hasAttachments = params.hasAttachments,
selected = params.selected,
threadCount = params.threadCount,
swapSenderWithSubject = params.swapSenderWithSubject,
contentPadding = MessageItemDefaults.relaxedContentPadding,
)
}
}

View file

@ -0,0 +1,21 @@
package net.thunderbird.core.ui.compose.designsystem.organism.message
import kotlin.time.Clock
import kotlin.time.ExperimentalTime
import kotlinx.datetime.LocalDateTime
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime
internal data class MessageItemPrevParams(
val sender: String,
val subject: String,
val preview: String,
val hasAttachments: Boolean,
val selected: Boolean,
val favourite: Boolean = false,
val threadCount: Int = 0,
val swapSenderWithSubject: Boolean = false,
val receivedAt: LocalDateTime = @OptIn(ExperimentalTime::class) Clock.System
.now()
.toLocalDateTime(TimeZone.currentSystemDefault()),
)

View file

@ -0,0 +1,196 @@
package net.thunderbird.core.ui.compose.designsystem.organism.message
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.IconButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
import androidx.compose.ui.tooling.preview.datasource.LoremIpsum
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.designsystem.atom.icon.Icons
import app.k9mail.core.ui.compose.designsystem.atom.text.TextLabelLarge
import app.k9mail.core.ui.compose.designsystem.atom.text.TextTitleSmall
import app.k9mail.core.ui.compose.theme2.MainTheme
import kotlin.time.Clock
import kotlin.time.Duration.Companion.days
import kotlin.time.Duration.Companion.minutes
import kotlin.time.ExperimentalTime
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime
import net.thunderbird.core.ui.compose.designsystem.atom.icon.filled.Star
private class MessageItemPrevParamCol : CollectionPreviewParameterProvider<MessageItemPrevParams>(
collection = listOf(
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 3).values.joinToString(),
hasAttachments = false,
selected = false,
receivedAt = @OptIn(ExperimentalTime::class) Clock.System
.now()
.toLocalDateTime(TimeZone.currentSystemDefault()),
),
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 3).values.joinToString(),
hasAttachments = false,
selected = false,
receivedAt = @OptIn(ExperimentalTime::class) Clock.System
.now()
.minus(1.minutes)
.toLocalDateTime(TimeZone.currentSystemDefault()),
),
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 5).values.joinToString(),
hasAttachments = true,
selected = false,
receivedAt = @OptIn(ExperimentalTime::class) Clock.System
.now()
.minus(1.days)
.toLocalDateTime(TimeZone.currentSystemDefault()),
),
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 10).values.joinToString(),
hasAttachments = false,
selected = true,
receivedAt = @OptIn(ExperimentalTime::class) Clock.System
.now()
.minus(31.days)
.toLocalDateTime(TimeZone.currentSystemDefault()),
),
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 20).values.joinToString(),
hasAttachments = true,
selected = true,
receivedAt = @OptIn(ExperimentalTime::class) Clock.System
.now()
.minus(365.days)
.toLocalDateTime(TimeZone.currentSystemDefault()),
),
),
)
@Preview
@Composable
private fun PreviewDefault(
@PreviewParameter(MessageItemPrevParamCol::class) params: MessageItemPrevParams,
) {
PreviewWithThemes {
MessageItem(
leading = {
Box(
modifier = Modifier
.size(MainTheme.sizes.iconAvatar)
.padding(MainTheme.spacings.half)
.background(color = MainTheme.colors.primary, shape = CircleShape),
)
},
sender = { TextTitleSmall(text = params.sender) },
subject = { TextLabelLarge(text = params.subject) },
preview = params.preview,
action = {
IconButton(
onClick = { },
modifier = Modifier.size(MainTheme.sizes.iconLarge),
) {
Image(imageVector = Icons.Filled.Star, contentDescription = null)
}
},
receivedAt = params.receivedAt,
onClick = { },
modifier = Modifier.padding(MainTheme.spacings.double),
hasAttachments = params.hasAttachments,
selected = params.selected,
colors = MessageItemDefaults.newMessageItemColors(),
)
}
}
@Preview
@Composable
private fun PreviewCompact(
@PreviewParameter(MessageItemPrevParamCol::class) params: MessageItemPrevParams,
) {
PreviewWithThemes {
MessageItem(
leading = {
Box(
modifier = Modifier
.size(MainTheme.sizes.iconAvatar)
.padding(MainTheme.spacings.half)
.background(color = MainTheme.colors.primary, shape = CircleShape),
)
},
sender = { TextTitleSmall(text = params.sender) },
subject = { TextLabelLarge(text = params.subject) },
preview = params.preview,
action = {
IconButton(
onClick = { },
modifier = Modifier.size(MainTheme.sizes.iconLarge),
) {
Image(imageVector = Icons.Filled.Star, contentDescription = null)
}
},
receivedAt = params.receivedAt,
onClick = { },
modifier = Modifier.padding(MainTheme.spacings.double),
hasAttachments = params.hasAttachments,
selected = params.selected,
contentPadding = MessageItemDefaults.compactContentPadding,
colors = MessageItemDefaults.unreadMessageItemColors(),
)
}
}
@Preview
@Composable
private fun PreviewRelaxed(
@PreviewParameter(MessageItemPrevParamCol::class) params: MessageItemPrevParams,
) {
PreviewWithThemes {
MessageItem(
leading = {
Box(
modifier = Modifier
.size(MainTheme.sizes.iconAvatar)
.padding(MainTheme.spacings.half)
.background(color = MainTheme.colors.primary, shape = CircleShape),
)
},
sender = { TextTitleSmall(text = params.sender) },
subject = { TextLabelLarge(text = params.subject) },
preview = params.preview,
action = {
IconButton(
onClick = { },
modifier = Modifier.size(MainTheme.sizes.iconLarge),
) {
Image(imageVector = Icons.Filled.Star, contentDescription = null)
}
},
receivedAt = params.receivedAt,
onClick = { },
modifier = Modifier.padding(MainTheme.spacings.double),
hasAttachments = params.hasAttachments,
selected = params.selected,
contentPadding = MessageItemDefaults.relaxedContentPadding,
colors = MessageItemDefaults.readMessageItemColors(),
)
}
}

View file

@ -0,0 +1,194 @@
package net.thunderbird.core.ui.compose.designsystem.organism.message
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
import androidx.compose.ui.tooling.preview.datasource.LoremIpsum
import androidx.compose.ui.unit.dp
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.designsystem.atom.text.TextTitleSmall
import app.k9mail.core.ui.compose.theme2.MainTheme
import kotlin.time.Clock
import kotlin.time.ExperimentalTime
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime
private class NewMessageItemPrevParamCol : CollectionPreviewParameterProvider<MessageItemPrevParams>(
collection = listOf(
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 3).values.joinToString(),
hasAttachments = false,
selected = false,
favourite = false,
threadCount = 0,
swapSenderWithSubject = false,
),
MessageItemPrevParams(
sender = LoremIpsum(words = 100).values.joinToString(),
subject = LoremIpsum(words = 100).values.joinToString(),
preview = LoremIpsum(words = 5).values.joinToString(),
hasAttachments = true,
selected = false,
favourite = false,
threadCount = 1,
swapSenderWithSubject = false,
),
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 10).values.joinToString(),
hasAttachments = false,
selected = true,
favourite = true,
threadCount = 10,
swapSenderWithSubject = false,
),
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 20).values.joinToString(),
hasAttachments = true,
selected = true,
favourite = true,
threadCount = 100,
swapSenderWithSubject = false,
),
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 3).values.joinToString(),
hasAttachments = false,
selected = false,
favourite = false,
threadCount = 0,
swapSenderWithSubject = true,
),
MessageItemPrevParams(
sender = LoremIpsum(words = 100).values.joinToString(),
subject = LoremIpsum(words = 100).values.joinToString(),
preview = LoremIpsum(words = 5).values.joinToString(),
hasAttachments = true,
selected = false,
favourite = false,
threadCount = 1,
swapSenderWithSubject = true,
),
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 10).values.joinToString(),
hasAttachments = false,
selected = true,
favourite = true,
threadCount = 10,
swapSenderWithSubject = true,
),
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 20).values.joinToString(),
hasAttachments = true,
selected = true,
favourite = true,
threadCount = 100,
swapSenderWithSubject = true,
),
),
)
@Preview
@Composable
private fun PreviewDefault(
@PreviewParameter(NewMessageItemPrevParamCol::class) params: MessageItemPrevParams,
) {
PreviewWithThemes {
NewMessageItem(
sender = params.sender,
subject = params.subject,
preview = params.preview,
receivedAt = @OptIn(ExperimentalTime::class) Clock.System.now().toLocalDateTime(TimeZone.UTC),
avatar = {
Box(
modifier = Modifier
.size(MainTheme.sizes.iconAvatar)
.background(
color = MainTheme.colors.primaryContainer.copy(alpha = 0.15f),
shape = CircleShape,
)
.border(width = 1.dp, color = MainTheme.colors.primary, shape = CircleShape),
) {
TextTitleSmall(text = "SN", modifier = Modifier.align(Alignment.Center))
}
},
onClick = { },
onFavouriteChange = {},
modifier = Modifier.padding(MainTheme.spacings.double),
hasAttachments = params.hasAttachments,
selected = params.selected,
favourite = params.favourite,
threadCount = params.threadCount,
swapSenderWithSubject = params.swapSenderWithSubject,
)
}
}
@Preview
@Composable
private fun PreviewCompact(
@PreviewParameter(NewMessageItemPrevParamCol::class) params: MessageItemPrevParams,
) {
PreviewWithThemes {
NewMessageItem(
sender = params.sender,
subject = params.subject,
preview = params.preview,
receivedAt = @OptIn(ExperimentalTime::class) Clock.System.now().toLocalDateTime(TimeZone.UTC),
avatar = { },
onClick = { },
onFavouriteChange = {},
modifier = Modifier.padding(MainTheme.spacings.double),
hasAttachments = params.hasAttachments,
selected = params.selected,
favourite = params.favourite,
contentPadding = MessageItemDefaults.compactContentPadding,
threadCount = params.threadCount,
swapSenderWithSubject = params.swapSenderWithSubject,
)
}
}
@Preview
@Composable
private fun PreviewRelaxed(
@PreviewParameter(NewMessageItemPrevParamCol::class) params: MessageItemPrevParams,
) {
PreviewWithThemes {
NewMessageItem(
sender = params.sender,
subject = params.subject,
preview = params.preview,
receivedAt = @OptIn(ExperimentalTime::class) Clock.System.now().toLocalDateTime(TimeZone.UTC),
avatar = { },
onClick = { },
onFavouriteChange = {},
modifier = Modifier.padding(MainTheme.spacings.double),
hasAttachments = params.hasAttachments,
selected = params.selected,
favourite = params.favourite,
contentPadding = MessageItemDefaults.relaxedContentPadding,
threadCount = params.threadCount,
swapSenderWithSubject = params.swapSenderWithSubject,
)
}
}

View file

@ -0,0 +1,194 @@
package net.thunderbird.core.ui.compose.designsystem.organism.message
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
import androidx.compose.ui.tooling.preview.datasource.LoremIpsum
import androidx.compose.ui.unit.dp
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.designsystem.atom.text.TextTitleSmall
import app.k9mail.core.ui.compose.theme2.MainTheme
import kotlin.time.Clock
import kotlin.time.ExperimentalTime
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime
private class ReadMessageItemPrevParamCol : CollectionPreviewParameterProvider<MessageItemPrevParams>(
collection = listOf(
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 3).values.joinToString(),
hasAttachments = false,
selected = false,
favourite = false,
threadCount = 0,
swapSenderWithSubject = false,
),
MessageItemPrevParams(
sender = LoremIpsum(words = 100).values.joinToString(),
subject = LoremIpsum(words = 100).values.joinToString(),
preview = LoremIpsum(words = 5).values.joinToString(),
hasAttachments = true,
selected = false,
favourite = false,
threadCount = 1,
swapSenderWithSubject = false,
),
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 10).values.joinToString(),
hasAttachments = false,
selected = true,
favourite = true,
threadCount = 10,
swapSenderWithSubject = false,
),
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 20).values.joinToString(),
hasAttachments = true,
selected = true,
favourite = true,
threadCount = 100,
swapSenderWithSubject = false,
),
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 3).values.joinToString(),
hasAttachments = false,
selected = false,
favourite = false,
threadCount = 0,
swapSenderWithSubject = true,
),
MessageItemPrevParams(
sender = LoremIpsum(words = 100).values.joinToString(),
subject = LoremIpsum(words = 100).values.joinToString(),
preview = LoremIpsum(words = 5).values.joinToString(),
hasAttachments = true,
selected = false,
favourite = false,
threadCount = 1,
swapSenderWithSubject = true,
),
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 10).values.joinToString(),
hasAttachments = false,
selected = true,
favourite = true,
threadCount = 10,
swapSenderWithSubject = true,
),
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 20).values.joinToString(),
hasAttachments = true,
selected = true,
favourite = true,
threadCount = 100,
swapSenderWithSubject = true,
),
),
)
@Preview
@Composable
private fun PreviewDefault(
@PreviewParameter(ReadMessageItemPrevParamCol::class) params: MessageItemPrevParams,
) {
PreviewWithThemes {
ReadMessageItem(
sender = params.sender,
subject = params.subject,
preview = params.preview,
receivedAt = @OptIn(ExperimentalTime::class) Clock.System.now().toLocalDateTime(TimeZone.UTC),
avatar = {
Box(
modifier = Modifier
.size(MainTheme.sizes.iconAvatar)
.background(
color = MainTheme.colors.primaryContainer.copy(alpha = 0.15f),
shape = CircleShape,
)
.border(width = 1.dp, color = MainTheme.colors.primary, shape = CircleShape),
) {
TextTitleSmall(text = "SN", modifier = Modifier.align(Alignment.Center))
}
},
onClick = { },
onFavouriteChange = {},
modifier = Modifier.padding(MainTheme.spacings.double),
hasAttachments = params.hasAttachments,
selected = params.selected,
favourite = params.favourite,
threadCount = params.threadCount,
swapSenderWithSubject = params.swapSenderWithSubject,
)
}
}
@Preview
@Composable
private fun PreviewCompact(
@PreviewParameter(ReadMessageItemPrevParamCol::class) params: MessageItemPrevParams,
) {
PreviewWithThemes {
ReadMessageItem(
sender = params.sender,
subject = params.subject,
preview = params.preview,
receivedAt = @OptIn(ExperimentalTime::class) Clock.System.now().toLocalDateTime(TimeZone.UTC),
avatar = { },
onClick = { },
onFavouriteChange = {},
modifier = Modifier.padding(MainTheme.spacings.double),
hasAttachments = params.hasAttachments,
selected = params.selected,
favourite = params.favourite,
threadCount = params.threadCount,
swapSenderWithSubject = params.swapSenderWithSubject,
contentPadding = MessageItemDefaults.compactContentPadding,
)
}
}
@Preview
@Composable
private fun PreviewRelaxed(
@PreviewParameter(ReadMessageItemPrevParamCol::class) params: MessageItemPrevParams,
) {
PreviewWithThemes {
ReadMessageItem(
sender = params.sender,
subject = params.subject,
preview = params.preview,
receivedAt = @OptIn(ExperimentalTime::class) Clock.System.now().toLocalDateTime(TimeZone.UTC),
avatar = { },
onClick = { },
onFavouriteChange = {},
modifier = Modifier.padding(MainTheme.spacings.double),
hasAttachments = params.hasAttachments,
selected = params.selected,
favourite = params.favourite,
threadCount = params.threadCount,
swapSenderWithSubject = params.swapSenderWithSubject,
contentPadding = MessageItemDefaults.relaxedContentPadding,
)
}
}

View file

@ -0,0 +1,194 @@
package net.thunderbird.core.ui.compose.designsystem.organism.message
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
import androidx.compose.ui.tooling.preview.datasource.LoremIpsum
import androidx.compose.ui.unit.dp
import app.k9mail.core.ui.compose.designsystem.PreviewWithThemes
import app.k9mail.core.ui.compose.designsystem.atom.text.TextTitleSmall
import app.k9mail.core.ui.compose.theme2.MainTheme
import kotlin.time.Clock
import kotlin.time.ExperimentalTime
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime
private class UnreadMessageItemPrevParamCol : CollectionPreviewParameterProvider<MessageItemPrevParams>(
collection = listOf(
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 3).values.joinToString(),
hasAttachments = false,
selected = false,
favourite = false,
threadCount = 0,
swapSenderWithSubject = false,
),
MessageItemPrevParams(
sender = LoremIpsum(words = 100).values.joinToString(),
subject = LoremIpsum(words = 100).values.joinToString(),
preview = LoremIpsum(words = 5).values.joinToString(),
hasAttachments = true,
selected = false,
favourite = false,
threadCount = 1,
swapSenderWithSubject = false,
),
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 10).values.joinToString(),
hasAttachments = false,
selected = true,
favourite = true,
threadCount = 10,
swapSenderWithSubject = false,
),
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 20).values.joinToString(),
hasAttachments = true,
selected = true,
favourite = true,
threadCount = 100,
swapSenderWithSubject = false,
),
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 3).values.joinToString(),
hasAttachments = false,
selected = false,
favourite = false,
threadCount = 0,
swapSenderWithSubject = true,
),
MessageItemPrevParams(
sender = LoremIpsum(words = 100).values.joinToString(),
subject = LoremIpsum(words = 100).values.joinToString(),
preview = LoremIpsum(words = 5).values.joinToString(),
hasAttachments = true,
selected = false,
favourite = false,
threadCount = 1,
swapSenderWithSubject = true,
),
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 10).values.joinToString(),
hasAttachments = false,
selected = true,
favourite = true,
threadCount = 10,
swapSenderWithSubject = true,
),
MessageItemPrevParams(
sender = "Sender Name",
subject = "The subject",
preview = LoremIpsum(words = 20).values.joinToString(),
hasAttachments = true,
selected = true,
favourite = true,
threadCount = 100,
swapSenderWithSubject = true,
),
),
)
@Preview
@Composable
private fun PreviewDefault(
@PreviewParameter(UnreadMessageItemPrevParamCol::class) params: MessageItemPrevParams,
) {
PreviewWithThemes {
UnreadMessageItem(
sender = params.sender,
subject = params.subject,
preview = params.preview,
receivedAt = @OptIn(ExperimentalTime::class) Clock.System.now().toLocalDateTime(TimeZone.UTC),
avatar = {
Box(
modifier = Modifier
.size(MainTheme.sizes.iconAvatar)
.background(
color = MainTheme.colors.primaryContainer.copy(alpha = 0.15f),
shape = CircleShape,
)
.border(width = 1.dp, color = MainTheme.colors.primary, shape = CircleShape),
) {
TextTitleSmall(text = "SN", modifier = Modifier.align(Alignment.Center))
}
},
onClick = { },
onFavouriteChange = {},
modifier = Modifier.padding(MainTheme.spacings.double),
hasAttachments = params.hasAttachments,
selected = params.selected,
favourite = params.favourite,
threadCount = params.threadCount,
swapSenderWithSubject = params.swapSenderWithSubject,
)
}
}
@Preview
@Composable
private fun PreviewCompact(
@PreviewParameter(UnreadMessageItemPrevParamCol::class) params: MessageItemPrevParams,
) {
PreviewWithThemes {
UnreadMessageItem(
sender = params.sender,
subject = params.subject,
preview = params.preview,
receivedAt = @OptIn(ExperimentalTime::class) Clock.System.now().toLocalDateTime(TimeZone.UTC),
avatar = { },
onClick = { },
onFavouriteChange = {},
modifier = Modifier.padding(MainTheme.spacings.double),
hasAttachments = params.hasAttachments,
selected = params.selected,
favourite = params.favourite,
threadCount = params.threadCount,
swapSenderWithSubject = params.swapSenderWithSubject,
contentPadding = MessageItemDefaults.compactContentPadding,
)
}
}
@Preview
@Composable
private fun PreviewRelaxed(
@PreviewParameter(UnreadMessageItemPrevParamCol::class) params: MessageItemPrevParams,
) {
PreviewWithThemes {
UnreadMessageItem(
sender = params.sender,
subject = params.subject,
preview = params.preview,
receivedAt = @OptIn(ExperimentalTime::class) Clock.System.now().toLocalDateTime(TimeZone.UTC),
avatar = { },
onClick = { },
onFavouriteChange = {},
modifier = Modifier.padding(MainTheme.spacings.double),
hasAttachments = params.hasAttachments,
selected = params.selected,
favourite = params.favourite,
threadCount = params.threadCount,
swapSenderWithSubject = params.swapSenderWithSubject,
contentPadding = MessageItemDefaults.relaxedContentPadding,
)
}
}

View file

@ -0,0 +1,20 @@
package app.k9mail.core.ui.compose.designsystem.atom
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.material3.Checkbox as Material3Checkbox
@Composable
fun Checkbox(
checked: Boolean,
onCheckedChange: ((Boolean) -> Unit)?,
modifier: Modifier = Modifier,
enabled: Boolean = true,
) {
Material3Checkbox(
checked = checked,
onCheckedChange = onCheckedChange,
modifier = modifier,
enabled = enabled,
)
}

View file

@ -0,0 +1,31 @@
package app.k9mail.core.ui.compose.designsystem.atom
import androidx.compose.material3.ProgressIndicatorDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.material3.CircularProgressIndicator as Material3CircularProgressIndicator
@Composable
fun CircularProgressIndicator(
progress: () -> Float,
modifier: Modifier = Modifier,
color: Color = ProgressIndicatorDefaults.circularColor,
) {
Material3CircularProgressIndicator(
progress = progress,
modifier = modifier,
color = color,
)
}
@Composable
fun CircularProgressIndicator(
modifier: Modifier = Modifier,
color: Color = ProgressIndicatorDefaults.circularColor,
) {
Material3CircularProgressIndicator(
modifier = modifier,
color = color,
)
}

View file

@ -0,0 +1,43 @@
package app.k9mail.core.ui.compose.designsystem.atom
import androidx.compose.material3.ProgressIndicatorDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
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.Color
import app.k9mail.core.ui.compose.common.visibility.hide
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
private const val LOADING_INDICATOR_DELAY = 500L
/**
* Only show a [CircularProgressIndicator] after [LOADING_INDICATOR_DELAY] ms.
*
* Use this to avoid flashing a loading indicator for loads that are usually very fast.
*/
@Composable
fun DelayedCircularProgressIndicator(
modifier: Modifier = Modifier,
color: Color = ProgressIndicatorDefaults.circularColor,
) {
var progressIndicatorVisible by remember { mutableStateOf(false) }
LaunchedEffect(key1 = Unit) {
launch {
delay(LOADING_INDICATOR_DELAY)
progressIndicatorVisible = true
}
}
CircularProgressIndicator(
modifier = Modifier
.hide(!progressIndicatorVisible)
.then(modifier),
color = color,
)
}

View file

@ -0,0 +1,21 @@
package app.k9mail.core.ui.compose.designsystem.atom
import androidx.compose.material3.DividerDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.Dp
import androidx.compose.material3.HorizontalDivider as Material3HorizontalDivider
@Composable
fun DividerHorizontal(
modifier: Modifier = Modifier,
thickness: Dp = DividerDefaults.Thickness,
color: Color = DividerDefaults.color,
) {
Material3HorizontalDivider(
modifier = modifier,
thickness = thickness,
color = color,
)
}

View file

@ -0,0 +1,21 @@
package app.k9mail.core.ui.compose.designsystem.atom
import androidx.compose.material3.DividerDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.Dp
import androidx.compose.material3.VerticalDivider as Material3VerticalDivider
@Composable
fun DividerVertical(
modifier: Modifier = Modifier,
thickness: Dp = DividerDefaults.Thickness,
color: Color = DividerDefaults.color,
) {
Material3VerticalDivider(
modifier = modifier,
thickness = thickness,
color = color,
)
}

View file

@ -0,0 +1,30 @@
package app.k9mail.core.ui.compose.designsystem.atom
import androidx.compose.foundation.layout.Column
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import app.k9mail.core.ui.compose.designsystem.atom.button.RadioButton
import kotlinx.collections.immutable.ImmutableList
@Composable
fun <T> RadioGroup(
onClick: (T) -> Unit,
options: ImmutableList<T>,
optionTitle: (T) -> String,
modifier: Modifier = Modifier,
selectedOption: T? = null,
) {
if (options.isEmpty()) {
return
}
Column(modifier = modifier) {
options.forEach { option ->
RadioButton(
label = optionTitle(option),
onClick = { onClick(option) },
selected = option == selectedOption,
)
}
}
}

Some files were not shown because too many files have changed in this diff Show more